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);
}
}
}
}