1
2
3
4
5
6
7
8 package org.dom4j.tree;
9
10 import java.lang.ref.WeakReference;
11 import java.lang.reflect.Constructor;
12 import java.util.Map;
13
14 import org.dom4j.Namespace;
15
16 /***
17 * <p>
18 * <code>NamespaceCache</code> caches instances of
19 * <code>DefaultNamespace</code> for reuse both across documents and within
20 * documents.
21 * </p>
22 *
23 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
24 * @author Maarten Coene
25 * @author Brett Finnell
26 * @version $Revision: 1.15 $
27 */
28 public class NamespaceCache {
29 private static final String CONCURRENTREADERHASHMAP_CLASS
30 = "EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap";
31
32 /***
33 * Cache of {@link Map}instances indexed by URI which contain caches of
34 * {@link Namespace}for each prefix
35 */
36 protected static Map cache;
37
38 /***
39 * Cache of {@link Namespace}instances indexed by URI for default
40 * namespaces with no prefixes
41 */
42 protected static Map noPrefixCache;
43
44 static {
45
46 try {
47 Class clazz = Class
48 .forName("java.util.concurrent.ConcurrentHashMap");
49 Constructor construct = clazz.getConstructor(new Class[] {
50 Integer.TYPE, Float.TYPE, Integer.TYPE });
51 cache = (Map) construct.newInstance(new Object[] {new Integer(11),
52 new Float(0.75f), new Integer(1) });
53 noPrefixCache = (Map) construct.newInstance(new Object[] {
54 new Integer(11), new Float(0.75f), new Integer(1) });
55 } catch (Throwable t1) {
56
57 try {
58 Class clazz = Class.forName(CONCURRENTREADERHASHMAP_CLASS);
59 cache = (Map) clazz.newInstance();
60 noPrefixCache = (Map) clazz.newInstance();
61 } catch (Throwable t2) {
62
63 cache = new ConcurrentReaderHashMap();
64 noPrefixCache = new ConcurrentReaderHashMap();
65 }
66 }
67 }
68
69 /***
70 * DOCUMENT ME!
71 *
72 * @param prefix
73 * DOCUMENT ME!
74 * @param uri
75 * DOCUMENT ME!
76 *
77 * @return the namespace for the given prefix and uri
78 */
79 public Namespace get(String prefix, String uri) {
80 Map uriCache = getURICache(uri);
81 WeakReference ref = (WeakReference) uriCache.get(prefix);
82 Namespace answer = null;
83
84 if (ref != null) {
85 answer = (Namespace) ref.get();
86 }
87
88 if (answer == null) {
89 synchronized (uriCache) {
90 ref = (WeakReference) uriCache.get(prefix);
91
92 if (ref != null) {
93 answer = (Namespace) ref.get();
94 }
95
96 if (answer == null) {
97 answer = createNamespace(prefix, uri);
98 uriCache.put(prefix, new WeakReference(answer));
99 }
100 }
101 }
102
103 return answer;
104 }
105
106 /***
107 * DOCUMENT ME!
108 *
109 * @param uri
110 * DOCUMENT ME!
111 *
112 * @return the name model for the given name and namepsace
113 */
114 public Namespace get(String uri) {
115 WeakReference ref = (WeakReference) noPrefixCache.get(uri);
116 Namespace answer = null;
117
118 if (ref != null) {
119 answer = (Namespace) ref.get();
120 }
121
122 if (answer == null) {
123 synchronized (noPrefixCache) {
124 ref = (WeakReference) noPrefixCache.get(uri);
125
126 if (ref != null) {
127 answer = (Namespace) ref.get();
128 }
129
130 if (answer == null) {
131 answer = createNamespace("", uri);
132 noPrefixCache.put(uri, new WeakReference(answer));
133 }
134 }
135 }
136
137 return answer;
138 }
139
140 /***
141 * DOCUMENT ME!
142 *
143 * @param uri
144 * DOCUMENT ME!
145 *
146 * @return the cache for the given namespace URI. If one does not currently
147 * exist it is created.
148 */
149 protected Map getURICache(String uri) {
150 Map answer = (Map) cache.get(uri);
151
152 if (answer == null) {
153 synchronized (cache) {
154 answer = (Map) cache.get(uri);
155
156 if (answer == null) {
157 answer = new ConcurrentReaderHashMap();
158 cache.put(uri, answer);
159 }
160 }
161 }
162
163 return answer;
164 }
165
166 /***
167 * A factory method to create {@link Namespace}instance
168 *
169 * @param prefix
170 * DOCUMENT ME!
171 * @param uri
172 * DOCUMENT ME!
173 *
174 * @return a newly created {@link Namespace}instance.
175 */
176 protected Namespace createNamespace(String prefix, String uri) {
177 return new Namespace(prefix, uri);
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216