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