001/* 002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 003 * 004 * This software is open source. 005 * See the bottom of this file for the licence. 006 * 007 * $Id: QName.java,v 1.9 2001/08/15 12:02:00 jstrachan Exp $ 008 */ 009 010package org.dom4j; 011 012import java.io.IOException; 013import java.io.Serializable; 014import java.io.ObjectInputStream; 015import java.io.ObjectOutputStream; 016 017import org.dom4j.tree.QNameCache; 018 019/** <p><code>QName</code> represents a qualified name value of an XML element 020 * or attribute. It consists of a local name and a {@link Namespace} 021 * instance. This object is immutable.</p> 022 * 023 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 024 * @version $Revision: 1.9 $ 025 */ 026public class QName implements Serializable { 027 028 protected transient static QNameCache cache = new QNameCache(); 029 030 031 /** The local name of the element or attribute */ 032 private String name; 033 034 /** The qualified name of the element or attribute */ 035 private String qualifiedName; 036 037 /** The Namespace of this element or attribute */ 038 private transient Namespace namespace; 039 040 /** A cached version of the hashcode for efficiency */ 041 private int hashCode; 042 043 /** The document factory used for this QName if specified or null */ 044 private DocumentFactory documentFactory; 045 046 047 public static synchronized QName get(String name) { 048 return cache.get(name); 049 } 050 051 public static synchronized QName get(String name, Namespace namespace) { 052 return cache.get(name, namespace); 053 } 054 055 public static synchronized QName get(String name, String prefix, String uri) { 056 return cache.get(name, Namespace.get( prefix, uri )); 057 } 058 059 public static synchronized QName get(String qualifiedName, String uri) { 060 return cache.get(qualifiedName, uri); 061 } 062 063 public static synchronized QName get(String localName, Namespace namespace, String qualifiedName) { 064 return cache.get(localName, namespace, qualifiedName); 065 } 066 067 public QName(String name) { 068 this( name, Namespace.NO_NAMESPACE ); 069 } 070 071 public QName(String name, Namespace namespace) { 072 this.name = (name == null) ? "" : name; 073 this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace; 074 } 075 076 public QName(String name, Namespace namespace, String qualifiedName) { 077 this.name = (name == null) ? "" : name; 078 this.qualifiedName = qualifiedName; 079 this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace; 080 } 081 082 083 /** @return the local name 084 */ 085 public String getName() { 086 return name; 087 } 088 089 /** @return the qualified name in the format <code>prefix:localName</code> 090 */ 091 public String getQualifiedName() { 092 if ( qualifiedName == null ) { 093 String prefix = getNamespacePrefix(); 094 if ( prefix != null && prefix.length() > 0 ) { 095 qualifiedName = prefix + ":" + name; 096 } 097 else { 098 qualifiedName = name; 099 } 100 } 101 return qualifiedName; 102 } 103 104 /** @return the namespace of this QName 105 */ 106 public Namespace getNamespace() { 107 return namespace; 108 } 109 110 /** @return the namespace URI of this QName 111 */ 112 public String getNamespacePrefix() { 113 if ( namespace == null ) { 114 return ""; 115 } 116 return namespace.getPrefix(); 117 } 118 119 /** @return the namespace URI of this QName 120 */ 121 public String getNamespaceURI() { 122 if ( namespace == null ) { 123 return ""; 124 } 125 return namespace.getURI(); 126 } 127 128 129 /** @return the hash code based on the qualified name and the URI of the 130 * namespace. 131 */ 132 public int hashCode() { 133 if ( hashCode == 0 ) { 134 hashCode = getName().hashCode() 135 ^ getNamespaceURI().hashCode(); 136 if ( hashCode == 0 ) { 137 hashCode = 0xbabe; 138 } 139 } 140 return hashCode; 141 } 142 143 public boolean equals(Object object) { 144 if ( this == object ) { 145 return true; 146 } 147 else if ( object instanceof QName ) { 148 QName that = (QName) object; 149 // we cache hash codes so this should be quick 150 if ( hashCode() == that.hashCode() ) { 151 return getName().equals( that.getName() ) 152 && getNamespaceURI().equals( that.getNamespaceURI()); 153 } 154 } 155 return false; 156 } 157 158 public String toString() { 159 return super.toString() + " [name: " + getName() 160 + " namespace: \"" + getNamespace() + "\"]"; 161 } 162 163 /** @return the factory that should be used for Elements of this QName */ 164 public DocumentFactory getDocumentFactory() { 165 return documentFactory; 166 } 167 168 public void setDocumentFactory(DocumentFactory documentFactory) { 169 this.documentFactory = documentFactory; 170 } 171 172 private void writeObject(ObjectOutputStream out) throws IOException { 173 174 // We use writeObject() and not writeUTF() to minimize space 175 // This allows for writing pointers to already written strings 176 out.writeObject(namespace.getPrefix()); 177 out.writeObject(namespace.getURI()); 178 179 out.defaultWriteObject(); 180 } 181 182 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 183 184 String prefix = (String) in.readObject(); 185 String uri = (String) in.readObject(); 186 187 in.defaultReadObject(); 188 189 namespace = Namespace.get( prefix, uri ); 190 } 191 192 193} 194 195 196 197 198/* 199 * Redistribution and use of this software and associated documentation 200 * ("Software"), with or without modification, are permitted provided 201 * that the following conditions are met: 202 * 203 * 1. Redistributions of source code must retain copyright 204 * statements and notices. Redistributions must also contain a 205 * copy of this document. 206 * 207 * 2. Redistributions in binary form must reproduce the 208 * above copyright notice, this list of conditions and the 209 * following disclaimer in the documentation and/or other 210 * materials provided with the distribution. 211 * 212 * 3. The name "DOM4J" must not be used to endorse or promote 213 * products derived from this Software without prior written 214 * permission of MetaStuff, Ltd. For written permission, 215 * please contact dom4j-info@metastuff.com. 216 * 217 * 4. Products derived from this Software may not be called "DOM4J" 218 * nor may "DOM4J" appear in their names without prior written 219 * permission of MetaStuff, Ltd. DOM4J is a registered 220 * trademark of MetaStuff, Ltd. 221 * 222 * 5. Due credit should be given to the DOM4J Project 223 * (http://dom4j.org/). 224 * 225 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS 226 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 227 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 228 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 229 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 230 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 231 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 232 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 233 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 234 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 235 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 236 * OF THE POSSIBILITY OF SUCH DAMAGE. 237 * 238 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 239 * 240 * $Id: QName.java,v 1.9 2001/08/15 12:02:00 jstrachan Exp $ 241 */