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