1   
2   
3   
4   
5   
6   
7   
8   package org.dom4j.tree;
9   
10  import java.util.ArrayList;
11  import java.util.Collections;
12  import java.util.HashMap;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  import java.util.WeakHashMap;
17  
18  import org.dom4j.DocumentFactory;
19  import org.dom4j.Namespace;
20  import org.dom4j.QName;
21  
22  /***
23   * <p>
24   * <code>QNameCache</code> caches instances of <code>QName</code> for reuse
25   * both across documents and within documents.
26   * </p>< < < < < < < QNameCache.java
27   * 
28   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
29   * @version $Revision: 1.16 $ =======
30   * 
31   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
32   * @version $Revision: 1.16 $ >>>>>>> 1.15
33   */
34  public class QNameCache {
35      /*** Cache of {@link QName}instances with no namespace */
36      protected Map noNamespaceCache = Collections
37              .synchronizedMap(new WeakHashMap());
38  
39      /***
40       * Cache of {@link Map}instances indexed by namespace which contain caches
41       * of {@link QName}for each name
42       */
43      protected Map namespaceCache = Collections
44              .synchronizedMap(new WeakHashMap());
45  
46      /***
47       * The document factory associated with new QNames instances in this cache
48       * or null if no instances should be associated by default
49       */
50      private DocumentFactory documentFactory;
51  
52      public QNameCache() {
53      }
54  
55      public QNameCache(DocumentFactory documentFactory) {
56          this.documentFactory = documentFactory;
57      }
58  
59      /***
60       * Returns a list of all the QName instances currently used
61       * 
62       * @return DOCUMENT ME!
63       */
64      public List getQNames() {
65          List answer = new ArrayList();
66          answer.addAll(noNamespaceCache.values());
67  
68          for (Iterator it = namespaceCache.values().iterator(); it.hasNext();) {
69              Map map = (Map) it.next();
70              answer.addAll(map.values());
71          }
72  
73          return answer;
74      }
75  
76      /***
77       * DOCUMENT ME!
78       * 
79       * @param name
80       *            DOCUMENT ME!
81       * 
82       * @return the QName for the given name and no namepsace
83       */
84      public QName get(String name) {
85          QName answer = null;
86  
87          if (name != null) {
88              answer = (QName) noNamespaceCache.get(name);
89          } else {
90              name = "";
91          }
92  
93          if (answer == null) {
94              answer = createQName(name);
95              answer.setDocumentFactory(documentFactory);
96              noNamespaceCache.put(name, answer);
97          }
98  
99          return answer;
100     }
101 
102     /***
103      * DOCUMENT ME!
104      * 
105      * @param name
106      *            DOCUMENT ME!
107      * @param namespace
108      *            DOCUMENT ME!
109      * 
110      * @return the QName for the given local name and namepsace
111      */
112     public QName get(String name, Namespace namespace) {
113         Map cache = getNamespaceCache(namespace);
114         QName answer = null;
115 
116         if (name != null) {
117             answer = (QName) cache.get(name);
118         } else {
119             name = "";
120         }
121 
122         if (answer == null) {
123             answer = createQName(name, namespace);
124             answer.setDocumentFactory(documentFactory);
125             cache.put(name, answer);
126         }
127 
128         return answer;
129     }
130 
131     /***
132      * DOCUMENT ME!
133      * 
134      * @param localName
135      *            DOCUMENT ME!
136      * @param namespace
137      *            DOCUMENT ME!
138      * @param qName
139      *            DOCUMENT ME!
140      * 
141      * @return the QName for the given local name, qualified name and namepsace
142      */
143     public QName get(String localName, Namespace namespace, String qName) {
144         Map cache = getNamespaceCache(namespace);
145         QName answer = null;
146 
147         if (localName != null) {
148             answer = (QName) cache.get(localName);
149         } else {
150             localName = "";
151         }
152 
153         if (answer == null) {
154             answer = createQName(localName, namespace, qName);
155             answer.setDocumentFactory(documentFactory);
156             cache.put(localName, answer);
157         }
158 
159         return answer;
160     }
161 
162     public QName get(String qualifiedName, String uri) {
163         int index = qualifiedName.indexOf(':');
164 
165         if (index < 0) {
166             return get(qualifiedName, Namespace.get(uri));
167         } else {
168             String name = qualifiedName.substring(index + 1);
169             String prefix = qualifiedName.substring(0, index);
170 
171             return get(name, Namespace.get(prefix, uri));
172         }
173     }
174 
175     /***
176      * DOCUMENT ME!
177      * 
178      * @param qname
179      *            DOCUMENT ME!
180      * 
181      * @return the cached QName instance if there is one or adds the given qname
182      *         to the cache if not
183      */
184     public QName intern(QName qname) {
185         return get(qname.getName(), qname.getNamespace(), qname
186                 .getQualifiedName());
187     }
188 
189     /***
190      * DOCUMENT ME!
191      * 
192      * @param namespace
193      *            DOCUMENT ME!
194      * 
195      * @return the cache for the given namespace. If one does not currently
196      *         exist it is created.
197      */
198     protected Map getNamespaceCache(Namespace namespace) {
199         if (namespace == Namespace.NO_NAMESPACE) {
200             return noNamespaceCache;
201         }
202 
203         Map answer = null;
204 
205         if (namespace != null) {
206             answer = (Map) namespaceCache.get(namespace);
207         }
208 
209         if (answer == null) {
210             answer = createMap();
211             namespaceCache.put(namespace, answer);
212         }
213 
214         return answer;
215     }
216 
217     /***
218      * A factory method
219      * 
220      * @return a newly created {@link Map}instance.
221      */
222     protected Map createMap() {
223         return Collections.synchronizedMap(new HashMap());
224     }
225 
226     /***
227      * Factory method to create a new QName object which can be overloaded to
228      * create derived QName instances
229      * 
230      * @param name
231      *            DOCUMENT ME!
232      * 
233      * @return DOCUMENT ME!
234      */
235     protected QName createQName(String name) {
236         return new QName(name);
237     }
238 
239     /***
240      * Factory method to create a new QName object which can be overloaded to
241      * create derived QName instances
242      * 
243      * @param name
244      *            DOCUMENT ME!
245      * @param namespace
246      *            DOCUMENT ME!
247      * 
248      * @return DOCUMENT ME!
249      */
250     protected QName createQName(String name, Namespace namespace) {
251         return new QName(name, namespace);
252     }
253 
254     /***
255      * Factory method to create a new QName object which can be overloaded to
256      * create derived QName instances
257      * 
258      * @param name
259      *            DOCUMENT ME!
260      * @param namespace
261      *            DOCUMENT ME!
262      * @param qualifiedName
263      *            DOCUMENT ME!
264      * 
265      * @return DOCUMENT ME!
266      */
267     protected QName createQName(String name, Namespace namespace,
268             String qualifiedName) {
269         return new QName(name, namespace, qualifiedName);
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 
296 
297 
298 
299 
300 
301 
302 
303 
304 
305 
306 
307 
308 
309 
310