SchemaExporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / SchemaExporter.cs / 2 / SchemaExporter.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    //using System.ServiceModel.Channels; 
    using System.Xml;
    using System.Xml.Schema; 
    using System.Xml.Serialization;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Reflection;
    using System.IO; 
    using System.Globalization; 
    using System.Diagnostics;
    using System.ServiceModel.Diagnostics; 
    using System.Security;

    internal class SchemaExporter
    { 
        XmlSchemaSet schemas;
        XmlDocument xmlDoc; 
        DataContractSet dataContractSet; 

        internal SchemaExporter(XmlSchemaSet schemas, DataContractSet dataContractSet) 
        {
            this.schemas = schemas;
            this.dataContractSet = dataContractSet;
        } 

        XmlSchemaSet Schemas 
        { 
            get { return schemas; }
        } 

        XmlDocument XmlDoc
        {
            get 
            {
                if (xmlDoc == null) 
                    xmlDoc = new XmlDocument(); 
                return xmlDoc;
            } 
        }

        internal void Export()
        { 
            try
            { 
                // Remove this if we decide to publish serialization schema at well-known location 
                ExportSerializationSchema();
                foreach (KeyValuePair pair in dataContractSet) 
                {
                    DataContract dataContract = pair.Value;
                    if (!dataContractSet.IsContractProcessed(dataContract))
                    { 
                        ExportDataContract(dataContract);
                        dataContractSet.SetContractProcessed(dataContract); 
                    } 
                }
            } 
            finally
            {
                xmlDoc = null;
                dataContractSet = null; 
            }
        } 
 
        void ExportSerializationSchema()
        { 
            if (!Schemas.Contains(Globals.SerializationNamespace))
            {
                StringReader reader = new StringReader(Globals.SerializationSchema);
                XmlSchema schema = XmlSchema.Read(reader, null); 
                if (schema == null)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace))); 
                Schemas.Add(schema); 
            }
        } 

        void ExportDataContract(DataContract dataContract)
        {
            if (dataContract.IsBuiltInDataContract) 
                return;
            else if (dataContract is XmlDataContract) 
                ExportXmlDataContract((XmlDataContract)dataContract); 
            else
            { 
                XmlSchema schema = GetSchema(dataContract.StableName.Namespace);

                if (dataContract is ClassDataContract)
                { 
                    ClassDataContract classDataContract = (ClassDataContract)dataContract;
                    if (classDataContract.IsISerializable) 
                        ExportISerializableDataContract(classDataContract, schema); 
                    else
                        ExportClassDataContract(classDataContract, schema); 
                }
                else if (dataContract is CollectionDataContract)
                    ExportCollectionDataContract((CollectionDataContract)dataContract, schema);
                else if (dataContract is EnumDataContract) 
                    ExportEnumDataContract((EnumDataContract)dataContract, schema);
                ExportTopLevelElement(dataContract, schema); 
                Schemas.Reprocess(schema); 
            }
        } 

        XmlSchemaElement ExportTopLevelElement(DataContract dataContract, XmlSchema schema)
        {
            if (schema == null || dataContract.StableName.Namespace != dataContract.TopLevelElementNamespace.Value) 
                schema = GetSchema(dataContract.TopLevelElementNamespace.Value);
 
            XmlSchemaElement topLevelElement = new XmlSchemaElement(); 
            topLevelElement.Name = dataContract.TopLevelElementName.Value;
            SetElementType(topLevelElement, dataContract, schema); 
            topLevelElement.IsNillable = true;
            schema.Items.Add(topLevelElement);
            return topLevelElement;
        } 

        void ExportClassDataContract(ClassDataContract classDataContract, XmlSchema schema) 
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = classDataContract.StableName.Name; 
            schema.Items.Add(type);
            XmlElement genericInfoElement = null;
            if (classDataContract.UnderlyingType.IsGenericType)
                genericInfoElement = ExportGenericInfo(classDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace); 

            XmlSchemaSequence rootSequence = new XmlSchemaSequence(); 
            for (int i=0; i < classDataContract.Members.Count; i++) 
            {
                DataMember dataMember = classDataContract.Members[i]; 

                XmlSchemaElement element = new XmlSchemaElement();
                element.Name = dataMember.Name;
                XmlElement actualTypeElement=null; 
                DataContract memberTypeContract = dataContractSet.GetMemberTypeDataContract(dataMember);
                if (CheckIfMemberHasConflict(dataMember)) 
                { 
                    element.SchemaTypeName = AnytypeQualifiedName;
                    actualTypeElement = ExportActualType(memberTypeContract.StableName); 
                    SchemaHelper.AddSchemaImport(memberTypeContract.StableName.Namespace, schema);
                }
                else
                    SetElementType(element, memberTypeContract, schema); 
                SchemaHelper.AddElementForm(element, schema);
                if (dataMember.IsNullable) 
                    element.IsNillable = true; 
                if (!dataMember.IsRequired)
                    element.MinOccurs = 0; 

                element.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(dataMember), ExportEmitDefaultValue(dataMember));
                rootSequence.Items.Add(element);
            } 

            XmlElement isValueTypeElement = null; 
            if (classDataContract.BaseContract != null) 
            {
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, classDataContract.BaseContract.StableName, schema); 
                extension.Particle = rootSequence;
                if (classDataContract.IsReference && !classDataContract.BaseContract.IsReference)
                {
                    AddReferenceAttributes(extension.Attributes, schema); 
                }
            } 
            else 
            {
                type.Particle = rootSequence; 
                if (classDataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(classDataContract.IsValueType), schema);
                if (classDataContract.IsReference)
                    AddReferenceAttributes(type.Attributes, schema); 
            }
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(classDataContract), isValueTypeElement); 
        } 

        void AddReferenceAttributes(XmlSchemaObjectCollection attributes, XmlSchema schema) 
        {
            SchemaHelper.AddSchemaImport(Globals.SerializationNamespace, schema);
            schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace);
            attributes.Add(IdAttribute); 
            attributes.Add(RefAttribute);
        } 
 
        void SetElementType(XmlSchemaElement element, DataContract dataContract, XmlSchema schema)
        { 
            XmlDataContract xmlDataContract = dataContract as XmlDataContract;
            if (xmlDataContract != null && xmlDataContract.IsAnonymous)
            {
                element.SchemaType = xmlDataContract.XsdType; 
            }
            else 
            { 
                element.SchemaTypeName = dataContract.StableName;
 
                if (element.SchemaTypeName.Namespace.Equals(Globals.SerializationNamespace))
                    schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace);

                SchemaHelper.AddSchemaImport(dataContract.StableName.Namespace, schema); 
            }
        } 
 
        bool CheckIfMemberHasConflict(DataMember dataMember)
        { 
            if (dataMember.HasConflictingNameAndType)
                return true;

            DataMember conflictingMember = dataMember.ConflictingMember; 
            while (conflictingMember != null)
            { 
                if (conflictingMember.HasConflictingNameAndType) 
                    return true;
                conflictingMember = conflictingMember.ConflictingMember; 
            }

            return false;
        } 

        private XmlElement ExportEmitDefaultValue(DataMember dataMember) 
        { 
            if (dataMember.EmitDefaultValue)
                return null; 
            XmlElement defaultValueElement = XmlDoc.CreateElement(DefaultValueAnnotation.Name, DefaultValueAnnotation.Namespace);
            XmlAttribute emitDefaultValueAttribute = XmlDoc.CreateAttribute(Globals.EmitDefaultValueAttribute);
            emitDefaultValueAttribute.Value = Globals.False;
            defaultValueElement.Attributes.Append(emitDefaultValueAttribute); 
            return defaultValueElement;
 
        } 

        XmlElement ExportActualType(XmlQualifiedName typeName) 
        {
            return ExportActualType(typeName, XmlDoc);
        }
 
        static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc)
        { 
            XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace); 

            XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute); 
            nameAttribute.Value = typeName.Name;
            actualTypeElement.Attributes.Append(nameAttribute);

            XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute); 
            nsAttribute.Value = typeName.Namespace;
            actualTypeElement.Attributes.Append(nsAttribute); 
 
            return actualTypeElement;
        } 

        XmlElement ExportGenericInfo(Type clrType, string elementName, string elementNs)
        {
            Type itemType; 
            int nestedCollectionLevel = 0;
            while (CollectionDataContract.IsCollection(clrType, out itemType)) 
            { 
                if (DataContract.GetBuiltInDataContract(clrType) != null
                    || CollectionDataContract.IsCollectionDataContract(clrType)) 
                {
                    break;
                }
                clrType = itemType; 
                nestedCollectionLevel++;
            } 
 
            Type[] genericArguments = null;
            IList genericArgumentCounts = null; 
            if (clrType.IsGenericType)
            {
                genericArguments = clrType.GetGenericArguments();
                string typeName; 
                if (clrType.DeclaringType == null)
                    typeName = clrType.Name; 
                else 
                {
                    int nsLen = (clrType.Namespace == null) ? 0 : clrType.Namespace.Length; 
                    if (nsLen > 0)
                        nsLen++; //include the . following namespace
                    typeName = DataContract.GetClrTypeFullName(clrType).Substring(nsLen).Replace('+', '.');
                } 
                int iParam = typeName.IndexOf('[');
                if (iParam >= 0) 
                    typeName = typeName.Substring(0, iParam); 
                genericArgumentCounts = DataContract.GetDataContractNameForGenericName(typeName, null);
                clrType = clrType.GetGenericTypeDefinition(); 
            }
            XmlQualifiedName dcqname = DataContract.GetStableName(clrType);
            if (nestedCollectionLevel > 0)
            { 
                string collectionName = dcqname.Name;
                for (int n = 0; n < nestedCollectionLevel; n++) 
                    collectionName = Globals.ArrayPrefix + collectionName; 
                dcqname = new XmlQualifiedName(collectionName, DataContract.GetCollectionNamespace(dcqname.Namespace));
            } 
            XmlElement typeElement = XmlDoc.CreateElement(elementName, elementNs);

            XmlAttribute nameAttribute = XmlDoc.CreateAttribute(Globals.GenericNameAttribute);
            nameAttribute.Value = genericArguments != null ? XmlConvert.DecodeName(dcqname.Name) : dcqname.Name; 
            //nameAttribute.Value = dcqname.Name;
            typeElement.Attributes.Append(nameAttribute); 
 
            XmlAttribute nsAttribute = XmlDoc.CreateAttribute(Globals.GenericNamespaceAttribute);
            nsAttribute.Value = dcqname.Namespace; 
            typeElement.Attributes.Append(nsAttribute);

            if (genericArguments != null)
            { 
                int argIndex = 0;
                int nestedLevel = 0; 
                foreach (int genericArgumentCount in genericArgumentCounts) 
                {
                    for (int i = 0; i < genericArgumentCount; i++, argIndex++) 
                    {
                        XmlElement argumentElement = ExportGenericInfo(genericArguments[argIndex], Globals.GenericParameterLocalName, Globals.SerializationNamespace);
                        if (nestedLevel > 0)
                        { 
                            XmlAttribute nestedLevelAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute);
                            nestedLevelAttribute.Value = nestedLevel.ToString(CultureInfo.InvariantCulture); 
                            argumentElement.Attributes.Append(nestedLevelAttribute); 
                        }
                        typeElement.AppendChild(argumentElement); 
                    }
                    nestedLevel++;
                }
                if (genericArgumentCounts[nestedLevel - 1] == 0) 
                {
                    XmlAttribute typeNestedLevelsAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute); 
                    typeNestedLevelsAttribute.Value = genericArgumentCounts.Count.ToString(CultureInfo.InvariantCulture); 
                    typeElement.Attributes.Append(typeNestedLevelsAttribute);
                } 
            }

            return typeElement;
        } 

        XmlElement ExportSurrogateData(object key) 
        { 
            object surrogateData = dataContractSet.GetSurrogateData(key);
            if (surrogateData == null) 
                return null;
            StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.OmitXmlDeclaration = true; 
            XmlWriter xmlWriter = XmlWriter.Create(stringWriter, writerSettings);
            Collection knownTypes = new Collection(); 
            DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes); 
            DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject,
                SurrogateDataAnnotationName.Name, SurrogateDataAnnotationName.Namespace, knownTypes, Int32.MaxValue, 
                false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
            serializer.WriteObject(xmlWriter, surrogateData);
            xmlWriter.Flush();
            return (XmlElement)XmlDoc.ReadNode(XmlReader.Create(new StringReader(stringWriter.ToString()))); 
        }
 
        void ExportCollectionDataContract(CollectionDataContract collectionDataContract, XmlSchema schema) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType(); 
            type.Name = collectionDataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null, isDictionaryElement = null;
            if (collectionDataContract.UnderlyingType.IsGenericType && CollectionDataContract.IsCollectionDataContract(collectionDataContract.UnderlyingType)) 
                genericInfoElement = ExportGenericInfo(collectionDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace);
            if (collectionDataContract.IsDictionary) 
                isDictionaryElement = ExportIsDictionary(); 
            type.Annotation = GetSchemaAnnotation(isDictionaryElement, genericInfoElement, ExportSurrogateData(collectionDataContract));
 
            XmlSchemaSequence rootSequence = new XmlSchemaSequence();

            XmlSchemaElement element = new XmlSchemaElement();
            element.Name = collectionDataContract.ItemName; 
            element.MinOccurs = 0;
            element.MaxOccursString = Globals.OccursUnbounded; 
            if (collectionDataContract.IsDictionary) 
            {
                ClassDataContract keyValueContract = collectionDataContract.ItemContract as ClassDataContract; 
                XmlSchemaComplexType keyValueType = new XmlSchemaComplexType();
                XmlSchemaSequence keyValueSequence = new XmlSchemaSequence();
                foreach (DataMember dataMember in keyValueContract.Members)
                { 
                    XmlSchemaElement keyValueElement = new XmlSchemaElement();
                    keyValueElement.Name = dataMember.Name; 
                    SetElementType(keyValueElement, dataContractSet.GetMemberTypeDataContract(dataMember), schema); 
                    SchemaHelper.AddElementForm(keyValueElement, schema);
                    if (dataMember.IsNullable) 
                        keyValueElement.IsNillable = true;
                    keyValueElement.Annotation = GetSchemaAnnotation(ExportSurrogateData(dataMember));
                    keyValueSequence.Items.Add(keyValueElement);
                } 
                keyValueType.Particle = keyValueSequence;
                element.SchemaType = keyValueType; 
            } 
            else
            { 
                if (collectionDataContract.IsItemTypeNullable)
                    element.IsNillable = true;
                DataContract itemContract = dataContractSet.GetItemTypeDataContract(collectionDataContract);
                SetElementType(element, itemContract, schema); 
            }
            SchemaHelper.AddElementForm(element, schema); 
            rootSequence.Items.Add(element); 

            type.Particle = rootSequence; 

            if (collectionDataContract.IsReference)
                AddReferenceAttributes(type.Attributes, schema);
        } 

        XmlElement ExportIsDictionary() 
        { 
            XmlElement isDictionaryElement = XmlDoc.CreateElement(IsDictionaryAnnotationName.Name, IsDictionaryAnnotationName.Namespace);
            isDictionaryElement.InnerText = Globals.True; 
            return isDictionaryElement;
        }

        void ExportEnumDataContract(EnumDataContract enumDataContract, XmlSchema schema) 
        {
            XmlSchemaSimpleType type = new XmlSchemaSimpleType(); 
            type.Name = enumDataContract.StableName.Name; 
            XmlElement actualTypeElement = (enumDataContract.BaseContractName == DefaultEnumBaseTypeName) ? null : ExportActualType(enumDataContract.BaseContractName);
            type.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(enumDataContract)); 
            schema.Items.Add(type);

            XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
            restriction.BaseTypeName = StringQualifiedName; 
            SchemaHelper.AddSchemaImport(enumDataContract.BaseContractName.Namespace, schema);
            if (enumDataContract.Values != null) 
            { 
                for (int i = 0; i < enumDataContract.Values.Count; i++)
                { 
                    XmlSchemaEnumerationFacet facet = new XmlSchemaEnumerationFacet();
                    facet.Value = enumDataContract.Members[i].Name;
                    if (enumDataContract.Values[i] != GetDefaultEnumValue(enumDataContract.IsFlags, i))
                        facet.Annotation = GetSchemaAnnotation(EnumerationValueAnnotationName, enumDataContract.GetStringFromEnumValue(enumDataContract.Values[i]), schema); 
                    restriction.Facets.Add(facet);
                } 
            } 
            if (enumDataContract.IsFlags)
            { 
                XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                XmlSchemaSimpleType anonymousType = new XmlSchemaSimpleType();
                anonymousType.Content = restriction;
                list.ItemType = anonymousType; 
                type.Content = list;
            } 
            else 
                type.Content = restriction;
        } 

        internal static long GetDefaultEnumValue(bool isFlags, int index)
        {
            return isFlags ? (long)Math.Pow(2, index) : index; 
        }
 
        void ExportISerializableDataContract(ClassDataContract dataContract, XmlSchema schema) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType(); 
            type.Name = dataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null;
            if (dataContract.UnderlyingType.IsGenericType) 
                genericInfoElement = ExportGenericInfo(dataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace);
 
            XmlElement isValueTypeElement = null; 
            if (dataContract.BaseContract != null)
            { 
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, dataContract.BaseContract.StableName, schema);
            }
            else
            { 
                schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace);
                type.Particle = ISerializableSequence; 
                XmlSchemaAttribute iSerializableFactoryTypeAttribute = ISerializableFactoryTypeAttribute; 
                type.Attributes.Add(iSerializableFactoryTypeAttribute);
                SchemaHelper.AddSchemaImport(ISerializableFactoryTypeAttribute.RefName.Namespace, schema); 
                if (dataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema);
            }
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(dataContract), isValueTypeElement); 
        }
 
        XmlSchemaComplexContentExtension CreateTypeContent(XmlSchemaComplexType type, XmlQualifiedName baseTypeName, XmlSchema schema) 
        {
            SchemaHelper.AddSchemaImport(baseTypeName.Namespace, schema); 

            XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
            extension.BaseTypeName = baseTypeName;
            type.ContentModel = new XmlSchemaComplexContent(); 
            type.ContentModel.Content = extension;
 
            return extension; 
        }
 
        void ExportXmlDataContract(XmlDataContract dataContract)
        {
            XmlQualifiedName typeQName;
            bool hasRoot; 
            XmlSchemaType xsdType;
 
            Type clrType = dataContract.UnderlyingType; 
            if (!IsSpecialXmlType(clrType, out typeQName, out xsdType, out hasRoot))
                if (!InvokeSchemaProviderMethod(clrType, schemas, out typeQName, out xsdType, out hasRoot)) 
                    InvokeGetSchemaMethod(clrType, schemas, typeQName);

            if (hasRoot)
            { 
                if (!(typeQName.Equals(dataContract.StableName)))
                { 
                    DiagnosticUtility.DebugAssert("XML data contract type name does not match schema name"); 
                }
 
                XmlSchema schema;
                if (SchemaHelper.GetSchemaElement(Schemas,
                    new XmlQualifiedName(dataContract.TopLevelElementName.Value, dataContract.TopLevelElementNamespace.Value),
                    out schema) == null) 
                {
                    XmlSchemaElement topLevelElement = ExportTopLevelElement(dataContract, schema); 
                    topLevelElement.IsNillable = dataContract.IsTopLevelElementNullable; 
                    ReprocessAll(schemas);
                } 

                XmlSchemaType anonymousType = xsdType;
                xsdType = SchemaHelper.GetSchemaType(schemas, typeQName, out schema);
                if (anonymousType == null && xsdType == null && typeQName.Namespace != XmlSchema.Namespace) 
                {
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeQName, DataContract.GetClrTypeFullName(clrType)))); 
                } 
                if (xsdType != null)
                    xsdType.Annotation = GetSchemaAnnotation( 
                                           ExportSurrogateData(dataContract),
                                           dataContract.IsValueType ?
                                             GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema) :
                                             null 
                                         );
                else if (DiagnosticUtility.ShouldTraceVerbose) 
                    DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.XsdExportAnnotationFailed, SR.GetString(SR.TraceCodeXsdExportAnnotationFailed), new StringTraceRecord("Type", typeQName.Namespace + ":" + typeQName.Name)); 
            }
        } 

        static void ReprocessAll(XmlSchemaSet schemas)// and remove duplicate items
        {
            Hashtable elements = new Hashtable(); 
            Hashtable types = new Hashtable();
            XmlSchema[] schemaArray = new XmlSchema[schemas.Count]; 
            schemas.CopyTo(schemaArray, 0); 
            for (int i=0;i values = new Dictionary(2);
                            values["ItemType"] = item.ToString(); 
                            values["Name"] = qname.Namespace + ":" + qname.Name;
                            DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.XsdExportDupItems, SR.GetString(SR.TraceCodeXsdExportDupItems), new DictionaryTraceRecord(values));
                        }
                       schema.Items.Remove(item); 
                    }
                    else 
                        items.Add(qname, item); 
                }
                schemas.Reprocess(schema); 
            }
        }

        internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot) 
        {
            if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot)) 
                return; 
            XmlSchemaSet schemas = new XmlSchemaSet();
            schemas.XmlResolver = null; 
            InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
            if (stableName.Name == null || stableName.Name.Length == 0)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
        } 

        static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot) 
        { 
            xsdType = null;
            hasRoot = true; 
            object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
            if (attrs == null || attrs.Length == 0)
            {
                stableName = DataContract.GetDefaultStableName(clrType); 
                return false;
            } 
 
            XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
            if (provider.IsAny) 
            {
                xsdType = CreateAnyElementType();
                hasRoot = false;
            } 
            string methodName = provider.MethodName;
            if (methodName == null || methodName.Length == 0) 
            { 
                if (!provider.IsAny)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); 
                stableName = DataContract.GetDefaultStableName(clrType);
            }
            else
            { 
                MethodInfo getMethod = clrType.GetMethod(methodName,  /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
                if (getMethod == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName))); 

                if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType))) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnTypeOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName, DataContract.GetClrTypeFullName(getMethod.ReturnType), DataContract.GetClrTypeFullName(Globals.TypeOfXmlQualifiedName), typeof(XmlSchemaType))));

                object typeInfo = getMethod.Invoke(null, new object[] { schemas });
 
                if (provider.IsAny)
                { 
                    if (typeInfo != null) 
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName)));
                    stableName = DataContract.GetDefaultStableName(clrType); 
                }
                else if (typeInfo == null)
                {
                    xsdType = CreateAnyElementType(); 
                    hasRoot = false;
                    stableName = DataContract.GetDefaultStableName(clrType); 
                } 
                else
                { 
                    XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
                    if (providerXsdType != null)
                    {
                        string typeName = providerXsdType.Name; 
                        string typeNs = null;
                        if (typeName == null || typeName.Length == 0) 
                        { 
                            DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs);
                            stableName = new XmlQualifiedName(typeName, typeNs); 
                            providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
                            xsdType = providerXsdType;
                        }
                        else 
                        {
                            foreach (XmlSchema schema in schemas.Schemas()) 
                            { 
                                foreach (XmlSchemaObject schemaItem in schema.Items)
                                { 
                                    if ((object)schemaItem == (object)providerXsdType)
                                    {
                                        typeNs = schema.TargetNamespace;
                                        if (typeNs == null) 
                                            typeNs = String.Empty;
                                        break; 
                                    } 
                                }
                                if (typeNs != null) 
                                    break;
                            }
                            if (typeNs == null)
                                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType)))); 
                            stableName = new XmlQualifiedName(typeName, typeNs);
                        } 
                    } 
                    else
                        stableName = (XmlQualifiedName)typeInfo; 
                }
            }
            return true;
        } 

        static void InvokeGetSchemaMethod(Type clrType, XmlSchemaSet schemas, XmlQualifiedName stableName) 
        { 
            IXmlSerializable ixmlSerializable = (IXmlSerializable)Activator.CreateInstance(clrType);
            XmlSchema schema = ixmlSerializable.GetSchema(); 
            if (schema == null)
            {
                AddDefaultDatasetType(schemas, stableName.Name, stableName.Namespace);
            } 
            else
            { 
                if (schema.Id == null || schema.Id.Length == 0) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnSchemaOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType))));
                AddDefaultTypedDatasetType(schemas, schema, stableName.Name, stableName.Namespace); 
            }
        }

        internal static void AddDefaultXmlType(XmlSchemaSet schemas, string localName, string ns) 
        {
            XmlSchemaComplexType defaultXmlType = CreateAnyType(); 
            defaultXmlType.Name = localName; 
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas);
            schema.Items.Add(defaultXmlType); 
            schemas.Reprocess(schema);
        }

        static XmlSchemaComplexType CreateAnyType() 
        {
            XmlSchemaComplexType anyType = new XmlSchemaComplexType(); 
            anyType.IsMixed = true; 
            anyType.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny(); 
            any.MinOccurs = 0;
            any.MaxOccurs = Decimal.MaxValue;
            any.ProcessContents = XmlSchemaContentProcessing.Lax;
            ((XmlSchemaSequence)anyType.Particle).Items.Add(any); 
            anyType.AnyAttribute = new XmlSchemaAnyAttribute();
            return anyType; 
        } 

        static XmlSchemaComplexType CreateAnyElementType() 
        {
            XmlSchemaComplexType anyElementType = new XmlSchemaComplexType();
            anyElementType.IsMixed = false;
            anyElementType.Particle = new XmlSchemaSequence(); 
            XmlSchemaAny any = new XmlSchemaAny();
            any.MinOccurs = 0; 
            any.ProcessContents = XmlSchemaContentProcessing.Lax; 
            ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any);
            return anyElementType; 
        }

        internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
        { 
            xsdType = null;
            hasRoot = true; 
            if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray) 
            {
                string name = null; 
                if (type == Globals.TypeOfXmlElement)
                {
                    xsdType = CreateAnyElementType();
                    name = "XmlElement"; 
                    hasRoot = false;
                } 
                else 
                {
                    xsdType = CreateAnyType(); 
                    name = "ArrayOfXmlNode";
                    hasRoot = true;
                }
                typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type)); 
                return true;
            } 
            typeName = null; 
            return false;
        } 

        static void AddDefaultDatasetType(XmlSchemaSet schemas, string localName, string ns)
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType(); 
            type.Name = localName;
            type.Particle = new XmlSchemaSequence(); 
            XmlSchemaElement schemaRefElement = new XmlSchemaElement(); 
            schemaRefElement.RefName = new XmlQualifiedName(Globals.SchemaLocalName, XmlSchema.Namespace);
            ((XmlSchemaSequence)type.Particle).Items.Add(schemaRefElement); 
            XmlSchemaAny any = new XmlSchemaAny();
            ((XmlSchemaSequence)type.Particle).Items.Add(any);
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas);
            schema.Items.Add(type); 
            schemas.Reprocess(schema);
        } 
 
        static void AddDefaultTypedDatasetType(XmlSchemaSet schemas, XmlSchema datasetSchema, string localName, string ns)
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = localName;
            type.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny(); 
            any.Namespace = (datasetSchema.TargetNamespace == null) ? String.Empty : datasetSchema.TargetNamespace;
            ((XmlSchemaSequence)type.Particle).Items.Add(any); 
            schemas.Add(datasetSchema); 
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas);
            schema.Items.Add(type); 
            schemas.Reprocess(datasetSchema);
            schemas.Reprocess(schema);
        }
 
        XmlSchemaAnnotation GetSchemaAnnotation(XmlQualifiedName annotationQualifiedName, string innerText, XmlSchema schema)
        { 
            XmlSchemaAnnotation annotation = new XmlSchemaAnnotation(); 
            XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
            XmlElement annotationElement = GetAnnotationMarkup(annotationQualifiedName, innerText, schema); 
            appInfo.Markup = new XmlNode[1] { annotationElement };
            annotation.Items.Add(appInfo);
            return annotation;
        } 

        static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes) 
        { 
            if (nodes == null || nodes.Length == 0)
                return null; 
            bool hasAnnotation = false;
            for (int i=0;i 
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        ///  
        [SecurityCritical]
        static XmlQualifiedName anytypeQualifiedName; 
        internal static XmlQualifiedName AnytypeQualifiedName
        {
            /// 
            /// Critical - fetches the critical anytypeQualifiedName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (anytypeQualifiedName == null)
                    anytypeQualifiedName = new XmlQualifiedName(Globals.AnyTypeLocalName, Globals.SchemaNamespace);
                return anytypeQualifiedName;
            } 
        }
 
        ///  
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityCritical]
        static XmlQualifiedName stringQualifiedName;
        internal static XmlQualifiedName StringQualifiedName 
        {
            ///  
            /// Critical - fetches the critical stringQualifiedName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get
            {
                if (stringQualifiedName == null) 
                    stringQualifiedName = new XmlQualifiedName(Globals.StringLocalName, Globals.SchemaNamespace);
                return stringQualifiedName; 
            } 
        }
 
        /// 
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain.
        ///  
        [SecurityCritical]
        static XmlQualifiedName defaultEnumBaseTypeName; 
        internal static XmlQualifiedName DefaultEnumBaseTypeName 
        {
            ///  
            /// Critical - fetches the critical defaultEnumBaseTypeName field
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (defaultEnumBaseTypeName == null) 
                    defaultEnumBaseTypeName = new XmlQualifiedName(Globals.IntLocalName, Globals.SchemaNamespace);
                return defaultEnumBaseTypeName; 
            }
        }

        ///  
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        ///  
        [SecurityCritical]
        static XmlQualifiedName enumerationValueAnnotationName; 
        internal static XmlQualifiedName EnumerationValueAnnotationName
        {
            /// 
            /// Critical - fetches the critical enumerationValueAnnotationName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (enumerationValueAnnotationName == null)
                    enumerationValueAnnotationName = new XmlQualifiedName(Globals.EnumerationValueLocalName, Globals.SerializationNamespace);
                return enumerationValueAnnotationName;
            } 
        }
 
        ///  
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityCritical]
        static XmlQualifiedName surrogateDataAnnotationName;
        internal static XmlQualifiedName SurrogateDataAnnotationName 
        {
            ///  
            /// Critical - fetches the critical surrogateDataAnnotationName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get
            {
                if (surrogateDataAnnotationName == null) 
                    surrogateDataAnnotationName = new XmlQualifiedName(Globals.SurrogateDataLocalName, Globals.SerializationNamespace);
                return surrogateDataAnnotationName; 
            } 
        }
 
        /// 
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain.
        ///  
        [SecurityCritical]
        static XmlQualifiedName defaultValueAnnotation; 
        internal static XmlQualifiedName DefaultValueAnnotation 
        {
            ///  
            /// Critical - fetches the critical defaultValueAnnotation field
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (defaultValueAnnotation == null) 
                    defaultValueAnnotation = new XmlQualifiedName(Globals.DefaultValueLocalName, Globals.SerializationNamespace);
                return defaultValueAnnotation; 
            }
        }

        ///  
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        ///  
        [SecurityCritical]
        static XmlQualifiedName actualTypeAnnotationName; 
        internal static XmlQualifiedName ActualTypeAnnotationName
        {
            /// 
            /// Critical - fetches the critical actualTypeAnnotationName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (actualTypeAnnotationName == null)
                    actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace);
                return actualTypeAnnotationName;
            } 
        }
 
        ///  
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain. 
        /// 
        [SecurityCritical]
        static XmlQualifiedName isDictionaryAnnotationName;
        internal static XmlQualifiedName IsDictionaryAnnotationName 
        {
            ///  
            /// Critical - fetches the critical isDictionaryAnnotationName field 
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get
            {
                if (isDictionaryAnnotationName == null) 
                    isDictionaryAnnotationName = new XmlQualifiedName(Globals.IsDictionaryLocalName, Globals.SerializationNamespace);
                return isDictionaryAnnotationName; 
            } 
        }
 
        /// 
        /// Critical - Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain.
        ///  
        [SecurityCritical]
        static XmlQualifiedName isValueTypeName; 
        internal static XmlQualifiedName IsValueTypeName 
        {
            ///  
            /// Critical - fetches the critical isValueTypeName field
            /// Safe - get-only properties only needs to be protected for write; initialized in getter if null.
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (isValueTypeName == null) 
                    isValueTypeName = new XmlQualifiedName(Globals.IsValueTypeLocalName, Globals.SerializationNamespace);
                return isValueTypeName; 
            }
        }

        // Property is not stored in a local because XmlSchemaAttribute is mutable. 
        // The schema export process should not expose objects that may be modified later.
        internal static XmlSchemaAttribute ISerializableFactoryTypeAttribute 
        { 
            get
            { 
                XmlSchemaAttribute iSerializableFactoryTypeAttribute = new XmlSchemaAttribute();
                iSerializableFactoryTypeAttribute.RefName = new XmlQualifiedName(Globals.ISerializableFactoryTypeLocalName, Globals.SerializationNamespace);
                return iSerializableFactoryTypeAttribute;
            } 
        }
 
        // Property is not stored in a local because XmlSchemaAttribute is mutable. 
        // The schema export process should not expose objects that may be modified later.
        internal static XmlSchemaAttribute RefAttribute 
        {
            get
            {
                XmlSchemaAttribute refAttribute = new XmlSchemaAttribute(); 
                refAttribute.RefName = Globals.RefQualifiedName;
                return refAttribute; 
            } 
        }
 
        // Property is not stored in a local because XmlSchemaAttribute is mutable.
        // The schema export process should not expose objects that may be modified later.
        internal static XmlSchemaAttribute IdAttribute
        { 
            get
            { 
                XmlSchemaAttribute idAttribute = new XmlSchemaAttribute(); 
                idAttribute.RefName = Globals.IdQualifiedName;
                return idAttribute; 
            }
        }
    }
} 


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