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