using System; using System.Collections; using System.Web; using System.Text; using System.IO; using System.Xml; using System.Text.RegularExpressions; using Cuyahoga.Core; using Cuyahoga.Core.Domain; using Cuyahoga.Core.Service; using Cuyahoga.Core.Util; using Cuyahoga.Web.Util; namespace Cuyahoga.Web { /// /// Summary description for Rss. /// public class Rdf : System.Web.UI.Page { private CoreRepository _coreRepository; private void Page_Load(object sender, System.EventArgs e) { Context.Response.Clear(); Context.Response.ContentType = "application/rdf+xml"; Context.Response.ContentEncoding = Encoding.UTF8; if (Context.Request.QueryString["SectionId"] != null) { int sectionId = Int32.Parse(Context.Request.QueryString["SectionId"]); string pathInfo = Context.Request.PathInfo; string cacheKey = String.Format("RDF_{0}_{1}", sectionId, pathInfo); string content = null; if (Context.Cache[cacheKey] == null) { // Get the data for the RSS feed because it's not in the cache yet. // Use the same cache duration for the RSS feed as the Section. this._coreRepository = (CoreRepository)HttpContext.Current.Items["CoreRepository"]; Section section = (Section)this._coreRepository.GetObjectById(typeof(Section), sectionId); section.SessionFactoryRebuilt += new EventHandler(Section_SessionFactoryRebuilt); ModuleBase module = section.CreateModule(UrlHelper.GetUrlFromSection(section)); // Create event handlers for NHibernate-related events that can occur in the module. module.ModulePathInfo = pathInfo; ISyndicatable syndicatableModule = module as ISyndicatable; if (syndicatableModule != null) { RssChannel channel = syndicatableModule.GetRssFeed(); // Rss feed writer code from http://aspnet.4guysfromrolla.com/articles/021804-1.aspx // Use an XmlTextWriter to write the XML data to a string... StringWriter sw = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(sw); writer.Formatting = Formatting.Indented; // write out writer.WriteStartElement("rdf:RDF"); writer.WriteAttributeString("xmlns", "http://purl.org/rss/1.0/"); writer.WriteAttributeString("xmlns:rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); writer.WriteAttributeString("xmlns:dc", "http://purl.org/dc/elements/1.1/"); writer.WriteAttributeString("xmlns:sy", "http://purl.org/rss/1.0/modules/syndication/"); writer.WriteAttributeString("xmlns:admin", "http://webns.net/mvcb/"); // write out writer.WriteStartElement("channel"); writer.WriteAttributeString("rdf:about", Util.UrlHelper.GetSiteUrl()); // write out -level elements writer.WriteElementString("title", channel.Title); writer.WriteElementString("link", Util.UrlHelper.GetFullUrlFromSection(section) + pathInfo); writer.WriteElementString("description", channel.Description); writer.WriteElementString("dc:date", channel.PubDate.ToUniversalTime().ToString("s") + "-06:00"); //writer.WriteElementString("lastBuildDate", channel.LastBuildDate.ToUniversalTime().ToString("r")); writer.WriteStartElement("admin:generatorAgent"); //, channel.Generator); writer.WriteAttributeString("rdf:resource", "http://www.cuyahoga-project.org"); writer.WriteEndElement(); writer.WriteElementString("sy:updatePeriod", "hourly"); writer.WriteElementString("sy:updateFrequency", "1"); //write items list for channel description writer.WriteStartElement("items"); writer.WriteStartElement("rdf:Seq"); foreach (RssItem item in channel.RssItems) { writer.WriteStartElement("rdf:li"); writer.WriteAttributeString("rdf:resource", Util.UrlHelper.GetFullUrlFromSection(section) + "/" + item.ItemId); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); //close channel tag writer.WriteEndElement(); // Regular expression to find relative urls string expression = String.Format(@"=[""']{0}", UrlHelper.GetApplicationPath()); Regex regExUrl = new Regex(expression, RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.Compiled); //write each item foreach (RssItem item in channel.RssItems) { // replace inline relative hyperlinks with full hyperlinks if (item.Description != null) { item.Description = regExUrl.Replace(item.Description, String.Format(@"=""{0}/", UrlHelper.GetSiteUrl())); } // write out writer.WriteStartElement("item"); // write out -level information writer.WriteAttributeString("rdf:about", Util.UrlHelper.GetFullUrlFromSection(section) + "/" + item.ItemId); writer.WriteElementString("title", item.Title); // TODO: Only supports ID's in the pathinfo now... writer.WriteElementString("link", Util.UrlHelper.GetFullUrlFromSection(section) + "/" + item.ItemId); writer.WriteElementString("description", item.Description); writer.WriteElementString("dc:creator", item.Author); writer.WriteElementString("dc:date", item.PubDate.ToUniversalTime().ToString("s") + "-06:00"); writer.WriteElementString("dc:subject", item.Category); // write out writer.WriteEndElement(); } // write out //writer.WriteEndElement(); // write out writer.WriteEndElement(); content = sw.ToString(); // save the string in the cache Cache.Insert(cacheKey, content, null, DateTime.Now.AddSeconds(section.CacheDuration), TimeSpan.Zero); writer.Close(); } else { throw new Exception(String.Format("The module {0} doesn't implement ISyndicatable", module.GetType().FullName)); } } else { content = Context.Cache[cacheKey].ToString(); } Context.Response.Write(content); } Context.Response.End(); } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Section_SessionFactoryRebuilt(object sender, EventArgs e) { // The SessionFactory was rebuilt, so the current NHibernate Session has become invalid. // This is handled by a simple reload of the page. // TODO: handle more elegantly? if (Context.Items["VirtualUrl"] != null) { Context.Response.Redirect(Context.Items["VirtualUrl"].ToString()); } else { Context.Response.Redirect(Context.Request.RawUrl); } } } }