KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > carol > jndi > spi > AbsContext


1 /**
2  * Copyright (C) 2005 - Bull S.A.
3  *
4  * CAROL: Common Architecture for RMI ObjectWeb Layer
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: AbsContext.java,v 1.4 2005/04/07 15:07:08 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.carol.jndi.spi;
26
27 import java.rmi.Remote JavaDoc;
28 import java.util.Hashtable JavaDoc;
29
30 import javax.naming.CompositeName JavaDoc;
31 import javax.naming.Context JavaDoc;
32 import javax.naming.InvalidNameException JavaDoc;
33 import javax.naming.Name JavaDoc;
34 import javax.naming.NameParser JavaDoc;
35 import javax.naming.NamingEnumeration JavaDoc;
36 import javax.naming.NamingException JavaDoc;
37
38 import org.objectweb.carol.jndi.wrapping.JNDIRemoteResource;
39 import org.objectweb.carol.rmi.exception.NamingExceptionHelper;
40 import org.objectweb.carol.util.configuration.ConfigurationRepository;
41
42 /**
43  * This abstract class define the common methods used for all existing protocol
44  * implementation of their SPI context. When integrating a new protocol, define
45  * a new SPI class extending this one. You only have to focus on specific
46  * implementation and let in major case all default implementation.
47  * @author Florent Benoit
48  */

49 public abstract class AbsContext implements Context JavaDoc {
50
51     /**
52      * The wrapping context (should be protocol context)
53      */

54     private Context JavaDoc wrappedContext = null;
55
56     /**
57      * Exported Wrapper Hashtable
58      */

59     private Hashtable JavaDoc exportedObjects = new Hashtable JavaDoc();
60
61     /**
62      * Constructs a wrapper on the given protocol context
63      * @param ctx the given context (could be jrmp context, jeremie context,
64      * iiop context,...).
65      */

66     protected AbsContext(Context JavaDoc ctx) {
67         this.wrappedContext = ctx;
68     }
69
70     /**
71      * If this object is a reference wrapper return the reference If this object
72      * is a resource wrapper return the resource
73      * @param o the object to resolve
74      * @param name name of the object to unwrap
75      * @return the unwrapped object
76      * @throws NamingException if the object cannot be unwraped
77      */

78     protected abstract Object JavaDoc unwrapObject(Object JavaDoc o, Name JavaDoc name) throws NamingException JavaDoc;
79
80     /**
81      * Wrap an Object : If the object is a reference wrap it into a Reference
82      * Wrapper Object here the good way is to contact the carol configuration to
83      * get the portable remote object
84      * @param o the object to encode
85      * @param name of the object
86      * @param replace if the object need to be replaced
87      * @return a <code>Remote JNDIRemoteReference Object</code> if o is a
88      * resource o if else
89      * @throws NamingException if object cannot be wrapped
90      */

91     protected abstract Object JavaDoc wrapObject(Object JavaDoc o, Name JavaDoc name, boolean replace) throws NamingException JavaDoc;
92
93     /**
94      * Default implementation of unwrapObject method If this object is a
95      * reference wrapper return the reference If this object is a resource
96      * wrapper return the resource
97      * @param o the object to resolve
98      * @param name name of the object to unwrap
99      * @return the unwrapped object
100      * @throws NamingException if the object cannot be unwraped
101      */

102     protected Object JavaDoc defaultUnwrapObject(Object JavaDoc o, Name JavaDoc name) throws NamingException JavaDoc {
103         try {
104             if (o instanceof JNDIRemoteResource) {
105                 return ((JNDIRemoteResource) o).getResource();
106             } else {
107                 return o;
108             }
109         } catch (Exception JavaDoc e) {
110             throw NamingExceptionHelper.create("Cannot unwrap object '" + o + "' with name '" + name + "' :"
111                     + e.getMessage(), e);
112         }
113     }
114
115     /**
116      * Get the object port to use (0 by default, declare this method in a subclass if you want to change value)
117      * @return object port to use
118      */

119     protected int getObjectPort() {
120         return 0;
121
122     }
123
124     /**
125      * Retrieves the named object.
126      * @param name the name of the object to look up
127      * @return the object bound to <tt>name</tt>
128      * @throws NamingException if a naming exception is encountered
129      */

130     public Object JavaDoc lookup(Name JavaDoc name) throws NamingException JavaDoc {
131         if (name.isEmpty()) {
132             return this;
133         }
134         return unwrapObject(wrappedContext.lookup(encode(name)), name);
135     }
136
137     /**
138      * Retrieves the named object.
139      * @param name the name of the object to look up
140      * @return the object bound to <tt>name</tt>
141      * @throws NamingException if a naming exception is encountered
142      */

143     public Object JavaDoc lookup(String JavaDoc name) throws NamingException JavaDoc {
144         return lookup(new CompositeName JavaDoc(name));
145     }
146
147     /**
148      * Binds a name to an object.
149      * @param name the name to bind; may not be empty
150      * @param obj the object to bind; possibly null
151      * @throws NamingException if a naming exception is encountered
152      */

153     public void bind(Name JavaDoc name, Object JavaDoc obj) throws NamingException JavaDoc {
154         if (name.isEmpty()) {
155             throw new NamingException JavaDoc("Cannot bind empty name");
156         }
157         wrappedContext.bind(encode(name), wrapObject(obj, name, false));
158     }
159
160     /**
161      * Binds a name to an object.
162      * @param name the name to bind; may not be empty
163      * @param obj the object to bind; possibly null
164      * @throws NamingException if a naming exception is encountered
165      */

166     public void bind(String JavaDoc name, Object JavaDoc obj) throws NamingException JavaDoc {
167         bind(new CompositeName JavaDoc(name), obj);
168     }
169
170     /**
171      * Binds a name to an object, overwriting any existing binding. All
172      * intermediate contexts and the target context (that named by all but
173      * terminal atomic component of the name) must already exist.
174      * @param name the name to bind; may not be empty
175      * @param obj the object to bind; possibly null
176      * @throws NamingException if a naming exception is encountered
177      */

178     public void rebind(Name JavaDoc name, Object JavaDoc obj) throws NamingException JavaDoc {
179         if (name.isEmpty()) {
180             throw new NamingException JavaDoc("Cannot rebind empty name");
181         }
182         wrappedContext.rebind(encode(name), wrapObject(obj, name, true));
183     }
184
185     /**
186      * Binds a name to an object, overwriting any existing binding.
187      * @param name the name to bind; may not be empty
188      * @param obj the object to bind; possibly null
189      * @throws NamingException if a naming exception is encountered
190      */

191     public void rebind(String JavaDoc name, Object JavaDoc obj) throws NamingException JavaDoc {
192         rebind(new CompositeName JavaDoc(name), obj);
193     }
194
195     /**
196      * Unbinds the named object. Removes the terminal atomic name in
197      * <code>name</code> from the target context--that named by all but the
198      * terminal atomic part of <code>name</code>.
199      * @param name the name to unbind; may not be empty
200      * @throws NamingException if a naming exception is encountered
201      */

202     public void unbind(Name JavaDoc name) throws NamingException JavaDoc {
203         if (name.isEmpty()) {
204             throw new NamingException JavaDoc("Cannot unbind empty name");
205         }
206         try {
207             wrappedContext.unbind(encode(name));
208             if (exportedObjects.containsKey(name)) {
209                 ConfigurationRepository.getCurrentConfiguration().getProtocol().getPortableRemoteObject().unexportObject(
210                         (Remote JavaDoc) exportedObjects.remove(name));
211             }
212         } catch (Exception JavaDoc e) {
213             throw NamingExceptionHelper.create("Cannot unbind name '" + name + "' : " + e.getMessage(), e);
214         }
215     }
216
217     /**
218      * Unbinds the named object.
219      * @param name the name to unbind; may not be empty
220      * @throws NamingException if a naming exception is encountered
221      */

222     public void unbind(String JavaDoc name) throws NamingException JavaDoc {
223         unbind(new CompositeName JavaDoc(name));
224     }
225
226     /**
227      * Binds a new name to the object bound to an old name, and unbinds the old
228      * name. Both names are relative to this context. Any attributes associated
229      * with the old name become associated with the new name.
230      * @param oldName the name of the existing binding; may not be empty
231      * @param newName the name of the new binding; may not be empty
232      * @throws NamingException if a naming exception is encountered
233      */

234     public void rename(Name JavaDoc oldName, Name JavaDoc newName) throws NamingException JavaDoc {
235         if (exportedObjects.containsKey(oldName)) {
236             exportedObjects.put(newName, exportedObjects.remove(oldName));
237         }
238         wrappedContext.rename(encode(oldName), encode(newName));
239     }
240
241     /**
242      * Binds a new name to the object bound to an old name, and unbinds the old
243      * name.
244      * @param oldName the name of the existing binding; may not be empty
245      * @param newName the name of the new binding; may not be empty
246      * @throws NamingException if a naming exception is encountered
247      */

248     public void rename(String JavaDoc oldName, String JavaDoc newName) throws NamingException JavaDoc {
249         rename(new CompositeName JavaDoc(oldName), new CompositeName JavaDoc(newName));
250     }
251
252     /**
253      * Enumerates the names bound in the named context, along with the class
254      * names of objects bound to them. The contents of any subcontexts are not
255      * included.
256      * @param name the name of the context to list
257      * @return an enumeration of the names and class names of the bindings in
258      * this context. Each element of the enumeration is of type
259      * <tt>NameClassPair</tt>.
260      * @throws NamingException if a naming exception is encountered
261      */

262     public NamingEnumeration JavaDoc list(Name JavaDoc name) throws NamingException JavaDoc {
263         return new WrappedEnumeration(wrappedContext.list(encode(name)));
264     }
265
266     /**
267      * Enumerates the names bound in the named context, along with the class
268      * names of objects bound to them.
269      * @param name the name of the context to list
270      * @return an enumeration of the names and class names of the bindings in
271      * this context. Each element of the enumeration is of type
272      * <tt>NameClassPair</tt>.
273      * @throws NamingException if a naming exception is encountered
274      */

275     public NamingEnumeration JavaDoc list(String JavaDoc name) throws NamingException JavaDoc {
276         return list(new CompositeName JavaDoc(name));
277     }
278
279     /**
280      * Enumerates the names bound in the named context, along with the objects
281      * bound to them. The contents of any subcontexts are not included.
282      * @param name the name of the context to list
283      * @return an enumeration of the bindings in this context. Each element of
284      * the enumeration is of type <tt>Binding</tt>.
285      * @throws NamingException if a naming exception is encountered
286      */

287     public NamingEnumeration JavaDoc listBindings(Name JavaDoc name) throws NamingException JavaDoc {
288         return new WrappedEnumeration(wrappedContext.listBindings(encode(name)));
289     }
290
291     /**
292      * Enumerates the names bound in the named context, along with the objects
293      * bound to them.
294      * @param name the name of the context to list
295      * @return an enumeration of the bindings in this context. Each element of
296      * the enumeration is of type <tt>Binding</tt>.
297      * @throws NamingException if a naming exception is encountered
298      */

299     public NamingEnumeration JavaDoc listBindings(String JavaDoc name) throws NamingException JavaDoc {
300         return listBindings(new CompositeName JavaDoc(name));
301     }
302
303     /**
304      * Destroys the named context and removes it from the namespace. Any
305      * attributes associated with the name are also removed. Intermediate
306      * contexts are not destroyed.
307      * @param name the name of the context to be destroyed; may not be empty
308      * @throws NamingException if a naming exception is encountered
309      */

310     public void destroySubcontext(Name JavaDoc name) throws NamingException JavaDoc {
311         wrappedContext.destroySubcontext(encode(name));
312     }
313
314     /**
315      * Destroys the named context and removes it from the namespace.
316      * @param name the name of the context to be destroyed; may not be empty
317      * @throws NamingException if a naming exception is encountered
318      */

319     public void destroySubcontext(String JavaDoc name) throws NamingException JavaDoc {
320         destroySubcontext(new CompositeName JavaDoc(name));
321     }
322
323     /**
324      * Creates and binds a new context.
325      * @param name the name of the context to create; may not be empty
326      * @return the newly created context
327      * @throws NamingException if a naming exception is encountered
328      */

329     public Context JavaDoc createSubcontext(Name JavaDoc name) throws NamingException JavaDoc {
330         return wrappedContext.createSubcontext(encode(name));
331     }
332
333     /**
334      * Creates and binds a new context.
335      * @param name the name of the context to create; may not be empty
336      * @return the newly created context
337      * @throws NamingException if a naming exception is encountered
338      */

339     public Context JavaDoc createSubcontext(String JavaDoc name) throws NamingException JavaDoc {
340         return createSubcontext(new CompositeName JavaDoc(name));
341     }
342
343     /**
344      * Retrieves the named object, following links except for the terminal
345      * atomic component of the name.
346      * @param name the name of the object to look up
347      * @return the object bound to <tt>name</tt>, not following the terminal
348      * link (if any).
349      * @throws NamingException if a naming exception is encountered
350      */

351     public Object JavaDoc lookupLink(Name JavaDoc name) throws NamingException JavaDoc {
352         return wrappedContext.lookupLink(encode(name));
353     }
354
355     /**
356      * Retrieves the named object, following links except for the terminal
357      * atomic component of the name.
358      * @param name the name of the object to look up
359      * @return the object bound to <tt>name</tt>, not following the terminal
360      * link (if any)
361      * @throws NamingException if a naming exception is encountered
362      */

363     public Object JavaDoc lookupLink(String JavaDoc name) throws NamingException JavaDoc {
364         return lookupLink(new CompositeName JavaDoc(name));
365     }
366
367     /**
368      * Retrieves the parser associated with the named context.
369      * @param name the name of the context from which to get the parser
370      * @return a name parser that can parse compound names into their atomic
371      * components
372      * @throws NamingException if a naming exception is encountered
373      */

374     public NameParser JavaDoc getNameParser(Name JavaDoc name) throws NamingException JavaDoc {
375         return wrappedContext.getNameParser(encode(name));
376     }
377
378     /**
379      * Retrieves the parser associated with the named context.
380      * @param name the name of the context from which to get the parser
381      * @return a name parser that can parse compound names into their atomic
382      * components
383      * @throws NamingException if a naming exception is encountered
384      */

385     public NameParser JavaDoc getNameParser(String JavaDoc name) throws NamingException JavaDoc {
386         return getNameParser(new CompositeName JavaDoc(name));
387     }
388
389     /**
390      * Composes the name of this context with a name relative to this context.
391      * @param name a name relative to this context
392      * @param prefix the name of this context relative to one of its ancestors
393      * @return the composition of <code>prefix</code> and <code>name</code>
394      * @throws NamingException if a naming exception is encountered
395      */

396     public String JavaDoc composeName(String JavaDoc name, String JavaDoc prefix) throws NamingException JavaDoc {
397         return name;
398     }
399
400     /**
401      * Composes the name of this context with a name relative to this context.
402      * @param name a name relative to this context
403      * @param prefix the name of this context relative to one of its ancestors
404      * @return the composition of <code>prefix</code> and <code>name</code>
405      * @throws NamingException if a naming exception is encountered
406      */

407     public Name JavaDoc composeName(Name JavaDoc name, Name JavaDoc prefix) throws NamingException JavaDoc {
408         return (Name JavaDoc) name.clone();
409     }
410
411     /**
412      * Adds a new environment property to the environment of this context. If
413      * the property already exists, its value is overwritten. See class
414      * description for more details on environment properties.
415      * @param propName the name of the environment property to add; may not be
416      * null
417      * @param propVal the value of the property to add; may not be null
418      * @return the previous value of the property, or null if the property was
419      * not in the environment before
420      * @throws NamingException if a naming exception is encountered
421      */

422     public Object JavaDoc addToEnvironment(String JavaDoc propName, Object JavaDoc propVal) throws NamingException JavaDoc {
423         return wrappedContext.addToEnvironment(propName, propVal);
424     }
425
426     /**
427      * Removes an environment property from the environment of this context. See
428      * class description for more details on environment properties.
429      * @param propName the name of the environment property to remove; may not
430      * be null
431      * @return the previous value of the property, or null if the property was
432      * not in the environment
433      * @throws NamingException if a naming exception is encountered
434      */

435     public Object JavaDoc removeFromEnvironment(String JavaDoc propName) throws NamingException JavaDoc {
436         return wrappedContext.removeFromEnvironment(propName);
437     }
438
439     /**
440      * Retrieves the environment in effect for this context. See class
441      * description for more details on environment properties.
442      * @return the environment of this context; never null
443      * @throws NamingException if a naming exception is encountered
444      */

445     public Hashtable JavaDoc getEnvironment() throws NamingException JavaDoc {
446         return wrappedContext.getEnvironment();
447     }
448
449     /**
450      * Closes this context. This method releases this context's resources
451      * immediately, instead of waiting for them to be released automatically by
452      * the garbage collector.
453      * @throws NamingException if a naming exception is encountered
454      */

455     public void close() throws NamingException JavaDoc {
456         // do nothing for the moment
457
}
458
459     /**
460      * Retrieves the full name of this context within its own namespace.
461      * @return this context's name in its own namespace; never null
462      * @throws NamingException if a naming exception is encountered
463      */

464     public String JavaDoc getNameInNamespace() throws NamingException JavaDoc {
465         return wrappedContext.getNameInNamespace();
466     }
467
468     /**
469      * Adds a new object to the list of exported objects
470      * @param name JNDI name of the exported object
471      * @param o exported object
472      * @return Returns the wrapperHash.
473      */

474     protected Object JavaDoc addToExported(Name JavaDoc name, Object JavaDoc o) {
475         return exportedObjects.put(name, o);
476     }
477
478     /**
479      * @return the wrappedContext.
480      */

481     protected Context JavaDoc getWrappedContext() {
482         return wrappedContext;
483     }
484
485     /**
486      * Hide special characters from flat namespace registry. Escape forward and
487      * backward slashes, and leading quote character.
488      * @param initialName the name to encode
489      * @return the encoded name
490      */

491     protected Name JavaDoc encode(Name JavaDoc initialName) {
492         String JavaDoc name = initialName.toString();
493
494         // nothing to encode
495
if (name.length() < 1) {
496             return initialName;
497         }
498         // replace all / and \ by adding a \\ prefix
499
StringBuffer JavaDoc newname = new StringBuffer JavaDoc(name);
500         int i = 0;
501         while (i < newname.length()) {
502             char c = newname.charAt(i);
503             if (c == '/' || c == '\\') {
504                 newname.insert(i, '\\');
505                 i++;
506             }
507             i++;
508         }
509         // prefix quote characters
510
if (newname.charAt(0) == '"' || newname.charAt(0) == '\'') {
511             newname.insert(0, '\\');
512         }
513
514         // return encoded name
515
try {
516             return new CompositeName JavaDoc(newname.toString());
517         } catch (InvalidNameException JavaDoc e) {
518             return initialName;
519         }
520     }
521
522     /**
523      * undo what encode() does
524      * @param name to decode
525      * @return decoded String from the given encoding string
526      */

527     protected String JavaDoc decode(String JavaDoc name) {
528         StringBuffer JavaDoc newname = new StringBuffer JavaDoc(name);
529         // we have a quoted string : remove the enclosing quotes
530
if (newname.length() >= 2 && (newname.charAt(0) == '"' || newname.charAt(0) == '\'')
531                 && newname.charAt(0) == newname.charAt(newname.length() - 1)) {
532             newname.deleteCharAt(0);
533             newname.deleteCharAt(newname.length() - 1);
534         }
535         // nothing to decode, return it directly
536
if (name.indexOf('\\') < 0) {
537             return newname.toString();
538         }
539         // Remove all \\ prefix
540
int i = 0;
541         while (i < newname.length()) {
542             if (newname.charAt(i) == '\\') {
543                 newname.deleteCharAt(i);
544                 i++;
545                 continue;
546             }
547             i++;
548         }
549
550         return newname.toString();
551     }
552
553     /**
554      * This class is used to return a naming enumeration by decoding encoded
555      * names
556      */

557     protected class WrappedEnumeration implements NamingEnumeration JavaDoc {
558
559         /**
560          * The existing enumeration which contains encoded names to decode
561          */

562         private NamingEnumeration JavaDoc wrappedEnumeration;
563
564         /**
565          * Build a new enumeration on which we have to decode names
566          * @param wrappedEnumeration given enumeration
567          */

568         WrappedEnumeration(NamingEnumeration JavaDoc wrappedEnumeration) {
569             this.wrappedEnumeration = wrappedEnumeration;
570         }
571
572         /**
573          * Tests if this enumeration contains more elements.
574          * @return <code>true</code> if and only if this enumeration object
575          * contains at least one more element to provide;
576          * <code>false</code> otherwise.
577          */

578         public boolean hasMoreElements() {
579             return wrappedEnumeration.hasMoreElements();
580         }
581
582         /**
583          * Determines whether there are any more elements in the enumeration.
584          * This method allows naming exceptions encountered while determining
585          * whether there are more elements to be caught and handled by the
586          * application.
587          * @return true if there is more in the enumeration ; false otherwise.
588          * @throws NamingException If a naming exception is encountered while
589          * attempting to determine whether there is another element in
590          * the enumeration.
591          */

592         public boolean hasMore() throws NamingException JavaDoc {
593             return hasMoreElements();
594         }
595
596         /**
597          * Returns the next element of this enumeration if this enumeration
598          * object has at least one more element to provide.
599          * @return the next element of this enumeration.
600          */

601         public Object JavaDoc nextElement() {
602             javax.naming.NameClassPair JavaDoc ncp;
603             ncp = (javax.naming.NameClassPair JavaDoc) wrappedEnumeration.nextElement();
604             ncp.setName(decode(ncp.getName()));
605             return ncp;
606         }
607
608         /**
609          * Retrieves the next element in the enumeration.
610          * @return the next element in the enumeration.
611          * @see java.util.Enumeration#nextElement
612          */

613         public Object JavaDoc next() {
614             return nextElement();
615         }
616
617         /**
618          * Closes this enumeration.
619          * @throws NamingException If a naming exception is encountered while
620          * closing the enumeration.
621          */

622         public void close() throws NamingException JavaDoc {
623             wrappedEnumeration = null;
624         }
625     }
626 }
627
Popular Tags