blob: e0c96a909dc2082759d010ea4c853ba085c37577 [file] [log] [blame]
/*
* Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.enterprise.naming.impl;
import org.glassfish.api.admin.ProcessEnvironment;
import org.glassfish.api.admin.ProcessEnvironment.ProcessType;
import org.glassfish.api.naming.NamingClusterInfo;
import org.glassfish.api.naming.NamingObjectProxy;
import org.glassfish.internal.api.Globals;
import org.glassfish.internal.api.ORBLocator;
import org.glassfish.internal.api.ServerContext;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.glassfish.hk2.api.ServiceLocator;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import javax.naming.*;
import javax.naming.spi.ObjectFactory;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Level;
import static com.sun.enterprise.naming.util.LogFacade.logger;
/**
* 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.
* <p/>
* <b>NOT THREAD SAFE: mutable instance variables</b>
*/
public class SerialContext implements Context {
@LogMessageInfo(message = "Exception during name lookup : {0}",
cause = "App Server may not be running at port intended, or possible Network Error.",
action = "Check to see if the AppServer is up and running on the port intended. The problem could be because of incorrect port. Check to see if you can access the host on which the AppServer running.")
public static final String EXCEPTION_DURING_LOOKUP = "AS-NAMING-00002";
// 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 NameParser myParser = new SerialNameParser();
private static final Map<ProviderCacheKey, SerialContextProvider> providerCache =
new HashMap<ProviderCacheKey, SerialContextProvider>();
private static final ThreadLocal<ThreadLocalIC> stickyContext =
new ThreadLocal<ThreadLocalIC>() {
@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 ServiceLocator services;
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, ServiceLocator h)
throws NamingException {
services = h;
myEnv = (Hashtable) environment.clone();
// 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( myEnv.get(INITIAL_CONTEXT_TEST_MODE) != null ) {
testMode = true;
System.out.println("SerialContext in test mode");
}
if( (services == null) && !testMode ) {
synchronized(SerialContext.class) {
if( SerialInitContextFactory.getDefaultServices() == 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.
services = Globals.getStaticHabitat();
SerialInitContextFactory.setDefaultServices(services);
} else {
services = SerialInitContextFactory.getDefaultServices();
}
}
}
if( testMode ) {
processType = ProcessType.Server;
} else {
ProcessEnvironment processEnv = services.getService(ProcessEnvironment.class);
if (processEnv == null) {
processEnv = services.create(ProcessEnvironment.class);
services.inject(processEnv);
services.postConstruct(processEnv);
}
processType = processEnv.getProcessType();
}
// using these two temp variables allows instance variables
// to be 'final'.
JavaURLContext urlContextTemp = null;
if (myEnv.get(NamingClusterInfo.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 (services != null) { // can happen in test mode
ServerContext sc = services.getService(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, ServiceLocator services) throws NamingException {
this("", env, services);
}
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 = services.getService(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(
NamingClusterInfo.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(services);
/**
* 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(NamingClusterInfo.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, services));
}
name = getRelativeName(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, services);
}
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, EXCEPTION_DURING_LOOKUP, 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} ", 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<NameClassPair> list(String name) throws NamingException {
if (name.isEmpty()) {
// listing this context
try {
Hashtable bindings = getProvider().list(myName);
return new RepNames<NameClassPair>(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<NameClassPair> 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<Binding> listBindings(String name) throws NamingException {
if (name.isEmpty()) {
// listing this context
try {
Hashtable bindings = getProvider().list(myName);
return new RepBindings<Binding>(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<Binding> 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 {
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
*/
c = new SerialContext(name, myEnv, services);
} 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<T> implements NamingEnumeration<T> {
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<T> implements NamingEnumeration<T> {
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) ;
}
}
}
}