View Javadoc

1   /*
2    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    *
7    * $Id: QNameCache.java,v 1.13 2004/06/25 08:03:41 maartenc Exp $
8    */
9   
10  package org.dom4j.tree;
11  
12  import java.util.ArrayList;
13  import java.util.Collections;
14  import java.util.HashMap;
15  import java.util.Iterator;
16  import java.util.List;
17  import java.util.Map;
18  
19  import org.dom4j.DocumentFactory;
20  import org.dom4j.Namespace;
21  import org.dom4j.QName;
22  
23  /*** <p><code>QNameCache</code> caches instances of <code>QName</code>
24    * for reuse both across documents and within documents.</p>
25    *
26    * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
27    * @version $Revision: 1.13 $
28    */
29  public class QNameCache {
30  
31      /*** Cache of {@link QName} instances with no namespace */
32      protected Map noNamespaceCache = Collections.synchronizedMap(new HashMap());
33  
34      /*** Cache of {@link Map} instances indexed by namespace which contain
35        * caches of {@link QName} for each name
36        */
37      protected Map namespaceCache = Collections.synchronizedMap(new HashMap());
38  
39      /*** The document factory associated with new QNames instances in this cache
40        * or null if no instances should be associated by default
41        */
42      private DocumentFactory documentFactory;
43  
44  
45      public QNameCache() {
46      }
47  
48      public QNameCache(DocumentFactory documentFactory) {
49          this.documentFactory = documentFactory;
50      }
51  
52      /*** Returns a list of all the QName instances currently used
53       */
54      public List getQNames() {
55          List answer = new ArrayList();
56          answer.addAll( noNamespaceCache.values() );
57          for ( Iterator iter = namespaceCache.values().iterator(); iter.hasNext(); ) {
58              Map map = (Map) iter.next();
59              answer.addAll( map.values() );
60          }
61          return answer;
62      }
63  
64      /*** @return the QName for the given name and no namepsace
65        */
66      public QName get(String name) {
67          QName answer = null;
68          if (name!=null) {
69            answer=(QName) noNamespaceCache.get(name);
70          }
71          else {
72            name="";
73          }
74          if (answer == null) {
75              answer = createQName(name);
76              answer.setDocumentFactory( documentFactory );
77              noNamespaceCache.put(name, answer);
78          }
79          return answer;
80      }
81  
82      /*** @return the QName for the given local name and namepsace
83        */
84      public QName get(String name, Namespace namespace) {
85          Map cache = getNamespaceCache(namespace);
86          QName answer = null;
87          if (name!=null) {
88            answer=(QName) cache.get(name);
89          }
90          else {
91            name="";
92          }
93          if (answer == null) {
94              answer = createQName(name, namespace);
95              answer.setDocumentFactory( documentFactory );
96              cache.put(name, answer);
97          }
98          return answer;
99      }
100 
101 
102     /*** @return the QName for the given local name, qualified name and namepsace
103       */
104     public QName get(String localName, Namespace namespace, String qualifiedName) {
105         Map cache = getNamespaceCache(namespace);
106         QName answer = null;
107         if (localName!=null) {
108           answer=(QName) cache.get(localName);
109         }
110         else {
111           localName="";
112         }
113 
114         if (answer == null) {
115             answer = createQName(localName, namespace, qualifiedName);
116             answer.setDocumentFactory( documentFactory );
117             cache.put(localName, answer);
118         }
119         return answer;
120     }
121 
122 
123     public QName get(String qualifiedName, String uri) {
124         int index = qualifiedName.indexOf( ':' );
125         if ( index < 0 ) {
126             return get( qualifiedName, Namespace.get( uri ) );
127         }
128         else {
129             String name = qualifiedName.substring( index + 1 );
130             String prefix = qualifiedName.substring( 0, index );
131             return get(name, Namespace.get( prefix, uri ));
132         }
133     }
134 
135 
136     /*** @return the cached QName instance if there is one or adds the given
137       * qname to the cache if not
138        */
139     public QName intern(QName qname) {
140         return get(qname.getName(), qname.getNamespace(), qname.getQualifiedName());
141     }
142 
143     /*** @return the cache for the given namespace. If one does not
144       * currently exist it is created.
145       */
146     protected Map getNamespaceCache(Namespace namespace) {
147         if (namespace == Namespace.NO_NAMESPACE) {
148             return noNamespaceCache;
149         }
150         Map answer = null;
151         if (namespace!=null) {
152           answer=(Map) namespaceCache.get(namespace);
153         }
154         if (answer == null) {
155             answer = createMap();
156             namespaceCache.put(namespace, answer);
157         }
158         return answer;
159     }
160 
161     /*** A factory method
162       * @return a newly created {@link Map} instance.
163       */
164     protected Map createMap() {
165         return Collections.synchronizedMap(new HashMap());
166     }
167 
168     /*** Factory method to create a new QName object
169       * which can be overloaded to create derived QName instances
170       */
171     protected QName createQName(String name) {
172         return new QName(name);
173     }
174 
175     /*** Factory method to create a new QName object
176       * which can be overloaded to create derived QName instances
177       */
178     protected QName createQName(String name, Namespace namespace) {
179         return new QName(name, namespace);
180     }
181 
182     /*** Factory method to create a new QName object
183       * which can be overloaded to create derived QName instances
184       */
185     protected QName createQName(String name, Namespace namespace, String qualifiedName) {
186         return new QName(name, namespace, qualifiedName);
187     }
188 }
189 
190 
191 
192 
193 /*
194  * Redistribution and use of this software and associated documentation
195  * ("Software"), with or without modification, are permitted provided
196  * that the following conditions are met:
197  *
198  * 1. Redistributions of source code must retain copyright
199  *    statements and notices.  Redistributions must also contain a
200  *    copy of this document.
201  *
202  * 2. Redistributions in binary form must reproduce the
203  *    above copyright notice, this list of conditions and the
204  *    following disclaimer in the documentation and/or other
205  *    materials provided with the distribution.
206  *
207  * 3. The name "DOM4J" must not be used to endorse or promote
208  *    products derived from this Software without prior written
209  *    permission of MetaStuff, Ltd.  For written permission,
210  *    please contact dom4j-info@metastuff.com.
211  *
212  * 4. Products derived from this Software may not be called "DOM4J"
213  *    nor may "DOM4J" appear in their names without prior written
214  *    permission of MetaStuff, Ltd. DOM4J is a registered
215  *    trademark of MetaStuff, Ltd.
216  *
217  * 5. Due credit should be given to the DOM4J Project - 
218  *    http://www.dom4j.org
219  *
220  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
221  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
222  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
223  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
224  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
225  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
226  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
227  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
228  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
229  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
230  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
231  * OF THE POSSIBILITY OF SUCH DAMAGE.
232  *
233  * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
234  *
235  * $Id: QNameCache.java,v 1.13 2004/06/25 08:03:41 maartenc Exp $
236  */