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: NamespaceCache.java,v 1.11 2004/08/04 18:22:39 maartenc Exp $
8    */
9   
10  package org.dom4j.tree;
11  
12  import java.lang.reflect.Constructor;
13  import java.util.Map;
14  
15  import org.dom4j.Namespace;
16  
17  /*** 
18   * <p><code>NamespaceCache</code> caches instances of <code>DefaultNamespace</code>
19   * for reuse both across documents and within documents.</p>
20   *
21   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
22   * @author Maarten Coene
23   * @author Brett Finnell
24   * @version $Revision: 1.11 $
25   */
26  public class NamespaceCache {
27  
28      /*** Cache of {@link Map} instances indexed by URI which contain
29        * caches of {@link Namespace} for each prefix
30        */
31      protected static Map cache; 
32  
33      /*** Cache of {@link Namespace} instances indexed by URI
34        * for default namespaces with no prefixes
35        */
36      protected static Map noPrefixCache;
37  
38      static {
39          /* Try the java.util.concurrent.ConcurrentHashMap first. */
40          try {
41              Class clazz = Class.forName("java.util.concurrent.ConcurrentHashMap");
42              Constructor construct = clazz.getConstructor(new Class[] {Integer.TYPE, Float.TYPE, Integer.TYPE});
43              cache = (Map) construct.newInstance(new Object[] {new Integer(11), new Float(0.75), new Integer(1)});
44              noPrefixCache = (Map) construct.newInstance(new Object[] {new Integer(11), new Float(0.75), new Integer(1)});
45          } catch (Exception exc1) {
46              /* Try to use the util.concurrent library (if in classpath) */
47              try {
48                  Class clazz = Class.forName("EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap");
49                  cache = (Map) clazz.newInstance();
50                  noPrefixCache = (Map) clazz.newInstance();
51              } catch (Exception exc2) {
52                  /* If previous implementations fail, use internal one */
53                  cache = new ConcurrentReaderHashMap();
54                  noPrefixCache = new ConcurrentReaderHashMap();
55              }
56          }
57         
58      }
59  
60  
61      /*** @return the name model for the given name and namepsace
62        */
63      public Namespace get(String prefix, String uri) {
64          Map cache = getURICache(uri);
65          Namespace answer = (Namespace) cache.get(prefix);
66          if (answer == null) {
67              synchronized (cache) {
68                  answer = (Namespace) cache.get(prefix);
69                  if (answer == null) {
70                      answer = createNamespace(prefix, uri);
71                      cache.put(prefix, answer);
72                  }
73              }
74          }
75          return answer;
76      }
77  
78  
79      /*** @return the name model for the given name and namepsace
80        */
81      public Namespace get(String uri) {
82          Namespace answer = (Namespace) noPrefixCache.get(uri);
83          if (answer == null) {
84              synchronized (noPrefixCache) {
85                  answer = (Namespace) noPrefixCache.get(uri);
86                  if (answer == null) {
87                      answer = createNamespace("", uri);
88                      noPrefixCache.put(uri, answer);
89                  }
90              }
91          }
92          return answer;
93      }
94  
95  
96      /*** @return the cache for the given namespace URI. If one does not
97        * currently exist it is created.
98        */
99      protected Map getURICache(String uri) {
100         Map answer = (Map) cache.get(uri);
101         if (answer == null) {
102             synchronized (cache) {
103                 answer = (Map) cache.get(uri);
104                 if (answer == null) {
105                     answer = new ConcurrentReaderHashMap();
106                     cache.put(uri, answer);
107                 }
108             }
109         }
110         return answer;
111     }
112 
113     /*** A factory method to create {@link Namespace} instance
114       * @return a newly created {@link Namespace} instance.
115       */
116     protected Namespace createNamespace(String prefix, String uri) {
117         return new Namespace(prefix, uri);
118     }
119 }
120 
121 
122 
123 
124 /*
125  * Redistribution and use of this software and associated documentation
126  * ("Software"), with or without modification, are permitted provided
127  * that the following conditions are met:
128  *
129  * 1. Redistributions of source code must retain copyright
130  *    statements and notices.  Redistributions must also contain a
131  *    copy of this document.
132  *
133  * 2. Redistributions in binary form must reproduce the
134  *    above copyright notice, this list of conditions and the
135  *    following disclaimer in the documentation and/or other
136  *    materials provided with the distribution.
137  *
138  * 3. The name "DOM4J" must not be used to endorse or promote
139  *    products derived from this Software without prior written
140  *    permission of MetaStuff, Ltd.  For written permission,
141  *    please contact dom4j-info@metastuff.com.
142  *
143  * 4. Products derived from this Software may not be called "DOM4J"
144  *    nor may "DOM4J" appear in their names without prior written
145  *    permission of MetaStuff, Ltd. DOM4J is a registered
146  *    trademark of MetaStuff, Ltd.
147  *
148  * 5. Due credit should be given to the DOM4J Project - 
149  *    http://dom4j.org/
150  *
151  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
152  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
153  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
154  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
155  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
156  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
157  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
158  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
159  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
160  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
161  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
162  * OF THE POSSIBILITY OF SUCH DAMAGE.
163  *
164  * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
165  *
166  * $Id: NamespaceCache.java,v 1.11 2004/08/04 18:22:39 maartenc Exp $
167  */