reportGenericSchemaError("globally-declared element " + nameStr + " cannot have a ref attribute");
int nameIndex = fStringPool.addSymbol(nameStr);
int eltKey = fSchemaGrammar.getElementDeclIndex(fTargetNSURI, nameIndex,TOP_LEVEL_SCOPE);
if (eltKey > -1 ) {
return new QName(-1,nameIndex,nameIndex,fTargetNSURI);
}
}
// parse out 'block', 'final', 'nillable', 'abstract'
if (blockAtt == null)
blockStr = null;
int blockSet = parseBlockSet(blockStr);
if( (blockStr != null) && !blockStr.equals("") &&
(!blockStr.equals(SchemaSymbols.ATTVAL_POUNDALL) &&
(((blockSet & SchemaSymbols.RESTRICTION) == 0) &&
(((blockSet & SchemaSymbols.EXTENSION) == 0) &&
((blockSet & SchemaSymbols.SUBSTITUTION) == 0)))))
reportGenericSchemaError("The values of the 'block' attribute of an element must be either #all or a list of 'substitution', 'restriction' and 'extension'; " + blockStr + " was found");
if (finalAtt == null)
finalStr = null;
int finalSet = parseFinalSet(finalStr);
if( (finalStr != null) && !finalStr.equals("") &&
(!finalStr.equals(SchemaSymbols.ATTVAL_POUNDALL) &&
(((finalSet & SchemaSymbols.RESTRICTION) == 0) &&
((finalSet & SchemaSymbols.EXTENSION) == 0))))
reportGenericSchemaError("The values of the 'final' attribute of an element must be either #all or a list of 'restriction' and 'extension'; " + finalStr + " was found");
boolean isNillable = nillableStr.equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
boolean isAbstract = abstractStr.equals(SchemaSymbols.ATTVAL_TRUE)? true:false;
int elementMiscFlags = 0;
if (isNillable) {
elementMiscFlags += SchemaSymbols.NILLABLE;
}
if (isAbstract) {
elementMiscFlags += SchemaSymbols.ABSTRACT;
}
// make the property of the element's value being fixed also appear in elementMiscFlags
if(fixedAtt != null)
elementMiscFlags += SchemaSymbols.FIXED;
//if this is a reference to a global element
if (refAtt != null) {
//REVISIT top level check for ref
if (abstractAtt != null || blockAtt != null || defaultAtt != null ||
finalAtt != null || fixedAtt != null || formAtt != null ||
nillableAtt != null || substitutionGroupAtt != null || typeAtt != null)
reportSchemaError(SchemaMessageProvider.BadAttWithRef, null); //src-element.2.2
if (nameAtt != null)
// REVISIT: Localize
reportGenericSchemaError("src-element.2.1: element " + nameStr + " cannot also have a ref attribute");
Element child = XUtil.getFirstChildElement(elementDecl);
if(child != null && child.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
if (XUtil.getNextSiblingElement(child) != null)
reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
else
traverseAnnotationDecl(child);
}
else if (child != null)
reportSchemaError(SchemaMessageProvider.NoContentForRef, null);
String prefix = "";
String localpart = refStr;
int colonptr = refStr.indexOf(":");
if ( colonptr > 0) {
prefix = refStr.substring(0,colonptr);
localpart = refStr.substring(colonptr+1);
}
int localpartIndex = fStringPool.addSymbol(localpart);
String uriString = resolvePrefixToURI(prefix);
QName eltName = new QName(prefix != null ? fStringPool.addSymbol(prefix) : -1,
localpartIndex,
fStringPool.addSymbol(refStr),
uriString != null ? fStringPool.addSymbol(uriString) : StringPool.EMPTY_STRING);
//if from another schema, just return the element QName
if (! uriString.equals(fTargetNSURIString) ) {
return eltName;
}
int elementIndex = fSchemaGrammar.getElementDeclIndex(eltName, TOP_LEVEL_SCOPE);
//if not found, traverse the top level element that if referenced
if (elementIndex == -1 ) {
Element targetElement = getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT,localpart);
if (targetElement == null ) {
// REVISIT: Localize
reportGenericSchemaError("Element " + localpart + " not found in the Schema");
//REVISIT, for now, the QName anyway
return eltName;
//return new QName(-1,fStringPool.addSymbol(localpart), -1, fStringPool.addSymbol(uriString));
}
else {
// do nothing here, other wise would cause infinite loop for
// <element name="recur"><complexType><element ref="recur"> ...
//eltName= traverseElementDecl(targetElement);
}
}
return eltName;
} else if (nameAtt == null)
// REVISIT: Localize
reportGenericSchemaError("src-element.2.1: a local element must have a name or a ref attribute present");
// Handle the substitutionGroup
Element substitutionGroupElementDecl = null;
int substitutionGroupElementDeclIndex = -1;
boolean noErrorSoFar = true;
String substitutionGroupUri = null;
String substitutionGroupLocalpart = null;
String substitutionGroupFullName = null;
ComplexTypeInfo substitutionGroupEltTypeInfo = null;
DatatypeValidator substitutionGroupEltDV = null;
if ( substitutionGroupStr.length() > 0 ) {
if(refAtt != null)
// REVISIT: Localize
reportGenericSchemaError("a local element cannot have a substitutionGroup");
substitutionGroupUri = resolvePrefixToURI(getPrefix(substitutionGroupStr));
substitutionGroupLocalpart = getLocalPart(substitutionGroupStr);
substitutionGroupFullName = substitutionGroupUri+","+substitutionGroupLocalpart;
if ( !substitutionGroupUri.equals(fTargetNSURIString) ) {
substitutionGroupEltTypeInfo = getElementDeclTypeInfoFromNS(substitutionGroupUri, substitutionGroupLocalpart);
if (substitutionGroupEltTypeInfo == null) {
substitutionGroupEltDV = getElementDeclTypeValidatorFromNS(substitutionGroupUri, substitutionGroupLocalpart);
if (substitutionGroupEltDV == null) {
//TO DO: report error here;
noErrorSoFar = false;
reportGenericSchemaError("Could not find type for element '" +substitutionGroupLocalpart
+ "' in schema '" + substitutionGroupUri+"'");
}
}
}
else {
substitutionGroupElementDecl = getTopLevelComponentByName(SchemaSymbols.ELT_ELEMENT, substitutionGroupLocalpart);
if (substitutionGroupElementDecl == null) {
substitutionGroupElementDeclIndex =
fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(substitutionGroupStr),TOP_LEVEL_SCOPE);
if ( substitutionGroupElementDeclIndex == -1) {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("unable to locate substitutionGroup affiliation element "
+substitutionGroupStr
+" in element declaration "
+nameStr);
}
}
else {
substitutionGroupElementDeclIndex =
fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(substitutionGroupStr),TOP_LEVEL_SCOPE);
if ( substitutionGroupElementDeclIndex == -1) {
traverseElementDecl(substitutionGroupElementDecl);
substitutionGroupElementDeclIndex =
fSchemaGrammar.getElementDeclIndex(fTargetNSURI, getLocalPartIndex(substitutionGroupStr),TOP_LEVEL_SCOPE);
}
}
if (substitutionGroupElementDeclIndex != -1) {
substitutionGroupEltTypeInfo = fSchemaGrammar.getElementComplexTypeInfo( substitutionGroupElementDeclIndex );
if (substitutionGroupEltTypeInfo == null) {
fSchemaGrammar.getElementDecl(substitutionGroupElementDeclIndex, fTempElementDecl);
substitutionGroupEltDV = fTempElementDecl.datatypeValidator;
if (substitutionGroupEltDV == null) {
//TO DO: report error here;
noErrorSoFar = false;
reportGenericSchemaError("Could not find type for element '" +substitutionGroupLocalpart
+ "' in schema '" + substitutionGroupUri+"'");
}
}
}
}
}
//
// resolving the type for this element right here
//
ComplexTypeInfo typeInfo = null;
// element has a single child element, either a datatype or a type, null if primitive
Element child = XUtil.getFirstChildElement(elementDecl);
if(child != null && child.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
traverseAnnotationDecl(child);
child = XUtil.getNextSiblingElement(child);
}
if(child != null && child.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION))
// REVISIT: Localize
reportGenericSchemaError("element declarations can contain at most one annotation Element Information Item");
boolean haveAnonType = false;
// Handle Anonymous type if there is one
if (child != null) {
String childName = child.getLocalName();
if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("anonymous complexType in element '" + nameStr +"' has a name attribute");
}
else {
// Determine what the type name will be
String anonTypeName = genAnonTypeName(child);
if (fCurrentTypeNameStack.search((Object)anonTypeName) > - 1) {
// A recursing element using an anonymous type
int uriInd = StringPool.EMPTY_STRING;
if ( formStr.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
fElementDefaultQualified) {
uriInd = fTargetNSURI;
}
int nameIndex = fStringPool.addSymbol(nameStr);
QName tempQName = new QName(fCurrentScope, nameIndex, nameIndex, uriInd);
fElementRecurseComplex.put(tempQName, anonTypeName);
return new QName(-1, nameIndex, nameIndex, uriInd);
}
else {
typeNameIndex = traverseComplexTypeDecl(child);
if (typeNameIndex != -1 ) {
typeInfo = (ComplexTypeInfo)
fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
}
else {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("traverse complexType error in element '" + nameStr +"'");
}
}
}
haveAnonType = true;
child = XUtil.getNextSiblingElement(child);
}
else if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("anonymous simpleType in element '" + nameStr +"' has a name attribute");
}
else
typeNameIndex = traverseSimpleTypeDecl(child);
if (typeNameIndex != -1) {
dv = fDatatypeRegistry.getDatatypeValidator(fStringPool.toString(typeNameIndex));
}
else {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("traverse simpleType error in element '" + nameStr +"'");
}
contentSpecType = XMLElementDecl.TYPE_SIMPLE;
haveAnonType = true;
child = XUtil.getNextSiblingElement(child);
} else if (typeAtt == null) { // "ur-typed" leaf
contentSpecType = XMLElementDecl.TYPE_ANY;
//REVISIT: is this right?
//contentSpecType = fStringPool.addSymbol("UR_TYPE");
// set occurrence count
contentSpecNodeIndex = -1;
}
// see if there's something here; it had better be key, keyref or unique.
if (child != null)
childName = child.getLocalName();
while ((child != null) && ((childName.equals(SchemaSymbols.ELT_KEY))
|| (childName.equals(SchemaSymbols.ELT_KEYREF))
|| (childName.equals(SchemaSymbols.ELT_UNIQUE)))) {
child = XUtil.getNextSiblingElement(child);
if (child != null) {
childName = child.getLocalName();
}
}
if (child != null) {
// REVISIT: Localize
noErrorSoFar = false;
reportGenericSchemaError("src-element.0: the content of an element information item must match (annotation?, (simpleType | complexType)?, (unique | key | keyref)*)");
}
}
// handle type="" here
if (haveAnonType && (typeAtt != null)) {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError( "src-element.3: Element '"+ nameStr +
"' have both a type attribute and a annoymous type child" );
}
// type specified as an attribute and no child is type decl.
else if (typeAtt != null) {
String prefix = "";
String localpart = typeStr;
int colonptr = typeStr.indexOf(":");
if ( colonptr > 0) {
prefix = typeStr.substring(0,colonptr);
localpart = typeStr.substring(colonptr+1);
}
String typeURI = resolvePrefixToURI(prefix);
// check if the type is from the same Schema
if ( !typeURI.equals(fTargetNSURIString)
&& !typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
&& typeURI.length() != 0) { // REVISIT, only needed because of resolvePrifixToURI.
fromAnotherSchema = typeURI;
typeInfo = getTypeInfoFromNS(typeURI, localpart);
if (typeInfo == null) {
dv = getTypeValidatorFromNS(typeURI, localpart);
if (dv == null) {
//TO DO: report error here;
noErrorSoFar = false;
reportGenericSchemaError("Could not find type " +localpart
+ " in schema " + typeURI);
}
}
}
else {
typeInfo = (ComplexTypeInfo) fComplexTypeRegistry.get(typeURI+","+localpart);
if (typeInfo == null) {
dv = getDatatypeValidator(typeURI, localpart);
if (dv == null )
if (typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
&& !fTargetNSURIString.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))
{
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("type not found : " + typeURI+":"+localpart);
}
else {
Element topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_COMPLEXTYPE,localpart);
if (topleveltype != null) {
if (fCurrentTypeNameStack.search((Object)localpart) > - 1) {
//then we found a recursive element using complexType.
// REVISIT: this will be broken when recursing happens between 2 schemas
int uriInd = StringPool.EMPTY_STRING;
if ( formStr.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
fElementDefaultQualified) {
uriInd = fTargetNSURI;
}
int nameIndex = fStringPool.addSymbol(nameStr);
QName tempQName = new QName(fCurrentScope, nameIndex, nameIndex, uriInd);
fElementRecurseComplex.put(tempQName, localpart);
return new QName(-1, nameIndex, nameIndex, uriInd);
}
else {
typeNameIndex = traverseComplexTypeDecl( topleveltype );
typeInfo = (ComplexTypeInfo)
fComplexTypeRegistry.get(fStringPool.toString(typeNameIndex));
}
}
else {
topleveltype = getTopLevelComponentByName(SchemaSymbols.ELT_SIMPLETYPE, localpart);
if (topleveltype != null) {
typeNameIndex = traverseSimpleTypeDecl( topleveltype );
dv = getDatatypeValidator(typeURI, localpart);
}
else {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("type not found : " + typeURI+":"+localpart);
}
}
}
}
}
}
// now we need to make sure that our substitution (if any)
// is valid, now that we have all the requisite type-related info.
if(substitutionGroupStr.length() > 0) {
checkSubstitutionGroupOK(elementDecl, substitutionGroupElementDecl, noErrorSoFar, substitutionGroupElementDeclIndex, typeInfo, substitutionGroupEltTypeInfo, dv, substitutionGroupEltDV);
}
// this element is ur-type, check its substitutionGroup affiliation.
// if there is substitutionGroup affiliation and not type definition found for this element,
// then grab substitutionGroup affiliation's type and give it to this element
if ( noErrorSoFar && typeInfo == null && dv == null ) {
typeInfo = substitutionGroupEltTypeInfo;
dv = substitutionGroupEltDV;
}
if (typeInfo == null && dv==null) {
if (noErrorSoFar) {
// Actually this Element's type definition is ur-type;
contentSpecType = XMLElementDecl.TYPE_ANY;
// REVISIT, need to wait till we have wildcards implementation.
// ADD attribute wildcards here
}
else {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError ("untyped element : " + nameStr );
}
}
// if element belongs to a compelx type
if (typeInfo!=null) {
contentSpecNodeIndex = typeInfo.contentSpecHandle;
contentSpecType = typeInfo.contentType;
scopeDefined = typeInfo.scopeDefined;
dv = typeInfo.datatypeValidator;
}
// if element belongs to a simple type
if (dv!=null) {
contentSpecType = XMLElementDecl.TYPE_SIMPLE;
if (typeInfo == null) {
fromAnotherSchema = null; // not to switch schema in this case
}
}
// Now we can handle validation etc. of default and fixed attributes,
// since we finally have all the type information.
if(fixedAtt != null) defaultStr = fixedStr;
if(!defaultStr.equals("")) {
if(typeInfo != null &&
(typeInfo.contentType != XMLElementDecl.TYPE_MIXED_SIMPLE &&
typeInfo.contentType != XMLElementDecl.TYPE_MIXED_COMPLEX &&
typeInfo.contentType != XMLElementDecl.TYPE_SIMPLE)) {
// REVISIT: Localize
reportGenericSchemaError ("e-props-correct.2.1: element " + nameStr + " has a fixed or default value and must have a mixed or simple content model");
}
if(typeInfo != null &&
(typeInfo.contentType == XMLElementDecl.TYPE_MIXED_SIMPLE ||
typeInfo.contentType == XMLElementDecl.TYPE_MIXED_COMPLEX)) {
if (particleEmptiable(typeInfo.contentSpecHandle))
reportGenericSchemaError ("e-props-correct.2.2.2: for element " + nameStr + ", the {content type} is mixed, then the {content type}'s particle must be emptiable");
}
try {
if(dv == null) { // in this case validate according to xs:string
new StringDatatypeValidator().validate(defaultStr, null);
} else {
dv.validate(defaultStr, null);
}
} catch (InvalidDatatypeValueException ide) {
reportGenericSchemaError ("e-props-correct.2: invalid fixed or default value '" + defaultStr + "' in element " + nameStr);
}
}
if (!defaultStr.equals("") &&
dv != null && dv instanceof IDDatatypeValidator) {
reportGenericSchemaError ("e-props-correct.4: If the {type definition} or {type definition}'s {content type} is or is derived from ID then there must not be a {value constraint} -- element " + nameStr);
}
//
// Create element decl
//
int elementNameIndex = fStringPool.addSymbol(nameStr);
int localpartIndex = elementNameIndex;
int uriIndex = StringPool.EMPTY_STRING;
int enclosingScope = fCurrentScope;
//refer to 4.3.2 in "XML Schema Part 1: Structures"
if ( isTopLevel(elementDecl)) {
uriIndex = fTargetNSURI;
enclosingScope = TOP_LEVEL_SCOPE;
}
else if ( !formStr.equals(SchemaSymbols.ATTVAL_UNQUALIFIED) &&
(( formStr.equals(SchemaSymbols.ATTVAL_QUALIFIED)||
fElementDefaultQualified ))) {
uriIndex = fTargetNSURI;
}
//There can never be two elements with the same name and different type in the same scope.
int existSuchElementIndex = fSchemaGrammar.getElementDeclIndex(uriIndex, localpartIndex, enclosingScope);
if ( existSuchElementIndex > -1) {
fSchemaGrammar.getElementDecl(existSuchElementIndex, fTempElementDecl);
DatatypeValidator edv = fTempElementDecl.datatypeValidator;
ComplexTypeInfo eTypeInfo = fSchemaGrammar.getElementComplexTypeInfo(existSuchElementIndex);
if ( ((eTypeInfo != null)&&(eTypeInfo!=typeInfo))
|| ((edv != null)&&(edv != dv)) ) {
noErrorSoFar = false;
// REVISIT: Localize
reportGenericSchemaError("duplicate element decl in the same scope : " +
fStringPool.toString(localpartIndex));
}
}
QName eltQName = new QName(-1,localpartIndex,elementNameIndex,uriIndex);
// add element decl to pool
int attrListHead = -1 ;