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 */