SchemaExporter_mobile.cs 10 KB

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