The Labs \ Source Viewer \ SSCLI \ System.Xml.Serialization \ SoapCodeExporter

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SoapCodeExporter.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">ElenaK</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Serialization
  17. {
  18.    
  19.     using System;
  20.     using System.Collections;
  21.     using System.IO;
  22.     using System.ComponentModel;
  23.     using System.Xml.Schema;
  24.     using System.CodeDom;
  25.     using System.CodeDom.Compiler;
  26.     using System.Reflection;
  27.     using System.Diagnostics;
  28.     using System.Xml;
  29.     using System.Security.Permissions;
  30.    
  31.     /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter"]/*' />
  32.     /// <internalonly/>
  33.     /// <devdoc>
  34.     /// <para>[To be supplied.]</para>
  35.     /// </devdoc>
  36.     public class SoapCodeExporter : CodeExporter
  37.     {
  38.        
  39.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter"]/*' />
  40.         /// <devdoc>
  41.         /// <para>[To be supplied.]</para>
  42.         /// </devdoc>
  43.         public SoapCodeExporter(CodeNamespace codeNamespace) : base(codeNamespace, null, null, CodeGenerationOptions.GenerateProperties, null)
  44.         {
  45.         }
  46.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter1"]/*' />
  47.         /// <devdoc>
  48.         /// <para>[To be supplied.]</para>
  49.         /// </devdoc>
  50.         public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit) : base(codeNamespace, codeCompileUnit, null, CodeGenerationOptions.GenerateProperties, null)
  51.         {
  52.         }
  53.        
  54.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter2"]/*' />
  55.         /// <devdoc>
  56.         /// <para>[To be supplied.]</para>
  57.         /// </devdoc>
  58.         public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options) : base(codeNamespace, codeCompileUnit, null, CodeGenerationOptions.GenerateProperties, null)
  59.         {
  60.         }
  61.        
  62.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter3"]/*' />
  63.         /// <devdoc>
  64.         /// <para>[To be supplied.]</para>
  65.         /// </devdoc>
  66.         public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeGenerationOptions options, Hashtable mappings) : base(codeNamespace, codeCompileUnit, null, options, mappings)
  67.         {
  68.         }
  69.        
  70.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter4"]/*' />
  71.         /// <devdoc>
  72.         /// <para>[To be supplied.]</para>
  73.         /// </devdoc>
  74.         public SoapCodeExporter(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, CodeDomProvider codeProvider, CodeGenerationOptions options, Hashtable mappings) : base(codeNamespace, codeCompileUnit, codeProvider, options, mappings)
  75.         {
  76.         }
  77.        
  78.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportTypeMapping"]/*' />
  79.         /// <devdoc>
  80.         /// <para>[To be supplied.]</para>
  81.         /// </devdoc>
  82.         public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping)
  83.         {
  84.             xmlTypeMapping.CheckShallow();
  85.             CheckScope(xmlTypeMapping.Scope);
  86.             ExportElement(xmlTypeMapping.Accessor);
  87.         }
  88.        
  89.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportMembersMapping"]/*' />
  90.         /// <devdoc>
  91.         /// <para>[To be supplied.]</para>
  92.         /// </devdoc>
  93.         public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping)
  94.         {
  95.             xmlMembersMapping.CheckShallow();
  96.             CheckScope(xmlMembersMapping.Scope);
  97.             for (int i = 0; i < xmlMembersMapping.Count; i++) {
  98.                 ExportElement((ElementAccessor)xmlMembersMapping[i].Accessor);
  99.             }
  100.         }
  101.        
  102.         void ExportElement(ElementAccessor element)
  103.         {
  104.             ExportType(element.Mapping);
  105.         }
  106.        
  107.         void ExportType(TypeMapping mapping)
  108.         {
  109.             if (mapping.IsReference)
  110.                 return;
  111.             if (ExportedMappings[mapping] == null) {
  112.                 CodeTypeDeclaration codeClass = null;
  113.                 ExportedMappings.Add(mapping, mapping);
  114.                 if (mapping is EnumMapping) {
  115.                     codeClass = ExportEnum((EnumMapping)mapping, typeof(SoapEnumAttribute));
  116.                 }
  117.                 else if (mapping is StructMapping) {
  118.                     codeClass = ExportStruct((StructMapping)mapping);
  119.                 }
  120.                 else if (mapping is ArrayMapping) {
  121.                     EnsureTypesExported(((ArrayMapping)mapping).Elements, null);
  122.                 }
  123.                 if (codeClass != null) {
  124.                     // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
  125.                     codeClass.CustomAttributes.Add(GeneratedCodeAttribute);
  126.                    
  127.                     // Add [SerializableAttribute]
  128.                     codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).FullName));
  129.                    
  130.                     if (!codeClass.IsEnum) {
  131.                         // Add [DebuggerStepThrough]
  132.                         codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName));
  133.                         // Add [DesignerCategory("code")]
  134.                         codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute).FullName, new CodeAttributeArgument[] {new CodeAttributeArgument(new CodePrimitiveExpression("code"))}));
  135.                     }
  136.                     AddTypeMetadata(codeClass.CustomAttributes, typeof(SoapTypeAttribute), mapping.TypeDesc.Name, Accessor.UnescapeName(mapping.TypeName), mapping.Namespace, mapping.IncludeInSchema);
  137.                     ExportedClasses.Add(mapping, codeClass);
  138.                 }
  139.             }
  140.         }
  141.        
  142.         CodeTypeDeclaration ExportStruct(StructMapping mapping)
  143.         {
  144.             if (mapping.TypeDesc.IsRoot) {
  145.                 ExportRoot(mapping, typeof(SoapIncludeAttribute));
  146.                 return null;
  147.             }
  148.             if (!mapping.IncludeInSchema)
  149.                 return null;
  150.            
  151.             string className = mapping.TypeDesc.Name;
  152.             string baseName = mapping.TypeDesc.BaseTypeDesc == null ? string.Empty : mapping.TypeDesc.BaseTypeDesc.Name;
  153.            
  154.             CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className);
  155.             codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes);
  156.             codeClass.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  157.            
  158.             CodeNamespace.Types.Add(codeClass);
  159.            
  160.             if (baseName != null && baseName.Length > 0) {
  161.                 codeClass.BaseTypes.Add(baseName);
  162.             }
  163.             else
  164.                 AddPropertyChangedNotifier(codeClass);
  165.            
  166.             codeClass.TypeAttributes |= TypeAttributes.Public;
  167.             if (mapping.TypeDesc.IsAbstract)
  168.                 codeClass.TypeAttributes |= TypeAttributes.Abstract;
  169.            
  170.             CodeExporter.AddIncludeMetadata(codeClass.CustomAttributes, mapping, typeof(SoapIncludeAttribute));
  171.            
  172.             if (GenerateProperties) {
  173.                 for (int i = 0; i < mapping.Members.Length; i++) {
  174.                     ExportProperty(codeClass, mapping.Members[i], mapping.Scope);
  175.                 }
  176.             }
  177.             else {
  178.                 for (int i = 0; i < mapping.Members.Length; i++) {
  179.                     ExportMember(codeClass, mapping.Members[i]);
  180.                 }
  181.             }
  182.             for (int i = 0; i < mapping.Members.Length; i++) {
  183.                 EnsureTypesExported(mapping.Members[i].Elements, null);
  184.             }
  185.            
  186.             if (mapping.BaseMapping != null)
  187.                 ExportType(mapping.BaseMapping);
  188.            
  189.             ExportDerivedStructs(mapping);
  190.             CodeGenerator.ValidateIdentifiers(codeClass);
  191.             return codeClass;
  192.         }
  193.        
  194.         [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
  195.         internal override void ExportDerivedStructs(StructMapping mapping)
  196.         {
  197.             for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
  198.                 ExportType(derived);
  199.         }
  200.        
  201.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata"]/*' />
  202.         /// <devdoc>
  203.         /// <para>[To be supplied.]</para>
  204.         /// </devdoc>
  205.         public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member, bool forceUseMemberName)
  206.         {
  207.             AddMemberMetadata(metadata, member.Mapping, forceUseMemberName);
  208.         }
  209.        
  210.         /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata1"]/*' />
  211.         /// <devdoc>
  212.         /// <para>[To be supplied.]</para>
  213.         /// </devdoc>
  214.         public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata, XmlMemberMapping member)
  215.         {
  216.             AddMemberMetadata(metadata, member.Mapping, false);
  217.         }
  218.        
  219.         void AddElementMetadata(CodeAttributeDeclarationCollection metadata, string elementName, TypeDesc typeDesc, bool isNullable)
  220.         {
  221.             CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapElementAttribute).FullName);
  222.             if (elementName != null) {
  223.                 attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(elementName)));
  224.             }
  225.             if (typeDesc != null && typeDesc.IsAmbiguousDataType) {
  226.                 attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(typeDesc.DataType.Name)));
  227.             }
  228.             if (isNullable) {
  229.                 attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(true)));
  230.             }
  231.             metadata.Add(attribute);
  232.         }
  233.        
  234.         void AddMemberMetadata(CodeAttributeDeclarationCollection metadata, MemberMapping member, bool forceUseMemberName)
  235.         {
  236.             if (member.Elements.Length == 0)
  237.                 return;
  238.             ElementAccessor element = member.Elements[0];
  239.             TypeMapping mapping = (TypeMapping)element.Mapping;
  240.             string elemName = Accessor.UnescapeName(element.Name);
  241.             bool sameName = ((elemName == member.Name) && !forceUseMemberName);
  242.            
  243.             if (!sameName || mapping.TypeDesc.IsAmbiguousDataType || element.IsNullable) {
  244.                 AddElementMetadata(metadata, sameName ? null : elemName, mapping.TypeDesc.IsAmbiguousDataType ? mapping.TypeDesc : null, element.IsNullable);
  245.             }
  246.         }
  247.        
  248.         void ExportMember(CodeTypeDeclaration codeClass, MemberMapping member)
  249.         {
  250.             string fieldType = member.GetTypeName(CodeProvider);
  251.             CodeMemberField field = new CodeMemberField(fieldType, member.Name);
  252.             field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
  253.             field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  254.             codeClass.Members.Add(field);
  255.             AddMemberMetadata(field.CustomAttributes, member, false);
  256.            
  257.             if (member.CheckSpecified) {
  258.                 field = new CodeMemberField(typeof(bool).FullName, member.Name + "Specified");
  259.                 field.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;
  260.                 field.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  261.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute).FullName);
  262.                 field.CustomAttributes.Add(attribute);
  263.                 codeClass.Members.Add(field);
  264.             }
  265.         }
  266.        
  267.         void ExportProperty(CodeTypeDeclaration codeClass, MemberMapping member, CodeIdentifiers memberScope)
  268.         {
  269.             string fieldName = memberScope.AddUnique(CodeExporter.MakeFieldName(member.Name), member);
  270.             string fieldType = member.GetTypeName(CodeProvider);
  271.             // need to create a private field
  272.             CodeMemberField field = new CodeMemberField(fieldType, fieldName);
  273.             field.Attributes = MemberAttributes.Private;
  274.             codeClass.Members.Add(field);
  275.            
  276.             CodeMemberProperty prop = CreatePropertyDeclaration(field, member.Name, fieldType);
  277.             prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  278.             AddMemberMetadata(prop.CustomAttributes, member, false);
  279.             codeClass.Members.Add(prop);
  280.            
  281.             if (member.CheckSpecified) {
  282.                 field = new CodeMemberField(typeof(bool).FullName, fieldName + "Specified");
  283.                 field.Attributes = MemberAttributes.Private;
  284.                 codeClass.Members.Add(field);
  285.                
  286.                 prop = CreatePropertyDeclaration(field, member.Name + "Specified", typeof(bool).FullName);
  287.                 prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.XmlRemarks), true));
  288.                 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute).FullName);
  289.                 prop.CustomAttributes.Add(attribute);
  290.                 codeClass.Members.Add(prop);
  291.             }
  292.         }
  293.        
  294.         internal override void EnsureTypesExported(Accessor[] accessors, string ns)
  295.         {
  296.             if (accessors == null)
  297.                 return;
  298.             for (int i = 0; i < accessors.Length; i++)
  299.                 ExportType(accessors[i].Mapping);
  300.         }
  301.     }
  302. }

Developer Fusion