View Javadoc

1   // ========================================================================
2   // Copyright (c) 2000-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.jndi.local;
15  
16  import java.util.Collections;
17  import java.util.HashMap;
18  import java.util.Hashtable;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Properties;
22  
23  import javax.naming.Binding;
24  import javax.naming.CompoundName;
25  import javax.naming.Context;
26  import javax.naming.InitialContext;
27  import javax.naming.LinkRef;
28  import javax.naming.Name;
29  import javax.naming.NameAlreadyBoundException;
30  import javax.naming.NameClassPair;
31  import javax.naming.NameNotFoundException;
32  import javax.naming.NameParser;
33  import javax.naming.NamingEnumeration;
34  import javax.naming.NamingException;
35  import javax.naming.NotContextException;
36  import javax.naming.OperationNotSupportedException;
37  import javax.naming.Reference;
38  import javax.naming.Referenceable;
39  import javax.naming.spi.NamingManager;
40  
41  import org.eclipse.jetty.jndi.BindingEnumeration;
42  import org.eclipse.jetty.jndi.NameEnumeration;
43  import org.eclipse.jetty.jndi.NamingContext;
44  import org.eclipse.jetty.jndi.NamingUtil;
45  import org.eclipse.jetty.util.log.Logger;
46  
47  /**
48   * 
49   * localContext
50   * 
51   * Implementation of the delegate for InitialContext for the local namespace. 
52   * 
53   * 
54   * @version $Revision: 4780 $ $Date: 2009-03-17 16:36:08 +0100 (Tue, 17 Mar 2009) $
55   * 
56   */
57  public class localContextRoot implements Context
58  {
59      private final static Logger __log=NamingUtil.__log;
60      protected final static NamingContext __root = new NamingRoot();
61      private final Hashtable<String,Object> _env;
62    
63  
64      static class NamingRoot extends NamingContext
65      {
66          public NamingRoot()
67          {
68              super (null,null,null,new LocalNameParser());
69          }
70      }
71      
72      
73  
74      static class LocalNameParser implements NameParser
75      {
76          Properties syntax = new Properties();
77  
78          LocalNameParser()
79          {
80              syntax.put("jndi.syntax.direction", "left_to_right");
81              syntax.put("jndi.syntax.separator", "/");
82              syntax.put("jndi.syntax.ignorecase", "false");
83          }
84  
85          public Name parse(String name) throws NamingException
86          {
87              return new CompoundName(name, syntax);
88          }
89      }
90      
91      
92      /*
93       * Root has to use the localContextRoot's  env for all operations.
94       * So, if createSubcontext in the root, use the env of the localContextRoot.
95       * If lookup binding in the root, use the env of the localContextRoot.
96       * 
97       */
98      
99    
100     
101     
102    
103 
104     public static NamingContext getRoot()
105     {
106         return __root;
107     }
108 
109     public localContextRoot(Hashtable env)
110     {
111         _env = new Hashtable(env);
112     }
113 
114     /**
115      * 
116      * 
117      * @see javax.naming.Context#close()
118      */
119     public void close() throws NamingException
120     {
121 
122     }
123 
124     /**
125      * 
126      * 
127      * @see javax.naming.Context#getNameInNamespace()
128      */
129     public String getNameInNamespace() throws NamingException
130     {
131         return "";
132     }
133 
134     
135     /**
136      * 
137      * 
138      * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
139      */
140     public void destroySubcontext(Name name) throws NamingException
141     {
142         synchronized (__root)
143         {
144             __root.destroySubcontext(getSuffix(name));   
145         }
146     }
147     
148     
149     /**
150      * 
151      * 
152      * @see javax.naming.Context#destroySubcontext(java.lang.String)
153      */
154     public void destroySubcontext(String name) throws NamingException
155     {
156         synchronized (__root)
157         {
158            
159            destroySubcontext(__root.getNameParser("").parse(getSuffix(name)));
160         }
161     }
162 
163   
164     /**
165      * 
166      * 
167      * @see javax.naming.Context#getEnvironment()
168      */
169     public Hashtable getEnvironment() throws NamingException
170     {
171         return _env;
172     }
173 
174  
175 
176     /**
177      * 
178      * 
179      * @see javax.naming.Context#unbind(javax.naming.Name)
180      */
181     public void unbind(Name name) throws NamingException
182     {
183         synchronized (__root)
184         {
185             //__root.unbind(getSuffix(name));
186             
187             if (name.size() == 0)
188                 return;
189             
190             
191             if (__root.isLocked())
192                 throw new NamingException ("This context is immutable");
193 
194             Name cname = __root.toCanonicalName(name);
195 
196             if (cname == null)
197                 throw new NamingException ("Name is null");
198             
199             if (cname.size() == 0)
200                 throw new NamingException ("Name is empty");
201 
202 
203             //if no subcontexts, just unbind it
204             if (cname.size() == 1)
205             {         
206                 __root.removeBinding (cname);
207             }
208             else
209             { 
210                 //walk down the subcontext hierarchy
211                 if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
212                         
213                 String firstComponent = cname.get(0);
214                 Object ctx = null;
215 
216                 
217                 if (firstComponent.equals(""))
218                     ctx = this;
219                 else
220                 {
221                     Binding  binding = __root.getBinding (name.get(0));
222                     if (binding == null)
223                         throw new NameNotFoundException (name.get(0)+ " is not bound");
224                 
225                     ctx = binding.getObject();
226 
227                     if (ctx instanceof Reference)
228                     {  
229                         //deference the object
230                         try
231                         {
232                             ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
233                         }
234                         catch (NamingException e)
235                         {
236                             throw e;
237                         }
238                         catch (Exception e)
239                         {
240                             __log.warn("",e);
241                             throw new NamingException (e.getMessage());
242                         }
243                     }
244                 }
245 
246                 if (ctx instanceof Context)
247                 {
248                     ((Context)ctx).unbind (cname.getSuffix(1));
249                 }
250                 else
251                     throw new NotContextException ("Object bound at "+firstComponent +" is not a Context");
252             } 
253             
254             
255             
256         }
257     }
258 
259     /**
260      * 
261      * 
262      * @see javax.naming.Context#unbind(java.lang.String)
263      */
264     public void unbind(String name) throws NamingException
265     {
266         unbind(__root.getNameParser("").parse(getSuffix(name)));
267     }
268 
269     
270 
271     /**
272      * 
273      * 
274      * @see javax.naming.Context#lookupLink(java.lang.String)
275      */
276     public Object lookupLink(String name) throws NamingException
277     {
278         synchronized (__root)
279         {
280             return lookupLink(__root.getNameParser("").parse(getSuffix(name)));
281         }
282     }
283 
284     /**
285      * 
286      * 
287      * @see javax.naming.Context#lookupLink(javax.naming.Name)
288      */
289     public Object lookupLink(Name name) throws NamingException
290     {
291         synchronized (__root)
292         {
293             //return __root.lookupLink(getSuffix(name));
294             
295             
296             Name cname = __root.toCanonicalName(name);
297 
298             if (cname == null)
299             {
300                 //If no name create copy of this context with same bindings, but with copy of the environment so it can be modified
301                 NamingContext ctx = new NamingContext (_env, null, null, __root.getNameParser(""));
302                 ctx.setBindings(__root.getBindings());
303                 return ctx;
304             }
305             
306             if (cname.size() == 0)
307                 throw new NamingException ("Name is empty");
308 
309             if (cname.size() == 1)
310             {
311                 Binding binding = __root.getBinding (cname);
312                 if (binding == null)
313                     throw new NameNotFoundException();
314 
315                 Object o = binding.getObject();
316 
317                 //handle links by looking up the link
318                 if (o instanceof Reference)
319                 {
320                     //deference the object
321                     try
322                     {
323                         return NamingManager.getObjectInstance(o, cname.getPrefix(1), __root, _env);
324                     }
325                     catch (NamingException e)
326                     {
327                         throw e;
328                     }
329                     catch (Exception e)
330                     {
331                         __log.warn("",e);
332                         throw new NamingException (e.getMessage());
333                     }
334                 }
335                 else
336                 {
337                     //object is either a LinkRef which we don't dereference
338                     //or a plain object in which case spec says we return it
339                     return o;
340                 }
341             }
342 
343 
344             //it is a multipart name, recurse to the first subcontext
345             String firstComponent = cname.get(0);
346             Object ctx = null;
347             
348             if (firstComponent.equals(""))
349                 ctx = this;
350             else
351             {
352                 Binding binding = __root.getBinding (firstComponent);
353                 if (binding == null)
354                     throw new NameNotFoundException ();
355                 
356                 ctx = binding.getObject();
357 
358                 if (ctx instanceof Reference)
359                 {  
360                     //deference the object
361                     try
362                     {
363                         ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
364                     }
365                     catch (NamingException e)
366                     {
367                         throw e;
368                     }
369                     catch (Exception e)
370                     {
371                         __log.warn("",e);
372                         throw new NamingException (e.getMessage());
373                     }
374                 }
375             }
376 
377             if (!(ctx instanceof Context))
378                 throw new NotContextException();
379 
380             return ((Context)ctx).lookup (cname.getSuffix(1)); 
381             
382             
383         }
384     }
385 
386     
387     /**
388      * 
389      *       
390      * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
391      */
392     public Object removeFromEnvironment(String propName) throws NamingException
393     {
394         return _env.remove(propName);
395     }
396 
397 
398     /**
399      * 
400      * 
401      * @see javax.naming.Context#lookup(javax.naming.Name)
402      */
403     public Object lookup(Name name) throws NamingException
404     {
405         synchronized (__root)
406         {
407             //return __root.lookup(getSuffix(name));
408             
409             if(__log.isDebugEnabled())__log.debug("Looking up name=\""+name+"\"");
410             Name cname = __root.toCanonicalName(name);
411 
412             if ((cname == null) || (cname.size() == 0))
413             {
414                 __log.debug("Null or empty name, returning copy of this context");
415                 NamingContext ctx = new NamingContext (_env, null, null, __root.getNameParser(""));
416                 ctx.setBindings(__root.getBindings());
417                 return ctx;
418             }
419 
420         
421           
422             if (cname.size() == 1)
423             {
424                 Binding binding = __root.getBinding (cname);
425                 if (binding == null)
426                 {
427                     NameNotFoundException nnfe = new NameNotFoundException();
428                     nnfe.setRemainingName(cname);
429                     throw nnfe;
430                 }
431                     
432 
433                 Object o = binding.getObject();
434 
435                 //handle links by looking up the link
436                 if (o instanceof LinkRef)
437                 {
438                     //if link name starts with ./ it is relative to current context
439                     String linkName = ((LinkRef)o).getLinkName();
440                     if (linkName.startsWith("./"))
441                         return lookup (linkName.substring(2));
442                     else
443                     {
444                         //link name is absolute
445                         InitialContext ictx = new InitialContext();
446                         return ictx.lookup (linkName);
447                     }
448                 }
449                 else if (o instanceof Reference)
450                 {
451                     //deference the object
452                     try
453                     {
454                         return NamingManager.getObjectInstance(o, cname, __root, _env);
455                     }
456                     catch (NamingException e)
457                     {
458                         throw e;
459                     }
460                     catch (final Exception e)
461                     {
462                         throw new NamingException (e.getMessage()) 
463                         {
464                             { initCause(e);}
465                         };
466                     }
467                 }
468                 else
469                     return o;
470             }
471 
472             //it is a multipart name, get the first subcontext
473        
474             String firstComponent = cname.get(0);
475             Object ctx = null;
476 
477             if (firstComponent.equals(""))
478                 ctx = this;
479             else
480             {
481                 
482                 Binding binding = __root.getBinding (firstComponent);
483                 if (binding == null)
484                 {
485                     NameNotFoundException nnfe = new NameNotFoundException();
486                     nnfe.setRemainingName(cname);
487                     throw nnfe;
488                 }
489                 
490                 //as we have bound a reference to an object factory 
491                 //for the component specific contexts
492                 //at "comp" we need to resolve the reference
493                 ctx = binding.getObject();
494                 
495                 if (ctx instanceof Reference)
496                 {  
497                     //deference the object
498                     try
499                     {
500                         ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
501                     }
502                     catch (NamingException e)
503                     {
504                         throw e;
505                     }
506                     catch (Exception e)
507                     {
508                         __log.warn("",e);
509                         throw new NamingException (e.getMessage());
510                     }
511                 }
512             }
513             if (!(ctx instanceof Context))
514                 throw new NotContextException();
515 
516             return ((Context)ctx).lookup (cname.getSuffix(1));
517             
518         }
519     }
520 
521     
522     /**
523      * 
524      * 
525      * @see javax.naming.Context#lookup(java.lang.String)
526      */
527     public Object lookup(String name) throws NamingException
528     {
529         synchronized (__root)
530         {
531             return lookup(__root.getNameParser("").parse(getSuffix(name)));
532         }
533     }
534     
535 
536     /**
537      * 
538      * 
539      * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
540      */
541     public void bind(String name, Object obj) throws NamingException
542     {
543         synchronized (__root)
544         {
545            bind(__root.getNameParser("").parse(getSuffix(name)), obj);
546             
547         }
548     }
549 
550 
551     /**
552      * 
553      * 
554      * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
555      */
556     public void bind(Name name, Object obj) throws NamingException
557     {
558         synchronized (__root)
559         {
560            // __root.bind(getSuffix(name), obj);
561             
562             
563             if (__root.isLocked())
564                 throw new NamingException ("This context is immutable");
565 
566             Name cname = __root.toCanonicalName(name);
567             
568             if (cname == null)
569                 throw new NamingException ("Name is null");
570             
571             if (cname.size() == 0)
572                 throw new NamingException ("Name is empty");
573 
574 
575             //if no subcontexts, just bind it
576             if (cname.size() == 1)
577             {
578                 //get the object to be bound
579                 Object objToBind = NamingManager.getStateToBind(obj, name,this, _env);
580                 // Check for Referenceable
581                 if (objToBind instanceof Referenceable) 
582                 {
583                     objToBind = ((Referenceable)objToBind).getReference();
584                 }
585                 
586                 //anything else we should be able to bind directly    
587                 __root.addBinding (cname, objToBind);
588             }
589             else
590             {
591                 if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
592               
593                 //walk down the subcontext hierarchy       
594                 //need to ignore trailing empty "" name components
595                         
596                 String firstComponent = cname.get(0);
597                 Object ctx = null;
598 
599                 if (firstComponent.equals(""))
600                     ctx = this;
601                 else
602                 {
603 
604                     Binding  binding = __root.getBinding (firstComponent);
605                     if (binding == null)
606                         throw new NameNotFoundException (firstComponent+ " is not bound");
607                     
608                     ctx = binding.getObject();
609                     
610                     if (ctx instanceof Reference)
611                     {  
612                         //deference the object
613                         try
614                         {
615                             ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
616                         }
617                         catch (NamingException e)
618                         {
619                             throw e;
620                         }
621                         catch (Exception e)
622                         {
623                             __log.warn("",e);
624                             throw new NamingException (e.getMessage());
625                         }
626                     }
627                 }
628 
629 
630                 if (ctx instanceof Context)
631                 {
632                     ((Context)ctx).bind (cname.getSuffix(1), obj);
633                 }
634                 else
635                     throw new NotContextException ("Object bound at "+firstComponent +" is not a Context");
636             }
637         }
638     }
639 
640     /**
641      *
642      * 
643      * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
644      */
645     public void rebind(Name name, Object obj) throws NamingException
646     {
647         synchronized (__root)
648         {
649             //__root.rebind(getSuffix(name), obj);
650             
651             
652             if (__root.isLocked())
653                 throw new NamingException ("This context is immutable");
654 
655             Name cname = __root.toCanonicalName(name);
656 
657             if (cname == null)
658                 throw new NamingException ("Name is null");
659             
660             if (cname.size() == 0)
661                 throw new NamingException ("Name is empty");
662 
663 
664             //if no subcontexts, just bind it
665             if (cname.size() == 1)
666             {      
667                 //check if it is a Referenceable
668                 Object objToBind = NamingManager.getStateToBind(obj, name, __root, _env);
669                 
670                 if (objToBind instanceof Referenceable)
671                 {
672                     objToBind = ((Referenceable)objToBind).getReference();
673                 }
674                 __root.removeBinding(cname);
675                 __root.addBinding (cname, objToBind);
676             }
677             else
678             { 
679                 //walk down the subcontext hierarchy
680                 if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
681                         
682                 String firstComponent = cname.get(0);
683                 Object ctx = null;
684 
685                 
686                 if (firstComponent.equals(""))
687                     ctx = this;
688                 else
689                 {
690                     Binding  binding = __root.getBinding (name.get(0));
691                     if (binding == null)
692                         throw new NameNotFoundException (name.get(0)+ " is not bound");
693                 
694                     ctx = binding.getObject();
695 
696 
697                     if (ctx instanceof Reference)
698                     {  
699                         //deference the object
700                         try
701                         {
702                             ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
703                         }
704                         catch (NamingException e)
705                         {
706                             throw e;
707                         }
708                         catch (Exception e)
709                         {
710                             __log.warn("",e);
711                             throw new NamingException (e.getMessage());
712                         }
713                     }
714                 }
715 
716                 if (ctx instanceof Context)
717                 {
718                     ((Context)ctx).rebind (cname.getSuffix(1), obj);
719                 }
720                 else
721                     throw new NotContextException ("Object bound at "+firstComponent +" is not a Context");
722             }
723         }
724     }
725 
726     /**
727      * 
728      * 
729      * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
730      */
731     public void rebind(String name, Object obj) throws NamingException
732     {
733         synchronized (__root)
734         {
735             rebind(__root.getNameParser("").parse(getSuffix(name)), obj);
736         }
737     }
738     /**
739      * 
740      * 
741      * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
742      */
743     public void rename(Name oldName, Name newName) throws NamingException
744     {
745         synchronized (__root)
746         {
747             throw new OperationNotSupportedException();
748         }
749     }
750 
751     /**
752      * 
753      * 
754      * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
755      */
756     public void rename(String oldName, String newName) throws NamingException
757     {
758         synchronized (__root)
759         {
760            throw new OperationNotSupportedException();
761         }
762     }
763 
764     /**
765      * 
766      * 
767      * @see javax.naming.Context#createSubcontext(java.lang.String)
768      */
769     public Context createSubcontext(String name) throws NamingException
770     {
771         synchronized (__root)
772         {
773             //if the subcontext comes directly off the root, use the env of the InitialContext
774             //as the root itself has no environment. Otherwise, it inherits the env of the parent
775             //Context further down the tree.
776             //NamingContext ctx = (NamingContext)__root.createSubcontext(name);
777             //if (ctx.getParent() == __root)
778             //    ctx.setEnv(_env);
779             //return ctx;
780             
781             return createSubcontext(__root.getNameParser("").parse(name));
782         }
783     }
784 
785     /**
786      * 
787      * 
788      * @see javax.naming.Context#createSubcontext(javax.naming.Name)
789      */
790     public Context createSubcontext(Name name) throws NamingException
791     {
792         synchronized (__root)
793         {            
794             //if the subcontext comes directly off the root, use the env of the InitialContext
795             //as the root itself has no environment. Otherwise, it inherits the env of the parent
796             //Context further down the tree.
797             //NamingContext ctx = (NamingContext)__root.createSubcontext(getSuffix(name));
798             //if (ctx.getParent() == __root)
799             //    ctx.setEnv(_env);
800             //return ctx;
801             
802             
803             
804             
805             if (__root.isLocked())
806             {
807                 NamingException ne = new NamingException ("This context is immutable"); 
808                 ne.setRemainingName(name);
809                 throw ne;
810             }
811             
812             Name cname = __root.toCanonicalName (name);
813 
814             if (cname == null)
815                 throw new NamingException ("Name is null");
816             if (cname.size() == 0)
817                 throw new NamingException ("Name is empty");
818 
819             if (cname.size() == 1)
820             {
821                 //not permitted to bind if something already bound at that name
822                 Binding binding = __root.getBinding (cname);
823                 if (binding != null)
824                     throw new NameAlreadyBoundException (cname.toString());
825 
826                 //make a new naming context with the root as the parent
827                 Context ctx = new NamingContext ((Hashtable)_env.clone(), cname.get(0), __root,  __root.getNameParser(""));
828                 __root.addBinding (cname, ctx);
829                 return ctx;
830             }
831             
832                 
833             //If the name has multiple subcontexts, walk the hierarchy by
834             //fetching the first one. All intermediate subcontexts in the 
835             //name must already exist.
836             String firstComponent = cname.get(0);
837             Object ctx = null;
838 
839             if (firstComponent.equals(""))
840                 ctx = this;
841             else
842             {
843                 Binding binding = __root.getBinding (firstComponent);
844                 if (binding == null)
845                     throw new NameNotFoundException (firstComponent + " is not bound");
846                 
847                 ctx = binding.getObject();
848                 
849                 if (ctx instanceof Reference)
850                 {  
851                     //deference the object
852                     if(__log.isDebugEnabled())__log.debug("Object bound at "+firstComponent +" is a Reference");
853                     try
854                     {
855                         ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
856                     }
857                     catch (NamingException e)
858                     {
859                         throw e;
860                     }
861                     catch (Exception e)
862                     {
863                         __log.warn("",e);
864                         throw new NamingException (e.getMessage());
865                     }
866                 }
867             }
868             
869             if (ctx instanceof Context)
870             {
871                 return ((Context)ctx).createSubcontext (cname.getSuffix(1));
872             }
873             else
874                 throw new NotContextException (firstComponent +" is not a Context");
875         }
876     }
877 
878   
879     /**
880      *
881      * 
882      * @see javax.naming.Context#getNameParser(java.lang.String)
883      */
884     public NameParser getNameParser(String name) throws NamingException
885     {
886         return __root.getNameParser(name);
887     }
888 
889     /**
890      * 
891      * 
892      * @see javax.naming.Context#getNameParser(javax.naming.Name)
893      */
894     public NameParser getNameParser(Name name) throws NamingException
895     {
896         return __root.getNameParser(name);
897     }
898 
899     /**
900      * 
901      * 
902      * @see javax.naming.Context#list(java.lang.String)
903      */
904     public NamingEnumeration list(String name) throws NamingException
905     {
906         synchronized (__root)
907         {
908             return list(__root.getNameParser("").parse(getSuffix(name)));
909         }
910     }
911 
912 
913     /**
914      *
915      * 
916      * @see javax.naming.Context#list(javax.naming.Name)
917      */
918     public NamingEnumeration list(Name name) throws NamingException
919     {
920         synchronized (__root)
921         {
922             //return __root.list(getSuffix(name));
923             
924            
925             Name cname = __root.toCanonicalName(name);
926 
927             if (cname == null)
928             {
929                 List<Binding> empty = Collections.emptyList();
930                 return new NameEnumeration(empty.iterator());
931             }
932 
933             
934             if (cname.size() == 0)
935             {
936                return new NameEnumeration (__root.getBindings().values().iterator()); 
937             }
938 
939           
940 
941             //multipart name
942             String firstComponent = cname.get(0);
943             Object ctx = null;
944 
945             if (firstComponent.equals(""))
946                 ctx = this;
947             else
948             {
949                 Binding binding = __root.getBinding (firstComponent);
950                 if (binding == null)
951                     throw new NameNotFoundException ();
952                 
953                 ctx = binding.getObject();
954                 
955                 if (ctx instanceof Reference)
956                 {  
957                     //deference the object
958                     if(__log.isDebugEnabled())__log.debug("Dereferencing Reference for "+name.get(0));
959                     try
960                     {
961                         ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
962                     }
963                     catch (NamingException e)
964                     {
965                         throw e;
966                     }
967                     catch (Exception e)
968                     {
969                         __log.warn("",e);
970                         throw new NamingException (e.getMessage());
971                     }
972                 }
973             }
974 
975             if (!(ctx instanceof Context))
976                 throw new NotContextException();
977 
978             return ((Context)ctx).list (cname.getSuffix(1));       
979             
980         }
981     }
982 
983     /**
984      *
985      * 
986      * @see javax.naming.Context#listBindings(javax.naming.Name)
987      */
988     public NamingEnumeration listBindings(Name name) throws NamingException
989     {
990         synchronized (__root)
991         {
992             //return __root.listBindings(getSuffix(name));
993             
994             Name cname = __root.toCanonicalName (name);
995 
996             if (cname == null)
997             {
998                 List<Binding> empty = Collections.emptyList();
999                 return new BindingEnumeration(empty.iterator());
1000             }
1001 
1002             if (cname.size() == 0)
1003             {
1004                return new BindingEnumeration (__root.getBindings().values().iterator()); 
1005             }
1006 
1007           
1008             
1009             //multipart name
1010             String firstComponent = cname.get(0);
1011             Object ctx = null;
1012 
1013             //if a name has a leading "/" it is parsed as "" so ignore it by staying
1014             //at this level in the tree
1015             if (firstComponent.equals(""))
1016                 ctx = this;
1017             else
1018             {
1019                 //it is a non-empty name component
1020                 Binding binding = __root.getBinding (firstComponent);
1021                 if (binding == null)
1022                     throw new NameNotFoundException ();
1023             
1024                 ctx = binding.getObject();
1025 
1026                 if (ctx instanceof Reference)
1027                 {  
1028                     //deference the object
1029                     try
1030                     {
1031                         ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env);
1032                     }
1033                     catch (NamingException e)
1034                     {
1035                         throw e;
1036                     }
1037                     catch (Exception e)
1038                     {
1039                         __log.warn("",e);
1040                         throw new NamingException (e.getMessage());
1041                     }
1042                 }
1043             }
1044 
1045             if (!(ctx instanceof Context))
1046                 throw new NotContextException();
1047 
1048             return ((Context)ctx).listBindings (cname.getSuffix(1));
1049             
1050         }
1051     }
1052 
1053 
1054     /**
1055      *
1056      * 
1057      * @see javax.naming.Context#listBindings(java.lang.String)
1058      */
1059     public NamingEnumeration listBindings(String name) throws NamingException
1060     {
1061         synchronized (__root)
1062         {
1063             return listBindings(__root.getNameParser("").parse(getSuffix(name)));
1064         }
1065     }
1066     
1067     
1068     /**
1069      *
1070      * 
1071      * @see javax.naming.Context#addToEnvironment(java.lang.String,
1072      *      java.lang.Object)
1073      */
1074     public Object addToEnvironment(String propName, Object propVal)
1075             throws NamingException
1076     {
1077         return _env.put(propName, propVal);
1078     }
1079 
1080     /**
1081      *
1082      * 
1083      * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
1084      */
1085     public String composeName(String name, String prefix)
1086             throws NamingException
1087     {
1088         return __root.composeName(name, prefix);
1089     }
1090 
1091     /**
1092      *
1093      * 
1094      * @see javax.naming.Context#composeName(javax.naming.Name,
1095      *      javax.naming.Name)
1096      */
1097     public Name composeName(Name name, Name prefix) throws NamingException
1098     {
1099         return __root.composeName(name, prefix);
1100     }
1101 
1102     protected String getSuffix(String url) throws NamingException
1103     {
1104         return url;
1105     }
1106 
1107     protected Name getSuffix(Name name) throws NamingException
1108     {
1109         return name;
1110     }
1111 
1112 }