You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by sa...@apache.org on 2002/09/19 01:22:15 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs/traversers XSAttributeChecker.java
sandygao 2002/09/18 16:22:15
Modified: java/src/org/apache/xerces/impl/xs/traversers
XSAttributeChecker.java
Log:
Performance improvement for schema grammar parsing:
1. Specify the size of hashtables, to avoid too many empty enties or rehashing.
2. Choose either vector or hashtable based on the number of enties.
3. Avoid whitespace normalization: stripping the leading and trailing spaces
are sufficient in most cases.
Revision Changes Path
1.18 +162 -103 xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSAttributeChecker.java
Index: XSAttributeChecker.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSAttributeChecker.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- XSAttributeChecker.java 30 Aug 2002 02:53:05 -0000 1.17
+++ XSAttributeChecker.java 18 Sep 2002 23:22:15 -0000 1.18
@@ -172,8 +172,10 @@
private static final XInt INT_UNBOUNDED = fXIntPool.getXInt(SchemaSymbols.OCCURRENCE_UNBOUNDED);
// used to store the map from element name to attribute list
- private static final Hashtable fEleAttrsMapG = new Hashtable();
- private static final Hashtable fEleAttrsMapL = new Hashtable();
+ // for 14 global elements
+ private static final Hashtable fEleAttrsMapG = new Hashtable(29);
+ // for 39 local elememnts
+ private static final Hashtable fEleAttrsMapL = new Hashtable(79);
// used to initialize fEleAttrsMap
// step 1: all possible data types
@@ -468,11 +470,11 @@
null);
// step 4: for each element, make a list of possible attributes
- Hashtable attrList;
+ Container attrList;
OneElement oneEle;
// for element "attribute" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(5);
// default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
// fixed = string
@@ -487,7 +489,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTE, oneEle);
// for element "attribute" - local name
- attrList = new Hashtable();
+ attrList = Container.getContainer(7);
// default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
// fixed = string
@@ -506,7 +508,7 @@
fEleAttrsMapL.put(ATTRIBUTE_N, oneEle);
// for element "attribute" - local ref
- attrList = new Hashtable();
+ attrList = Container.getContainer(5);
// default = string
attrList.put(SchemaSymbols.ATT_DEFAULT, allAttrs[ATT_DEFAULT_N]);
// fixed = string
@@ -521,7 +523,7 @@
fEleAttrsMapL.put(ATTRIBUTE_R, oneEle);
// for element "element" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(10);
// abstract = boolean : false
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
// block = (#all | List of (substitution | extension | restriction | list | union))
@@ -546,7 +548,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_ELEMENT, oneEle);
// for element "element" - local name
- attrList = new Hashtable();
+ attrList = Container.getContainer(10);
// block = (#all | List of (substitution | extension | restriction | list | union))
attrList.put(SchemaSymbols.ATT_BLOCK, allAttrs[ATT_BLOCK_N]);
// default = string
@@ -571,7 +573,7 @@
fEleAttrsMapL.put(ELEMENT_N, oneEle);
// for element "element" - local ref
- attrList = new Hashtable();
+ attrList = Container.getContainer(4);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// maxOccurs = (nonNegativeInteger | unbounded) : 1
@@ -584,7 +586,7 @@
fEleAttrsMapL.put(ELEMENT_R, oneEle);
// for element "complexType" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(6);
// abstract = boolean : false
attrList.put(SchemaSymbols.ATT_ABSTRACT, allAttrs[ATT_ABSTRACT_D]);
// block = (#all | List of (extension | restriction))
@@ -601,7 +603,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_COMPLEXTYPE, oneEle);
// for element "notation" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(4);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// name = NCName
@@ -615,7 +617,7 @@
// for element "complexType" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// mixed = boolean : false
@@ -624,14 +626,14 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXTYPE, oneEle);
// for element "simpleContent" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(1);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
oneEle = new OneElement (attrList);
fEleAttrsMapL.put(SchemaSymbols.ELT_SIMPLECONTENT, oneEle);
// for element "restriction" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// base = QName
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_N]);
// id = ID
@@ -640,7 +642,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_RESTRICTION, oneEle);
// for element "extension" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// base = QName
attrList.put(SchemaSymbols.ATT_BASE, allAttrs[ATT_BASE_R]);
// id = ID
@@ -649,7 +651,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_EXTENSION, oneEle);
// for element "attributeGroup" - local ref
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// ref = QName
@@ -658,7 +660,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, oneEle);
// for element "anyAttribute" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
@@ -669,7 +671,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ANYATTRIBUTE, oneEle);
// for element "complexContent" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// mixed = boolean
@@ -678,7 +680,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_COMPLEXCONTENT, oneEle);
// for element "attributeGroup" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// name = NCName
@@ -687,7 +689,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_ATTRIBUTEGROUP, oneEle);
// for element "group" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// name = NCName
@@ -696,7 +698,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_GROUP, oneEle);
// for element "group" - local ref
- attrList = new Hashtable();
+ attrList = Container.getContainer(4);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// maxOccurs = (nonNegativeInteger | unbounded) : 1
@@ -709,7 +711,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_GROUP, oneEle);
// for element "all" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// maxOccurs = 1 : 1
@@ -720,7 +722,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ALL, oneEle);
// for element "choice" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// maxOccurs = (nonNegativeInteger | unbounded) : 1
@@ -733,7 +735,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_SEQUENCE, oneEle);
// for element "any" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(5);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// maxOccurs = (nonNegativeInteger | unbounded) : 1
@@ -748,7 +750,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ANY, oneEle);
// for element "unique" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// name = NCName
@@ -759,7 +761,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_KEY, oneEle);
// for element "keyref" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// name = NCName
@@ -770,7 +772,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_KEYREF, oneEle);
// for element "selector" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// xpath = a subset of XPath expression
@@ -779,7 +781,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_SELECTOR, oneEle);
// for element "field" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// xpath = a subset of XPath expression
@@ -788,7 +790,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_FIELD, oneEle);
// for element "annotation" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(1);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
oneEle = new OneElement (attrList);
@@ -797,7 +799,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ANNOTATION, oneEle);
// for element "appinfo" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(1);
// source = anyURI
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
oneEle = new OneElement (attrList, false);
@@ -805,7 +807,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_APPINFO, oneEle);
// for element "documentation" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(1);
// source = anyURI
attrList.put(SchemaSymbols.ATT_SOURCE, allAttrs[ATT_SOURCE_N]);
// xml:lang = language ???
@@ -814,7 +816,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_DOCUMENTATION, oneEle);
// for element "simpleType" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// final = (#all | (list | union | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
// id = ID
@@ -825,7 +827,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_SIMPLETYPE, oneEle);
// for element "simpleType" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// final = (#all | (list | union | restriction))
attrList.put(SchemaSymbols.ATT_FINAL, allAttrs[ATT_FINAL1_N]);
// id = ID
@@ -837,7 +839,7 @@
// already registered for complexType
// for element "list" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// itemType = QName
@@ -846,7 +848,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_LIST, oneEle);
// for element "union" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// memberTypes = List of QName
@@ -855,7 +857,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_UNION, oneEle);
// for element "schema" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(7);
// attributeFormDefault = (qualified | unqualified) : unqualified
attrList.put(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT, allAttrs[ATT_ATTRIBUTE_FD_D]);
// blockDefault = (#all | List of (substitution | extension | restriction | list | union)) : ''
@@ -875,7 +877,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_SCHEMA, oneEle);
// for element "include" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// schemaLocation = anyURI
@@ -886,7 +888,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_REDEFINE, oneEle);
// for element "import" - global
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// namespace = anyURI
@@ -897,7 +899,7 @@
fEleAttrsMapG.put(SchemaSymbols.ELT_IMPORT, oneEle);
// for element "length" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// value = nonNegativeInteger
@@ -916,7 +918,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_FRACTIONDIGITS, oneEle);
// for element "pattern" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// value = string
@@ -925,7 +927,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_PATTERN, oneEle);
// for element "enumeration" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(2);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// value = anySimpleType
@@ -934,7 +936,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_ENUMERATION, oneEle);
// for element "whiteSpace" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// value = preserve | replace | collapse
@@ -945,7 +947,7 @@
fEleAttrsMapL.put(SchemaSymbols.ELT_WHITESPACE, oneEle);
// for element "maxInclusive" - local
- attrList = new Hashtable();
+ attrList = Container.getContainer(3);
// id = ID
attrList.put(SchemaSymbols.ATT_ID, allAttrs[ATT_ID_N]);
// value = anySimpleType
@@ -971,6 +973,9 @@
// used to store the mapping from processed element to attributes
protected Hashtable fNonSchemaAttrs = new Hashtable();
+ // temprory vector, used to hold the namespace list
+ protected Vector fNamespaceList = new Vector();
+
// constructor. Sets fErrorReproter and get datatype validators
public XSAttributeChecker(XSDHandler schemaHandler) {
fSchemaHandler = schemaHandler;
@@ -1014,13 +1019,17 @@
XSDocumentInfo schemaDoc, boolean enumAsQName) {
if (element == null)
return null;
+
+ // get all attributes
+ Attr[] attrs = DOMUtil.getAttrs(element);
+
// update NamespaceSupport
- resolveNamespace(element, schemaDoc.fNamespaceSupport);
+ resolveNamespace(element, attrs, schemaDoc.fNamespaceSupport);
String uri = DOMUtil.getNamespaceURI(element);
String elName = DOMUtil.getLocalName(element);
- if (uri == null || !uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
+ if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(uri)) {
reportSchemaError("s4s-elt-schema-ns", new Object[] {elName}, element);
}
@@ -1060,12 +1069,15 @@
Object[] attrValues = getAvailableArray();
//Hashtable otherValues = new Hashtable();
long fromDefault = 0;
- Hashtable attrList = oneEle.attrList;
+ Container attrList = oneEle.attrList;
+
+ // clear the "seen" flag.
+ attrList.start();
// traverse all attributes
- Attr[] attrs = DOMUtil.getAttrs(element);
+ int length = attrs.length;
Attr sattr = null;
- for (int i = 0; i < attrs.length; i++) {
+ for (int i = 0; i < length; i++) {
sattr = attrs[i];
// get the attribute name/value
//String attrName = DOMUtil.getLocalName(sattr);
@@ -1161,15 +1173,15 @@
attrValues[ATTIDX_ENUMNSDECLS] = new SchemaNamespaceSupport(schemaDoc.fNamespaceSupport);
}
}
- // traverse all required attributes
- OneAttr[] reqAttrs = oneEle.attrArray;
+
+ // 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 &&
- DOMUtil.getAttr(element, oneAttr.name) == null) {
+ if (oneAttr.dfltValue != null && !oneAttr.seen) {
//attrValues.put(oneAttr.name, oneAttr.dfltValue);
attrValues[oneAttr.valueIndex] = oneAttr.dfltValue;
fromDefault |= (1<<oneAttr.valueIndex);
@@ -1202,9 +1214,12 @@
if (ivalue == null)
return null;
- // the whiteSpace facet of all types here have the value "collapse"
- String value = normalize(ivalue, XSSimpleType.WS_COLLAPSE);
- Object retValue = value;
+ // 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;
@@ -1238,7 +1253,8 @@
XSConstants.DERIVATION_UNION;
}
else {
- StringTokenizer t = new StringTokenizer (value, " ");
+ // use the default \t\r\n\f delimiters
+ StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
@@ -1286,7 +1302,8 @@
XSConstants.DERIVATION_UNION;
}
else {
- StringTokenizer t = new StringTokenizer (value, " ");
+ // use the default \t\r\n\f delimiters
+ StringTokenizer t = new StringTokenizer(value);
while (t.hasMoreTokens()) {
String token = t.nextToken ();
@@ -1365,7 +1382,8 @@
// memberTypes = List of QName
memberType = new Vector();
try {
- StringTokenizer t = new StringTokenizer (value, " ");
+ // 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);
@@ -1405,10 +1423,11 @@
// list
wildcard.fType = XSWildcardDecl.NSCONSTRAINT_LIST;
+ fNamespaceList.removeAllElements();
+
// tokenize
+ // use the default \t\r\n\f delimiters
StringTokenizer tokens = new StringTokenizer(value);
- String[] namespaceList = new String[tokens.countTokens()];
- int nsNum = 0;
String token;
String tempNamespace;
try {
@@ -1426,29 +1445,19 @@
}
//check for duplicate namespaces in the list
- int j = 0;
- for (; j < nsNum; j++) {
- if (tempNamespace == namespaceList[j])
- break;
- }
- if (j == nsNum) {
- // this means traversed whole for loop
- // i.e. not a duplicate namespace
- namespaceList[nsNum++] = tempNamespace;
+ 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)) )"});
}
- // resize the array, so there is no empty entry
- if (nsNum == namespaceList.length) {
- wildcard.fNamespaceList = namespaceList;
- } else {
- wildcard.fNamespaceList = new String[nsNum];
- System.arraycopy(namespaceList, 0, wildcard.fNamespaceList, 0, nsNum);
- }
-
+ // convert the vector to an array
+ int num = fNamespaceList.size();
+ String[] list = new String[num];
+ wildcard.fNamespaceList = list;
+ fNamespaceList.copyInto(list);
}
retValue = wildcard;
break;
@@ -1467,7 +1476,7 @@
case DT_PUBLIC:
// public = A public identifier, per ISO 8879
// REVISIT: how to validate "public"???
- fExtraDVs[DT_TOKEN].validate(value, schemaDoc.fValidationContext, null);
+ retValue = fExtraDVs[DT_TOKEN].validate(value, schemaDoc.fValidationContext, null);
break;
case DT_USE:
// use = (optional | prohibited | required)
@@ -1658,27 +1667,26 @@
fArrayPool[--fPoolPos] = attrArray;
}
- public void resolveNamespace(Element element, SchemaNamespaceSupport nsSupport) {
+ public void resolveNamespace(Element element, Attr[] attrs,
+ SchemaNamespaceSupport nsSupport) {
// push the namespace context
nsSupport.pushContext();
// search for new namespace bindings
- Attr[] attrs = DOMUtil.getAttrs(element);
+ int length = attrs.length;
Attr sattr = null;
String rawname, prefix, uri;
- for (int i = 0; i < attrs.length; i++) {
+ for (int i = 0; i < length; i++) {
sattr = attrs[i];
rawname = DOMUtil.getName(sattr);
- if (rawname == XMLSymbols.PREFIX_XMLNS || rawname.startsWith("xmlns:")) {
- prefix = null;
- if (rawname.length() == 5)
- prefix = XMLSymbols.EMPTY_STRING;
- else if (rawname.charAt(5) == ':')
- prefix = fSymbolTable.addSymbol(DOMUtil.getLocalName(sattr));
- if (prefix != null) {
- uri = fSymbolTable.addSymbol(DOMUtil.getValue(sattr));
- nsSupport.declarePrefix(prefix, uri.length()!=0 ? uri : null);
- }
+ 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);
}
}
}
@@ -1693,6 +1701,8 @@
public int valueIndex;
// the default value of this attribute
public Object dfltValue;
+ // whether this attribute appeared in the current element
+ public boolean seen;
public OneAttr(String name, int dvIndex, int valueIndex, Object dfltValue) {
this.name = name;
@@ -1704,25 +1714,74 @@
class OneElement {
// the list of attributes that can appear in one element
- public Hashtable attrList;
- // the array of attributes that can appear in one element
- public OneAttr[] attrArray;
+ public Container attrList;
// does this element allow attributes from non-schema namespace
public boolean allowNonSchemaAttr;
- public OneElement (Hashtable attrList) {
+ public OneElement (Container attrList) {
this(attrList, true);
}
- public OneElement (Hashtable attrList, boolean allowNonSchemaAttr) {
+ public OneElement (Container attrList, boolean allowNonSchemaAttr) {
this.attrList = attrList;
+ this.allowNonSchemaAttr = allowNonSchemaAttr;
+ }
+}
- int count = attrList.size();
- this.attrArray = new OneAttr[count];
- Enumeration enum = attrList.elements();
- for (int i = 0; i < count; i++)
- this.attrArray[i] = (OneAttr)enum.nextElement();
+abstract class Container {
+ static final int THRESHOLD = 5;
+ static Container getContainer(int size) {
+ if (size > THRESHOLD)
+ return new LargeContainer(size);
+ else
+ return new SmallContainer(size);
+ }
+ abstract void put(String key, OneAttr value);
+ abstract OneAttr get(String key);
- this.allowNonSchemaAttr = allowNonSchemaAttr;
+ OneAttr[] values;
+ int pos = 0;
+ void start() {
+ for (int i = 0; i < pos; i++)
+ values[i].seen = false;
+ }
+}
+
+class SmallContainer extends Container {
+ String[] keys;
+ SmallContainer(int size) {
+ keys = new String[size];
+ values = new OneAttr[size];
+ }
+ void put(String key, OneAttr value) {
+ keys[pos] = key;
+ values[pos++] = value;
+ }
+ OneAttr get(String key) {
+ for (int i = 0; i < pos; i++) {
+ if (keys[i].equals(key)) {
+ values[i].seen = true;
+ return values[i];
+ }
+ }
+ return null;
+ }
+}
+
+class LargeContainer extends Container {
+ Hashtable items;
+ LargeContainer(int size) {
+ items = new Hashtable(size*2+1);
+ values = new OneAttr[size];
+ }
+ void put(String key, OneAttr value) {
+ items.put(key, value);
+ values[pos++] = value;
+ }
+ OneAttr get(String key) {
+ OneAttr ret = (OneAttr)items.get(key);
+ if (ret != null)
+ ret.seen = true;
+ return ret;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org