SchemaExporter_mobile.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. namespace System.Runtime.Serialization
  2. {
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.Diagnostics;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.Reflection;
  11. using System.Runtime.Diagnostics;
  12. using System.ServiceModel.Diagnostics;
  13. using System.Security;
  14. using System.Xml;
  15. using System.Xml.Schema;
  16. using System.Xml.Serialization;
  17. using System.Runtime.Serialization.Diagnostics;
  18. class SchemaExporter
  19. {
  20. internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
  21. {
  22. if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot))
  23. return;
  24. XmlSchemaSet schemas = new XmlSchemaSet();
  25. schemas.XmlResolver = null;
  26. InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
  27. if (stableName.Name == null || stableName.Name.Length == 0)
  28. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
  29. }
  30. internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
  31. {
  32. xsdType = null;
  33. hasRoot = true;
  34. if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
  35. {
  36. string name = null;
  37. if (type == Globals.TypeOfXmlElement)
  38. {
  39. xsdType = CreateAnyElementType();
  40. name = "XmlElement";
  41. hasRoot = false;
  42. }
  43. else
  44. {
  45. xsdType = CreateAnyType();
  46. name = "ArrayOfXmlNode";
  47. hasRoot = true;
  48. }
  49. typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
  50. return true;
  51. }
  52. typeName = null;
  53. return false;
  54. }
  55. static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
  56. {
  57. xsdType = null;
  58. hasRoot = true;
  59. object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
  60. if (attrs == null || attrs.Length == 0)
  61. {
  62. stableName = DataContract.GetDefaultStableName(clrType);
  63. return false;
  64. }
  65. XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
  66. if (provider.IsAny)
  67. {
  68. xsdType = CreateAnyElementType();
  69. hasRoot = false;
  70. }
  71. string methodName = provider.MethodName;
  72. if (methodName == null || methodName.Length == 0)
  73. {
  74. if (!provider.IsAny)
  75. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType))));
  76. stableName = DataContract.GetDefaultStableName(clrType);
  77. }
  78. else
  79. {
  80. MethodInfo getMethod = clrType.GetMethod(methodName, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
  81. if (getMethod == null)
  82. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
  83. if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType)))
  84. 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))));
  85. object typeInfo = getMethod.Invoke(null, new object[] { schemas });
  86. if (provider.IsAny)
  87. {
  88. if (typeInfo != null)
  89. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName)));
  90. stableName = DataContract.GetDefaultStableName(clrType);
  91. }
  92. else if (typeInfo == null)
  93. {
  94. xsdType = CreateAnyElementType();
  95. hasRoot = false;
  96. stableName = DataContract.GetDefaultStableName(clrType);
  97. }
  98. else
  99. {
  100. XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
  101. if (providerXsdType != null)
  102. {
  103. string typeName = providerXsdType.Name;
  104. string typeNs = null;
  105. if (typeName == null || typeName.Length == 0)
  106. {
  107. DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs);
  108. stableName = new XmlQualifiedName(typeName, typeNs);
  109. providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
  110. xsdType = providerXsdType;
  111. }
  112. else
  113. {
  114. foreach (XmlSchema schema in schemas.Schemas())
  115. {
  116. foreach (XmlSchemaObject schemaItem in schema.Items)
  117. {
  118. if ((object)schemaItem == (object)providerXsdType)
  119. {
  120. typeNs = schema.TargetNamespace;
  121. if (typeNs == null)
  122. typeNs = String.Empty;
  123. break;
  124. }
  125. }
  126. if (typeNs != null)
  127. break;
  128. }
  129. if (typeNs == null)
  130. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
  131. stableName = new XmlQualifiedName(typeName, typeNs);
  132. }
  133. }
  134. else
  135. stableName = (XmlQualifiedName)typeInfo;
  136. }
  137. }
  138. return true;
  139. }
  140. static XmlSchemaComplexType CreateAnyElementType()
  141. {
  142. XmlSchemaComplexType anyElementType = new XmlSchemaComplexType();
  143. anyElementType.IsMixed = false;
  144. anyElementType.Particle = new XmlSchemaSequence();
  145. XmlSchemaAny any = new XmlSchemaAny();
  146. any.MinOccurs = 0;
  147. any.ProcessContents = XmlSchemaContentProcessing.Lax;
  148. ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any);
  149. return anyElementType;
  150. }
  151. static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes)
  152. {
  153. if (nodes == null || nodes.Length == 0)
  154. return null;
  155. bool hasAnnotation = false;
  156. for (int i = 0; i < nodes.Length; i++)
  157. if (nodes[i] != null)
  158. {
  159. hasAnnotation = true;
  160. break;
  161. }
  162. if (!hasAnnotation)
  163. return null;
  164. XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
  165. XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
  166. annotation.Items.Add(appInfo);
  167. appInfo.Markup = nodes;
  168. return annotation;
  169. }
  170. static XmlSchemaComplexType CreateAnyType()
  171. {
  172. XmlSchemaComplexType anyType = new XmlSchemaComplexType();
  173. anyType.IsMixed = true;
  174. anyType.Particle = new XmlSchemaSequence();
  175. XmlSchemaAny any = new XmlSchemaAny();
  176. any.MinOccurs = 0;
  177. any.MaxOccurs = Decimal.MaxValue;
  178. any.ProcessContents = XmlSchemaContentProcessing.Lax;
  179. ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
  180. anyType.AnyAttribute = new XmlSchemaAnyAttribute();
  181. return anyType;
  182. }
  183. static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc)
  184. {
  185. XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
  186. XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
  187. nameAttribute.Value = typeName.Name;
  188. actualTypeElement.Attributes.Append(nameAttribute);
  189. XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
  190. nsAttribute.Value = typeName.Namespace;
  191. actualTypeElement.Attributes.Append(nsAttribute);
  192. return actualTypeElement;
  193. }
  194. static XmlQualifiedName actualTypeAnnotationName;
  195. internal static XmlQualifiedName ActualTypeAnnotationName
  196. {
  197. get
  198. {
  199. if (actualTypeAnnotationName == null)
  200. actualTypeAnnotationName = new XmlQualifiedName(Globals.ActualTypeLocalName, Globals.SerializationNamespace);
  201. return actualTypeAnnotationName;
  202. }
  203. }
  204. }
  205. }