1 /*
   2  * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.corba.se.impl.naming.cosnaming;
  27 
  28 // Imports for Logging
  29 import java.util.logging.Logger;
  30 import java.util.logging.Level;
  31 import com.sun.corba.se.impl.orbutil.LogKeywords;
  32 
  33 // Import general CORBA classes
  34 import org.omg.CORBA.Object;
  35 import org.omg.CORBA.BAD_PARAM;
  36 import org.omg.CORBA.INTERNAL;
  37 import org.omg.CORBA.CompletionStatus;
  38 import org.omg.PortableServer.POA;
  39 import org.omg.PortableServer.Servant;
  40 
  41 // Import org.omg.CosNaming classes
  42 import org.omg.CosNaming.BindingType;
  43 import org.omg.CosNaming.BindingTypeHolder;
  44 import org.omg.CosNaming.BindingListHolder;
  45 import org.omg.CosNaming.BindingIteratorHolder;
  46 import org.omg.CosNaming.NameComponent;
  47 import org.omg.CosNaming.NamingContextHelper;
  48 import org.omg.CosNaming.NamingContext;
  49 import org.omg.CosNaming.NamingContextPackage.*;
  50 import org.omg.CosNaming._NamingContextImplBase;
  51 import org.omg.CosNaming.NamingContextExtHelper;
  52 import org.omg.CosNaming.NamingContextExt;
  53 import org.omg.CosNaming.NamingContextExtPOA;
  54 import org.omg.CosNaming.NamingContextExtPackage.*;
  55 import org.omg.CosNaming.NamingContextPackage.NotFound;
  56 
  57 import com.sun.corba.se.impl.naming.cosnaming.NamingContextDataStore;
  58 
  59 import com.sun.corba.se.impl.naming.namingutil.INSURLHandler;
  60 import com.sun.corba.se.spi.logging.CORBALogDomains;
  61 import com.sun.corba.se.impl.logging.NamingSystemException ;
  62 
  63 import com.sun.corba.se.spi.orb.ORB;
  64 
  65 /**
  66  * Class NamingContextImpl implements the org.omg.CosNaming::NamingContext
  67  * interface, but does not implement the methods associated with
  68  * maintaining the "table" of current bindings in a NamingContext.
  69  * Instead, this implementation assumes that the derived implementation
  70  * implements the NamingContextDataStore interface, which has the necessary
  71  * methods. This allows multiple
  72  * NamingContext implementations that differ in storage of the bindings,
  73  * as well as implementations of interfaces derived from
  74  * CosNaming::NamingContext that still reuses the implementation.
  75  * <p>
  76  * The operations bind(), rebind(), bind_context() and rebind_context()
  77  * are all really implemented by doBind(). resolve() is really implemented
  78  * by doResolve(), unbind() by doUnbind(). list(), new_context() and
  79  * destroy() uses the NamingContextDataStore interface directly. All the
  80  * doX() methods are public static.
  81  * They synchronize on the NamingContextDataStore object.
  82  * <p>
  83  * An implementation a NamingContext must extend this class and implement
  84  * the NamingContextDataStore interface with the operations:
  85  * Bind(), Resolve(),
  86  * Unbind(), List(), NewContext() and Destroy(). Calls
  87  * to these methods are synchronized; these methods should
  88  * therefore not be synchronized.
  89  */
  90 public abstract class NamingContextImpl
  91     extends NamingContextExtPOA
  92     implements NamingContextDataStore
  93 {
  94 
  95     protected POA nsPOA;
  96     private Logger readLogger, updateLogger, lifecycleLogger;
  97     private NamingSystemException wrapper ;
  98     private static NamingSystemException staticWrapper =
  99         NamingSystemException.get( CORBALogDomains.NAMING_UPDATE ) ;
 100 
 101     // The grammer for Parsing and Building Interoperable Stringified Names
 102     // are implemented in this class
 103     private InterOperableNamingImpl insImpl;
 104     /**
 105      * Create a naming context servant.
 106      * Runs the super constructor.
 107      * @param orb an ORB object.
 108      * @exception java.lang.Exception a Java exception.
 109      */
 110     public NamingContextImpl(ORB orb, POA poa) throws java.lang.Exception {
 111         super();
 112         this.orb = orb;
 113         wrapper = NamingSystemException.get( orb,
 114             CORBALogDomains.NAMING_UPDATE ) ;
 115 
 116         insImpl = new InterOperableNamingImpl( );
 117         this.nsPOA = poa;
 118         readLogger = orb.getLogger( CORBALogDomains.NAMING_READ);
 119         updateLogger = orb.getLogger( CORBALogDomains.NAMING_UPDATE);
 120         lifecycleLogger = orb.getLogger(
 121             CORBALogDomains.NAMING_LIFECYCLE);
 122     }
 123 
 124     public POA getNSPOA( ) {
 125         return nsPOA;
 126     }
 127 
 128     /**
 129      * Bind an object under a name in this NamingContext. If the name
 130      * contains multiple (n) components, n-1 will be resolved in this
 131      * NamingContext and the object bound in resulting NamingContext.
 132      * An exception is thrown if a binding with the supplied name already
 133      * exists. If the
 134      * object to be bound is a NamingContext it will not participate in
 135      * a recursive resolve.
 136      * @param n a sequence of NameComponents which is the name under which
 137      * the object will be bound.
 138      * @param obj the object reference to be bound.
 139      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 140      * multiple components was supplied, but the first component could not be
 141      * resolved.
 142      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could
 143      * not proceed in resolving the n-1 components of the supplied name.
 144      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 145      * supplied name is invalid (i.e., has length less than 1).
 146      * @exception org.omg.CosNaming.NamingContextPackage.AlreadyBound An object
 147      * is already bound under the supplied name.
 148      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 149      * system exceptions.
 150      * @see doBind
 151      */
 152     public void bind(NameComponent[] n, org.omg.CORBA.Object obj)
 153         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 154                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 155                org.omg.CosNaming.NamingContextPackage.InvalidName,
 156                org.omg.CosNaming.NamingContextPackage.AlreadyBound
 157     {
 158         if( obj == null )
 159         {
 160             updateLogger.warning( LogKeywords.NAMING_BIND +
 161                 " unsuccessful because NULL Object cannot be Bound " );
 162             throw wrapper.objectIsNull() ;
 163         }
 164         // doBind implements all four flavors of binding
 165         NamingContextDataStore impl = (NamingContextDataStore)this;
 166         doBind(impl,n,obj,false,BindingType.nobject);
 167         if( updateLogger.isLoggable( Level.FINE  ) ) {
 168             // isLoggable call to make sure that we save some precious
 169             // processor cycles, if there is no need to log.
 170             updateLogger.fine( LogKeywords.NAMING_BIND_SUCCESS + " Name = " +
 171                 NamingUtils.getDirectoryStructuredName( n ) );
 172         }
 173     }
 174 
 175 
 176     /**
 177      * Bind a NamingContext under a name in this NamingContext. If the name
 178      * contains multiple (n) components, n-1 will be resolved in this
 179      * NamingContext and the object bound in resulting NamingContext.
 180      * An exception is thrown if a binding with the supplied name already
 181      * exists. The NamingContext will participate in recursive resolving.
 182      * @param n a sequence of NameComponents which is the name under which
 183      * the object will be bound.
 184      * @param nc the NamingContext object reference to be bound.
 185      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 186      * multiple components was supplied, but the first component could not be
 187      * resolved.
 188      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could
 189      * not proceed in resolving the n-1 components of the supplied name.
 190      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 191      * supplied name is invalid (i.e., has length less than 1).
 192      * @exception org.omg.CosNaming.NamingContextPackage.AlreadyBound An object
 193      * is already bound under the supplied name.
 194      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 195      * system exceptions.
 196      * @see doBind
 197      */
 198     public void bind_context(NameComponent[] n, NamingContext nc)
 199         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 200                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 201                org.omg.CosNaming.NamingContextPackage.InvalidName,
 202                org.omg.CosNaming.NamingContextPackage.AlreadyBound
 203     {
 204         if( nc == null ) {
 205             updateLogger.warning( LogKeywords.NAMING_BIND_FAILURE +
 206                 " NULL Context cannot be Bound " );
 207             throw new BAD_PARAM( "Naming Context should not be null " );
 208         }
 209         // doBind implements all four flavors of binding
 210         NamingContextDataStore impl = (NamingContextDataStore)this;
 211         doBind(impl,n,nc,false,BindingType.ncontext);
 212         if( updateLogger.isLoggable( Level.FINE ) ) {
 213             // isLoggable call to make sure that we save some precious
 214             // processor cycles, if there is no need to log.
 215             updateLogger.fine( LogKeywords.NAMING_BIND_SUCCESS + " Name = " +
 216                 NamingUtils.getDirectoryStructuredName( n ) );
 217         }
 218     }
 219 
 220     /**
 221      * Bind an object under a name in this NamingContext. If the name
 222      * contains multiple (n) components, n-1 will be resolved in this
 223      * NamingContext and the object bound in resulting NamingContext.
 224      * If a binding under the supplied name already exists it will be
 225      * unbound first. If the
 226      * object to be bound is a NamingContext it will not participate in
 227      * a recursive resolve.
 228      * @param n a sequence of NameComponents which is the name under which
 229      * the object will be bound.
 230      * @param obj the object reference to be bound.
 231      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 232      * multiple components was supplied, but the first component could not be
 233      * resolved.
 234      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 235      * proceed in resolving the n-1 components of the supplied name.
 236      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 237      * supplied name is invalid (i.e., has length less than 1).
 238      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 239      * system exceptions.
 240      * @see doBind
 241      */
 242     public  void rebind(NameComponent[] n, org.omg.CORBA.Object obj)
 243         throws       org.omg.CosNaming.NamingContextPackage.NotFound,
 244                      org.omg.CosNaming.NamingContextPackage.CannotProceed,
 245                      org.omg.CosNaming.NamingContextPackage.InvalidName
 246     {
 247         if( obj == null )
 248         {
 249             updateLogger.warning( LogKeywords.NAMING_REBIND_FAILURE +
 250                 " NULL Object cannot be Bound " );
 251             throw wrapper.objectIsNull() ;
 252         }
 253         try {
 254             // doBind implements all four flavors of binding
 255             NamingContextDataStore impl = (NamingContextDataStore)this;
 256             doBind(impl,n,obj,true,BindingType.nobject);
 257         } catch (org.omg.CosNaming.NamingContextPackage.AlreadyBound ex) {
 258             updateLogger.warning( LogKeywords.NAMING_REBIND_FAILURE +
 259                 NamingUtils.getDirectoryStructuredName( n ) +
 260                 " is already bound to a Naming Context" );
 261             // This should not happen
 262             throw wrapper.namingCtxRebindAlreadyBound( ex ) ;
 263         }
 264         if( updateLogger.isLoggable( Level.FINE  ) ) {
 265             // isLoggable call to make sure that we save some precious
 266             // processor cycles, if there is no need to log.
 267             updateLogger.fine( LogKeywords.NAMING_REBIND_SUCCESS + " Name = " +
 268                 NamingUtils.getDirectoryStructuredName( n ) );
 269         }
 270     }
 271 
 272     /**
 273      * Bind a NamingContext under a name in this NamingContext. If the name
 274      * contains multiple (n) components, the first n-1 components will be
 275      * resolved in this NamingContext and the object bound in resulting
 276      * NamingContext. If a binding under the supplied name already exists it
 277      * will be unbound first. The NamingContext will participate in recursive
 278      * resolving.
 279      * @param n a sequence of NameComponents which is the name under which
 280      * the object will be bound.
 281      * @param nc the object reference to be bound.
 282      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 283      * multiple components was supplied, but the first component could not be
 284      * resolved.
 285      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 286      * proceed in resolving the n-1 components of the supplied name.
 287      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 288      * supplied name is invalid (i.e., has length less than 1).
 289      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 290      * system exceptions.
 291      * @see doBind
 292      */
 293     public  void rebind_context(NameComponent[] n, NamingContext nc)
 294         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 295                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 296                org.omg.CosNaming.NamingContextPackage.InvalidName
 297     {
 298         if( nc == null )
 299         {
 300             updateLogger.warning( LogKeywords.NAMING_REBIND_FAILURE +
 301                 " NULL Context cannot be Bound " );
 302             throw wrapper.objectIsNull() ;
 303         }
 304         try {
 305             // doBind implements all four flavors of binding
 306             NamingContextDataStore impl = (NamingContextDataStore)this;
 307             doBind(impl,n,nc,true,BindingType.ncontext);
 308         } catch (org.omg.CosNaming.NamingContextPackage.AlreadyBound ex) {
 309             // This should not happen
 310             updateLogger.warning( LogKeywords.NAMING_REBIND_FAILURE +
 311                 NamingUtils.getDirectoryStructuredName( n ) +
 312                 " is already bound to a CORBA Object" );
 313             throw wrapper.namingCtxRebindctxAlreadyBound( ex ) ;
 314         }
 315         if( updateLogger.isLoggable( Level.FINE ) ) {
 316             // isLoggable call to make sure that we save some precious
 317             // processor cycles, if there is no need to log.
 318             updateLogger.fine( LogKeywords.NAMING_REBIND_SUCCESS + " Name = " +
 319                 NamingUtils.getDirectoryStructuredName( n ) );
 320         }
 321     }
 322 
 323     /**
 324      * Resolve a name in this NamingContext and return the object reference
 325      * bound to the name. If the name contains multiple (n) components,
 326      * the first component will be resolved in this NamingContext and the
 327      * remaining components resolved in the resulting NamingContext, provided
 328      * that the NamingContext bound to the first component of the name was
 329      * bound with bind_context().
 330      * @param n a sequence of NameComponents which is the name to be resolved.
 331      * @return the object reference bound under the supplied name.
 332      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 333      * multiple components was supplied, but the first component could not be
 334      * resolved.
 335      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 336      * proceed in resolving the n-1 components of the supplied name.
 337      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 338      * supplied name is invalid (i.e., has length less than 1).
 339      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 340      * system exceptions.
 341      * @see doResolve
 342      */
 343     public  org.omg.CORBA.Object resolve(NameComponent[] n)
 344         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 345                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 346                org.omg.CosNaming.NamingContextPackage.InvalidName
 347     {
 348         // doResolve actually resolves
 349         NamingContextDataStore impl = (NamingContextDataStore)this;
 350         org.omg.CORBA.Object obj = doResolve(impl,n);
 351         if( obj != null ) {
 352             if( readLogger.isLoggable( Level.FINE ) ) {
 353                  readLogger.fine( LogKeywords.NAMING_RESOLVE_SUCCESS +
 354                  " Name: " + NamingUtils.getDirectoryStructuredName( n ) );
 355             }
 356         } else {
 357              readLogger.warning( LogKeywords.NAMING_RESOLVE_FAILURE +
 358                  " Name: " + NamingUtils.getDirectoryStructuredName( n ) );
 359         }
 360         return obj;
 361     }
 362 
 363 
 364     /**
 365      * Remove a binding from this NamingContext. If the name contains
 366      * multiple (n) components, the first n-1 components will be resolved
 367      * from this NamingContext and the final component unbound in
 368      * the resulting NamingContext.
 369      * @param n a sequence of NameComponents which is the name to be unbound.
 370      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 371      * multiple components was supplied, but the first component could not be
 372      * resolved.
 373      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 374      * proceed in resolving the n-1 components of the supplied name.
 375      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 376      * supplied name is invalid (i.e., has length less than 1).
 377      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 378      * system exceptions.
 379      * @see doUnbind
 380      */
 381     public  void unbind(NameComponent[] n)
 382         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 383                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 384                org.omg.CosNaming.NamingContextPackage.InvalidName
 385     {
 386         // doUnbind actually unbinds
 387         NamingContextDataStore impl = (NamingContextDataStore)this;
 388         doUnbind(impl,n);
 389         if( updateLogger.isLoggable( Level.FINE ) ) {
 390             // isLoggable call to make sure that we save some precious
 391             // processor cycles, if there is no need to log.
 392             updateLogger.fine( LogKeywords.NAMING_UNBIND_SUCCESS +
 393                 " Name: " + NamingUtils.getDirectoryStructuredName( n ) );
 394         }
 395     }
 396 
 397     /**
 398      * List the contents of this NamingContest. A sequence of bindings
 399      * is returned (a BindingList) containing up to the number of requested
 400      * bindings, and a BindingIterator object reference is returned for
 401      * iterating over the remaining bindings.
 402      * @param how_many The number of requested bindings in the BindingList.
 403      * @param bl The BindingList as an out parameter.
 404      * @param bi The BindingIterator as an out parameter.
 405      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 406      * system exceptions.
 407      * @see BindingListHolder
 408      * @see BindingIteratorImpl
 409      */
 410     public  void list(int how_many, BindingListHolder bl,
 411         BindingIteratorHolder bi)
 412     {
 413         // List actually generates the list
 414         NamingContextDataStore impl = (NamingContextDataStore)this;
 415         synchronized (impl) {
 416             impl.List(how_many,bl,bi);
 417         }
 418         if( readLogger.isLoggable( Level.FINE ) && (bl.value != null )) {
 419             // isLoggable call to make sure that we save some precious
 420             // processor cycles, if there is no need to log.
 421             readLogger.fine ( LogKeywords.NAMING_LIST_SUCCESS +
 422                 "list(" + how_many + ") -> bindings[" + bl.value.length +
 423                 "] + iterator: " + bi.value);
 424         }
 425     }
 426 
 427     /**
 428      * Create a NamingContext object and return its object reference.
 429      * @return an object reference for a new NamingContext object implemented
 430      * by this Name Server.
 431      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 432      * system exceptions.
 433      */
 434     public synchronized NamingContext new_context()
 435     {
 436         // Create actually creates a new naming context
 437         lifecycleLogger.fine( "Creating New Naming Context " );
 438         NamingContextDataStore impl = (NamingContextDataStore)this;
 439         synchronized (impl) {
 440             NamingContext nctx = impl.NewContext();
 441             if( nctx != null ) {
 442                 lifecycleLogger.fine( LogKeywords.LIFECYCLE_CREATE_SUCCESS );
 443             } else {
 444                 // If naming context is null, then that must be a serious
 445                 // error.
 446                 lifecycleLogger.severe ( LogKeywords.LIFECYCLE_CREATE_FAILURE );
 447             }
 448             return nctx;
 449         }
 450     }
 451 
 452     /**
 453      * Create a new NamingContext, bind it in this Naming Context and return
 454      * its object reference. This is equivalent to using new_context() followed
 455      * by bind_context() with the supplied name and the object reference for
 456      * the newly created NamingContext.
 457      * @param n a sequence of NameComponents which is the name to be unbound.
 458      * @return an object reference for a new NamingContext object implemented
 459      * by this Name Server, bound to the supplied name.
 460      * @exception org.omg.CosNaming.NamingContextPackage.AlreadyBound An object
 461      * is already bound under the supplied name.
 462      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 463      * multiple components was supplied, but the first component could not be
 464      * resolved.
 465      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 466      * proceed in resolving the n-1 components of the supplied name.
 467      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 468      * supplied name is invalid (i.e., has length less than 1).
 469      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 470      * system exceptions.
 471      * @see new_context
 472      * @see bind_context
 473      */
 474     public  NamingContext bind_new_context(NameComponent[] n)
 475         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 476                org.omg.CosNaming.NamingContextPackage.AlreadyBound,
 477                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 478                org.omg.CosNaming.NamingContextPackage.InvalidName
 479     {
 480         NamingContext nc = null;
 481         NamingContext rnc = null;
 482         try {
 483             if (debug)
 484                 dprint("bind_new_context " + nameToString(n));
 485             // The obvious solution:
 486             nc = this.new_context();
 487             this.bind_context(n,nc);
 488             rnc = nc;
 489             nc = null;
 490         } finally {
 491             try {
 492                 if(nc != null)
 493                     nc.destroy();
 494             } catch (org.omg.CosNaming.NamingContextPackage.NotEmpty e) {
 495             }
 496         }
 497         if( updateLogger.isLoggable( Level.FINE ) ) {
 498             // isLoggable call to make sure that we save some precious
 499             // processor cycles, if there is no need to log.
 500             updateLogger.fine ( LogKeywords.NAMING_BIND +
 501                 "New Context Bound To " +
 502                 NamingUtils.getDirectoryStructuredName( n ) );
 503         }
 504         return rnc;
 505     }
 506 
 507     /**
 508      * Destroy this NamingContext object. If this NamingContext contains
 509      * no bindings, the NamingContext is deleted.
 510      * @exception org.omg.CosNaming.NamingContextPackage.NotEmpty This
 511      * NamingContext is not empty (i.e., contains bindings).
 512      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 513      * system exceptions.
 514      */
 515     public  void destroy()
 516         throws org.omg.CosNaming.NamingContextPackage.NotEmpty
 517     {
 518         lifecycleLogger.fine( "Destroying Naming Context " );
 519         NamingContextDataStore impl = (NamingContextDataStore)this;
 520         synchronized (impl) {
 521             if (impl.IsEmpty() == true) {
 522                 // The context is empty so it can be destroyed
 523                 impl.Destroy();
 524                 lifecycleLogger.fine ( LogKeywords.LIFECYCLE_DESTROY_SUCCESS );
 525             }
 526             else {
 527                 // This context is not empty!
 528                 // Not a fatal error, warning should do.
 529                 lifecycleLogger.warning( LogKeywords.LIFECYCLE_DESTROY_FAILURE +
 530                     " NamingContext children are not destroyed still.." );
 531                 throw new NotEmpty();
 532             }
 533         }
 534     }
 535 
 536     /**
 537      * Implements all four flavors of binding. It uses Resolve() to
 538      * check if a binding already exists (for bind and bind_context), and
 539      * unbind() to ensure that a binding does not already exist.
 540      * If the length of the name is 1, then Bind() is called with
 541      * the name and the object to bind. Otherwise, the first component
 542      * of the name is resolved in this NamingContext and the appropriate
 543      * form of bind passed to the resulting NamingContext.
 544      * This method is static for maximal reuse - even for extended naming
 545      * context implementations where the recursive semantics still apply.
 546      * @param impl an implementation of NamingContextDataStore
 547      * @param n a sequence of NameComponents which is the name under which
 548      * the object will be bound.
 549      * @param obj the object reference to be bound.
 550      * @param rebind Replace an existing binding or not.
 551      * @param bt Type of binding (as object or as context).
 552      * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 553      * multiple components was supplied, but the first component could not be
 554      * resolved.
 555      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not     * proceed
 556      * in resolving the first component of the supplied name.
 557      * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The
 558      * supplied name is invalid (i.e., has length less than 1).
 559      * @exception org.omg.CosNaming.NamingContextPackage.AlreadyBound An object
 560      * is already bound under the supplied name.
 561      * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA
 562      * system exceptions.
 563      * @see resolve
 564      * @see unbind
 565      * @see bind
 566      * @see bind_context
 567      * @see rebind
 568      * @see rebind_context
 569      */
 570     public static void doBind(NamingContextDataStore impl,
 571                               NameComponent[] n,
 572                               org.omg.CORBA.Object obj,
 573                               boolean rebind,
 574                               org.omg.CosNaming.BindingType bt)
 575         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 576                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 577                org.omg.CosNaming.NamingContextPackage.InvalidName,
 578                org.omg.CosNaming.NamingContextPackage.AlreadyBound
 579     {
 580         // Valid name?
 581         if (n.length < 1)
 582             throw new InvalidName();
 583 
 584     // At bottom level?
 585         if (n.length == 1) {
 586             // The identifier must be set
 587             if ( (n[0].id.length() == 0) && (n[0].kind.length() == 0 ) ) {
 588                 throw new InvalidName();
 589             }
 590 
 591             // Ensure synchronization of backend
 592             synchronized (impl) {
 593                 // Yes: bind object in this context under the name
 594                 BindingTypeHolder bth = new BindingTypeHolder();
 595                 if (rebind) {
 596                     org.omg.CORBA.Object objRef = impl.Resolve( n[0], bth );
 597                     if( objRef != null ) {
 598                         // Refer Naming Service Doc:00-11-01 section 2.2.3.4
 599                         // If there is an object already bound with the name
 600                         // and the binding type is not ncontext a NotFound
 601                         // Exception with a reason of not a context has to be
 602                         // raised.
 603                         // Fix for bug Id: 4384628
 604                         if ( bth.value.value() == BindingType.nobject.value() ){
 605                             if ( bt.value() == BindingType.ncontext.value() ) {
 606                                 throw new NotFound(
 607                                     NotFoundReason.not_context, n);
 608                             }
 609                         } else {
 610                             // Previously a Context was bound and now trying to
 611                             // bind Object. It is invalid.
 612                             if ( bt.value() == BindingType.nobject.value() ) {
 613                                 throw new NotFound(
 614                                     NotFoundReason.not_object, n);
 615                             }
 616                         }
 617                         impl.Unbind(n[0]);
 618                     }
 619 
 620                 } else {
 621                     if (impl.Resolve(n[0],bth) != null)
 622                         // "Resistence is futile." [Borg pickup line]
 623                         throw new AlreadyBound();
 624                 }
 625 
 626                 // Now there are no other bindings under this name
 627                 impl.Bind(n[0],obj,bt);
 628             }
 629         } else {
 630             // No: bind in a different context
 631             NamingContext context = resolveFirstAsContext(impl,n);
 632 
 633             // Compute tail
 634             NameComponent[] tail = new NameComponent[n.length - 1];
 635             System.arraycopy(n,1,tail,0,n.length-1);
 636 
 637       // How should we propagate the bind
 638             switch (bt.value()) {
 639             case BindingType._nobject:
 640                 {
 641                     // Bind as object
 642                     if (rebind)
 643                         context.rebind(tail,obj);
 644                     else
 645                         context.bind(tail,obj);
 646                 }
 647                 break;
 648             case BindingType._ncontext:
 649                 {
 650                     // Narrow to a naming context using Java casts. It must
 651                     // work.
 652                     NamingContext objContext = (NamingContext)obj;
 653                     // Bind as context
 654                     if (rebind)
 655                         context.rebind_context(tail,objContext);
 656                     else
 657                         context.bind_context(tail,objContext);
 658                 }
 659                 break;
 660             default:
 661                 // This should not happen
 662                 throw staticWrapper.namingCtxBadBindingtype() ;
 663             }
 664         }
 665     }
 666 
 667     /**
 668    * Implements resolving names in this NamingContext. The first component
 669    * of the supplied name is resolved in this NamingContext by calling
 670    * Resolve(). If there are no more components in the name, the
 671    * resulting object reference is returned. Otherwise, the resulting object
 672    * reference must have been bound as a context and be narrowable to
 673    * a NamingContext. If this is the case, the remaining
 674    * components of the name is resolved in the resulting NamingContext.
 675    * This method is static for maximal reuse - even for extended naming
 676    * context implementations where the recursive semantics still apply.
 677    * @param impl an implementation of NamingContextDataStore
 678    * @param n a sequence of NameComponents which is the name to be resolved.
 679    * @return the object reference bound under the supplied name.
 680    * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with
 681    * multiple components was supplied, but the first component could not be
 682    * resolved.
 683    * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not
 684    * proceed
 685    * in resolving the first component of the supplied name.
 686    * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The supplied
 687    * name is invalid (i.e., has length less than 1).
 688    * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA system
 689    * exceptions.
 690    * @see resolve
 691    */
 692     public static org.omg.CORBA.Object doResolve(NamingContextDataStore impl,
 693                                                  NameComponent[] n)
 694         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 695                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 696                org.omg.CosNaming.NamingContextPackage.InvalidName
 697     {
 698         org.omg.CORBA.Object obj = null;
 699         BindingTypeHolder bth = new BindingTypeHolder();
 700 
 701 
 702         // Length must be greater than 0
 703         if (n.length < 1)
 704             throw new InvalidName();
 705 
 706         // The identifier must be set
 707         if (n.length == 1) {
 708             synchronized (impl) {
 709                 // Resolve first level in this context
 710                 obj = impl.Resolve(n[0],bth);
 711             }
 712             if (obj == null) {
 713                 // Object was not found
 714                 throw new NotFound(NotFoundReason.missing_node,n);
 715             }
 716             return obj;
 717         } else {
 718             // n.length > 1
 719             if ( (n[1].id.length() == 0) && (n[1].kind.length() == 0) ) {
 720                 throw new InvalidName();
 721             }
 722 
 723             NamingContext context = resolveFirstAsContext(impl,n);
 724 
 725             // Compute restOfName = name[1..length]
 726             NameComponent[] tail = new NameComponent[n.length -1];
 727             System.arraycopy(n,1,tail,0,n.length-1);
 728 
 729             // Resolve rest of name in context
 730             try {
 731                 // First try to resolve using the local call, this should work
 732                 // most of the time unless there are federated naming contexts.
 733                 Servant servant = impl.getNSPOA().reference_to_servant(
 734                     context );
 735                 return doResolve(((NamingContextDataStore)servant), tail) ;
 736             } catch( Exception e ) {
 737                 return context.resolve(tail);
 738             }
 739         }
 740     }
 741 
 742     /**
 743    * Implements unbinding bound names in this NamingContext. If the
 744    * name contains only one component, the name is unbound in this
 745    * NamingContext using Unbind(). Otherwise, the first component
 746    * of the name is resolved in this NamingContext and
 747    * unbind passed to the resulting NamingContext.
 748    * This method is static for maximal reuse - even for extended naming
 749    * context implementations where the recursive semantics still apply.
 750    * @param impl an implementation of NamingContextDataStore
 751    * @param n a sequence of NameComponents which is the name to be unbound.
 752    * @exception org.omg.CosNaming.NamingContextPackage.NotFound A name with multiple
 753    * components was supplied, but the first component could not be
 754    * resolved.
 755    * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not proceed
 756    * in resolving the n-1 components of the supplied name.
 757    * @exception org.omg.CosNaming.NamingContextPackage.InvalidName The supplied name
 758    * is invalid (i.e., has length less than 1).
 759    * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA system exceptions.
 760    * @see resolve
 761    */
 762     public static void doUnbind(NamingContextDataStore impl,
 763                                 NameComponent[] n)
 764         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 765                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 766                org.omg.CosNaming.NamingContextPackage.InvalidName
 767     {
 768         // Name valid?
 769         if (n.length < 1)
 770             throw new InvalidName();
 771 
 772     // Unbind here?
 773         if (n.length == 1) {
 774             // The identifier must be set
 775             if ( (n[0].id.length() == 0) && (n[0].kind.length() == 0 ) ) {
 776                 throw new InvalidName();
 777             }
 778 
 779             org.omg.CORBA.Object objRef = null;
 780             synchronized (impl) {
 781                 // Yes: unbind in this context
 782                 objRef = impl.Unbind(n[0]);
 783             }
 784 
 785             if (objRef == null)
 786                 // It was not bound
 787                 throw new NotFound(NotFoundReason.missing_node,n);
 788             // Done
 789             return;
 790         } else {
 791             // No: unbind in a different context
 792 
 793       // Resolve first  - must be resolveable
 794             NamingContext context = resolveFirstAsContext(impl,n);
 795 
 796             // Compute tail
 797             NameComponent[] tail = new NameComponent[n.length - 1];
 798             System.arraycopy(n,1,tail,0,n.length-1);
 799 
 800       // Propagate unbind to this context
 801             context.unbind(tail);
 802         }
 803     }
 804 
 805     /**
 806    * Implements resolving a NameComponent in this context and
 807    * narrowing it to CosNaming::NamingContext. It will throw appropriate
 808    * exceptions if not found or not narrowable.
 809    * @param impl an implementation of NamingContextDataStore
 810    * @param n a NameComponents which is the name to be found.
 811    * @exception org.omg.CosNaming.NamingContextPackage.NotFound The
 812    * first component could not be resolved.
 813    * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed Could not proceed
 814    * in resolving the first component of the supplied name.
 815    * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA system exceptions.
 816    * @see resolve
 817    */
 818     protected static NamingContext resolveFirstAsContext(NamingContextDataStore impl,
 819                                                          NameComponent[] n)
 820         throws org.omg.CosNaming.NamingContextPackage.NotFound {
 821         org.omg.CORBA.Object topRef = null;
 822         BindingTypeHolder bth = new BindingTypeHolder();
 823         NamingContext context = null;
 824 
 825         synchronized (impl) {
 826             // Resolve first  - must be resolveable
 827             topRef = impl.Resolve(n[0],bth);
 828             if (topRef == null) {
 829                 // It was not bound
 830                 throw new NotFound(NotFoundReason.missing_node,n);
 831             }
 832         }
 833 
 834         // Was it bound as a context?
 835         if (bth.value != BindingType.ncontext) {
 836             // It was not a context
 837             throw new NotFound(NotFoundReason.not_context,n);
 838         }
 839 
 840         // Narrow to a naming context
 841         try {
 842             context = NamingContextHelper.narrow(topRef);
 843         } catch (org.omg.CORBA.BAD_PARAM ex) {
 844             // It was not a context
 845             throw new NotFound(NotFoundReason.not_context,n);
 846         }
 847 
 848         // Hmm. must be ok
 849         return context;
 850     }
 851 
 852 
 853    /**
 854     * This operation creates a stringified name from the array of Name
 855     * components.
 856     * @param n Name of the object
 857     * @exception org.omg.CosNaming.NamingContextExtPackage.InvalidName
 858     * Indicates the name does not identify a binding.
 859     */
 860     public String to_string(org.omg.CosNaming.NameComponent[] n)
 861          throws org.omg.CosNaming.NamingContextPackage.InvalidName
 862     {
 863         // Name valid?
 864         if ( (n == null ) || (n.length == 0) )
 865         {
 866                 throw new InvalidName();
 867         }
 868         NamingContextDataStore impl = (NamingContextDataStore)this;
 869 
 870         String theStringifiedName = insImpl.convertToString( n );
 871 
 872         if( theStringifiedName == null )
 873         {
 874                 throw new InvalidName();
 875         }
 876 
 877         return theStringifiedName;
 878     }
 879 
 880 
 881    /**
 882     * This operation  converts a Stringified Name into an  equivalent array
 883     * of Name Components.
 884     * @param sn Stringified Name of the object
 885     * @exception org.omg.CosNaming.NamingContextExtPackage.InvalidName
 886     * Indicates the name does not identify a binding.
 887     */
 888     public org.omg.CosNaming.NameComponent[] to_name(String sn)
 889          throws org.omg.CosNaming.NamingContextPackage.InvalidName
 890     {
 891         // Name valid?
 892         if  ( (sn == null ) || (sn.length() == 0) )
 893         {
 894                 throw new InvalidName();
 895         }
 896         NamingContextDataStore impl = (NamingContextDataStore)this;
 897         org.omg.CosNaming.NameComponent[] theNameComponents =
 898                 insImpl.convertToNameComponent( sn );
 899         if( ( theNameComponents == null ) || (theNameComponents.length == 0 ) )
 900         {
 901                 throw new InvalidName();
 902         }
 903         for( int i = 0; i < theNameComponents.length; i++ ) {
 904             // If there is a name component whose id and kind null or
 905             // zero length string, then an invalid name exception needs to be
 906             // raised.
 907             if ( ( ( theNameComponents[i].id  == null )
 908                  ||( theNameComponents[i].id.length() == 0 ) )
 909                &&( ( theNameComponents[i].kind == null )
 910                  ||( theNameComponents[i].kind.length() == 0 ) ) ) {
 911                 throw new InvalidName();
 912             }
 913         }
 914         return theNameComponents;
 915     }
 916 
 917    /**
 918     * This operation creates a URL based "iiopname://" format name
 919     * from the Stringified Name of the object.
 920     * @param addr internet based address of the host machine where
 921     * Name Service is running
 922     * @param sn Stringified Name of the object
 923     * @exception org.omg.CosNaming.NamingContextExtPackage.InvalidName
 924     * Indicates the name does not identify a binding.
 925     * @exception org.omg.CosNaming.NamingContextPackage.InvalidAddress
 926     * Indicates the internet based address of the host machine is
 927     * incorrect
 928     */
 929 
 930     public String to_url(String addr, String sn)
 931         throws org.omg.CosNaming.NamingContextExtPackage.InvalidAddress,
 932                org.omg.CosNaming.NamingContextPackage.InvalidName
 933     {
 934         // Name valid?
 935         if  ( (sn == null ) || (sn.length() == 0) )
 936         {
 937             throw new InvalidName();
 938         }
 939         if( addr == null )
 940         {
 941             throw new
 942                 org.omg.CosNaming.NamingContextExtPackage.InvalidAddress();
 943         }
 944         NamingContextDataStore impl = (NamingContextDataStore)this;
 945         String urlBasedAddress = null;
 946         urlBasedAddress = insImpl.createURLBasedAddress( addr, sn );
 947         // Extra check to see that corba name url created is valid as per
 948         // INS spec grammer.
 949         try {
 950             INSURLHandler.getINSURLHandler( ).parseURL( urlBasedAddress );
 951         } catch( BAD_PARAM e ) {
 952             throw new
 953                 org.omg.CosNaming.NamingContextExtPackage.InvalidAddress();
 954         }
 955         return urlBasedAddress;
 956     }
 957 
 958     /**
 959      * This operation resolves the Stringified name into the object
 960      * reference.
 961      * @param sn Stringified Name of the object
 962      * @exception org.omg.CosNaming.NamingContextPackage.NotFound
 963      * Indicates there is no object reference for the given name.
 964      * @exception org.omg.CosNaming.NamingContextPackage.CannotProceed
 965      * Indicates that the given compound name is incorrect
 966      * @exception org.omg.CosNaming.NamingContextExtPackage.InvalidName
 967      * Indicates the name does not identify a binding.
 968      * @exception org.omg.CosNaming.NamingContextPackage.AlreadyBound
 969      * Indicates the name is already bound.
 970      *
 971      */
 972     public org.omg.CORBA.Object resolve_str(String sn)
 973         throws org.omg.CosNaming.NamingContextPackage.NotFound,
 974                org.omg.CosNaming.NamingContextPackage.CannotProceed,
 975                org.omg.CosNaming.NamingContextPackage.InvalidName
 976     {
 977         org.omg.CORBA.Object theObject = null;
 978         // Name valid?
 979         if  ( (sn == null ) || (sn.length() == 0) )
 980         {
 981                 throw new InvalidName();
 982         }
 983         NamingContextDataStore impl = (NamingContextDataStore)this;
 984         org.omg.CosNaming.NameComponent[] theNameComponents =
 985                 insImpl.convertToNameComponent( sn );
 986 
 987         if( ( theNameComponents == null ) || (theNameComponents.length == 0 ) )
 988         {
 989                 throw new InvalidName();
 990         }
 991         theObject = resolve( theNameComponents );
 992         return theObject;
 993     }
 994 
 995 
 996     transient protected ORB orb;
 997 
 998     public static String nameToString(NameComponent[] name)
 999     {
1000         StringBuffer s = new StringBuffer("{");
1001         if (name != null || name.length > 0) {
1002             for (int i=0;i<name.length;i++) {
1003                 if (i>0)
1004                     s.append(",");
1005                 s.append("[").
1006                     append(name[i].id).
1007                     append(",").
1008                     append(name[i].kind).
1009                     append("]");
1010             }
1011         }
1012         s.append("}");
1013         return s.toString();
1014     }
1015 
1016     // Debugging aids.
1017     public static final boolean debug = false;
1018 
1019     private static void dprint(String msg) {
1020         NamingUtils.dprint("NamingContextImpl("  +
1021                            Thread.currentThread().getName() + " at " +
1022                            System.currentTimeMillis() +
1023                            " ems): " + msg);
1024     }
1025 }