RSS Generation Classes





13
Date Submitted Tue. Nov. 8th, 2005 11:45 AM
Revision 1 of 1
Beginner wwb
Tags CSharp | Generation | RSS
Comments 0 comments
RSS Generation Classes
using System;
using System.Xml;
using System.Collections;

namespace WWB.Rss
{
        #region IRssItem interface
        /// <summary>
        /// Decorator Interface for an RSS Item
        /// </summary>
        public interface IRssItem
        {
                /// <summary>
                /// Gets the title element data of the item.
                /// </summary>
                string Title
                {
                        get;
                }

                /// <summary>
                /// Gets the link element data of the item.
                /// </summary>
                string Link
                {
                        get;
                }

                /// <summary>
                /// Gets the description of the item.
                /// </summary>
                string Description
                {
                        get;
                }

                /// <summary>
                /// Gets the pubDate of the item.
                /// </summary>
                DateTime PubDate
                {
                        get;
                }

                /// <summary>
                /// Gets the author of the item.
                /// </summary>
                string Author
                {
                        get;
                }

                /// <summary>
                /// Gets the GUID of the item.
                /// </summary>
                string Guid
                {
                        get;
                }
        }
        #endregion

        #region Rss Feed class
        /// <summary>
        /// Summary description for RssFeed.
        /// </summary>
        public class RssFeed
        {
                #region fields
                string title=string.Empty;
                string link=string.Empty;
                string description=string.Empty;
                string language="en-us";
                string webmaster=string.Empty;
                DateTime pubDate=DateTime.Now;
                IRssItemCollection items=new IRssItemCollection();
                XmlDocument rss=null;
                int ttl;
                string managingeditor=string.Empty;

                private const string RSSVERSION="2.0";

                #endregion

                #region public properties
                public string Title
                {
                        get {return this.title;}
                        set {this.title=value;}
                }

                public string Link
                {
                        get {return this.link;}
                        set {this.link=value;}
                }

                public string Description
                {
                        get {return this.description;}
                        set {this.description=value;}
                }

                public string Language
                {
                        get {return this.language;}
                        set {this.language=value;}
                }

                public string Webmaster
                {
                        get {return this.webmaster;}
                        set {this.webmaster=value;}
                }

                public DateTime PubDate
                {
                        get {return this.pubDate;}
                        set {this.pubDate=value;}
                }

                public IRssItemCollection Items
                {
                        get {return this.items;}
                }

                public XmlDocument Rss
                {
                        get
                        {
                                if (this.rss==null)
                                {
                                        this.BuildRss();
                                }
                                return this.rss;
                        }
                }

                public string ManagingEditor
                {
                        get{return this.managingeditor;}
                        set{this.managingeditor=value;}
                }

                public int TTL
                {
                        get {return this.ttl;}
                        set {this.ttl=value;}
                }

                #endregion

                #region Constructors
                public RssFeed()
                {}

                public RssFeed(IRssItem[] items)
                {
                        this.items=new IRssItemCollection(items);
                }
                #endregion


                #region public methods
                /// <summary>
                /// Builds the Rss feed. Called automatically when accessing the Rss property. Call again if the object changes before accessing the Rss property.
                /// </summary>
                public void BuildRss()
                {
                        this.rss=new XmlDocument();
                        //create document element
                        XmlElement elem=rss.CreateElement("rss");
                        XmlNode text;
                        XmlAttribute attrib=rss.CreateAttribute("version");
                        attrib.Value=RssFeed.RSSVERSION;
                        elem.Attributes.Append(attrib);
                        rss.AppendChild(elem);
                        //create channel
                        XmlElement channel=rss.CreateElement("channel");
                        //add stuff to channel starting with title.
                        elem=rss.CreateElement("title");
                        text=rss.CreateTextNode(this.title);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add link
                        elem=rss.CreateElement("link");
                        text=rss.CreateTextNode(this.link);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add description
                        elem=rss.CreateElement("description");
                        text=rss.CreateTextNode(this.description);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add language
                        elem=rss.CreateElement("language");
                        text=rss.CreateTextNode(this.language);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add pubDate
                        elem=rss.CreateElement("pubDate");
                        text=rss.CreateTextNode(this.pubDate.ToString("r"));
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add managing editor
                        elem=rss.CreateElement("managingEditor");
                        text=rss.CreateTextNode(this.managingeditor);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add webmaster
                        elem=rss.CreateElement("webMaster");
                        text=rss.CreateTextNode(this.webmaster);
                        elem.AppendChild(text);
                        channel.AppendChild(elem);
                        //add the individual items
                        foreach (IRssItem rssitem in this.items)
                        {
                                channel.AppendChild(this.CreateItem(rssitem,this.rss));
                        }
                        this.rss.DocumentElement.AppendChild(channel);
                }
                #endregion
                #region private methods

                private XmlElement CreateItem(IRssItem item, XmlDocument doc)
                {
                        //build item.
                        XmlElement itemelement=doc.CreateElement("item");
                        XmlNode text;
                        //add title
                        XmlElement elem=doc.CreateElement("title");
                        text=doc.CreateTextNode(item.Title);
                        elem.AppendChild(text);
                        itemelement.AppendChild(elem);
                        //add link
                        elem=doc.CreateElement("link");
                        text=doc.CreateTextNode(item.Link);
                        elem.AppendChild(text);
                        itemelement.AppendChild(elem);
                        //add description
                        elem=doc.CreateElement("description");
                        text=doc.CreateTextNode(item.Description);
                        elem.AppendChild(text);
                        itemelement.AppendChild(elem);
                        //add pubDate
                        elem=doc.CreateElement("pubDate");
                        text=doc.CreateTextNode(item.PubDate.ToString("r"));
                        elem.AppendChild(text);
                        itemelement.AppendChild(elem);
                        //add Guid
                        elem=doc.CreateElement("guid");
                        text=doc.CreateTextNode(item.Guid);
                        elem.AppendChild(text);
                        itemelement.AppendChild(elem);
                        return itemelement;
                }
                #endregion
        }
        #endregion

        #region IRssItemCollection
        /// <summary>
        ///          A strongly-typed collection of <see cref="IRssItem"/> objects. Generated using CodeSmith 3.1
        /// </summary>
        [Serializable]
        public class IRssItemCollection : ICollection, IList, IEnumerable, ICloneable
        {
                #region Interfaces
                /// <summary>
                ///          Supports type-safe iteration over a <see cref="IRssItemCollection"/>.
                /// </summary>
                public interface IIRssItemCollectionEnumerator
                {
                        /// <summary>
                        ///          Gets the current element in the collection.
                        /// </summary>
                        IRssItem Current {get;}

                        /// <summary>
                        ///          Advances the enumerator to the next element in the collection.
                        /// </summary>
                        /// <exception cref="InvalidOperationException">
                        ///          The collection was modified after the enumerator was created.
                        /// </exception>
                        /// <returns>
                        ///          <c>true</c> if the enumerator was successfully advanced to the next element;
                        ///          <c>false</c> if the enumerator has passed the end of the collection.
                        /// </returns>
                        bool MoveNext();

                        /// <summary>
                        ///          Sets the enumerator to its initial position, before the first element in the collection.
                        /// </summary>
                        void Reset();
                }
                #endregion

                private const int DEFAULT_CAPACITY = 16;

                #region Implementation (data)
                private IRssItem[] m_array;
                private int m_count = 0;
                [NonSerialized]
                private int m_version = 0;
                #endregion
       
                #region Static Wrappers
                /// <summary>
                ///          Creates a synchronized (thread-safe) wrapper for a
                ///     <c>IRssItemCollection</c> instance.
                /// </summary>
                /// <returns>
                ///     An <c>IRssItemCollection</c> wrapper that is synchronized (thread-safe).
                /// </returns>
                public static IRssItemCollection Synchronized(IRssItemCollection list)
                {
                        if(list==null)
                                throw new ArgumentNullException("list");
                        return new SyncIRssItemCollection(list);
                }
               
                /// <summary>
                ///          Creates a read-only wrapper for a
                ///     <c>IRssItemCollection</c> instance.
                /// </summary>
                /// <returns>
                ///     An <c>IRssItemCollection</c> wrapper that is read-only.
                /// </returns>
                public static IRssItemCollection ReadOnly(IRssItemCollection list)
                {
                        if(list==null)
                                throw new ArgumentNullException("list");
                        return new ReadOnlyIRssItemCollection(list);
                }
                #endregion

                #region Construction
                /// <summary>
                ///          Initializes a new instance of the <c>IRssItemCollection</c> class
                ///          that is empty and has the default initial capacity.
                /// </summary>
                public IRssItemCollection()
                {
                        m_array = new IRssItem[DEFAULT_CAPACITY];
                }
               
                /// <summary>
                ///          Initializes a new instance of the <c>IRssItemCollection</c> class
                ///          that has the specified initial capacity.
                /// </summary>
                /// <param name="capacity">
                ///          The number of elements that the new <c>IRssItemCollection</c> is initially capable of storing.
                ///     </param>
                public IRssItemCollection(int capacity)
                {
                        m_array = new IRssItem[capacity];
                }

                /// <summary>
                ///          Initializes a new instance of the <c>IRssItemCollection</c> class
                ///          that contains elements copied from the specified <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="c">The <c>IRssItemCollection</c> whose elements are copied to the new collection.</param>
                public IRssItemCollection(IRssItemCollection c)
                {
                        m_array = new IRssItem[c.Count];
                        AddRange(c);
                }

                /// <summary>
                ///          Initializes a new instance of the <c>IRssItemCollection</c> class
                ///          that contains elements copied from the specified <see cref="IRssItem"/> array.
                /// </summary>
                /// <param name="a">The <see cref="IRssItem"/> array whose elements are copied to the new list.</param>
                public IRssItemCollection(IRssItem[] a)
                {
                        m_array = new IRssItem[a.Length];
                        AddRange(a);
                }
               
                protected enum Tag
                {
                        Default
                }

                protected IRssItemCollection(Tag t)
                {
                        m_array = null;
                }
                #endregion
               
                #region Operations (type-safe ICollection)
                /// <summary>
                ///          Gets the number of elements actually contained in the <c>IRssItemCollection</c>.
                /// </summary>
                public virtual int Count
                {
                        get { return m_count; }
                }

                /// <summary>
                ///          Copies the entire <c>IRssItemCollection</c> to a one-dimensional
                ///          <see cref="IRssItem"/> array.
                /// </summary>
                /// <param name="array">The one-dimensional <see cref="IRssItem"/> array to copy to.</param>
                public virtual void CopyTo(IRssItem[] array)
                {
                        this.CopyTo(array, 0);
                }

                /// <summary>
                ///          Copies the entire <c>IRssItemCollection</c> to a one-dimensional
                ///          <see cref="IRssItem"/> array, starting at the specified index of the target array.
                /// </summary>
                /// <param name="array">The one-dimensional <see cref="IRssItem"/> array to copy to.</param>
                /// <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
                public virtual void CopyTo(IRssItem[] array, int start)
                {
                        if (m_count > array.GetUpperBound(0) + 1 - start)
                                throw new System.ArgumentException("Destination array was not long enough.");
                       
                        Array.Copy(m_array, 0, array, start, m_count);
                }

                /// <summary>
                ///          Gets a value indicating whether access to the collection is synchronized (thread-safe).
                /// </summary>
                /// <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns>
                public virtual bool IsSynchronized
                {
                        get { return m_array.IsSynchronized; }
                }

                /// <summary>
                ///          Gets an object that can be used to synchronize access to the collection.
                /// </summary>
                public virtual object SyncRoot
                {
                        get { return m_array.SyncRoot; }
                }
                #endregion
               
                #region Operations (type-safe IList)
                /// <summary>
                ///          Gets or sets the <see cref="IRssItem"/> at the specified index.
                /// </summary>
                /// <param name="index">The zero-based index of the element to get or set.</param>
                /// <exception cref="ArgumentOutOfRangeException">
                ///          <para><paramref name="index"/> is less than zero</para>
                ///          <para>-or-</para>
                ///          <para><paramref name="index"/> is equal to or greater than <see cref="IRssItemCollection.Count"/>.</para>
                /// </exception>
                public virtual IRssItem this[int index]
                {
                        get
                        {
                                ValidateIndex(index); // throws
                                return m_array[index];
                        }
                        set
                        {
                                ValidateIndex(index); // throws
                                ++m_version;
                                m_array[index] = value;
                        }
                }

                /// <summary>
                ///          Adds a <see cref="IRssItem"/> to the end of the <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="item">The <see cref="IRssItem"/> to be added to the end of the <c>IRssItemCollection</c>.</param>
                /// <returns>The index at which the value has been added.</returns>
                public virtual int Add(IRssItem item)
                {
                        if (m_count == m_array.Length)
                                EnsureCapacity(m_count + 1);

                        m_array[m_count] = item;
                        m_version++;

                        return m_count++;
                }
               
                /// <summary>
                ///          Removes all elements from the <c>IRssItemCollection</c>.
                /// </summary>
                public virtual void Clear()
                {
                        ++m_version;
                        m_array = new IRssItem[DEFAULT_CAPACITY];
                        m_count = 0;
                }
               
                /// <summary>
                ///          Creates a shallow copy of the <see cref="IRssItemCollection"/>.
                /// </summary>
                public virtual object Clone()
                {
                        IRssItemCollection newColl = new IRssItemCollection(m_count);
                        Array.Copy(m_array, 0, newColl.m_array, 0, m_count);
                        newColl.m_count = m_count;
                        newColl.m_version = m_version;

                        return newColl;
                }

                /// <summary>
                ///          Determines whether a given <see cref="IRssItem"/> is in the <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="item">The <see cref="IRssItem"/> to check for.</param>
                /// <returns><c>true</c> if <paramref name="item"/> is found in the <c>IRssItemCollection</c>; otherwise, <c>false</c>.</returns>
                public virtual bool Contains(IRssItem item)
                {
                        for (int i=0; i != m_count; ++i)
                                if (m_array[i].Equals(item))
                                        return true;
                        return false;
                }

                /// <summary>
                ///          Returns the zero-based index of the first occurrence of a <see cref="IRssItem"/>
                ///          in the <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="item">The <see cref="IRssItem"/> to locate in the <c>IRssItemCollection</c>.</param>
                /// <returns>
                ///          The zero-based index of the first occurrence of <paramref name="item"/>
                ///          in the entire <c>IRssItemCollection</c>, if found; otherwise, -1.
                ///     </returns>
                public virtual int IndexOf(IRssItem item)
                {
                        for (int i=0; i != m_count; ++i)
                                if (m_array[i].Equals(item))
                                        return i;
                        return -1;
                }

                /// <summary>
                ///          Inserts an element into the <c>IRssItemCollection</c> at the specified index.
                /// </summary>
                /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
                /// <param name="item">The <see cref="IRssItem"/> to insert.</param>
                /// <exception cref="ArgumentOutOfRangeException">
                ///          <para><paramref name="index"/> is less than zero</para>
                ///          <para>-or-</para>
                ///          <para><paramref name="index"/> is equal to or greater than <see cref="IRssItemCollection.Count"/>.</para>
                /// </exception>
                public virtual void Insert(int index, IRssItem item)
                {
                        ValidateIndex(index, true); // throws
                       
                        if (m_count == m_array.Length)
                                EnsureCapacity(m_count + 1);

                        if (index < m_count)
                        {
                                Array.Copy(m_array, index, m_array, index + 1, m_count - index);
                        }

                        m_array[index] = item;
                        m_count++;
                        m_version++;
                }

                /// <summary>
                ///          Removes the first occurrence of a specific <see cref="IRssItem"/> from the <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="item">The <see cref="IRssItem"/> to remove from the <c>IRssItemCollection</c>.</param>
                /// <exception cref="ArgumentException">
                ///          The specified <see cref="IRssItem"/> was not found in the <c>IRssItemCollection</c>.
                /// </exception>
                public virtual void Remove(IRssItem item)
                {                 
                        int i = IndexOf(item);
                        if (i < 0)
                                throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection.");
                       
                        ++m_version;
                        RemoveAt(i);
                }

                /// <summary>
                ///          Removes the element at the specified index of the <c>IRssItemCollection</c>.
                /// </summary>
                /// <param name="index">The zero-based index of the element to remove.</param>
                /// <exception cref="ArgumentOutOfRangeException">
                ///          <para><paramref name="index"/> is less than zero</para>
                ///          <para>-or-</para>
                ///          <para><paramref name="index"/> is equal to or greater than <see cref="IRssItemCollection.Count"/>.</para>
                /// </exception>
                public virtual void RemoveAt(int index)
                {
                        ValidateIndex(index); // throws
                       
                        m_count--;

                        if (index < m_count)
                        {
                                Array.Copy(m_array, index + 1, m_array, index, m_count - index);
                        }
                       
                        // We can't set the deleted entry equal to null, because it might be a value type.
                        // Instead, we'll create an empty single-element array of the right type and copy it
                        // over the entry we want to erase.
                        IRssItem[] temp = new IRssItem[1];
                        Array.Copy(temp, 0, m_array, m_count, 1);
                        m_version++;
                }

                /// <summary>
                ///          Gets a value indicating whether the collection has a fixed size.
                /// </summary>
                /// <value>true if the collection has a fixed size; otherwise, false. The default is false</value>
                public virtual bool IsFixedSize
                {
                        get { return false; }
                }

                /// <summary>
                ///          gets a value indicating whether the <B>IList</B> is read-only.
                /// </summary>
                /// <value>true if the collection is read-only; otherwise, false. The default is false</value>
                public virtual bool IsReadOnly
                {
                        get { return false; }
                }
                #endregion

                #region Operations (type-safe IEnumerable)
               
                /// <summary>
                ///          Returns an enumerator that can iterate through the <c>IRssItemCollection</c>.
                /// </summary>
                /// <returns>An <see cref="Enumerator"/> for the entire <c>IRssItemCollection</c>.</returns>
                public virtual IIRssItemCollectionEnumerator GetEnumerator()
                {
                        return new Enumerator(this);
                }
                #endregion

                #region Public helpers (just to mimic some nice features of ArrayList)
               
                /// <summary>
                ///          Gets or sets the number of elements the <c>IRssItemCollection</c> can contain.
                /// </summary>
                public virtual int Capacity
                {
                        get { return m_array.Length; }
                       
                        set
                        {
                                if (value < m_count)
                                        value = m_count;

                                if (value != m_array.Length)