javolution.xml.QName Maven / Gradle / Ivy
The newest version!
/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2007 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.xml;
import java.io.ObjectStreamException;
import java.lang.CharSequence;
import javolution.lang.Immutable;
import javolution.text.CharArray;
import javolution.text.TextBuilder;
import javolution.util.FastMap;
import javolution.util.function.Equalities;
/**
* This class represents unique identifiers for XML elements (tags) or
* attributes (names).
*
* It should be noted that QName.valueOf(null, "name")
and
* QName.valueOf("", "name")
are distinct; the first one has no
* namespace associated with; whereas the second is associated
* to the root namespace.
*
* {@link QName} have a textual representation ({@link CharSequence}) which
* is either the local name (if no namespace URI) or
* {namespaceURI}localName
(otherwise).
*
* @author Jean-Marie Dautelle
* @version 5.3, January 14, 2007
* @see Wikipedia: QName
*/
public final class QName implements XMLSerializable, Immutable, CharSequence {
/**
* Holds the local name.
*/
private transient final CharArray _localName;
/**
* Holds the namespace URI reference or null
if none.
*/
private transient final CharArray _namespaceURI;
/**
* Holds the string representation.
*/
private final String _toString;
/**
* Holds the full name (String) to QName mapping.
*/
private static final FastMap FULL_NAME_TO_QNAME = new FastMap(
Equalities.LEXICAL);
/**
* Creates a qualified name having the specified local name and namespace
* reference.
*
* @param namespaceURI the URI reference or null
if none.
* @param localName the local name.
* @param toString the string representation.
*/
private QName(String namespaceURI, String localName, String toString) {
_namespaceURI = (namespaceURI == null) ? null : new CharArray(
namespaceURI);
_localName = new CharArray(localName);
_toString = toString;
}
/**
* Returns the qualified name corresponding to the specified character
* sequence representation (may include the "{namespaceURI}" prefix).
*
* @param name the qualified name lexical representation.
* @see #toString()
*/
public static QName valueOf(CharSequence name) {
QName qName = (QName) FULL_NAME_TO_QNAME.get(name);
return (qName != null) ? qName : QName.createNoNamespace(name
.toString());
}
private static QName createNoNamespace(String name) {
String localName = name;
String namespaceURI = null;
if (name.length() > 0 && name.charAt(0) == '{') { // Namespace URI.
int index = name.lastIndexOf('}');
localName = name.substring(index + 1);
namespaceURI = name.substring(1, index);
}
QName qName = new QName(namespaceURI, localName, name);
synchronized (FULL_NAME_TO_QNAME) {
QName tmp = (QName) FULL_NAME_TO_QNAME.putIfAbsent(name, qName);
return tmp == null ? qName : tmp;
}
}
/**
* Equivalent to {@link #valueOf(CharSequence)} (for J2ME compatibility).
*
* @param name the qualified name lexical representation.
* @see #toString()
*/
public static QName valueOf(String name) {
QName qName = (QName) FULL_NAME_TO_QNAME.get(name);
return (qName != null) ? qName : QName.createNoNamespace(name);
}
/**
* Returns the qualified name corresponding to the specified namespace URI
* and local name.
*
* @param namespaceURI the URI reference or null
if none.
* @param localName the local name.
* @see #toString()
*/
public static QName valueOf(CharSequence namespaceURI,
CharSequence localName) {
if (namespaceURI == null)
return QName.valueOf(localName);
TextBuilder tmp = new TextBuilder();
tmp.append('{');
tmp.append(namespaceURI);
tmp.append('}');
tmp.append(localName);
return QName.valueOf(tmp);
}
/**
* Returns the local part of this qualified name or the full qualified
* name if there is no namespace.
*
* @return the local name.
*/
public CharSequence getLocalName() {
return _localName;
}
/**
* Returns the namespace URI of this qualified name or null
* if none (the local name is then the full qualified name).
*
* @return the URI reference or null
*/
public CharSequence getNamespaceURI() {
return _namespaceURI;
}
/**
* Instances of this class are unique; object's equality can be
* replaced object identity (==
).
*
* @return this == obj
*/
public boolean equals(Object obj) {
return this == obj;
}
/**
* Returns the String
representation of this qualified name.
*
* @return the textual representation.
*/
public String toString() {
return _toString;
}
/**
* Returns the hash code for this qualified name.
*
* Note: Returns the same hashCode as java.lang.String
* (consistent with {@link #equals})
* @return the hash code value.
*/
public int hashCode() {
return _toString.hashCode();
}
/**
* Returns the character at the specified index.
*
* @param index the index of the character starting at 0
.
* @return the character at the specified index of this character sequence.
* @throws IndexOutOfBoundsException if ((index < 0) ||
* (index >= length))
*/
public char charAt(int index) {
return _toString.charAt(index);
}
/**
* Returns the length of this character sequence.
*
* @return the number of characters (16-bits Unicode) composing this
* character sequence.
*/
public int length() {
return _toString.length();
}
/**
* Returns a new character sequence that is a subsequence of this sequence.
*
* @param start the index of the first character inclusive.
* @param end the index of the last character exclusive.
* @return the character sequence starting at the specified
* start
position and ending just before the specified
* end
position.
* @throws IndexOutOfBoundsException if {@code (start < 0) || (end < 0) ||
* (start > end) || (end > this.length())}
*/
public CharSequence subSequence(int start, int end) {
return _toString.substring(start, end);
}
//Maintains unicity.
private Object readResolve() throws ObjectStreamException {
return QName.valueOf(_toString);
}
private static final long serialVersionUID = -6126031630693748647L;
@Override
public QName value() {
return this;
}
}