private SpecialMapping ImportSpecialMapping(Type type, TypeDesc typeDesc, string ns, ImportContext context, RecursionLimiter limiter)
{
if (_specials == null)
_specials = new Hashtable();
SpecialMapping mapping = (SpecialMapping)_specials[type];
if (mapping != null)
{
CheckContext(mapping.TypeDesc, context);
return mapping;
}
if (typeDesc.Kind == TypeKind.Serializable)
{
SerializableMapping serializableMapping = null;
// get the schema method info
object[] attrs = type.GetCustomAttributes(typeof(XmlSchemaProviderAttribute), false);
if (attrs.Length > 0)
{
// new IXmlSerializable
XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0];
MethodInfo method = GetMethodFromSchemaProvider(provider, type);
serializableMapping = new SerializableMapping(method, provider.IsAny, ns);
XmlQualifiedName qname = serializableMapping.XsiType;
if (qname != null && !qname.IsEmpty)
{
if (_serializables == null)
_serializables = new NameTable();
SerializableMapping existingMapping = (SerializableMapping)_serializables[qname];
if (existingMapping != null)
{
if (existingMapping.Type == null)
{
serializableMapping = existingMapping;
}
else if (existingMapping.Type != type)
{
SerializableMapping next = existingMapping.Next;
existingMapping.Next = serializableMapping;
serializableMapping.Next = next;
}
}
else
{
XmlSchemaType xsdType = serializableMapping.XsdType;
if (xsdType != null)
SetBase(serializableMapping, xsdType.DerivedFrom);
_serializables[qname] = serializableMapping;
}
serializableMapping.TypeName = qname.Name;
serializableMapping.Namespace = qname.Namespace;
}
serializableMapping.TypeDesc = typeDesc;
serializableMapping.Type = type;
IncludeTypes(type.GetTypeInfo());
}
else
{
// old IXmlSerializable
serializableMapping = new SerializableMapping();
serializableMapping.TypeDesc = typeDesc;
serializableMapping.Type = type;
}
mapping = serializableMapping;
}
else
{
mapping = new SpecialMapping();
mapping.TypeDesc = typeDesc;
}
CheckContext(typeDesc, context);
_specials.Add(type, mapping);
_typeScope.AddTypeMapping(mapping);
return mapping;
}