KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > naming > context > ContextImpl


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: ContextImpl.java 1037 2006-08-06 17:41:31Z sauthieg $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.naming.context;
27
28 import java.util.Hashtable JavaDoc;
29
30 import javax.naming.Binding JavaDoc;
31 import javax.naming.CompositeName JavaDoc;
32 import javax.naming.Context JavaDoc;
33 import javax.naming.InitialContext JavaDoc;
34 import javax.naming.InvalidNameException JavaDoc;
35 import javax.naming.LinkRef JavaDoc;
36 import javax.naming.Name JavaDoc;
37 import javax.naming.NameAlreadyBoundException JavaDoc;
38 import javax.naming.NameClassPair JavaDoc;
39 import javax.naming.NameNotFoundException JavaDoc;
40 import javax.naming.NameParser JavaDoc;
41 import javax.naming.NamingEnumeration JavaDoc;
42 import javax.naming.NamingException JavaDoc;
43 import javax.naming.NotContextException JavaDoc;
44 import javax.naming.OperationNotSupportedException JavaDoc;
45 import javax.naming.RefAddr JavaDoc;
46 import javax.naming.Reference JavaDoc;
47
48 import org.objectweb.easybeans.log.JLog;
49 import org.objectweb.easybeans.log.JLogFactory;
50
51 /**
52  * Implementation of Context interface.
53  * @author Florent Benoit
54  */

55 public class ContextImpl implements Context JavaDoc {
56
57     /**
58      * Logger.
59      */

60     private static JLog logger = JLogFactory.getLog(ContextImpl.class);
61
62     /**
63      * Environment.
64      */

65     private Hashtable JavaDoc environment = null;
66
67     /**
68      * Bindings (Name <--> Object).
69      */

70     private Hashtable JavaDoc<String JavaDoc, Object JavaDoc> bindings = new Hashtable JavaDoc<String JavaDoc, Object JavaDoc>();
71
72     /**
73      * Parser.
74      */

75     private static NameParser JavaDoc myParser = new JavaNameParser();
76
77     /**
78      * Naming id.
79      */

80     private String JavaDoc compId;
81
82     /**
83      * Constructor.
84      * @param id id of the context.
85      * @param env initial environment.
86      */

87     public ContextImpl(final String JavaDoc id, final Hashtable JavaDoc<Object JavaDoc, Object JavaDoc> env) {
88         if (env != null) {
89             // clone env to be able to change it.
90
environment = (Hashtable JavaDoc) (env.clone());
91         } else {
92             environment = new Hashtable JavaDoc<Object JavaDoc, Object JavaDoc>();
93         }
94         compId = id;
95     }
96
97     /**
98      * Constructor.
99      * @param id id of the context.
100      */

101     @SuppressWarnings JavaDoc("unchecked")
102     public ContextImpl(final String JavaDoc id) {
103         this(id, new Hashtable JavaDoc());
104     }
105
106     /**
107      * Retrieves the named object.
108      * @param name the name of the object to look up
109      * @return the object bound to <tt>name</tt>
110      * @throws NamingException if a naming exception is encountered
111      */

112     public Object JavaDoc lookup(final Name JavaDoc name) throws NamingException JavaDoc {
113         // Just use the string version for now.
114
return lookup(name.toString());
115     }
116
117     /**
118      * Retrieves the named object.
119      * @param name the name of the object to look up
120      * @return the object bound to name
121      * @throws NamingException if a naming exception is encountered
122      */

123     public Object JavaDoc lookup(final String JavaDoc name) throws NamingException JavaDoc {
124         logger.debug("lookup {0}", name);
125
126         Name JavaDoc n = new CompositeName JavaDoc(name);
127         if (n.size() < 1) {
128             // Empty name means this context
129
logger.debug("Empty name");
130             return this;
131         }
132
133         if (n.size() > 1) {
134             // sub context in the env tree
135
String JavaDoc suffix = n.getSuffix(1).toString();
136             // should throw exception if sub context not found!
137
Context JavaDoc subctx = lookupCtx(n.get(0));
138             return subctx.lookup(suffix);
139         }
140         // leaf in the env tree
141
Object JavaDoc ret = bindings.get(name);
142         if (ret == null) {
143             logger.debug(" {0} not found.", name);
144             throw new NameNotFoundException JavaDoc(name);
145         }
146         if (ret instanceof LinkRef JavaDoc) {
147             // Handle special case of the LinkRef since I think
148
// it's not handled by std NamingManager.getObjectInstance().
149
// The name hidden in linkref is in the initial context.
150

151             InitialContext JavaDoc ictx = new InitialContext JavaDoc();
152             RefAddr JavaDoc ra = ((Reference JavaDoc) ret).get(0);
153             try {
154                 ret = ictx.lookup((String JavaDoc) ra.getContent());
155             } catch (Exception JavaDoc e) {
156                 NamingException JavaDoc ne = new NamingException JavaDoc(e.getMessage());
157                 ne.setRootCause(e);
158                 logger.error("unexpected exception {0}", e.getMessage(), e);
159                 throw ne;
160             }
161         } else if (ret instanceof Reference JavaDoc) {
162             // Use NamingManager to build an object
163
try {
164                 Object JavaDoc o = javax.naming.spi.NamingManager.getObjectInstance(ret, n, this, environment);
165                 ret = o;
166             } catch (NamingException JavaDoc e) {
167                 throw e;
168             } catch (Exception JavaDoc e) {
169                 NamingException JavaDoc ne = new NamingException JavaDoc(e.getMessage());
170                 ne.setRootCause(e);
171                 throw ne;
172             }
173             if (ret == null) {
174                 logger.error("Can not build an object with the reference {0}", name);
175                 throw new NamingException JavaDoc("Can not build an object with the reference '" + name + "'");
176             }
177         }
178         return ret;
179
180     }
181
182     /**
183      * Binds a name to an object. Delegate to the String version.
184      * @param name the name to bind; may not be empty
185      * @param obj the object to bind; possibly null
186      * @throws NamingException if a naming exception is encountered
187      * @see javax.naming.NameAlreadyBoundException
188      */

189     public void bind(final Name JavaDoc name, final Object JavaDoc obj) throws NamingException JavaDoc {
190         // Just use the string version for now.
191
bind(name.toString(), obj);
192     }
193
194     /**
195      * Binds a name to an object.
196      * @param name the name to bind; may not be empty
197      * @param obj the object to bind; possibly null
198      * @throws NamingException if a naming exception is encountered
199      * @see javax.naming.NameAlreadyBoundException
200      */

201     public void bind(final String JavaDoc name, final Object JavaDoc obj) throws NamingException JavaDoc {
202         logger.debug("bind {0}", name);
203
204         Name JavaDoc n = new CompositeName JavaDoc(name);
205         if (n.size() < 1) {
206             logger.error("CompNamingContext bind empty name ?");
207
208             throw new InvalidNameException JavaDoc("CompNamingContext cannot bind empty name");
209         }
210
211         if (n.size() == 1) {
212             // leaf in the env tree
213
if (bindings.get(name) != null) {
214                 logger.error("CompNamingContext: trying to overbind");
215                 throw new NameAlreadyBoundException JavaDoc("CompNamingContext: Use rebind to bind over a name");
216             }
217             bindings.put(name, obj);
218         } else {
219             // sub context in the env tree
220
String JavaDoc suffix = n.getSuffix(1).toString();
221             // must create the subcontext first if it does not exist yet.
222
Context JavaDoc subctx;
223             try {
224                 subctx = lookupCtx(n.get(0));
225             } catch (NameNotFoundException JavaDoc e) {
226                 subctx = createSubcontext(n.get(0));
227             }
228             subctx.bind(suffix, obj);
229         }
230     }
231
232     /**
233      * Binds a name to an object, overwriting any existing binding.
234      * @param name the name to bind; may not be empty
235      * @param obj the object to bind; possibly null
236      * @throws NamingException if a naming exception is encountered
237      */

238     public void rebind(final Name JavaDoc name, final Object JavaDoc obj) throws NamingException JavaDoc {
239         // Just use the string version for now.
240
rebind(name.toString(), obj);
241     }
242
243     /**
244      * Binds a name to an object, overwriting any existing binding.
245      * @param name the name to bind; may not be empty
246      * @param obj the object to bind; possibly null
247      * @throws NamingException if a naming exception is encountered
248      * @see javax.naming.InvalidNameException
249      */

250     public void rebind(final String JavaDoc name, final Object JavaDoc obj) throws NamingException JavaDoc {
251
252         logger.debug("rebind {0}", name);
253
254         Name JavaDoc n = new CompositeName JavaDoc(name);
255         if (n.size() < 1) {
256             logger.error("CompNamingContext rebind empty name ?");
257             throw new InvalidNameException JavaDoc("CompNamingContext cannot rebind empty name");
258         }
259
260         if (n.size() == 1) {
261             // leaf in the env tree
262
bindings.put(name, obj);
263         } else {
264             // sub context in the env tree
265
String JavaDoc suffix = n.getSuffix(1).toString();
266             // must create the subcontext first if it does not exist yet.
267
Context JavaDoc subctx;
268             try {
269                 subctx = lookupCtx(n.get(0));
270             } catch (NameNotFoundException JavaDoc e) {
271                 subctx = createSubcontext(n.get(0));
272             }
273             subctx.rebind(suffix, obj);
274         }
275     }
276
277     /**
278      * Unbinds the named object.
279      * @param name the name to unbind; may not be empty
280      * @throws NamingException if a naming exception is encountered
281      * @see javax.naming.NameNotFoundException
282      */

283     public void unbind(final Name JavaDoc name) throws NamingException JavaDoc {
284         // Just use the string version for now.
285
unbind(name.toString());
286     }
287
288     /**
289      * Unbinds the named object.
290      * @param name the name to unbind; may not be empty
291      * @throws NamingException if a naming exception is encountered
292      * @see javax.naming.NameNotFoundException
293      * @see javax.naming.InvalidNameException
294      */

295     public void unbind(final String JavaDoc name) throws NamingException JavaDoc {
296
297         logger.debug("unbind {0}", name);
298
299         Name JavaDoc n = new CompositeName JavaDoc(name);
300         if (n.size() < 1) {
301             logger.error("CompNamingContext rebind empty name ?");
302             throw new InvalidNameException JavaDoc("CompNamingContext cannot unbind empty name");
303         }
304
305         if (n.size() == 1) {
306             // leaf in the env tree
307
if (bindings.get(name) == null) {
308                 logger.error("CompNamingContext nothing to unbind");
309                 throw new NameNotFoundException JavaDoc(name);
310             }
311             bindings.remove(name);
312         } else {
313             // sub context in the env tree
314
String JavaDoc suffix = n.getSuffix(1).toString();
315             // should throw exception if sub context not found!
316
Context JavaDoc subctx = lookupCtx(n.get(0));
317             subctx.unbind(suffix);
318         }
319     }
320
321     /**
322      * Binds a new name to the object bound to an old name, and unbinds the old
323      * name.
324      * @param oldName the name of the existing binding; may not be empty
325      * @param newName the name of the new binding; may not be empty
326      * @throws NamingException if a naming exception is encountered
327      */

328     public void rename(final Name JavaDoc oldName, final Name JavaDoc newName) throws NamingException JavaDoc {
329         // Just use the string version for now.
330
rename(oldName.toString(), newName.toString());
331     }
332
333     /**
334      * Binds a new name to the object bound to an old name, and unbinds the old
335      * name.
336      * @param oldName the name of the existing binding; may not be empty
337      * @param newName the name of the new binding; may not be empty
338      * @throws NamingException if a naming exception is encountered
339      */

340     public void rename(final String JavaDoc oldName, final String JavaDoc newName) throws NamingException JavaDoc {
341         logger.debug("CompNamingContext rename {0} in {1}", oldName, newName);
342         Object JavaDoc obj = lookup(oldName);
343         rebind(newName, obj);
344         unbind(oldName);
345     }
346
347     /**
348      * Enumerates the names bound in the named context, along with the class
349      * names of objects bound to them. The contents of any subcontexts are not
350      * included.
351      * @param name the name of the context to list
352      * @return an enumeration of the names and class names of the bindings in
353      * this context. Each element of the enumeration is of type
354      * NameClassPair.
355      * @throws NamingException if a naming exception is encountered
356      */

357     public NamingEnumeration JavaDoc<NameClassPair JavaDoc> list(final Name JavaDoc name) throws NamingException JavaDoc {
358         // Just use the string version for now.
359
return list(name.toString());
360     }
361
362     /**
363      * Enumerates the names bound in the named context, along with the class
364      * names of objects bound to them.
365      * @param name the name of the context to list
366      * @return an enumeration of the names and class names of the bindings in
367      * this context. Each element of the enumeration is of type
368      * NameClassPair.
369      * @throws NamingException if a naming exception is encountered
370      */

371     public NamingEnumeration JavaDoc<NameClassPair JavaDoc> list(final String JavaDoc name) throws NamingException JavaDoc {
372         logger.debug("list {0}", name);
373
374         if (name.length() == 0) {
375             // List this context
376
return new NamingEnumerationImpl(bindings);
377         }
378         Object JavaDoc obj = lookup(name);
379         if (obj instanceof Context JavaDoc) {
380             return ((Context JavaDoc) obj).list("");
381         }
382         throw new NotContextException JavaDoc(name);
383     }
384
385     /**
386      * Enumerates the names bound in the named context, along with the objects
387      * bound to them. The contents of any subcontexts are not included. If a
388      * binding is added to or removed from this context, its effect on an
389      * enumeration previously returned is undefined.
390      * @param name the name of the context to list
391      * @return an enumeration of the bindings in this context. Each element of
392      * the enumeration is of type Binding.
393      * @throws NamingException if a naming exception is encountered
394      */

395     public NamingEnumeration JavaDoc<Binding JavaDoc> listBindings(final Name JavaDoc name) throws NamingException JavaDoc {
396         // Just use the string version for now.
397
return listBindings(name.toString());
398     }
399
400     /**
401      * Enumerates the names bound in the named context, along with the objects
402      * bound to them.
403      * @param name the name of the context to list
404      * @return an enumeration of the bindings in this context. Each element of
405      * the enumeration is of type Binding.
406      * @throws NamingException if a naming exception is encountered
407      */

408     public NamingEnumeration JavaDoc<Binding JavaDoc> listBindings(final String JavaDoc name) throws NamingException JavaDoc {
409         logger.debug("listBindings {0}", name);
410
411         if (name.length() == 0) {
412             // List this context
413
return new BindingsImpl(bindings);
414         }
415         Object JavaDoc obj = lookup(name);
416         if (obj instanceof Context JavaDoc) {
417             return ((Context JavaDoc) obj).listBindings("");
418         }
419         logger.error("CompNamingContext: can only list a Context");
420         throw new NotContextException JavaDoc(name);
421
422     }
423
424     /**
425      * Destroys the named context and removes it from the namespace. Not
426      * supported yet.
427      * @param name the name of the context to be destroyed; may not be empty
428      * @throws NamingException if a naming exception is encountered
429      */

430     public void destroySubcontext(final Name JavaDoc name) throws NamingException JavaDoc {
431         // Just use the string version for now.
432
destroySubcontext(name.toString());
433     }
434
435     /**
436      * Destroys the named context and removes it from the namespace. Not
437      * supported yet.
438      * @param name the name of the context to be destroyed; may not be empty
439      * @throws NamingException if a naming exception is encountered
440      */

441     public void destroySubcontext(final String JavaDoc name) throws NamingException JavaDoc {
442         logger.error("CompNamingContext try to destroySubcontext {0}", name);
443         throw new OperationNotSupportedException JavaDoc("CompNamingContext: destroySubcontext");
444     }
445
446     /**
447      * Creates and binds a new context. Creates a new context with the given
448      * name and binds it in the target context.
449      * @param name the name of the context to create; may not be empty
450      * @return the newly created context
451      * @throws NamingException if a naming exception is encountered
452      * @see javax.naming.NameAlreadyBoundException
453      */

454     public Context JavaDoc createSubcontext(final Name JavaDoc name) throws NamingException JavaDoc {
455         // Just use the string version for now.
456
return createSubcontext(name.toString());
457     }
458
459     /**
460      * Creates and binds a new context.
461      * @param name the name of the context to create; may not be empty
462      * @return the newly created context
463      * @throws NamingException if a naming exception is encountered
464      * @see javax.naming.NameAlreadyBoundException
465      */

466     @SuppressWarnings JavaDoc("unchecked")
467     public Context JavaDoc createSubcontext(final String JavaDoc name) throws NamingException JavaDoc {
468         logger.debug("createSubcontext {0}", name);
469
470         Name JavaDoc n = new CompositeName JavaDoc(name);
471         if (n.size() < 1) {
472             logger.error("CompNamingContext createSubcontext with empty name ?");
473             throw new InvalidNameException JavaDoc("CompNamingContext cannot create empty Subcontext");
474         }
475
476         Context JavaDoc ctx = null; // returned ctx
477
if (n.size() == 1) {
478             // leaf in the env tree: create ctx and bind it in parent.
479
ctx = new ContextImpl(compId, environment);
480             bindings.put(name, ctx);
481         } else {
482             // as for bind, we must create first all the subcontexts
483
// if they don't exist yet.
484
String JavaDoc suffix = n.getSuffix(1).toString();
485             Context JavaDoc subctx;
486             String JavaDoc newName = n.get(0);
487             try {
488                 subctx = lookupCtx(newName);
489             } catch (NameNotFoundException JavaDoc e) {
490                 subctx = createSubcontext(newName);
491             }
492             ctx = subctx.createSubcontext(suffix);
493         }
494         return ctx;
495     }
496
497     /**
498      * Retrieves the named object, following links except for the terminal
499      * atomic component of the name. If the object bound to name is not a link,
500      * returns the object itself.
501      * @param name the name of the object to look up
502      * @return the object bound to name, not following the terminal link (if
503      * any).
504      * @throws NamingException if a naming exception is encountered
505      */

506     public Object JavaDoc lookupLink(final Name JavaDoc name) throws NamingException JavaDoc {
507         // Just use the string version for now.
508
return lookupLink(name.toString());
509     }
510
511     /**
512      * Retrieves the named object, following links except for the terminal
513      * atomic component of the name. If the object bound to name is not a link,
514      * returns the object itself.
515      * @param name the name of the object to look up
516      * @return the object bound to name, not following the terminal link (if
517      * any)
518      * @throws NamingException if a naming exception is encountered
519      */

520     public Object JavaDoc lookupLink(final String JavaDoc name) throws NamingException JavaDoc {
521         logger.debug("lookupLink {0}", name);
522
523         // To be done. For now: just return the object
524
logger.error("CompNamingContext lookupLink not implemented yet!");
525
526         return lookup(name);
527     }
528
529     /**
530      * Retrieves the parser associated with the named context.
531      * @param name the name of the context from which to get the parser
532      * @return a name parser that can parse compound names into their atomic
533      * components
534      * @throws NamingException if a naming exception is encountered
535      */

536     public NameParser JavaDoc getNameParser(final Name JavaDoc name) throws NamingException JavaDoc {
537         return myParser;
538     }
539
540     /**
541      * Retrieves the parser associated with the named context.
542      * @param name the name of the context from which to get the parser
543      * @return a name parser that can parse compound names into their atomic
544      * components
545      * @throws NamingException if a naming exception is encountered
546      */

547     public NameParser JavaDoc getNameParser(final String JavaDoc name) throws NamingException JavaDoc {
548         return myParser;
549     }
550
551     /**
552      * Composes the name of this context with a name relative to this context.
553      * @param name a name relative to this context
554      * @param prefix the name of this context relative to one of its ancestors
555      * @return the composition of prefix and name
556      * @throws NamingException if a naming exception is encountered
557      */

558     public Name JavaDoc composeName(final Name JavaDoc name, final Name JavaDoc prefix) throws NamingException JavaDoc {
559         logger.error("CompNamingContext composeName not implemented yet!");
560
561         throw new OperationNotSupportedException JavaDoc("CompNamingContext composeName");
562     }
563
564     /**
565      * Composes the name of this context with a name relative to this context:
566      * Not supported.
567      * @param name a name relative to this context
568      * @param prefix the name of this context relative to one of its ancestors
569      * @return the composition of prefix and name
570      * @throws NamingException if a naming exception is encountered
571      */

572     public String JavaDoc composeName(final String JavaDoc name, final String JavaDoc prefix) throws NamingException JavaDoc {
573         logger.error("CompNamingContext composeName {0} {1}", name, prefix);
574
575         throw new OperationNotSupportedException JavaDoc("CompNamingContext composeName");
576     }
577
578     /**
579      * Adds a new environment property to the environment of this context. If
580      * the property already exists, its value is overwritten.
581      * @param propName the name of the environment property to add; may not be
582      * null
583      * @param propVal the value of the property to add; may not be null
584      * @return the previous value of the property, or null if the property was
585      * not in the environment before
586      * @throws NamingException if a naming exception is encountered
587      */

588     @SuppressWarnings JavaDoc("unchecked")
589     public Object JavaDoc addToEnvironment(final String JavaDoc propName, final Object JavaDoc propVal) throws NamingException JavaDoc {
590         return environment.put(propName, propVal);
591     }
592
593     /**
594      * Removes an environment property from the environment of this context.
595      * @param propName the name of the environment property to remove; may not
596      * be null
597      * @return the previous value of the property, or null if the property was
598      * not in the environment
599      * @throws NamingException if a naming exception is encountered
600      */

601     public Object JavaDoc removeFromEnvironment(final String JavaDoc propName) throws NamingException JavaDoc {
602
603         logger.debug("removeFromEnvironment {0}", propName);
604
605         if (environment == null) {
606             return null;
607         }
608         return environment.remove(propName);
609     }
610
611     /**
612      * Retrieves the environment in effect for this context.
613      * @return the environment of this context; never null
614      * @throws NamingException if a naming exception is encountered
615      */

616     public Hashtable JavaDoc<?, ?> getEnvironment() throws NamingException JavaDoc {
617         return environment;
618     }
619
620     /**
621      * Closes this context.
622      * @throws NamingException if a naming exception is encountered
623      */

624     public void close() throws NamingException JavaDoc {
625         environment = null;
626     }
627
628     /**
629      * Retrieves the full name of this context within its own namespace.
630      * @return this context's name in its own namespace; never null
631      */

632     public String JavaDoc getNameInNamespace() {
633         // this is used today for debug only.
634
return compId;
635     }
636
637     // ------------------------------------------------------------------
638
// Private Methods
639
// ------------------------------------------------------------------
640

641     /**
642      * Find if this name is a sub context.
643      * @param name the sub context name
644      * @return the named Context
645      * @throws NamingException When nam?ing fails
646      * @see javax.naming.NameNotFoundException
647      * @see javax.naming.NameAlreadyBoundException
648      */

649     private Context JavaDoc lookupCtx(final String JavaDoc name) throws NamingException JavaDoc {
650         Object JavaDoc obj = bindings.get(name);
651         if (obj == null) {
652             throw new NameNotFoundException JavaDoc();
653         }
654         if (obj instanceof ContextImpl) {
655             return (Context JavaDoc) obj;
656         }
657         throw new NameAlreadyBoundException JavaDoc(name);
658     }
659
660 }
661
Popular Tags