KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > naming > ContextImpl


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.naming;
31
32 import com.caucho.log.Log;
33 import com.caucho.util.L10N;
34
35 import javax.naming.*;
36 import javax.naming.spi.NamingManager JavaDoc;
37 import java.util.Hashtable JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.logging.Level JavaDoc;
40 import java.util.logging.Logger JavaDoc;
41
42 /**
43  * Resin's implementation of the JNDI <code>Context</code>. The actual storage
44  * of the persistent data is in the <code>AbstractModel</code>.
45  *
46  * <p>The <code>ContextImpl</code> is just a Visitor around
47  * the <code>AbstractModel</code> which also encapsulate
48  * the JNDI environment.
49  *
50  * <p>In JNDI, each <code>Context</code> is a &lt;model, env> pair.
51  * Each client might pass a different environment
52  * to the <code>InitialContext</code> so each <code>ContextImpl</code>
53  * must be unique for each client. (Granted, this is a bit wasteful of
54  * space which is why JNDI values should be cached.)
55  *
56  * <p>Applications which want a different model can still use
57  * <code>ContextImpl</code> and specify the root
58  * object for <code>AbstractModel</code>. <code>ContextImpl</code> will
59  * take care of the JNDI API for the model.
60  */

61 public class ContextImpl implements Context {
62   protected static final Logger JavaDoc dbg = Log.open(ContextImpl.class);
63   protected static final L10N L = new L10N(ContextImpl.class);
64
65   protected Hashtable JavaDoc _env;
66   protected AbstractModel _model;
67   protected String JavaDoc _name;
68
69   /**
70    * Creates a <code>ContextImpl</code>.
71    *
72    * @param model The underlying storage node.
73    * @param env The client's JNDI environment.
74    */

75   public ContextImpl(AbstractModel model, Hashtable JavaDoc env)
76   {
77     _model = model;
78     _env = env;
79     _name = "";
80
81     if (_model == null)
82       throw new NullPointerException JavaDoc();
83   }
84
85   /**
86    * Creates a <code>ContextImpl</code>.
87    *
88    * @param name JNDI name, used for error messages, etc.
89    * @param model The underlying storage node.
90    * @param env The client's JNDI environment.
91    */

92   public ContextImpl(String JavaDoc name, AbstractModel model, Hashtable JavaDoc env)
93   {
94     _model = model;
95     _env = env;
96     _name = name;
97
98     if (_model == null)
99       throw new NullPointerException JavaDoc();
100   }
101
102   /**
103    * Creates a new instance of the <code>ContextImpl</code>. Subclasses will
104    * override this method to return a new instance of the subclass.
105    *
106    * @param name the JNDI name for the new context
107    * @param model the underlying storage node
108    * @param env the client's JNDI environment.
109    *
110    * @return a new instance of the implementing class.
111    */

112   protected ContextImpl create(String JavaDoc name, AbstractModel model, Hashtable JavaDoc env)
113   {
114     return new ContextImpl(name, model, env);
115   }
116
117   /**
118    * Creates a new <code>ContextImpl</code> when the name is irrelevant.
119    *
120    * @param model the underlying storage node
121    * @param env the client's JNDI environment.
122    *
123    * @return a new instance of the implementing class.
124    */

125   final protected ContextImpl create(AbstractModel model, Hashtable JavaDoc env)
126   {
127     return create("", model, env);
128   }
129
130   /**
131    * Returns the underlying storage node.
132    */

133   public AbstractModel getModel()
134   {
135     return _model;
136   }
137
138   /**
139    * Returns the name.
140    */

141   public String JavaDoc getName()
142   {
143     return _name;
144   }
145
146   /**
147    * Looks up an object using its full string name. The path is searched
148    * recursively. <code>parseFirst</code> returns the first segment. The
149    *
150    * @param name the JNDI name to lookup for the child.
151    *
152    * @return the retrieved object
153    */

154   public Object JavaDoc lookup(String JavaDoc name)
155     throws NamingException
156   {
157     Object JavaDoc value = lookupImpl(name);
158
159     // server/1509
160
if (value != null)
161       return value;
162     else
163       throw new NameNotFoundException(getFullPath(name));
164   }
165
166   /**
167    * Looks up an object using its full string name. The path is searched
168    * recursively. <code>parseFirst</code> returns the first segment. The
169    *
170    * @param name the JNDI name to lookup for the child.
171    *
172    * @return the retrieved object
173    */

174   protected Object JavaDoc lookupImpl(String JavaDoc name)
175     throws NamingException
176   {
177     String JavaDoc tail = name;
178     AbstractModel model = _model;
179
180     while (tail != null) {
181       String JavaDoc first = parseFirst(tail);
182       String JavaDoc rest = parseRest(tail);
183
184       if (first == null)
185         return create(getFullPath(name), model, _env);
186
187       Object JavaDoc value = model.lookup(first);
188
189       if (value instanceof AbstractModel) {
190         model = (AbstractModel) value;
191         tail = rest;
192         continue;
193       }
194
195       value = dereference(value, null, model);
196
197       if (rest == null)
198         return value;
199       else if (value instanceof Context)
200         return ((Context) value).lookup(rest);
201       else if (value != null)
202         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
203                                           getFullPath(name), value));
204       else
205         throw new NameNotFoundException(getFullPath(name));
206     }
207
208     return create(getFullPath(name), model, _env);
209   }
210
211   /**
212    * Looks up an object with the given parsed JNDI name.
213    */

214   public Object JavaDoc lookup(Name name)
215     throws NamingException
216   {
217     if (dbg.isLoggable(Level.FINEST))
218       dbg.finest(L.l("JNDI lookup `{0}'", name));
219     
220     if (name == null)
221       return create(_model, _env);
222
223     AbstractModel model = _model;
224
225     for (int i = 0; i < name.size(); i++) {
226       String JavaDoc first = name.get(i);
227
228       Object JavaDoc value = model.lookup(first);
229
230       if (value instanceof AbstractModel) {
231         model = (AbstractModel) value;
232         continue;
233       }
234
235       value = dereference(value, null, model);
236
237       if (i + 1 == name.size())
238         return value;
239       else if (value instanceof Context)
240         return ((Context) value).lookup(name.getSuffix(i + 1));
241       else if (value != null)
242         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
243                                           getFullPath(name), value));
244       else
245         throw new NameNotFoundException(getFullPath(name));
246     }
247
248     return create(getFullPath(name), model, _env);
249   }
250
251   /**
252    * Looks up an object given the name, but doesn't dereference links.
253    */

254   public Object JavaDoc lookupLink(String JavaDoc name)
255     throws NamingException
256   {
257     String JavaDoc tail = name;
258     AbstractModel model = _model;
259
260     while (tail != null) {
261       String JavaDoc first = parseFirst(tail);
262       String JavaDoc rest = parseRest(tail);
263
264       if (first == null)
265         return create(getFullPath(name), model, _env);
266
267       Object JavaDoc value = model.lookup(first);
268
269       if (value instanceof AbstractModel) {
270         model = (AbstractModel) value;
271         tail = rest;
272         continue;
273       }
274
275       if (rest == null)
276         return value;
277
278       value = dereference(value, null, model);
279
280       if (value instanceof Context)
281         return ((Context) value).lookupLink(rest);
282       else if (value != null)
283         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
284                                           getFullPath(name), value));
285       else
286         throw new NameNotFoundException(getFullPath(name));
287     }
288
289     return create(getFullPath(name), model, _env);
290   }
291
292   /**
293    * Looks up an object with the given parsed JNDI name, but don't
294    * dereference the final object.
295    */

296   public Object JavaDoc lookupLink(Name name)
297     throws NamingException
298   {
299     if (name == null)
300       return create(_model, _env);
301     
302     AbstractModel model = _model;
303
304     for (int i = 0; i < name.size(); i++) {
305       String JavaDoc first = name.get(i);
306
307       Object JavaDoc value = model.lookup(first);
308
309       if (value instanceof AbstractModel) {
310         model = (AbstractModel) value;
311         continue;
312       }
313
314       if (i + 1 == name.size())
315         return value;
316       
317       value = dereference(value, null, model);
318
319       if (value instanceof Context)
320         return ((Context) value).lookupLink(name.getSuffix(i + 1));
321       else if (value != null)
322         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
323                                           getFullPath(name), value));
324       else
325         throw new NameNotFoundException(getFullPath(name));
326     }
327
328     return create(getFullPath(name), model, _env);
329   }
330
331   /**
332    * Binds an object to the context.
333    */

334   public void bind(String JavaDoc name, Object JavaDoc obj)
335     throws NamingException
336   {
337     String JavaDoc tail = name;
338     AbstractModel model = _model;
339
340     while (true) {
341       String JavaDoc first = parseFirst(tail);
342       String JavaDoc rest = parseRest(tail);
343       
344       if (first == null)
345         throw new NamingException(L.l("can't bind root"));
346
347       if (rest == null) {
348         Object JavaDoc value = model.lookup(first);
349         if (value != null)
350           throw new NamingException(L.l("`{0}' is already bound to `{1}'",
351                                         name, value));
352
353         model.bind(first, getReference(model, obj));
354         return;
355       }
356
357       Object JavaDoc value = model.lookup(first);
358
359       if (value instanceof AbstractModel) {
360         model = (AbstractModel) value;
361         tail = rest;
362         continue;
363       }
364       
365       value = dereference(value, null, model);
366
367       if (value instanceof Context) {
368         ((Context) value).bind(rest, obj);
369         return;
370       }
371       else if (value != null)
372         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
373                                           getFullPath(name), value));
374       else
375         throw new NameNotFoundException(getFullPath(name));
376     }
377   }
378   
379   /**
380    * Binds an object to the context.
381    */

382   public void bind(Name name, Object JavaDoc obj)
383     throws NamingException
384   {
385     if (dbg.isLoggable(Level.FINEST))
386       dbg.finest(L.l("JNDI bind `{0}'", name));
387     
388     if (name.size() == 0)
389       throw new NamingException(L.l("can't bind root"));
390       
391     AbstractModel model = _model;
392
393     int i = 0;
394     for (; i + 1 < name.size(); i++) {
395       String JavaDoc first = name.get(i);
396
397       Object JavaDoc value = model.lookup(first);
398
399       if (value instanceof AbstractModel) {
400         model = (AbstractModel) value;
401         continue;
402       }
403
404       value = dereference(value, null, model);
405
406       if (value instanceof Context) {
407         ((Context) value).bind(name.getSuffix(i + 1), obj);
408         return;
409       }
410       else if (value != null)
411         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
412                                           getFullPath(name), value));
413       else
414         throw new NameNotFoundException(getFullPath(name));
415     }
416
417     String JavaDoc first = name.get(i);
418     
419     Object JavaDoc value = model.lookup(first);
420     if (value != null)
421       throw new NamingException(L.l("`{0}' is already bound to `{1}'",
422                                     name, value));
423
424     model.bind(first, getReference(model, obj));
425   }
426
427   /**
428    * Binds an object to the context, overriding any old value.
429    *
430    * @param name the name to bind
431    * @param obj the object to bind
432    */

433   public void rebind(String JavaDoc name, Object JavaDoc obj)
434     throws NamingException
435   {
436     if (dbg.isLoggable(Level.FINEST))
437       dbg.finest(L.l("JNDI rebind `{0}' value: {1}", name, obj));
438     
439     String JavaDoc tail = name;
440     AbstractModel model = _model;
441
442     while (true) {
443       String JavaDoc first = parseFirst(tail);
444       String JavaDoc rest = parseRest(tail);
445
446       if (first == null)
447         throw new NamingException(L.l("can't bind root"));
448
449       if (rest == null) {
450         model.bind(first, getReference(model, obj));
451         return;
452       }
453
454       Object JavaDoc value = model.lookup(first);
455
456       if (value instanceof AbstractModel) {
457         model = (AbstractModel) value;
458         tail = rest;
459         continue;
460       }
461
462       value = dereference(value, null, model);
463
464       if (value instanceof Context) {
465         ((Context) value).rebind(rest, obj);
466         return;
467       }
468       else if (value != null)
469         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
470                                           getFullPath(name), value));
471       else
472         throw new NameNotFoundException(getFullPath(name));
473     }
474   }
475   
476   public void rebind(Name name, Object JavaDoc obj)
477     throws NamingException
478   {
479     if (name.size() == 0)
480       throw new NamingException(L.l("can't bind root"));
481       
482     AbstractModel model = _model;
483
484     int i = 0;
485     for (; i + 1 < name.size(); i++) {
486       String JavaDoc first = name.get(i);
487
488       Object JavaDoc value = model.lookup(first);
489
490       if (value instanceof AbstractModel) {
491         model = (AbstractModel) value;
492         continue;
493       }
494
495       value = dereference(value, null, model);
496
497       if (value instanceof Context) {
498         ((Context) value).bind(name.getSuffix(i + 1), obj);
499         return;
500       }
501       else if (value != null)
502         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
503                                           getFullPath(name), value));
504       else
505         throw new NameNotFoundException(getFullPath(name));
506     }
507
508     String JavaDoc first = name.get(i);
509     
510     model.bind(first, getReference(model, obj));
511   }
512
513   private Object JavaDoc getReference(AbstractModel model, Object JavaDoc obj)
514   {
515     return obj;
516   }
517
518   /**
519    * Unbinds an object from the context.
520    *
521    * @param name the name to unbind
522    */

523   public void unbind(String JavaDoc name)
524     throws NamingException
525   {
526     String JavaDoc tail = name;
527     AbstractModel model = _model;
528
529     while (true) {
530       String JavaDoc first = parseFirst(tail);
531       String JavaDoc rest = parseRest(tail);
532       
533       if (first == null)
534         throw new NamingException(L.l("can't unbind root"));
535
536       if (rest == null) {
537         if (model.lookup(name) instanceof AbstractModel)
538           throw new NamingException(L.l("can't unbind subcontext; use destroySubcontext"));
539           
540         model.unbind(first);
541         return;
542       }
543
544       Object JavaDoc value = model.lookup(first);
545
546       if (value instanceof AbstractModel) {
547         model = (AbstractModel) value;
548         tail = rest;
549         continue;
550       }
551
552       value = dereference(value, null, model);
553
554       if (value instanceof Context) {
555         ((Context) value).unbind(rest);
556         return;
557       }
558       else if (value != null)
559         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
560                                           getFullPath(name), value));
561       else
562         throw new NameNotFoundException(getFullPath(name));
563     }
564   }
565
566   private Object JavaDoc dereference(Object JavaDoc value, Name tail, AbstractModel model)
567     throws NamingException
568   {
569     try {
570       if (value instanceof ObjectProxy)
571         return ((ObjectProxy) value).createObject(_env);
572       else if (value instanceof Reference) {
573         Context context = create(model, _env);
574         return NamingManager.getObjectInstance(value, null, context, _env);
575       }
576       else
577         return value;
578     } catch (NamingException e) {
579       throw e;
580     } catch (Exception JavaDoc e) {
581       throw new NamingExceptionWrapper(e);
582     }
583   }
584   
585   public void unbind(Name name)
586     throws NamingException
587   {
588     if (name.size() == 0)
589       throw new NamingException(L.l("can't unbind root"));
590       
591     AbstractModel model = _model;
592
593     int i = 0;
594     for (; i + 1 < name.size(); i++) {
595       String JavaDoc first = name.get(i);
596
597       Object JavaDoc value = model.lookup(first);
598
599       if (value instanceof AbstractModel) {
600         model = (AbstractModel) value;
601         continue;
602       }
603
604       value = dereference(value, null, model);
605
606       if (value instanceof Context) {
607         ((Context) value).unbind(name.getSuffix(i + 1));
608         return;
609       }
610       else if (value != null)
611         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
612                                           getFullPath(name), value));
613       else
614         throw new NameNotFoundException(getFullPath(name));
615     }
616
617     String JavaDoc first = name.get(i);
618     
619     model.unbind(first);
620   }
621
622   public void rename(String JavaDoc oldName, String JavaDoc newName)
623     throws NamingException
624   {
625     Object JavaDoc obj = lookup(oldName);
626     unbind(oldName);
627     bind(newName, obj);
628   }
629
630   public void rename(Name oldName, Name newName)
631     throws NamingException
632   {
633     Object JavaDoc obj = lookup(oldName);
634     unbind(oldName);
635     bind(newName, obj);
636   }
637
638   /**
639    * List the names for a context.
640    */

641   public NamingEnumeration list(String JavaDoc name)
642     throws NamingException
643   {
644     String JavaDoc tail = name;
645     AbstractModel model = _model;
646
647     while (true) {
648       String JavaDoc first = parseFirst(tail);
649       String JavaDoc rest = parseRest(tail);
650       
651       if (first == null) {
652         return new QNameClassEnumeration(create(model, _env),
653                                          model.list());
654       }
655
656       Object JavaDoc value = model.lookup(first);
657
658       if (value instanceof AbstractModel) {
659         model = (AbstractModel) value;
660         tail = rest;
661         continue;
662       }
663
664       value = dereference(value, null, model);
665
666       if (value instanceof Context) {
667     if (rest == null)
668       return ((Context) value).list("");
669     else
670       return ((Context) value).list(rest);
671       }
672       else if (value != null)
673         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
674                                           getFullPath(name), value));
675       else
676         throw new NameNotFoundException(getFullPath(name));
677     }
678   }
679
680   /**
681    * Lists the names for the context.
682    */

683   public NamingEnumeration list(Name name)
684     throws NamingException
685   {
686     AbstractModel model = _model;
687
688     if (name == null) {
689       return new QNameClassEnumeration(create(model, _env),
690                                        model.list());
691     }
692
693     for (int i = 0; i < name.size(); i++) {
694       String JavaDoc first = name.get(i);
695
696       Object JavaDoc value = model.lookup(first);
697
698       if (value instanceof AbstractModel) {
699         model = (AbstractModel) value;
700         continue;
701       }
702
703       value = dereference(value, null, model);
704
705       if (value instanceof Context)
706         return ((Context) value).list(name.getSuffix(i + 1));
707       else if (value != null)
708         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
709                                           getFullPath(name), value));
710       else
711         throw new NameNotFoundException(getFullPath(name));
712     }
713     
714     return new QNameClassEnumeration(create(model, _env),
715                                      model.list());
716   }
717
718   /**
719    * List the bindings for a context.
720    */

721   public NamingEnumeration listBindings(String JavaDoc name)
722     throws NamingException
723   {
724     String JavaDoc tail = name;
725     AbstractModel model = _model;
726
727     while (true) {
728       String JavaDoc first = parseFirst(tail);
729       String JavaDoc rest = parseRest(tail);
730       
731       if (first == null) {
732         return new QBindingEnumeration(create(model, _env),
733                                        model.list());
734       }
735
736       Object JavaDoc value = model.lookup(first);
737
738       if (value instanceof AbstractModel) {
739         model = (AbstractModel) value;
740         tail = rest;
741         continue;
742       }
743
744       value = dereference(value, null, model);
745
746       if (value instanceof Context)
747         return ((Context) value).listBindings(rest);
748       else if (value != null)
749         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
750                                           getFullPath(name), value));
751       else
752         throw new NameNotFoundException(getFullPath(name));
753     }
754   }
755
756   /**
757    * Lists the bindings for the given name.
758    */

759   public NamingEnumeration listBindings(Name name)
760     throws NamingException
761   {
762     AbstractModel model = _model;
763
764     for (int i = 0; name != null && i < name.size(); i++) {
765       String JavaDoc first = name.get(i);
766
767       Object JavaDoc value = model.lookup(first);
768
769       if (value instanceof AbstractModel) {
770         model = (AbstractModel) value;
771         continue;
772       }
773
774       value = dereference(value, null, model);
775
776       if (value instanceof Context)
777         return ((Context) value).listBindings(name.getSuffix(i + 1));
778       else if (value != null)
779         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
780                                           getFullPath(name), value));
781       else
782         throw new NameNotFoundException(getFullPath(name));
783     }
784     
785     return new QBindingEnumeration(create(model, _env),
786                                    model.list());
787   }
788
789   /**
790    * Creates a subcontext for the current model.
791    */

792   public Context createSubcontext(String JavaDoc name)
793     throws NamingException
794   {
795     String JavaDoc tail = name;
796     AbstractModel model = _model;
797
798     while (true) {
799       String JavaDoc first = parseFirst(tail);
800       String JavaDoc rest = parseRest(tail);
801
802       if (first == null)
803         throw new NamingException(L.l("can't create root subcontext"));
804
805       if (rest == null) {
806         model = model.createSubcontext(first);
807         return create(getFullPath(name), model, _env);
808       }
809
810       Object JavaDoc value = model.lookup(first);
811
812       if (value instanceof AbstractModel) {
813         model = (AbstractModel) value;
814         tail = rest;
815         continue;
816       }
817
818       value = dereference(value, null, model);
819
820       if (value instanceof Context)
821         return ((Context) value).createSubcontext(rest);
822       else if (value != null)
823         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
824                                           getFullPath(name), value));
825       else
826         throw new NameNotFoundException(getFullPath(name));
827     }
828   }
829
830   public Context createSubcontext(Name name)
831     throws NamingException
832   {
833     if (name.size() == 0)
834       throw new NamingException(L.l("can't createSubcontext root"));
835       
836     AbstractModel model = _model;
837
838     int i = 0;
839     for (; i + 1 < name.size(); i++) {
840       String JavaDoc first = name.get(i);
841
842       Object JavaDoc value = model.lookup(first);
843
844       if (value instanceof AbstractModel) {
845         model = (AbstractModel) value;
846         continue;
847       }
848
849       value = dereference(value, null, model);
850
851       if (value instanceof Context) {
852         return ((Context) value).createSubcontext(name.getSuffix(i + 1));
853       }
854       else if (value != null)
855         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
856                                           getFullPath(name), value));
857       else
858         throw new NameNotFoundException(getFullPath(name));
859     }
860
861     String JavaDoc first = name.get(i);
862     
863     model = model.createSubcontext(first);
864
865     return create(model, _env);
866   }
867
868   /**
869    * Destroys the named subcontext.
870    */

871   public void destroySubcontext(String JavaDoc name)
872     throws NamingException
873   {
874     String JavaDoc tail = name;
875     AbstractModel model = _model;
876
877     while (true) {
878       String JavaDoc first = parseFirst(tail);
879       String JavaDoc rest = parseRest(tail);
880       
881       if (first == null)
882         throw new NamingException(L.l("can't create root subcontext"));
883
884       if (rest == null) {
885         model.unbind(first);
886         return;
887       }
888
889       Object JavaDoc value = model.lookup(first);
890
891       if (value instanceof AbstractModel) {
892         model = (AbstractModel) value;
893         tail = rest;
894         continue;
895       }
896
897       value = dereference(value, null, model);
898
899       if (value instanceof Context) {
900         ((Context) value).destroySubcontext(rest);
901         return;
902       }
903       else if (value != null)
904         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
905                                           getFullPath(name), value));
906       else
907         throw new NameNotFoundException(getFullPath(name));
908     }
909   }
910   
911   public void destroySubcontext(Name name)
912     throws NamingException
913   {
914     if (name.size() == 0)
915       throw new NamingException(L.l("can't createSubcontext root"));
916       
917     AbstractModel model = _model;
918
919     int i = 0;
920     for (; i + 1 < name.size(); i++) {
921       String JavaDoc first = name.get(i);
922
923       Object JavaDoc value = model.lookup(first);
924
925       if (value instanceof AbstractModel) {
926         model = (AbstractModel) value;
927         continue;
928       }
929
930       value = dereference(value, null, model);
931
932       if (value instanceof Context) {
933         ((Context) value).destroySubcontext(name.getSuffix(i + 1));
934         return;
935       }
936       else if (value != null)
937         throw new NotContextException(L.l("{0}: expected intermediate context at `{1}'",
938                                           getFullPath(name), value));
939       else
940         throw new NameNotFoundException(getFullPath(name));
941     }
942
943     String JavaDoc first = name.get(i);
944     
945     model.unbind(first);
946   }
947
948   public NameParser getNameParser(String JavaDoc name)
949     throws NamingException
950   {
951     String JavaDoc first = parseFirst(name);
952     String JavaDoc rest = parseRest(name);
953     
954     if (first == null)
955       return new QNameParser(this);
956
957     Object JavaDoc obj = lookupSingleObject(first);
958
959     if (obj instanceof Context)
960       return ((Context) obj).getNameParser(rest == null ? "" : rest);
961
962     else
963       return new QNameParser(this);
964   }
965
966   public NameParser getNameParser(Name name)
967     throws NamingException
968   {
969     if (name.size() == 0)
970       return new QNameParser(this);
971       
972     Object JavaDoc obj = lookupSingleObject(name.get(0));
973
974     if (obj instanceof Context)
975       return ((Context) obj).getNameParser(name.getSuffix(1));
976
977     else
978       return new QNameParser(this);
979   }
980
981   public String JavaDoc composeName(String JavaDoc suffix, String JavaDoc prefix)
982     throws NamingException
983   {
984     return prefix + "/" + suffix;
985   }
986
987   public Name composeName(Name suffix, Name prefix)
988     throws NamingException
989   {
990     return prefix.addAll(suffix);
991   }
992
993   public String JavaDoc getNameInNamespace()
994     throws NamingException
995   {
996     throw new OperationNotSupportedException();
997   }
998
999   /**
1000   * Looks up the object and dereferences any proxy objects.
1001   */

1002  private Object JavaDoc lookupSingleObject(String JavaDoc name)
1003    throws NamingException
1004  {
1005    Object JavaDoc obj = lookupSingle(name);
1006
1007    if (obj instanceof ObjectProxy)
1008      return ((ObjectProxy) obj).createObject(_env);
1009    else
1010      return obj;
1011  }
1012
1013  /**
1014   * Returns the object named by the single name segment.
1015   *
1016   * @param name the name segment.
1017   *
1018   * @return the object bound to the context.
1019   */

1020  protected Object JavaDoc lookupSingle(String JavaDoc name)
1021    throws NamingException
1022  {
1023    throw new UnsupportedOperationException JavaDoc();
1024  }
1025
1026  protected void rebindSingle(String JavaDoc name, Object JavaDoc obj)
1027    throws NamingException
1028  {
1029    throw new UnsupportedOperationException JavaDoc();
1030  }
1031
1032  protected void unbindSingle(String JavaDoc name)
1033    throws NamingException
1034  {
1035    throw new UnsupportedOperationException JavaDoc();
1036  }
1037
1038  protected Context createSingleSubcontext(String JavaDoc name)
1039    throws NamingException
1040  {
1041    throw new UnsupportedOperationException JavaDoc();
1042  }
1043  
1044  protected void destroySingleSubcontext(String JavaDoc name)
1045    throws NamingException
1046  {
1047    unbindSingle(name);
1048  }
1049
1050  protected Iterator JavaDoc listSingle()
1051  {
1052    throw new UnsupportedOperationException JavaDoc();
1053  }
1054
1055  protected String JavaDoc parseFirst(String JavaDoc name)
1056    throws NamingException
1057  {
1058    if (name == null || name.equals(""))
1059      return null;
1060    
1061    int p = name.indexOf(getSeparator());
1062
1063    if (p == 0)
1064      return parseFirst(name.substring(1));
1065    else if (p > 0)
1066      return name.substring(0, p);
1067    else
1068      return name;
1069  }
1070    
1071  protected String JavaDoc parseRest(String JavaDoc name)
1072    throws NamingException
1073  {
1074    if (name == null || name.equals(""))
1075      return null;
1076    
1077    int p = name.indexOf(getSeparator());
1078
1079    if (p == 0)
1080      return parseRest(name.substring(1));
1081    else if (p > 0)
1082      return name.substring(p + 1);
1083    else
1084      return null;
1085  }
1086
1087  protected char getSeparator()
1088  {
1089    return '/';
1090  }
1091
1092  protected String JavaDoc getSeparatorString()
1093  {
1094    return "/";
1095  }
1096
1097  /**
1098   * Returns the full name for the context.
1099   */

1100  protected String JavaDoc getFullPath(String JavaDoc name)
1101  {
1102    if (_name == null || _name.equals(""))
1103      return name;
1104
1105    else if (name == null)
1106      return _name;
1107
1108    String JavaDoc sep = getSeparatorString();
1109    
1110    while (name.endsWith(sep))
1111      name = name.substring(0, name.length() - sep.length());
1112        
1113    if (name.equals(""))
1114      return _name;
1115      
1116    else if (name.startsWith(sep))
1117      return _name + name;
1118    else
1119      return _name + sep + name;
1120  }
1121
1122  /**
1123   * Returns the full name for the context.
1124   */

1125  protected String JavaDoc getFullPath(Name name)
1126  {
1127    if (_name == null || _name.equals(""))
1128      return name.toString();
1129
1130    else if (name == null || name.size() == 0)
1131      return _name;
1132
1133    String JavaDoc sep = getSeparatorString();
1134
1135    return _name + sep + name;
1136  }
1137
1138  /**
1139   * Adds a property to the context environment.
1140   */

1141  public Object JavaDoc addToEnvironment(String JavaDoc prop, Object JavaDoc value)
1142    throws NamingException
1143  {
1144    Object JavaDoc old = _env.get(prop);
1145    _env.put(prop, value);
1146    return old;
1147  }
1148
1149  /**
1150   * Removes a property from the context environment.
1151   */

1152  public Object JavaDoc removeFromEnvironment(String JavaDoc prop)
1153    throws NamingException
1154  {
1155    Object JavaDoc old = _env.get(prop);
1156    _env.remove(prop);
1157    return old;
1158  }
1159
1160  /**
1161   * Returns the context environment.
1162   */

1163  public Hashtable JavaDoc getEnvironment()
1164    throws NamingException
1165  {
1166    return _env;
1167  }
1168
1169  /**
1170   * Close is intended to free any transient data, like a cached
1171   * socket. It does not affect the JNDI tree.
1172   */

1173  public void close()
1174    throws NamingException
1175  {
1176  }
1177
1178  /**
1179   * Returns a string value.
1180   */

1181  public String JavaDoc toString()
1182  {
1183    return "[ContextImpl " + _name + "]";
1184  }
1185}
1186
Popular Tags