1
2
3
4
5
6
7
8
9
10 package org.dom4j;
11
12
13 import java.io.IOException;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
16 import java.io.Serializable;
17
18 import org.dom4j.tree.QNameCache;
19
20 /*** <p><code>QName</code> represents a qualified name value of an XML element
21 * or attribute. It consists of a local name and a {@link Namespace}
22 * instance. This object is immutable.</p>
23 *
24 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
25 * @version $Revision: 1.15 $
26 */
27 public class QName implements Serializable {
28
29
30 protected transient static ThreadLocal cachePerThread = new ThreadLocal();
31
32 /*** The local name of the element or attribute */
33 private String name;
34
35 /*** The qualified name of the element or attribute */
36 private String qualifiedName;
37
38 /*** The Namespace of this element or attribute */
39 private transient Namespace namespace;
40
41 /*** A cached version of the hashcode for efficiency */
42 private int hashCode;
43
44 /*** The document factory used for this QName if specified or null */
45 private DocumentFactory documentFactory;
46
47
48 public static QName get(String name) {
49 return getCache().get(name);
50 }
51
52 public static QName get(String name, Namespace namespace) {
53 return getCache().get(name, namespace);
54 }
55
56 public static QName get(String name, String prefix, String uri) {
57 if ((prefix == null || prefix.length() == 0) && (uri == null)) {
58 return QName.get(name);
59 } else if (prefix == null || prefix.length() == 0) {
60 return getCache().get(name, Namespace.get(uri));
61 } else if (uri == null) {
62 return QName.get(name);
63 } else {
64 return getCache().get(name, Namespace.get(prefix, uri));
65 }
66 }
67
68 public static QName get(String qualifiedName, String uri) {
69 if (uri == null) {
70 return getCache().get(qualifiedName);
71 } else {
72 return getCache().get(qualifiedName, uri);
73 }
74 }
75
76 public static QName get(String localName, Namespace namespace, String qualifiedName) {
77 return getCache().get(localName, namespace, qualifiedName);
78 }
79
80 public QName(String name) {
81 this( name, Namespace.NO_NAMESPACE );
82 }
83
84 public QName(String name, Namespace namespace) {
85 this.name = (name == null) ? "" : name;
86 this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace;
87 }
88
89 public QName(String name, Namespace namespace, String qualifiedName) {
90 this.name = (name == null) ? "" : name;
91 this.qualifiedName = qualifiedName;
92 this.namespace = (namespace == null) ? Namespace.NO_NAMESPACE : namespace;
93 }
94
95
96 /*** @return the local name
97 */
98 public String getName() {
99 return name;
100 }
101
102 /*** @return the qualified name in the format <code>prefix:localName</code>
103 */
104 public String getQualifiedName() {
105 if ( qualifiedName == null ) {
106 String prefix = getNamespacePrefix();
107 if ( prefix != null && prefix.length() > 0 ) {
108 qualifiedName = prefix + ":" + name;
109 }
110 else {
111 qualifiedName = name;
112 }
113 }
114 return qualifiedName;
115 }
116
117 /*** @return the namespace of this QName
118 */
119 public Namespace getNamespace() {
120 return namespace;
121 }
122
123 /*** @return the namespace URI of this QName
124 */
125 public String getNamespacePrefix() {
126 if ( namespace == null ) {
127 return "";
128 }
129 return namespace.getPrefix();
130 }
131
132 /*** @return the namespace URI of this QName
133 */
134 public String getNamespaceURI() {
135 if ( namespace == null ) {
136 return "";
137 }
138 return namespace.getURI();
139 }
140
141
142 /*** @return the hash code based on the qualified name and the URI of the
143 * namespace.
144 */
145 public int hashCode() {
146 if ( hashCode == 0 ) {
147 hashCode = getName().hashCode()
148 ^ getNamespaceURI().hashCode();
149 if ( hashCode == 0 ) {
150 hashCode = 0xbabe;
151 }
152 }
153 return hashCode;
154 }
155
156 public boolean equals(Object object) {
157 if ( this == object ) {
158 return true;
159 }
160 else if ( object instanceof QName ) {
161 QName that = (QName) object;
162
163 if ( hashCode() == that.hashCode() ) {
164 return getName().equals( that.getName() )
165 && getNamespaceURI().equals( that.getNamespaceURI());
166 }
167 }
168 return false;
169 }
170
171 public String toString() {
172 return super.toString() + " [name: " + getName()
173 + " namespace: \"" + getNamespace() + "\"]";
174 }
175
176 /*** @return the factory that should be used for Elements of this QName */
177 public DocumentFactory getDocumentFactory() {
178 return documentFactory;
179 }
180
181 public void setDocumentFactory(DocumentFactory documentFactory) {
182 this.documentFactory = documentFactory;
183 }
184
185 private void writeObject(ObjectOutputStream out) throws IOException {
186
187
188
189 out.writeObject(namespace.getPrefix());
190 out.writeObject(namespace.getURI());
191
192 out.defaultWriteObject();
193 }
194
195 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
196
197 String prefix = (String) in.readObject();
198 String uri = (String) in.readObject();
199
200 in.defaultReadObject();
201
202 namespace = Namespace.get( prefix, uri );
203 }
204
205
206 private static QNameCache getCache() {
207 QNameCache cache = (QNameCache) cachePerThread.get();
208 if (cache==null) {
209 cache = new QNameCache();
210 cachePerThread.set(cache);
211 }
212 return cache;
213 }
214
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263