package org.jboss.naming;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.invocation.jrmp.server.JRMPProxyFactoryMBean;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.util.threadpool.ThreadPool;
import org.jboss.util.threadpool.BasicThreadPoolMBean;
import org.jnp.interfaces.Naming;
import org.jnp.interfaces.MarshalledValuePair;
import org.jnp.server.Main;
public class NamingService
extends ServiceMBeanSupport
implements NamingServiceMBean
{
private Main naming;
private Map marshalledInvocationMapping = new HashMap();
private JRMPProxyFactoryMBean proxyFactory;
public NamingService()
{
naming = new Main(this.getClass().getName());
}
public void setLookupPool(BasicThreadPoolMBean poolMBean)
{
ThreadPool lookupPool = poolMBean.getInstance();
naming.setLookupPool(lookupPool);
}
public boolean getCallByValue()
{
return MarshalledValuePair.getEnableCallByReference() == false;
}
public void setCallByValue(boolean flag)
{
boolean callByValue = ! flag;
MarshalledValuePair.setEnableCallByReference(callByValue);
}
public void setPort(int port)
{
naming.setPort(port);
}
public int getPort()
{
return naming.getPort();
}
public void setRmiPort(int port)
{
naming.setRmiPort(port);
}
public int getRmiPort()
{
return naming.getRmiPort();
}
public String getBindAddress()
{
return naming.getBindAddress();
}
public void setBindAddress(String host) throws UnknownHostException
{
naming.setBindAddress(host);
}
public String getRmiBindAddress()
{
return naming.getRmiBindAddress();
}
public void setRmiBindAddress(String host) throws UnknownHostException
{
naming.setRmiBindAddress(host);
}
public int getBacklog()
{
return naming.getBacklog();
}
public void setBacklog(int backlog)
{
naming.setBacklog(backlog);
}
public boolean getInstallGlobalService()
{
return naming.getInstallGlobalService();
}
public void setInstallGlobalService(boolean flag)
{
naming.setInstallGlobalService(flag);
}
public String getClientSocketFactory()
{
return naming.getClientSocketFactory();
}
public void setClientSocketFactory(String factoryClassName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
naming.setClientSocketFactory(factoryClassName);
}
public String getServerSocketFactory()
{
return naming.getServerSocketFactory();
}
public void setServerSocketFactory(String factoryClassName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
naming.setServerSocketFactory(factoryClassName);
}
public void setJNPServerSocketFactory(String factoryClassName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
naming.setJNPServerSocketFactory(factoryClassName);
}
public void setInvokerProxyFactory(JRMPProxyFactoryMBean proxyFactory)
{
this.proxyFactory = proxyFactory;
}
protected void startService()
throws Exception
{
boolean debug = log.isDebugEnabled();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("jndi.properties");
if (is == null)
throw new RuntimeException("Cannot find jndi.properties, it should be at conf/jndi.properties by default.");
Properties props = new Properties();
try
{
props.load(is);
}
finally
{
is.close();
}
for (Enumeration keys = props.propertyNames(); keys.hasMoreElements(); )
{
String key = (String) keys.nextElement();
String value = props.getProperty(key);
if (debug)
{
log.debug("System.setProperty, key="+key+", value="+value);
}
System.setProperty(key, value);
}
if( proxyFactory != null )
naming.setNamingProxy(proxyFactory.getProxy());
naming.start();
InitialContext iniCtx = new InitialContext();
Hashtable env = iniCtx.getEnvironment();
if (debug)
log.debug("InitialContext Environment:");
String providerURL = null;
for (Enumeration keys = env.keys(); keys.hasMoreElements(); )
{
String key = (String) keys.nextElement();
String value = (String) env.get(key);
if (debug) {
log.debug("key="+key+", value="+value);
}
if( key.equals(Context.PROVIDER_URL) )
providerURL = value;
}
if( providerURL != null )
log.warn("Context.PROVIDER_URL in server jndi.properties, url="+providerURL);
ClassLoader topLoader = Thread.currentThread().getContextClassLoader();
ENCFactory.setTopClassLoader(topLoader);
RefAddr refAddr = new StringRefAddr("nns", "ENC");
Reference envRef = new Reference("javax.naming.Context", refAddr, ENCFactory.class.getName(), null);
Context ctx = (Context)iniCtx.lookup("java:");
ctx.rebind("comp", envRef);
log.debug("Listening on port "+naming.getPort());
ctx.close();
iniCtx.close();
HashMap tmpMap = new HashMap(13);
Method[] methods = Naming.class.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
}
protected void stopService()
throws Exception
{
naming.stop();
log.debug("JNP server stopped");
}
protected Main getNamingServer()
{
return naming;
}
public Map getMethodMap()
{
return marshalledInvocationMapping;
}
public Object invoke(Invocation invocation) throws Exception
{
Naming theServer = naming.getServer();
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try
{
value = method.invoke(theServer, args);
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
}
}