/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006-2011 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.enterprise.naming.impl; import com.sun.enterprise.naming.util.LogFacade; import org.glassfish.api.naming.NamingObjectProxy; import org.jvnet.hk2.component.Habitat; import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; import javax.naming.spi.ObjectFactory; import java.rmi.RemoteException; import java.util.Enumeration; import java.util.Hashtable; import java.util.logging.Level; import java.util.logging.Logger; import java.util.Map; import java.util.HashMap; import javax.naming.Binding; import javax.naming.CommunicationException; import javax.naming.CompositeName; import javax.naming.Context; import javax.naming.Name; import javax.naming.NameClassPair; import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.NotContextException; import javax.naming.Reference; import javax.naming.Referenceable; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContextHelper; import javax.rmi.PortableRemoteObject; import org.glassfish.internal.api.Globals; import org.glassfish.internal.api.ORBLocator; import org.glassfish.internal.api.ServerContext; import org.omg.CORBA.ORB; import org.omg.CosNaming.NamingContextPackage.CannotProceed; import org.omg.CosNaming.NamingContextPackage.NotFound; /** * This context provides access to the app server naming service. This * is the default Context for GlassFish. Lookups of unqualified names (i.e. * names not starting with "java:", "corbaname:" etc) are serviced by * SerialContext. The namespace is implemented in the * SerialContextProviderImpl object, which is accessed directly in the * case that the client is collocated with the naming service impl or * remotely via RMI-IIOP if not collocated. *

* NOT THREAD SAFE: mutable instance variables */ public class SerialContext implements Context { // Maximum number of recursive calls to lookup on comm error // Maximum number of recursive calls to lookup on comm error private static final int MAX_LEVEL = 5 ; private static final String JAVA_URL = "java:"; private static final String JAVA_GLOBAL_URL = "java:global/"; // Sets unmanaged SerialContext in test mode to prevent attempts to contact server. static final String INITIAL_CONTEXT_TEST_MODE = "com.sun.enterprise.naming.TestMode"; private static final Logger _logger = LogFacade.getLogger(); private static final NameParser myParser = new SerialNameParser(); private static final Map providerCache = new HashMap(); private static final ThreadLocal stickyContext = new ThreadLocal() { @Override protected ThreadLocalIC initialValue() { return new ThreadLocalIC() ; } } ; private Hashtable myEnv = null; // THREAD UNSAFE private SerialContextProvider provider; private final String myName; private final JavaURLContext javaUrlContext; private Habitat habitat; private boolean testMode = false; private ProcessType processType = ProcessType.Server; private ORB orbFromEnv; private String targetHost; private String targetPort; private ORB orb = null ; // True if we're running in the server and no orb,host, or port // properties have been explicitly set in the properties // Allows special optimized intra-server naming service access private boolean intraServerLookups; // Common Class Loader. It is used as a fallback classloader to locate // GlassFish object factories. private ClassLoader commonCL; /** Methods for preserving stickiness. This is a * solution to store the sticky IC as a thread local variable. This sticky * IC will be used by all classes that require a context object to do lookup * (if LB is enabled) SerialContext.lookup() sets a value for the thread * local variable (stickyContext) before performing th lookup in case LB is * enabled. If not, the thread local variable is null. At the end of the * SerialContext.lookup() method, the thread local variable gets set to * null. So actually speaking, more than being a global variable for the * entire thread, its global only during the execution of the * SerialContext.lookup() method. bug 5050591 * */ static Context getStickyContext() { return stickyContext.get().getContext() ; } private void grabSticky() { stickyContext.get().grab( this ) ; } private void releaseSticky() { stickyContext.get().release() ; } static void clearSticky() { stickyContext.get().clear() ; } /** Store the sticky context as a threadlocal variable (bug 5050591). * Count is needed to know how many times the lookup method is being called * from within the user code's ic.lookup(). * e.g. JMS resource lookups (via ConnectorObjectFactory) */ private static class ThreadLocalIC { private Context ctx = null ; private int count = 0; Context getContext() { return ctx ; } void grab( Context context ) { if (ctx == null) { ctx = context ; } count++ ; } void release() { if (count > 0) { count-- ; if (count == 0) { ctx = null ; } } else { if (_logger.isLoggable(Level.FINE)) { _logger.log( Level.FINE, "SerialContext: attempt to release StickyContext " + " without grab") ; } ctx = null ; } } void clear() { ctx = null ; count = 0 ; } } /** * Constructor for the context. Initializes the object reference to the * remote provider object. */ public SerialContext(String name, Hashtable environment, Habitat h) throws NamingException { habitat = h; myEnv = (environment != null) ? (Hashtable) (environment.clone()) : null; // TODO REMOVE when property stuff is figured out myEnv.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); myEnv.put("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl" ); this.myName = name; if (_logger.isLoggable(Level.FINE)) _logger.fine("SerialContext ==> SerialContext instance created : " + this); if( myEnv.get(INITIAL_CONTEXT_TEST_MODE) != null ) { testMode = true; System.out.println("SerialContext in test mode"); } if( (habitat == null) && !testMode ) { synchronized(SerialContext.class) { if( SerialInitContextFactory.getDefaultHabitat() == null ) { // Bootstrap a hk2 environment. // TODO This will need to be moved somewhere else. Potentially any // piece of glassfish code that can be an initial entry point from a // Java SE client will need to make this happen. habitat = Globals.getStaticHabitat(); SerialInitContextFactory.setDefaultHabitat(habitat); } else { habitat = SerialInitContextFactory.getDefaultHabitat(); } } } if( testMode ) { processType = ProcessType.Server; } else { ProcessEnvironment processEnv = habitat.getComponent(ProcessEnvironment.class); processType = processEnv.getProcessType(); if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "Serial Context initializing with process environment {0}", processEnv); } } // using these two temp variables allows instance variables // to be 'final'. JavaURLContext urlContextTemp = null; if (myEnv.get(SerialInitContextFactory.IIOP_URL_PROPERTY) != null) { urlContextTemp = new JavaURLContext(myEnv, this); } else { urlContextTemp = new JavaURLContext(myEnv, null); } javaUrlContext = urlContextTemp; orbFromEnv = (ORB) myEnv.get(ORBLocator.JNDI_CORBA_ORB_PROPERTY); String targetHostFromEnv = (String)myEnv.get( ORBLocator.OMG_ORB_INIT_HOST_PROPERTY); String targetPortFromEnv = (String)myEnv.get( ORBLocator.OMG_ORB_INIT_PORT_PROPERTY); intraServerLookups = (processType.isServer()) && (orbFromEnv == null) && (targetHostFromEnv == null) && (targetPortFromEnv == null); // Set target host / port from env. If only one of the two is set, fill in the // other with the default. if( targetHostFromEnv != null ) { targetHost = targetHostFromEnv; if( targetPortFromEnv == null ) { targetPort = ORBLocator.DEFAULT_ORB_INIT_PORT; } } if( targetPortFromEnv != null ) { targetPort = targetPortFromEnv; if( targetHostFromEnv == null ) { targetHost = ORBLocator.DEFAULT_ORB_INIT_HOST; } } orb = orbFromEnv; if (habitat != null) { // can happen in test mode ServerContext sc = habitat.getByContract(ServerContext.class); if (sc != null) { commonCL = sc.getCommonClassLoader(); } } } /** * This constructor takes the component id as an argument. All name * arguments to operations are prepended by the component id. */ public SerialContext(Hashtable env, Habitat habitat) throws NamingException { this("", env, habitat); } private SerialContextProvider getProvider() throws NamingException { SerialContextProvider returnValue = provider; if (provider == null) { try { if (intraServerLookups) { returnValue = ProviderManager.getProviderManager().getLocalProvider(); } else { returnValue = getRemoteProvider(); } } catch(Exception e) { clearSticky() ; e.printStackTrace(); NamingException ne = new NamingException( "Unable to acquire SerialContextProvider for " + this); ne.initCause(e); throw ne; } } return returnValue; } private ORB getORB() { ORBLocator orbHelper = habitat.getComponent(ORBLocator.class); if (orb == null) { orb = orbHelper.getORB() ; } return orb ; } private ProviderCacheKey getProviderCacheKey() { final ORB myORB = getORB(); ProviderCacheKey key; String eplist = null ; if (myEnv != null) { eplist = (String)myEnv.get( SerialInitContextFactory.IIOP_URL_PROPERTY) ; } if (eplist != null) { key = new ProviderCacheKey(eplist) ; } else if (targetHost == null) { key = new ProviderCacheKey(myORB) ; } else { key = new ProviderCacheKey(targetHost, targetPort); } return key ; } private void clearProvider() { ProviderCacheKey key = getProviderCacheKey() ; synchronized(SerialContext.class) { providerCache.remove( key ) ; } provider = null ; } private SerialContextProvider getRemoteProvider() throws Exception { if (provider == null) { ProviderCacheKey key = getProviderCacheKey() ; SerialContextProvider cachedProvider; synchronized(SerialContext.class) { cachedProvider = providerCache.get(key); } if (cachedProvider == null) { // Don't hold lock during this call: remote invocation SerialContextProvider newProvider = key.getNameService() ; synchronized(SerialContext.class) { cachedProvider = providerCache.get(key); if (cachedProvider == null) { providerCache.put(key, newProvider); provider = newProvider; } else { provider = cachedProvider; } } } else { provider = cachedProvider; } } return provider; } /** * The getNameInNamespace API is not supported in this context. * * @throws NamingException if there is a naming exception. */ @Override public String getNameInNamespace() throws NamingException { return myName; } /** * method to check if the name to look up starts with "java:" */ private boolean isjavaURL(String name) { return name.startsWith(JAVA_URL) && !name.startsWith(JAVA_GLOBAL_URL) ; } /** * Lookup the specified name in the context. Returns the resolved object. * * @return the resolved object. * @throws NamingException if there is a naming exception. */ @Override public Object lookup(String name) throws NamingException { return lookup( name, 0 ) ; } private Object lookup(String name, int level ) throws NamingException { // Before any lookup bind any NamedNamingObjectProxy // Skip if in plain Java SE client // TODO this should really be moved somewhere else NamedNamingObjectManager.checkAndLoadProxies(habitat); if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "SerialContext ==> lookup( {0})", name); } /** * In case a user is creating an IC with env passed in constructor; env * specifies endpoints in some form in that case, the sticky IC should * be stored as a thread local variable. * */ final boolean useSticky = myEnv.get( SerialInitContextFactory.IIOP_URL_PROPERTY) != null ; if (useSticky) { grabSticky() ; } try { if (name.isEmpty()) { // Asking to look up this context itself. Create and return // a new instance with its own independent environment. return (new SerialContext(myName, myEnv, habitat)); } name = getRelativeName(name); if (_logger.isLoggable(Level.FINE)) { _logger.log(Level.FINE, "SerialContext ==> lookup relative name : {0}", name); } if (isjavaURL(name)) { //it is possible that the object bound in a java url ("java:") is //reference object. Object o = javaUrlContext.lookup(name); if(o instanceof Reference){ o = getObjectInstance(name, o); } return o; } else { SerialContextProvider prvdr = getProvider() ; Object obj = prvdr.lookup(name); if (obj instanceof NamingObjectProxy) { return ((NamingObjectProxy) obj).create(this); } if (obj instanceof Context) { return new SerialContext(name, myEnv, habitat); } Object retObj = getObjectInstance(name, obj); return retObj; } } catch (NamingException nnfe) { NamingException ne = new NamingException ("Lookup failed for '" + name + "' in " + this); ne.initCause(nnfe); throw ne; } catch (Exception ex) { // Issue 14732: make this FINE, as a cluster configuration change // can send us here in a normal retry scenario. _logger.log(Level.FINE, "enterprise_naming.serialctx_communication_exception", name); _logger.log(Level.FINE, "", ex); final int nextLevel = level + 1 ; // temp fix for 6320008 // this should be removed once we change the transient NS // implementation to persistent if (ex instanceof java.rmi.MarshalException && ex.getCause() instanceof org.omg.CORBA.COMM_FAILURE && nextLevel < MAX_LEVEL) { clearProvider(); _logger.fine("Resetting provider to NULL. Will get new obj ref " + "for provider since previous obj ref was stale..."); return lookup(name, nextLevel ); } else { CommunicationException ce = new CommunicationException( "Communication exception for " + this); ce.initCause(ex); throw ce; } } finally { if (useSticky) { releaseSticky(); } } } private Object getObjectInstance(String name, Object obj) throws Exception { Object retObj = javax.naming.spi.NamingManager.getObjectInstance( obj, new CompositeName(name), null, myEnv); if (retObj == obj) { // NamingManager.getObjectInstance() returns the same object // when it can't find the factory class. Since NamingManager // uses Thread's context class loader to locate factory classes, // it may not be able to locate the various GlassFish factories // when lookup is performed outside of a Java EE context like // inside an OSGi bundle's activator. // So, let's see if using CommonClassLoader helps or not. // We will only try with CommonClassLoader when the passed object // reference has a factory class name set. ClassLoader tccl = Thread.currentThread().getContextClassLoader(); if (tccl != commonCL) { Reference ref = getReference(obj); if (ref != null) { _logger.logp(Level.FINE, "SerialContext", "getObjectInstance", "Trying with CommonClassLoader for name {0} ", new Object[]{name}); ObjectFactory factory = getObjectFactory(ref, commonCL); if (factory != null) { retObj = factory.getObjectInstance( ref, new CompositeName(name), null, myEnv); } if (retObj != obj) { _logger.logp(Level.FINE, "SerialContext", "getObjectInstance", "Found with CommonClassLoader"); } } } } return retObj; } /** * This method tries to check if the passed object is a Reference or * Refenciable. If it is a Reference, it just casts it to a Reference and * returns, else if it is a Referenceable, it tries to get a Reference from * the Referenceable and returns that, otherwise, it returns null. * * @param obj * @return * @throws NamingException */ private Reference getReference(Object obj) throws NamingException { Reference ref = null; if (obj instanceof Reference) { ref = (Reference) obj; } else if (obj instanceof Referenceable) { ref = ((Referenceable)(obj)).getReference(); } return ref; } /** * It tries to load the factory class for the given reference using the * given class loader and return an instance of the same. Returns null * if it can't load the class. * * @param ref * @param cl * @return * @throws IllegalAccessException * @throws InstantiationException */ private ObjectFactory getObjectFactory(Reference ref, ClassLoader cl) throws IllegalAccessException, InstantiationException { String factoryName = ref.getFactoryClassName(); if (factoryName != null) { try { Class c = Class.forName(factoryName, false, cl); return (ObjectFactory)c.newInstance(); } catch (ClassNotFoundException e) { // ignore only CNFE, all other exceptions are considered errors } } return null; } /** * Lookup the specifed name in the context. Returns the resolved object. * * @return the resolved object. * @throws NamingException if there is a naming exception. */ @Override public Object lookup(Name name) throws NamingException { // Flat namespace; no federation; just call string version return lookup(name.toString()); } /** * Bind the object to the specified name. * * @param name name that the object is being bound to. * @param obj object that is being bound. * @throws NamingException if there is a naming exception. */ @Override public void bind(String name, Object obj) throws NamingException { name = getRelativeName(name); if (isjavaURL(name)) { javaUrlContext.bind(name, obj); } else { try { getProvider().bind(name, obj); } catch (RemoteException ex) { throw new CommunicationException(ex.toString()); } } } /** * Bind the object to the specified name. * * @param name name that the object is being bound to. * @param obj object that is being bound. * @throws NamingException if there is a naming exception. */ @Override public void bind(Name name, Object obj) throws NamingException { // Flat namespace; no federation; just call string version bind(name.toString(), obj); } /** * Rebind the object to the specified name. * * @param name name that the object is being bound to. * @param obj object that is being bound. * @throws NamingException if there is a naming exception. */ @Override public void rebind(String name, Object obj) throws NamingException { name = getRelativeName(name); if (isjavaURL(name)) { javaUrlContext.rebind(name, obj); } else { try { getProvider().rebind(name, obj); } catch (RemoteException ex) { throw new CommunicationException(ex.toString()); } } } /** * Rebind the object to the specified name. * * @param name name that the object is being bound to. * @param obj object that is being bound. * @throws NamingException if there is a naming exception. */ @Override public void rebind(Name name, Object obj) throws NamingException { // Flat namespace; no federation; just call string version rebind(name.toString(), obj); } /** * Unbind the object with the specified name. * * @param name that is being unbound. * @throws NamingException if there is a naming exception. */ @Override public void unbind(String name) throws NamingException { name = getRelativeName(name); if (isjavaURL(name)) { javaUrlContext.unbind(name); } else { try { getProvider().unbind(name); } catch (RemoteException ex) { throw new CommunicationException(ex.toString()); } } } /** * Unbind the object with the specified name. * * @param name name that is being unbound. * @throws NamingException if there is a naming exception. */ @Override public void unbind(Name name) throws NamingException { // Flat namespace; no federation; just call string version unbind(name.toString()); } /** * Rename the bound object. * * @param oldname old name that the object is bound as. * @param newname new name that the object will be bound as. * @throws NamingException if there is a naming exception. */ @Override public void rename(String oldname, String newname) throws NamingException { oldname = getRelativeName(oldname); newname = getRelativeName(newname); if (isjavaURL(oldname)) { javaUrlContext.rename(oldname, newname); } else { try { getProvider().rename(oldname, newname); } catch (RemoteException ex) { throw new CommunicationException(ex.toString()); } } } /** * Rename the bound object. * * @param oldname old name that the object is bound as. * @param newname new name that the object will be bound as. * @throws NamingException if there is a naming exception. */ @Override public void rename(Name oldname, Name newname) throws NamingException { // Flat namespace; no federation; just call string version rename(oldname.toString(), newname.toString()); } /** * List the contents of the specified context. * * @param name context name. * @return an enumeration of the contents. * @throws NamingException if there is a naming exception. */ @Override public NamingEnumeration list(String name) throws NamingException { if (name.isEmpty()) { // listing this context try { Hashtable bindings = getProvider().list(myName); return new RepNames(bindings); } catch (RemoteException ex) { throw new CommunicationException(ex.toString()); } } name = getRelativeName(name); if (isjavaURL(name)) { return javaUrlContext.list(name); } else { // Perhaps 'name' names a context Object target = lookup(name); if (target instanceof Context) { return ((Context) target).list(""); } throw new NotContextException(name + " cannot be listed"); } } /** * List the contents of the specified context. * * @param name context name. * @return an enumeration of the contents. * @throws NamingException if there is a naming exception. */ @Override public NamingEnumeration list(Name name) throws NamingException { // Flat namespace; no federation; just call string version return list(name.toString()); } /** * List the bindings in the specified context. * * @param name context name. * @return an enumeration of the bindings. * @throws NamingException if there is a naming exception. */ @Override public NamingEnumeration listBindings(String name) throws NamingException { if (name.isEmpty()) { // listing this context try { Hashtable bindings = getProvider().list(myName); return new RepBindings(bindings); } catch (RemoteException ex) { CommunicationException ce = new CommunicationException(ex .toString()); ce.initCause(ex); throw ce; } } name = getRelativeName(name); if (isjavaURL(name)) { return javaUrlContext.listBindings(name); } else { // Perhaps 'name' names a context Object target = lookup(name); if (target instanceof Context) { return ((Context) target).listBindings(""); } throw new NotContextException(name + " cannot be listed"); } } /** * List the bindings in the specified context. * * @param name context name. * @return an enumeration of the bindings. * @throws NamingException if there is a naming exception. */ @Override public NamingEnumeration listBindings(Name name) throws NamingException { // Flat namespace; no federation; just call string version return listBindings(name.toString()); } /** * Destroy the specified subcontext. * * @param name name of the subcontext. * @throws NamingException if there is a naming exception. */ @Override public void destroySubcontext(String name) throws NamingException { name = getRelativeName(name); if (isjavaURL(name)) { javaUrlContext.destroySubcontext(name); } else { try { getProvider().destroySubcontext(name); } catch (RemoteException e) { CommunicationException ce = new CommunicationException(e .toString()); ce.initCause(e); throw ce; } } } /** * Destroy the specified subcontext. * * @param name name of the subcontext. * @throws NamingException if there is a naming exception. */ @Override public void destroySubcontext(Name name) throws NamingException { // Flat namespace; no federation; just call string version destroySubcontext(name.toString()); } /** * Create the specified subcontext. * * @param name name of the subcontext. * @return the created subcontext. * @throws NamingException if there is a naming exception. */ @Override public Context createSubcontext(String name) throws NamingException { Context c = null; name = getRelativeName(name); if (isjavaURL(name)) { return javaUrlContext.createSubcontext(name); } else { try { c = getProvider().createSubcontext(name); /* * this simulates the transient context structure on the client * side. Have to do this - as reference to Transient Context is * not resolved properly due to rmi */ if (c instanceof Context) { c = new SerialContext(name, myEnv, habitat); } } catch (RemoteException e) { CommunicationException ce = new CommunicationException(e .toString()); ce.initCause(e); throw ce; } return c; } } /** * Create the specified subcontext. * * @param name name of the subcontext. * @return the created subcontext. * @throws NamingException if there is a naming exception. */ @Override public Context createSubcontext(Name name) throws NamingException { // Flat namespace; no federation; just call string version return createSubcontext(name.toString()); } /** * Links are not treated specially. * * @param name name of the link. * @return the resolved object. * @throws NamingException if there is a naming exception. */ @Override public Object lookupLink(String name) throws NamingException { name = getRelativeName(name); if (isjavaURL(name)) { return javaUrlContext.lookupLink(name); } else { // This flat context does not treat links specially return lookup(name); } } /** * Links are not treated specially. * * @param name name of the link. * @return the resolved object. * @throws NamingException if there is a naming exception. */ @Override public Object lookupLink(Name name) throws NamingException { // Flat namespace; no federation; just call string version return lookupLink(name.toString()); } /** * Allow access to the name parser object. * * @param name JNDI name, is ignored since there is only one Name Parser * object. * @return NameParser object * @throws NamingException */ @Override public NameParser getNameParser(String name) throws NamingException { return myParser; } /** * Allow access to the name parser object. * * @param name JNDI name, is ignored since there is only one Name Parser * object. * @return NameParser object * @throws NamingException */ @Override public NameParser getNameParser(Name name) throws NamingException { // Flat namespace; no federation; just call string version return getNameParser(name.toString()); } @Override public String composeName(String name, String prefix) throws NamingException { Name result = composeName(new CompositeName(name), new CompositeName( prefix)); return result.toString(); } @Override public Name composeName(Name name, Name prefix) throws NamingException { Name result = (Name) (prefix.clone()); result.addAll(name); return result; } /** * Add to the environment for the current context. * * @throws NamingException if there is a naming exception. */ @Override public Object addToEnvironment(String propName, Object propVal) throws NamingException { if (myEnv == null) { myEnv = new Hashtable(5, 0.75f); } return myEnv.put(propName, propVal); } /** * Remove from the environment for the current context. * * @throws NamingException if there is a naming exception. */ @Override public Object removeFromEnvironment(String propName) throws NamingException { if (myEnv == null) { return null; } return myEnv.remove(propName); } /** * Return the environment for the current context. * * @throws NamingException if there is a naming exception. */ @Override public Hashtable getEnvironment() throws NamingException { if (myEnv == null) { // Must return non-null myEnv = new Hashtable(3, 0.75f); } return myEnv; } /** * Set the environment for the current context to null when close is called. * * @throws NamingException if there is a naming exception. */ @Override public void close() throws NamingException { myEnv = null; } private String getRelativeName(String name) { if (!myName.equals("")) { name = myName + "/" + name; } return name; } // Class for enumerating name/class pairs static class RepNames implements NamingEnumeration { Hashtable bindings; Enumeration names; RepNames(Hashtable bindings) { this.bindings = bindings; this.names = bindings.keys(); } @Override public boolean hasMoreElements() { return names.hasMoreElements(); } @Override public boolean hasMore() throws NamingException { return hasMoreElements(); } @Override public T nextElement() { if (names.hasMoreElements()) { String name = (String) names.nextElement(); String className = bindings.get(name).getClass().getName(); return (T) (new NameClassPair(name, className)); } else { return null; } } @Override public T next() throws NamingException { return nextElement(); } @Override public void close() { //no-op since no steps needed to free up resources } } // Class for enumerating bindings static class RepBindings implements NamingEnumeration { Enumeration names; Hashtable bindings; RepBindings(Hashtable bindings) { this.bindings = bindings; this.names = bindings.keys(); } @Override public boolean hasMoreElements() { return names.hasMoreElements(); } @Override public boolean hasMore() throws NamingException { return hasMoreElements(); } @Override public T nextElement() { if (hasMoreElements()) { String name = (String) names.nextElement(); return (T) (new Binding(name, bindings.get(name))); } else { return null; } } @Override public T next() throws NamingException { return nextElement(); } @Override public void close() { //no-op since no steps needed to free up resources } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SerialContext["); if(testMode) { sb.append("( IN TEST MODE ) "); } sb.append( "myEnv=" ) ; sb.append( myEnv ) ; return sb.toString(); } private class ProviderCacheKey { // Key is either orb OR host/port combo. private ORB localORB = null ; private String endpoints = null ; ProviderCacheKey(ORB orb) { this.localORB = orb; } // Host and Port must both be non-null ProviderCacheKey(String host, String port) { endpoints = "corbaloc:iiop:1.2@" + host + ":" + port + "/NameService" ; } ProviderCacheKey( String endpoints ) { this.endpoints = endpoints ; } @Override public String toString() { if (localORB == null) { return "ProviderCacheKey[" + endpoints + "]" ; } else { return "ProviderCacheKey[" + localORB + "]" ; } } public SerialContextProvider getNameService() throws InvalidName, NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName { org.omg.CORBA.Object objref = null; if (endpoints == null) { objref = orb.resolve_initial_references( "NameService"); } else { objref = orb.string_to_object(endpoints) ; } final NamingContext nctx = NamingContextHelper.narrow(objref); final NameComponent[] path = { new NameComponent("SerialContextProvider", "") }; final org.omg.CORBA.Object obj = nctx.resolve(path) ; SerialContextProvider result = (SerialContextProvider)PortableRemoteObject.narrow( obj, SerialContextProvider.class ); return result ; } @Override public int hashCode() { return (orb != null) ? orb.hashCode() : endpoints.hashCode(); } @Override public boolean equals(Object other) { if (other == null) { return false ; } if (!(other instanceof ProviderCacheKey)) { return false ; } ProviderCacheKey otherKey = (ProviderCacheKey) other; if (localORB != null) { return localORB == otherKey.localORB ; } else { if (endpoints == null) { return otherKey.endpoints == null ; } return endpoints.equals(otherKey.endpoints) ; } } } }