private void RetrieveSerializableSchema()
{
if (_needSchema)
{
_needSchema = false;
if (_getSchemaMethod != null)
{
// get the type info
if (_schemas == null)
_schemas = new XmlSchemaSet();
object typeInfo = _getSchemaMethod.Invoke(null, new object[] { _schemas });
_xsiType = XmlQualifiedName.Empty;
if (typeInfo != null)
{
if (typeof(XmlSchemaType).IsAssignableFrom(_getSchemaMethod.ReturnType))
{
_xsdType = (XmlSchemaType)typeInfo;
// check if type is named
_xsiType = _xsdType.QualifiedName;
}
else if (typeof(XmlQualifiedName).IsAssignableFrom(_getSchemaMethod.ReturnType))
{
_xsiType = (XmlQualifiedName)typeInfo;
if (_xsiType.IsEmpty)
{
throw new InvalidOperationException(SR.Format(SR.XmlGetSchemaEmptyTypeName, _type.FullName, _getSchemaMethod.Name));
}
}
else
{
throw new InvalidOperationException(SR.Format(SR.XmlGetSchemaMethodReturnType, _type.Name, _getSchemaMethod.Name, typeof(XmlSchemaProviderAttribute).Name, typeof(XmlQualifiedName).FullName));
}
}
else
{
_any = true;
}
// make sure that user-specified schemas are valid
_schemas.ValidationEventHandler += new ValidationEventHandler(ValidationCallbackWithErrorCode);
_schemas.Compile();
// at this point we verified that the information returned by the IXmlSerializable is valid
// Now check to see if the type was referenced before:
// UNDONE check for the duplcate types
if (!_xsiType.IsEmpty)
{
// try to find the type in the schemas collection
if (_xsiType.Namespace != XmlSchema.Namespace)
{
ArrayList srcSchemas = (ArrayList)_schemas.Schemas(_xsiType.Namespace);
if (srcSchemas.Count == 0)
{
throw new InvalidOperationException(SR.Format(SR.XmlMissingSchema, _xsiType.Namespace));
}
if (srcSchemas.Count > 1)
{
throw new InvalidOperationException(SR.Format(SR.XmlGetSchemaInclude, _xsiType.Namespace, _getSchemaMethod.DeclaringType.FullName, _getSchemaMethod.Name));
}
XmlSchema s = (XmlSchema)srcSchemas[0];
if (s == null)
{
throw new InvalidOperationException(SR.Format(SR.XmlMissingSchema, _xsiType.Namespace));
}
_xsdType = (XmlSchemaType)s.SchemaTypes[_xsiType];
if (_xsdType == null)
{
throw new InvalidOperationException(SR.Format(SR.XmlGetSchemaTypeMissing, _getSchemaMethod.DeclaringType.FullName, _getSchemaMethod.Name, _xsiType.Name, _xsiType.Namespace));
}
_xsdType = _xsdType.Redefined != null ? _xsdType.Redefined : _xsdType;
}
}
}
else
{
IXmlSerializable serializable = (IXmlSerializable)Activator.CreateInstance(_type);
_schema = serializable.GetSchema();
if (_schema != null)
{
if (_schema.Id == null || _schema.Id.Length == 0) throw new InvalidOperationException(SR.Format(SR.XmlSerializableNameMissing1, _type.FullName));
}
}
}
}
}