/*********************************************************************/ /* */ /* AgentService Framework */ /* www.agentservice.it */ /* */ /* Copyright (C) 2007 l.i.d.o. - DIST, University of Genoa, Italy */ /* GNU Lesser General Public License */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Lesser General Public */ /* License as published by the Free Software Foundation, */ /* version 2.1 of the License. */ /* */ /* This library is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ /* Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with this library; if not, write to the */ /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ /* Boston, MA 02111-1307, USA. */ /* */ /*********************************************************************/ using System; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using System.Collections; namespace AgentService.Install.XmlDataModel { /// /// Class XmlPropertyInfo. Stores the information /// about a key-value pair, that is persisted on /// an xml stream as simple tag which has two /// attributes: the name and the value of the /// property. /// [XmlRoot(ElementName="property")] public class XmlPropertyInfo : ICloneable { /// /// name of the propery. /// protected string name; /// /// Gets the name of the propery /// [XmlAttribute(AttributeName="name")] public string Name { get { return this.name; } set { this.name = value; } } /// /// value of the property /// protected string value; /// /// Gets, sets the value of /// the property. /// [XmlAttribute(AttributeName="value")] public string Value { get { return this.value; } set { this.value = value; } } /// /// Constructs an instance of the XmlPropertyInfo class. /// public XmlPropertyInfo() { this.name = string.Empty; this.value = string.Empty; } /// /// Constructs an instance of the XmlPropertyInfo class. /// /// name of the property /// value of the property public XmlPropertyInfo(string name, string value) { this.name = name; this.value = value; } #region ICloneable Members /// /// Clones this instance of XmlPropertyInfoCollection. /// /// identical copy of the object public object Clone() { XmlPropertyInfo clone = new XmlPropertyInfo(); clone.name = this.name.Clone() as string; clone.value = this.value.Clone() as string; return clone; } #endregion } /// /// Class XmlPropertyInfoCollection. Specialized Collection of XmlPropertyInfo objects /// [Serializable] [XmlRoot(ElementName = "additional")] public class XmlPropertyInfoCollection : ICollection, IEnumerator, IEnumerable, IXmlSerializable, ICloneable { /// /// InitialDimension, default value of the Size of the collection /// private readonly static int InitialDimension = 10; /// /// incFactor, defines the increment factor when the internal data structure /// needs to increase in Size /// private int incFactor = 2; /// /// Size of the collection /// private int size = 0; /// /// index of the current element in the collection /// private int index = 0; /// /// internal data structure that stores the XmlPropertyInfoXmlPropertyInfo objects /// private XmlPropertyInfo[] items; /// /// Constructs an empty collection with initial Size equal to /// XmlPropertyInfoCollection.InitialDimension /// public XmlPropertyInfoCollection() { this.items = new XmlPropertyInfo[XmlPropertyInfoCollection.InitialDimension]; this.index = -1; } /// /// Constructs an empty collection with initial Size equal to /// the argument, if the argument is less than 1 the collection /// is constructed by using the default Size /// /// initial dimension of the collection public XmlPropertyInfoCollection(int initialDimension) { if (initialDimension > 0) { this.items = new XmlPropertyInfo[initialDimension]; } else { this.items = new XmlPropertyInfo[XmlPropertyInfoCollection.InitialDimension]; } this.index = -1; } /// /// Constructs an empty collection with initial Size equal to the first argument /// and increment factor equal to second parameter. If the supplied initial Size is less than 1 /// the constructor will use the default Size, while if the increment factor is less than 1 it /// will be ignored /// /// initial Size of the collection /// increment factor public XmlPropertyInfoCollection(int initialDimension, int incFactor) { if (initialDimension > 0) { this.items = new XmlPropertyInfo[initialDimension]; } else { this.items = new XmlPropertyInfo[XmlPropertyInfoCollection.InitialDimension]; } if (incFactor > 0) { this.incFactor = incFactor; } this.index = -1; } #region ICollection Methods /// /// Gets the number of the elements actually stored in the collection /// public int Count { get { return size; } } /// /// true if the collection is synchronized /// public bool IsSynchronized { get { return false; } } /// /// Gets the sinchronization object for the collection /// public object SyncRoot { get { return null; } } /// /// Copies the elements of the collection into a System.Array object, starting at the given index. /// Throws NullArgumetException if the supplied array is null. /// Throws ArgumentOutOfRangeException if /// - the index argument is negative /// - the index argument is greater than the array's Size /// - the sum of the index argument and of the collection Size is greater then the array's Size /// - the rank of the array argument is greater than 1 /// /// array where the items of the collection will be copied to /// starting index public void CopyTo(System.Array array, int index) { if (array == null) throw new ArgumentNullException("array", "the argument cannot be null"); if (index < 0) throw new ArgumentOutOfRangeException("index", index, "the index must be >= 0"); if (array.Length <= index) throw new ArgumentOutOfRangeException("index", index, "index is greater then array Size"); if (array.Length < index + this.size) throw new ArgumentOutOfRangeException("index", index, "the index value is too forward for the insertion of the elements in the collection"); if (array.Rank != 1) throw new ArgumentOutOfRangeException("array", array, "the array has more than one dimension"); for (int ndx = 0; ndx < this.size; ndx++) array.SetValue(this.items[ndx], index + ndx); } #endregion #region IEnumerable Methods /// /// returns the enumerator object for the collection /// /// enumerator for the collection public IEnumerator GetEnumerator() { this.Reset(); return this; } #endregion #region IEnumerator Methods /// /// gets the current object for the collection /// public object Current { get { if ((this.index < this.size) && (this.index > -1)) return this.items[index]; else return null; } } /// /// resets the collection enumerator /// public void Reset() { this.index = -1; } /// /// moves to the next element of the collection. /// /// false if there are no more elements to navigate, true otherwise public bool MoveNext() { this.index++; return (this.index < this.size); } #endregion /// /// adds a property to the collection /// /// property name /// property value public void Add(string name, string value) { this.Add(new XmlPropertyInfo(name, value)); } /// /// adds a non null item to the collection /// /// item to Add public void Add(XmlPropertyInfo item) { if (item == null) throw new ArgumentNullException("item", "cannot Add a null item"); if (this.size >= this.items.Length) { int ndx; XmlPropertyInfo[] backing = new XmlPropertyInfo[this.size * this.incFactor]; for (ndx = 0; ndx < this.size; ndx++) backing[ndx] = this.items[ndx]; backing[ndx] = item; this.size = ndx + 1; this.items = backing; } else this.items[size++] = item; } /// /// Remove the first occurrence of the element equal to the argument /// /// item to Remove public void Remove(XmlPropertyInfo item) { if (item != null) { int found = size; int finalSize = size; for (int ndx = 0; ndx < this.size; ndx++) { if ((this.items[ndx] == item) && (found == this.size)) { found = ndx; finalSize--; } if (found < ndx) { this.items[found++] = this.items[ndx]; } } if (size > finalSize) { this.items[size - 1] = null; } this.size = finalSize; } } /// /// Removes all the messages from each agent queue /// public void Clear() { this.items = null; this.items = new XmlPropertyInfo[XmlPropertyInfoCollection.InitialDimension]; this.size = 0; } /// /// true if the collection Contains the supplied item /// /// item candidate /// true if found false otherwise public bool Contains(XmlPropertyInfo item) { return (this.IndexOf(item) != -1); } /// /// returns the index of the item passed as argument /// /// item to found /// zero-based index of the item, -1 otherwise public int IndexOf(XmlPropertyInfo item) { int retval = -1; for (int ndx = 0; ndx < this.size; ndx++) if (this.items[ndx] == item) retval = ndx; return retval; } /// /// returns the item at the given position in the collection /// /// position of the item /// the item at the desired position public XmlPropertyInfo this[int index] { get { if (index >= this.size) throw new IndexOutOfRangeException(String.Format("index {0} is greater or equal than the collection Size [{1}]", index, this.size)); return this.items[index]; } set { if (index >= this.size) throw new IndexOutOfRangeException(String.Format("index {0} is greater or equal than the collection Size [{1}]", index, this.size)); if (value == null) throw new NullReferenceException("Cannot insert a null item into the collection"); this.items[index] = value; } } /// /// Adds all the entries contained in the given collection /// /// collection of items to Add public void AddAll(XmlPropertyInfoCollection entries) { int needed = entries.size; int maxLen = this.size + needed; if ((this.items.Length - this.size) < needed) { XmlPropertyInfo[] backing = new XmlPropertyInfo[maxLen]; for (int i = 0; i < this.size; i++) { backing[i] = this.items[i]; } this.items = backing; } for (int offset = this.size; this.size < maxLen; this.size++) { this.items[this.size] = entries.items[this.size - offset]; } } #region IXmlSerializable Members /// /// Writes to the Xml writer this /// collection as an XML node. /// /// xml writer public void WriteXml(XmlWriter writer) { //MOD: 17/05/2006 Marco Garr : added code to Remove annoying xmlns:xssi from file XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlSerializer serializer = new XmlSerializer(typeof(XmlPropertyInfo)); for (int ndx = 0; ndx < this.size; ndx++) { serializer.Serialize(writer, this.items[ndx],ns); } writer.WriteEndElement(); } /// /// Gets the XML schema of the collection /// /// null public System.Xml.Schema.XmlSchema GetSchema() { // TODO: Add Site.GetSchema implementation return null; } /// /// Reads from the XML stream a collection object. /// /// xml reader public void ReadXml(XmlReader reader) { // Reads the element enclosing the object reader.ReadStartElement(); if (reader.LocalName == "property") { reader.MoveToContent(); // Reads the "data" element XmlSerializer serializer = new XmlSerializer(typeof(XmlPropertyInfo)); while (reader.NodeType != XmlNodeType.EndElement) { XmlPropertyInfo XmlPropertyInfo = (XmlPropertyInfo)serializer.Deserialize(reader); this.Add(XmlPropertyInfo); } reader.ReadEndElement(); } } #endregion #region ICloneable Members /// /// Clones this instance of XmlPropertyInfoCollection. /// /// identical copy of the object public object Clone() { XmlPropertyInfoCollection clone = new XmlPropertyInfoCollection(this.items.Length, this.incFactor); clone.index = index; clone.size = size; for (int ndx = 0; ndx < this.size; ndx++) { clone.items[ndx] = this.items[ndx].Clone() as XmlPropertyInfo; } return clone; } #endregion } }