aboutsummaryrefslogtreecommitdiff
path: root/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java')
-rw-r--r--src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java1296
1 files changed, 0 insertions, 1296 deletions
diff --git a/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java b/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java
deleted file mode 100644
index a02d54a..0000000
--- a/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.org.apache.xerces.internal.util;
-
-import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.xni.QName;
-import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
-import com.sun.org.apache.xerces.internal.xni.XMLString;
-import com.sun.xml.internal.stream.XMLBufferListener;
-/**
- * The XMLAttributesImpl class is an implementation of the XMLAttributes
- * interface which defines a collection of attributes for an element.
- * In the parser, the document source would scan the entire start element
- * and collect the attributes. The attributes are communicated to the
- * document handler in the startElement method.
- * <p>
- * The attributes are read-write so that subsequent stages in the document
- * pipeline can modify the values or change the attributes that are
- * propogated to the next stage.
- *
- * @see com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler#startElement
- *
- * @author Andy Clark, IBM
- * @author Elena Litani, IBM
- * @author Michael Glavassevich, IBM
- *
- * @version $Id: XMLAttributesImpl.java,v 1.7 2010/05/07 20:13:09 joehw Exp $
- */
-public class XMLAttributesImpl
-implements XMLAttributes, XMLBufferListener {
-
- //
- // Constants
- //
-
- /** Default table size. */
- protected static final int TABLE_SIZE = 101;
-
- /** Maximum hash collisions per bucket. */
- protected static final int MAX_HASH_COLLISIONS = 40;
-
- protected static final int MULTIPLIERS_SIZE = 1 << 5;
- protected static final int MULTIPLIERS_MASK = MULTIPLIERS_SIZE - 1;
-
- /**
- * Threshold at which an instance is treated
- * as a large attribute list.
- */
- protected static final int SIZE_LIMIT = 20;
-
- //
- // Data
- //
-
- // features
-
- /** Namespaces. */
- protected boolean fNamespaces = true;
-
- // data
-
- /**
- * Usage count for the attribute table view.
- * Incremented each time all attributes are removed
- * when the attribute table view is in use.
- */
- protected int fLargeCount = 1;
-
- /** Attribute count. */
- protected int fLength;
-
- /** Attribute information. */
- protected Attribute[] fAttributes = new Attribute[4];
-
- /**
- * Provides an alternate view of the attribute specification.
- */
- protected Attribute[] fAttributeTableView;
-
- /**
- * Tracks whether each chain in the hash table is stale
- * with respect to the current state of this object.
- * A chain is stale if its state is not the same as the number
- * of times the attribute table view has been used.
- */
- protected int[] fAttributeTableViewChainState;
-
- /**
- * Actual number of buckets in the table view.
- */
- protected int fTableViewBuckets;
-
- /**
- * Indicates whether the table view contains consistent data.
- */
- protected boolean fIsTableViewConsistent;
-
- /**
- * Array of randomly selected hash function multipliers or <code>null</code>
- * if the default String.hashCode() function should be used.
- */
- protected int[] fHashMultipliers;
-
- //
- // Constructors
- //
-
- /** Default constructor. */
- public XMLAttributesImpl() {
- this(TABLE_SIZE);
- }
-
- /**
- * @param tableSize initial size of table view
- */
- public XMLAttributesImpl(int tableSize) {
- fTableViewBuckets = tableSize;
- for (int i = 0; i < fAttributes.length; i++) {
- fAttributes[i] = new Attribute();
- }
- } // <init>()
-
- //
- // Public methods
- //
-
- /**
- * Sets whether namespace processing is being performed. This state
- * is needed to return the correct value from the getLocalName method.
- *
- * @param namespaces True if namespace processing is turned on.
- *
- * @see #getLocalName
- */
- public void setNamespaces(boolean namespaces) {
- fNamespaces = namespaces;
- } // setNamespaces(boolean)
-
- //
- // XMLAttributes methods
- //
-
- /**
- * Adds an attribute. The attribute's non-normalized value of the
- * attribute will have the same value as the attribute value until
- * set using the <code>setNonNormalizedValue</code> method. Also,
- * the added attribute will be marked as specified in the XML instance
- * document unless set otherwise using the <code>setSpecified</code>
- * method.
- * <p>
- * <strong>Note:</strong> If an attribute of the same name already
- * exists, the old values for the attribute are replaced by the new
- * values.
- *
- * @param name The attribute name.
- * @param type The attribute type. The type name is determined by
- * the type specified for this attribute in the DTD.
- * For example: "CDATA", "ID", "NMTOKEN", etc. However,
- * attributes of type enumeration will have the type
- * value specified as the pipe ('|') separated list of
- * the enumeration values prefixed by an open
- * parenthesis and suffixed by a close parenthesis.
- * For example: "(true|false)".
- * @param value The attribute value.
- *
- * @return Returns the attribute index.
- *
- * @see #setNonNormalizedValue
- * @see #setSpecified
- */
- public int addAttribute(QName name, String type, String value) {
- return addAttribute(name,type,value,null);
- }
- public int addAttribute(QName name, String type, String value,XMLString valueCache) {
-
- int index;
- if (fLength < SIZE_LIMIT) {
- index = name.uri != null && !name.uri.equals("")
- ? getIndexFast(name.uri, name.localpart)
- : getIndexFast(name.rawname);
-
- if (index == -1) {
- index = fLength;
- if (fLength++ == fAttributes.length) {
- Attribute[] attributes = new Attribute[fAttributes.length + 4];
- System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length);
- for (int i = fAttributes.length; i < attributes.length; i++) {
- attributes[i] = new Attribute();
- }
- fAttributes = attributes;
- }
- }
- }
- else if (name.uri == null ||
- name.uri.length() == 0 ||
- (index = getIndexFast(name.uri, name.localpart)) == -1) {
-
- /**
- * If attributes were removed from the list after the table
- * becomes in use this isn't reflected in the table view. It's
- * assumed that once a user starts removing attributes they're
- * not likely to add more. We only make the view consistent if
- * the user of this class adds attributes, removes them, and
- * then adds more.
- */
- if (!fIsTableViewConsistent || fLength == SIZE_LIMIT ||
- (fLength > SIZE_LIMIT && fLength > fTableViewBuckets)) {
- prepareAndPopulateTableView();
- fIsTableViewConsistent = true;
- }
-
- int bucket = getTableViewBucket(name.rawname);
-
- // The chain is stale.
- // This must be a unique attribute.
- if (fAttributeTableViewChainState[bucket] != fLargeCount) {
- index = fLength;
- if (fLength++ == fAttributes.length) {
- Attribute[] attributes = new Attribute[fAttributes.length << 1];
- System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length);
- for (int i = fAttributes.length; i < attributes.length; i++) {
- attributes[i] = new Attribute();
- }
- fAttributes = attributes;
- }
-
- // Update table view.
- fAttributeTableViewChainState[bucket] = fLargeCount;
- fAttributes[index].next = null;
- fAttributeTableView[bucket] = fAttributes[index];
- }
- // This chain is active.
- // We need to check if any of the attributes has the same rawname.
- else {
- // Search the table.
- int collisionCount = 0;
- Attribute found = fAttributeTableView[bucket];
- while (found != null) {
- if (found.name.rawname == name.rawname) {
- break;
- }
- found = found.next;
- ++collisionCount;
- }
- // This attribute is unique.
- if (found == null) {
- index = fLength;
- if (fLength++ == fAttributes.length) {
- Attribute[] attributes = new Attribute[fAttributes.length << 1];
- System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length);
- for (int i = fAttributes.length; i < attributes.length; i++) {
- attributes[i] = new Attribute();
- }
- fAttributes = attributes;
- }
-
- // Select a new hash function and rehash the table view
- // if the collision threshold is exceeded.
- if (collisionCount >= MAX_HASH_COLLISIONS) {
- // The current attribute will be processed in the rehash.
- // Need to set its name first.
- fAttributes[index].name.setValues(name);
- rebalanceTableView(fLength);
- }
- else {
- // Update table view
- fAttributes[index].next = fAttributeTableView[bucket];
- fAttributeTableView[bucket] = fAttributes[index];
- }
- }
- // Duplicate. We still need to find the index.
- else {
- index = getIndexFast(name.rawname);
- }
- }
- }
-
- // set values
- Attribute attribute = fAttributes[index];
- attribute.name.setValues(name);
- attribute.type = type;
- attribute.value = value;
- attribute.xmlValue = valueCache;
- attribute.nonNormalizedValue = value;
- attribute.specified = false;
-
- // clear augmentations
- if(attribute.augs != null)
- attribute.augs.removeAllItems();
-
- return index;
-
- } // addAttribute(QName,String,XMLString)
-
- /**
- * Removes all of the attributes. This method will also remove all
- * entities associated to the attributes.
- */
- public void removeAllAttributes() {
- fLength = 0;
- } // removeAllAttributes()
-
- /**
- * Removes the attribute at the specified index.
- * <p>
- * <strong>Note:</strong> This operation changes the indexes of all
- * attributes following the attribute at the specified index.
- *
- * @param attrIndex The attribute index.
- */
- public void removeAttributeAt(int attrIndex) {
- fIsTableViewConsistent = false;
- if (attrIndex < fLength - 1) {
- Attribute removedAttr = fAttributes[attrIndex];
- System.arraycopy(fAttributes, attrIndex + 1,
- fAttributes, attrIndex, fLength - attrIndex - 1);
- // Make the discarded Attribute object available for re-use
- // by tucking it after the Attributes that are still in use
- fAttributes[fLength-1] = removedAttr;
- }
- fLength--;
- } // removeAttributeAt(int)
-
- /**
- * Sets the name of the attribute at the specified index.
- *
- * @param attrIndex The attribute index.
- * @param attrName The new attribute name.
- */
- public void setName(int attrIndex, QName attrName) {
- fAttributes[attrIndex].name.setValues(attrName);
- } // setName(int,QName)
-
- /**
- * Sets the fields in the given QName structure with the values
- * of the attribute name at the specified index.
- *
- * @param attrIndex The attribute index.
- * @param attrName The attribute name structure to fill in.
- */
- public void getName(int attrIndex, QName attrName) {
- attrName.setValues(fAttributes[attrIndex].name);
- } // getName(int,QName)
-
- /**
- * Sets the type of the attribute at the specified index.
- *
- * @param attrIndex The attribute index.
- * @param attrType The attribute type. The type name is determined by
- * the type specified for this attribute in the DTD.
- * For example: "CDATA", "ID", "NMTOKEN", etc. However,
- * attributes of type enumeration will have the type
- * value specified as the pipe ('|') separated list of
- * the enumeration values prefixed by an open
- * parenthesis and suffixed by a close parenthesis.
- * For example: "(true|false)".
- */
- public void setType(int attrIndex, String attrType) {
- fAttributes[attrIndex].type = attrType;
- } // setType(int,String)
-
- /**
- * Sets the value of the attribute at the specified index. This
- * method will overwrite the non-normalized value of the attribute.
- *
- * @param attrIndex The attribute index.
- * @param attrValue The new attribute value.
- *
- * @see #setNonNormalizedValue
- */
- public void setValue(int attrIndex, String attrValue) {
- setValue(attrIndex,attrValue,null);
- }
-
- public void setValue(int attrIndex, String attrValue,XMLString value) {
- Attribute attribute = fAttributes[attrIndex];
- attribute.value = attrValue;
- attribute.nonNormalizedValue = attrValue;
- attribute.xmlValue = value;
- } // setValue(int,String)
-
- /**
- * Sets the non-normalized value of the attribute at the specified
- * index.
- *
- * @param attrIndex The attribute index.
- * @param attrValue The new non-normalized attribute value.
- */
- public void setNonNormalizedValue(int attrIndex, String attrValue) {
- if (attrValue == null) {
- attrValue = fAttributes[attrIndex].value;
- }
- fAttributes[attrIndex].nonNormalizedValue = attrValue;
- } // setNonNormalizedValue(int,String)
-
- /**
- * Returns the non-normalized value of the attribute at the specified
- * index. If no non-normalized value is set, this method will return
- * the same value as the <code>getValue(int)</code> method.
- *
- * @param attrIndex The attribute index.
- */
- public String getNonNormalizedValue(int attrIndex) {
- String value = fAttributes[attrIndex].nonNormalizedValue;
- return value;
- } // getNonNormalizedValue(int):String
-
- /**
- * Sets whether an attribute is specified in the instance document
- * or not.
- *
- * @param attrIndex The attribute index.
- * @param specified True if the attribute is specified in the instance
- * document.
- */
- public void setSpecified(int attrIndex, boolean specified) {
- fAttributes[attrIndex].specified = specified;
- } // setSpecified(int,boolean)
-
- /**
- * Returns true if the attribute is specified in the instance document.
- *
- * @param attrIndex The attribute index.
- */
- public boolean isSpecified(int attrIndex) {
- return fAttributes[attrIndex].specified;
- } // isSpecified(int):boolean
-
- //
- // AttributeList and Attributes methods
- //
-
- /**
- * Return the number of attributes in the list.
- *
- * <p>Once you know the number of attributes, you can iterate
- * through the list.</p>
- *
- * @return The number of attributes in the list.
- */
- public int getLength() {
- return fLength;
- } // getLength():int
-
- /**
- * Look up an attribute's type by index.
- *
- * <p>The attribute type is one of the strings "CDATA", "ID",
- * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
- * or "NOTATION" (always in upper case).</p>
- *
- * <p>If the parser has not read a declaration for the attribute,
- * or if the parser does not report attribute types, then it must
- * return the value "CDATA" as stated in the XML 1.0 Recommentation
- * (clause 3.3.3, "Attribute-Value Normalization").</p>
- *
- * <p>For an enumerated attribute that is not a notation, the
- * parser will report the type as "NMTOKEN".</p>
- *
- * @param index The attribute index (zero-based).
- * @return The attribute's type as a string, or null if the
- * index is out of range.
- * @see #getLength
- */
- public String getType(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- return getReportableType(fAttributes[index].type);
- } // getType(int):String
-
- /**
- * Look up an attribute's type by XML 1.0 qualified name.
- *
- * <p>See {@link #getType(int) getType(int)} for a description
- * of the possible types.</p>
- *
- * @param qname The XML 1.0 qualified name.
- * @return The attribute type as a string, or null if the
- * attribute is not in the list or if qualified names
- * are not available.
- */
- public String getType(String qname) {
- int index = getIndex(qname);
- return index != -1 ? getReportableType(fAttributes[index].type) : null;
- } // getType(String):String
-
- /**
- * Look up an attribute's value by index.
- *
- * <p>If the attribute value is a list of tokens (IDREFS,
- * ENTITIES, or NMTOKENS), the tokens will be concatenated
- * into a single string with each token separated by a
- * single space.</p>
- *
- * @param index The attribute index (zero-based).
- * @return The attribute's value as a string, or null if the
- * index is out of range.
- * @see #getLength
- */
- public String getValue(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- if(fAttributes[index].value == null && fAttributes[index].xmlValue != null)
- fAttributes[index].value = fAttributes[index].xmlValue.toString();
- return fAttributes[index].value;
- } // getValue(int):String
-
- /**
- * Look up an attribute's value by XML 1.0 qualified name.
- *
- * <p>See {@link #getValue(int) getValue(int)} for a description
- * of the possible values.</p>
- *
- * @param qname The XML 1.0 qualified name.
- * @return The attribute value as a string, or null if the
- * attribute is not in the list or if qualified names
- * are not available.
- */
- public String getValue(String qname) {
- int index = getIndex(qname);
- if(index == -1 )
- return null;
- if(fAttributes[index].value == null)
- fAttributes[index].value = fAttributes[index].xmlValue.toString();
- return fAttributes[index].value;
- } // getValue(String):String
-
- //
- // AttributeList methods
- //
-
- /**
- * Return the name of an attribute in this list (by position).
- *
- * <p>The names must be unique: the SAX parser shall not include the
- * same attribute twice. Attributes without values (those declared
- * #IMPLIED without a value specified in the start tag) will be
- * omitted from the list.</p>
- *
- * <p>If the attribute name has a namespace prefix, the prefix
- * will still be attached.</p>
- *
- * @param i The index of the attribute in the list (starting at 0).
- * @return The name of the indexed attribute, or null
- * if the index is out of range.
- * @see #getLength
- */
- public String getName(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- return fAttributes[index].name.rawname;
- } // getName(int):String
-
- //
- // Attributes methods
- //
-
- /**
- * Look up the index of an attribute by XML 1.0 qualified name.
- *
- * @param qName The qualified (prefixed) name.
- * @return The index of the attribute, or -1 if it does not
- * appear in the list.
- */
- public int getIndex(String qName) {
- for (int i = 0; i < fLength; i++) {
- Attribute attribute = fAttributes[i];
- if (attribute.name.rawname != null &&
- attribute.name.rawname.equals(qName)) {
- return i;
- }
- }
- return -1;
- } // getIndex(String):int
-
- /**
- * Look up the index of an attribute by Namespace name.
- *
- * @param uri The Namespace URI, or null if
- * the name has no Namespace URI.
- * @param localName The attribute's local name.
- * @return The index of the attribute, or -1 if it does not
- * appear in the list.
- */
- public int getIndex(String uri, String localPart) {
- for (int i = 0; i < fLength; i++) {
- Attribute attribute = fAttributes[i];
- if (attribute.name.localpart != null &&
- attribute.name.localpart.equals(localPart) &&
- ((uri==attribute.name.uri) ||
- (uri!=null && attribute.name.uri!=null && attribute.name.uri.equals(uri)))) {
- return i;
- }
- }
- return -1;
- } // getIndex(String,String):int
-
- /**
- * Look up the index of an attribute by local name only,
- * ignoring its namespace.
- *
- * @param localName The attribute's local name.
- * @return The index of the attribute, or -1 if it does not
- * appear in the list.
- */
- public int getIndexByLocalName(String localPart) {
- for (int i = 0; i < fLength; i++) {
- Attribute attribute = fAttributes[i];
- if (attribute.name.localpart != null &&
- attribute.name.localpart.equals(localPart)) {
- return i;
- }
- }
- return -1;
- } // getIndex(String):int
-
- /**
- * Look up an attribute's local name by index.
- *
- * @param index The attribute index (zero-based).
- * @return The local name, or the empty string if Namespace
- * processing is not being performed, or null
- * if the index is out of range.
- * @see #getLength
- */
- public String getLocalName(int index) {
- if (!fNamespaces) {
- return "";
- }
- if (index < 0 || index >= fLength) {
- return null;
- }
- return fAttributes[index].name.localpart;
- } // getLocalName(int):String
-
- /**
- * Look up an attribute's XML 1.0 qualified name by index.
- *
- * @param index The attribute index (zero-based).
- * @return The XML 1.0 qualified name, or the empty string
- * if none is available, or null if the index
- * is out of range.
- * @see #getLength
- */
- public String getQName(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- String rawname = fAttributes[index].name.rawname;
- return rawname != null ? rawname : "";
- } // getQName(int):String
-
- public QName getQualifiedName(int index){
- if (index < 0 || index >= fLength) {
- return null;
- }
- return fAttributes[index].name;
- }
-
- /**
- * Look up an attribute's type by Namespace name.
- *
- * <p>See {@link #getType(int) getType(int)} for a description
- * of the possible types.</p>
- *
- * @param uri The Namespace URI, or null if the
- * name has no Namespace URI.
- * @param localName The local name of the attribute.
- * @return The attribute type as a string, or null if the
- * attribute is not in the list or if Namespace
- * processing is not being performed.
- */
- public String getType(String uri, String localName) {
- if (!fNamespaces) {
- return null;
- }
- int index = getIndex(uri, localName);
- return index != -1 ? getType(index) : null;
- } // getType(String,String):String
- /**
- * Look up the index of an attribute by XML 1.0 qualified name.
- * <p>
- * <strong>Note:</strong>
- * This method uses reference comparison, and thus should
- * only be used internally. We cannot use this method in any
- * code exposed to users as they may not pass in unique strings.
- *
- * @param qName The qualified (prefixed) name.
- * @return The index of the attribute, or -1 if it does not
- * appear in the list.
- */
- public int getIndexFast(String qName) {
- for (int i = 0; i < fLength; ++i) {
- Attribute attribute = fAttributes[i];
- if (attribute.name.rawname == qName) {
- return i;
- }
- }
- return -1;
- } // getIndexFast(String):int
-
- /**
- * Adds an attribute. The attribute's non-normalized value of the
- * attribute will have the same value as the attribute value until
- * set using the <code>setNonNormalizedValue</code> method. Also,
- * the added attribute will be marked as specified in the XML instance
- * document unless set otherwise using the <code>setSpecified</code>
- * method.
- * <p>
- * This method differs from <code>addAttribute</code> in that it
- * does not check if an attribute of the same name already exists
- * in the list before adding it. In order to improve performance
- * of namespace processing, this method allows uniqueness checks
- * to be deferred until all the namespace information is available
- * after the entire attribute specification has been read.
- * <p>
- * <strong>Caution:</strong> If this method is called it should
- * not be mixed with calls to <code>addAttribute</code> unless
- * it has been determined that all the attribute names are unique.
- *
- * @param name the attribute name
- * @param type the attribute type
- * @param value the attribute value
- *
- * @see #setNonNormalizedValue
- * @see #setSpecified
- * @see #checkDuplicatesNS
- */
- public void addAttributeNS(QName name, String type, String value) {
- int index = fLength;
- if (fLength++ == fAttributes.length) {
- Attribute[] attributes;
- if (fLength < SIZE_LIMIT) {
- attributes = new Attribute[fAttributes.length + 4];
- }
- else {
- attributes = new Attribute[fAttributes.length << 1];
- }
- System.arraycopy(fAttributes, 0, attributes, 0, fAttributes.length);
- for (int i = fAttributes.length; i < attributes.length; i++) {
- attributes[i] = new Attribute();
- }
- fAttributes = attributes;
- }
-
- // set values
- Attribute attribute = fAttributes[index];
- attribute.name.setValues(name);
- attribute.type = type;
- attribute.value = value;
- attribute.nonNormalizedValue = value;
- attribute.specified = false;
-
- // clear augmentations
- attribute.augs.removeAllItems();
- }
-
- /**
- * Checks for duplicate expanded names (local part and namespace name
- * pairs) in the attribute specification. If a duplicate is found its
- * name is returned.
- * <p>
- * This should be called once all the in-scope namespaces for the element
- * enclosing these attributes is known, and after all the attributes
- * have gone through namespace binding.
- *
- * @return the name of a duplicate attribute found in the search,
- * otherwise null.
- */
- public QName checkDuplicatesNS() {
- // If the list is small check for duplicates using pairwise comparison.
- final int length = fLength;
- if (length <= SIZE_LIMIT) {
- final Attribute[] attributes = fAttributes;
- for (int i = 0; i < length - 1; ++i) {
- Attribute att1 = attributes[i];
- for (int j = i + 1; j < length; ++j) {
- Attribute att2 = attributes[j];
- if (att1.name.localpart == att2.name.localpart &&
- att1.name.uri == att2.name.uri) {
- return att2.name;
- }
- }
- }
- return null;
- }
- // If the list is large check duplicates using a hash table.
- else {
- return checkManyDuplicatesNS();
- }
- }
-
- private QName checkManyDuplicatesNS() {
- // We don't want this table view to be read if someone calls
- // addAttribute so we invalidate it up front.
- fIsTableViewConsistent = false;
-
- prepareTableView();
-
- Attribute attr;
- int bucket;
-
- final int length = fLength;
- final Attribute[] attributes = fAttributes;
- final Attribute[] attributeTableView = fAttributeTableView;
- final int[] attributeTableViewChainState = fAttributeTableViewChainState;
- int largeCount = fLargeCount;
-
- for (int i = 0; i < length; ++i) {
- attr = attributes[i];
- bucket = getTableViewBucket(attr.name.localpart, attr.name.uri);
-
- // The chain is stale.
- // This must be a unique attribute.
- if (attributeTableViewChainState[bucket] != largeCount) {
- attributeTableViewChainState[bucket] = largeCount;
- attr.next = null;
- attributeTableView[bucket] = attr;
- }
- // This chain is active.
- // We need to check if any of the attributes has the same name.
- else {
- // Search the table.
- int collisionCount = 0;
- Attribute found = attributeTableView[bucket];
- while (found != null) {
- if (found.name.localpart == attr.name.localpart &&
- found.name.uri == attr.name.uri) {
- return attr.name;
- }
- found = found.next;
- ++collisionCount;
- }
- // Select a new hash function and rehash the table view
- // if the collision threshold is exceeded.
- if (collisionCount >= MAX_HASH_COLLISIONS) {
- // The current attribute will be processed in the rehash.
- rebalanceTableViewNS(i+1);
- largeCount = fLargeCount;
- }
- else {
- // Update table view
- attr.next = attributeTableView[bucket];
- attributeTableView[bucket] = attr;
- }
- }
- }
- return null;
- }
-
- /**
- * Look up the index of an attribute by Namespace name.
- * <p>
- * <strong>Note:</strong>
- * This method uses reference comparison, and thus should
- * only be used internally. We cannot use this method in any
- * code exposed to users as they may not pass in unique strings.
- *
- * @param uri The Namespace URI, or null if
- * the name has no Namespace URI.
- * @param localName The attribute's local name.
- * @return The index of the attribute, or -1 if it does not
- * appear in the list.
- */
- public int getIndexFast(String uri, String localPart) {
- for (int i = 0; i < fLength; ++i) {
- Attribute attribute = fAttributes[i];
- if (attribute.name.localpart == localPart &&
- attribute.name.uri == uri) {
- return i;
- }
- }
- return -1;
- } // getIndexFast(String,String):int
-
- /**
- * Returns the value passed in or NMTOKEN if it's an enumerated type.
- *
- * @param type attribute type
- * @return the value passed in or NMTOKEN if it's an enumerated type.
- */
- private String getReportableType(String type) {
-
- if (type.charAt(0) == '(') {
- return "NMTOKEN";
- }
- return type;
- }
-
- /**
- * Returns the position in the table view
- * where the given attribute name would be hashed.
- *
- * @param qname the attribute name
- * @return the position in the table view where the given attribute
- * would be hashed
- */
- protected int getTableViewBucket(String qname) {
- return (hash(qname) & 0x7FFFFFFF) % fTableViewBuckets;
- }
-
- /**
- * Returns the position in the table view
- * where the given attribute name would be hashed.
- *
- * @param localpart the local part of the attribute
- * @param uri the namespace name of the attribute
- * @return the position in the table view where the given attribute
- * would be hashed
- */
- protected int getTableViewBucket(String localpart, String uri) {
- if (uri == null) {
- return (hash(localpart) & 0x7FFFFFFF) % fTableViewBuckets;
- }
- else {
- return (hash(localpart, uri) & 0x7FFFFFFF) % fTableViewBuckets;
- }
- }
-
- private int hash(String localpart) {
- if (fHashMultipliers == null) {
- return localpart.hashCode();
- }
- return hash0(localpart);
- } // hash(String):int
-
- private int hash(String localpart, String uri) {
- if (fHashMultipliers == null) {
- return localpart.hashCode() + uri.hashCode() * 31;
- }
- return hash0(localpart) + hash0(uri) * fHashMultipliers[MULTIPLIERS_SIZE];
- } // hash(String,String):int
-
- private int hash0(String symbol) {
- int code = 0;
- final int length = symbol.length();
- final int[] multipliers = fHashMultipliers;
- for (int i = 0; i < length; ++i) {
- code = code * multipliers[i & MULTIPLIERS_MASK] + symbol.charAt(i);
- }
- return code;
- } // hash0(String):int
-
- /**
- * Purges all elements from the table view.
- */
- protected void cleanTableView() {
- if (++fLargeCount < 0) {
- // Overflow. We actually need to visit the chain state array.
- if (fAttributeTableViewChainState != null) {
- for (int i = fTableViewBuckets - 1; i >= 0; --i) {
- fAttributeTableViewChainState[i] = 0;
- }
- }
- fLargeCount = 1;
- }
- }
-
- /**
- * Increases the capacity of the table view.
- */
- private void growTableView() {
- final int length = fLength;
- int tableViewBuckets = fTableViewBuckets;
- do {
- tableViewBuckets = (tableViewBuckets << 1) + 1;
- if (tableViewBuckets < 0) {
- tableViewBuckets = Integer.MAX_VALUE;
- break;
- }
- }
- while (length > tableViewBuckets);
- fTableViewBuckets = tableViewBuckets;
- fAttributeTableView = null;
- fLargeCount = 1;
- }
-
- /**
- * Prepares the table view of the attributes list for use.
- */
- protected void prepareTableView() {
- if (fLength > fTableViewBuckets) {
- growTableView();
- }
- if (fAttributeTableView == null) {
- fAttributeTableView = new Attribute[fTableViewBuckets];
- fAttributeTableViewChainState = new int[fTableViewBuckets];
- }
- else {
- cleanTableView();
- }
- }
-
- /**
- * Prepares the table view of the attributes list for use,
- * and populates it with the attributes which have been
- * previously read.
- */
- protected void prepareAndPopulateTableView() {
- prepareAndPopulateTableView(fLength);
- }
-
- private void prepareAndPopulateTableView(final int count) {
- prepareTableView();
- // Need to populate the hash table with the attributes we've processed so far.
- Attribute attr;
- int bucket;
- for (int i = 0; i < count; ++i) {
- attr = fAttributes[i];
- bucket = getTableViewBucket(attr.name.rawname);
- if (fAttributeTableViewChainState[bucket] != fLargeCount) {
- fAttributeTableViewChainState[bucket] = fLargeCount;
- attr.next = null;
- fAttributeTableView[bucket] = attr;
- }
- else {
- // Update table view
- attr.next = fAttributeTableView[bucket];
- fAttributeTableView[bucket] = attr;
- }
- }
- }
-
-
- /**
- * Returns the prefix of the attribute at the specified index.
- *
- * @param index The index of the attribute.
- */
- public String getPrefix(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- String prefix = fAttributes[index].name.prefix;
- // REVISIT: The empty string is not entered in the symbol table!
- return prefix != null ? prefix : "";
- } // getPrefix(int):String
-
- /**
- * Look up an attribute's Namespace URI by index.
- *
- * @param index The attribute index (zero-based).
- * @return The Namespace URI
- * @see #getLength
- */
- public String getURI(int index) {
- if (index < 0 || index >= fLength) {
- return null;
- }
- String uri = fAttributes[index].name.uri;
- return uri;
- } // getURI(int):String
-
- /**
- * Look up an attribute's value by Namespace name and
- * Local name. If Namespace is null, ignore namespace
- * comparison. If Namespace is "", treat the name as
- * having no Namespace URI.
- *
- * <p>See {@link #getValue(int) getValue(int)} for a description
- * of the possible values.</p>
- *
- * @param uri The Namespace URI, or null namespaces are ignored.
- * @param localName The local name of the attribute.
- * @return The attribute value as a string, or null if the
- * attribute is not in the list.
- */
- public String getValue(String uri, String localName) {
- int index = getIndex(uri, localName);
- return index != -1 ? getValue(index) : null;
- } // getValue(String,String):String
-
- /**
- * Look up an augmentations by Namespace name.
- *
- * @param uri The Namespace URI, or null if the
- * @param localName The local name of the attribute.
- * @return Augmentations
- */
- public Augmentations getAugmentations (String uri, String localName) {
- int index = getIndex(uri, localName);
- return index != -1 ? fAttributes[index].augs : null;
- }
-
- /**
- * Look up an augmentation by XML 1.0 qualified name.
- * <p>
- *
- * @param qName The XML 1.0 qualified name.
- *
- * @return Augmentations
- *
- */
- public Augmentations getAugmentations(String qName){
- int index = getIndex(qName);
- return index != -1 ? fAttributes[index].augs : null;
- }
-
-
-
- /**
- * Look up an augmentations by attributes index.
- *
- * @param attributeIndex The attribute index.
- * @return Augmentations
- */
- public Augmentations getAugmentations (int attributeIndex){
- if (attributeIndex < 0 || attributeIndex >= fLength) {
- return null;
- }
- return fAttributes[attributeIndex].augs;
- }
-
- /**
- * Sets the augmentations of the attribute at the specified index.
- *
- * @param attrIndex The attribute index.
- * @param augs The augmentations.
- */
- public void setAugmentations(int attrIndex, Augmentations augs) {
- fAttributes[attrIndex].augs = augs;
- }
-
- /**
- * Sets the uri of the attribute at the specified index.
- *
- * @param attrIndex The attribute index.
- * @param uri Namespace uri
- */
- public void setURI(int attrIndex, String uri) {
- fAttributes[attrIndex].name.uri = uri;
- } // getURI(int,QName)
-
- // Implementation methods
- public void setSchemaId(int attrIndex, boolean schemaId) {
- fAttributes[attrIndex].schemaId = schemaId;
- }
-
- public boolean getSchemaId(int index) {
- if (index < 0 || index >= fLength) {
- return false;
- }
- return fAttributes[index].schemaId;
- }
-
- public boolean getSchemaId(String qname) {
- int index = getIndex(qname);
- return index != -1 ? fAttributes[index].schemaId : false;
- } // getType(String):String
-
- public boolean getSchemaId(String uri, String localName) {
- if (!fNamespaces) {
- return false;
- }
- int index = getIndex(uri, localName);
- return index != -1 ? fAttributes[index].schemaId : false;
- } // getType(String,String):String
-
- //XMLBufferListener methods
- /**
- * This method will be invoked by XMLEntityReader before ScannedEntities buffer
- * is reloaded.
- */
- public void refresh() {
- if(fLength > 0){
- for(int i = 0 ; i < fLength ; i++){
- getValue(i);
- }
- }
- }
- public void refresh(int pos) {
- }
-
- private void prepareAndPopulateTableViewNS(final int count) {
- prepareTableView();
- // Need to populate the hash table with the attributes we've processed so far.
- Attribute attr;
- int bucket;
- for (int i = 0; i < count; ++i) {
- attr = fAttributes[i];
- bucket = getTableViewBucket(attr.name.localpart, attr.name.uri);
- if (fAttributeTableViewChainState[bucket] != fLargeCount) {
- fAttributeTableViewChainState[bucket] = fLargeCount;
- attr.next = null;
- fAttributeTableView[bucket] = attr;
- }
- else {
- // Update table view
- attr.next = fAttributeTableView[bucket];
- fAttributeTableView[bucket] = attr;
- }
- }
- }
-
- /**
- * Randomly selects a new hash function and reorganizes the table view
- * in order to more evenly distribute its entries. This method is called
- * automatically when the number of attributes in one bucket exceeds
- * MAX_HASH_COLLISIONS.
- */
- private void rebalanceTableView(final int count) {
- if (fHashMultipliers == null) {
- fHashMultipliers = new int[MULTIPLIERS_SIZE + 1];
- }
- PrimeNumberSequenceGenerator.generateSequence(fHashMultipliers);
- prepareAndPopulateTableView(count);
- }
-
- /**
- * Randomly selects a new hash function and reorganizes the table view
- * in order to more evenly distribute its entries. This method is called
- * automatically when the number of attributes in one bucket exceeds
- * MAX_HASH_COLLISIONS.
- */
- private void rebalanceTableViewNS(final int count) {
- if (fHashMultipliers == null) {
- fHashMultipliers = new int[MULTIPLIERS_SIZE + 1];
- }
- PrimeNumberSequenceGenerator.generateSequence(fHashMultipliers);
- prepareAndPopulateTableViewNS(count);
- }
-
- //
- // Classes
- //
-
- /**
- * Attribute information.
- *
- * @author Andy Clark, IBM
- */
- static class Attribute {
-
- //
- // Data
- //
-
- // basic info
-
- /** Name. */
- public QName name = new QName();
-
- /** Type. */
- public String type;
-
- /** Value. */
- public String value;
-
- /** This will point to the ScannedEntities buffer.*/
- public XMLString xmlValue;
-
- /** Non-normalized value. */
- public String nonNormalizedValue;
-
- /** Specified. */
- public boolean specified;
-
- /** Schema ID type. */
- public boolean schemaId;
-
- /**
- * Augmentations information for this attribute.
- * XMLAttributes has no knowledge if any augmentations
- * were attached to Augmentations.
- */
- public Augmentations augs = new AugmentationsImpl();
-
- // Additional data for attribute table view
-
- /** Pointer to the next attribute in the chain. **/
- public Attribute next;
-
- } // class Attribute
-
-} // class XMLAttributesImpl