-//\r
-// XmlTypeMapping.cs: \r
-//\r
-// Author:\r
-// John Donagher (john@webmeta.com)\r
-// Lluis Sanchez Gual (lluis@ximian.com)\r
-//\r
-// (C) 2002 John Donagher\r
-//\r
+//
+// XmlTypeMapping.cs:
+//
+// Author:
+// John Donagher (john@webmeta.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// (C) 2002 John Donagher
+//
//
// Permission is hereby granted, free of charge, to any person obtaining
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-\r
-using System.Xml;\r
-using System;\r
-using System.Collections;\r
+
+using System.Xml;
+using System;
+using System.Collections;
using System.Globalization;
-using System.Xml.Schema;\r
-\r
-namespace System.Xml.Serialization\r
-{\r
- public class XmlTypeMapping : XmlMapping\r
- {\r
- private string xmlType;\r
- private string xmlTypeNamespace;\r
- TypeData type;\r
- XmlTypeMapping baseMap;\r
- bool multiReferenceType = false;\r
- bool isSimpleType;\r
- string documentation;\r
- bool includeInSchema;\r
- bool isNullable = true;\r
-\r
- ArrayList _derivedTypes = new ArrayList();\r
-\r
- internal XmlTypeMapping(string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)\r
- : base (elementName, ns)\r
- {\r
- this.type = typeData;\r
- this.xmlType = xmlType;\r
- this.xmlTypeNamespace = xmlTypeNamespace;\r
- }\r
-\r
-#if !NET_2_0\r
- public string ElementName\r
- {\r
- get { return _elementName; }\r
- }\r
-\r
- public string Namespace\r
- {\r
- get { return _namespace; }\r
- }\r
-#endif\r
-\r
- public string TypeFullName\r
- {\r
- get { return type.FullTypeName; }\r
- }\r
-\r
- public string TypeName\r
- {\r
- get { return type.TypeName; }\r
- }\r
-\r
- internal TypeData TypeData\r
- {\r
- get { return type; }\r
- }\r
-\r
- internal string XmlType\r
- {\r
- get { return xmlType; }\r
- }\r
-\r
- internal string XmlTypeNamespace\r
- {\r
- get { return xmlTypeNamespace; }\r
- }\r
-\r
- internal ArrayList DerivedTypes\r
- {\r
- get { return _derivedTypes; }\r
- set { _derivedTypes = value; }\r
- }\r
-\r
- internal bool MultiReferenceType\r
- {\r
- get { return multiReferenceType; }\r
- set { multiReferenceType = value; }\r
- }\r
-\r
- internal XmlTypeMapping BaseMap\r
- {\r
- get { return baseMap; }\r
- set { baseMap = value; }\r
- }\r
-\r
- internal bool IsSimpleType\r
- {\r
- get { return isSimpleType; }\r
- set { isSimpleType = value; }\r
- }\r
-\r
- internal string Documentation\r
- {\r
- set { documentation = value; }\r
- get { return documentation; }\r
- }\r
-\r
- internal bool IncludeInSchema\r
- {\r
- get { return includeInSchema; }\r
- set { includeInSchema = value; }\r
- }\r
- \r
- internal bool IsNullable\r
- {\r
- get { return isNullable; }\r
- set { isNullable = value; }\r
- }\r
-\r
- internal XmlTypeMapping GetRealTypeMap (string objectFullTypeName)\r
- {\r
- // Returns the map for a subtype of this map's type\r
-\r
- objectFullTypeName = objectFullTypeName.Replace ('+','.');\r
- if (TypeFullName == objectFullTypeName) return this;\r
- for (int n=0; n<_derivedTypes.Count; n++) {\r
- XmlTypeMapping map = (XmlTypeMapping) _derivedTypes[n];\r
- if (map.TypeFullName == objectFullTypeName) return map;\r
- }\r
- \r
- return null;\r
- }\r
-\r
- internal XmlTypeMapping GetRealElementMap (string name, string ens)\r
- {\r
- if (xmlType == name && xmlTypeNamespace == ens) return this;\r
- foreach (XmlTypeMapping map in _derivedTypes)\r
- if (map.xmlType == name && map.xmlTypeNamespace == ens) return map;\r
- \r
- return null;\r
- }\r
- \r
- internal void UpdateRoot (XmlQualifiedName qname)\r
- {\r
- if (qname != null) {\r
- this._elementName = qname.Name;\r
- this._namespace = qname.Namespace;\r
- }\r
- }\r
- }\r
-\r
+using System.Xml.Schema;
+using System.Reflection;
+
+namespace System.Xml.Serialization
+{
+ public class XmlTypeMapping : XmlMapping
+ {
+ private string xmlType;
+ private string xmlTypeNamespace;
+ TypeData type;
+ XmlTypeMapping baseMap;
+ bool multiReferenceType = false;
+ bool isSimpleType;
+ string documentation;
+ bool includeInSchema;
+ bool isNullable = true;
+
+ ArrayList _derivedTypes = new ArrayList();
+
+ internal XmlTypeMapping(string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)
+ : base (elementName, ns)
+ {
+ this.type = typeData;
+ this.xmlType = xmlType;
+ this.xmlTypeNamespace = xmlTypeNamespace;
+ }
+
+#if !NET_2_0
+ public string ElementName
+ {
+ get { return _elementName; }
+ }
+
+ public string Namespace
+ {
+ get { return _namespace; }
+ }
+#endif
+
+ public string TypeFullName
+ {
+ get { return type.FullTypeName; }
+ }
+
+ public string TypeName
+ {
+ get { return type.TypeName; }
+ }
+
+#if NET_2_0
+ public string XsdTypeName
+ {
+ get { return XmlType; }
+ }
+
+ public string XsdTypeNamespace
+ {
+ get { return XmlTypeNamespace; }
+ }
+#endif
+
+ internal TypeData TypeData
+ {
+ get { return type; }
+ }
+
+ internal string XmlType
+ {
+ get { return xmlType; }
+ set { xmlType = value; }
+ }
+
+ internal string XmlTypeNamespace
+ {
+ get { return xmlTypeNamespace ?? string.Empty; }
+ set { xmlTypeNamespace = value; }
+ }
+
+ internal bool HasXmlTypeNamespace
+ {
+ get { return xmlTypeNamespace != null; }
+ }
+
+ internal ArrayList DerivedTypes
+ {
+ get { return _derivedTypes; }
+ set { _derivedTypes = value; }
+ }
+
+ internal bool MultiReferenceType
+ {
+ get { return multiReferenceType; }
+ set { multiReferenceType = value; }
+ }
+
+ internal XmlTypeMapping BaseMap
+ {
+ get { return baseMap; }
+ set { baseMap = value; }
+ }
+
+ internal bool IsSimpleType
+ {
+ get { return isSimpleType; }
+ set { isSimpleType = value; }
+ }
+
+ internal string Documentation
+ {
+ set { documentation = value; }
+ get { return documentation; }
+ }
+
+ internal bool IncludeInSchema
+ {
+ get { return includeInSchema; }
+ set { includeInSchema = value; }
+ }
+
+ internal bool IsNullable
+ {
+ get { return isNullable; }
+ set { isNullable = value; }
+ }
+
+ internal XmlTypeMapping GetRealTypeMap (Type objectType)
+ {
+ if (TypeData.SchemaType == SchemaTypes.Enum)
+ return this;
+
+ // Returns the map for a subtype of this map's type
+ if (TypeData.Type == objectType) return this;
+ for (int n=0; n<_derivedTypes.Count; n++) {
+ XmlTypeMapping map = (XmlTypeMapping) _derivedTypes[n];
+ if (map.TypeData.Type == objectType) return map;
+ }
+
+ return null;
+ }
+
+ internal XmlTypeMapping GetRealElementMap (string name, string ens)
+ {
+ if (xmlType == name && XmlTypeNamespace == ens) return this;
+ foreach (XmlTypeMapping map in _derivedTypes)
+ if (map.xmlType == name && map.XmlTypeNamespace == ens) return map;
+
+ return null;
+ }
+
+ internal void UpdateRoot (XmlQualifiedName qname)
+ {
+ if (qname != null) {
+ this._elementName = qname.Name;
+ this._namespace = qname.Namespace;
+ }
+ }
+ }
+
// Mapping info for XmlSerializable
internal class XmlSerializableMapping : XmlTypeMapping
{
XmlSchema _schema;
+#if NET_2_0 && !MOONLIGHT
+ XmlSchemaComplexType _schemaType;
+ XmlQualifiedName _schemaTypeName;
+#endif
- internal XmlSerializableMapping(string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)
+ internal XmlSerializableMapping(XmlRootAttribute root, string elementName, string ns, TypeData typeData, string xmlType, string xmlTypeNamespace)
: base(elementName, ns, typeData, xmlType, xmlTypeNamespace)
{
- IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance(typeData.Type);
+#if NET_2_0 && !MOONLIGHT
+ XmlSchemaProviderAttribute schemaProvider = (XmlSchemaProviderAttribute) Attribute.GetCustomAttribute (typeData.Type, typeof (XmlSchemaProviderAttribute));
+
+ if (schemaProvider != null) {
+ string method = schemaProvider.MethodName;
+ MethodInfo mi = typeData.Type.GetMethod (method, BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
+ if (mi == null)
+ throw new InvalidOperationException (String.Format ("Type '{0}' must implement public static method '{1}'", typeData.Type, method));
+ if (!typeof (XmlQualifiedName).IsAssignableFrom (mi.ReturnType) &&
+ // LAMESPEC: it is undocumented. (We don't have to tell users about it in the error message.)
+ // Also do not add such a silly compatibility test to assert that it does not raise an error.
+ !typeof (XmlSchemaComplexType).IsAssignableFrom (mi.ReturnType))
+ throw new InvalidOperationException (String.Format ("Method '{0}' indicated by XmlSchemaProviderAttribute must have its return type as XmlQualifiedName", method));
+ XmlSchemaSet xs = new XmlSchemaSet ();
+ object retVal = mi.Invoke (null, new object [] { xs });
+ _schemaTypeName = XmlQualifiedName.Empty;
+ if (retVal == null)
+ return;
+
+ if (retVal is XmlSchemaComplexType) {
+ _schemaType = (XmlSchemaComplexType) retVal;
+ if (!_schemaType.QualifiedName.IsEmpty)
+ _schemaTypeName = _schemaType.QualifiedName;
+ else
+ _schemaTypeName = new XmlQualifiedName (xmlType, xmlTypeNamespace);
+ }
+ else if (retVal is XmlQualifiedName) {
+ _schemaTypeName = (XmlQualifiedName)retVal;
+ }
+ else
+ throw new InvalidOperationException (
+ String.Format ("Method {0}.{1}() specified by XmlSchemaProviderAttribute has invalid signature: return type must be compatible with System.Xml.XmlQualifiedName.", typeData.Type.Name, method));
+
+ // defaultNamespace at XmlReflectionImporter takes precedence for Namespace, but not for XsdTypeNamespace.
+ UpdateRoot (new XmlQualifiedName (root != null ? root.ElementName : _schemaTypeName.Name, root != null ? root.Namespace : Namespace ?? _schemaTypeName.Namespace));
+ XmlTypeNamespace = _schemaTypeName.Namespace;
+ XmlType = _schemaTypeName.Name;
+
+ if (!_schemaTypeName.IsEmpty && xs.Count > 0) {
+ XmlSchema [] schemas = new XmlSchema [xs.Count];
+ xs.CopyTo (schemas, 0);
+ _schema = schemas [0];
+ }
+
+ return;
+ }
+#endif
+#if NET_2_0 && !MOONLIGHT
+ IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance (typeData.Type, true);
+ try {
+ _schema = serializable.GetSchema();
+ } catch (Exception) {
+ // LAMESPEC: .NET has a bad exception catch and swallows it silently.
+ }
+#else
+ IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance (typeData.Type);
_schema = serializable.GetSchema();
+#endif
+#if !MOONLIGHT
if (_schema != null)
{
if (_schema.Id == null || _schema.Id.Length == 0)
throw new InvalidOperationException("Schema Id is missing. The schema returned from " + typeData.Type.FullName + ".GetSchema() must have an Id.");
}
+#endif
}
internal XmlSchema Schema
{
get { return _schema; }
}
+
+#if NET_2_0 && !MOONLIGHT
+ internal XmlSchemaType SchemaType {
+ get { return _schemaType; }
+ }
+
+ internal XmlQualifiedName SchemaTypeName {
+ get { return _schemaTypeName; }
+ }
+#endif
}
- // Mapping info for classes and structs\r
-\r
- internal class ClassMap: ObjectMap\r
- {\r
- Hashtable _elements = new Hashtable ();\r
- ArrayList _elementMembers;\r
- Hashtable _attributeMembers;\r
- XmlTypeMapMemberAttribute[] _attributeMembersArray;\r
- XmlTypeMapElementInfo[] _elementsByIndex;\r
- ArrayList _flatLists;\r
- ArrayList _allMembers = new ArrayList ();\r
- ArrayList _membersWithDefault;\r
- ArrayList _listMembers;\r
- XmlTypeMapMemberAnyElement _defaultAnyElement;\r
- XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;\r
- XmlTypeMapMemberNamespaces _namespaceDeclarations;\r
- XmlTypeMapMember _xmlTextCollector;\r
- XmlTypeMapMember _returnMember;\r
- bool _ignoreMemberNamespace;\r
- bool _canBeSimpleType = true;\r
-\r
- public void AddMember (XmlTypeMapMember member)\r
- {\r
- _allMembers.Add (member);\r
- \r
- if (!(member.DefaultValue is System.DBNull) && member.DefaultValue != null) {\r
- if (_membersWithDefault == null) _membersWithDefault = new ArrayList ();\r
- _membersWithDefault.Add (member);\r
- }\r
- \r
- if (member.IsReturnValue)\r
- _returnMember = member;\r
- \r
- if (member is XmlTypeMapMemberAttribute)\r
- {\r
- XmlTypeMapMemberAttribute atm = (XmlTypeMapMemberAttribute)member;\r
- if (_attributeMembers == null) _attributeMembers = new Hashtable();\r
- string key = BuildKey (atm.AttributeName, atm.Namespace);\r
- if (_attributeMembers.ContainsKey (key))\r
- throw new InvalidOperationException ("The XML attribute named '" + atm.AttributeName + "' from namespace '" + atm.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");\r
- member.Index = _attributeMembers.Count;\r
- _attributeMembers.Add (key, member);\r
- return;\r
- }\r
- else if (member is XmlTypeMapMemberFlatList)\r
- {\r
- RegisterFlatList ((XmlTypeMapMemberFlatList)member);\r
- }\r
- else if (member is XmlTypeMapMemberAnyElement)\r
- {\r
- XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement) member;\r
- if (mem.IsDefaultAny) _defaultAnyElement = mem;\r
- if (mem.TypeData.IsListType) RegisterFlatList (mem);\r
- }\r
- else if (member is XmlTypeMapMemberAnyAttribute)\r
- {\r
- _defaultAnyAttribute = (XmlTypeMapMemberAnyAttribute) member;\r
- return;\r
- }\r
- else if (member is XmlTypeMapMemberNamespaces)\r
- {\r
- _namespaceDeclarations = (XmlTypeMapMemberNamespaces) member;\r
- return;\r
- }\r
-\r
- if (member is XmlTypeMapMemberElement && ((XmlTypeMapMemberElement)member).IsXmlTextCollector)\r
- {\r
- if (_xmlTextCollector != null) throw new InvalidOperationException ("XmlTextAttribute can only be applied once in a class");\r
- _xmlTextCollector = member;\r
- }\r
-\r
- if (_elementMembers == null) {\r
- _elementMembers = new ArrayList();\r
- _elements = new Hashtable();\r
- }\r
-\r
- member.Index = _elementMembers.Count;\r
- _elementMembers.Add (member);\r
-\r
- ICollection elemsInfo = ((XmlTypeMapMemberElement)member).ElementInfo;\r
- foreach (XmlTypeMapElementInfo elem in elemsInfo)\r
- {\r
- string key = BuildKey (elem.ElementName, elem.Namespace);\r
- if (_elements.ContainsKey (key)) \r
- throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");\r
- _elements.Add (key, elem);\r
+ // Mapping info for classes and structs
+
+ internal class ClassMap: ObjectMap
+ {
+ Hashtable _elements = new Hashtable ();
+ ArrayList _elementMembers;
+ Hashtable _attributeMembers;
+ XmlTypeMapMemberAttribute[] _attributeMembersArray;
+ XmlTypeMapElementInfo[] _elementsByIndex;
+ ArrayList _flatLists;
+ ArrayList _allMembers = new ArrayList ();
+ ArrayList _membersWithDefault;
+ ArrayList _listMembers;
+ XmlTypeMapMemberAnyElement _defaultAnyElement;
+ XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;
+ XmlTypeMapMemberNamespaces _namespaceDeclarations;
+ XmlTypeMapMember _xmlTextCollector;
+ XmlTypeMapMember _returnMember;
+ bool _ignoreMemberNamespace;
+ bool _canBeSimpleType = true;
+ bool? _isOrderDependentMap;
+
+ public void AddMember (XmlTypeMapMember member)
+ {
+ // If GlobalIndex has not been set, set it now
+ if (member.GlobalIndex == -1)
+ member.GlobalIndex = _allMembers.Count;
+
+ _allMembers.Add (member);
+
+ if (!(member.DefaultValue is System.DBNull) && member.DefaultValue != null) {
+ if (_membersWithDefault == null) _membersWithDefault = new ArrayList ();
+ _membersWithDefault.Add (member);
+ }
+
+ if (member.IsReturnValue)
+ _returnMember = member;
+
+ if (member is XmlTypeMapMemberAttribute)
+ {
+ XmlTypeMapMemberAttribute atm = (XmlTypeMapMemberAttribute)member;
+ if (_attributeMembers == null) _attributeMembers = new Hashtable();
+ string key = BuildKey (atm.AttributeName, atm.Namespace, -1);
+ if (_attributeMembers.ContainsKey (key))
+ throw new InvalidOperationException ("The XML attribute named '" + atm.AttributeName + "' from namespace '" + atm.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");
+ member.Index = _attributeMembers.Count;
+ _attributeMembers.Add (key, member);
+ return;
+ }
+ else if (member is XmlTypeMapMemberFlatList)
+ {
+ RegisterFlatList ((XmlTypeMapMemberFlatList)member);
+ }
+ else if (member is XmlTypeMapMemberAnyElement)
+ {
+ XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement) member;
+ if (mem.IsDefaultAny) _defaultAnyElement = mem;
+ if (mem.TypeData.IsListType) RegisterFlatList (mem);
+ }
+ else if (member is XmlTypeMapMemberAnyAttribute)
+ {
+ _defaultAnyAttribute = (XmlTypeMapMemberAnyAttribute) member;
+ return;
+ }
+ else if (member is XmlTypeMapMemberNamespaces)
+ {
+ _namespaceDeclarations = (XmlTypeMapMemberNamespaces) member;
+ return;
+ }
+
+ if (member is XmlTypeMapMemberElement && ((XmlTypeMapMemberElement)member).IsXmlTextCollector)
+ {
+ if (_xmlTextCollector != null) throw new InvalidOperationException ("XmlTextAttribute can only be applied once in a class");
+ _xmlTextCollector = member;
+ }
+
+ if (_elementMembers == null) {
+ _elementMembers = new ArrayList();
+ _elements = new Hashtable();
+ }
+
+ member.Index = _elementMembers.Count;
+ _elementMembers.Add (member);
+
+ ICollection elemsInfo = ((XmlTypeMapMemberElement)member).ElementInfo;
+ foreach (XmlTypeMapElementInfo elem in elemsInfo)
+ {
+ string key = BuildKey (elem.ElementName, elem.Namespace, elem.ExplicitOrder);
+ if (_elements.ContainsKey (key))
+ throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");
+ _elements.Add (key, elem);
}
if (member.TypeData.IsListType && member.TypeData.Type != null && !member.TypeData.Type.IsArray) {
- if (_listMembers == null) _listMembers = new ArrayList ();\r
- _listMembers.Add (member);\r
- }\r
- }\r
-\r
- void RegisterFlatList (XmlTypeMapMemberExpandable member)\r
- {\r
- if (_flatLists == null) _flatLists = new ArrayList ();\r
- member.FlatArrayIndex = _flatLists.Count;\r
- _flatLists.Add (member);\r
- }\r
-\r
- public XmlTypeMapMemberAttribute GetAttribute (string name, string ns)\r
- {\r
- if (_attributeMembers == null) return null;\r
- return (XmlTypeMapMemberAttribute)_attributeMembers [BuildKey(name,ns)];\r
- }\r
-\r
- public XmlTypeMapElementInfo GetElement (string name, string ns)\r
- {\r
- if (_elements == null) return null;\r
- return (XmlTypeMapElementInfo)_elements [BuildKey(name,ns)];\r
- }\r
- \r
- public XmlTypeMapElementInfo GetElement (int index)\r
- {\r
- if (_elements == null) return null;\r
- \r
- if (_elementsByIndex == null)\r
- {\r
- _elementsByIndex = new XmlTypeMapElementInfo [_elementMembers.Count];\r
- foreach (XmlTypeMapMemberElement mem in _elementMembers)\r
- {\r
- if (mem.ElementInfo.Count != 1) \r
- throw new InvalidOperationException ("Read by order only possible for encoded/bare format");\r
- \r
- _elementsByIndex [mem.Index] = (XmlTypeMapElementInfo) mem.ElementInfo [0];\r
- }\r
- }\r
- \r
- return _elementsByIndex [index];\r
- }\r
- \r
- private string BuildKey (string name, string ns)\r
- {\r
- if (_ignoreMemberNamespace) return name;\r
- else return name + " / " + ns;\r
- }\r
- \r
- public ICollection AllElementInfos\r
- {\r
- get { return _elements.Values; }\r
- }\r
- \r
- \r
- public bool IgnoreMemberNamespace\r
- {\r
- get { return _ignoreMemberNamespace; }\r
- set { _ignoreMemberNamespace = value; }\r
- }\r
-\r
- public XmlTypeMapMember FindMember (string name)\r
- {\r
- for (int n=0; n<_allMembers.Count; n++)\r
- if (((XmlTypeMapMember)_allMembers[n]).Name == name) return (XmlTypeMapMember)_allMembers[n];\r
- return null;\r
- }\r
-\r
- public XmlTypeMapMemberAnyElement DefaultAnyElementMember\r
- {\r
- get { return _defaultAnyElement; }\r
- }\r
-\r
- public XmlTypeMapMemberAnyAttribute DefaultAnyAttributeMember\r
- {\r
- get { return _defaultAnyAttribute; }\r
- }\r
-\r
- public XmlTypeMapMemberNamespaces NamespaceDeclarations\r
- {\r
- get { return _namespaceDeclarations; }\r
- }\r
-\r
- public ICollection AttributeMembers\r
- {\r
- get \r
- {\r
- if (_attributeMembers == null) return null;\r
- if (_attributeMembersArray != null) return _attributeMembersArray;\r
- \r
- _attributeMembersArray = new XmlTypeMapMemberAttribute[_attributeMembers.Count];\r
- foreach (XmlTypeMapMemberAttribute mem in _attributeMembers.Values)\r
- _attributeMembersArray [mem.Index] = mem;\r
- return _attributeMembersArray;\r
- }\r
- }\r
-\r
- public ICollection ElementMembers\r
- {\r
- get { return _elementMembers; }\r
- }\r
-\r
- public ArrayList AllMembers\r
- {\r
- get { return _allMembers; }\r
- }\r
-\r
- public ArrayList FlatLists\r
- {\r
- get { return _flatLists; }\r
- }\r
- \r
- public ArrayList MembersWithDefault\r
- {\r
- get { return _membersWithDefault; }\r
+ if (_listMembers == null) _listMembers = new ArrayList ();
+ _listMembers.Add (member);
+ }
+ }
+
+ void RegisterFlatList (XmlTypeMapMemberExpandable member)
+ {
+ if (_flatLists == null) _flatLists = new ArrayList ();
+ member.FlatArrayIndex = _flatLists.Count;
+ _flatLists.Add (member);
+ }
+
+ public XmlTypeMapMemberAttribute GetAttribute (string name, string ns)
+ {
+ if (_attributeMembers == null) return null;
+ return (XmlTypeMapMemberAttribute)_attributeMembers [BuildKey (name,ns, -1)];
+ }
+
+ public XmlTypeMapElementInfo GetElement (string name, string ns, int order)
+ {
+ if (_elements == null) return null;
+ return (XmlTypeMapElementInfo)_elements [BuildKey (name,ns, order)];
+ }
+
+ public XmlTypeMapElementInfo GetElement(string name, string ns)
+ {
+ if (_elements == null) return null;
+
+ foreach (XmlTypeMapElementInfo info in _elements.Values)
+ if (info.ElementName == name && info.Namespace == ns)
+ return info;
+
+ return null;
+ }
+
+ public XmlTypeMapElementInfo GetElement (int index)
+ {
+ if (_elements == null) return null;
+
+ if (_elementsByIndex == null)
+ {
+ _elementsByIndex = new XmlTypeMapElementInfo [_elementMembers.Count];
+ foreach (XmlTypeMapMemberElement mem in _elementMembers)
+ {
+ if (mem.ElementInfo.Count != 1)
+ throw new InvalidOperationException ("Read by order only possible for encoded/bare format");
+
+ _elementsByIndex [mem.Index] = (XmlTypeMapElementInfo) mem.ElementInfo [0];
+ }
+ }
+ if (index >= _elementMembers.Count)
+ return null;
+ return _elementsByIndex [index];
+ }
+
+ private string BuildKey (string name, string ns, int explicitOrder)
+ {
+ if (_ignoreMemberNamespace) return name;
+ else return name + " / " + ns + (explicitOrder < 0 ? "" : "/" + explicitOrder);
+ }
+
+ public ICollection AllElementInfos
+ {
+ get { return _elements.Values; }
+ }
+
+
+ public bool IgnoreMemberNamespace
+ {
+ get { return _ignoreMemberNamespace; }
+ set { _ignoreMemberNamespace = value; }
+ }
+
+ public bool IsOrderDependentMap {
+ get {
+ if (_isOrderDependentMap == null) {
+ _isOrderDependentMap = false;
+ foreach (XmlTypeMapElementInfo ei in _elements.Values)
+ if (ei.ExplicitOrder >= 0) {
+ _isOrderDependentMap = true;
+ break;
+ }
+ }
+ return (bool) _isOrderDependentMap;
+ }
+ }
+
+ public XmlTypeMapMember FindMember (string name)
+ {
+ for (int n=0; n<_allMembers.Count; n++)
+ if (((XmlTypeMapMember)_allMembers[n]).Name == name) return (XmlTypeMapMember)_allMembers[n];
+ return null;
+ }
+
+ public XmlTypeMapMemberAnyElement DefaultAnyElementMember
+ {
+ get { return _defaultAnyElement; }
+ }
+
+ public XmlTypeMapMemberAnyAttribute DefaultAnyAttributeMember
+ {
+ get { return _defaultAnyAttribute; }
+ }
+
+ public XmlTypeMapMemberNamespaces NamespaceDeclarations
+ {
+ get { return _namespaceDeclarations; }
+ }
+
+ public ICollection AttributeMembers
+ {
+ get
+ {
+ if (_attributeMembers == null) return null;
+ if (_attributeMembersArray != null) return _attributeMembersArray;
+
+ _attributeMembersArray = new XmlTypeMapMemberAttribute[_attributeMembers.Count];
+ foreach (XmlTypeMapMemberAttribute mem in _attributeMembers.Values)
+ _attributeMembersArray [mem.Index] = mem;
+ return _attributeMembersArray;
+ }
+ }
+
+ public ICollection ElementMembers
+ {
+ get { return _elementMembers; }
+ }
+
+ public ArrayList AllMembers
+ {
+ get { return _allMembers; }
+ }
+
+ public ArrayList FlatLists
+ {
+ get { return _flatLists; }
+ }
+
+ public ArrayList MembersWithDefault
+ {
+ get { return _membersWithDefault; }
}
- public ArrayList ListMembers\r
- {\r
- get { return _listMembers; }\r
- }
-\r
- public XmlTypeMapMember XmlTextCollector\r
- {\r
- get { return _xmlTextCollector; }\r
- }\r
- \r
- public XmlTypeMapMember ReturnMember\r
- {\r
- get { return _returnMember; }\r
- }\r
-\r
- public XmlQualifiedName SimpleContentBaseType\r
- {\r
- get\r
- {\r
- if (!_canBeSimpleType || _elementMembers == null || _elementMembers.Count != 1) return null;\r
- XmlTypeMapMemberElement member = (XmlTypeMapMemberElement) _elementMembers[0];\r
- if (member.ElementInfo.Count != 1) return null;\r
- XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo[0];\r
- if (!einfo.IsTextElement) return null;\r
- if (member.TypeData.SchemaType == SchemaTypes.Primitive || member.TypeData.SchemaType == SchemaTypes.Enum)\r
- return new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);\r
- return null;\r
- }\r
- }\r
- \r
- public void SetCanBeSimpleType (bool can)\r
- {\r
- _canBeSimpleType = can;\r
- }\r
-\r
- public bool HasSimpleContent\r
- {\r
- get\r
- {\r
- return SimpleContentBaseType != null;\r
- }\r
- }\r
-\r
- }\r
-\r
- // Mapping info for arrays and lists\r
-\r
- internal class ListMap: ObjectMap\r
- {\r
- XmlTypeMapElementInfoList _itemInfo;\r
- bool _gotNestedMapping;\r
+ public ArrayList ListMembers
+ {
+ get { return _listMembers; }
+ }
+
+ public XmlTypeMapMember XmlTextCollector
+ {
+ get { return _xmlTextCollector; }
+ }
+
+ public XmlTypeMapMember ReturnMember
+ {
+ get { return _returnMember; }
+ }
+
+ public XmlQualifiedName SimpleContentBaseType
+ {
+ get
+ {
+ if (!_canBeSimpleType || _elementMembers == null || _elementMembers.Count != 1) return null;
+ XmlTypeMapMemberElement member = (XmlTypeMapMemberElement) _elementMembers[0];
+ if (member.ElementInfo.Count != 1) return null;
+ XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo[0];
+ if (!einfo.IsTextElement) return null;
+ if (member.TypeData.SchemaType == SchemaTypes.Primitive || member.TypeData.SchemaType == SchemaTypes.Enum)
+ return new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
+ return null;
+ }
+ }
+
+ public void SetCanBeSimpleType (bool can)
+ {
+ _canBeSimpleType = can;
+ }
+
+ public bool HasSimpleContent
+ {
+ get
+ {
+ return SimpleContentBaseType != null;
+ }
+ }
+
+ }
+
+ // Mapping info for arrays and lists
+
+ internal class ListMap: ObjectMap
+ {
+ XmlTypeMapElementInfoList _itemInfo;
+ bool _gotNestedMapping;
XmlTypeMapping _nestedArrayMapping;
string _choiceMember;
-\r
- public bool IsMultiArray\r
- {\r
- get\r
- {\r
- return (NestedArrayMapping != null);\r
- }\r
- }\r
-\r
+
+ public bool IsMultiArray
+ {
+ get
+ {
+ return (NestedArrayMapping != null);
+ }
+ }
+
public string ChoiceMember
{
get { return _choiceMember; }
set { _choiceMember = value; }
}
- public XmlTypeMapping NestedArrayMapping\r
- {\r
- get\r
- {\r
- if (_gotNestedMapping) return _nestedArrayMapping;\r
- _gotNestedMapping = true;\r
-\r
- _nestedArrayMapping = ((XmlTypeMapElementInfo)_itemInfo[0]).MappedType;\r
-\r
- if (_nestedArrayMapping == null) return null;\r
- \r
- if (_nestedArrayMapping.TypeData.SchemaType != SchemaTypes.Array) {\r
- _nestedArrayMapping = null; return null;\r
- }\r
-\r
- foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
- if (elem.MappedType != _nestedArrayMapping) {\r
- _nestedArrayMapping = null;\r
- return null;\r
- }\r
-\r
- return _nestedArrayMapping;\r
- }\r
- }\r
-\r
- public XmlTypeMapElementInfoList ItemInfo\r
- {\r
-\r
- get { return _itemInfo; }\r
- set { _itemInfo = value; }\r
- }\r
-\r
- public XmlTypeMapElementInfo FindElement (object ob, int index, object memberValue)\r
- {\r
- if (_itemInfo.Count == 1) \r
- return (XmlTypeMapElementInfo) _itemInfo[0];\r
+ public XmlTypeMapping NestedArrayMapping
+ {
+ get
+ {
+ if (_gotNestedMapping) return _nestedArrayMapping;
+ _gotNestedMapping = true;
+
+ _nestedArrayMapping = ((XmlTypeMapElementInfo)_itemInfo[0]).MappedType;
+
+ if (_nestedArrayMapping == null) return null;
+
+ if (_nestedArrayMapping.TypeData.SchemaType != SchemaTypes.Array) {
+ _nestedArrayMapping = null; return null;
+ }
+
+ foreach (XmlTypeMapElementInfo elem in _itemInfo)
+ if (elem.MappedType != _nestedArrayMapping) {
+ _nestedArrayMapping = null;
+ return null;
+ }
+
+ return _nestedArrayMapping;
+ }
+ }
+
+ public XmlTypeMapElementInfoList ItemInfo
+ {
+
+ get { return _itemInfo; }
+ set { _itemInfo = value; }
+ }
+
+ public XmlTypeMapElementInfo FindElement (object ob, int index, object memberValue)
+ {
+ if (_itemInfo.Count == 1)
+ return (XmlTypeMapElementInfo) _itemInfo[0];
else if (_choiceMember != null && index != -1)
{
Array values = (Array) XmlTypeMapMember.GetValue (ob, _choiceMember);
if (elem.ChoiceValue != null && elem.ChoiceValue.Equals (val))
return elem;
}
- else\r
- {\r
- if (memberValue == null) return null;\r
- Type type = memberValue.GetType();\r
- foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
- if (elem.TypeData.Type == type) return elem;\r
- }\r
- return null;\r
- } \r
-\r
- public XmlTypeMapElementInfo FindElement (string elementName, string ns)\r
- {\r
- foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
- if (elem.ElementName == elementName && elem.Namespace == ns) return elem;\r
- return null;\r
- }\r
- \r
- public XmlTypeMapElementInfo FindTextElement ()\r
- {\r
- foreach (XmlTypeMapElementInfo elem in _itemInfo)\r
- if (elem.IsTextElement) return elem;\r
- return null;\r
- }\r
- \r
- public string GetSchemaArrayName ()\r
- {\r
- XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) _itemInfo[0];\r
- if (einfo.MappedType != null) return TypeTranslator.GetArrayName (einfo.MappedType.XmlType);\r
- else return TypeTranslator.GetArrayName (einfo.TypeData.XmlType);\r
- }\r
-\r
- public void GetArrayType (int itemCount, out string localName, out string ns)\r
- {\r
- string arrayDim;\r
- if (itemCount != -1) arrayDim = "[" + itemCount + "]";\r
- else arrayDim = "[]";\r
-\r
- XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) _itemInfo[0];\r
- if (info.TypeData.SchemaType == SchemaTypes.Array)\r
- {\r
- string nm;\r
- ((ListMap)info.MappedType.ObjectMap).GetArrayType (-1, out nm, out ns);\r
- localName = nm + arrayDim;\r
- }\r
- else \r
- {\r
- if (info.MappedType != null)\r
- {\r
- localName = info.MappedType.XmlType + arrayDim;\r
- ns = info.MappedType.Namespace;\r
- }\r
- else \r
- {\r
- localName = info.TypeData.XmlType + arrayDim;\r
- ns = info.DataTypeNamespace;\r
- }\r
- }\r
- }\r
-\r
- public override bool Equals (object other)\r
- {\r
- ListMap lmap = other as ListMap;\r
- if (lmap == null) return false;\r
-\r
- if (_itemInfo.Count != lmap._itemInfo.Count) return false;\r
- for (int n=0; n<_itemInfo.Count; n++)\r
- if (!_itemInfo[n].Equals (lmap._itemInfo[n])) return false;\r
- return true;\r
- }\r
-\r
- public override int GetHashCode ()\r
- {\r
- return base.GetHashCode ();\r
- }\r
- }\r
-\r
- internal class EnumMap: ObjectMap\r
- {\r
- EnumMapMember[] _members;\r
- bool _isFlags;\r
-\r
- public class EnumMapMember\r
- {\r
- string _xmlName;\r
- string _enumName;\r
- string _documentation;\r
-\r
- public EnumMapMember (string xmlName, string enumName)\r
- {\r
- _xmlName = xmlName;\r
- _enumName = enumName;\r
- }\r
-\r
- public string XmlName\r
- {\r
- get { return _xmlName; }\r
- }\r
-\r
- public string EnumName\r
- {\r
- get { return _enumName; }\r
- }\r
-\r
- public string Documentation\r
- {\r
- get { return _documentation; }\r
- set { _documentation = value; }\r
- }\r
- }\r
-\r
- public EnumMap (EnumMapMember[] members, bool isFlags)\r
- {\r
- _members = members;\r
- _isFlags = isFlags;\r
- }\r
- \r
- public bool IsFlags\r
- {\r
- get { return _isFlags; }\r
- }\r
-\r
- public EnumMapMember[] Members\r
- {\r
- get { return _members; }\r
- }\r
-\r
- public string GetXmlName (object enumValue)\r
- {\r
- string enumName = enumValue.ToString();\r
-\r
- if (_isFlags && enumName.IndexOf (',') != -1)\r
- {\r
- System.Text.StringBuilder sb = new System.Text.StringBuilder ();\r
- string[] enumNames = enumValue.ToString().Split (',');\r
- foreach (string name in enumNames)\r
- {\r
- string tname = name.Trim();\r
- foreach (EnumMapMember mem in _members)\r
- if (mem.EnumName == tname) {\r
- sb.Append (mem.XmlName).Append (' ');\r
- break;\r
- }\r
- }\r
- sb.Remove (sb.Length-1, 1);\r
- return sb.ToString ();\r
- }\r
-\r
- foreach (EnumMapMember mem in _members)\r
- if (mem.EnumName == enumName) return mem.XmlName;\r
- \r
- // Enum default value will not be written\r
- // unless it is one of the enum legal values\r
- if (enumName == "0" && IsFlags)\r
- return String.Empty;\r
- else\r
- return Convert.ToInt64(enumValue).ToString(CultureInfo.InvariantCulture);\r
- }\r
-\r
- public string GetEnumName (string xmlName)\r
- {\r
- if (_isFlags && xmlName.Length == 0) \r
- return "0";\r
- \r
- if (_isFlags && xmlName.Trim().IndexOf (' ') != -1)\r
- {\r
- System.Text.StringBuilder sb = new System.Text.StringBuilder ();\r
- string[] enumNames = xmlName.ToString().Split (' ');\r
- foreach (string name in enumNames)\r
- {\r
- if (name == string.Empty) continue;\r
- string foundEnumValue = null;\r
- foreach (EnumMapMember mem in _members)\r
- if (mem.XmlName == name) { foundEnumValue = mem.EnumName; break; }\r
-\r
- if (foundEnumValue != null) sb.Append (foundEnumValue).Append (','); \r
- else return null;\r
- }\r
- sb.Remove (sb.Length-1, 1);\r
- return sb.ToString ();\r
- }\r
-\r
- foreach (EnumMapMember mem in _members)\r
- if (mem.XmlName == xmlName) return mem.EnumName;\r
- \r
- return null;\r
- }\r
- }\r
-}\r
+ else
+ {
+ if (memberValue == null) return null;
+ Type type = memberValue.GetType();
+ foreach (XmlTypeMapElementInfo elem in _itemInfo)
+ if (elem.TypeData.Type == type) return elem;
+ }
+ return null;
+ }
+
+ public XmlTypeMapElementInfo FindElement (string elementName, string ns)
+ {
+ foreach (XmlTypeMapElementInfo elem in _itemInfo)
+ if (elem.ElementName == elementName && elem.Namespace == ns) return elem;
+ return null;
+ }
+
+ public XmlTypeMapElementInfo FindTextElement ()
+ {
+ foreach (XmlTypeMapElementInfo elem in _itemInfo)
+ if (elem.IsTextElement) return elem;
+ return null;
+ }
+
+ public string GetSchemaArrayName ()
+ {
+ XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) _itemInfo[0];
+ if (einfo.MappedType != null) return TypeTranslator.GetArrayName (einfo.MappedType.XmlType);
+ else return TypeTranslator.GetArrayName (einfo.TypeData.XmlType);
+ }
+
+ public void GetArrayType (int itemCount, out string localName, out string ns)
+ {
+ string arrayDim;
+ if (itemCount != -1) arrayDim = "[" + itemCount + "]";
+ else arrayDim = "[]";
+
+ XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) _itemInfo[0];
+ if (info.TypeData.SchemaType == SchemaTypes.Array)
+ {
+ string nm;
+ ((ListMap)info.MappedType.ObjectMap).GetArrayType (-1, out nm, out ns);
+ localName = nm + arrayDim;
+ }
+ else
+ {
+ if (info.MappedType != null)
+ {
+ localName = info.MappedType.XmlType + arrayDim;
+ ns = info.MappedType.Namespace;
+ }
+ else
+ {
+ localName = info.TypeData.XmlType + arrayDim;
+ ns = info.DataTypeNamespace;
+ }
+ }
+ }
+
+ public override bool Equals (object other)
+ {
+ ListMap lmap = other as ListMap;
+ if (lmap == null) return false;
+
+ if (_itemInfo.Count != lmap._itemInfo.Count) return false;
+ for (int n=0; n<_itemInfo.Count; n++)
+ if (!_itemInfo[n].Equals (lmap._itemInfo[n])) return false;
+ return true;
+ }
+
+ public override int GetHashCode ()
+ {
+ return base.GetHashCode ();
+ }
+ }
+
+ internal class EnumMap: ObjectMap
+ {
+ readonly EnumMapMember[] _members;
+ readonly bool _isFlags;
+ readonly string[] _enumNames = null;
+ readonly string[] _xmlNames = null;
+ readonly long[] _values = null;
+
+ public class EnumMapMember
+ {
+ readonly string _xmlName;
+ readonly string _enumName;
+ readonly long _value;
+ string _documentation;
+
+ public EnumMapMember (string xmlName, string enumName)
+ : this (xmlName, enumName, 0)
+ {
+ }
+
+ public EnumMapMember (string xmlName, string enumName, long value)
+ {
+ _xmlName = xmlName;
+ _enumName = enumName;
+ _value = value;
+ }
+
+ public string XmlName
+ {
+ get { return _xmlName; }
+ }
+
+ public string EnumName
+ {
+ get { return _enumName; }
+ }
+
+ public long Value
+ {
+ get { return _value; }
+ }
+
+ public string Documentation
+ {
+ get { return _documentation; }
+ set { _documentation = value; }
+ }
+ }
+
+ public EnumMap (EnumMapMember[] members, bool isFlags)
+ {
+ _members = members;
+ _isFlags = isFlags;
+
+ _enumNames = new string[_members.Length];
+ _xmlNames = new string[_members.Length];
+ _values = new long[_members.Length];
+
+ for (int i = 0; i < _members.Length; i++) {
+ EnumMapMember mem = _members[i];
+ _enumNames[i] = mem.EnumName;
+ _xmlNames[i] = mem.XmlName;
+ _values[i] = mem.Value;
+ }
+ }
+
+ public bool IsFlags
+ {
+ get { return _isFlags; }
+ }
+
+ public EnumMapMember[] Members
+ {
+ get { return _members; }
+ }
+
+ public string[] EnumNames
+ {
+ get {
+ return _enumNames;
+ }
+ }
+
+ public string[] XmlNames
+ {
+ get {
+ return _xmlNames;
+ }
+ }
+
+ public long[] Values
+ {
+ get {
+ return _values;
+ }
+ }
+
+ public string GetXmlName (string typeName, object enumValue)
+ {
+ if (enumValue is string) {
+ throw new InvalidCastException ();
+ }
+
+ long value = 0;
+
+ try {
+ value = ((IConvertible) enumValue).ToInt64 (CultureInfo.CurrentCulture);
+ } catch (FormatException) {
+ throw new InvalidCastException ();
+ }
+
+ for (int i = 0; i < Values.Length; i++) {
+ if (Values[i] == value)
+ return XmlNames[i];
+ }
+
+ if (IsFlags && value == 0)
+ return string.Empty;
+
+ string xmlName = string.Empty;
+ if (IsFlags) {
+#if NET_2_0
+ xmlName = XmlCustomFormatter.FromEnum (value, XmlNames, Values, typeName);
+#else
+ xmlName = XmlCustomFormatter.FromEnum (value, XmlNames, Values);
+#endif
+ }
+
+ if (xmlName.Length == 0) {
+#if NET_2_0
+ throw new InvalidOperationException (string.Format(CultureInfo.CurrentCulture,
+ "'{0}' is not a valid value for {1}.", value, typeName));
+#else
+ return value.ToString (CultureInfo.InvariantCulture);
+#endif
+ }
+ return xmlName;
+ }
+
+ public string GetEnumName (string typeName, string xmlName)
+ {
+ if (_isFlags) {
+ xmlName = xmlName.Trim ();
+ if (xmlName.Length == 0)
+ return "0";
+
+ System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+ string[] enumNames = xmlName.Split (null);
+ foreach (string name in enumNames) {
+ if (name == string.Empty) continue;
+ string foundEnumValue = null;
+ for (int i = 0; i < XmlNames.Length; i++)
+ if (XmlNames[i] == name) {
+ foundEnumValue = EnumNames[i];
+ break;
+ }
+
+ if (foundEnumValue != null) {
+ if (sb.Length > 0)
+ sb.Append (',');
+ sb.Append (foundEnumValue);
+ } else {
+ throw new InvalidOperationException (string.Format (CultureInfo.CurrentCulture,
+ "'{0}' is not a valid value for {1}.", name, typeName));
+ }
+ }
+ return sb.ToString ();
+ }
+
+ foreach (EnumMapMember mem in _members)
+ if (mem.XmlName == xmlName) return mem.EnumName;
+
+ return null;
+ }
+ }
+}