KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > winstone > jndi > WinstoneContext


1 /*
2  * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
3  * Distributed under the terms of either:
4  * - the common development and distribution license (CDDL), v1.0; or
5  * - the GNU Lesser General Public License, v2.1 or later
6  */

7 package winstone.jndi;
8
9 import java.util.ArrayList JavaDoc;
10 import java.util.Hashtable JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.List JavaDoc;
13 import java.util.Map JavaDoc;
14
15 import javax.naming.CompositeName JavaDoc;
16 import javax.naming.Context JavaDoc;
17 import javax.naming.Name JavaDoc;
18 import javax.naming.NameNotFoundException JavaDoc;
19 import javax.naming.NameParser JavaDoc;
20 import javax.naming.NamingEnumeration JavaDoc;
21 import javax.naming.NamingException JavaDoc;
22 import javax.naming.NotContextException JavaDoc;
23 import javax.naming.OperationNotSupportedException JavaDoc;
24 import javax.naming.spi.NamingManager JavaDoc;
25
26 import winstone.Logger;
27
28 /**
29  * The main jndi context implementation class.
30  *
31  * @author <a HREF="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
32  * @version $Id: WinstoneContext.java,v 1.3 2006/02/28 07:32:48 rickknowles Exp $
33  */

34 public class WinstoneContext implements Context JavaDoc {
35     static final String JavaDoc PREFIX = "java:";
36     static final String JavaDoc FIRST_CHILD = "comp";
37     static final String JavaDoc BODGED_PREFIX = "java:comp";
38     
39     private Hashtable JavaDoc environment;
40     private Hashtable JavaDoc bindings;
41     private final static NameParser JavaDoc nameParser = new WinstoneNameParser();
42     private WinstoneContext parent;
43     private String JavaDoc myAbsoluteName;
44     private Object JavaDoc contextLock;
45
46     /**
47      * Constructor - sets up environment
48      */

49     public WinstoneContext(Map JavaDoc sourceEnvironment, WinstoneContext parent,
50             String JavaDoc absoluteName, Object JavaDoc contextLock) throws NamingException JavaDoc {
51         this.environment = new Hashtable JavaDoc();
52         List JavaDoc sourceKeys = new ArrayList JavaDoc(sourceEnvironment.keySet());
53         for (Iterator JavaDoc i = sourceKeys.iterator(); i.hasNext();) {
54             String JavaDoc key = (String JavaDoc) i.next();
55             addToEnvironment(key, sourceEnvironment.get(key));
56         }
57         this.parent = parent;
58         this.myAbsoluteName = absoluteName;
59         this.contextLock = contextLock;
60         this.bindings = new Hashtable JavaDoc();
61         Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES,
62                 "WinstoneContext.Initialised", this.myAbsoluteName);
63     }
64
65     /**
66      * Constructor - sets up environment and copies the bindings across
67      */

68     protected WinstoneContext(Map JavaDoc sourceEnvironment, WinstoneContext parent,
69             String JavaDoc absoluteName, Object JavaDoc contextLock, Hashtable JavaDoc bindings) throws NamingException JavaDoc {
70         this.environment = new Hashtable JavaDoc();
71         List JavaDoc sourceKeys = new ArrayList JavaDoc(sourceEnvironment.keySet());
72         for (Iterator JavaDoc i = sourceKeys.iterator(); i.hasNext();) {
73             String JavaDoc key = (String JavaDoc) i.next();
74             addToEnvironment(key, sourceEnvironment.get(key));
75         }
76         this.parent = parent;
77         this.myAbsoluteName = absoluteName;
78         this.contextLock = contextLock;
79         this.bindings = bindings;
80         Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES,
81                 "WinstoneContext.Copied", this.myAbsoluteName);
82     }
83
84     public void close() throws NamingException JavaDoc {
85     }
86
87     public Hashtable JavaDoc getEnvironment() throws NamingException JavaDoc {
88         return new Hashtable JavaDoc(this.environment);
89     }
90
91     public Object JavaDoc removeFromEnvironment(String JavaDoc property) throws NamingException JavaDoc {
92         return this.environment.remove(property);
93     }
94
95     public Object JavaDoc addToEnvironment(String JavaDoc property, Object JavaDoc value)
96             throws NamingException JavaDoc {
97         return this.environment.put(property, value);
98     }
99
100     /**
101      * Handles the processing of relative and absolute names. If a relative name
102      * is detected, it is processed by the name parser. If an absolute name is
103      * detected, it determines first if the absolute name refers to this
104      * context. If not, it then determines whether the request can be passed
105      * back to the parent or not, and returns null if it can, and throws an
106      * exception otherwise.
107      */

108     protected Name JavaDoc validateName(Name JavaDoc name) throws NamingException JavaDoc {
109         // Check for absolute urls and redirect or correct
110
if (name.isEmpty())
111             return name;
112         else if (name.get(0).equals(BODGED_PREFIX)) {
113             Name JavaDoc newName = name.getSuffix(1).add(0, FIRST_CHILD).add(0, PREFIX);
114             return validateName(newName);
115         } else if (name.get(0).equals(PREFIX)) {
116             String JavaDoc stringName = name.toString();
117             if (stringName.equals(this.myAbsoluteName))
118                 return nameParser.parse("");
119             else if (stringName.startsWith(this.myAbsoluteName))
120                 return nameParser.parse(stringName
121                         .substring(this.myAbsoluteName.length() + 1));
122             else if (this.parent != null)
123                 return null;
124             else
125                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
126                         "WinstoneContext.NameNotFound", name.toString()));
127         } else if (name instanceof CompositeName JavaDoc)
128             return nameParser.parse(name.toString());
129         else
130             return name;
131     }
132
133     /**
134      * Lookup an object in the context. Returns a copy of this context if the
135      * name is empty, or the specified resource (if we have it). If the name is
136      * unknown, throws a NameNotFoundException.
137      */

138     public Object JavaDoc lookup(Name JavaDoc name) throws NamingException JavaDoc {
139         Name JavaDoc searchName = validateName(name);
140
141         // If null, it means we don't know how to handle this -> throw to the
142
// parent
143
if (searchName == null)
144             return this.parent.lookup(name);
145         // If empty name, return a copy of this Context
146
else if (searchName.isEmpty())
147             return new WinstoneContext(this.environment, this.parent,
148                     this.myAbsoluteName, this.contextLock, this.bindings);
149
150         String JavaDoc thisName = searchName.get(0);
151         synchronized (this.contextLock) {
152             Object JavaDoc thisValue = bindings.get(thisName);
153
154             // If the name points to something in this level, try to find it,
155
// and give
156
// an error if not available
157
if (searchName.size() == 1) {
158                 if (thisValue == null)
159                     throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
160                             "WinstoneContext.NameNotFound", name.toString()));
161
162                 try {
163                     return NamingManager.getObjectInstance(thisValue,
164                             new CompositeName JavaDoc().add(thisName), this,
165                             this.environment);
166                 } catch (Exception JavaDoc e) {
167                     NamingException JavaDoc ne = new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES
168                             .getString("WinstoneContext.FailedToGetInstance"));
169                     ne.setRootCause(e);
170                     throw ne;
171                 }
172             }
173
174             else if (thisValue == null)
175                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
176                         "WinstoneContext.NameNotFound", thisName.toString()));
177
178             // If it's not in this level and what we found is not a context,
179
// complain
180
else if (!(thisValue instanceof Context JavaDoc))
181                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
182                         "WinstoneContext.NotContext", new String JavaDoc[] {
183                                 thisName.toString(),
184                                 thisValue.getClass().getName() }));
185
186             // Open the context, perform a lookup, then close the context we
187
// opened
188
else
189                 try {
190                     return ((Context JavaDoc) thisValue)
191                             .lookup(searchName.getSuffix(1));
192                 } finally {
193                     ((Context JavaDoc) thisValue).close();
194                 }
195         }
196     }
197
198     public Object JavaDoc lookup(String JavaDoc name) throws NamingException JavaDoc {
199         return lookup(new CompositeName JavaDoc(name));
200     }
201
202     public Object JavaDoc lookupLink(Name JavaDoc name) throws NamingException JavaDoc {
203         Logger.log(Logger.WARNING, ContainerJNDIManager.JNDI_RESOURCES,
204                 "WinstoneContext.LinkRefUnsupported");
205         return lookup(name);
206     }
207
208     public Object JavaDoc lookupLink(String JavaDoc name) throws NamingException JavaDoc {
209         return lookupLink(new CompositeName JavaDoc(name));
210     }
211
212     /**
213      * Returns a list of objects bound to the context
214      */

215     public NamingEnumeration JavaDoc list(Name JavaDoc name) throws NamingException JavaDoc {
216         Name JavaDoc searchName = validateName(name);
217
218         // If null, it means we don't know how to handle this -> throw to the
219
// parent
220
if (searchName == null)
221             return this.parent.list(name);
222         // If empty name, return a copy of this Context
223
else if (searchName.isEmpty()) {
224             NamingEnumeration JavaDoc e = null;
225             synchronized (this.contextLock) {
226                 e = new WinstoneNameEnumeration(this.bindings);
227             }
228             return e;
229         }
230
231         // Lookup the object - if it's not a context, throw an error
232
else {
233             Object JavaDoc ctx = this.lookup(searchName);
234             if (ctx instanceof Context JavaDoc)
235                 try {
236                     return ((Context JavaDoc) ctx).list(new CompositeName JavaDoc(""));
237                 } finally {
238                     ((Context JavaDoc) ctx).close();
239                 }
240             else if (ctx == null)
241                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
242                         "WinstoneContext.NameNotFound", searchName.toString()));
243             else
244                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
245                         "WinstoneContext.NotContext",
246                         new String JavaDoc[] { searchName.toString(),
247                                 ctx.getClass().getName() }));
248         }
249     }
250
251     public NamingEnumeration JavaDoc list(String JavaDoc name) throws NamingException JavaDoc {
252         return list(new CompositeName JavaDoc(name));
253     }
254
255     public NamingEnumeration JavaDoc listBindings(Name JavaDoc name) throws NamingException JavaDoc {
256         Name JavaDoc searchName = validateName(name);
257
258         // If null, it means we don't know how to handle this -> throw to the
259
// parent
260
if (searchName == null)
261             return this.parent.list(name);
262         // If empty name, return a copy of this Context
263
else if (searchName.isEmpty()) {
264             NamingEnumeration JavaDoc e = null;
265             synchronized (this.contextLock) {
266                 e = new WinstoneBindingEnumeration(this.bindings,
267                         this.environment, this);
268             }
269             return e;
270         }
271
272         // Lookup the object - if it's not a context, throw an error
273
else {
274             Object JavaDoc ctx = this.lookup(searchName);
275             if (ctx instanceof Context JavaDoc)
276                 try {
277                     return ((Context JavaDoc) ctx).listBindings(new CompositeName JavaDoc(""));
278                 } finally {
279                     ((Context JavaDoc) ctx).close();
280                 }
281             else if (ctx == null)
282                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
283                         "WinstoneContext.NameNotFound", searchName.toString()));
284             else
285                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
286                         "WinstoneContext.NotContext",
287                         new String JavaDoc[] { searchName.toString(),
288                                 ctx.getClass().getName() }));
289         }
290     }
291
292     public NamingEnumeration JavaDoc listBindings(String JavaDoc name) throws NamingException JavaDoc {
293         return listBindings(new CompositeName JavaDoc(name));
294     }
295
296     public NameParser JavaDoc getNameParser(Name JavaDoc name) throws NamingException JavaDoc {
297         Object JavaDoc obj = lookup(name);
298         if (obj instanceof Context JavaDoc) {
299             ((Context JavaDoc) obj).close();
300         }
301         return nameParser;
302     }
303
304     public NameParser JavaDoc getNameParser(String JavaDoc name) throws NamingException JavaDoc {
305         return getNameParser(new CompositeName JavaDoc(name));
306     }
307
308     public String JavaDoc getNameInNamespace() throws NamingException JavaDoc {
309         return this.myAbsoluteName;
310     }
311
312     /***************************************************************************
313      * Below here is for read-write contexts ... *
314      **************************************************************************/

315
316     public void bind(String JavaDoc name, Object JavaDoc value) throws NamingException JavaDoc {
317         bind(new CompositeName JavaDoc(name), value);
318     }
319
320     public void bind(Name JavaDoc name, Object JavaDoc value) throws NamingException JavaDoc {
321         bind(name, value, false);
322     }
323
324     protected void bind(Name JavaDoc name, Object JavaDoc value, boolean allowOverwrites)
325             throws NamingException JavaDoc {
326         Name JavaDoc bindName = validateName(name);
327
328         // If null, it means we don't know how to handle this -> throw to the
329
// parent
330
if (bindName == null)
331             this.parent.bind(name, value, allowOverwrites);
332         // If empty name, complain - we should have a child name here
333
else if (bindName.isEmpty())
334             throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
335                     "WinstoneContext.AlreadyExists", name.toString()));
336         else if (bindName.size() > 1) {
337             Object JavaDoc ctx = lookup(bindName.get(0));
338             if (!(ctx instanceof Context JavaDoc))
339                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
340                         "WinstoneContext.NotContext", new String JavaDoc[] {
341                                 bindName.get(0), ctx.getClass().getName() }));
342             else if (ctx == null)
343                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
344                         "WinstoneContext.NameNotFound", bindName.get(0)));
345             else
346                 try {
347                     if (allowOverwrites)
348                         ((Context JavaDoc) ctx).rebind(bindName.getSuffix(1), value);
349                     else
350                         ((Context JavaDoc) ctx).bind(bindName.getSuffix(1), value);
351                 } finally {
352                     ((Context JavaDoc) ctx).close();
353                 }
354         } else if ((!allowOverwrites) && this.bindings.get(name.get(0)) != null)
355             throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
356                     "WinstoneContext.AlreadyExists", name.toString()));
357         else {
358             value = NamingManager.getStateToBind(value, new CompositeName JavaDoc()
359                     .add(bindName.get(0)), this, this.environment);
360             synchronized (this.contextLock) {
361                 this.bindings.put(bindName.get(0), value);
362             }
363         }
364     }
365
366     public void rebind(String JavaDoc name, Object JavaDoc value) throws NamingException JavaDoc {
367         rebind(new CompositeName JavaDoc(name), value);
368     }
369
370     public void rebind(Name JavaDoc name, Object JavaDoc value) throws NamingException JavaDoc {
371         bind(name, value, true);
372     }
373
374     public void unbind(String JavaDoc name) throws NamingException JavaDoc {
375         unbind(new CompositeName JavaDoc(name));
376     }
377
378     public void unbind(Name JavaDoc name) throws NamingException JavaDoc {
379         Name JavaDoc unbindName = validateName(name);
380
381         // If null, it means we don't know how to handle this -> throw to the
382
// parent
383
if (unbindName == null)
384             this.parent.unbind(name);
385         // If empty name, complain - we should have a child name here
386
else if (unbindName.isEmpty())
387             throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES
388                     .getString("WinstoneContext.CantUnbindEmptyName"));
389         else if (unbindName.size() > 1) {
390             Object JavaDoc ctx = lookup(unbindName.get(0));
391             if (!(ctx instanceof Context JavaDoc))
392                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
393                         "WinstoneContext.NotContext", new String JavaDoc[] {
394                                 unbindName.get(0), ctx.getClass().getName() }));
395             else if (ctx == null)
396                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
397                         "WinstoneContext.NameNotFound", unbindName.get(0)));
398             else
399                 try {
400                     ((Context JavaDoc) ctx).unbind(unbindName.getSuffix(1));
401                 } finally {
402                     ((Context JavaDoc) ctx).close();
403                 }
404         } else if (this.bindings.get(name.get(0)) == null)
405             throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
406                     "WinstoneContext.NameNotFound", name.toString()));
407         else {
408             synchronized (this.contextLock) {
409                 // Object removing = this.bindings.get(unbindName.get(0));
410
this.bindings.remove(unbindName.get(0));
411             }
412         }
413     }
414
415     public void rename(Name JavaDoc oldName, Name JavaDoc newName) throws NamingException JavaDoc {
416         throw new OperationNotSupportedException JavaDoc(
417                 "rename not supported in Winstone java:/ context");
418     }
419
420     public void rename(String JavaDoc oldName, String JavaDoc newName) throws NamingException JavaDoc {
421         rename(new CompositeName JavaDoc(oldName), new CompositeName JavaDoc(newName));
422     }
423
424     public Context JavaDoc createSubcontext(String JavaDoc name) throws NamingException JavaDoc {
425         return createSubcontext(new CompositeName JavaDoc(name));
426     }
427
428     public Context JavaDoc createSubcontext(Name JavaDoc name) throws NamingException JavaDoc {
429         Name JavaDoc childName = validateName(name);
430
431         // If null, it means we don't know how to handle this -> throw to the
432
// parent
433
if (childName == null)
434             return this.parent.createSubcontext(name);
435         // If empty name, complain - we should have a child name here
436
else if (childName.isEmpty())
437             throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
438                     "WinstoneContext.AlreadyExists", name.toString()));
439         else if (childName.size() > 1) {
440             Object JavaDoc ctx = lookup(childName.get(0));
441             if (!(ctx instanceof Context JavaDoc))
442                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
443                         "WinstoneContext.NotContext", new String JavaDoc[] {
444                                 childName.get(0), ctx.getClass().getName() }));
445             else if (ctx == null)
446                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
447                         "WinstoneContext.NameNotFound", childName.get(0)));
448             else
449                 try {
450                     ((Context JavaDoc) ctx).createSubcontext(childName.getSuffix(1));
451                 } finally {
452                     ((Context JavaDoc) ctx).close();
453                 }
454         }
455
456         Context JavaDoc childContext = null;
457         synchronized (this.contextLock) {
458             if (this.bindings.get(childName.get(0)) != null)
459                 throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
460                         "WinstoneContext.AlreadyExists", childName.get(0)));
461             else {
462                 childContext = new WinstoneContext(this.environment, this,
463                         this.myAbsoluteName + "/" + childName.get(0),
464                         new Boolean JavaDoc(true));
465                 this.bindings.put(childName.get(0), childContext);
466             }
467         }
468         return childContext;
469     }
470
471     public void destroySubcontext(String JavaDoc name) throws NamingException JavaDoc {
472         destroySubcontext(new CompositeName JavaDoc(name));
473     }
474
475     public void destroySubcontext(Name JavaDoc name) throws NamingException JavaDoc {
476         Name JavaDoc childName = validateName(name);
477
478         // If null, it means we don't know how to handle this -> throw to the parent
479
if (childName == null)
480             this.parent.destroySubcontext(name);
481         // If absolutely referring to this context, tell the parent to delete this context
482
else if (childName.isEmpty()) {
483             if (!name.isEmpty())
484                 this.parent.destroySubcontext(name.getSuffix(name.size() - 2));
485             else
486                 throw new NamingException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES
487                         .getString("WinstoneContext.CantDestroyEmptyName"));
488         } else if (childName.size() > 1) {
489             Object JavaDoc ctx = lookup(childName.get(0));
490             if (!(ctx instanceof Context JavaDoc))
491                 throw new NotContextException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
492                         "WinstoneContext.NotContext", new String JavaDoc[] {
493                                 childName.get(0), ctx.getClass().getName() }));
494             else if (ctx == null)
495                 throw new NameNotFoundException JavaDoc(ContainerJNDIManager.JNDI_RESOURCES.getString(
496                         "WinstoneContext.NameNotFound", childName.get(0)));
497             else
498                 try {
499                     ((Context JavaDoc) ctx).destroySubcontext(childName.getSuffix(1));
500                 } finally {
501                     ((Context JavaDoc) ctx).close();
502                 }
503         } else
504             synchronized (this.contextLock) {
505                 Context JavaDoc childContext = (Context JavaDoc) lookup(childName.get(0));
506                 childContext.close();
507                 this.bindings.remove(childName.get(0));
508             }
509     }
510
511     public String JavaDoc composeName(String JavaDoc name1, String JavaDoc name2)
512             throws NamingException JavaDoc {
513         Name JavaDoc name = composeName(new CompositeName JavaDoc(name1), new CompositeName JavaDoc(
514                 name2));
515         return name == null ? null : name.toString();
516     }
517
518     public Name JavaDoc composeName(Name JavaDoc name1, Name JavaDoc name2) throws NamingException JavaDoc {
519         throw new OperationNotSupportedException JavaDoc(
520                 "composeName not supported in Winstone java:/ namespace");
521     }
522 }
523
Popular Tags