throw new ComplexTypeRecoverableError(
"The BASE attribute must be specified for the " +
"RESTRICTION or EXTENSION element");
}
QName baseQName = parseBase(base);
// check if we're extending a simpleType which has a "final" setting which precludes this
Integer finalValue =
((Integer)fSimpleTypeFinalRegistry.get(fStringPool.toString(baseQName.uri) + "," +fStringPool.toString(baseQName.localpart)));
if(finalValue != null &&
(finalValue.intValue() == typeInfo.derivedBy))
throw new ComplexTypeRecoverableError(
"The simpleType " + base + " that " + typeName + " uses has a value of \"final\" which does not permit extension");
String baseTypeURI = fStringPool.toString(baseQName.uri);
String baseLocalName = fStringPool.toString(baseQName.localpart);
if (baseTypeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
baseLocalName.equals("anyType")) {
throw new ComplexTypeRecoverableError(
"The type '"+ base +"' specified as the " +
"base in the simpleContent element must be a complex type with simple content");
}
processBaseTypeInfo(baseQName,typeInfo);
// check that the base isn't a complex type with simple content
if (typeInfo.baseComplexTypeInfo != null) {
if (typeInfo.baseComplexTypeInfo.contentType != XMLElementDecl.TYPE_SIMPLE) {
throw new ComplexTypeRecoverableError(
"The type '"+ base +"' specified as the " +
"base in the simpleContent element must not have complexContent");
}
}
// -----------------------------------------------------------------------
// Process the content of the derivation
// -----------------------------------------------------------------------
Element attrNode = null;
//
// RESTRICTION
//
if (typeInfo.derivedBy==SchemaSymbols.RESTRICTION) {
//
//Schema Spec : Complex Type Definition Properties Correct : 2
//
if (typeInfo.baseDataTypeValidator != null) {
throw new ComplexTypeRecoverableError(
"ct-props-correct.2: The type '" + base +"' is a simple type. It cannot be used in a "+
"derivation by RESTRICTION for a complexType");
}
else {
typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
}
//
// Check that the base's final set does not include RESTRICTION
//
if((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.RESTRICTION) != 0) {
throw new ComplexTypeRecoverableError("Derivation by restriction is forbidden by either the base type " + base + " or the schema");
}
// -----------------------------------------------------------------------
// There may be a simple type definition in the restriction element
// The data type validator will be based on it, if specified
// -----------------------------------------------------------------------
if (content.getLocalName().equals(SchemaSymbols.ELT_SIMPLETYPE )) {
int simpleTypeNameIndex = traverseSimpleTypeDecl(content);
if (simpleTypeNameIndex!=-1) {
DatatypeValidator dv=fDatatypeRegistry.getDatatypeValidator(
fStringPool.toString(simpleTypeNameIndex));
//check that this datatype validator is validly derived from the base
//according to derivation-ok-restriction 5.1.1
if (!checkSimpleTypeDerivationOK(dv,typeInfo.baseDataTypeValidator)) {
throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.1.1: The content type is not a valid restriction of the content type of the base");
}
typeInfo.baseDataTypeValidator = dv;
content = XUtil.getNextSiblingElement(content);
}
else {
throw new ComplexTypeRecoverableError();
}
}
//
// Build up facet information
//
int numEnumerationLiterals = 0;
int numFacets = 0;
Hashtable facetData = new Hashtable();
Vector enumData = new Vector();
Element child;
// General Attribute Checking
scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
Hashtable contentAttrs;
//REVISIT: there is a better way to do this,
for (child = content;
child != null && (child.getLocalName().equals(SchemaSymbols.ELT_MINEXCLUSIVE) ||
child.getLocalName().equals(SchemaSymbols.ELT_MININCLUSIVE) ||
child.getLocalName().equals(SchemaSymbols.ELT_MAXEXCLUSIVE) ||
child.getLocalName().equals(SchemaSymbols.ELT_MAXINCLUSIVE) ||
child.getLocalName().equals(SchemaSymbols.ELT_TOTALDIGITS) ||
child.getLocalName().equals(SchemaSymbols.ELT_FRACTIONDIGITS) ||
child.getLocalName().equals(SchemaSymbols.ELT_LENGTH) ||
child.getLocalName().equals(SchemaSymbols.ELT_MINLENGTH) ||
child.getLocalName().equals(SchemaSymbols.ELT_MAXLENGTH) ||
child.getLocalName().equals(SchemaSymbols.ELT_PERIOD) ||
child.getLocalName().equals(SchemaSymbols.ELT_DURATION) ||
child.getLocalName().equals(SchemaSymbols.ELT_ENUMERATION) ||
child.getLocalName().equals(SchemaSymbols.ELT_PATTERN) ||
child.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION));
child = XUtil.getNextSiblingElement(child))
{
if ( child.getNodeType() == Node.ELEMENT_NODE ) {
Element facetElt = (Element) child;
// General Attribute Checking
contentAttrs = generalCheck(facetElt, scope);
numFacets++;
if (facetElt.getLocalName().equals(SchemaSymbols.ELT_ENUMERATION)) {
numEnumerationLiterals++;
enumData.addElement(facetElt.getAttribute(SchemaSymbols.ATT_VALUE));
//Enumerations can have annotations ? ( 0 | 1 )
Element enumContent = XUtil.getFirstChildElement( facetElt );
if( enumContent != null &&
enumContent.getLocalName().equals
( SchemaSymbols.ELT_ANNOTATION )){
traverseAnnotationDecl( child );
}
// TO DO: if Jeff check in new changes to TraverseSimpleType, copy them over
}
else {
facetData.put(facetElt.getLocalName(),
facetElt.getAttribute( SchemaSymbols.ATT_VALUE ));
}
}
} // end of for loop thru facets
if (numEnumerationLiterals > 0) {
facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
}
//
// If there were facets, create a new data type validator, otherwise
// the data type validator is from the base
//
if (numFacets > 0) {
try{
typeInfo.datatypeValidator = fDatatypeRegistry.createDatatypeValidator(
typeName,
typeInfo.baseDataTypeValidator, facetData, false);
} catch (Exception e) {
throw new ComplexTypeRecoverableError(e.getMessage());
}
}
else
typeInfo.datatypeValidator =
typeInfo.baseDataTypeValidator;
if (child != null) {
//
// Check that we have attributes
//
if (!isAttrOrAttrGroup(child)) {
throw new ComplexTypeRecoverableError(
"Invalid child in the RESTRICTION element of simpleContent");
}
else
attrNode = child;
}
} // end RESTRICTION
//
// EXTENSION
//
else {
if (typeInfo.baseComplexTypeInfo != null) {
typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
//
// Check that the base's final set does not include EXTENSION
//
if((typeInfo.baseComplexTypeInfo.finalSet &
SchemaSymbols.EXTENSION) != 0) {
throw new ComplexTypeRecoverableError("Derivation by extension is forbidden by either the base type " + base + " or the schema");
}
}
typeInfo.datatypeValidator = typeInfo.baseDataTypeValidator;
//
// Look for attributes
//
if (content != null) {
//
// Check that we have attributes
//
if (!isAttrOrAttrGroup(content)) {
throw new ComplexTypeRecoverableError(
"Only annotations and attributes are allowed in the " +
"content of an EXTENSION element for a complexType with simpleContent");
}
else {
attrNode = content;
}
}
}
// -----------------------------------------------------------------------
// add a template element to the grammar element decl pool for the type
// -----------------------------------------------------------------------
int templateElementNameIndex = fStringPool.addSymbol("$"+typeName);
typeInfo.templateElementIndex = fSchemaGrammar.addElementDecl(
new QName(-1, templateElementNameIndex,typeNameIndex,fTargetNSURI),
(fTargetNSURI==StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING : fCurrentScope, typeInfo.scopeDefined,
typeInfo.contentType,
typeInfo.contentSpecHandle, -1, typeInfo.datatypeValidator);
typeInfo.attlistHead = fSchemaGrammar.getFirstAttributeDeclIndex(
typeInfo.templateElementIndex);