| /* | ||
| * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved. | ||
| * | ||
| * This software is open source. | ||
| * See the bottom of this file for the licence. | ||
| * | ||
| * $Id: QName.java,v 1.15 2004/06/25 08:03:33 maartenc Exp $ | ||
| */ | ||
| package org.dom4j; | ||
| import java.io.IOException; | ||
| import java.io.ObjectInputStream; | ||
| import java.io.ObjectOutputStream; | ||
| import java.io.Serializable; | ||
| import org.dom4j.tree.QNameCache; | ||
| /** <p><code>QName</code> represents a qualified name value of an XML element | ||
| * or attribute. It consists of a local name and a {@link Namespace} | ||
| * instance. This object is immutable.</p> | ||
| * | ||
| * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> | ||
| * @version $Revision: 1.15 $ | ||
| */ | ||
| public class QName implements Serializable { | ||
| //protected transient static QNameCache cache = new QNameCache(); | ||
| protected transient static ThreadLocal cachePerThread = new ThreadLocal(); | ||
| /** The local name of the element or attribute */ | ||
| private String name; | ||
| /** The qualified name of the element or attribute */ | ||
| private String qualifiedName; | ||
| /** The Namespace of this element or attribute */ | ||
| private transient Namespace namespace; | ||
| /** A cached version of the hashcode for efficiency */ | ||
| private int hashCode; | ||
| /** The document factory used for this QName if specified or null */ | ||
| private DocumentFactory documentFactory; | ||
| public static QName get(String name) { | ||
| 21838x | return getCache().get(name); | |
| } | ||
| public static QName get(String name, Namespace namespace) { | ||
| 1024x | return getCache().get(name, namespace); | |
| } | ||
| public static QName get(String name, String prefix, String uri) { | ||
| 4/6 21884x | if ((prefix == null || prefix.length() == 0) && (uri == null)) { | |
| 21836x | return QName.get(name); | |
| 2/4 48x | } else if (prefix == null || prefix.length() == 0) { | |
| 0x | return getCache().get(name, Namespace.get(uri)); | |
| 1/2 48x | } else if (uri == null) { | |
| 0x | return QName.get(name); | |
| } else { | ||
| 48x | return getCache().get(name, Namespace.get(prefix, uri)); | |
| } | ||
| } | ||
| public static QName get(String qualifiedName, String uri) { | ||
| 0/2 0x | if (uri == null) { | |
| 0x | return getCache().get(qualifiedName); | |
| } else { | ||
| 0x | return getCache().get(qualifiedName, uri); | |
| } | ||
| } | ||
| public static QName get(String localName, Namespace namespace, String qualifiedName) { | ||
| 0x | return getCache().get(localName, namespace, qualifiedName); | |
| } | ||
| public QName(String name) { | ||
| 284x | this( name, Namespace.NO_NAMESPACE ); | |
| 284x | } | |
| 902x | public QName(String name, Namespace namespace) { | |
| 1/2 902x | this.name = (name == null) ? "" : name; | |
| 1/2 902x | this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace; | |
| 902x | } | |
| 0x | public QName(String name, Namespace namespace, String qualifiedName) { | |
| 0/2 0x | this.name = (name == null) ? "" : name; | |
| 0x | this.qualifiedName = qualifiedName; | |
| 0/2 0x | this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace; | |
| 0x | } | |
| /** @return the local name | ||
| */ | ||
| public String getName() { | ||
| 45222x | return name; | |
| } | ||
| /** @return the qualified name in the format <code>prefix:localName</code> | ||
| */ | ||
| public String getQualifiedName() { | ||
| 2/2 7640x | if ( qualifiedName == null ) { | |
| 226x | String prefix = getNamespacePrefix(); | |
| 3/4 226x | if ( prefix != null && prefix.length() > 0 ) { | |
| 34x | qualifiedName = prefix + ":" + name; | |
| } | ||
| else { | ||
| 192x | qualifiedName = name; | |
| } | ||
| } | ||
| 7640x | return qualifiedName; | |
| } | ||
| /** @return the namespace of this QName | ||
| */ | ||
| public Namespace getNamespace() { | ||
| 134644x | return namespace; | |
| } | ||
| /** @return the namespace URI of this QName | ||
| */ | ||
| public String getNamespacePrefix() { | ||
| 1/2 47486x | if ( namespace == null ) { | |
| 0x | return ""; | |
| } | ||
| 47486x | return namespace.getPrefix(); | |
| } | ||
| /** @return the namespace URI of this QName | ||
| */ | ||
| public String getNamespaceURI() { | ||
| 1/2 42522x | if ( namespace == null ) { | |
| 0x | return ""; | |
| } | ||
| 42522x | return namespace.getURI(); | |
| } | ||
| /** @return the hash code based on the qualified name and the URI of the | ||
| * namespace. | ||
| */ | ||
| public int hashCode() { | ||
| 2/2 76566x | if ( hashCode == 0 ) { | |
| 352x | hashCode = getName().hashCode() | |
| ^ getNamespaceURI().hashCode(); | ||
| 1/2 352x | if ( hashCode == 0 ) { | |
| 0x | hashCode = 0xbabe; | |
| } | ||
| } | ||
| 76566x | return hashCode; | |
| } | ||
| public boolean equals(Object object) { | ||
| 2/2 41342x | if ( this == object ) { | |
| 3114x | return true; | |
| } | ||
| 2/2 38228x | else if ( object instanceof QName ) { | |
| 38222x | QName that = (QName) object; | |
| // we cache hash codes so this should be quick | ||
| 2/2 38222x | if ( hashCode() == that.hashCode() ) { | |
| 2/4 5702x | return getName().equals( that.getName() ) | |
| && getNamespaceURI().equals( that.getNamespaceURI()); | ||
| } | ||
| } | ||
| 32526x | return false; | |
| } | ||
| public String toString() { | ||
| 0x | return super.toString() + " [name: " + getName() | |
| + " namespace: \"" + getNamespace() + "\"]"; | ||
| } | ||
| /** @return the factory that should be used for Elements of this QName */ | ||
| public DocumentFactory getDocumentFactory() { | ||
| 235498x | return documentFactory; | |
| } | ||
| public void setDocumentFactory(DocumentFactory documentFactory) { | ||
| 936x | this.documentFactory = documentFactory; | |
| 936x | } | |
| private void writeObject(ObjectOutputStream out) throws IOException { | ||
| // We use writeObject() and not writeUTF() to minimize space | ||
| // This allows for writing pointers to already written strings | ||
| 0x | out.writeObject(namespace.getPrefix()); | |
| 0x | out.writeObject(namespace.getURI()); | |
| 0x | out.defaultWriteObject(); | |
| 0x | } | |
| private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { | ||
| 0x | String prefix = (String) in.readObject(); | |
| 0x | String uri = (String) in.readObject(); | |
| 0x | in.defaultReadObject(); | |
| 0x | namespace = Namespace.get( prefix, uri ); | |
| 0x | } | |
| private static QNameCache getCache() { | ||
| 22910x | QNameCache cache = (QNameCache) cachePerThread.get(); | |
| 2/2 22910x | if (cache==null) { | |
| 12x | cache = new QNameCache(); | |
| 12x | cachePerThread.set(cache); | |
| } | ||
| 22910x | return cache; | |
| } | ||
| } | ||
| /* | ||
| * Redistribution and use of this software and associated documentation | ||
| * ("Software"), with or without modification, are permitted provided | ||
| * that the following conditions are met: | ||
| * | ||
| * 1. Redistributions of source code must retain copyright | ||
| * statements and notices. Redistributions must also contain a | ||
| * copy of this document. | ||
| * | ||
| * 2. Redistributions in binary form must reproduce the | ||
| * above copyright notice, this list of conditions and the | ||
| * following disclaimer in the documentation and/or other | ||
| * materials provided with the distribution. | ||
| * | ||
| * 3. The name "DOM4J" must not be used to endorse or promote | ||
| * products derived from this Software without prior written | ||
| * permission of MetaStuff, Ltd. For written permission, | ||
| * please contact dom4j-info@metastuff.com. | ||
| * | ||
| * 4. Products derived from this Software may not be called "DOM4J" | ||
| * nor may "DOM4J" appear in their names without prior written | ||
| * permission of MetaStuff, Ltd. DOM4J is a registered | ||
| * trademark of MetaStuff, Ltd. | ||
| * | ||
| * 5. Due credit should be given to the DOM4J Project - | ||
| * http://www.dom4j.org | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS | ||
| * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT | ||
| * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
| * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
| * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | ||
| * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| * | ||
| * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved. | ||
| * | ||
| * $Id: QName.java,v 1.15 2004/06/25 08:03:33 maartenc Exp $ | ||
| */ |