1 //------------------------------------------------------------------------------
2 // <copyright file="SoapCodeExporter.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 namespace System
.Xml
.Serialization
{
11 using System
.Collections
;
13 using System
.ComponentModel
;
14 using System
.Xml
.Schema
;
16 using System
.CodeDom
.Compiler
;
17 using System
.Reflection
;
18 using System
.Diagnostics
;
20 using System
.Security
.Permissions
;
22 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter"]/*' />
25 /// <para>[To be supplied.]</para>
27 public class SoapCodeExporter
: CodeExporter
{
29 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter"]/*' />
31 /// <para>[To be supplied.]</para>
33 public SoapCodeExporter(CodeNamespace codeNamespace
) : base(codeNamespace
, null, null, CodeGenerationOptions
.GenerateProperties
, null) {}
34 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter1"]/*' />
36 /// <para>[To be supplied.]</para>
38 public SoapCodeExporter(CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
) : base(codeNamespace
, codeCompileUnit
, null, CodeGenerationOptions
.GenerateProperties
, null) {}
40 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.SoapCodeExporter2"]/*' />
42 /// <para>[To be supplied.]</para>
44 public SoapCodeExporter(CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
, CodeGenerationOptions options
) : base(codeNamespace
, codeCompileUnit
, null, CodeGenerationOptions
.GenerateProperties
, null) {}
46 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter3"]/*' />
48 /// <para>[To be supplied.]</para>
50 public SoapCodeExporter(CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
, CodeGenerationOptions options
, Hashtable mappings
)
51 : base(codeNamespace
, codeCompileUnit
, null, options
, mappings
) {}
53 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="XmlCodeExporter.SoapCodeExporter4"]/*' />
55 /// <para>[To be supplied.]</para>
57 public SoapCodeExporter(CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
, CodeDomProvider codeProvider
, CodeGenerationOptions options
, Hashtable mappings
)
58 : base(codeNamespace
, codeCompileUnit
, codeProvider
, options
, mappings
) {}
60 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportTypeMapping"]/*' />
62 /// <para>[To be supplied.]</para>
64 public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping
) {
65 xmlTypeMapping
.CheckShallow();
66 CheckScope(xmlTypeMapping
.Scope
);
67 ExportElement(xmlTypeMapping
.Accessor
);
70 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.ExportMembersMapping"]/*' />
72 /// <para>[To be supplied.]</para>
74 public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping
) {
75 xmlMembersMapping
.CheckShallow();
76 CheckScope(xmlMembersMapping
.Scope
);
77 for (int i
= 0; i
< xmlMembersMapping
.Count
; i
++) {
78 ExportElement((ElementAccessor
)xmlMembersMapping
[i
].Accessor
);
82 void ExportElement(ElementAccessor element
) {
83 ExportType(element
.Mapping
);
86 void ExportType(TypeMapping mapping
) {
87 if (mapping
.IsReference
)
89 if (ExportedMappings
[mapping
] == null) {
90 CodeTypeDeclaration codeClass
= null;
91 ExportedMappings
.Add(mapping
, mapping
);
92 if (mapping
is EnumMapping
) {
93 codeClass
= ExportEnum((EnumMapping
)mapping
, typeof(SoapEnumAttribute
));
95 else if (mapping
is StructMapping
) {
96 codeClass
= ExportStruct((StructMapping
)mapping
);
98 else if (mapping
is ArrayMapping
) {
99 EnsureTypesExported(((ArrayMapping
)mapping
).Elements
, null);
101 if (codeClass
!= null) {
102 // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
103 codeClass
.CustomAttributes
.Add(GeneratedCodeAttribute
);
105 // Add [SerializableAttribute]
106 codeClass
.CustomAttributes
.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute
).FullName
));
108 if (!codeClass
.IsEnum
) {
109 // Add [DebuggerStepThrough]
110 codeClass
.CustomAttributes
.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute
).FullName
));
111 // Add [DesignerCategory("code")]
112 codeClass
.CustomAttributes
.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute
).FullName
, new CodeAttributeArgument
[] {new CodeAttributeArgument(new CodePrimitiveExpression("code"))}
));
114 AddTypeMetadata(codeClass
.CustomAttributes
, typeof(SoapTypeAttribute
), mapping
.TypeDesc
.Name
, Accessor
.UnescapeName(mapping
.TypeName
), mapping
.Namespace
, mapping
.IncludeInSchema
);
115 ExportedClasses
.Add(mapping
, codeClass
);
120 CodeTypeDeclaration
ExportStruct(StructMapping mapping
) {
121 if (mapping
.TypeDesc
.IsRoot
) {
122 ExportRoot(mapping
, typeof(SoapIncludeAttribute
));
125 if (!mapping
.IncludeInSchema
)
128 string className
= mapping
.TypeDesc
.Name
;
129 string baseName
= mapping
.TypeDesc
.BaseTypeDesc
== null ? string.Empty
: mapping
.TypeDesc
.BaseTypeDesc
.Name
;
131 CodeTypeDeclaration codeClass
= new CodeTypeDeclaration(className
);
132 codeClass
.IsPartial
= CodeProvider
.Supports(GeneratorSupport
.PartialTypes
);
133 codeClass
.Comments
.Add(new CodeCommentStatement(Res
.GetString(Res
.XmlRemarks
), true));
135 CodeNamespace
.Types
.Add(codeClass
);
137 if (baseName
!= null && baseName
.Length
> 0) {
138 codeClass
.BaseTypes
.Add(baseName
);
141 AddPropertyChangedNotifier(codeClass
);
143 codeClass
.TypeAttributes
|= TypeAttributes
.Public
;
144 if (mapping
.TypeDesc
.IsAbstract
)
145 codeClass
.TypeAttributes
|= TypeAttributes
.Abstract
;
147 CodeExporter
.AddIncludeMetadata(codeClass
.CustomAttributes
, mapping
, typeof(SoapIncludeAttribute
));
149 if (GenerateProperties
) {
150 for (int i
= 0; i
< mapping
.Members
.Length
; i
++) {
151 ExportProperty(codeClass
, mapping
.Members
[i
], mapping
.Scope
);
155 for (int i
= 0; i
< mapping
.Members
.Length
; i
++) {
156 ExportMember(codeClass
, mapping
.Members
[i
]);
159 for (int i
= 0; i
< mapping
.Members
.Length
; i
++) {
160 EnsureTypesExported(mapping
.Members
[i
].Elements
, null);
163 if (mapping
.BaseMapping
!= null)
164 ExportType(mapping
.BaseMapping
);
166 ExportDerivedStructs(mapping
);
167 CodeGenerator
.ValidateIdentifiers(codeClass
);
171 [PermissionSet(SecurityAction
.InheritanceDemand
, Name
="FullTrust")]
172 internal override void ExportDerivedStructs(StructMapping mapping
) {
173 for (StructMapping derived
= mapping
.DerivedMappings
; derived
!= null; derived
= derived
.NextDerivedMapping
)
177 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata"]/*' />
179 /// <para>[To be supplied.]</para>
181 public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata
, XmlMemberMapping member
, bool forceUseMemberName
) {
182 AddMemberMetadata(metadata
, member
.Mapping
, forceUseMemberName
);
185 /// <include file='doc\SoapCodeExporter.uex' path='docs/doc[@for="SoapCodeExporter.AddMappingMetadata1"]/*' />
187 /// <para>[To be supplied.]</para>
189 public void AddMappingMetadata(CodeAttributeDeclarationCollection metadata
, XmlMemberMapping member
) {
190 AddMemberMetadata(metadata
, member
.Mapping
, false);
193 void AddElementMetadata(CodeAttributeDeclarationCollection metadata
, string elementName
, TypeDesc typeDesc
, bool isNullable
) {
194 CodeAttributeDeclaration attribute
= new CodeAttributeDeclaration(typeof(SoapElementAttribute
).FullName
);
195 if (elementName
!= null) {
196 attribute
.Arguments
.Add(new CodeAttributeArgument(new CodePrimitiveExpression(elementName
)));
198 if (typeDesc
!= null && typeDesc
.IsAmbiguousDataType
) {
199 attribute
.Arguments
.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(typeDesc
.DataType
.Name
)));
202 attribute
.Arguments
.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(true)));
204 metadata
.Add(attribute
);
207 void AddMemberMetadata(CodeAttributeDeclarationCollection metadata
, MemberMapping member
, bool forceUseMemberName
) {
208 if (member
.Elements
.Length
== 0) return;
209 ElementAccessor element
= member
.Elements
[0];
210 TypeMapping mapping
= (TypeMapping
)element
.Mapping
;
211 string elemName
= Accessor
.UnescapeName(element
.Name
);
212 bool sameName
= ((elemName
== member
.Name
) && !forceUseMemberName
);
214 if (!sameName
|| mapping
.TypeDesc
.IsAmbiguousDataType
|| element
.IsNullable
) {
215 AddElementMetadata(metadata
, sameName
? null : elemName
, mapping
.TypeDesc
.IsAmbiguousDataType
? mapping
.TypeDesc
: null, element
.IsNullable
);
219 void ExportMember(CodeTypeDeclaration codeClass
, MemberMapping member
) {
220 string fieldType
= member
.GetTypeName(CodeProvider
);
221 CodeMemberField field
= new CodeMemberField(fieldType
, member
.Name
);
222 field
.Attributes
= (field
.Attributes
& ~MemberAttributes
.AccessMask
) | MemberAttributes
.Public
;
223 field
.Comments
.Add(new CodeCommentStatement(Res
.GetString(Res
.XmlRemarks
), true));
224 codeClass
.Members
.Add(field
);
225 AddMemberMetadata(field
.CustomAttributes
, member
, false);
227 if (member
.CheckSpecified
!= SpecifiedAccessor
.None
) {
228 field
= new CodeMemberField(typeof(bool).FullName
, member
.Name
+ "Specified");
229 field
.Attributes
= (field
.Attributes
& ~MemberAttributes
.AccessMask
) | MemberAttributes
.Public
;
230 field
.Comments
.Add(new CodeCommentStatement(Res
.GetString(Res
.XmlRemarks
), true));
231 CodeAttributeDeclaration attribute
= new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute
).FullName
);
232 field
.CustomAttributes
.Add(attribute
);
233 codeClass
.Members
.Add(field
);
237 void ExportProperty(CodeTypeDeclaration codeClass
, MemberMapping member
, CodeIdentifiers memberScope
) {
238 string fieldName
= memberScope
.AddUnique(CodeExporter
.MakeFieldName(member
.Name
), member
);
239 string fieldType
= member
.GetTypeName(CodeProvider
);
240 // need to create a private field
241 CodeMemberField field
= new CodeMemberField(fieldType
, fieldName
);
242 field
.Attributes
= MemberAttributes
.Private
;
243 codeClass
.Members
.Add(field
);
245 CodeMemberProperty prop
= CreatePropertyDeclaration(field
, member
.Name
, fieldType
);
246 prop
.Comments
.Add(new CodeCommentStatement(Res
.GetString(Res
.XmlRemarks
), true));
247 AddMemberMetadata(prop
.CustomAttributes
, member
, false);
248 codeClass
.Members
.Add(prop
);
250 if (member
.CheckSpecified
!= SpecifiedAccessor
.None
) {
251 field
= new CodeMemberField(typeof(bool).FullName
, fieldName
+ "Specified");
252 field
.Attributes
= MemberAttributes
.Private
;
253 codeClass
.Members
.Add(field
);
255 prop
= CreatePropertyDeclaration(field
, member
.Name
+ "Specified", typeof(bool).FullName
);
256 prop
.Comments
.Add(new CodeCommentStatement(Res
.GetString(Res
.XmlRemarks
), true));
257 CodeAttributeDeclaration attribute
= new CodeAttributeDeclaration(typeof(SoapIgnoreAttribute
).FullName
);
258 prop
.CustomAttributes
.Add(attribute
);
259 codeClass
.Members
.Add(prop
);
263 internal override void EnsureTypesExported(Accessor
[] accessors
, string ns
) {
264 if (accessors
== null) return;
265 for (int i
= 0; i
< accessors
.Length
; i
++)
266 ExportType(accessors
[i
].Mapping
);