XsdDataContractExporter.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.Runtime.Serialization
  5. {
  6. using System;
  7. //using System.ServiceModel.Channels;
  8. using System.Xml;
  9. using System.Xml.Schema;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Reflection;
  13. using System.Diagnostics;
  14. using System.ServiceModel.Diagnostics;
  15. using System.Runtime.Serialization.Diagnostics;
  16. public class XsdDataContractExporter
  17. {
  18. ExportOptions options;
  19. XmlSchemaSet schemas;
  20. DataContractSet dataContractSet;
  21. public XsdDataContractExporter()
  22. {
  23. }
  24. public XsdDataContractExporter(XmlSchemaSet schemas)
  25. {
  26. this.schemas = schemas;
  27. }
  28. public ExportOptions Options
  29. {
  30. get { return options; }
  31. set { options = value; }
  32. }
  33. public XmlSchemaSet Schemas
  34. {
  35. get
  36. {
  37. XmlSchemaSet schemaSet = GetSchemaSet();
  38. SchemaImporter.CompileSchemaSet(schemaSet);
  39. return schemaSet;
  40. }
  41. }
  42. XmlSchemaSet GetSchemaSet()
  43. {
  44. if (schemas == null)
  45. {
  46. schemas = new XmlSchemaSet();
  47. schemas.XmlResolver = null;
  48. }
  49. return schemas;
  50. }
  51. DataContractSet DataContractSet
  52. {
  53. get
  54. {
  55. if (dataContractSet == null)
  56. {
  57. dataContractSet = new DataContractSet((Options == null) ? null : Options.GetSurrogate());
  58. }
  59. return dataContractSet;
  60. }
  61. }
  62. void TraceExportBegin()
  63. {
  64. if (DiagnosticUtility.ShouldTraceInformation)
  65. {
  66. TraceUtility.Trace(TraceEventType.Information, TraceCode.XsdExportBegin, SR.GetString(SR.TraceCodeXsdExportBegin));
  67. }
  68. }
  69. void TraceExportEnd()
  70. {
  71. if (DiagnosticUtility.ShouldTraceInformation)
  72. {
  73. TraceUtility.Trace(TraceEventType.Information, TraceCode.XsdExportEnd, SR.GetString(SR.TraceCodeXsdExportEnd));
  74. }
  75. }
  76. void TraceExportError(Exception exception)
  77. {
  78. if (DiagnosticUtility.ShouldTraceError)
  79. {
  80. TraceUtility.Trace(TraceEventType.Error, TraceCode.XsdExportError, SR.GetString(SR.TraceCodeXsdExportError), null, exception);
  81. }
  82. }
  83. public void Export(ICollection<Assembly> assemblies)
  84. {
  85. if (assemblies == null)
  86. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("assemblies"));
  87. TraceExportBegin();
  88. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  89. try
  90. {
  91. foreach (Assembly assembly in assemblies)
  92. {
  93. if (assembly == null)
  94. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullAssembly, "assemblies")));
  95. Type[] types = assembly.GetTypes();
  96. for (int j = 0; j < types.Length; j++)
  97. CheckAndAddType(types[j]);
  98. }
  99. Export();
  100. }
  101. catch (Exception ex)
  102. {
  103. if (Fx.IsFatal(ex))
  104. {
  105. throw;
  106. }
  107. dataContractSet = oldValue;
  108. TraceExportError(ex);
  109. throw;
  110. }
  111. TraceExportEnd();
  112. }
  113. public void Export(ICollection<Type> types)
  114. {
  115. if (types == null)
  116. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("types"));
  117. TraceExportBegin();
  118. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  119. try
  120. {
  121. foreach (Type type in types)
  122. {
  123. if (type == null)
  124. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullType, "types")));
  125. AddType(type);
  126. }
  127. Export();
  128. }
  129. catch (Exception ex)
  130. {
  131. if (Fx.IsFatal(ex))
  132. {
  133. throw;
  134. }
  135. dataContractSet = oldValue;
  136. TraceExportError(ex);
  137. throw;
  138. }
  139. TraceExportEnd();
  140. }
  141. public void Export(Type type)
  142. {
  143. if (type == null)
  144. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
  145. TraceExportBegin();
  146. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  147. try
  148. {
  149. AddType(type);
  150. Export();
  151. }
  152. catch (Exception ex)
  153. {
  154. if (Fx.IsFatal(ex))
  155. {
  156. throw;
  157. }
  158. dataContractSet = oldValue;
  159. TraceExportError(ex);
  160. throw;
  161. }
  162. TraceExportEnd();
  163. }
  164. public XmlQualifiedName GetSchemaTypeName(Type type)
  165. {
  166. if (type == null)
  167. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
  168. type = GetSurrogatedType(type);
  169. DataContract dataContract = DataContract.GetDataContract(type);
  170. DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
  171. XmlDataContract xmlDataContract = dataContract as XmlDataContract;
  172. if (xmlDataContract != null && xmlDataContract.IsAnonymous)
  173. return XmlQualifiedName.Empty;
  174. return dataContract.StableName;
  175. }
  176. public XmlSchemaType GetSchemaType(Type type)
  177. {
  178. if (type == null)
  179. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
  180. type = GetSurrogatedType(type);
  181. DataContract dataContract = DataContract.GetDataContract(type);
  182. DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
  183. XmlDataContract xmlDataContract = dataContract as XmlDataContract;
  184. if (xmlDataContract != null && xmlDataContract.IsAnonymous)
  185. return xmlDataContract.XsdType;
  186. return null;
  187. }
  188. public XmlQualifiedName GetRootElementName(Type type)
  189. {
  190. if (type == null)
  191. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
  192. type = GetSurrogatedType(type);
  193. DataContract dataContract = DataContract.GetDataContract(type);
  194. DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
  195. if (dataContract.HasRoot)
  196. {
  197. return new XmlQualifiedName(dataContract.TopLevelElementName.Value, dataContract.TopLevelElementNamespace.Value);
  198. }
  199. else
  200. {
  201. return null;
  202. }
  203. }
  204. Type GetSurrogatedType(Type type)
  205. {
  206. IDataContractSurrogate dataContractSurrogate;
  207. if (options != null && (dataContractSurrogate = Options.GetSurrogate()) != null)
  208. type = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, type);
  209. return type;
  210. }
  211. void CheckAndAddType(Type type)
  212. {
  213. type = GetSurrogatedType(type);
  214. if (!type.ContainsGenericParameters && DataContract.IsTypeSerializable(type))
  215. AddType(type);
  216. }
  217. void AddType(Type type)
  218. {
  219. DataContractSet.Add(type);
  220. }
  221. void Export()
  222. {
  223. AddKnownTypes();
  224. SchemaExporter schemaExporter = new SchemaExporter(GetSchemaSet(), DataContractSet);
  225. schemaExporter.Export();
  226. }
  227. void AddKnownTypes()
  228. {
  229. if (Options != null)
  230. {
  231. Collection<Type> knownTypes = Options.KnownTypes;
  232. if (knownTypes != null)
  233. {
  234. for (int i = 0; i < knownTypes.Count; i++)
  235. {
  236. Type type = knownTypes[i];
  237. if (type == null)
  238. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullKnownType)));
  239. AddType(type);
  240. }
  241. }
  242. }
  243. }
  244. public bool CanExport(ICollection<Assembly> assemblies)
  245. {
  246. if (assemblies == null)
  247. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("assemblies"));
  248. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  249. try
  250. {
  251. foreach (Assembly assembly in assemblies)
  252. {
  253. if (assembly == null)
  254. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullAssembly, "assemblies")));
  255. Type[] types = assembly.GetTypes();
  256. for (int j = 0; j < types.Length; j++)
  257. CheckAndAddType(types[j]);
  258. }
  259. AddKnownTypes();
  260. return true;
  261. }
  262. catch (InvalidDataContractException)
  263. {
  264. dataContractSet = oldValue;
  265. return false;
  266. }
  267. catch (Exception ex)
  268. {
  269. if (Fx.IsFatal(ex))
  270. {
  271. throw;
  272. }
  273. dataContractSet = oldValue;
  274. TraceExportError(ex);
  275. throw;
  276. }
  277. }
  278. public bool CanExport(ICollection<Type> types)
  279. {
  280. if (types == null)
  281. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("types"));
  282. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  283. try
  284. {
  285. foreach (Type type in types)
  286. {
  287. if (type == null)
  288. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullType, "types")));
  289. AddType(type);
  290. }
  291. AddKnownTypes();
  292. return true;
  293. }
  294. catch (InvalidDataContractException)
  295. {
  296. dataContractSet = oldValue;
  297. return false;
  298. }
  299. catch (Exception ex)
  300. {
  301. if (Fx.IsFatal(ex))
  302. {
  303. throw;
  304. }
  305. dataContractSet = oldValue;
  306. TraceExportError(ex);
  307. throw;
  308. }
  309. }
  310. public bool CanExport(Type type)
  311. {
  312. if (type == null)
  313. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
  314. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  315. try
  316. {
  317. AddType(type);
  318. AddKnownTypes();
  319. return true;
  320. }
  321. catch (InvalidDataContractException)
  322. {
  323. dataContractSet = oldValue;
  324. return false;
  325. }
  326. catch (Exception ex)
  327. {
  328. if (Fx.IsFatal(ex))
  329. {
  330. throw;
  331. }
  332. dataContractSet = oldValue;
  333. TraceExportError(ex);
  334. throw;
  335. }
  336. }
  337. #if USE_REFEMIT
  338. //Returns warnings
  339. public IList<string> GenerateCode(IList<Assembly> assemblies)
  340. {
  341. if (assemblies == null)
  342. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("assemblies"));
  343. List<string> warnings = new List<string>();
  344. DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
  345. try
  346. {
  347. for (int i=0; i < assemblies.Count; i++)
  348. {
  349. Assembly assembly = assemblies[i];
  350. if (assembly == null)
  351. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotExportNullAssembly, "assemblies")));
  352. Type[] types = assembly.GetTypes();
  353. for (int j=0; j < types.Length; j++)
  354. {
  355. try
  356. {
  357. CheckAndAddType(types[j]);
  358. }
  359. catch (Exception ex)
  360. {
  361. warnings.Add("Error on exporting Type " + DataContract.GetClrTypeFullName(types[j]) + ". " + ex.Message);
  362. }
  363. }
  364. }
  365. foreach (KeyValuePair<XmlQualifiedName, DataContract> pair in dataContractSet)
  366. {
  367. DataContract dataContract = pair.Value;
  368. if (dataContract is ClassDataContract)
  369. {
  370. try
  371. {
  372. XmlFormatClassWriterDelegate writerMethod = ((ClassDataContract)dataContract).XmlFormatWriterDelegate;
  373. XmlFormatClassReaderDelegate readerMethod = ((ClassDataContract)dataContract).XmlFormatReaderDelegate;
  374. }
  375. catch (Exception ex)
  376. {
  377. warnings.Add("Error on exporting Type " + dataContract.UnderlyingType + ". " + ex.Message);
  378. }
  379. }
  380. else if (dataContract is CollectionDataContract)
  381. {
  382. try
  383. {
  384. XmlFormatCollectionWriterDelegate writerMethod = ((CollectionDataContract)dataContract).XmlFormatWriterDelegate;
  385. XmlFormatCollectionReaderDelegate readerMethod = ((CollectionDataContract)dataContract).XmlFormatReaderDelegate;
  386. }
  387. catch (Exception ex)
  388. {
  389. warnings.Add("Error on exporting Type " + dataContract.UnderlyingType + ". " + ex.Message);
  390. }
  391. }
  392. }
  393. return warnings;
  394. }
  395. catch (Exception ex)
  396. {
  397. if (Fx.IsFatal(ex))
  398. {
  399. throw;
  400. }
  401. dataContractSet = oldValue;
  402. TraceExportError(ex);
  403. throw;
  404. }
  405. }
  406. #endif
  407. }
  408. }