/* Woodstox XML processor
 *
 * Copyright (c) 2004 Tatu Saloranta, tatu.saloranta@iki.fi
 *
 * Licensed under the License specified in file LICENSE, included with
 * the source code.
 * You may not use this file except in compliance with the License.
 *
 * 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.ctc.wstx.util;

import javax.xml.namespace.QName;

Simple key Object to be used for storing/accessing of potentially namespace scoped element and attribute names.

One important note about usage is that two of the name components (prefix and local name) HAVE to have been interned some way, as all comparisons are done using identity comparison; whereas URI is NOT necessarily interned.

Note that the main reason this class is mutable -- unlike most key classes -- is that this allows reusing key objects for access, as long as the code using it knows ramifications of trying to modify a key that's used in a data structure.

Note, too, that the hash code is cached as this class is mostly used as a Map key, and hash code is used a lot.

/** * Simple key Object to be used for storing/accessing of potentially namespace * scoped element and attribute names. *<p> * One important note about usage is that two of the name components (prefix * and local name) HAVE to have been interned some way, as all comparisons * are done using identity comparison; whereas URI is NOT necessarily * interned. *<p> * Note that the main reason this class is mutable -- unlike most key classes * -- is that this allows reusing key objects for access, as long as the code * using it knows ramifications of trying to modify a key that's used * in a data structure. *<p> * Note, too, that the hash code is cached as this class is mostly used as * a Map key, and hash code is used a lot. */
public final class PrefixedName implements Comparable<PrefixedName> // to allow alphabetic ordering { private String mPrefix, mLocalName; volatile int mHash = 0; /* /////////////////////////////////////////////////// // Life-cycle /////////////////////////////////////////////////// */ public PrefixedName(String prefix, String localName) { mLocalName = localName; mPrefix = (prefix != null && prefix.length() == 0) ? null : prefix; } public PrefixedName reset(String prefix, String localName) { mLocalName = localName; mPrefix = (prefix != null && prefix.length() == 0) ? null : prefix; mHash = 0; return this; } public static PrefixedName valueOf(QName n) { return new PrefixedName(n.getPrefix(), n.getLocalPart()); } /* /////////////////////////////////////////////////// // Accessors: /////////////////////////////////////////////////// */ public String getPrefix() { return mPrefix; } public String getLocalName() { return mLocalName; }
Returns:True, if this attribute name would result in a namespace binding (ie. it's "xmlns" or starts with "xmlns:").
/** * @return True, if this attribute name would result in a namespace * binding (ie. it's "xmlns" or starts with "xmlns:"). */
public boolean isaNsDeclaration() { if (mPrefix == null) { return mLocalName == "xmlns"; } return mPrefix == "xmlns"; }
Method used to check for xml reserved attribute names, like "xml:space" and "xml:id".

Note: it is assumed that the passed-in localName is also interned.

/** * Method used to check for xml reserved attribute names, like * "xml:space" and "xml:id". *<p> * Note: it is assumed that the passed-in localName is also * interned. */
public boolean isXmlReservedAttr(boolean nsAware, String localName) { if (nsAware) { if ("xml" == mPrefix) { return mLocalName == localName; } } else { if (mLocalName.length() == (4 + localName.length())) { return (mLocalName.startsWith("xml:") && mLocalName.endsWith(localName)); } } return false; } /* /////////////////////////////////////////////////// // Overridden standard methods: /////////////////////////////////////////////////// */ @Override public String toString() { if (mPrefix == null || mPrefix.length() == 0) { return mLocalName; } StringBuilder sb = new StringBuilder(mPrefix.length() + 1 + mLocalName.length()); sb.append(mPrefix); sb.append(':'); sb.append(mLocalName); return sb.toString(); } @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof PrefixedName)) { // also filters out nulls return false; } PrefixedName other = (PrefixedName) o; if (mLocalName != other.mLocalName) { // assumes equality return false; } return (mPrefix == other.mPrefix); } @Override public int hashCode() { int hash = mHash; if (hash == 0) { hash = mLocalName.hashCode(); if (mPrefix != null) { hash ^= mPrefix.hashCode(); } mHash = hash; } return hash; } @Override public int compareTo(PrefixedName other) { // First, by prefix, then by local name: String op = other.mPrefix; // Missing prefix is ordered before existing prefix if (op == null || op.length() == 0) { if (mPrefix != null && mPrefix.length() > 0) { return 1; } } else if (mPrefix == null || mPrefix.length() == 0) { return -1; } else { int result = mPrefix.compareTo(op); if (result != 0) { return result; } } return mLocalName.compareTo(other.mLocalName); } }