1
2
3
4
5
6
7
8
9
10 package org.mule.config.spring.jndi;
11
12 import java.io.Serializable;
13 import java.util.HashMap;
14 import java.util.Hashtable;
15 import java.util.Iterator;
16 import java.util.Map;
17
18 import javax.naming.Binding;
19 import javax.naming.CompositeName;
20 import javax.naming.Context;
21 import javax.naming.LinkRef;
22 import javax.naming.Name;
23 import javax.naming.NameClassPair;
24 import javax.naming.NameNotFoundException;
25 import javax.naming.NameParser;
26 import javax.naming.NamingEnumeration;
27 import javax.naming.NamingException;
28 import javax.naming.NotContextException;
29 import javax.naming.OperationNotSupportedException;
30 import javax.naming.Reference;
31 import javax.naming.spi.NamingManager;
32
33
34
35
36
37
38
39
40 public class DefaultSpringJndiContext implements Context, Serializable {
41
42 private static final long serialVersionUID = -5754338187296859149L;
43 protected static final NameParser nameParser = new DefaultNameParser();
44
45 private boolean freeze = false;
46
47 protected final Hashtable environment;
48 protected final Map bindings;
49 protected final Map treeBindings;
50
51 private boolean frozen = false;
52 private String nameInNamespace = "";
53 public static final String SEPARATOR = "/";
54
55 public DefaultSpringJndiContext() {
56 environment = new Hashtable();
57 bindings = new HashMap();
58 treeBindings = new HashMap();
59 }
60
61 public DefaultSpringJndiContext(Hashtable env) {
62 if (env == null) {
63 this.environment = new Hashtable();
64 }
65 else {
66 this.environment = new Hashtable(env);
67 }
68 this.bindings = new HashMap();
69 this.treeBindings = new HashMap();
70 }
71
72 public DefaultSpringJndiContext(Hashtable environment, Map bindings) {
73 if (environment == null) {
74 this.environment = new Hashtable();
75 }
76 else {
77 this.environment = new Hashtable(environment);
78 }
79 this.bindings = bindings;
80 treeBindings = new HashMap();
81 frozen = true;
82 }
83
84 public DefaultSpringJndiContext(Hashtable environment, Map bindings, String nameInNamespace) {
85 this(environment, bindings);
86 this.nameInNamespace = nameInNamespace;
87 }
88
89 protected DefaultSpringJndiContext(DefaultSpringJndiContext clone, Hashtable env) {
90 this.bindings = clone.bindings;
91 this.treeBindings = clone.treeBindings;
92 this.environment = new Hashtable(env);
93 }
94
95 protected DefaultSpringJndiContext(DefaultSpringJndiContext clone, Hashtable env, String nameInNamespace) {
96 this(clone, env);
97 this.nameInNamespace = nameInNamespace;
98 }
99
100 public Object addToEnvironment(String propName, Object propVal) throws NamingException {
101 return environment.put(propName, propVal);
102 }
103
104 public Hashtable getEnvironment() throws NamingException {
105 return (Hashtable) environment.clone();
106 }
107
108 public Object removeFromEnvironment(String propName) throws NamingException {
109 return environment.remove(propName);
110 }
111
112 public Object lookup(String name) throws NamingException {
113 if (name.length() == 0) {
114 return this;
115 }
116 Object result = treeBindings.get(name);
117 if (result == null) {
118 result = bindings.get(name);
119 }
120 if (result == null) {
121 int pos = name.indexOf(':');
122 if (pos > 0) {
123 String scheme = name.substring(0, pos);
124 Context ctx = NamingManager.getURLContext(scheme, environment);
125 if (ctx == null) {
126 throw new NamingException("scheme " + scheme + " not recognized");
127 }
128 return ctx.lookup(name);
129 }
130 else {
131
132
133 CompositeName path = new CompositeName(name);
134
135 if (path.size() == 0) {
136 return this;
137 }
138 else {
139 String first = path.get(0);
140 Object obj = bindings.get(first);
141 if (obj == null) {
142 throw new NameNotFoundException(name);
143 }
144 else if (obj instanceof Context && path.size() > 1) {
145 Context subContext = (Context) obj;
146 obj = subContext.lookup(path.getSuffix(1));
147 }
148 return obj;
149 }
150 }
151 }
152 if (result instanceof LinkRef) {
153 LinkRef ref = (LinkRef) result;
154 result = lookup(ref.getLinkName());
155 }
156 if (result instanceof Reference) {
157 try {
158 result = NamingManager.getObjectInstance(result, null, null, this.environment);
159 }
160 catch (NamingException e) {
161 throw e;
162 }
163 catch (Exception e) {
164 throw (NamingException) new NamingException("could not look up : " + name).initCause(e);
165 }
166 }
167 if (result instanceof DefaultSpringJndiContext) {
168 String prefix = getNameInNamespace();
169 if (prefix.length() > 0) {
170 prefix = prefix + SEPARATOR;
171 }
172 result = new DefaultSpringJndiContext((DefaultSpringJndiContext) result, environment, prefix + name);
173 }
174 return result;
175 }
176
177 public Object lookup(Name name) throws NamingException {
178 return lookup(name.toString());
179 }
180
181 public Object lookupLink(String name) throws NamingException {
182 return lookup(name);
183 }
184
185 public Name composeName(Name name, Name prefix) throws NamingException {
186 Name result = (Name) prefix.clone();
187 result.addAll(name);
188 return result;
189 }
190
191 public String composeName(String name, String prefix) throws NamingException {
192 CompositeName result = new CompositeName(prefix);
193 result.addAll(new CompositeName(name));
194 return result.toString();
195 }
196
197 public NamingEnumeration list(String name) throws NamingException {
198 Object o = lookup(name);
199 if (o == this) {
200 return new DefaultSpringJndiContext.ListEnumeration();
201 }
202 else if (o instanceof Context) {
203 return ((Context) o).list("");
204 }
205 else {
206 throw new NotContextException();
207 }
208 }
209
210 public NamingEnumeration listBindings(String name) throws NamingException {
211 Object o = lookup(name);
212 if (o == this) {
213 return new DefaultSpringJndiContext.ListBindingEnumeration();
214 }
215 else if (o instanceof Context) {
216 return ((Context) o).listBindings("");
217 }
218 else {
219 throw new NotContextException();
220 }
221 }
222
223 public Object lookupLink(Name name) throws NamingException {
224 return lookupLink(name.toString());
225 }
226
227 public NamingEnumeration list(Name name) throws NamingException {
228 return list(name.toString());
229 }
230
231 public NamingEnumeration listBindings(Name name) throws NamingException {
232 return listBindings(name.toString());
233 }
234
235 public void bind(Name name, Object value) throws NamingException {
236 bind(name.toString(), value);
237 }
238
239 public void bind(String name, Object value) throws NamingException {
240 checkFrozen();
241 internalBind(name, value);
242 }
243
244 public void close() throws NamingException {
245
246 }
247
248 public Context createSubcontext(Name name) throws NamingException {
249 throw new OperationNotSupportedException();
250 }
251
252 public Context createSubcontext(String name) throws NamingException {
253 throw new OperationNotSupportedException();
254 }
255
256 public void destroySubcontext(Name name) throws NamingException {
257 throw new OperationNotSupportedException();
258 }
259
260 public void destroySubcontext(String name) throws NamingException {
261 throw new OperationNotSupportedException();
262 }
263
264 public String getNameInNamespace() throws NamingException {
265 return nameInNamespace;
266 }
267
268 public NameParser getNameParser(Name name) throws NamingException {
269 return nameParser;
270 }
271
272 public NameParser getNameParser(String name) throws NamingException {
273 return nameParser;
274 }
275
276 public void rebind(Name name, Object value) throws NamingException {
277 rebind(name.toString(), value);
278 }
279
280 public void rebind(String name, Object value) throws NamingException {
281 checkFrozen();
282 internalBind(name, value, true);
283 }
284
285 public void rename(Name oldName, Name newName) throws NamingException {
286 checkFrozen();
287 Object value = lookup(oldName);
288 unbind(oldName);
289 bind(newName, value);
290 }
291
292 public void rename(String oldName, String newName) throws NamingException {
293 Object value = lookup(oldName);
294 unbind(oldName);
295 bind(newName, value);
296 }
297
298 public void unbind(Name name) throws NamingException {
299 unbind(name.toString());
300 }
301
302 public void unbind(String name) throws NamingException {
303 checkFrozen();
304 internalBind(name, null, true);
305 }
306
307 private abstract class LocalNamingEnumeration implements NamingEnumeration {
308 private Iterator i = bindings.entrySet().iterator();
309
310 public boolean hasMore() throws NamingException {
311 return i.hasNext();
312 }
313
314 public boolean hasMoreElements() {
315 return i.hasNext();
316 }
317
318 protected Map.Entry getNext() {
319 return (Map.Entry) i.next();
320 }
321
322 public void close() throws NamingException {
323 }
324 }
325
326 private class ListEnumeration extends DefaultSpringJndiContext.LocalNamingEnumeration {
327 public Object next() throws NamingException {
328 return nextElement();
329 }
330
331 public Object nextElement() {
332 Map.Entry entry = getNext();
333 return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName());
334 }
335 }
336
337 private class ListBindingEnumeration extends DefaultSpringJndiContext.LocalNamingEnumeration {
338 public Object next() throws NamingException {
339 return nextElement();
340 }
341
342 public Object nextElement() {
343 Map.Entry entry = getNext();
344 return new Binding((String) entry.getKey(), entry.getValue());
345 }
346 }
347
348 public Map getEntries() {
349 return new HashMap(bindings);
350 }
351
352 public void setEntries(Map entries) throws NamingException {
353 if (entries != null) {
354 for (Iterator iter = entries.entrySet().iterator(); iter.hasNext();) {
355 Map.Entry entry = (Map.Entry) iter.next();
356 String name = (String) entry.getKey();
357 Object value = entry.getValue();
358 internalBind(name, value);
359 }
360 }
361 }
362
363 public boolean isFreeze() {
364 return freeze;
365 }
366
367 public void setFreeze(boolean freeze) {
368 this.freeze = freeze;
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 protected Map internalBind(String name, Object value) throws NamingException {
385 return internalBind(name, value, false);
386
387 }
388 protected Map internalBind(String name, Object value, boolean allowRebind) throws NamingException {
389
390 if (name == null || name.length() == 0){
391 throw new NamingException("Invalid Name " + name);
392 }
393 if (frozen){
394 throw new NamingException("Read only");
395 }
396
397 Map newBindings = new HashMap();
398 int pos = name.indexOf('/');
399 if (pos == -1) {
400 Object oldValue = treeBindings.put(name, value);
401 if (!allowRebind && oldValue != null) {
402 throw new NamingException("Something already bound at " + name);
403 }
404 bindings.put(name, value);
405 newBindings.put(name, value);
406 }
407 else {
408 String segment = name.substring(0, pos);
409
410 if (segment == null || segment.length()==0){
411 throw new NamingException("Invalid segment " + segment);
412 }
413 Object o = treeBindings.get(segment);
414 if (o == null) {
415 o = newContext();
416 treeBindings.put(segment, o);
417 bindings.put(segment, o);
418 newBindings.put(segment, o);
419 }
420 else if (!(o instanceof DefaultSpringJndiContext)) {
421 throw new NamingException("Something already bound where a subcontext should go");
422 }
423 DefaultSpringJndiContext defaultContext = (DefaultSpringJndiContext) o;
424 String remainder = name.substring(pos + 1);
425 Map subBindings = defaultContext.internalBind(remainder, value, allowRebind);
426 for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) {
427 Map.Entry entry = (Map.Entry) iterator.next();
428 String subName = segment + "/" + (String) entry.getKey();
429 Object bound = entry.getValue();
430 treeBindings.put(subName, bound);
431 newBindings.put(subName, bound);
432 }
433 }
434 return newBindings;
435 }
436
437 protected void checkFrozen() throws OperationNotSupportedException {
438 if (isFreeze()) {
439 throw new OperationNotSupportedException("JNDI context is frozen!");
440 }
441 }
442
443 protected DefaultSpringJndiContext newContext() {
444 return new DefaultSpringJndiContext();
445 }
446
447 }
448