LocatorPartList.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Annotations / LocatorPartList.cs / 1305600 / LocatorPartList.cs

                            #pragma warning disable 1634, 1691 
//------------------------------------------------------------------------------
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved. 
// 
// 
// Description: 
//     ContentLocatorBase contains an ordered set of ContentLocatorParts which each identify
//     a piece of content within a certain context. Resolving one part 
//     provides the context to resolve the next part.  Locators are used
//     to refer to external data in a structured way.
//
//     Spec: http://team/sites/ag/Specifications/Simplifying%20Store%20Cache%20Model.doc 
//
// History: 
//  06/30/2004: rruiz:  Introduced new concrete class to specifically represent 
//                      a list of LocatorParts (before we overloaded LocatorBase).
//  02/28/2005: rruiz:  Renamed class to Locator for FxCop violation. 
//  05/02/2005: rruiz:  Renamed the class and simplified API by using collections.
//
//-----------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Collections.Specialized; 
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Annotations.Storage;
using System.Windows.Data; 
using System.Xml;
using System.Xml.Schema; 
using System.Xml.Serialization; 
using MS.Internal;
using MS.Internal.Annotations; 

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings

namespace System.Windows.Annotations 
{
    ///  
    ///     ContentLocatorBase contains an ordered set of ContentLocatorParts which each identify 
    ///     a piece of content within a certain context. Resolving one part
    ///     provides the context to resolve the next part.  Locators are used 
    ///     to refer to external data in a structured way.
    /// 
    [XmlRoot(Namespace = AnnotationXmlConstants.Namespaces.CoreSchemaNamespace, ElementName = AnnotationXmlConstants.Elements.ContentLocator)]
    public sealed class ContentLocator : ContentLocatorBase, IXmlSerializable 
    {
        //----------------------------------------------------- 
        // 
        //  Constructors
        // 
        //-----------------------------------------------------

        #region Constructors
 
        /// 
        ///     Creates an instance of ContentLocator. 
        ///  
        public ContentLocator()
        { 
            _parts = new AnnotationObservableCollection();
            _parts.CollectionChanged += OnCollectionChanged;
        }
 
        #endregion Constructors
 
        //------------------------------------------------------ 
        //
        //  Public Methods 
        //
        //-----------------------------------------------------

        #region Public Methods 

        ///  
        ///     Determines if this list begins with the ContentLocatorParts that 
        ///     make up matchList.  All ContentLocatorParts in matchList must
        ///     be present and in the same order in this list for 
        ///     true to be returned.
        /// 
        /// the list to compare with
        ///  
        ///     true if this list begins with the ContentLocatorParts in locator;
        ///     false otherwise.  If locator is longer than this locator, will 
        ///     return false as well. 
        /// 
        /// locator is null 
        public bool StartsWith(ContentLocator locator)
        {
            if (locator == null)
            { 
                throw new ArgumentNullException("locator");
            } 
 
            Invariant.Assert(locator.Parts != null, "Locator has null Parts property.");
 
            // If this locator is shorter than matchList, then this can't contain matchList.
            #pragma warning suppress 6506 // Invariant.Assert(locator.Parts != null)
            if (this.Parts.Count < locator.Parts.Count)
            { 
                return false;
            } 
 
            for (int locatorPartIndex = 0; locatorPartIndex < locator.Parts.Count; locatorPartIndex++)
            { 
                ContentLocatorPart left = locator.Parts[locatorPartIndex];
                ContentLocatorPart right = this.Parts[locatorPartIndex];

                // ContentLocator parts can be null so check for that case here 
                if (left == null && right != null)
                { 
                    return false; 
                }
 
                if (!left.Matches(right))
                {
                    return false;
                } 
            }
 
            return true; 
        }
 
        /// 
        ///     Creates a deep copy of this list.  A new list with a clone of
        ///     every ContentLocatorPart in this list, in the same order, is returned.
        ///     Never returns null. 
        /// 
        /// a deep copy of this list 
        public override Object Clone() 
        {
            ContentLocator clone = new ContentLocator(); 
            ContentLocatorPart newPart = null;
            foreach (ContentLocatorPart part in this.Parts)
            {
                if (part != null) 
                    newPart = (ContentLocatorPart)part.Clone();
                else 
                    newPart = null; 

                clone.Parts.Add(newPart); 
            }

            return clone;
        } 

        #region IXmlSerializable Implementation 
 
        /// 
        ///     Returns the null.  The annotations schema can be found at 
        ///     http://schemas.microsoft.com/windows/annotations/2003/11/core.
        /// 
        public XmlSchema GetSchema()
        { 
            return null;
        } 
 
        /// 
        ///     Writes the internal data for this ContentLocator to the writer.  This 
        ///     method is used by an XmlSerializer to serialize a ContentLocator.  Don't
        ///     use this method directly, to serialize a ContentLocator to Xml, use an
        ///     XmlSerializer.
        ///  
        /// the writer to write internal data to
        /// writer is null 
        public void WriteXml(XmlWriter writer) 
        {
            if (writer == null) 
            {
                throw new ArgumentNullException("writer");
            }
 
            string prefix = writer.LookupPrefix(AnnotationXmlConstants.Namespaces.CoreSchemaNamespace);
            if (prefix == null) 
            { 
                writer.WriteAttributeString(AnnotationXmlConstants.Prefixes.XmlnsPrefix, AnnotationXmlConstants.Prefixes.CoreSchemaPrefix, null, AnnotationXmlConstants.Namespaces.CoreSchemaNamespace);
            } 
            prefix = writer.LookupPrefix(AnnotationXmlConstants.Namespaces.BaseSchemaNamespace);
            if (prefix == null)
            {
                writer.WriteAttributeString(AnnotationXmlConstants.Prefixes.XmlnsPrefix, AnnotationXmlConstants.Prefixes.BaseSchemaPrefix, null, AnnotationXmlConstants.Namespaces.BaseSchemaNamespace); 
            }
 
            // Write each ContentLocatorPart as its own element 
            foreach (ContentLocatorPart part in _parts)
            { 
                prefix = writer.LookupPrefix(part.PartType.Namespace);
                if (String.IsNullOrEmpty(prefix))
                {
                    prefix = "tmp"; 
                }
 
                // ContentLocatorParts cannot write themselves out becuase the element 
                // name is based on the part's type.  The ContentLocatorPart instance
                // has no way (through normal serialization) to change the element 
                // name it writes out at runtime.
                writer.WriteStartElement(prefix, part.PartType.Name, part.PartType.Namespace);

                // Each name/value pair for the ContentLocatorPart becomes an attribute 
                foreach (KeyValuePair pair in part.NameValuePairs)
                { 
                    writer.WriteStartElement(AnnotationXmlConstants.Elements.Item, AnnotationXmlConstants.Namespaces.CoreSchemaNamespace); 
                    writer.WriteAttributeString(AnnotationXmlConstants.Attributes.ItemName, pair.Key);
                    writer.WriteAttributeString(AnnotationXmlConstants.Attributes.ItemValue, pair.Value); 
                    writer.WriteEndElement();
                }

                writer.WriteEndElement(); 
            }
        } 
 
        /// 
        ///     Reads the internal data for this ContentLocator from the reader.  This 
        ///     method is used by an XmlSerializer to deserialize a ContentLocator.  Don't
        ///     use this method directly, to deserialize a ContentLocator from Xml, use an
        ///     XmlSerializer.
        ///  
        /// the reader to read internal data from
        /// reader is null 
        public void ReadXml(XmlReader reader) 
        {
            if (reader == null) 
            {
                throw new ArgumentNullException("reader");
            }
 
            // We expect no attributes on a "ContentLocator",
            // so throw using the name of one of the unexpected attributes 
            Annotation.CheckForNonNamespaceAttribute(reader, AnnotationXmlConstants.Elements.ContentLocator); 

            if (!reader.IsEmptyElement) 
            {
                reader.Read();  // Reads the start of the "ContentLocator" element

                // ContentLocatorParts cannot write themselves out (see above).  They could read 
                // themselves in but instead of having write code in one place and read
                // code somewhere else - we keep it together in this class. 
                while (!(AnnotationXmlConstants.Elements.ContentLocator == reader.LocalName && XmlNodeType.EndElement == reader.NodeType)) 
                {
                    if (XmlNodeType.Element != reader.NodeType) 
                    {
                        throw new XmlException(SR.Get(SRID.InvalidXmlContent, AnnotationXmlConstants.Elements.ContentLocator));
                    }
 
                    ContentLocatorPart part = new ContentLocatorPart(new XmlQualifiedName(reader.LocalName, reader.NamespaceURI));
 
                    // Read each of the Item elements within the ContentLocatorPart 
                    if (!reader.IsEmptyElement)
                    { 
                        // We expect no attributes on a locator part tag,
                        // so throw using the name of one of the unexpected attributes
                        Annotation.CheckForNonNamespaceAttribute(reader, part.PartType.Name);
 
                        reader.Read(); // Read the start of the locator part tag
 
                        while (!(XmlNodeType.EndElement == reader.NodeType && part.PartType.Name == reader.LocalName)) 
                        {
                            if (AnnotationXmlConstants.Elements.Item == reader.LocalName && reader.NamespaceURI == AnnotationXmlConstants.Namespaces.CoreSchemaNamespace) 
                            {
                                string name = null;
                                string value = null;
 
                                while (reader.MoveToNextAttribute())
                                { 
                                    switch (reader.LocalName) 
                                    {
                                        case AnnotationXmlConstants.Attributes.ItemName: 
                                            name = reader.Value;
                                            break;
                                        case AnnotationXmlConstants.Attributes.ItemValue:
                                            value = reader.Value; 
                                            break;
                                        default: 
                                            if (!Annotation.IsNamespaceDeclaration(reader)) 
                                                throw new XmlException(SR.Get(SRID.UnexpectedAttribute, reader.LocalName, AnnotationXmlConstants.Elements.Item));
                                            break; 
                                    }
                                }

                                if (name == null) 
                                {
                                    throw new XmlException(SR.Get(SRID.RequiredAttributeMissing, AnnotationXmlConstants.Attributes.ItemName, AnnotationXmlConstants.Elements.Item)); 
                                } 
                                if (value == null)
                                { 
                                    throw new XmlException(SR.Get(SRID.RequiredAttributeMissing, AnnotationXmlConstants.Attributes.ItemValue, AnnotationXmlConstants.Elements.Item));
                                }

                                reader.MoveToContent(); 

                                part.NameValuePairs.Add(name, value); 
 
                                bool isEmpty = reader.IsEmptyElement;
 
                                reader.Read();  // Read the beginning of the complete Item tag

                                if (!isEmpty)
                                { 
                                    if (!(XmlNodeType.EndElement == reader.NodeType && AnnotationXmlConstants.Elements.Item == reader.LocalName))
                                    { 
                                        // Should not contain any content, only attributes 
                                        throw new XmlException(SR.Get(SRID.InvalidXmlContent, AnnotationXmlConstants.Elements.Item));
                                    } 
                                    else
                                    {
                                        reader.Read(); // Read the end of the Item tag
                                    } 
                                }
                            } 
                            else 
                            {
                                // The locator part contains data other than just "Item" tags 
                                throw new XmlException(SR.Get(SRID.InvalidXmlContent, part.PartType.Name));
                            }
                        }
                    } 

                    _parts.Add(part); 
 
                    reader.Read();  // Read the ContentLocatorPart element
                } 
            }

            reader.Read(); // Reads the end of the "ContentLocator" element (or whole element if empty)
        } 

        #endregion IXmlSerializable Implementation 
 
        #endregion Public Methods
 
        //------------------------------------------------------
        //
        //  Public Operators
        // 
        //------------------------------------------------------
 
        //----------------------------------------------------- 
        //
        //  Public Events 
        //
        //------------------------------------------------------

        //----------------------------------------------------- 
        //
        //  Public Properties 
        // 
        //-----------------------------------------------------
 
        #region Public Properties

        /// 
        /// 
        /// 
        public Collection Parts 
        { 
            get
            { 
                return _parts;
            }
        }
 
        #endregion Public Properties
 
        //----------------------------------------------------- 
        //
        //  Internal Methods 
        //
        //------------------------------------------------------

        #region InternalMethods 

        ///  
        ///     Creates the dot product of this ContentLocator and the list of 
        ///     ContentLocatorParts.  The result is n Locators where n is the number of
        ///     ContentLocatorParts passed in. 
        ///     One of the resulting Locators is this ContentLocator.  If there are no
        ///     additional ContentLocatorParts a list with just this ContentLocator (unmodified)
        ///     is returned.
        ///  
        /// array of ContentLocatorParts
        /// array of Locators (one for each additional ContentLocatorPart) 
        internal IList DotProduct(IList additionalLocatorParts) 
        {
            List results = null; 

            // If there aren't any additional locator parts - this is basically a no-op
            if (additionalLocatorParts == null || additionalLocatorParts.Count == 0)
            { 
                results = new List(1);
                results.Add(this); 
            } 
            else
            { 
                results = new List(additionalLocatorParts.Count);

                for (int i = 1; i < additionalLocatorParts.Count; i++)
                { 
                    ContentLocator loc = (ContentLocator)this.Clone();
                    loc.Parts.Add(additionalLocatorParts[i]); 
                    results.Add(loc); 
                }
 
                this.Parts.Add(additionalLocatorParts[0]);
                results.Insert(0, this);
            }
            return results; 
        }
 
        ///  
        ///     Merges this ContentLocator with a ContentLocatorBase.  If other is a
        ///     ContentLocatorGroup, each of its Locators are added to clones of 
        ///     this ContentLocatorBase and are added to a new ContentLocatorGroup which is
        ///     returned.  If other is a ContentLocatorBase, its appended to this
        ///     ContentLocatorBase and this ContentLocatorBase is returned.
        ///     Both operation modify this ContentLocatorBase. 
        /// 
        /// the ContentLocatorBase to merge with 
        /// a ContentLocatorBase containing the final merged product 
        internal override ContentLocatorBase Merge(ContentLocatorBase other)
        { 
            if (other == null)
                return this;

            ContentLocatorGroup locatorGroup = other as ContentLocatorGroup; 
            if (locatorGroup != null)
            { 
                ContentLocatorGroup newGroup = new ContentLocatorGroup(); 

                ContentLocator temp = null; 
                // Create n-1 clones of this LPS and append all but one
                // LPSs in the set to the clones, adding the clones to a
                // new ContentLocatorGroup
                foreach (ContentLocator loc in locatorGroup.Locators) 
                {
                    if (temp == null) 
                    { 
                        temp = loc;
                    } 
                    else
                    {
                        ContentLocator clone = (ContentLocator)this.Clone();
                        clone.Append(loc); 
                        newGroup.Locators.Add(clone);
                    } 
                } 

                // Finally, add the remaining LPS in the set to this LPS 
                // and add this to the new ContentLocatorGroup
                if (temp != null)
                {
                    this.Append(temp); 
                    newGroup.Locators.Add(this);
                } 
 
                if (newGroup.Locators.Count == 0)
                    return this; 
                else
                    return newGroup;
            }
            else 
            {
                // Safe cast - ContentLocator only has two subclasses 
                this.Append((ContentLocator)other); 
                return this;
            } 
        }

        /// 
        ///     Appends a ContentLocator to this ContentLocator.  The passed in 
        ///     ContentLocator is not modified in anyway.  Its ContentLocatorParts are cloned.
        ///  
        /// locator to append 
        internal void Append(ContentLocator other)
        { 
            Invariant.Assert(other != null, "Parameter 'other' is null.");

            foreach(ContentLocatorPart part in other.Parts)
            { 
                this.Parts.Add((ContentLocatorPart)part.Clone());
            } 
        } 

        #endregion Internal Methods 

        //-----------------------------------------------------
        //
        //  Private Methods 
        //
        //------------------------------------------------------ 
 
        #region Private Methods
 
        /// 
        /// Listens for change events from the list of parts.  Fires a change event
        /// for this ContentLocator when an event is received.
        ///  
        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        { 
            FireLocatorChanged("Parts"); 
        }
 
        #endregion Private Methods

        //------------------------------------------------------
        // 
        //  Private Fields
        // 
        //----------------------------------------------------- 

        #region Private Fields 

        /// 
        ///     List of ContentLocatorParts in this locator.
        ///  
        private AnnotationObservableCollection _parts;
 
        #endregion Private Fields 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK