ReachSerializableProperties.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Print / Reach / Serialization / manager / ReachSerializableProperties.cs / 1 / ReachSerializableProperties.cs

                            /*++ 

    Copyright (C) 2004- 2005 Microsoft Corporation
    All rights reserved.
 
    Module Name:
        ReachSerializationManager.cs 
 
    Abstract:
        Defining some classes encapsulating some information about 
        the properties contained within an object and used in the
        serialization process

    Author: 
        [....] ([....]) 1-December-2004
 
    Revision History: 
--*/
using System; 
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics; 
using System.Reflection;
using System.Xml; 
using System.IO; 
using System.Security;
using System.Security.Permissions; 
using System.ComponentModel.Design.Serialization;
using System.Windows.Xps.Packaging;
using System.Windows.Documents;
using System.Windows.Media; 
using System.Windows.Markup;
 
namespace System.Windows.Xps.Serialization 
{
    internal class SerializablePropertyCollection : 
                   IEnumerable,
                   IEnumerator
    {
        #region Contstructor 

        ///  
        /// Intantiate a SerializablePropertyCollection 
        /// 
        internal 
        SerializablePropertyCollection(
            PackageSerializationManager manager,
            object                      targetObject
            ) 
        {
            this._simplePropertyCollection  = null; 
            this._complexPropertyCollection = null; 
            this._simplePropertiesIndex     = -1;
            this._complexPropertiesIndex    = -1; 
            this._queueEnumerator           = null;
            this._serializationManager      = manager;
            this._target                    = targetObject;
            this._isSimpleMode              = true; 

            Initialize(manager, _target); 
        } 

        #endregion Constructor 

        #region IEnumerable implementation

        ///  
        /// return the Enumerator for the collection
        ///  
        public 
        IEnumerator
        GetEnumerator( 
            )
        {
            return this;
        } 

        #endregion IEnumerable implementation 
 
        #region IEnumerator implementation
 
        /// 
        /// Current object in the collection
        /// 
        public 
        object
        Current 
        { 
            get
            { 
                return _queueEnumerator.Current;
            }
        }
 
        /// 
        /// Move to the next PropertyContext 
        ///  
        public
        bool 
        MoveNext()
        {
            bool canMoveToNext = false;
 
            if(_isSimpleMode)
            { 
                if(_simplePropertiesIndex == -1) 
                {
                    _queueEnumerator = _simplePropertyCollection.GetEnumerator(); 
                }
                if(_simplePropertiesIndex < _simplePropertyCollection.Count-1)
                {
                    _simplePropertiesIndex++; 
                    _queueEnumerator.MoveNext();
                    canMoveToNext = true; 
                } 
                else
                { 
                    _isSimpleMode = false;
                }
            }
 
            if(!_isSimpleMode)
            { 
                if(_complexPropertiesIndex == -1) 
                {
                    _queueEnumerator = _complexPropertyCollection.GetEnumerator(); 
                }
                if(_complexPropertiesIndex < _complexPropertyCollection.Count-1)
                {
                    _complexPropertiesIndex++; 
                    _queueEnumerator.MoveNext();
                    canMoveToNext = true; 
                } 
            }
 
            return canMoveToNext;
        }

        ///  
        /// Reset all necessary indices and pointers to
        /// the beginning of the collection 
        ///  
        public
        void 
        Reset(
            )
        {
            this._simplePropertiesIndex     = -1; 
            this._complexPropertiesIndex    = -1;
            this._queueEnumerator           = null; 
            this._isSimpleMode              = true; 
        }
 
        #endregion IEnumerator implementation

        #region Internal Methods
 
        /// 
        /// Initialize this instance 
        ///  
        internal
        void 
        Initialize(
            PackageSerializationManager serializationManager,
            object                      targetObject
            ) 
        {
            this._serializationManager = serializationManager; 
            this._target               = targetObject; 

            // 
            // Collect all serializable properties on the
            // current object instance. Those could be
            // o clr properties
            // o dependency properties 
            //
            if (_simplePropertyCollection == null) 
            { 
                _simplePropertyCollection = new Queue();
            } 

            if (_complexPropertyCollection == null)
            {
                _complexPropertyCollection = new Queue(); 
            }
 
            // 
            // Collecting information about the CLR properties
            // 
            InitializeSerializableClrProperties();

            //
            // Now that we are done with the clr serializable properties we need to 
            // iterate through locally set dependency properties on this instance
            // that have not been serialized already. 
            // Note: Dependency Properties can only be set on Dependency Objects 
            //
            InitializeSerializableDependencyProperties(); 

            //
            // Reset the enumerator
            // to begin enumerating 
            // from the start of the
            // properties collection 
            // 
            Reset();
        } 

        /// 
        /// Clear all references for reuse without
        /// instantiation. This is a way of caching 
        /// already instantiated through recycling
        /// for future use. 
        ///  
        internal void Clear()
        { 
            this._simplePropertyCollection.Clear();
            this._complexPropertyCollection.Clear();
            this._simplePropertiesIndex     = -1;
            this._complexPropertiesIndex    = -1; 
            this._queueEnumerator           = null;
            this._serializationManager      = null; 
            this._target                    = null; 
            this._isSimpleMode              = true;
        } 

        #endregion Internal Methods

        #region Private Methods 

        ///  
        /// Fill out the portion of the collection which 
        /// points out to the CLR properties
        ///  
        private
        void
        InitializeSerializableClrProperties(
            ) 
        {
            TypePropertyCache[] clrProperties = _serializationManager.CacheManager.GetClrSerializableProperties(_target); 
 
            if(clrProperties!=null)
            { 
                for (int indexInClrSerializableProperties=0;
                     indexInClrSerializableProperties < clrProperties.Length;
                     indexInClrSerializableProperties++)
                { 
                    TypePropertyCache propertyCache = clrProperties[indexInClrSerializableProperties];
 
                    // 
                    // Create SerializablePropertyContext out of the cache retrieved
                    // 
                    SerializablePropertyContext propertyContext = new SerializablePropertyContext(_target,
                                                                                                  propertyCache);

                    propertyContext.Name = propertyContext.TypePropertyCache.PropertyInfo.Name; 

                    // 
                    // We have to differentiate between simple properties and complex properties. 
                    // o Simple properties would be considered as attributes within the markup and
                    //   would not require new writers 
                    // o Complex properties would be considered elements within the markup and might
                    //   require a new writer
                    //
                    if(propertyContext.IsComplexProperty(_serializationManager)) 
                    {
                        propertyContext.IsComplex = true; 
                        _complexPropertyCollection.Enqueue(propertyContext); 
                    }
                    else 
                    {
                        propertyContext.IsComplex = false;
                        _simplePropertyCollection.Enqueue(propertyContext);
                    } 
                }
            } 
        } 

        ///  
        /// Fill out the portion of the collection
        /// that points out to the dependency properties
        /// 
        private 
        void
        InitializeSerializableDependencyProperties( 
            ) 
        {
            TypeDependencyPropertyCache[] dependencyProperties = _serializationManager. 
                                                                 CacheManager.
                                                                 GetSerializableDependencyProperties(_target);

            if(dependencyProperties!=null) 
            {
                for (int indexInSerializableDependencyProperties=0; 
                     indexInSerializableDependencyProperties < dependencyProperties.Length; 
                     indexInSerializableDependencyProperties++)
                { 
                    TypeDependencyPropertyCache dependencyPropertyCache =
                    dependencyProperties[indexInSerializableDependencyProperties];

                    // 
                    // Create SerializableDependencyPropertyContext out of the cache retrieved
                    // 
                    SerializableDependencyPropertyContext dependencyPropertyContext = 
                    new SerializableDependencyPropertyContext(_target,
                                                              dependencyPropertyCache); 

                    dependencyPropertyContext.Name =
                    ((DependencyProperty)((TypeDependencyPropertyCache)dependencyPropertyContext.TypePropertyCache).
                    DependencyProperty).Name; 

                    // 
                    // We have to differentiate between simple properties and complex properties. 
                    // o Simple properties would be considered as attributes within the markup and
                    //   would not require new writers 
                    // o Complex properties would be considered elements within the markup and might
                    //   require a new writer
                    //
                    if(dependencyPropertyContext.IsComplexProperty(_serializationManager)) 
                    {
                        dependencyPropertyContext.IsComplex = true; 
                        _complexPropertyCollection.Enqueue(dependencyPropertyContext); 
                    }
                    else 
                    {
                        dependencyPropertyContext.IsComplex = false;
                        _simplePropertyCollection.Enqueue(dependencyPropertyContext);
                    } 
                }
            } 
        } 

 
        #endregion Private Methods

        #region Private Data
 
        private
        PackageSerializationManager _serializationManager; 
        private 
        object                      _target;
        private 
        bool                        _isSimpleMode;
        private
        int                         _simplePropertiesIndex;
        private 
        Queue                       _simplePropertyCollection;
        private 
        int                         _complexPropertiesIndex; 
        private
        Queue                       _complexPropertyCollection; 
        private
        IEnumerator                 _queueEnumerator;

        #endregion Private Data 
    };
 
 
    /// 
    /// A class defining a context for the serializable CLR property 
    /// 
    internal class SerializablePropertyContext :
                   BasicContext
    { 
        #region Constructor
 
        ///  
        /// Constructor for SerializablePropertyContext
        ///  
        public
        SerializablePropertyContext(
            string            name,
            string            prefix, 
            object            target,
            TypePropertyCache propertyCache) : 
        base(name, prefix) 
        {
            // 
            // Validate Input Arguments
            //
            if (target == null)
            { 
                throw new ArgumentNullException("target");
            } 
 
            if(propertyCache == null)
            { 
                throw new ArgumentNullException("propertyCache");
            }

            this._targetObject = target; 
            this._propertyInfo = propertyCache;
            this._isComplex    = false; 
        } 

        ///  
        /// Constructor for SerializablePropertyContext
        /// 
        internal
        SerializablePropertyContext( 
            object            target,
            TypePropertyCache propertyCache) : 
        base() 
        {
            // 
            // Validate Input Arguments
            //
            if (target == null)
            { 
                throw new ArgumentNullException("target");
            } 
 
            if(propertyCache == null)
            { 
                throw new ArgumentNullException("propertyCache");
            }

            _targetObject   = target; 
            _propertyInfo   = propertyCache;
            this._isComplex = false; 
        } 

        #endregion Constructor 

        #region Public Methods

        ///  
        /// Detect whether it is a complex property or not.
        ///  
        virtual 
        public
        bool 
        IsComplexProperty(
            PackageSerializationManager serializationManager
            )
        { 
            bool isComplex = false;
 
            // 
            // Null property value is always serialized
            // in simple attribute="*null" notation 
            //
            if (Value != null)
            {
                // 
                // If the property has a DesignerSerializationOptions.SerializeAsAttribute
                // then obviously we do not use complex notation 
                // 
                if(!(DesignerSerializationOptionsAttribute != null &&
                     (DesignerSerializationOptionsAttribute.DesignerSerializationOptions == 
                      DesignerSerializationOptions.SerializeAsAttribute)))

                {
                    // 
                    // String space preservation is honoured by System.Xml only for contents of a tag not within
                    // an attribute value. Hence we always emit strings as content within a tag 
                    // 
                    Type valueType = Value.GetType();
 
                    if (valueType == typeof(string) &&
                        ((string)Value) != string.Empty)
                    {
                        isComplex = true; 
                    }
                    else 
                    { 
                        bool canConvert;
                        isComplex = IsComplexValue(serializationManager, 
                                                   out canConvert);
                    }
                }
            } 

            return isComplex; 
        } 

        virtual 
        public
        bool
        IsComplexValue(
                PackageSerializationManager manager, 
            out bool                        canConvert
            ) 
        { 
            bool isComplex = true;
 
            canConvert = true;

            if(SerializerType!=null)
            { 
                isComplex = true;
            } 
            else 
            {
                TypeConverter converter = this.TypeConverter; 

                canConvert = converter.CanConvertTo(null,typeof(string)) &&
                             converter.CanConvertFrom(null,typeof(string));
 
                if(canConvert)
                { 
                    isComplex = false; 
                }
            } 

            return isComplex;
        }
 
        #endregion Public Methods
 
        #region Public Properties 

        ///  
        /// Qyery the Target Object
        /// 
        public
        object 
        TargetObject
        { 
            get 
            {
                return _targetObject; 
            }
        }

        ///  
        /// Qyery the CLR propertyInfo structure of this property
        ///  
        public 
        PropertyInfo
        PropertyInfo 
        {
            get
            {
                PropertyInfo info = null; 

                if (_propertyInfo != null) 
                { 
                    info = (PropertyInfo)_propertyInfo.PropertyInfo;
                } 

                return info;
            }
        } 

        //  
        // Query / Set whether the property is Complex / Simple 
        // 
        public 
        bool
        IsComplex
        {
            get 
            {
                return _isComplex; 
            } 

            set 
            {
                _isComplex = value;
            }
        } 

 
        ///  
        /// Query the visibility of the property
        ///  
        public
        DesignerSerializationVisibility
        Visibility
        { 
            get
            { 
                DesignerSerializationVisibility visibility = DesignerSerializationVisibility.Visible; 

                if (_propertyInfo != null) 
                {
                    visibility = _propertyInfo.Visibility;
                }
 
                return visibility;
            } 
        } 

        ///  
        /// Queries the Serializer type used to serialize this
        /// property if it happens to be a complex property
        /// 
        public 
        Type
        SerializerType 
        { 
            get
            { 
                Type type = null;

                if (_propertyInfo != null)
                { 
                    type =  _propertyInfo.SerializerTypeForProperty;
                } 
 
                return type;
            } 
        }

        /// 
        /// Queries the TypeConverter used to convert this property 
        /// to some equivalent string
        ///  
        public 
        TypeConverter
        TypeConverter 
        {
            get
            {
                TypeConverter converter = null; 

                if (_propertyInfo != null) 
                { 
                    converter = _propertyInfo.TypeConverterForProperty;
                } 

                return converter;
            }
        } 

        ///  
        /// Query the default value attribute 
        /// 
        public 
        DefaultValueAttribute
        DefaultValueAttribute
        {
            get 
            {
                DefaultValueAttribute defValAttr = null; 
 
                if (_propertyInfo != null)
                { 
                    defValAttr = _propertyInfo.DefaultValueAttr;
                }

                return defValAttr; 
            }
        } 
 
        /// 
        /// Query the serialization attributes 
        /// 
        public
        DesignerSerializationOptionsAttribute
        DesignerSerializationOptionsAttribute 
        {
            get 
            { 
                DesignerSerializationOptionsAttribute designerSerFlagAttr = null;
 
                if (_propertyInfo != null)
                {
                    designerSerFlagAttr = _propertyInfo.DesignerSerializationOptionsAttr;
                } 

                return designerSerFlagAttr; 
            } 
        }
 

        /// 
        /// Query whether this is a read only or a read/write property
        ///  
        public
        bool 
        IsReadOnly 
        {
            get 
            {
                bool isReadOnly = false;

                if ( (_propertyInfo != null) && 
                     (((PropertyInfo)_propertyInfo.PropertyInfo) != null) )
                { 
                    isReadOnly = !((PropertyInfo)_propertyInfo.PropertyInfo).CanWrite; 
                }
 
                return isReadOnly;
            }
        }
 
        /// 
        /// Query / set the value of this property 
        ///  
        public
        object 
        Value
        {
            get
            { 
                return _propertyInfo.PropertyValue;
            } 
 
            set
            { 
                 _propertyInfo.PropertyValue = value;
            }
        }
 
        /// 
        /// This is the cache information about the property. Each 
        /// property discovered is saved for performance optimization 
        /// 
        public 
        TypePropertyCache
        TypePropertyCache
        {
            get 
            {
                return _propertyInfo; 
            } 
        }
 
        #endregion Public Properties

        #region Private Data
 
        private
        object              _targetObject; 
        private 
        TypePropertyCache   _propertyInfo;
        private 
        bool                _isComplex;

        #endregion Private Data
    }; 

    ///  
    /// A class defining context for serializable Dependency Properties 
    /// 
    internal class SerializableDependencyPropertyContext : 
                   SerializablePropertyContext
    {
        #region Constructor
 
        /// 
        /// Constructor for SerializableDependencyPropertyContext 
        ///  
        public
        SerializableDependencyPropertyContext( 
            string                      name,
            string                      prefix,
            object                      target,
            TypeDependencyPropertyCache propertyCache) : 
        base(name, prefix,target,propertyCache)
        { 
        } 

        ///  
        /// Constructor for SerializableDependencyPropertyContext
        /// 
        public
        SerializableDependencyPropertyContext( 
            object                      target,
            TypeDependencyPropertyCache propertyCache) : 
        base(target,propertyCache) 
        {
        } 

        #endregion Constructor

 
        #region Public Methods
 
        ///  
        /// Detects whether this property is complex or simple
        ///  
        public
        override
        bool
        IsComplexProperty( 
            PackageSerializationManager serializationManager
            ) 
        { 
            bool isComplex = false;
 
            //
            // Null property value is always serialized
            // in simple attribute="*null" notation
            // 
            if (Value != null)
            { 
                // 
                // If the property has a DesignerSerializationOptions.SerializeAsAttribute
                // then obviously we do not use complex notation 
                //
                if(!(DesignerSerializationOptionsAttribute != null &&
                     (DesignerSerializationOptionsAttribute.DesignerSerializationOptions ==
                      DesignerSerializationOptions.SerializeAsAttribute))) 

                { 
                    // 
                    // String space preservation is honored by System.Xml only for contents of a tag not within
                    // an attribute value. Hence we always emit strings as content within a tag 
                    //
                    Type valueType = Value.GetType();

                    if (valueType == typeof(string) && 
                        ((string)Value) != string.Empty)
                    { 
                        isComplex = true; 
                    }
                    else 
                    {
                        bool canConvert;
                        isComplex = IsComplexValue(serializationManager,
                                                   out canConvert); 

                        if (!canConvert) 
                        { 
                            Expression expr = this.Value as Expression;
 
                            if (expr != null)
                            {
                                this.Value = ((DependencyObject)this.TargetObject).GetValue((DependencyProperty)this.DependencyProperty);
                                isComplex = this.IsComplexProperty(serializationManager); 
                            }
                        } 
                    } 
                }
            } 

            return isComplex;
        }
 
        public
        override 
        bool 
        IsComplexValue(
                PackageSerializationManager manager, 
            out bool                        canConvert
            )
        {
            bool isComplex = true; 

            canConvert = true; 
 
            if(SerializerType!=null)
            { 
                isComplex = true;
            }
            else
            { 
                TypeConverter converter = this.TypeConverter;
 
                canConvert = converter.CanConvertTo(null,typeof(string)) && 
                             converter.CanConvertFrom(null,typeof(string));
 
                if(canConvert)
                {
                    isComplex = false;
                } 
            }
 
            return isComplex; 
        }
 
        #endregion Public Methods

        #region Public Properties
 
        /// 
        /// return info about the dependency property 
        ///  
        public
        MemberInfo 
        MemberInfo
        {
            get
            { 
                MemberInfo memberInfo = null;
 
                if (this.PropertyInfo != null) 
                {
                    memberInfo = ((TypeDependencyPropertyCache)TypePropertyCache).MemberInfo; 
                }

                return memberInfo;
            } 
        }
 
        ///  
        /// return the dependency property
        ///  
        public
        Object
        DependencyProperty
        { 
            get
            { 
                Object dependencyProperty = null; 

                if (this.PropertyInfo != null) 
                {
                    dependencyProperty = ((TypeDependencyPropertyCache)TypePropertyCache).DependencyProperty;
                }
 
                return dependencyProperty;
            } 
        } 

        #endregion Public Properties 
    };
}

// 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