/OxmLibraryServiceExtensions/WsdlDataTypeNormalizer.cs

# · C# · 243 lines · 221 code · 22 blank · 0 comment · 37 complexity · dd042f53e757ad1e7fbf629e3874d8dd MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using OxmLibrary.CodeGeneration;
  6. using System.CodeDom;
  7. using OxmLibrary;
  8. using System.IO;
  9. namespace OxmLibrary.WSDLServiceExtensions
  10. {
  11. public class WsdlDataTypeNormalizer
  12. {
  13. private GenerationConfiguration options;
  14. private OxmGenerator3 generator;
  15. private CodeNamespaceCollection namespaces;
  16. public List<CodeTypeDeclaration> TypesToGenerate { get; private set; }
  17. private TextWriter currentOutput;
  18. public WsdlDataTypeNormalizer(GenerationConfiguration config, OxmGenerator3 generator, CodeNamespaceCollection namespaces)
  19. {
  20. this.options = config;
  21. this.generator = generator;
  22. this.namespaces = namespaces;
  23. TypesToGenerate = new List<CodeTypeDeclaration>();
  24. }
  25. public void AssignWriter(TextWriter writer)
  26. {
  27. this.currentOutput = writer;
  28. }
  29. public string NormalizeDataTypes(CodeTypeReference typeReference, bool AsMethodSignature)
  30. {
  31. return NormalizeDataTypes(typeReference.BaseType, AsMethodSignature);
  32. }
  33. public string NormalizeDataTypes(string typeName, bool AsMethodSignature)
  34. {
  35. string result;
  36. if (typeName.EndsWith("oxm"))
  37. return typeName;
  38. if (TryToGetFromGenerator(typeName, AsMethodSignature, out result))
  39. return generator.NormalizeDataTypeToSystem(result);
  40. if (TryToGetFromKnownTypes(typeName, AsMethodSignature, out result))
  41. return result.EndsWith("oxm") ? result : result + "oxm";
  42. return generator.NormalizeDataType(typeName);
  43. }
  44. public List<CodeParameterDeclarationExpression> GetMethodSignatureParameters(CodeParameterDeclarationExpression previous)
  45. {
  46. List<CodeParameterDeclarationExpression> result = new List<CodeParameterDeclarationExpression>();
  47. var typeName = previous.Type.BaseType;
  48. if (TryToGenerateFromGenerator(previous, result))
  49. return result;
  50. if (TryToGenerateFromKnownTypes(previous, result))
  51. return result;
  52. result.Add(previous);
  53. return result;
  54. }
  55. private bool TryToGenerateFromKnownTypes(CodeParameterDeclarationExpression typeName, List<CodeParameterDeclarationExpression> result)
  56. {
  57. var type = SearchTypes(typeName.Type.BaseType, namespaces);
  58. if (type != null)
  59. {
  60. AddToGeneratedTypes(type);
  61. result.Add(typeName);
  62. return true;
  63. }
  64. return false;
  65. }
  66. private void AddToGeneratedTypes(CodeTypeDeclaration type)
  67. {
  68. if (!TypesToGenerate.Contains(type))
  69. {
  70. TypesToGenerate.Add(type);
  71. FixType(type, namespaces);
  72. }
  73. }
  74. private void FixType(CodeTypeDeclaration generatedTypes, CodeNamespaceCollection collection)
  75. {
  76. var TypesToRemove = new List<CodeMemberField>();
  77. var properties = generatedTypes.Members.OfType<CodeMemberProperty>().ToList();
  78. ClassDescriptor cd;
  79. foreach (var field in generatedTypes.Members.OfType<CodeMemberField>())
  80. {
  81. if (properties.Any(a => field.Name == a.Name + "Field"))
  82. {
  83. TypesToRemove.Add(field);
  84. continue;
  85. }
  86. var type = field.Type.BaseType;
  87. if (generator.TryGetClass(field.Name, out cd))
  88. {
  89. field.Type.BaseType = cd.ClassName;
  90. continue;
  91. }
  92. var theType = SearchTypes(type, collection);
  93. if (theType != null)
  94. {
  95. AddToGeneratedTypes(theType);
  96. if (!field.Type.BaseType.EndsWith("oxm"))
  97. field.Type.BaseType += "oxm";
  98. }
  99. }
  100. foreach (var field in generatedTypes.Members.OfType<CodeMemberProperty>())
  101. {
  102. var type = field.Type.BaseType;
  103. if (generator.TryGetClass(field.Name, out cd))
  104. {
  105. field.Type.BaseType = cd.ClassName;
  106. continue;
  107. }
  108. var theType = SearchTypes(type, collection);
  109. if (theType != null)
  110. {
  111. AddToGeneratedTypes(theType);
  112. if (!field.Type.BaseType.EndsWith("oxm"))
  113. field.Type.BaseType += "oxm";
  114. }
  115. }
  116. TypesToRemove.ForEach(ttr => generatedTypes.Members.Remove(ttr));
  117. foreach (var constructor in generatedTypes.Members.OfType<CodeConstructor>())
  118. {
  119. if (constructor.Parameters.Count > 0)
  120. {
  121. var parametersToRemove = new List<CodeParameterDeclarationExpression>();
  122. foreach (var parameter in constructor.Parameters.OfType<CodeParameterDeclarationExpression>())
  123. {
  124. var type = parameter.Type.BaseType;
  125. var theType = SearchTypes(type, collection);
  126. if (theType != null)
  127. {
  128. var typeName = NormalizeDataTypes(theType.Name, false);
  129. if (!parameter.Type.BaseType.EndsWith("oxm"))
  130. parameter.Type.BaseType += "oxm";
  131. }
  132. }
  133. parametersToRemove.ForEach(pm => constructor.Parameters.Remove(pm));
  134. }
  135. }
  136. }
  137. private bool TryToGenerateFromGenerator(CodeParameterDeclarationExpression typeName, List<CodeParameterDeclarationExpression> result)
  138. {
  139. ClassDescriptor descriptor;
  140. var probableClassName = typeName.Type.BaseType.Length > 7 ? typeName.Type.BaseType.Substring(0, typeName.Type.BaseType.Length - 7) : typeName.Type.BaseType;
  141. if (!generator.TryGetClass(typeName.Type.BaseType, out descriptor) && !generator.TryGetClass(probableClassName, out descriptor))
  142. {
  143. result = null;
  144. return false;
  145. }
  146. if (options.GetAdditionalParameter<bool>("MessageContract"))
  147. {
  148. result.Add(typeName);
  149. typeName.Type.BaseType = descriptor.OxmName;
  150. return true;
  151. }
  152. else if (descriptor.Count > 0)
  153. {
  154. foreach (var item in descriptor.Where(a => !a.Value.DefaultValueOnly))
  155. {
  156. result.Add(item.Value.AsCodeParameter(options.CustomCollectionType, FieldDirection.In, generator.NormalizeDataTypeToSystem));
  157. }
  158. return true;
  159. }
  160. return true;
  161. }
  162. private bool TryToGetFromKnownTypes(string typeName, bool AsMethodSignature, out string result)
  163. {
  164. var type = SearchTypes(typeName, namespaces);
  165. if (type != null)
  166. {
  167. AddToGeneratedTypes(type);
  168. result = type.Name;
  169. return true;
  170. }
  171. result = null;
  172. return false;
  173. }
  174. private CodeTypeDeclaration SearchTypes(string type, CodeNamespaceCollection collection)
  175. {
  176. foreach (CodeNamespace codeNamespace in collection)
  177. {
  178. foreach (CodeTypeDeclaration typeDeclartion in codeNamespace.Types)
  179. {
  180. if (typeDeclartion.Name == type)
  181. {
  182. return typeDeclartion;
  183. }
  184. }
  185. }
  186. return null;
  187. }
  188. private bool TryToGetFromGenerator(string typeName, bool AsMethodSignature, out string result)
  189. {
  190. ClassDescriptor descriptor;
  191. if (typeName.EndsWith("oxm")) typeName = typeName.Substring(0, typeName.Length - 3);
  192. if (!generator.TryGetClass(typeName, out descriptor))
  193. {
  194. result = null;
  195. return false;
  196. }
  197. if (options.GetAdditionalParameter<bool>("MessageContract"))
  198. {
  199. result = descriptor.OxmName;
  200. return true;
  201. }
  202. else if (descriptor.Count > 1)
  203. {
  204. if (AsMethodSignature)
  205. {
  206. StringWriter writer = new StringWriter();
  207. generator.CodeGenerator.GetClassMethodSignature(writer, descriptor);
  208. result = writer.GetStringBuilder().ToString();
  209. return true;
  210. }
  211. else
  212. {
  213. result = generator.NormalizeDataTypeToSystem(descriptor.First(a => !a.Value.DefaultValueOnly).Value.PType);
  214. return true;
  215. }
  216. }
  217. result = string.Empty;
  218. return true;
  219. }
  220. }
  221. }