KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > naming > NamingContextImpl


1 package org.jacorb.naming;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import java.net.*;
24 import java.util.*;
25 import java.io.*;
26
27 import org.omg.CosNaming.*;
28 import org.omg.CosNaming.NamingContextPackage.*;
29 import org.omg.CosNaming.NamingContextExtPackage.*;
30
31 import org.apache.avalon.framework.logger.Logger;
32 import org.apache.avalon.framework.configuration.*;
33
34 /**
35  * The implementation for the CORBAService Naming
36  *
37  * @author Gerald Brose
38  * @version $Id: NamingContextImpl.java,v 1.26 2005/06/01 10:03:50 andre.spiegel Exp $
39  */

40
41 public class NamingContextImpl
42     extends NamingContextExtPOA
43     implements java.io.Serializable JavaDoc, Configurable
44 {
45     /** table of all name bindings in this contexts, ie. name -> obj ref. */
46     private Hashtable names = new Hashtable();
47
48     /** table of all subordinate naming contexts, ie. name -> obj ref. */
49     private Hashtable contexts = new Hashtable();
50
51     /** configuration */
52     private org.jacorb.config.Configuration configuration = null;
53
54     /** no tests of bound objects for existence */
55     private boolean noPing = false;
56
57     /** purge? */
58     private boolean doPurge = false;
59
60     /** the logger used by the naming service implementation */
61     private static Logger logger = null;
62
63     /** the POAs used */
64     transient private org.omg.PortableServer.POA JavaDoc poa;
65     private static org.omg.PortableServer.POA JavaDoc rootPoa;
66     private static org.omg.CORBA.ORB JavaDoc orb;
67
68     private int child_count;
69     private boolean destroyed = false;
70
71
72     public void configure(Configuration myConfiguration)
73         throws ConfigurationException
74     {
75         this.configuration = (org.jacorb.config.Configuration)myConfiguration;
76         logger = configuration.getNamedLogger("jacorb.naming");
77         doPurge = configuration.getAttribute("jacorb.naming.purge","off").equals("on");
78         noPing = configuration.getAttribute("jacorb.naming.noping","off").equals("on");
79     }
80
81
82     /**
83      * bind a name (an array of name components) to an object
84      */

85
86     public void bind( NameComponent[] nc, org.omg.CORBA.Object JavaDoc obj)
87         throws NotFound, CannotProceed, InvalidName, AlreadyBound
88     {
89         if( destroyed )
90             throw new CannotProceed();
91
92         if( nc == null || nc.length == 0 )
93             throw new InvalidName();
94
95         if( obj == null )
96             throw new org.omg.CORBA.BAD_PARAM JavaDoc();
97
98         Name n = new Name( nc );
99         Name ctx = n.ctxName();
100         NameComponent nb = n.baseNameComponent();
101         if( ctx == null )
102         {
103             if( names.containsKey( n ))
104             {
105                 // if the name is still in use, try to ping the object
106
org.omg.CORBA.Object JavaDoc s = (org.omg.CORBA.Object JavaDoc)names.get(n);
107                 if( isDead(s) )
108                 {
109                     rebind( n.components(), obj );
110                     return;
111                 }
112                 throw new AlreadyBound();
113             }
114             else if( contexts.containsKey( n ))
115             {
116                 // if the name is still in use, try to ping the object
117
org.omg.CORBA.Object JavaDoc s = (org.omg.CORBA.Object JavaDoc)contexts.get(n);
118                 if( isDead(s) )
119                 {
120                     unbind( n.components());
121                 }
122                 throw new AlreadyBound();
123             }
124
125             if(( names.put( n, obj )) != null )
126                 throw new CannotProceed( _this(), n.components() );
127
128             if( logger.isInfoEnabled() )
129             {
130                 logger.info("Bound name: " + n.toString());
131             }
132         }
133         else
134         {
135             NameComponent[] ncx = new NameComponent[1];
136             ncx[0] = nb;
137             NamingContextExtHelper.narrow(resolve(ctx.components())).bind(ncx,obj);
138         }
139     }
140
141
142     /**
143      * Bind an object to a name that's already in use, i.e. rebind the name
144      */

145
146     public void rebind(NameComponent[] nc, org.omg.CORBA.Object JavaDoc obj)
147         throws NotFound, CannotProceed, InvalidName
148     {
149         if( destroyed )
150             throw new CannotProceed();
151
152         if( nc == null || nc.length == 0 )
153             throw new InvalidName();
154
155         if( obj == null )
156             throw new org.omg.CORBA.BAD_PARAM JavaDoc();
157
158         Name n = new Name( nc );
159         Name ctx = n.ctxName();
160         NameComponent nb = n.baseNameComponent();
161
162         // the name is bound, but it is bound to a context,
163
// the client should have been using rebind_context!
164

165         if( contexts.containsKey( n ))
166             throw new NotFound(NotFoundReason.not_object, new NameComponent[]{ nb } );
167
168         // try remove an existing binding
169

170         org.omg.CORBA.Object JavaDoc _o = (org.omg.CORBA.Object JavaDoc)names.remove( n );
171         if( _o != null)
172             _o._release();
173
174         if( ctx == null )
175         {
176             // do the rebinding in this context
177

178             names.put( n, obj );
179             if( logger.isInfoEnabled() )
180             {
181                 logger.info("re-Bound name: " + n.toString());
182             }
183         }
184         else
185         {
186             // rebind in the correct context
187

188             NameComponent[] ncx = new NameComponent[1];
189             ncx[0] = nb;
190             NamingContextExt nce = NamingContextExtHelper.narrow(resolve(ctx.components()));
191             if( nce == null )
192                 throw new CannotProceed();
193             nce.rebind(ncx,obj);
194         }
195     }
196
197
198     /**
199      * Bind an context to a name that's already in use, i.e. rebind the name
200      */

201
202     public void rebind_context(NameComponent[] nc, NamingContext obj)
203         throws NotFound, CannotProceed, InvalidName
204     {
205         if( destroyed )
206             throw new CannotProceed();
207
208         if( nc == null || nc.length == 0 )
209             throw new InvalidName();
210
211         if( obj == null )
212             throw new org.omg.CORBA.BAD_PARAM JavaDoc();
213
214         Name n = new Name( nc );
215         Name ctx = n.ctxName();
216         NameComponent nb = n.baseNameComponent();
217
218         // the name is bound, but it is bound to an object,
219
// the client should have been using rebind() !
220

221         if( names.containsKey( n ))
222             throw new NotFound(NotFoundReason.not_context,new NameComponent[]{ nb });
223
224         // try to remove an existing context binding
225

226         org.omg.CORBA.Object JavaDoc _o = (org.omg.CORBA.Object JavaDoc)contexts.remove( n );
227         if( _o != null)
228             _o._release();
229
230         if( ctx == null )
231         {
232             contexts.put( n, obj );
233             if (logger.isInfoEnabled())
234             {
235                 logger.info("Re-Bound context: " +
236                             n.baseNameComponent().id);
237             }
238         }
239     }
240
241
242
243     /**
244      * Bind a context to a name
245      */

246
247     public void bind_context(NameComponent[] nc,
248                              NamingContext obj)
249         throws NotFound, CannotProceed, InvalidName, AlreadyBound
250     {
251         if( destroyed )
252             throw new CannotProceed();
253
254         Name n = new Name( nc );
255         Name ctx = n.ctxName();
256         NameComponent nb = n.baseNameComponent();
257
258         if( ctx == null )
259         {
260             if( names.containsKey( n ))
261             {
262                 // if the name is still in use, try to ping the object
263
org.omg.CORBA.Object JavaDoc s = (org.omg.CORBA.Object JavaDoc)names.get(n);
264                 if( isDead(s) )
265                 {
266                     unbind( n.components());
267                 }
268                 else
269                     throw new AlreadyBound();
270             }
271             else if( contexts.containsKey( n ))
272             {
273                 // if the name is still in use, try to ping the object
274
org.omg.CORBA.Object JavaDoc s = (org.omg.CORBA.Object JavaDoc)contexts.get(n);
275                 if( isDead(s) )
276                 {
277                     rebind_context( n.components(), obj );
278                     return;
279                 }
280                 throw new AlreadyBound();
281             }
282
283             if( (contexts.put( n, obj )) != null )
284                 throw new CannotProceed( _this(), n.components());
285             contexts.put( n, obj );
286
287             if (logger.isInfoEnabled())
288             {
289                 logger.info("Bound context: " + n.toString());
290             }
291         }
292         else
293         {
294             NameComponent[] ncx = new NameComponent[1];
295             ncx[0] = nb;
296             NamingContextExtHelper.narrow(resolve(ctx.components())).bind_context(ncx,obj);
297         }
298     }
299
300     public NamingContext bind_new_context(NameComponent[] nc )
301         throws NotFound, CannotProceed, InvalidName, AlreadyBound
302     {
303         if( destroyed )
304             throw new CannotProceed();
305
306         if( nc == null || nc.length == 0 )
307             throw new InvalidName();
308
309         NamingContextExt ns = NamingContextExtHelper.narrow(new_context());
310         bind_context( nc, ns );
311
312         if( ns == null )
313         {
314             throw new CannotProceed();
315         }
316         return ns;
317     }
318
319     /**
320      * cleanup bindings, i.e. ping every object and remove bindings to
321      * non-existent objects
322      */

323
324     private void cleanup ()
325     {
326         // Check if object purging enabled
327

328         if (! doPurge)
329         {
330            return;
331         }
332
333         Vector deletionVector = new Vector();
334
335         for( Enumeration n = names.keys(); n.hasMoreElements(); )
336         {
337             Name _n = (Name)n.nextElement();
338
339             if( isDead(((org.omg.CORBA.Object JavaDoc)names.get( _n ))) )
340             {
341                 if (logger.isInfoEnabled())
342                 {
343                     logger.info("Removing name " + _n.baseNameComponent().id);
344                 }
345                 deletionVector.addElement( _n );
346             }
347         }
348
349         if( deletionVector.size() > 0 )
350         {
351             for( int i = deletionVector.size(); i-- > 0; )
352                 names.remove( (Name)deletionVector.elementAt(i));
353             deletionVector.removeAllElements();
354         }
355
356         /* ping contexts */
357
358         for( Enumeration c = contexts.keys(); c.hasMoreElements(); )
359         {
360             Name _n = (Name)c.nextElement();
361             if( isDead(((org.omg.CORBA.Object JavaDoc)contexts.get( _n ))) )
362             {
363                 if (logger.isInfoEnabled())
364                 {
365                     logger.info("Removing context " + _n.baseNameComponent().id);
366                 }
367                 deletionVector.addElement( _n );
368             }
369         }
370
371         if( deletionVector.size() > 0 )
372         {
373             for( int i = deletionVector.size(); i-- > 0; )
374                 contexts.remove( (Name)deletionVector.elementAt(i));
375             deletionVector.removeAllElements();
376         }
377     }
378
379     public void destroy()
380         throws NotEmpty
381     {
382         if( destroyed )
383             return;
384
385         if(!names.isEmpty() || !contexts.isEmpty() )
386             throw new NotEmpty();
387         else
388         {
389             names = null;
390             contexts = null;
391             destroyed = true;
392         }
393     }
394
395     /**
396      * @return numer of bindings in this context
397      */

398
399     public int how_many()
400     {
401         if( destroyed )
402             return 0;
403         return names.size() + contexts.size();
404     }
405
406
407
408     /**
409      * list all bindings
410      */

411
412     private Binding[] list()
413     {
414         Binding[] result;
415         cleanup();
416
417         int how_many = how_many();
418
419         Enumeration n = names.keys();
420         Enumeration c = contexts.keys();
421
422         result = new Binding[how_many];
423         for( ; n.hasMoreElements() && how_many > 0; how_many-- )
424         {
425             result[how_many-1] =
426                 new Binding(((Name)n.nextElement()).components(),
427                             BindingType.nobject );
428         }
429
430         for( ; c.hasMoreElements() && how_many > 0; how_many-- )
431         {
432             result[how_many-1] =
433                 new Binding(((Name)c.nextElement()).components(),
434                             BindingType.ncontext);
435         }
436
437         return result;
438     }
439
440     /**
441      * list all bindings
442      */

443
444     public void list(int how_many, BindingListHolder bl, BindingIteratorHolder bi)
445     {
446         if( destroyed )
447             return;
448
449         Binding[] result;
450
451         cleanup();
452
453         int size = how_many();
454
455         Enumeration n = names.keys();
456         Enumeration c = contexts.keys();
457
458         if( how_many < size )
459         {
460             // counter for copies
461
int how_many_ctr = how_many;
462
463             // set up an array with "how_many" bindings
464

465             result = new Binding[how_many];
466             for( ; n.hasMoreElements() && how_many_ctr > 0; how_many_ctr-- )
467             {
468                 result[how_many_ctr-1] = new Binding(((Name)n.nextElement()).components(),
469                                                  BindingType.nobject );
470             }
471
472             for( ; c.hasMoreElements() && how_many_ctr > 0; how_many_ctr-- )
473             {
474                 result[how_many_ctr-1] = new Binding(((Name)c.nextElement()).components(),
475                                                  BindingType.ncontext);
476             }
477
478             // create a new BindingIterator for the remaining arrays
479

480             size -= how_many;
481             Binding[] rest = new Binding[ size ];
482             for( ; n.hasMoreElements() && size > 0; size-- )
483             {
484                 rest[size-1] = new Binding(((Name)n.nextElement()).components(),
485                                            BindingType.nobject );
486             }
487
488             for( ; c.hasMoreElements() && size > 0; size-- )
489             {
490                 rest[size-1] = new Binding(((Name)c.nextElement()).components(),
491                                            BindingType.ncontext);
492             }
493
494             org.omg.CORBA.Object JavaDoc o = null;
495             try
496             {
497                 // Iterators are activated with the RootPOA (transient)
498
byte[] oid = rootPoa.activate_object( new BindingIteratorImpl( rest ) );
499                 o = rootPoa.id_to_reference(oid);
500             }
501             catch ( Exception JavaDoc ue )
502             {
503                 ue.printStackTrace();
504             }
505
506             bi.value = BindingIteratorHelper.narrow(o);
507         }
508         else
509         {
510             result = new Binding[size];
511             for( ; n.hasMoreElements() && size > 0; size-- )
512             {
513                 result[size-1] =
514                     new Binding(((Name)n.nextElement()).components(),
515                                 BindingType.nobject );
516             }
517
518             for( ; c.hasMoreElements() && size > 0; size-- )
519             {
520                 result[size-1] =
521                     new Binding(((Name)c.nextElement()).components(),
522                                 BindingType.ncontext);
523             }
524         }
525
526         bl.value = result;
527     }
528
529     public NamingContext new_context()
530     {
531         if( destroyed )
532             return null;
533
534         org.omg.CORBA.Object JavaDoc ctx = null;
535         try
536         {
537             byte[] oid = (new String JavaDoc(poa.servant_to_id(this)) +
538                           "_ctx" + (++child_count)).getBytes();
539
540             ctx = poa.create_reference_with_id( oid, "IDL:omg.org/CosNaming/NamingContextExt:1.0");
541             if (logger.isInfoEnabled())
542             {
543                 logger.info("New context.");
544             }
545         }
546         catch ( Exception JavaDoc ue )
547         {
548             if (logger.isErrorEnabled())
549             {
550                 logger.error ("failed to create new context", ue);
551             }
552             throw new RuntimeException JavaDoc ("failed to create new context: "
553                                         + ue.toString());
554         }
555         return NamingContextExtHelper.narrow(ctx);
556     }
557
558
559
560     /**
561      * resolve a name
562      */

563
564     public org.omg.CORBA.Object JavaDoc resolve(NameComponent[] nc)
565         throws NotFound, CannotProceed, InvalidName
566     {
567         if( destroyed )
568             throw new CannotProceed();
569
570         if( nc == null || nc.length == 0 )
571             throw new InvalidName();
572
573         Name n = new Name( nc[0] );
574         if( nc.length > 1 )
575         {
576             NamingContextExt next_context =
577                 NamingContextExtHelper.narrow((org.omg.CORBA.Object JavaDoc)contexts.get(n));
578
579
580             if ((next_context == null)||(isDead(next_context)))
581             {
582                 throw new NotFound(NotFoundReason.missing_node,nc);
583             }
584
585             NameComponent[] nc_prime =
586                 new NameComponent[nc.length-1];
587
588             for( int i = 1; i < nc.length; i++)
589                 nc_prime[i-1] = nc[i];
590
591             return next_context.resolve(nc_prime);
592         }
593         else
594         {
595             org.omg.CORBA.Object JavaDoc result = null;
596
597             result = (org.omg.CORBA.Object JavaDoc)contexts.get(n);
598
599             if( result == null )
600                 result = (org.omg.CORBA.Object JavaDoc)names.get(n);
601
602             if (result == null)
603                 throw new NotFound(NotFoundReason.missing_node, n.components());
604             
605             if ( !noPing && isDead(result))
606             {
607                 throw new NotFound(NotFoundReason.missing_node, n.components());
608             }
609
610             return result;
611         }
612     }
613
614     /**
615      * unbind a name
616      */

617
618     public void unbind(NameComponent[] nc )
619         throws NotFound, CannotProceed, InvalidName
620     {
621         if( destroyed )
622             throw new CannotProceed();
623
624         if( nc == null || nc.length == 0 )
625             throw new InvalidName();
626
627         Name n = new Name( nc );
628         Name ctx = n.ctxName();
629         NameComponent nb = n.baseNameComponent();
630
631         if( ctx == null )
632         {
633             if( names.containsKey(n))
634             {
635                 org.omg.CORBA.Object JavaDoc o = (org.omg.CORBA.Object JavaDoc)names.remove( n );
636                 o._release();
637                 if (logger.isInfoEnabled())
638                 {
639                     logger.info("Unbound: " + n.toString());
640                 }
641             }
642             else if( contexts.containsKey(n))
643             {
644                 org.omg.CORBA.Object JavaDoc o = (org.omg.CORBA.Object JavaDoc)contexts.remove( n );
645                 o._release();
646
647                 if (logger.isInfoEnabled())
648                 {
649                     logger.info("Unbound: " + n.toString());
650                 }
651             }
652             else
653             {
654                 if (logger.isWarnEnabled())
655                 {
656                     logger.warn("Unbind failed for " + n.toString() );
657                 }
658                 throw new NotFound(NotFoundReason.not_context,
659                                    n.components());
660             }
661         }
662         else
663         {
664             NameComponent[] ncx = new NameComponent[1];
665             ncx[0] = nb;
666             NamingContextExtHelper.narrow( resolve( ctx.components())).unbind(ncx );
667         }
668     }
669
670     /**
671      * POA-related,
672      */

673
674     public org.omg.PortableServer.POA JavaDoc default_POA()
675     {
676         return poa;
677     }
678
679
680     /**
681      * Overrides writeObject in Serializable
682      */

683
684     private void writeObject(java.io.ObjectOutputStream JavaDoc out)
685         throws IOException
686     {
687         /*
688          * For serialization, object references are transformed
689          * into strings
690          */

691
692         for( Enumeration e = contexts.keys(); e.hasMoreElements();)
693         {
694             Name key = (Name)e.nextElement();
695             org.omg.CORBA.Object JavaDoc o = (org.omg.CORBA.Object JavaDoc)contexts.remove( key );
696             contexts.put( key, orb.object_to_string( o ));
697         }
698
699         for( Enumeration e = names.keys(); e.hasMoreElements();)
700         {
701             Name key = (Name)e.nextElement();
702             org.omg.CORBA.Object JavaDoc o = (org.omg.CORBA.Object JavaDoc)names.remove(key);
703             names.put( key, orb.object_to_string( o ));
704         }
705
706         out.defaultWriteObject();
707     }
708
709     /**
710      * This method needs to be called once to initialize
711      * the static fields orb and rootPoa.
712      *
713      */

714
715     public static void init(org.omg.CORBA.ORB JavaDoc orb,
716                             org.omg.PortableServer.POA JavaDoc rootPoa)
717     {
718         NamingContextImpl.orb = orb;
719         NamingContextImpl.rootPoa = rootPoa;
720     }
721
722     /**
723      * This method needs to be called for each newly created
724      * or re-read naming context to set its poa.
725      *
726      */

727
728     void init(org.omg.PortableServer.POA JavaDoc poa)
729     {
730         this.poa = poa;
731
732         /**
733          * Recreate tables. For serialization, object references
734          * have been transformed into strings
735          */

736
737         for( Enumeration e = contexts.keys(); e.hasMoreElements();)
738         {
739             Name key = (Name)e.nextElement();
740             String JavaDoc ref = (String JavaDoc)contexts.remove(key);
741             contexts.put( key, orb.string_to_object( ref ));
742         }
743
744         for( Enumeration e = names.keys(); e.hasMoreElements();)
745         {
746             Name key = (Name)e.nextElement();
747             String JavaDoc ref = (String JavaDoc)names.remove(key);
748             names.put( key, orb.string_to_object( ref ));
749         }
750
751     }
752
753     /* NamingContextExt */
754
755     /**
756      * convert a name into its string representation
757      */

758
759     public String JavaDoc to_string(NameComponent[] n)
760         throws InvalidName
761     {
762         return Name.toString(n);
763     }
764
765     /**
766      * convert a string into name
767      * @throws InvalidName
768      */

769
770     public NameComponent[] to_name( String JavaDoc sn )
771         throws InvalidName
772     {
773         return Name.toName( sn );
774     }
775
776
777     /**
778      *
779      */

780
781     public String JavaDoc to_url(String JavaDoc addr, String JavaDoc sn)
782         throws InvalidAddress, InvalidName
783     {
784         org.jacorb.orb.util.CorbaLoc corbaLoc;
785         try
786         {
787             corbaLoc =
788                 new org.jacorb.orb.util.CorbaLoc((org.jacorb.orb.ORB)orb, addr);
789             return corbaLoc.toCorbaName(sn);
790         }
791         catch (IllegalArgumentException JavaDoc ia)
792         {
793             throw new InvalidAddress();
794         }
795     }
796
797     /**
798      *
799      */

800
801     public org.omg.CORBA.Object JavaDoc resolve_str(String JavaDoc n)
802         throws NotFound, CannotProceed, InvalidName
803     {
804         return resolve( to_name(n));
805     }
806
807
808     /**
809      * determine if non_existent
810      */

811
812     private boolean isDead(org.omg.CORBA.Object JavaDoc o)
813     {
814         boolean non_exist = true;
815         try
816         {
817             non_exist = o._non_existent();
818         } catch (org.omg.CORBA.SystemException JavaDoc e)
819         {
820             non_exist = true;
821         }
822         return non_exist;
823     }
824 }
825
Popular Tags