| File: FrameworkFork\System.Runtime.Serialization\System\Runtime\Serialization\SchemaExporter.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace System.Runtime.Serialization { using System; using System.Linq; using Microsoft.Xml; using Microsoft.Xml.Schema; using Microsoft.Xml.Serialization; using System.Reflection; using System.Security; internal class SchemaExporter { 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 = 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(string.Format(SRSerialization.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type)))); } internal static long GetDefaultEnumValue(bool isFlags, int index) { return isFlags ? (long)Math.Pow(2, index) : index; } private static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot) { xsdType = null; hasRoot = true; object[] attrs = clrType.GetTypeInfo().GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false).ToArray(); 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(string.Format(SRSerialization.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); stableName = DataContract.GetDefaultStableName(clrType); } else { MethodInfo getMethod = clrType.GetMethod(methodName, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, new Type[] { typeof(XmlSchemaSet) }); if (getMethod == null) throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(string.Format(SRSerialization.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName))); if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType))) throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(string.Format(SRSerialization.InvalidReturnTypeOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName, DataContract.GetClrTypeFullName(getMethod.ReturnType), DataContract.GetClrTypeFullName(Globals.TypeOfXmlQualifiedName)))); object typeInfo = getMethod.Invoke(null, new object[] { schemas }); if (provider.IsAny) { if (typeInfo != null) throw /*System.Runtime.Serialization.*/DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(string.Format(SRSerialization.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName))); stableName = DataContract.GetDefaultStableName(clrType); } else if (typeInfo == null) { xsdType = CreateAnyElementType(); hasRoot = false; stableName = DataContract.GetDefaultStableName(clrType); } else { stableName = (XmlQualifiedName)typeInfo; } } return true; } private 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; } private 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; } 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; } // Property is not stored in a local because XmlSchemaAny is mutable. // The schema export process should not expose objects that may be modified later. internal static XmlSchemaAny ISerializableWildcardElement { get { XmlSchemaAny iSerializableWildcardElement = new XmlSchemaAny(); iSerializableWildcardElement.MinOccurs = 0; iSerializableWildcardElement.MaxOccursString = Globals.OccursUnbounded; iSerializableWildcardElement.Namespace = "##local"; iSerializableWildcardElement.ProcessContents = XmlSchemaContentProcessing.Skip; return iSerializableWildcardElement; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_anytypeQualifiedName; internal static XmlQualifiedName AnytypeQualifiedName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical anytypeQualifiedName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_anytypeQualifiedName == null) s_anytypeQualifiedName = new XmlQualifiedName(Globals.AnyTypeLocalName, Globals.SchemaNamespace); return s_anytypeQualifiedName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_stringQualifiedName; internal static XmlQualifiedName StringQualifiedName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical stringQualifiedName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_stringQualifiedName == null) s_stringQualifiedName = new XmlQualifiedName(Globals.StringLocalName, Globals.SchemaNamespace); return s_stringQualifiedName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_defaultEnumBaseTypeName; internal static XmlQualifiedName DefaultEnumBaseTypeName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical defaultEnumBaseTypeName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_defaultEnumBaseTypeName == null) s_defaultEnumBaseTypeName = new XmlQualifiedName(Globals.IntLocalName, Globals.SchemaNamespace); return s_defaultEnumBaseTypeName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_enumerationValueAnnotationName; internal static XmlQualifiedName EnumerationValueAnnotationName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical enumerationValueAnnotationName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_enumerationValueAnnotationName == null) s_enumerationValueAnnotationName = new XmlQualifiedName(Globals.EnumerationValueLocalName, Globals.SerializationNamespace); return s_enumerationValueAnnotationName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_surrogateDataAnnotationName; internal static XmlQualifiedName SurrogateDataAnnotationName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical surrogateDataAnnotationName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_surrogateDataAnnotationName == null) s_surrogateDataAnnotationName = new XmlQualifiedName(Globals.SurrogateDataLocalName, Globals.SerializationNamespace); return s_surrogateDataAnnotationName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_defaultValueAnnotation; internal static XmlQualifiedName DefaultValueAnnotation { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical defaultValueAnnotation field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_defaultValueAnnotation == null) s_defaultValueAnnotation = new XmlQualifiedName(Globals.DefaultValueLocalName, Globals.SerializationNamespace); return s_defaultValueAnnotation; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_actualTypeAnnotationName; internal static XmlQualifiedName ActualTypeAnnotationName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical actualTypeAnnotationName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_actualTypeAnnotationName == null) s_actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace); return s_actualTypeAnnotationName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_isDictionaryAnnotationName; internal static XmlQualifiedName IsDictionaryAnnotationName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical isDictionaryAnnotationName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_isDictionaryAnnotationName == null) s_isDictionaryAnnotationName = new XmlQualifiedName(Globals.IsDictionaryLocalName, Globals.SerializationNamespace); return s_isDictionaryAnnotationName; } } // TODO: [Fx.Tag.SecurityNote(Critical = "Static fields are marked SecurityCritical or readonly to prevent" // + " data from being modified or leaked to other components in appdomain.")] [SecurityCritical] private static XmlQualifiedName s_isValueTypeName; internal static XmlQualifiedName IsValueTypeName { // TODO: [Fx.Tag.SecurityNote(Critical = "Fetches the critical isValueTypeName field.", // Safe = "Get-only properties only needs to be protected for write; initialized in getter if null.")] [SecuritySafeCritical] get { if (s_isValueTypeName == null) s_isValueTypeName = new XmlQualifiedName(Globals.IsValueTypeLocalName, Globals.SerializationNamespace); return s_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; } } } }