XSAttributeCheckerpublic class XSAttributeChecker extends Object Class XSAttributeCheck is used to check the validity of attributes
appearing in the schema document. It
- reports an error for invalid element (invalid namespace, invalid name)
- reports an error for invalid attribute (invalid namespace, invalid name)
- reports an error for invalid attribute value
- return compiled values for attriute values
- provide default value for missing optional attributes
- provide default value for incorrect attribute values
But it's the caller's responsibility to check whether a required attribute
is present.
Things need revisiting:
- Whether to return non-schema attributes/values
- Do we need to update NamespaceScope and ErrorReporter when reset()?
- Should have the datatype validators return compiled value
- use symbol table instead of many hashtables |
Fields Summary |
---|
private static final String | ELEMENT_N | private static final String | ELEMENT_R | private static final String | ATTRIBUTE_N | private static final String | ATTRIBUTE_R | private static int | ATTIDX_COUNT | public static final int | ATTIDX_ABSTRACT | public static final int | ATTIDX_AFORMDEFAULT | public static final int | ATTIDX_BASE | public static final int | ATTIDX_BLOCK | public static final int | ATTIDX_BLOCKDEFAULT | public static final int | ATTIDX_DEFAULT | public static final int | ATTIDX_EFORMDEFAULT | public static final int | ATTIDX_FINAL | public static final int | ATTIDX_FINALDEFAULT | public static final int | ATTIDX_FIXED | public static final int | ATTIDX_FORM | public static final int | ATTIDX_ID | public static final int | ATTIDX_ITEMTYPE | public static final int | ATTIDX_MAXOCCURS | public static final int | ATTIDX_MEMBERTYPES | public static final int | ATTIDX_MINOCCURS | public static final int | ATTIDX_MIXED | public static final int | ATTIDX_NAME | public static final int | ATTIDX_NAMESPACE | public static final int | ATTIDX_NAMESPACE_LIST | public static final int | ATTIDX_NILLABLE | public static final int | ATTIDX_NONSCHEMA | public static final int | ATTIDX_PROCESSCONTENTS | public static final int | ATTIDX_PUBLIC | public static final int | ATTIDX_REF | public static final int | ATTIDX_REFER | public static final int | ATTIDX_SCHEMALOCATION | public static final int | ATTIDX_SOURCE | public static final int | ATTIDX_SUBSGROUP | public static final int | ATTIDX_SYSTEM | public static final int | ATTIDX_TARGETNAMESPACE | public static final int | ATTIDX_TYPE | public static final int | ATTIDX_USE | public static final int | ATTIDX_VALUE | public static final int | ATTIDX_ENUMNSDECLS | public static final int | ATTIDX_VERSION | public static final int | ATTIDX_XPATH | public static final int | ATTIDX_FROMDEFAULT | public static final int | ATTIDX_ISRETURNED | private static final XIntPool | fXIntPool | private static final XInt | INT_QUALIFIED | private static final XInt | INT_UNQUALIFIED | private static final XInt | INT_EMPTY_SET | private static final XInt | INT_ANY_STRICT | private static final XInt | INT_ANY_LAX | private static final XInt | INT_ANY_SKIP | private static final XInt | INT_ANY_ANY | private static final XInt | INT_ANY_LIST | private static final XInt | INT_ANY_NOT | private static final XInt | INT_USE_OPTIONAL | private static final XInt | INT_USE_REQUIRED | private static final XInt | INT_USE_PROHIBITED | private static final XInt | INT_WS_PRESERVE | private static final XInt | INT_WS_REPLACE | private static final XInt | INT_WS_COLLAPSE | private static final XInt | INT_UNBOUNDED | private static final Hashtable | fEleAttrsMapG | private static final Hashtable | fEleAttrsMapL | protected static final int | DT_ANYURI | protected static final int | DT_ID | protected static final int | DT_QNAME | protected static final int | DT_STRING | protected static final int | DT_TOKEN | protected static final int | DT_NCNAME | protected static final int | DT_XPATH | protected static final int | DT_XPATH1 | protected static final int | DT_COUNT | private static final XSSimpleType[] | fExtraDVs | protected static final int | DT_BLOCK | protected static final int | DT_BLOCK1 | protected static final int | DT_FINAL | protected static final int | DT_FINAL1 | protected static final int | DT_FINAL2 | protected static final int | DT_FORM | protected static final int | DT_MAXOCCURS | protected static final int | DT_MAXOCCURS1 | protected static final int | DT_MEMBERTYPES | protected static final int | DT_MINOCCURS1 | protected static final int | DT_NAMESPACE | protected static final int | DT_PROCESSCONTENTS | protected static final int | DT_USE | protected static final int | DT_WHITESPACE | protected static final int | DT_BOOLEAN | protected static final int | DT_NONNEGINT | protected static final int | DT_POSINT | protected XSDHandler | fSchemaHandler | protected SymbolTable | fSymbolTable | protected Hashtable | fNonSchemaAttrs | protected Vector | fNamespaceList | protected boolean[] | fSeen | private static boolean[] | fSeenTemp | static final int | INIT_POOL_SIZE | static final int | INC_POOL_SIZE | Object[] | fArrayPool | private static Object[] | fTempArray | int | fPoolPos |
Constructors Summary |
---|
public XSAttributeChecker(XSDHandler schemaHandler)
// constructor. Sets fErrorReproter and get datatype validators
fSchemaHandler = schemaHandler;
|
Methods Summary |
---|
public java.lang.Object[] | checkAttributes(org.w3c.dom.Element element, boolean isGlobal, com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDocumentInfo schemaDoc)check whether the specified element conforms to the attributes restriction
an array of attribute values is returned. the caller must call
returnAttrArray to return that array.
return checkAttributes(element, isGlobal, schemaDoc, false);
| public java.lang.Object[] | checkAttributes(org.w3c.dom.Element element, boolean isGlobal, com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDocumentInfo schemaDoc, boolean enumAsQName)check whether the specified element conforms to the attributes restriction
an array of attribute values is returned. the caller must call
returnAttrArray to return that array. This method also takes
an extra parameter: if the element is "enumeration", whether to make a
copy of the namespace context, so that the value can be resolved as a
QName later.
if (element == null)
return null;
// get all attributes
Attr[] attrs = DOMUtil.getAttrs(element);
// update NamespaceSupport
resolveNamespace(element, attrs, schemaDoc.fNamespaceSupport);
String uri = DOMUtil.getNamespaceURI(element);
String elName = DOMUtil.getLocalName(element);
if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(uri)) {
reportSchemaError("s4s-elt-schema-ns", new Object[] {elName}, element);
}
Hashtable eleAttrsMap = fEleAttrsMapG;
String lookupName = elName;
// REVISIT: only local element and attribute are different from others.
// it's possible to have either name or ref. all the others
// are only allowed to have one of name or ref, or neither of them.
// we'd better move such checking to the traverser.
if (!isGlobal) {
eleAttrsMap = fEleAttrsMapL;
if (elName.equals(SchemaSymbols.ELT_ELEMENT)) {
if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
lookupName = ELEMENT_R;
else
lookupName = ELEMENT_N;
} else if (elName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
if (DOMUtil.getAttr(element, SchemaSymbols.ATT_REF) != null)
lookupName = ATTRIBUTE_R;
else
lookupName = ATTRIBUTE_N;
}
}
// get desired attribute list of this element
OneElement oneEle = (OneElement)eleAttrsMap.get(lookupName);
if (oneEle == null) {
// should never gets here.
// when this method is called, the call already knows that
// the element can appear.
reportSchemaError ("s4s-elt-invalid", new Object[] {elName}, element);
return null;
}
//Hashtable attrValues = new Hashtable();
Object[] attrValues = getAvailableArray();
//Hashtable otherValues = new Hashtable();
long fromDefault = 0;
Container attrList = oneEle.attrList;
// clear the "seen" flag.
System.arraycopy(fSeenTemp, 0, fSeen, 0, ATTIDX_COUNT);
// traverse all attributes
int length = attrs.length;
Attr sattr = null;
for (int i = 0; i < length; i++) {
sattr = attrs[i];
// get the attribute name/value
//String attrName = DOMUtil.getLocalName(sattr);
String attrName = sattr.getName();
String attrVal = DOMUtil.getValue(sattr);
// we don't want to add namespace declarations to the non-schema attributes
if (attrName.startsWith("xmlns")) {
continue;
}
// skip anything starts with x/X m/M l/L
// add this to the list of "non-schema" attributes
if (attrName.toLowerCase(Locale.ENGLISH).startsWith("xml")) {
if(attrValues[ATTIDX_NONSCHEMA] == null) {
// these are usually small
attrValues[ATTIDX_NONSCHEMA] = new Vector(4,2);
}
((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrName);
((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrVal);
//otherValues.put(attrName, attrVal);
continue;
}
// for attributes with namespace prefix
//
String attrURI = DOMUtil.getNamespaceURI(sattr);
if (attrURI != null && attrURI.length() != 0) {
// attributes with schema namespace are not allowed
// and not allowed on "document" and "appInfo"
if (attrURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ||
!oneEle.allowNonSchemaAttr) {
reportSchemaError ("s4s-att-not-allowed", new Object[] {elName, attrName}, element);
}
else {
if(attrValues[ATTIDX_NONSCHEMA] == null) {
// these are usually small
attrValues[ATTIDX_NONSCHEMA] = new Vector(4,2);
}
((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrName);
((Vector)attrValues[ATTIDX_NONSCHEMA]).addElement(attrVal);
// for attributes from other namespace
// store them in a list, and TRY to validate them after
// schema traversal (because it's "lax")
//otherValues.put(attrName, attrVal);
// REVISIT: actually use this some day...
// String attrRName = attrURI + "," + attrName;
// Vector values = (Vector)fNonSchemaAttrs.get(attrRName);
// if (values == null) {
// values = new Vector();
// values.addElement(attrName);
// values.addElement(elName);
// values.addElement(attrVal);
// fNonSchemaAttrs.put(attrRName, values);
// }
// else {
// values.addElement(elName);
// values.addElement(attrVal);
// }
}
continue;
}
// check whether this attribute is allowed
OneAttr oneAttr = (OneAttr)attrList.get(attrName);
if (oneAttr == null) {
reportSchemaError ("s4s-att-not-allowed",
new Object[] {elName, attrName},
element);
continue;
}
// we've seen this attribute
fSeen[oneAttr.valueIndex] = true;
// check the value against the datatype
try {
// no checking on string needs to be done here.
// no checking on xpath needs to be done here.
// xpath values are validated in xpath parser
if (oneAttr.dvIndex >= 0) {
if (oneAttr.dvIndex != DT_STRING &&
oneAttr.dvIndex != DT_XPATH &&
oneAttr.dvIndex != DT_XPATH1) {
XSSimpleType dv = fExtraDVs[oneAttr.dvIndex];
Object avalue = dv.validate(attrVal, schemaDoc.fValidationContext, null);
// kludge to handle chameleon includes/redefines...
if (oneAttr.dvIndex == DT_QNAME) {
QName qname = (QName)avalue;
if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
qname.uri = schemaDoc.fTargetNamespace;
}
attrValues[oneAttr.valueIndex] = avalue;
} else {
attrValues[oneAttr.valueIndex] = attrVal;
}
}
else {
attrValues[oneAttr.valueIndex] = validate(attrValues, attrName, attrVal, oneAttr.dvIndex, schemaDoc);
}
} catch (InvalidDatatypeValueException ide) {
reportSchemaError ("s4s-att-invalid-value",
new Object[] {elName, attrName, ide.getMessage()},
element);
if (oneAttr.dfltValue != null)
//attrValues.put(attrName, oneAttr.dfltValue);
attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
}
// For "enumeration", and type is possible to be a QName, we need
// to return namespace context for later QName resolution.
if (elName.equals(SchemaSymbols.ELT_ENUMERATION) && enumAsQName) {
attrValues[ATTIDX_ENUMNSDECLS] = new SchemaNamespaceSupport(schemaDoc.fNamespaceSupport);
}
}
// apply default values
OneAttr[] reqAttrs = oneEle.attrList.values;
for (int i = 0; i < reqAttrs.length; i++) {
OneAttr oneAttr = reqAttrs[i];
// if the attribute didn't apprear, and
// if the attribute is optional with default value, apply it
if (oneAttr.dfltValue != null && !fSeen[oneAttr.valueIndex]) {
//attrValues.put(oneAttr.name, oneAttr.dfltValue);
attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
fromDefault |= (1<<oneAttr.valueIndex);
}
}
attrValues[ATTIDX_FROMDEFAULT] = new Long(fromDefault);
//attrValues[ATTIDX_OTHERVALUES] = otherValues;
// maxOccurs
if (attrValues[ATTIDX_MAXOCCURS] != null) {
int min = ((XInt)attrValues[ATTIDX_MINOCCURS]).intValue();
int max = ((XInt)attrValues[ATTIDX_MAXOCCURS]).intValue();
if (max != SchemaSymbols.OCCURRENCE_UNBOUNDED) {
// if secure processing in effect, test maxOccurs for maximum
// maxOccurLimit
if (fSchemaHandler.fSecureProcessing != null) {
//Revisit :: IMO this is not right place to check
// maxOccurNodeLimit.
int maxOccurNodeLimit = fSchemaHandler.fSecureProcessing.getMaxOccurNodeLimit();
if (max > maxOccurNodeLimit) {
reportSchemaError("maxOccurLimit", new Object[] {new Integer(maxOccurNodeLimit)}, element);
// reset max values in case processing continues on error
attrValues[ATTIDX_MAXOCCURS] = fXIntPool.getXInt(maxOccurNodeLimit);
//new Integer(maxOccurNodeLimit);
max = maxOccurNodeLimit;
}
}
// Check that minOccurs isn't greater than maxOccurs.
// p-props-correct 2.1
if (min > max) {
reportSchemaError ("p-props-correct.2.1",
new Object[] {elName, attrValues[ATTIDX_MINOCCURS], attrValues[ATTIDX_MAXOCCURS]},
element);
attrValues[ATTIDX_MINOCCURS] = attrValues[ATTIDX_MAXOCCURS];
}
}
}
return attrValues;
| public void | checkNonSchemaAttributes(com.sun.org.apache.xerces.internal.impl.xs.XSGrammarBucket grammarBucket)
// for all attributes
Enumeration keys = fNonSchemaAttrs.keys();
XSAttributeDecl attrDecl;
while (keys.hasMoreElements()) {
// get name, uri, localpart
String attrRName = (String)keys.nextElement();
String attrURI = attrRName.substring(0,attrRName.indexOf(',"));
String attrLocal = attrRName.substring(attrRName.indexOf(',")+1);
// find associated grammar
SchemaGrammar sGrammar = grammarBucket.getGrammar(attrURI);
if (sGrammar == null)
continue;
// and get the datatype validator, if there is one
attrDecl = sGrammar.getGlobalAttributeDecl(attrLocal);
if (attrDecl == null)
continue;
XSSimpleType dv = (XSSimpleType)attrDecl.getTypeDefinition();
if (dv == null)
continue;
// get all values appeared with this attribute name
Vector values = (Vector)fNonSchemaAttrs.get(attrRName);
String elName, attrVal;
String attrName = (String)values.elementAt(0);
// for each of the values
int count = values.size();
for (int i = 1; i < count; i += 2) {
elName = (String)values.elementAt(i);
try {
// and validate it using the XSSimpleType
// REVISIT: what would be the proper validation context?
// guess we need to save that in the vectors too.
dv.validate((String)values.elementAt(i+1), null, null);
} catch(InvalidDatatypeValueException ide) {
reportSchemaError ("s4s-att-invalid-value",
new Object[] {elName, attrName, ide.getMessage()},
null);
}
}
}
| protected java.lang.Object[] | getAvailableArray()
// get the next available array
// if no array left in the pool, increase the pool size
if (fArrayPool.length == fPoolPos) {
// increase size
fArrayPool = new Object[fPoolPos+INC_POOL_SIZE][];
// initialize each *new* array
for (int i = fPoolPos; i < fArrayPool.length; i++)
fArrayPool[i] = new Object[ATTIDX_COUNT];
}
// get the next available one
Object[] retArray = fArrayPool[fPoolPos];
// clear it from the pool. this is for GC: if a caller forget to
// return the array, we want that array to be GCed.
fArrayPool[fPoolPos++] = null;
// to make sure that one array is not returned twice, we use
// the last entry to indicate whether an array is already returned
// now set it to false.
System.arraycopy(fTempArray, 0, retArray, 0, ATTIDX_COUNT-1);
retArray[ATTIDX_ISRETURNED] = Boolean.FALSE;
return retArray;
| public static java.lang.String | normalize(java.lang.String content, short ws)
int len = content == null ? 0 : content.length();
if (len == 0 || ws == XSSimpleType.WS_PRESERVE)
return content;
StringBuffer sb = new StringBuffer();
if (ws == XSSimpleType.WS_REPLACE) {
char ch;
// when it's replace, just replace #x9, #xa, #xd by #x20
for (int i = 0; i < len; i++) {
ch = content.charAt(i);
if (ch != 0x9 && ch != 0xa && ch != 0xd)
sb.append(ch);
else
sb.append((char)0x20);
}
} else {
char ch;
int i;
boolean isLeading = true;
// when it's collapse
for (i = 0; i < len; i++) {
ch = content.charAt(i);
// append real characters, so we passed leading ws
if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
sb.append(ch);
isLeading = false;
}
else {
// for whitespaces, we skip all following ws
for (; i < len-1; i++) {
ch = content.charAt(i+1);
if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
break;
}
// if it's not a leading or tailing ws, then append a space
if (i < len - 1 && !isLeading)
sb.append((char)0x20);
}
}
}
return sb.toString();
| void | reportSchemaError(java.lang.String key, java.lang.Object[] args, org.w3c.dom.Element ele)
fSchemaHandler.reportSchemaError(key, args, ele);
| public void | reset(com.sun.org.apache.xerces.internal.util.SymbolTable symbolTable)
fSymbolTable = symbolTable;
fNonSchemaAttrs.clear();
| public void | resolveNamespace(org.w3c.dom.Element element, org.w3c.dom.Attr[] attrs, com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport nsSupport)
// push the namespace context
nsSupport.pushContext();
// search for new namespace bindings
int length = attrs.length;
Attr sattr = null;
String rawname, prefix, uri;
for (int i = 0; i < length; i++) {
sattr = attrs[i];
rawname = DOMUtil.getName(sattr);
prefix = null;
if (rawname.equals(XMLSymbols.PREFIX_XMLNS))
prefix = XMLSymbols.EMPTY_STRING;
else if (rawname.startsWith("xmlns:"))
prefix = fSymbolTable.addSymbol(DOMUtil.getLocalName(sattr));
if (prefix != null) {
uri = fSymbolTable.addSymbol(DOMUtil.getValue(sattr));
nsSupport.declarePrefix(prefix, uri.length()!=0 ? uri : null);
}
}
| public void | returnAttrArray(java.lang.Object[] attrArray, com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDocumentInfo schemaDoc)
// pop the namespace context
if (schemaDoc != null)
schemaDoc.fNamespaceSupport.popContext();
// if 1. the pool is full; 2. the array is null;
// 3. the array is of wrong size; 4. the array is already returned
// then we can't accept this array to be returned
if (fPoolPos == 0 ||
attrArray == null ||
attrArray.length != ATTIDX_COUNT ||
((Boolean)attrArray[ATTIDX_ISRETURNED]).booleanValue()) {
return;
}
// mark this array as returned
attrArray[ATTIDX_ISRETURNED] = Boolean.TRUE;
// better clear nonschema vector
if(attrArray[ATTIDX_NONSCHEMA] != null)
((Vector)attrArray[ATTIDX_NONSCHEMA]).clear();
// and put it into the pool
fArrayPool[--fPoolPos] = attrArray;
| private java.lang.Object | validate(java.lang.Object[] attrValues, java.lang.String attr, java.lang.String ivalue, int dvIndex, com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDocumentInfo schemaDoc)
if (ivalue == null)
return null;
// To validate these types, we don't actually need to normalize the
// strings. We only need to remove the whitespace from both ends.
// In some special cases (list types), StringTokenizer can correctly
// process the un-normalized whitespace.
String value = ivalue.trim();
Object retValue = null;
Vector memberType;
int choice;
switch (dvIndex) {
case DT_BOOLEAN:
if (value.equals(SchemaSymbols.ATTVAL_FALSE) ||
value.equals(SchemaSymbols.ATTVAL_FALSE_0)) {
retValue = Boolean.FALSE;
} else if (value.equals(SchemaSymbols.ATTVAL_TRUE) ||
value.equals(SchemaSymbols.ATTVAL_TRUE_1)) {
retValue = Boolean.TRUE;
} else {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "boolean"});
}
break;
case DT_NONNEGINT:
try {
if (value.length() > 0 && value.charAt(0) == '+")
value = value.substring(1);
retValue = fXIntPool.getXInt(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
}
if (((XInt)retValue).intValue() < 0)
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "nonNegativeInteger"});
break;
case DT_POSINT:
try {
if (value.length() > 0 && value.charAt(0) == '+")
value = value.substring(1);
retValue = fXIntPool.getXInt(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
}
if (((XInt)retValue).intValue() <= 0)
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{value, "positiveInteger"});
break;
case DT_BLOCK:
// block = (#all | List of (substitution | extension | restriction | list | union))
choice = 0;
if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
XSConstants.DERIVATION_UNION;
}
else {
// use the default \t\r\n\f delimiters
StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
if (token.equals (SchemaSymbols.ATTVAL_SUBSTITUTION)) {
choice |= XSConstants.DERIVATION_SUBSTITUTION;
}
else if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
choice |= XSConstants.DERIVATION_EXTENSION;
}
else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
choice |= XSConstants.DERIVATION_RESTRICTION;
}
else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
choice |= XSConstants.DERIVATION_LIST;
}
else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
choice |= XSConstants.DERIVATION_RESTRICTION;
}
else {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (substitution | extension | restriction | list | union))"});
}
}
}
retValue = fXIntPool.getXInt(choice);
break;
case DT_BLOCK1:
case DT_FINAL:
// block = (#all | List of (extension | restriction))
// final = (#all | List of (extension | restriction))
choice = 0;
if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
//choice = SchemaSymbols.EXTENSION|SchemaSymbols.RESTRICTION;
// REVISIT: if #all, then make the result the combination of
// everything: substitution/externsion/restriction/list/union.
// would this be a problem?
// the reason doing so is that when final/blockFinal on <schema>
// is #all, it's not always the same as the conbination of those
// values allowed by final/blockFinal.
// for example, finalDefault="#all" is not always the same as
// finalDefault="extension restriction".
// if finalDefault="#all", final on any simple type would be
// "extension restriction list union".
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
XSConstants.DERIVATION_UNION;
}
else {
// use the default \t\r\n\f delimiters
StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
choice |= XSConstants.DERIVATION_EXTENSION;
}
else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
choice |= XSConstants.DERIVATION_RESTRICTION;
}
else {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction))"});
}
}
}
retValue = fXIntPool.getXInt(choice);
break;
case DT_FINAL1:
// final = (#all | List of (list | union | restriction))
choice = 0;
if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
//choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
// SchemaSymbols.UNION;
// REVISIT: if #all, then make the result the combination of
// everything: substitution/externsion/restriction/list/union.
// would this be a problem?
// same reason as above DT_BLOCK1/DT_FINAL
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
XSConstants.DERIVATION_UNION;
}
else if (value.equals (SchemaSymbols.ATTVAL_LIST)) {
choice = XSConstants.DERIVATION_LIST;
}
else if (value.equals (SchemaSymbols.ATTVAL_UNION)) {
choice = XSConstants.DERIVATION_UNION;
} else {
// use the default \t\r\n\f delimiters
StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
choice |= XSConstants.DERIVATION_LIST;
}
else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
choice |= XSConstants.DERIVATION_UNION;
}
else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
choice |= XSConstants.DERIVATION_RESTRICTION;
}
else {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (list | union | restriction))"});
}
}
}
retValue = fXIntPool.getXInt(choice);
break;
case DT_FINAL2:
// finalDefault = (#all | List of (extension | restriction | list | union))
choice = 0;
if (value.equals (SchemaSymbols.ATTVAL_POUNDALL)) {
//choice = SchemaSymbols.RESTRICTION|SchemaSymbols.LIST|
// SchemaSymbols.UNION;
// REVISIT: if #all, then make the result the combination of
// everything: substitution/externsion/restriction/list/union.
// would this be a problem?
// same reason as above DT_BLOCK1/DT_FINAL
choice = XSConstants.DERIVATION_SUBSTITUTION|XSConstants.DERIVATION_EXTENSION|
XSConstants.DERIVATION_RESTRICTION|XSConstants.DERIVATION_LIST|
XSConstants.DERIVATION_UNION;
}
else {
// use the default \t\r\n\f delimiters
StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
if (token.equals (SchemaSymbols.ATTVAL_EXTENSION)) {
choice |= XSConstants.DERIVATION_EXTENSION;
}
else if (token.equals (SchemaSymbols.ATTVAL_RESTRICTION)) {
choice |= XSConstants.DERIVATION_RESTRICTION;
}
else if (token.equals (SchemaSymbols.ATTVAL_LIST)) {
choice |= XSConstants.DERIVATION_LIST;
}
else if (token.equals (SchemaSymbols.ATTVAL_UNION)) {
choice |= XSConstants.DERIVATION_UNION;
}
else {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(#all | List of (extension | restriction | list | union))"});
}
}
}
retValue = fXIntPool.getXInt(choice);
break;
case DT_FORM:
// form = (qualified | unqualified)
if (value.equals (SchemaSymbols.ATTVAL_QUALIFIED))
retValue = INT_QUALIFIED;
else if (value.equals (SchemaSymbols.ATTVAL_UNQUALIFIED))
retValue = INT_UNQUALIFIED;
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(qualified | unqualified)"});
break;
case DT_MAXOCCURS:
// maxOccurs = (nonNegativeInteger | unbounded)
if (value.equals(SchemaSymbols.ATTVAL_UNBOUNDED)) {
retValue = INT_UNBOUNDED;
} else {
try {
retValue = validate(attrValues, attr, value, DT_NONNEGINT, schemaDoc);
} catch (NumberFormatException e) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "(nonNegativeInteger | unbounded)"});
}
}
break;
case DT_MAXOCCURS1:
// maxOccurs = 1
if (value.equals("1"))
retValue = fXIntPool.getXInt(1);
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(1)"});
break;
case DT_MEMBERTYPES:
// memberTypes = List of QName
memberType = new Vector();
try {
// use the default \t\r\n\f delimiters
StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
QName qname = (QName)fExtraDVs[DT_QNAME].validate(token, schemaDoc.fValidationContext, null);
// kludge to handle chameleon includes/redefines...
if(qname.prefix == XMLSymbols.EMPTY_STRING && qname.uri == null && schemaDoc.fIsChameleonSchema)
qname.uri = schemaDoc.fTargetNamespace;
memberType.addElement(qname);
}
retValue = memberType;
}
catch (InvalidDatatypeValueException ide) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.2", new Object[]{value, "(List of QName)"});
}
break;
case DT_MINOCCURS1:
// minOccurs = (0 | 1)
if (value.equals("0"))
retValue = fXIntPool.getXInt(0);
else if (value.equals("1"))
retValue = fXIntPool.getXInt(1);
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(0 | 1)"});
break;
case DT_NAMESPACE:
// namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )
if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY)) {
// ##any
retValue = INT_ANY_ANY;
} else if (value.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
// ##other
retValue = INT_ANY_NOT;
String[] list = new String[2];
list[0] = schemaDoc.fTargetNamespace;
list[1] = null;
attrValues[ATTIDX_NAMESPACE_LIST] = list;
} else {
// list
retValue = INT_ANY_LIST;
fNamespaceList.removeAllElements();
// tokenize
// use the default \t\r\n\f delimiters
StringTokenizer tokens = new StringTokenizer(value);
String token;
String tempNamespace;
try {
while (tokens.hasMoreTokens()) {
token = tokens.nextToken();
if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
tempNamespace = null;
} else if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS)) {
tempNamespace = schemaDoc.fTargetNamespace;
} else {
// we have found namespace URI here
// need to add it to the symbol table
fExtraDVs[DT_ANYURI].validate(token, schemaDoc.fValidationContext, null);
tempNamespace = fSymbolTable.addSymbol(token);
}
//check for duplicate namespaces in the list
if (!fNamespaceList.contains(tempNamespace)) {
fNamespaceList.addElement(tempNamespace);
}
}
} catch (InvalidDatatypeValueException ide) {
throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", new Object[]{value, "((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )"});
}
// convert the vector to an array
int num = fNamespaceList.size();
String[] list = new String[num];
fNamespaceList.copyInto(list);
attrValues[ATTIDX_NAMESPACE_LIST] = list;
}
break;
case DT_PROCESSCONTENTS:
// processContents = (lax | skip | strict)
if (value.equals (SchemaSymbols.ATTVAL_STRICT))
retValue = INT_ANY_STRICT;
else if (value.equals (SchemaSymbols.ATTVAL_LAX))
retValue = INT_ANY_LAX;
else if (value.equals (SchemaSymbols.ATTVAL_SKIP))
retValue = INT_ANY_SKIP;
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(lax | skip | strict)"});
break;
case DT_USE:
// use = (optional | prohibited | required)
if (value.equals (SchemaSymbols.ATTVAL_OPTIONAL))
retValue = INT_USE_OPTIONAL;
else if (value.equals (SchemaSymbols.ATTVAL_REQUIRED))
retValue = INT_USE_REQUIRED;
else if (value.equals (SchemaSymbols.ATTVAL_PROHIBITED))
retValue = INT_USE_PROHIBITED;
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(optional | prohibited | required)"});
break;
case DT_WHITESPACE:
// value = preserve | replace | collapse
if (value.equals (SchemaSymbols.ATTVAL_PRESERVE))
retValue = INT_WS_PRESERVE;
else if (value.equals (SchemaSymbols.ATTVAL_REPLACE))
retValue = INT_WS_REPLACE;
else if (value.equals (SchemaSymbols.ATTVAL_COLLAPSE))
retValue = INT_WS_COLLAPSE;
else
throw new InvalidDatatypeValueException("cvc-enumeration-valid",
new Object[]{value, "(preserve | replace | collapse)"});
break;
}
return retValue;
|
|