/**
*
* JOnAS: Java(TM) Open Application Server
* Copyright (C) 1999-2005 Bull S.A.
* Contact: jonas-team@objectweb.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: NamingManager.java 6893 2005-06-06 11:20:35Z benoitf $
* --------------------------------------------------------------------------
*/
package org.objectweb.jonas.naming;
import java.util.Hashtable;
import javax.ejb.spi.HandleDelegate;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.omg.CORBA.ORB;
import org.objectweb.carol.jndi.ns.JacORBCosNaming;
import org.objectweb.jonas_ejb.container.JHandleDelegate;
import org.objectweb.jonas_lib.naming.ContainerNaming;
import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
/**
* Naming Manager for an EJB Server. this singleton class must exist in each
* jonas server.
* @author Philippe Durieux
* @author Philippe Coq : Monolog
* @author Florent Benoit & Ludovic Bert : Context for web container
*/
public class NamingManager implements ContainerNaming {
/**
* Logger used for traces
*/
private static Logger logger = Log.getLogger(Log.JONAS_NAMING_PREFIX);
/**
* Naming Context associated with the thread
*/
private ThreadLocal threadContext = new ThreadLocal();
/**
* Initial Context
*/
private InitialContext ictx = null;
/**
* Context of the server
*/
private static Context serverContext = null;
/**
* Environment
*/
private Hashtable myEnv = null;
/**
* Associate a context to a class loader
*/
private Hashtable clBindings = null;
/**
* Static context used by client container. One context for all the JVM.
*/
private static Context clientCtx = null;
/**
* Singleton management: - the constructor is private. - use static method
* getInstance to retrieve/create the instance.
*/
private static NamingManager unique = null;
/**
* UserTransaction object, to be shared by all components.
*/
private Object userTransaction = null;
/**
* HandleDelegate implementation is shared by all component contexts
*/
private HandleDelegate handleDelegate = null;
/**
* Create the naming manager.
* @throws NamingException if no initial context is built
*/
private NamingManager() throws NamingException {
try {
ictx = new InitialContext();
// there is a bug in carol that makes this not work.
//myEnv = ictx.getEnvironment();
clBindings = new Hashtable();
} catch (NamingException n) {
logger.log(BasicLevel.ERROR, "NamingManager: " + n.getExplanation());
Throwable t = n.getRootCause();
if (t != null) {
if (t.getMessage().startsWith("Connection refused to host:")) {
logger.log(BasicLevel.ERROR, "NamingManager: rmi registry not started ?");
} else if (t.getMessage().startsWith("error during remote invocation")) {
logger.log(BasicLevel.ERROR, "NamingManager: jrmi registry not started ?");
} else {
logger.log(BasicLevel.ERROR, "NamingManager: " + t.getMessage());
}
}
throw n;
}
}
/**
* Return the unique instance of a NamingManager.
* @return NamingManager the unique instance.
* @throws NamingException if it failed.
*/
public static NamingManager getInstance() throws NamingException {
if (unique == null) {
unique = new NamingManager();
}
return unique;
}
// ------------------------------------------------------------------
// ContainerNaming implementation
// ------------------------------------------------------------------
/**
* Get the initialContext used in this jonas server.
* @return InitialContext the initial context.
*/
public InitialContext getInitialContext() {
return ictx;
}
/**
* @return The HandleDelegate implementation for this server
*/
public HandleDelegate getHandleDelegate() {
if (handleDelegate == null) {
handleDelegate = new JHandleDelegate();
}
return handleDelegate;
}
/**
* Create Context for application and component environments. (formally
* known as createComponentContext)
* @param namespace namespace to used for the Context
* @return a java: context with comp/ subcontext
* @throws NamingException if the creation of the java: context failed.
*/
public Context createEnvironmentContext(String namespace) throws NamingException {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, namespace);
}
// Create a new environment
CompNamingContext ctx = new CompNamingContext(namespace);
// Create subContext
Context compCtx = ctx.createSubcontext("comp");
// Bind java:comp/UserTransaction
if (userTransaction == null) {
try {
userTransaction = ictx.lookup("javax.transaction.UserTransaction");
} catch (NamingException ne) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "Cannot lookup UserTransaction.");
}
}
}
if (userTransaction != null) {
compCtx.rebind("UserTransaction", userTransaction);
}
ORB orb = JacORBCosNaming.getOrb();
if (orb != null) {
try {
// Bind the java:comp/ORB object instance
compCtx.rebind("ORB", orb);
} catch (NamingException e) {
String err = "Cannot create URL for java:comp/ORB object : " + e;
logger.log(BasicLevel.ERROR, err);
throw new NamingException(err);
}
}
// Bind java:comp/HandleDelegate
compCtx.rebind("HandleDelegate", getHandleDelegate());
return ctx;
}
/**
* Get the Context associated with the current thread or to a class loader
* @return Context the component context.
* @throws NamingException When operation is not allowed
*/
public Context getComponentContext() throws NamingException {
Context ctx = null;
// Check if there is a context to the local thread
// For ejbs
ctx = (Context) threadContext.get();
if (ctx != null) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "return Context for ejb");
}
return ctx;
}
// Check if there is a context which match the currentThread
// classLoader
// For webapps
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if ((cl != null) && (cl.getParent() != null)) {
ctx = (Context) clBindings.get(cl.getParent());
if (ctx != null) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "return Context for webapp");
}
return ctx;
}
}
// Check static context. use in client. One context per JVM.
if (clientCtx != null) {
ctx = clientCtx;
if (ctx != null) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "return Context for client");
}
return ctx;
}
}
// No context found. This is outside of a j2ee component or server
// component.
if (ctx == null) {
ctx = getServerContext();
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "return default server Context");
}
}
return ctx;
}
/**
* Associate this CompNamingContext with the current thread. This method
* should be called in preinvoke/postinvoke and when we build the bean
* environment or web environment.
* @param ctx the context to associate to the current thread.
* @return Context the context of the thread
*/
public Context setComponentContext(Context ctx) {
Context ret = (Context) threadContext.get();
threadContext.set(ctx);
return ret;
}
/**
* Set back the context with the given value.
* Don't return the previous context, use setComponentContext() method for this.
* @param ctx the context to associate to the current thread.
*/
public void resetComponentContext(Context ctx) {
threadContext.set(ctx);
}
/**
* Associate the specified CompNamingContext with the given classloader.
* @param ctx the context to associate to the classloader.
* @param cl the classloader which is bind to the context.
*/
public void setComponentContext(Context ctx, ClassLoader cl) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "class loader = " + cl);
}
clBindings.put(cl, ctx);
}
/**
* Set the context used by client container (per JVM instead of per thread)
* @param ctx the context to set
*/
public void setClientContainerComponentContext(Context ctx) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "");
}
clientCtx = ctx;
}
/**
* Return the CompNamingContext associated with the given classloader.
* @param cl the classloader which is bind to the context.
* @return the CompNamingContext associated with the given classloader.
*/
public Context getComponentContext(ClassLoader cl) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "class loader = " + cl);
}
return (Context) clBindings.get(cl);
}
/**
* Remove the CompNamingContext associated with the given classloader.
* @param cl the classloader which is bind to the context.
*/
public void unSetComponentContext(ClassLoader cl) {
if (Log.isDebugNaming()) {
logger.log(BasicLevel.DEBUG, "class loader = " + cl);
}
clBindings.remove(cl);
}
/**
* Return the environment for JNDI This is used only for handles today.
* @return Hashtable the environment.
*/
public Hashtable getEnv() {
return myEnv;
}
/**
* Create Immutable Context. Not implemented !
* @param namespace namespace to used for the Context
* @return Context an immutable context
* @throws NamingException if the creation of the java: context failed.
*/
public Context createImmutableEnvironmentContext(String namespace) throws NamingException {
logger.log(BasicLevel.ERROR, "Not Implemented");
return null;
}
// ------------------------------------------------------------------
// other proprietary methods
// ------------------------------------------------------------------
/**
* Get the server component context. This is used only internally in the
* jonas NamingManager.
* @return Context the server component context.
*/
public Context getServerContext() {
if (serverContext == null) {
try {
serverContext = createEnvironmentContext("server");
} catch (NamingException e) {
logger.log(BasicLevel.ERROR, "cannot create serverContext:" + e);
}
}
return serverContext;
}
}
|