2 // System.Xml.Serialization.TypeData
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // (C) 2002 Ximian, Inc (http://www.ximian.com)
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
.Reflection
;
36 namespace System
.Xml
.Serialization
38 internal class TypeData
46 TypeData listItemTypeData
;
47 TypeData listTypeData
;
48 bool hasPublicConstructor
= true;
50 public TypeData (Type type
, string elementName
, bool isPrimitive
)
53 this.typeName
= type
.Name
;
54 this.fullTypeName
= type
.FullName
.Replace ('+', '.');
57 sType
= SchemaTypes
.Primitive
;
61 sType
= SchemaTypes
.Enum
;
62 else if (typeof(IXmlSerializable
).IsAssignableFrom (type
))
63 sType
= SchemaTypes
.XmlSerializable
;
64 else if (typeof (System
.Xml
.XmlNode
).IsAssignableFrom (type
))
65 sType
= SchemaTypes
.XmlNode
;
66 else if (type
.IsArray
|| typeof(IEnumerable
).IsAssignableFrom (type
))
67 sType
= SchemaTypes
.Array
;
69 sType
= SchemaTypes
.Class
;
73 this.elementName
= TypeTranslator
.GetArrayName (ListItemTypeData
.XmlType
);
75 this.elementName
= elementName
;
77 if (sType
== SchemaTypes
.Array
|| sType
== SchemaTypes
.Class
) {
78 hasPublicConstructor
= (type
.IsArray
|| type
.GetConstructor (Type
.EmptyTypes
) != null || type
.IsAbstract
|| type
.IsValueType
);
82 internal TypeData (string typeName
, string fullTypeName
, string xmlType
, SchemaTypes schemaType
, TypeData listItemTypeData
)
84 this.elementName
= xmlType
;
85 this.typeName
= typeName
;
86 this.fullTypeName
= fullTypeName
.Replace ('+', '.');
87 this.listItemTypeData
= listItemTypeData
;
88 this.sType
= schemaType
;
89 this.hasPublicConstructor
= true;
92 public string TypeName
113 public string FullTypeName
120 public SchemaTypes SchemaType
127 public bool IsListType
129 get { return SchemaType == SchemaTypes.Array; }
132 public bool IsComplexType
136 return (SchemaType
== SchemaTypes
.Class
||
137 SchemaType
== SchemaTypes
.Array
||
138 SchemaType
== SchemaTypes
.Enum
||
139 SchemaType
== SchemaTypes
.XmlNode
||
140 SchemaType
== SchemaTypes
.XmlSerializable
);
144 public bool IsValueType
148 if (type
!= null) return type
.IsValueType
;
149 else return (sType
== SchemaTypes
.Primitive
|| sType
== SchemaTypes
.Enum
);
153 public TypeData ListItemTypeData
157 if (listItemTypeData
== null && type
!= null)
158 listItemTypeData
= TypeTranslator
.GetTypeData (ListItemType
);
159 return listItemTypeData
;
163 public Type ListItemType
168 throw new InvalidOperationException ("Property ListItemType is not supported for custom types");
170 if (listItemType
!= null) return listItemType
;
172 if (SchemaType
!= SchemaTypes
.Array
)
173 throw new InvalidOperationException (Type
.FullName
+ " is not a collection");
174 else if (type
.IsArray
)
175 listItemType
= type
.GetElementType ();
176 else if (typeof(ICollection
).IsAssignableFrom (type
))
178 PropertyInfo prop
= GetIndexerProperty (type
);
180 throw new InvalidOperationException ("You must implement a default accessor on " + type
.FullName
+ " because it inherits from ICollection");
182 return prop
.PropertyType
;
186 MethodInfo met
= type
.GetMethod ("Add");
188 throw new InvalidOperationException ("The collection " + type
.FullName
+ " must implement an Add method");
190 ParameterInfo
[] pars
= met
.GetParameters();
191 if (pars
.Length
!= 1)
192 throw new InvalidOperationException ("The Add method of the collection " + type
.FullName
+ " must have only one parameter");
194 return pars
[0].ParameterType
;
201 public TypeData ListTypeData
205 if (listTypeData
!= null) return listTypeData
;
207 listTypeData
= new TypeData (TypeName
+ "[]",
209 TypeTranslator
.GetArrayName(XmlType
),
210 SchemaTypes
.Array
, this);
216 public bool HasPublicConstructor
218 get { return hasPublicConstructor; }
222 public static PropertyInfo
GetIndexerProperty (Type collectionType
)
224 PropertyInfo
[] props
= collectionType
.GetProperties (BindingFlags
.Instance
| BindingFlags
.Public
);
225 foreach (PropertyInfo prop
in props
)
227 ParameterInfo
[] pi
= prop
.GetIndexParameters ();
228 if (pi
!= null && pi
.Length
== 1 && pi
[0].ParameterType
== typeof(int))