XmlTypeMapping ImportListMapping (TypeData typeData, XmlRootAttribute root, string defaultNamespace, XmlAttributes atts, int nestingLevel)
{
Type type = typeData.Type;
ListMap obmap = new ListMap ();
if (!allowPrivateTypes)
ReflectionHelper.CheckSerializableType (type, true);
if (atts == null) atts = new XmlAttributes();
Type itemType = typeData.ListItemType;
// warning: byte[][] should not be considered multiarray
bool isMultiArray = (type.IsArray && (TypeTranslator.GetTypeData(itemType).SchemaType == SchemaTypes.Array) && itemType.IsArray);
XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
foreach (XmlArrayItemAttribute att in atts.XmlArrayItems)
{
if (att.Namespace != null && att.Form == XmlSchemaForm.Unqualified)
throw new InvalidOperationException ("XmlArrayItemAttribute.Form must not be Unqualified when it has an explicit Namespace value.");
if (att.NestingLevel != nestingLevel) continue;
Type elemType = (att.Type != null) ? att.Type : itemType;
XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (null, TypeTranslator.GetTypeData(elemType, att.DataType));
elem.Namespace = att.Namespace != null ? att.Namespace : defaultNamespace;
if (elem.Namespace == null) elem.Namespace = "";
elem.Form = att.Form;
if (att.Form == XmlSchemaForm.Unqualified)
elem.Namespace = string.Empty;
elem.IsNullable = att.IsNullable && CanBeNull (elem.TypeData);
elem.NestingLevel = att.NestingLevel;
if (isMultiArray) {
elem.MappedType = ImportListMapping (elemType, null, elem.Namespace, atts, nestingLevel + 1);
} else if (elem.TypeData.IsComplexType) {
elem.MappedType = ImportTypeMapping (elemType, null, elem.Namespace);
}
if (att.ElementName.Length != 0) {
elem.ElementName = XmlConvert.EncodeLocalName (att.ElementName);
} else if (elem.MappedType != null) {
elem.ElementName = elem.MappedType.ElementName;
} else {
elem.ElementName = TypeTranslator.GetTypeData (elemType).XmlType;
}
list.Add (elem);
}
if (list.Count == 0)
{
XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (null, TypeTranslator.GetTypeData (itemType));
if (isMultiArray)
elem.MappedType = ImportListMapping (itemType, null, defaultNamespace, atts, nestingLevel + 1);
else if (elem.TypeData.IsComplexType)
elem.MappedType = ImportTypeMapping (itemType, null, defaultNamespace);
if (elem.MappedType != null) {
elem.ElementName = elem.MappedType.XmlType;
} else {
elem.ElementName = TypeTranslator.GetTypeData (itemType).XmlType;
}
elem.Namespace = (defaultNamespace != null) ? defaultNamespace : "";
elem.IsNullable = CanBeNull (elem.TypeData);
list.Add (elem);
}
obmap.ItemInfo = list;
// If there can be different element names (types) in the array, then its name cannot
// be "ArrayOfXXX" it must be something like ArrayOfChoiceNNN
string baseName;
if (list.Count > 1) {
baseName = "ArrayOfChoice" + (arrayChoiceCount++);
} else {
XmlTypeMapElementInfo elem = ((XmlTypeMapElementInfo) list[0]);
if (elem.MappedType != null) {
baseName = TypeTranslator.GetArrayName (elem.MappedType.XmlType);
} else {
baseName = TypeTranslator.GetArrayName (elem.ElementName);
}
}
// Avoid name colisions
int nameCount = 1;
string name = baseName;
do {
XmlTypeMapping foundMap = helper.GetRegisteredSchemaType (name, defaultNamespace);
if (foundMap == null) nameCount = -1;
else if (obmap.Equals (foundMap.ObjectMap) && typeData.Type == foundMap.TypeData.Type) return foundMap;
else name = baseName + (nameCount++);
}
while (nameCount != -1);
XmlTypeMapping map = CreateTypeMapping (typeData, root, name, defaultNamespace);
map.ObjectMap = obmap;
// Register any of the including types as a derived class of object
XmlIncludeAttribute[] includes = (XmlIncludeAttribute[])type.GetCustomAttributes (typeof (XmlIncludeAttribute), false);
XmlTypeMapping objectMapping = ImportTypeMapping (typeof(object));
for (int i = 0; i < includes.Length; i++)
{
Type includedType = includes[i].Type;
objectMapping.DerivedTypes.Add(ImportTypeMapping (includedType, null, defaultNamespace));
}
// Register this map as a derived class of object
helper.RegisterSchemaType (map, name, defaultNamespace);
ImportTypeMapping (typeof(object)).DerivedTypes.Add (map);
return map;
}