XsdDataContractImporter.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.Runtime.Serialization
  5. {
  6. using System;
  7. using System.CodeDom;
  8. using System.Collections.Generic;
  9. using System.Diagnostics;
  10. using System.Security;
  11. using System.ServiceModel.Diagnostics;
  12. using System.Xml;
  13. using System.Xml.Schema;
  14. using System.Runtime.Serialization.Diagnostics;
  15. using System.Security.Permissions;
  16. public class XsdDataContractImporter
  17. {
  18. ImportOptions options;
  19. CodeCompileUnit codeCompileUnit;
  20. DataContractSet dataContractSet;
  21. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
  22. + " data from being modified or leaked to other components in appdomain.")]
  23. static readonly XmlQualifiedName[] emptyTypeNameArray = new XmlQualifiedName[0];
  24. [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
  25. + " data from being modified or leaked to other components in appdomain.")]
  26. static readonly XmlSchemaElement[] emptyElementArray = new XmlSchemaElement[0];
  27. XmlQualifiedName[] singleTypeNameArray;
  28. XmlSchemaElement[] singleElementArray;
  29. public XsdDataContractImporter()
  30. {
  31. }
  32. public XsdDataContractImporter(CodeCompileUnit codeCompileUnit)
  33. {
  34. this.codeCompileUnit = codeCompileUnit;
  35. }
  36. public ImportOptions Options
  37. {
  38. get { return options; }
  39. set { options = value; }
  40. }
  41. public CodeCompileUnit CodeCompileUnit
  42. {
  43. get
  44. {
  45. return GetCodeCompileUnit();
  46. }
  47. }
  48. CodeCompileUnit GetCodeCompileUnit()
  49. {
  50. if (codeCompileUnit == null)
  51. codeCompileUnit = new CodeCompileUnit();
  52. return codeCompileUnit;
  53. }
  54. DataContractSet DataContractSet
  55. {
  56. get
  57. {
  58. if (dataContractSet == null)
  59. {
  60. dataContractSet = Options == null ? new DataContractSet(null, null, null) :
  61. new DataContractSet(Options.DataContractSurrogate, Options.ReferencedTypes, Options.ReferencedCollectionTypes);
  62. }
  63. return dataContractSet;
  64. }
  65. }
  66. public void Import(XmlSchemaSet schemas)
  67. {
  68. if (schemas == null)
  69. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  70. InternalImport(schemas, null, null, null);
  71. }
  72. public void Import(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames)
  73. {
  74. if (schemas == null)
  75. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  76. if (typeNames == null)
  77. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeNames"));
  78. InternalImport(schemas, typeNames, emptyElementArray, emptyTypeNameArray);
  79. }
  80. public void Import(XmlSchemaSet schemas, XmlQualifiedName typeName)
  81. {
  82. if (schemas == null)
  83. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  84. if (typeName == null)
  85. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeName"));
  86. SingleTypeNameArray[0] = typeName;
  87. InternalImport(schemas, SingleTypeNameArray, emptyElementArray, emptyTypeNameArray);
  88. }
  89. public XmlQualifiedName Import(XmlSchemaSet schemas, XmlSchemaElement element)
  90. {
  91. if (schemas == null)
  92. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  93. if (element == null)
  94. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("element"));
  95. SingleTypeNameArray[0] = null;
  96. SingleElementArray[0] = element;
  97. InternalImport(schemas, emptyTypeNameArray, SingleElementArray, SingleTypeNameArray/*filled on return*/);
  98. return SingleTypeNameArray[0];
  99. }
  100. public bool CanImport(XmlSchemaSet schemas)
  101. {
  102. if (schemas == null)
  103. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  104. return InternalCanImport(schemas, null, null, null);
  105. }
  106. public bool CanImport(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames)
  107. {
  108. if (schemas == null)
  109. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  110. if (typeNames == null)
  111. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeNames"));
  112. return InternalCanImport(schemas, typeNames, emptyElementArray, emptyTypeNameArray);
  113. }
  114. public bool CanImport(XmlSchemaSet schemas, XmlQualifiedName typeName)
  115. {
  116. if (schemas == null)
  117. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  118. if (typeName == null)
  119. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeName"));
  120. return InternalCanImport(schemas, new XmlQualifiedName[] { typeName }, emptyElementArray, emptyTypeNameArray);
  121. }
  122. public bool CanImport(XmlSchemaSet schemas, XmlSchemaElement element)
  123. {
  124. if (schemas == null)
  125. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("schemas"));
  126. if (element == null)
  127. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("element"));
  128. SingleTypeNameArray[0] = null;
  129. SingleElementArray[0] = element;
  130. return InternalCanImport(schemas, emptyTypeNameArray, SingleElementArray, SingleTypeNameArray);
  131. }
  132. public CodeTypeReference GetCodeTypeReference(XmlQualifiedName typeName)
  133. {
  134. DataContract dataContract = FindDataContract(typeName);
  135. CodeExporter codeExporter = new CodeExporter(DataContractSet, Options, GetCodeCompileUnit());
  136. return codeExporter.GetCodeTypeReference(dataContract);
  137. }
  138. public CodeTypeReference GetCodeTypeReference(XmlQualifiedName typeName, XmlSchemaElement element)
  139. {
  140. if (element == null)
  141. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("element"));
  142. if (typeName == null)
  143. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeName"));
  144. DataContract dataContract = FindDataContract(typeName);
  145. CodeExporter codeExporter = new CodeExporter(DataContractSet, Options, GetCodeCompileUnit());
  146. #pragma warning suppress 56506 // Code Exporter will never be null
  147. return codeExporter.GetElementTypeReference(dataContract, element.IsNillable);
  148. }
  149. internal DataContract FindDataContract(XmlQualifiedName typeName)
  150. {
  151. if (typeName == null)
  152. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeName"));
  153. DataContract dataContract = DataContract.GetBuiltInDataContract(typeName.Name, typeName.Namespace);
  154. if (dataContract == null)
  155. {
  156. dataContract = DataContractSet[typeName];
  157. if (dataContract == null)
  158. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TypeHasNotBeenImported, typeName.Name, typeName.Namespace)));
  159. }
  160. return dataContract;
  161. }
  162. public ICollection<CodeTypeReference> GetKnownTypeReferences(XmlQualifiedName typeName)
  163. {
  164. if (typeName == null)
  165. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("typeName"));
  166. DataContract dataContract = DataContract.GetBuiltInDataContract(typeName.Name, typeName.Namespace);
  167. if (dataContract == null)
  168. {
  169. dataContract = DataContractSet[typeName];
  170. if (dataContract == null)
  171. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TypeHasNotBeenImported, typeName.Name, typeName.Namespace)));
  172. }
  173. CodeExporter codeExporter = new CodeExporter(DataContractSet, Options, GetCodeCompileUnit());
  174. return codeExporter.GetKnownTypeReferences(dataContract);
  175. }
  176. XmlQualifiedName[] SingleTypeNameArray
  177. {
  178. get
  179. {
  180. if (singleTypeNameArray == null)
  181. singleTypeNameArray = new XmlQualifiedName[1];
  182. return singleTypeNameArray;
  183. }
  184. }
  185. XmlSchemaElement[] SingleElementArray
  186. {
  187. get
  188. {
  189. if (singleElementArray == null)
  190. singleElementArray = new XmlSchemaElement[1];
  191. return singleElementArray;
  192. }
  193. }
  194. [Fx.Tag.SecurityNote(Critical = "Critical because it calls the security critical method CodeExporter.Export(..).",
  195. Safe = "Safe because it does a Demand for FullTrust.")]
  196. [SecuritySafeCritical]
  197. [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
  198. void InternalImport(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames, ICollection<XmlSchemaElement> elements, XmlQualifiedName[] elementTypeNames/*filled on return*/)
  199. {
  200. if (DiagnosticUtility.ShouldTraceInformation)
  201. {
  202. TraceUtility.Trace(TraceEventType.Information, TraceCode.XsdImportBegin, SR.GetString(SR.TraceCodeXsdImportBegin));
  203. }
  204. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  205. try
  206. {
  207. SchemaImporter schemaImporter = new SchemaImporter(schemas, typeNames, elements, elementTypeNames/*filled on return*/, DataContractSet, ImportXmlDataType);
  208. schemaImporter.Import();
  209. CodeExporter codeExporter = new CodeExporter(DataContractSet, Options, GetCodeCompileUnit());
  210. codeExporter.Export();
  211. }
  212. catch (Exception ex)
  213. {
  214. if (Fx.IsFatal(ex))
  215. {
  216. throw;
  217. }
  218. dataContractSet = oldValue;
  219. TraceImportError(ex);
  220. throw;
  221. }
  222. if (DiagnosticUtility.ShouldTraceInformation)
  223. {
  224. TraceUtility.Trace(TraceEventType.Information, TraceCode.XsdImportEnd, SR.GetString(SR.TraceCodeXsdImportEnd));
  225. }
  226. }
  227. bool ImportXmlDataType
  228. {
  229. get
  230. {
  231. return this.Options == null ? false : this.Options.ImportXmlType;
  232. }
  233. }
  234. void TraceImportError(Exception exception)
  235. {
  236. if (DiagnosticUtility.ShouldTraceError)
  237. {
  238. TraceUtility.Trace(TraceEventType.Error, TraceCode.XsdImportError, SR.GetString(SR.TraceCodeXsdImportError), null, exception);
  239. }
  240. }
  241. bool InternalCanImport(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames, ICollection<XmlSchemaElement> elements, XmlQualifiedName[] elementTypeNames)
  242. {
  243. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  244. try
  245. {
  246. SchemaImporter schemaImporter = new SchemaImporter(schemas, typeNames, elements, elementTypeNames, DataContractSet, ImportXmlDataType);
  247. schemaImporter.Import();
  248. return true;
  249. }
  250. catch (InvalidDataContractException)
  251. {
  252. dataContractSet = oldValue;
  253. return false;
  254. }
  255. catch (Exception ex)
  256. {
  257. if (Fx.IsFatal(ex))
  258. {
  259. throw;
  260. }
  261. dataContractSet = oldValue;
  262. TraceImportError(ex);
  263. throw;
  264. }
  265. }
  266. }
  267. }