2 // System.Xml.Serialization.XmlCodeExporter
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
34 using System
.Xml
.Schema
;
35 using System
.CodeDom
.Compiler
;
37 namespace System
.Xml
.Serialization
40 public class XmlCodeExporter
45 // CodeGenerationOptions options;
51 public XmlCodeExporter (CodeNamespace codeNamespace
): this (codeNamespace
, null)
55 public XmlCodeExporter (CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
)
57 codeGenerator
= new XmlMapCodeGenerator (codeNamespace
, codeCompileUnit
, CodeGenerationOptions
.GenerateProperties
);
60 public XmlCodeExporter (CodeNamespace codeNamespace
,
61 CodeCompileUnit codeCompileUnit
,
62 CodeGenerationOptions options
)
63 : this (codeNamespace
, codeCompileUnit
, null, options
, null)
67 public XmlCodeExporter (CodeNamespace codeNamespace
,
68 CodeCompileUnit codeCompileUnit
,
69 CodeGenerationOptions options
,
71 : this (codeNamespace
, codeCompileUnit
, null, options
, mappings
)
76 [MonoTODO
]// FIXME: mappings?
77 public XmlCodeExporter (CodeNamespace codeNamespace
,
78 CodeCompileUnit codeCompileUnit
,
79 CodeDomProvider codeProvider
,
80 CodeGenerationOptions options
,
83 codeGenerator
= new XmlMapCodeGenerator (codeNamespace
, codeCompileUnit
, codeProvider
, options
, mappings
);
86 #endregion // Constructors
95 public void AddMappingMetadata (CodeAttributeDeclarationCollection metadata
, XmlMemberMapping member
, string ns
)
97 AddMappingMetadata (metadata
, member
, ns
, false);
100 public void AddMappingMetadata (CodeAttributeDeclarationCollection metadata
, XmlTypeMapping mapping
, string ns
)
102 if ( (mapping
.TypeData
.SchemaType
== SchemaTypes
.Primitive
||
103 mapping
.TypeData
.SchemaType
== SchemaTypes
.Array
)
104 && mapping
.Namespace
!= XmlSchema
.Namespace
)
106 CodeAttributeDeclaration ratt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRoot");
107 ratt
.Arguments
.Add (MapCodeGenerator
.GetArg (mapping
.ElementName
));
108 ratt
.Arguments
.Add (MapCodeGenerator
.GetArg ("Namespace", mapping
.Namespace
));
109 ratt
.Arguments
.Add (MapCodeGenerator
.GetArg ("IsNullable", mapping
.IsNullable
));
114 public void AddMappingMetadata (CodeAttributeDeclarationCollection metadata
, XmlMemberMapping member
, string ns
, bool forceUseMemberName
)
116 CodeAttributeDeclaration att
;
117 TypeData memType
= member
.TypeMapMember
.TypeData
;
121 XmlTypeMapElementInfoList list
= (XmlTypeMapElementInfoList
)((XmlTypeMapMemberElement
)member
.TypeMapMember
).ElementInfo
;
122 foreach (XmlTypeMapElementInfo info
in list
)
124 if (info
.IsTextElement
)
125 metadata
.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlText"));
127 att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlAnyElement");
128 if (!info
.IsUnnamedAnyElement
) {
129 att
.Arguments
.Add (MapCodeGenerator
.GetArg ("Name", info
.ElementName
));
130 if (info
.Namespace
!= ns
) att
.Arguments
.Add (MapCodeGenerator
.GetArg ("Namespace", member
.Namespace
));
136 else if (member
.TypeMapMember
is XmlTypeMapMemberList
)
139 XmlTypeMapMemberList list
= member
.TypeMapMember
as XmlTypeMapMemberList
;
140 ListMap listMap
= (ListMap
) list
.ListTypeMapping
.ObjectMap
;
142 codeGenerator
.AddArrayAttributes (metadata
, list
, ns
, forceUseMemberName
);
143 codeGenerator
.AddArrayItemAttributes (metadata
, listMap
, memType
.ListItemTypeData
, list
.Namespace
, 0);
145 else if (member
.TypeMapMember
is XmlTypeMapMemberElement
) {
146 codeGenerator
.AddElementMemberAttributes ((XmlTypeMapMemberElement
) member
.TypeMapMember
, ns
, metadata
, forceUseMemberName
);
148 else if (member
.TypeMapMember
is XmlTypeMapMemberAttribute
) {
149 codeGenerator
.AddAttributeMemberAttributes ((XmlTypeMapMemberAttribute
) member
.TypeMapMember
, ns
, metadata
, forceUseMemberName
);
152 throw new NotSupportedException ("Schema type not supported");
155 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping
)
157 codeGenerator
.ExportMembersMapping (xmlMembersMapping
);
160 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping
)
162 codeGenerator
.ExportTypeMapping (xmlTypeMapping
, true);
165 #endregion // Methods
168 class XmlMapCodeGenerator
: MapCodeGenerator
170 public XmlMapCodeGenerator (CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
, CodeGenerationOptions options
)
171 : base (codeNamespace
, codeCompileUnit
, options
)
175 public XmlMapCodeGenerator (CodeNamespace codeNamespace
, CodeCompileUnit codeCompileUnit
, CodeDomProvider codeProvider
, CodeGenerationOptions options
, Hashtable mappings
)
176 : base (codeNamespace
, codeCompileUnit
, codeProvider
, options
, mappings
)
180 protected override void GenerateClass (XmlTypeMapping map
, CodeTypeDeclaration codeClass
, bool isTopLevel
)
182 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlTypeAttribute");
183 if (map
.XmlType
!= map
.TypeData
.TypeName
) att
.Arguments
.Add (GetArg (map
.XmlType
));
184 if (map
.XmlTypeNamespace
!= "") att
.Arguments
.Add (GetArg ("Namespace", map
.XmlTypeNamespace
));
185 if (!map
.IncludeInSchema
) att
.Arguments
.Add (GetArg ("IncludeInSchema", false));
186 AddCustomAttribute (codeClass
, att
, false);
188 CodeAttributeDeclaration ratt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlRootAttribute");
189 if (map
.ElementName
!= map
.XmlType
) ratt
.Arguments
.Add (GetArg (map
.ElementName
));
191 ratt
.Arguments
.Add (GetArg ("Namespace", map
.Namespace
));
192 ratt
.Arguments
.Add (GetArg ("IsNullable", map
.IsNullable
));
194 if (map
.Namespace
!= "")
195 ratt
.Arguments
.Add (GetArg ("Namespace", map
.Namespace
));
197 AddCustomAttribute (codeClass
, ratt
, isTopLevel
);
200 protected override void GenerateClassInclude (CodeAttributeDeclarationCollection attributes
, XmlTypeMapping map
)
202 CodeAttributeDeclaration iatt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlIncludeAttribute");
203 iatt
.Arguments
.Add (new CodeAttributeArgument (new CodeTypeOfExpression(map
.TypeData
.FullTypeName
)));
204 attributes
.Add (iatt
);
207 protected override void GenerateAnyAttribute (CodeTypeMember codeField
)
209 AddCustomAttribute (codeField
, "System.Xml.Serialization.XmlAnyAttribute");
212 protected override void GenerateAttributeMember (CodeAttributeDeclarationCollection attributes
, XmlTypeMapMemberAttribute attinfo
, string defaultNamespace
, bool forceUseMemberName
)
214 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlAttributeAttribute");
215 if (forceUseMemberName
|| attinfo
.Name
!= attinfo
.AttributeName
) att
.Arguments
.Add (GetArg (attinfo
.AttributeName
));
216 if (attinfo
.Namespace
!= defaultNamespace
) att
.Arguments
.Add (GetArg ("Namespace", attinfo
.Namespace
));
217 if (attinfo
.Form
== XmlSchemaForm
.Qualified
) att
.Arguments
.Add (GetEnumArg ("Form","System.Xml.Schema.XmlSchemaForm",attinfo
.Form
.ToString()));
218 if (!TypeTranslator
.IsDefaultPrimitiveTpeData(attinfo
.TypeData
)) att
.Arguments
.Add (GetArg ("DataType",attinfo
.TypeData
.XmlType
));
219 attributes
.Add (att
);
222 attributes
.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
225 protected override void GenerateElementInfoMember (CodeAttributeDeclarationCollection attributes
, XmlTypeMapMemberElement member
, XmlTypeMapElementInfo einfo
, TypeData defaultType
, string defaultNamespace
, bool addAlwaysAttr
, bool forceUseMemberName
)
227 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlElementAttribute");
228 if (forceUseMemberName
|| einfo
.ElementName
!= member
.Name
) att
.Arguments
.Add (GetArg (einfo
.ElementName
));
229 if (einfo
.TypeData
.FullTypeName
!= defaultType
.FullTypeName
) att
.Arguments
.Add (GetTypeArg ("Type", einfo
.TypeData
.FullTypeName
));
230 if (einfo
.Namespace
!= defaultNamespace
) att
.Arguments
.Add (GetArg ("Namespace", einfo
.Namespace
));
231 if (einfo
.Form
== XmlSchemaForm
.Unqualified
) att
.Arguments
.Add (GetEnumArg ("Form", "System.Xml.Schema.XmlSchemaForm", einfo
.Form
.ToString()));
232 if (einfo
.IsNullable
) att
.Arguments
.Add (GetArg ("IsNullable", true));
233 if (!TypeTranslator
.IsDefaultPrimitiveTpeData(einfo
.TypeData
)) att
.Arguments
.Add (GetArg ("DataType",einfo
.TypeData
.XmlType
));
234 if (addAlwaysAttr
|| att
.Arguments
.Count
> 0) attributes
.Add (att
);
237 protected override void GenerateElementMember (CodeAttributeDeclarationCollection attributes
, XmlTypeMapMemberElement member
)
239 if (member
.ChoiceMember
!= null) {
240 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlChoiceIdentifier");
241 att
.Arguments
.Add (GetArg(member
.ChoiceMember
));
242 attributes
.Add (att
);
246 attributes
.Add (new CodeAttributeDeclaration ("System.Xml.Serialization.XmlIgnoreAttribute"));
249 protected override void GenerateArrayElement (CodeAttributeDeclarationCollection attributes
, XmlTypeMapMemberElement member
, string defaultNamespace
, bool forceUseMemberName
)
251 XmlTypeMapElementInfo einfo
= (XmlTypeMapElementInfo
) member
.ElementInfo
[0];
252 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlArray");
253 if (forceUseMemberName
|| (einfo
.ElementName
!= member
.Name
)) att
.Arguments
.Add (GetArg ("ElementName", einfo
.ElementName
));
254 if (einfo
.Namespace
!= defaultNamespace
) att
.Arguments
.Add (GetArg ("Namespace", einfo
.Namespace
));
255 if (einfo
.Form
== XmlSchemaForm
.Unqualified
) att
.Arguments
.Add (MapCodeGenerator
.GetEnumArg ("Form", "System.Xml.Schema.XmlSchemaForm", einfo
.Form
.ToString()));
256 if (einfo
.IsNullable
) att
.Arguments
.Add (GetArg ("IsNullable", true));
257 if (att
.Arguments
.Count
> 0) attributes
.Add (att
);
260 protected override void GenerateArrayItemAttributes (CodeAttributeDeclarationCollection attributes
, ListMap listMap
, TypeData type
, XmlTypeMapElementInfo ainfo
, string defaultName
, string defaultNamespace
, int nestingLevel
)
262 bool needsType
= (listMap
.ItemInfo
.Count
> 1) ||
263 (ainfo
.TypeData
.FullTypeName
!= type
.FullTypeName
&& !listMap
.IsMultiArray
);
265 CodeAttributeDeclaration att
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlArrayItem");
266 if (ainfo
.ElementName
!= defaultName
) att
.Arguments
.Add (GetArg ("ElementName", ainfo
.ElementName
));
267 if (ainfo
.Namespace
!= defaultNamespace
&& ainfo
.Namespace
!= XmlSchema
.Namespace
) att
.Arguments
.Add (GetArg ("Namespace", ainfo
.Namespace
));
268 if (needsType
) att
.Arguments
.Add (GetTypeArg ("Type", ainfo
.TypeData
.FullTypeName
));
269 if (!ainfo
.IsNullable
) att
.Arguments
.Add (GetArg ("IsNullable", false));
270 if (ainfo
.Form
== XmlSchemaForm
.Unqualified
) att
.Arguments
.Add (MapCodeGenerator
.GetEnumArg ("Form", "System.Xml.Schema.XmlSchemaForm", ainfo
.Form
.ToString()));
271 if (att
.Arguments
.Count
> 0 && nestingLevel
> 0) att
.Arguments
.Add (GetArg ("NestingLevel", nestingLevel
));
273 if (att
.Arguments
.Count
> 0) attributes
.Add (att
);
276 protected override void GenerateTextElementAttribute (CodeAttributeDeclarationCollection attributes
, XmlTypeMapElementInfo einfo
, TypeData defaultType
)
278 CodeAttributeDeclaration uatt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlTextAttribute");
279 if (einfo
.TypeData
.FullTypeName
!= defaultType
.FullTypeName
) uatt
.Arguments
.Add (GetTypeArg ("Type", einfo
.TypeData
.FullTypeName
));
280 attributes
.Add (uatt
);
283 protected override void GenerateUnnamedAnyElementAttribute (CodeAttributeDeclarationCollection attributes
, XmlTypeMapElementInfo einfo
, string defaultNamespace
)
285 CodeAttributeDeclaration uatt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlAnyElement");
286 if (!einfo
.IsUnnamedAnyElement
) uatt
.Arguments
.Add (GetArg ("Name", einfo
.ElementName
));
287 if (einfo
.Namespace
!= defaultNamespace
) uatt
.Arguments
.Add (GetArg ("Namespace", einfo
.Namespace
));
288 attributes
.Add (uatt
);
291 protected override void GenerateEnum (XmlTypeMapping map
, CodeTypeDeclaration codeEnum
, bool isTopLevel
)
293 GenerateClass (map
, codeEnum
, isTopLevel
);
296 protected override void GenerateEnumItem (CodeMemberField codeField
, EnumMap
.EnumMapMember emem
)
298 if (emem
.EnumName
!= emem
.XmlName
)
300 CodeAttributeDeclaration xatt
= new CodeAttributeDeclaration ("System.Xml.Serialization.XmlEnumAttribute");
301 xatt
.Arguments
.Add (GetArg (emem
.XmlName
));
303 AddCustomAttribute (codeField
, xatt
, true);
307 protected override void GenerateSpecifierMember (CodeTypeMember codeField
)
309 AddCustomAttribute (codeField
, "System.Xml.Serialization.XmlIgnore");