src/share/classes/com/sun/jndi/cosnaming/CNCtx.java

Print this page


   1 /*
   2  * Copyright (c) 1999, 2005, 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.jndi.cosnaming;
  27 
  28 import javax.naming.*;
  29 import javax.naming.spi.NamingManager;
  30 import javax.naming.spi.ResolveResult;
  31 
  32 import java.util.Hashtable;
  33 import java.util.Vector;
  34 import java.net.MalformedURLException;
  35 import java.net.URL;
  36 import java.io.InputStream;
  37 import java.io.InputStreamReader;
  38 import java.io.BufferedReader;
  39 import java.io.IOException;
  40 
  41 import org.omg.CosNaming.*;
  42 import org.omg.CosNaming.NamingContextPackage.*;
  43 import org.omg.CORBA.*;
  44 
  45 import com.sun.jndi.toolkit.corba.CorbaUtils;
  46 
  47 // Needed for creating default ORB
  48 import java.applet.Applet;
  49 
  50 /**
  51   * Provides a bridge to the CosNaming server provided by
  52   * JavaIDL. This class provides the InitialContext from CosNaming.
  53   *
  54   * @author Raj Krishnamurthy
  55   * @author Rosanna Lee
  56   */
  57 
  58 public class CNCtx implements javax.naming.Context {
  59 
  60     private final static boolean debug = false;
  61 
  62     ORB _orb;                   // used by ExceptionMapper and RMI/IIOP factory
  63     public NamingContext _nc;   // public for accessing underlying NamingContext
  64     private NameComponent[] _name = null;
  65 
  66     Hashtable _env; // used by ExceptionMapper
  67     static final CNNameParser parser = new CNNameParser();
  68 
  69     private static final String FED_PROP = "com.sun.jndi.cosnaming.federation";
  70     boolean federation = false;
  71 
  72     // Reference counter for tracking _orb references
  73     OrbReuseTracker orbTracker = null;
  74     int enumCount;
  75     boolean isCloseCalled = false;
  76 
  77     /**
  78       * Create a CNCtx object. Gets the initial naming
  79       * reference for the COS Naming Service from the ORB.
  80       * The ORB can be passed in via the java.naming.corba.orb property
  81       * or be created using properties in the environment properties.
  82       * @param env Environment properties for initializing name service.
  83       * @exception NamingException Cannot initialize ORB or naming context.
  84       */
  85     CNCtx(Hashtable env) throws NamingException {

  86         if (env != null) {
  87             env = (Hashtable) env.clone();
  88         }
  89         _env = env;
  90         federation = "true".equals(env != null ? env.get(FED_PROP) : null);
  91         initOrbAndRootContext(env);
  92     }
  93 
  94     private CNCtx() {
  95     }
  96 
  97     /**
  98      * This method is used by the iiop and iiopname URL Context factories.
  99      */
 100     public static ResolveResult createUsingURL(String url, Hashtable env)

 101     throws NamingException {
 102         CNCtx ctx = new CNCtx();
 103         if (env != null) {
 104             env = (Hashtable) env.clone();
 105         }
 106         ctx._env = env;
 107         String rest = ctx.initUsingUrl(
 108             env != null ?
 109                 (org.omg.CORBA.ORB) env.get("java.naming.corba.orb")
 110                 : null,
 111             url, env);
 112 
 113         // rest is the INS name
 114         // Return the parsed form to prevent subsequent lookup
 115         // from parsing the string as a composite name
 116         // The caller should be aware that a toString() of the name
 117         // will yield its INS syntax, rather than a composite syntax
 118         return new ResolveResult(ctx, parser.parse(rest));
 119     }
 120 
 121     /**
 122       * Creates a CNCtx object which supports the javax.naming
 123       * apis given a COS Naming Context object.
 124       * @param orb The ORB used by this context
 125       * @param tracker The ORB reuse tracker for tracking references to the
 126       *  orb object
 127       * @param nctx The COS NamingContext object associated with this context
 128       * @param name The name of this context relative to the root
 129       */
 130 
 131     CNCtx(ORB orb, OrbReuseTracker tracker, NamingContext nctx, Hashtable env,
 132                         NameComponent[]name)
 133         throws NamingException {
 134             if (orb == null || nctx == null)
 135                 throw new ConfigurationException(
 136                     "Must supply ORB or NamingContext");
 137             _orb = orb;
 138             orbTracker = tracker;
 139             if (orbTracker != null) {
 140                 orbTracker.incRefCount();
 141             }
 142             _nc = nctx;
 143             _env = env;
 144             _name = name;
 145             federation = "true".equals(env != null ? env.get(FED_PROP) : null);
 146     }
 147 
 148     NameComponent[] makeFullName(NameComponent[] child) {
 149         if (_name == null || _name.length == 0) {
 150             return child;
 151         }
 152         NameComponent[] answer = new NameComponent[_name.length+child.length];


 190       * _orb is obtained from java.naming.corba.orb if it has been set.
 191       * Otherwise, _orb is created using the host/port from PROVIDER_URL
 192       * (if it contains an "iiop" or "iiopname" URL), or from initialization
 193       * properties specified in env.
 194       *<p>
 195       * _nc is obtained from the IOR stored in PROVIDER_URL if it has been
 196       * set and does not contain an "iiop" or "iiopname" URL. It can be
 197       * a stringified IOR, "corbaloc" URL, "corbaname" URL,
 198       * or a URL (such as file/http/ftp) to a location
 199       * containing a stringified IOR. If PROVIDER_URL has not been
 200       * set in this way, it is obtained from the result of
 201       *     ORB.resolve_initial_reference("NameService");
 202       *<p>
 203       * _name is obtained from the "iiop", "iiopname", or "corbaname" URL.
 204       * It is the empty name by default.
 205       *
 206       * @param env Environment The possibly null environment.
 207       * @exception NamingException When an error occurs while initializing the
 208       * ORB or the naming context.
 209       */
 210     private void initOrbAndRootContext(Hashtable env) throws NamingException {
 211         org.omg.CORBA.ORB inOrb = null;
 212         String ncIor = null;
 213 
 214         if (env != null) {
 215             inOrb = (org.omg.CORBA.ORB) env.get("java.naming.corba.orb");
 216         }
 217 
 218         // Extract PROVIDER_URL from environment
 219         String provUrl = null;
 220         if (env != null) {
 221             provUrl = (String)env.get(javax.naming.Context.PROVIDER_URL);
 222         }
 223 
 224         if (provUrl != null && !isCorbaUrl(provUrl)) {
 225             // Initialize the root naming context by using the IOR supplied
 226             // in the PROVIDER_URL
 227             ncIor = getStringifiedIor(provUrl);
 228 
 229             if (inOrb == null) {
 230 
 231                 // no ORB instance specified; create one using env and defaults
 232                 inOrb = CorbaUtils.getOrb(null, -1, env);
 233                 orbTracker = new OrbReuseTracker(inOrb);
 234             }
 235             setOrbAndRootContext(inOrb, ncIor);
 236         } else if (provUrl != null) {
 237             // Initialize the root naming context by using the URL supplied
 238             // in the PROVIDER_URL
 239             String insName = initUsingUrl(inOrb, provUrl, env);
 240 
 241             // If name supplied in URL, resolve it to a NamingContext
 242             if (insName.length() > 0) {
 243                 _name = parser.nameToCosName(parser.parse(insName));
 244                 try {
 245                     org.omg.CORBA.Object obj = _nc.resolve(_name);
 246                     _nc = NamingContextHelper.narrow(obj);
 247                     if (_nc == null) {
 248                         throw new ConfigurationException(insName +
 249                             " does not name a NamingContext");
 250                     }
 251                 } catch (org.omg.CORBA.BAD_PARAM e) {
 252                     throw new ConfigurationException(insName +
 253                         " does not name a NamingContext");
 254                 } catch (Exception e) {
 255                     throw ExceptionMapper.mapException(e, this, _name);
 256                 }
 257             }
 258         } else {
 259             // No PROVIDER_URL supplied; initialize using defaults
 260             if (inOrb == null) {
 261 
 262                 // No ORB instance specified; create one using env and defaults
 263                 inOrb = CorbaUtils.getOrb(null, -1, env);
 264                 orbTracker = new OrbReuseTracker(inOrb);
 265                 if (debug) {
 266                     System.err.println("Getting default ORB: " + inOrb + env);
 267                 }
 268             }
 269             setOrbAndRootContext(inOrb, (String)null);
 270         }
 271     }
 272 
 273 
 274     private String initUsingUrl(ORB orb, String url, Hashtable env)
 275         throws NamingException {
 276         if (url.startsWith("iiop://") || url.startsWith("iiopname://")) {
 277             return initUsingIiopUrl(orb, url, env);
 278         } else {
 279             return initUsingCorbanameUrl(orb, url, env);
 280         }
 281     }
 282 
 283     /**
 284      * Handles "iiop" and "iiopname" URLs (INS 98-10-11)
 285      */
 286     private String initUsingIiopUrl(ORB defOrb, String url, Hashtable env)
 287         throws NamingException {
 288         try {
 289             IiopUrl parsedUrl = new IiopUrl(url);
 290 
 291             Vector addrs = parsedUrl.getAddresses();
 292             IiopUrl.Address addr;
 293             NamingException savedException = null;
 294 
 295             for (int i = 0; i < addrs.size(); i++) {
 296                 addr = (IiopUrl.Address)addrs.elementAt(i);
 297 
 298                 try {
 299                     if (defOrb != null) {
 300                         try {
 301                             String tmpUrl = "corbaloc:iiop:" + addr.host
 302                                 + ":" + addr.port + "/NameService";
 303                             if (debug) {
 304                                 System.err.println("Using url: " + tmpUrl);
 305                             }
 306                             org.omg.CORBA.Object rootCtx =
 307                                 defOrb.string_to_object(tmpUrl);
 308                             setOrbAndRootContext(defOrb, rootCtx);
 309                             return parsedUrl.getStringName();
 310                         } catch (Exception e) {} // keep going
 311                     }
 312 
 313                     // Get ORB
 314                     if (debug) {
 315                         System.err.println("Getting ORB for " + addr.host
 316                             + " and port " + addr.port);


 324                     setOrbAndRootContext(orb, (String)null);
 325                     return parsedUrl.getStringName();
 326 
 327                 } catch (NamingException ne) {
 328                     savedException = ne;
 329                 }
 330             }
 331             if (savedException != null) {
 332                 throw savedException;
 333             } else {
 334                 throw new ConfigurationException("Problem with URL: " + url);
 335             }
 336         } catch (MalformedURLException e) {
 337             throw new ConfigurationException(e.getMessage());
 338         }
 339     }
 340 
 341     /**
 342      * Initializes using "corbaname" URL (INS 99-12-03)
 343      */
 344     private String initUsingCorbanameUrl(ORB orb, String url, Hashtable env)
 345         throws NamingException {
 346         try {
 347             CorbanameUrl parsedUrl = new CorbanameUrl(url);
 348 
 349             String corbaloc = parsedUrl.getLocation();
 350             String cosName = parsedUrl.getStringName();
 351 
 352             if (orb == null) {
 353 
 354                 // No ORB instance specified; create one using env and defaults
 355                 orb = CorbaUtils.getOrb(null, -1, env);
 356                 orbTracker = new OrbReuseTracker(orb);
 357             }
 358             setOrbAndRootContext(orb, corbaloc);
 359 
 360             return parsedUrl.getStringName();
 361         } catch (MalformedURLException e) {
 362             throw new ConfigurationException(e.getMessage());
 363         }
 364     }


 714     /**
 715       * Calls the unbind api of COS Naming and uses the exception mapper
 716       * class  to map the exceptions
 717       * @param path NameComponent[] object
 718       * @exception NotFound No objects under the name. If leaf
 719       * is not found, that's OK according to the JNDI spec
 720       * @exception CannotProceed Unable to obtain a continuation context
 721       * @exception InvalidName Name not understood.
 722       */
 723     private void callUnbind(NameComponent[] path) throws NamingException {
 724             if (_nc == null)
 725                 throw new ConfigurationException(
 726                     "Context does not have a corresponding NamingContext");
 727             try {
 728                 _nc.unbind(path);
 729             } catch (NotFound e) {
 730                 // If leaf is the one missing, return success
 731                 // as per JNDI spec
 732 
 733                 if (leafNotFound(e, path[path.length-1])) {
 734                     ; // do nothing
 735                 } else {
 736                     throw ExceptionMapper.mapException(e, this, path);
 737                 }
 738             } catch (Exception e) {
 739                 throw ExceptionMapper.mapException(e, this, path);
 740             }
 741     }
 742 
 743     private boolean leafNotFound(NotFound e, NameComponent leaf) {
 744 
 745         // This test is not foolproof because some name servers
 746         // always just return one component in rest_of_name
 747         // so you might not be able to tell whether that is
 748         // the leaf (e.g. aa/aa/aa, which one is missing?)
 749 
 750         NameComponent rest;
 751         return e.why.value() == NotFoundReason._missing_node &&
 752             e.rest_of_name.length == 1 &&
 753             (rest=e.rest_of_name[0]).id.equals(leaf.id) &&
 754             (rest.kind == leaf.kind ||


 812     public  void rename(Name oldName,Name newName)
 813         throws NamingException {
 814             if (_nc == null)
 815                 throw new ConfigurationException(
 816                     "Context does not have a corresponding NamingContext");
 817             if (oldName.size() == 0 || newName.size() == 0)
 818                 throw new InvalidNameException("One or both names empty");
 819             java.lang.Object obj = lookup(oldName);
 820             bind(newName,obj);
 821             unbind(oldName);
 822     }
 823 
 824     /**
 825       * Returns a NameClassEnumeration object which has a list of name
 826       * class pairs. Lists the current context if the name is empty.
 827       * @param name string
 828       * @exception NamingException All exceptions thrown by lookup
 829       * with a non-null argument
 830       * @return a list of name-class objects as a NameClassEnumeration.
 831       */
 832     public  NamingEnumeration list(String name) throws NamingException {
 833             return list(new CompositeName(name));
 834     }
 835 
 836     /**
 837       * Returns a NameClassEnumeration object which has a list of name
 838       * class pairs. Lists the current context if the name is empty.
 839       * @param name JNDI Name
 840       * @exception NamingException All exceptions thrown by lookup
 841       * @return a list of name-class objects as a NameClassEnumeration.
 842       */
 843     public  NamingEnumeration list(Name name)

 844         throws NamingException {
 845             return listBindings(name);
 846     }
 847 
 848     /**
 849       * Returns a BindingEnumeration object which has a list of name
 850       * object pairs. Lists the current context if the name is empty.
 851       * @param name string
 852       * @exception NamingException all exceptions returned by lookup
 853       * @return a list of bindings as a BindingEnumeration.
 854       */
 855     public  NamingEnumeration listBindings(String name)
 856         throws NamingException {
 857             return listBindings(new CompositeName(name));
 858     }
 859 
 860     /**
 861       * Returns a BindingEnumeration object which has a list of name
 862       * class pairs. Lists the current context if the name is empty.
 863       * @param name JNDI Name
 864       * @exception NamingException all exceptions returned by lookup.
 865       * @return a list of bindings as a BindingEnumeration.
 866       */
 867     public  NamingEnumeration listBindings(Name name)
 868         throws NamingException {
 869             if (_nc == null)
 870                 throw new ConfigurationException(
 871                     "Context does not have a corresponding NamingContext");
 872             if (name.size() > 0) {
 873                 try {
 874                     java.lang.Object obj = lookup(name);
 875                     if (obj instanceof CNCtx) {
 876                         return new CNBindingEnumeration(
 877                                         (CNCtx) obj, true, _env);
 878                     } else {
 879                         throw new NotContextException(name.toString());
 880                     }
 881                 } catch (NamingException ne) {
 882                     throw ne;
 883                 } catch (BAD_PARAM e) {
 884                     NamingException ne =
 885                         new NotContextException(name.toString());
 886                     ne.setRootCause(e);
 887                     throw ne;


1047       */
1048     public  NameParser getNameParser(String name) throws NamingException {
1049         return parser;
1050     }
1051 
1052     /**
1053       * Allow access to the name parser object.
1054       * @param Name JNDI name, is ignored since there is only one Name
1055       * Parser object.
1056       * @exception NamingException --
1057       * @return NameParser object
1058       */
1059     public  NameParser getNameParser(Name name) throws NamingException {
1060         return parser;
1061     }
1062 
1063     /**
1064       * Returns the current environment.
1065       * @return Environment.
1066       */
1067     public  Hashtable getEnvironment() throws NamingException {

1068         if (_env == null) {
1069             return new Hashtable(5, 0.75f);
1070         } else {
1071             return (Hashtable)_env.clone();
1072         }
1073     }
1074 
1075     public String composeName(String name, String prefix) throws NamingException {
1076         return composeName(new CompositeName(name),
1077             new CompositeName(prefix)).toString();
1078     }
1079 
1080     public Name composeName(Name name, Name prefix) throws NamingException {
1081         Name result = (Name)prefix.clone();
1082         return result.addAll(name);
1083     }
1084 
1085     /**
1086       * Adds to the environment for the current context.
1087       * Record change but do not reinitialize ORB.
1088       *
1089       * @param propName The property name.
1090       * @param propVal  The ORB.
1091       * @return the previous value of this property if any.
1092       */

1093     public java.lang.Object addToEnvironment(String propName,
1094         java.lang.Object propValue)
1095         throws NamingException {
1096             if (_env == null) {
1097                 _env = new Hashtable(7, 0.75f);
1098             } else {
1099                 // copy-on-write
1100                 _env = (Hashtable)_env.clone();
1101             }
1102 
1103             return _env.put(propName, propValue);
1104     }
1105 
1106     // Record change but do not reinitialize ORB

1107     public java.lang.Object removeFromEnvironment(String propName)
1108         throws NamingException {
1109             if (_env != null  && _env.get(propName) != null) {
1110                 // copy-on-write
1111                 _env = (Hashtable)_env.clone();
1112                 return _env.remove(propName);
1113             }
1114             return null;
1115     }
1116 
1117     synchronized public void incEnumCount() {
1118         if (orbTracker == null) {
1119             return;
1120         }
1121         enumCount++;
1122         if (debug) {
1123             System.out.println("incEnumCount, new count:" + enumCount);
1124         }
1125     }
1126 
1127     synchronized public void decEnumCount()
1128             throws NamingException {
1129         if (orbTracker == null) {
1130             return;
1131         }


   1 /*
   2  * Copyright (c) 1999, 2011, 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.jndi.cosnaming;
  27 
  28 import javax.naming.*;
  29 import javax.naming.spi.NamingManager;
  30 import javax.naming.spi.ResolveResult;
  31 
  32 import java.util.Hashtable;

  33 import java.net.MalformedURLException;
  34 import java.net.URL;
  35 import java.io.InputStream;
  36 import java.io.InputStreamReader;
  37 import java.io.BufferedReader;
  38 import java.io.IOException;
  39 
  40 import org.omg.CosNaming.*;
  41 import org.omg.CosNaming.NamingContextPackage.*;
  42 import org.omg.CORBA.*;
  43 
  44 import com.sun.jndi.toolkit.corba.CorbaUtils;
  45 
  46 // Needed for creating default ORB
  47 import java.applet.Applet;
  48 
  49 /**
  50   * Provides a bridge to the CosNaming server provided by
  51   * JavaIDL. This class provides the InitialContext from CosNaming.
  52   *
  53   * @author Raj Krishnamurthy
  54   * @author Rosanna Lee
  55   */
  56 
  57 public class CNCtx implements javax.naming.Context {
  58 
  59     private final static boolean debug = false;
  60 
  61     ORB _orb;                   // used by ExceptionMapper and RMI/IIOP factory
  62     public NamingContext _nc;   // public for accessing underlying NamingContext
  63     private NameComponent[] _name = null;
  64 
  65     Hashtable<String, java.lang.Object> _env; // used by ExceptionMapper
  66     static final CNNameParser parser = new CNNameParser();
  67 
  68     private static final String FED_PROP = "com.sun.jndi.cosnaming.federation";
  69     boolean federation = false;
  70 
  71     // Reference counter for tracking _orb references
  72     OrbReuseTracker orbTracker = null;
  73     int enumCount;
  74     boolean isCloseCalled = false;
  75 
  76     /**
  77       * Create a CNCtx object. Gets the initial naming
  78       * reference for the COS Naming Service from the ORB.
  79       * The ORB can be passed in via the java.naming.corba.orb property
  80       * or be created using properties in the environment properties.
  81       * @param env Environment properties for initializing name service.
  82       * @exception NamingException Cannot initialize ORB or naming context.
  83       */
  84     @SuppressWarnings("unchecked")
  85     CNCtx(Hashtable<?,?> env) throws NamingException {
  86         if (env != null) {
  87             env = (Hashtable<?,?>)env.clone();
  88         }
  89         _env = (Hashtable<String, java.lang.Object>)env;
  90         federation = "true".equals(env != null ? env.get(FED_PROP) : null);
  91         initOrbAndRootContext(env);
  92     }
  93 
  94     private CNCtx() {
  95     }
  96 
  97     /**
  98      * This method is used by the iiop and iiopname URL Context factories.
  99      */
 100     @SuppressWarnings("unchecked")
 101     public static ResolveResult createUsingURL(String url, Hashtable<?,?> env)
 102     throws NamingException {
 103         CNCtx ctx = new CNCtx();
 104         if (env != null) {
 105             env = (Hashtable<?,?>) env.clone();
 106         }
 107         ctx._env = (Hashtable<String, java.lang.Object>)env;
 108         String rest = ctx.initUsingUrl(
 109             env != null ?
 110                 (org.omg.CORBA.ORB) env.get("java.naming.corba.orb")
 111                 : null,
 112             url, env);
 113 
 114         // rest is the INS name
 115         // Return the parsed form to prevent subsequent lookup
 116         // from parsing the string as a composite name
 117         // The caller should be aware that a toString() of the name
 118         // will yield its INS syntax, rather than a composite syntax
 119         return new ResolveResult(ctx, parser.parse(rest));
 120     }
 121 
 122     /**
 123       * Creates a CNCtx object which supports the javax.naming
 124       * apis given a COS Naming Context object.
 125       * @param orb The ORB used by this context
 126       * @param tracker The ORB reuse tracker for tracking references to the
 127       *  orb object
 128       * @param nctx The COS NamingContext object associated with this context
 129       * @param name The name of this context relative to the root
 130       */
 131 
 132     CNCtx(ORB orb, OrbReuseTracker tracker, NamingContext nctx,
 133           Hashtable<String, java.lang.Object> env, NameComponent[]name)
 134         throws NamingException {
 135             if (orb == null || nctx == null)
 136                 throw new ConfigurationException(
 137                     "Must supply ORB or NamingContext");
 138             _orb = orb;
 139             orbTracker = tracker;
 140             if (orbTracker != null) {
 141                 orbTracker.incRefCount();
 142             }
 143             _nc = nctx;
 144             _env = env;
 145             _name = name;
 146             federation = "true".equals(env != null ? env.get(FED_PROP) : null);
 147     }
 148 
 149     NameComponent[] makeFullName(NameComponent[] child) {
 150         if (_name == null || _name.length == 0) {
 151             return child;
 152         }
 153         NameComponent[] answer = new NameComponent[_name.length+child.length];


 191       * _orb is obtained from java.naming.corba.orb if it has been set.
 192       * Otherwise, _orb is created using the host/port from PROVIDER_URL
 193       * (if it contains an "iiop" or "iiopname" URL), or from initialization
 194       * properties specified in env.
 195       *<p>
 196       * _nc is obtained from the IOR stored in PROVIDER_URL if it has been
 197       * set and does not contain an "iiop" or "iiopname" URL. It can be
 198       * a stringified IOR, "corbaloc" URL, "corbaname" URL,
 199       * or a URL (such as file/http/ftp) to a location
 200       * containing a stringified IOR. If PROVIDER_URL has not been
 201       * set in this way, it is obtained from the result of
 202       *     ORB.resolve_initial_reference("NameService");
 203       *<p>
 204       * _name is obtained from the "iiop", "iiopname", or "corbaname" URL.
 205       * It is the empty name by default.
 206       *
 207       * @param env Environment The possibly null environment.
 208       * @exception NamingException When an error occurs while initializing the
 209       * ORB or the naming context.
 210       */
 211     private void initOrbAndRootContext(Hashtable<?,?> env) throws NamingException {
 212         org.omg.CORBA.ORB inOrb = null;
 213         String ncIor = null;
 214 
 215         if (env != null) {
 216             inOrb = (org.omg.CORBA.ORB) env.get("java.naming.corba.orb");
 217         }
 218 
 219         // Extract PROVIDER_URL from environment
 220         String provUrl = null;
 221         if (env != null) {
 222             provUrl = (String)env.get(javax.naming.Context.PROVIDER_URL);
 223         }
 224 
 225         if (provUrl != null && !isCorbaUrl(provUrl)) {
 226             // Initialize the root naming context by using the IOR supplied
 227             // in the PROVIDER_URL
 228             ncIor = getStringifiedIor(provUrl);
 229 
 230             if (inOrb == null) {
 231 
 232                 // no ORB instance specified; create one using env and defaults
 233                 inOrb = CorbaUtils.getOrb(null, -1, env);
 234                 orbTracker = new OrbReuseTracker(inOrb);
 235             }
 236             setOrbAndRootContext(inOrb, ncIor);
 237         } else if (provUrl != null) {
 238             // Initialize the root naming context by using the URL supplied
 239             // in the PROVIDER_URL
 240             String insName = initUsingUrl(inOrb, provUrl, env);
 241 
 242             // If name supplied in URL, resolve it to a NamingContext
 243             if (insName.length() > 0) {
 244                 _name = CNNameParser.nameToCosName(parser.parse(insName));
 245                 try {
 246                     org.omg.CORBA.Object obj = _nc.resolve(_name);
 247                     _nc = NamingContextHelper.narrow(obj);
 248                     if (_nc == null) {
 249                         throw new ConfigurationException(insName +
 250                             " does not name a NamingContext");
 251                     }
 252                 } catch (org.omg.CORBA.BAD_PARAM e) {
 253                     throw new ConfigurationException(insName +
 254                         " does not name a NamingContext");
 255                 } catch (Exception e) {
 256                     throw ExceptionMapper.mapException(e, this, _name);
 257                 }
 258             }
 259         } else {
 260             // No PROVIDER_URL supplied; initialize using defaults
 261             if (inOrb == null) {
 262 
 263                 // No ORB instance specified; create one using env and defaults
 264                 inOrb = CorbaUtils.getOrb(null, -1, env);
 265                 orbTracker = new OrbReuseTracker(inOrb);
 266                 if (debug) {
 267                     System.err.println("Getting default ORB: " + inOrb + env);
 268                 }
 269             }
 270             setOrbAndRootContext(inOrb, (String)null);
 271         }
 272     }
 273 
 274 
 275     private String initUsingUrl(ORB orb, String url, Hashtable<?,?> env)
 276         throws NamingException {
 277         if (url.startsWith("iiop://") || url.startsWith("iiopname://")) {
 278             return initUsingIiopUrl(orb, url, env);
 279         } else {
 280             return initUsingCorbanameUrl(orb, url, env);
 281         }
 282     }
 283 
 284     /**
 285      * Handles "iiop" and "iiopname" URLs (INS 98-10-11)
 286      */
 287     private String initUsingIiopUrl(ORB defOrb, String url, Hashtable<?,?> env)
 288         throws NamingException {
 289         try {
 290             IiopUrl parsedUrl = new IiopUrl(url);
 291 


 292             NamingException savedException = null;
 293             
 294             for (IiopUrl.Address addr : parsedUrl.getAddresses()) {

 295 
 296                 try {
 297                     if (defOrb != null) {
 298                         try {
 299                             String tmpUrl = "corbaloc:iiop:" + addr.host
 300                                 + ":" + addr.port + "/NameService";
 301                             if (debug) {
 302                                 System.err.println("Using url: " + tmpUrl);
 303                             }
 304                             org.omg.CORBA.Object rootCtx =
 305                                 defOrb.string_to_object(tmpUrl);
 306                             setOrbAndRootContext(defOrb, rootCtx);
 307                             return parsedUrl.getStringName();
 308                         } catch (Exception e) {} // keep going
 309                     }
 310 
 311                     // Get ORB
 312                     if (debug) {
 313                         System.err.println("Getting ORB for " + addr.host
 314                             + " and port " + addr.port);


 322                     setOrbAndRootContext(orb, (String)null);
 323                     return parsedUrl.getStringName();
 324 
 325                 } catch (NamingException ne) {
 326                     savedException = ne;
 327                 }
 328             }
 329             if (savedException != null) {
 330                 throw savedException;
 331             } else {
 332                 throw new ConfigurationException("Problem with URL: " + url);
 333             }
 334         } catch (MalformedURLException e) {
 335             throw new ConfigurationException(e.getMessage());
 336         }
 337     }
 338 
 339     /**
 340      * Initializes using "corbaname" URL (INS 99-12-03)
 341      */
 342     private String initUsingCorbanameUrl(ORB orb, String url, Hashtable<?,?> env)
 343         throws NamingException {
 344         try {
 345             CorbanameUrl parsedUrl = new CorbanameUrl(url);
 346 
 347             String corbaloc = parsedUrl.getLocation();
 348             String cosName = parsedUrl.getStringName();
 349 
 350             if (orb == null) {
 351 
 352                 // No ORB instance specified; create one using env and defaults
 353                 orb = CorbaUtils.getOrb(null, -1, env);
 354                 orbTracker = new OrbReuseTracker(orb);
 355             }
 356             setOrbAndRootContext(orb, corbaloc);
 357 
 358             return parsedUrl.getStringName();
 359         } catch (MalformedURLException e) {
 360             throw new ConfigurationException(e.getMessage());
 361         }
 362     }


 712     /**
 713       * Calls the unbind api of COS Naming and uses the exception mapper
 714       * class  to map the exceptions
 715       * @param path NameComponent[] object
 716       * @exception NotFound No objects under the name. If leaf
 717       * is not found, that's OK according to the JNDI spec
 718       * @exception CannotProceed Unable to obtain a continuation context
 719       * @exception InvalidName Name not understood.
 720       */
 721     private void callUnbind(NameComponent[] path) throws NamingException {
 722             if (_nc == null)
 723                 throw new ConfigurationException(
 724                     "Context does not have a corresponding NamingContext");
 725             try {
 726                 _nc.unbind(path);
 727             } catch (NotFound e) {
 728                 // If leaf is the one missing, return success
 729                 // as per JNDI spec
 730 
 731                 if (leafNotFound(e, path[path.length-1])) {
 732                     // do nothing
 733                 } else {
 734                     throw ExceptionMapper.mapException(e, this, path);
 735                 }
 736             } catch (Exception e) {
 737                 throw ExceptionMapper.mapException(e, this, path);
 738             }
 739     }
 740 
 741     private boolean leafNotFound(NotFound e, NameComponent leaf) {
 742 
 743         // This test is not foolproof because some name servers
 744         // always just return one component in rest_of_name
 745         // so you might not be able to tell whether that is
 746         // the leaf (e.g. aa/aa/aa, which one is missing?)
 747 
 748         NameComponent rest;
 749         return e.why.value() == NotFoundReason._missing_node &&
 750             e.rest_of_name.length == 1 &&
 751             (rest=e.rest_of_name[0]).id.equals(leaf.id) &&
 752             (rest.kind == leaf.kind ||


 810     public  void rename(Name oldName,Name newName)
 811         throws NamingException {
 812             if (_nc == null)
 813                 throw new ConfigurationException(
 814                     "Context does not have a corresponding NamingContext");
 815             if (oldName.size() == 0 || newName.size() == 0)
 816                 throw new InvalidNameException("One or both names empty");
 817             java.lang.Object obj = lookup(oldName);
 818             bind(newName,obj);
 819             unbind(oldName);
 820     }
 821 
 822     /**
 823       * Returns a NameClassEnumeration object which has a list of name
 824       * class pairs. Lists the current context if the name is empty.
 825       * @param name string
 826       * @exception NamingException All exceptions thrown by lookup
 827       * with a non-null argument
 828       * @return a list of name-class objects as a NameClassEnumeration.
 829       */
 830     public  NamingEnumeration<NameClassPair> list(String name) throws NamingException {
 831             return list(new CompositeName(name));
 832     }
 833 
 834     /**
 835       * Returns a NameClassEnumeration object which has a list of name
 836       * class pairs. Lists the current context if the name is empty.
 837       * @param name JNDI Name
 838       * @exception NamingException All exceptions thrown by lookup
 839       * @return a list of name-class objects as a NameClassEnumeration.
 840       */
 841     @SuppressWarnings("unchecked")
 842     public  NamingEnumeration<NameClassPair> list(Name name)
 843         throws NamingException {
 844             return (NamingEnumeration)listBindings(name);
 845     }
 846 
 847     /**
 848       * Returns a BindingEnumeration object which has a list of name
 849       * object pairs. Lists the current context if the name is empty.
 850       * @param name string
 851       * @exception NamingException all exceptions returned by lookup
 852       * @return a list of bindings as a BindingEnumeration.
 853       */
 854     public  NamingEnumeration<javax.naming.Binding> listBindings(String name)
 855         throws NamingException {
 856             return listBindings(new CompositeName(name));
 857     }
 858 
 859     /**
 860       * Returns a BindingEnumeration object which has a list of name
 861       * class pairs. Lists the current context if the name is empty.
 862       * @param name JNDI Name
 863       * @exception NamingException all exceptions returned by lookup.
 864       * @return a list of bindings as a BindingEnumeration.
 865       */
 866     public  NamingEnumeration<javax.naming.Binding> listBindings(Name name)
 867         throws NamingException {
 868             if (_nc == null)
 869                 throw new ConfigurationException(
 870                     "Context does not have a corresponding NamingContext");
 871             if (name.size() > 0) {
 872                 try {
 873                     java.lang.Object obj = lookup(name);
 874                     if (obj instanceof CNCtx) {
 875                         return new CNBindingEnumeration(
 876                                         (CNCtx) obj, true, _env);
 877                     } else {
 878                         throw new NotContextException(name.toString());
 879                     }
 880                 } catch (NamingException ne) {
 881                     throw ne;
 882                 } catch (BAD_PARAM e) {
 883                     NamingException ne =
 884                         new NotContextException(name.toString());
 885                     ne.setRootCause(e);
 886                     throw ne;


1046       */
1047     public  NameParser getNameParser(String name) throws NamingException {
1048         return parser;
1049     }
1050 
1051     /**
1052       * Allow access to the name parser object.
1053       * @param Name JNDI name, is ignored since there is only one Name
1054       * Parser object.
1055       * @exception NamingException --
1056       * @return NameParser object
1057       */
1058     public  NameParser getNameParser(Name name) throws NamingException {
1059         return parser;
1060     }
1061 
1062     /**
1063       * Returns the current environment.
1064       * @return Environment.
1065       */
1066     @SuppressWarnings("unchecked")
1067     public  Hashtable<String, java.lang.Object> getEnvironment() throws NamingException {
1068         if (_env == null) {
1069             return new Hashtable<>(5, 0.75f);
1070         } else {
1071             return (Hashtable<String, java.lang.Object>)_env.clone();
1072         }
1073     }
1074 
1075     public String composeName(String name, String prefix) throws NamingException {
1076         return composeName(new CompositeName(name),
1077             new CompositeName(prefix)).toString();
1078     }
1079 
1080     public Name composeName(Name name, Name prefix) throws NamingException {
1081         Name result = (Name)prefix.clone();
1082         return result.addAll(name);
1083     }
1084 
1085     /**
1086       * Adds to the environment for the current context.
1087       * Record change but do not reinitialize ORB.
1088       *
1089       * @param propName The property name.
1090       * @param propVal  The ORB.
1091       * @return the previous value of this property if any.
1092       */
1093     @SuppressWarnings("unchecked")
1094     public java.lang.Object addToEnvironment(String propName,
1095         java.lang.Object propValue)
1096         throws NamingException {
1097             if (_env == null) {
1098                 _env = new Hashtable<>(7, 0.75f);
1099             } else {
1100                 // copy-on-write
1101                 _env = (Hashtable<String, java.lang.Object>)_env.clone();
1102             }
1103 
1104             return _env.put(propName, propValue);
1105     }
1106 
1107     // Record change but do not reinitialize ORB
1108     @SuppressWarnings("unchecked")
1109     public java.lang.Object removeFromEnvironment(String propName)
1110         throws NamingException {
1111             if (_env != null  && _env.get(propName) != null) {
1112                 // copy-on-write
1113                 _env = (Hashtable<String, java.lang.Object>)_env.clone();
1114                 return _env.remove(propName);
1115             }
1116             return null;
1117     }
1118 
1119     synchronized public void incEnumCount() {
1120         if (orbTracker == null) {
1121             return;
1122         }
1123         enumCount++;
1124         if (debug) {
1125             System.out.println("incEnumCount, new count:" + enumCount);
1126         }
1127     }
1128 
1129     synchronized public void decEnumCount()
1130             throws NamingException {
1131         if (orbTracker == null) {
1132             return;
1133         }