* TypeData.cs, TypeTranslator.cs: Renamed some properties.
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / XmlTypeMapping.cs
1 //\r
2 // XmlTypeMapping.cs: \r
3 //\r
4 // Author:\r
5 //   John Donagher (john@webmeta.com)\r
6 //   Lluis Sanchez Gual (lluis@ximian.com)\r
7 //\r
8 // (C) 2002 John Donagher\r
9 //\r
10 \r
11 using System.Xml;\r
12 using System;\r
13 using System.Collections;\r
14 \r
15 namespace System.Xml.Serialization\r
16 {\r
17         public class XmlTypeMapping : XmlMapping\r
18         {\r
19                 private string elementName;\r
20                 private string ns;\r
21                 private string xmlType;\r
22                 TypeData type;\r
23 \r
24                 ArrayList _derivedTypes = new ArrayList();\r
25 \r
26                 internal XmlTypeMapping(string elementName, string ns, TypeData typeData, string xmlType)\r
27                 {\r
28                         this.elementName = elementName;\r
29                         this.ns = ns;\r
30                         this.type = typeData;\r
31                         this.xmlType = xmlType;\r
32                 }\r
33 \r
34                 public string ElementName\r
35                 {\r
36                         get { return elementName; }\r
37                 }\r
38 \r
39                 public string Namespace\r
40                 {\r
41                         get { return ns; }\r
42                 }\r
43 \r
44                 public string TypeFullName\r
45                 {\r
46                         get { return type.FullTypeName; }\r
47                 }\r
48 \r
49                 public string TypeName\r
50                 {\r
51                         get { return type.TypeName; }\r
52                 }\r
53 \r
54                 internal TypeData TypeData\r
55                 {\r
56                         get { return type; }\r
57                 }\r
58 \r
59                 internal string XmlType\r
60                 {\r
61                         get { return xmlType; }\r
62                 }\r
63 \r
64                 internal ArrayList DerivedTypes\r
65                 {\r
66                         get { return _derivedTypes; }\r
67                         set { _derivedTypes = value; }\r
68                 }\r
69 \r
70                 internal XmlTypeMapping GetRealTypeMap (string objectFullTypeName)\r
71                 {\r
72                         // Returns the map for a subtype of this map's type\r
73 \r
74                         if (TypeFullName == objectFullTypeName) return this;\r
75                         foreach (XmlTypeMapping map in _derivedTypes)\r
76                                 if (map.TypeFullName == objectFullTypeName) return map;\r
77 \r
78                         return null;\r
79                 }\r
80 \r
81                 internal XmlTypeMapping GetRealElementMap (string name, string ens)\r
82                 {\r
83                         if (xmlType == name && ns == ens) return this;\r
84                         foreach (XmlTypeMapping map in _derivedTypes)\r
85                                 if (map.xmlType == name && map.ns == ens) return map;\r
86                         return null;\r
87                 }\r
88         }\r
89 \r
90         // Mapping info for classes and structs\r
91 \r
92         internal class ClassMap: ObjectMap\r
93         {\r
94                 Hashtable _elements;\r
95                 ArrayList _elementMembers;\r
96                 Hashtable _attributeMembers;\r
97                 ArrayList _flatLists;\r
98                 XmlTypeMapMemberAnyElement _defaultAnyElement;\r
99                 XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;\r
100 \r
101                 public void AddMember (XmlTypeMapMember member)\r
102                 {\r
103                         if (member is XmlTypeMapMemberAttribute)\r
104                         {\r
105                                 XmlTypeMapMemberAttribute atm = (XmlTypeMapMemberAttribute)member;\r
106                                 if (_attributeMembers == null) _attributeMembers = new Hashtable();\r
107                                 _attributeMembers.Add (atm.AttributeName + "/" + atm.Namespace, member);\r
108                                 return;\r
109                         }\r
110                         else if (member is XmlTypeMapMemberFlatList)\r
111                         {\r
112                                 RegisterFlatList ((XmlTypeMapMemberFlatList)member);\r
113                         }\r
114                         else if (member is XmlTypeMapMemberAnyElement)\r
115                         {\r
116                                 XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement) member;\r
117                                 if (mem.IsDefaultAny) _defaultAnyElement = mem;\r
118                                 if (mem.TypeData.IsListType) RegisterFlatList (mem);\r
119                         }\r
120                         else if (member is XmlTypeMapMemberAnyAttribute)\r
121                         {\r
122                                 _defaultAnyAttribute = (XmlTypeMapMemberAnyAttribute) member;\r
123                                 return;\r
124                         }\r
125 \r
126                         if (_elementMembers == null) {\r
127                                 _elementMembers = new ArrayList();\r
128                                 _elements = new Hashtable();\r
129                         }\r
130 \r
131                         member.Index = _elementMembers.Count;\r
132                         _elementMembers.Add (member);\r
133 \r
134                         ICollection elemsInfo = ((XmlTypeMapMemberElement)member).ElementInfo;\r
135                         foreach (XmlTypeMapElementInfo elem in elemsInfo)\r
136                         {\r
137                                 string key = elem.ElementName+"/"+elem.Namespace;\r
138                                 if (_elements.ContainsKey (key)) \r
139                                         throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");\r
140                                 _elements.Add (key, elem);\r
141                         }\r
142                 }\r
143 \r
144                 void RegisterFlatList (XmlTypeMapMemberExpandable member)\r
145                 {\r
146                         if (_flatLists == null) _flatLists = new ArrayList ();\r
147                         member.FlatArrayIndex = _flatLists.Count;\r
148                         _flatLists.Add (member);\r
149                 }\r
150 \r
151                 public XmlTypeMapMemberAttribute GetAttribute (string name, string ns)\r
152                 {\r
153                         if (_attributeMembers == null) return null;\r
154                         return (XmlTypeMapMemberAttribute)_attributeMembers[name + "/" + ns];\r
155                 }\r
156 \r
157                 public XmlTypeMapElementInfo GetElement (string name, string ns)\r
158                 {\r
159                         if (_elements == null) return null;\r
160                         return (XmlTypeMapElementInfo)_elements[name + "/" + ns];\r
161                 }\r
162 \r
163                 public XmlTypeMapMemberAnyElement DefaultAnyElementMember\r
164                 {\r
165                         get { return _defaultAnyElement; }\r
166                 }\r
167 \r
168                 public XmlTypeMapMemberAnyAttribute DefaultAnyAttributeMember\r
169                 {\r
170                         get { return _defaultAnyAttribute; }\r
171                 }\r
172 \r
173                 public ICollection AttributeMembers\r
174                 {\r
175                         get { return (_attributeMembers != null) ? _attributeMembers.Values : null; }\r
176                 }\r
177 \r
178                 public ICollection ElementMembers\r
179                 {\r
180                         get { return _elementMembers; }\r
181                 }\r
182 \r
183                 public ICollection FlatLists\r
184                 {\r
185                         get { return _flatLists; }\r
186                 }\r
187         }\r
188 \r
189         // Mapping info for arrays and lists\r
190 \r
191         internal class ListMap: ObjectMap\r
192         {\r
193                 XmlTypeMapElementInfoList _itemInfo;\r
194 \r
195                 public XmlTypeMapElementInfoList ItemInfo\r
196                 {\r
197                         get { return _itemInfo; }\r
198                         set { _itemInfo = value; }\r
199                 }\r
200 \r
201                 public XmlTypeMapElementInfo FindElement (object memberValue)\r
202                 {\r
203                         if (_itemInfo.Count == 1) \r
204                                 return (XmlTypeMapElementInfo) _itemInfo[0];\r
205                         else\r
206                         {\r
207                                 if (memberValue == null) return null;\r
208                                 Type type = memberValue.GetType();\r
209                                 foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
210                                         if (elem.TypeData.Type == type) return elem;\r
211                         }\r
212                         return null;\r
213                 }       \r
214 \r
215                 public XmlTypeMapElementInfo FindElement (string elementName, string ns)\r
216                 {\r
217                         foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
218                                 if (elem.ElementName == elementName && elem.Namespace == ns) return elem;\r
219                         return null;\r
220                 }\r
221 \r
222                 public override bool Equals (object other)\r
223                 {\r
224                         ListMap lmap = other as ListMap;\r
225                         if (lmap == null) return false;\r
226 \r
227                         if (_itemInfo.Count != lmap._itemInfo.Count) return false;\r
228                         for (int n=0; n<_itemInfo.Count; n++)\r
229                                 if (!_itemInfo[n].Equals (lmap._itemInfo[n])) return false;\r
230                         return true;\r
231                 }\r
232 \r
233                 public override int GetHashCode ()\r
234                 {\r
235                         return base.GetHashCode ();\r
236                 }\r
237         }\r
238 \r
239         internal class EnumMap: ObjectMap\r
240         {\r
241                 EnumMapMember[] _members;\r
242 \r
243                 public class EnumMapMember\r
244                 {\r
245                         string _xmlName;\r
246                         string _enumName;\r
247 \r
248                         public EnumMapMember (string xmlName, string enumName)\r
249                         {\r
250                                 _xmlName = xmlName;\r
251                                 _enumName = enumName;\r
252                         }\r
253 \r
254                         public string XmlName\r
255                         {\r
256                                 get { return _xmlName; }\r
257                         }\r
258 \r
259                         public string EnumName\r
260                         {\r
261                                 get { return _enumName; }\r
262                         }\r
263                 }\r
264 \r
265                 public EnumMap (EnumMapMember[] members)\r
266                 {\r
267                         _members = members;\r
268                 }\r
269 \r
270                 public EnumMapMember[] Members\r
271                 {\r
272                         get { return _members; }\r
273                 }\r
274 \r
275                 public string GetXmlName (string enumName)\r
276                 {\r
277                         foreach (EnumMapMember mem in _members)\r
278                                 if (mem.EnumName == enumName) return mem.XmlName;\r
279                         throw new InvalidOperationException ("Invalid enumeration value: " + enumName);\r
280                 }\r
281 \r
282                 public string GetEnumName (string xmlName)\r
283                 {\r
284                         foreach (EnumMapMember mem in _members)\r
285                                 if (mem.XmlName == xmlName) return mem.EnumName;\r
286                         throw new InvalidOperationException ("Invalid enumeration value: " + xmlName);\r
287                 }\r
288         }\r
289 }\r