package org.jboss.remoting;
import org.jboss.logging.Logger;
import org.jboss.remoting.transport.ClientInvoker;
import org.jboss.remoting.transport.http.HTTPClientInvoker;
import org.jboss.remoting.transport.http.HTTPServerInvoker;
import org.jboss.remoting.transport.local.LocalClientInvoker;
import org.jboss.remoting.transport.rmi.RMIClientInvoker;
import org.jboss.remoting.transport.rmi.RMIServerInvoker;
import org.jboss.remoting.transport.socket.SocketClientInvoker;
import org.jboss.remoting.transport.socket.SocketServerInvoker;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class InvokerRegistry
{
private static final Logger log = Logger.getLogger(InvokerRegistry.class);
private static final Map clientInvokers = new HashMap();
private static final Map serverInvokers = new HashMap();
private static final Map clientLocators = new HashMap();
private static final Map serverLocators = new HashMap();
private static final Set registeredLocators = new HashSet();
private static final Object serverLock = new Object();
private static final Object clientLock = new Object();
static
{
registerInvoker("socket", SocketClientInvoker.class, SocketServerInvoker.class);
registerInvoker("rmi", RMIClientInvoker.class, RMIServerInvoker.class);
registerInvoker("http", HTTPClientInvoker.class, HTTPServerInvoker.class);
}
public static synchronized final InvokerLocator[] getRegisteredServerLocators()
{
return (InvokerLocator[]) registeredLocators.toArray(new InvokerLocator[registeredLocators.size()]);
}
public static synchronized InvokerLocator getSuitableServerLocatorForRemote(InvokerLocator remote)
{
Iterator iter = registeredLocators.iterator();
while(iter.hasNext())
{
InvokerLocator l = (InvokerLocator) iter.next();
if(l.getProtocol().equals(remote.getProtocol()))
{
return l;
}
}
return null;
}
public static final String[] getRegisteredInvokerTransports()
{
synchronized(clientLock)
{
Set set = clientInvokers.keySet();
String transports[] = new String[set.size()];
return (String[]) set.toArray(transports);
}
}
public static final ClientInvoker[] getClientInvokers()
{
synchronized(clientLock)
{
if(clientLocators.isEmpty())
{
return new ClientInvoker[0];
}
Collection collection = clientLocators.values();
return (ClientInvoker[]) collection.toArray(new RemoteClientInvoker[collection.size()]);
}
}
public static final ServerInvoker[] getServerInvokers()
{
synchronized(serverLock)
{
if(serverLocators.isEmpty())
{
return new ServerInvoker[0];
}
Collection collection = serverLocators.values();
return (ServerInvoker[]) collection.toArray(new ServerInvoker[collection.size()]);
}
}
public static synchronized void registerInvoker(String transport, Class client, Class server)
{
clientInvokers.put(transport, client);
serverInvokers.put(transport, server);
}
public static synchronized void unregisterInvoker(String transport)
{
clientInvokers.remove(transport);
serverInvokers.remove(transport);
}
public static synchronized void unregisterLocator(InvokerLocator locator)
{
serverLocators.remove(locator);
registeredLocators.remove(locator);
}
public static boolean isClientInvokerRegistered(InvokerLocator locator)
{
synchronized(clientLock)
{
return clientLocators.containsKey(locator);
}
}
public static void destroyClientInvoker(InvokerLocator locator)
{
ClientInvoker invoker = null;
synchronized(clientLock)
{
invoker = (ClientInvoker) clientLocators.remove(locator);
}
if(invoker != null)
{
if(log.isDebugEnabled())
{
log.debug("destroying client for locator: " + locator + ", invoker:" + invoker + ", remaining list:" + clientLocators);
}
invoker.disconnect();
invoker = null;
}
}
public static ClientInvoker createClientInvoker(InvokerLocator locator)
throws Exception
{
if(locator == null)
{
throw new NullPointerException("locator cannot be null");
}
synchronized(clientLock)
{
ClientInvoker invoker = (ClientInvoker) clientLocators.get(locator);
if(invoker != null)
{
return invoker;
}
boolean isPassByValue = false;
Map parameters = locator.getParameters();
if(parameters != null)
{
String value = (String) parameters.get(InvokerLocator.BYVALUE);
if(value != null && Boolean.valueOf(value).booleanValue())
{
isPassByValue = true;
}
}
ServerInvoker svrInvoker = (ServerInvoker) serverLocators.get(locator);
if(svrInvoker != null && !isPassByValue)
{
LocalClientInvoker localInvoker = new LocalClientInvoker(locator);
localInvoker.setServerInvoker(svrInvoker);
invoker = localInvoker;
InvokerLocator l = invoker.getLocator();
clientLocators.put(l, invoker);
}
else {
String protocol = locator.getProtocol();
if(protocol == null)
{
throw new NullPointerException("protocol cannot be null for the locator");
}
Class cl = (Class) clientInvokers.get(protocol);
if(cl == null)
{
throw new RuntimeException("Couldn't find valid client invoker class for transport '" + protocol + "'");
}
Constructor ctor = cl.getConstructor(new Class[]{InvokerLocator.class});
invoker = (ClientInvoker) ctor.newInstance(new Object[]{locator});
InvokerLocator l = invoker.getLocator();
clientLocators.put(l, invoker);
}
return invoker;
}
}
public static boolean isServerInvokerRegistered(InvokerLocator locator)
{
synchronized(serverLock)
{
return serverLocators.containsKey(locator);
}
}
public static ServerInvoker createServerInvoker(InvokerLocator locator)
throws Exception
{
return createServerInvoker(locator, null);
}
public static ServerInvoker createServerInvoker(InvokerLocator locator, Map configuration)
throws Exception
{
ServerInvoker invoker = null;
synchronized(serverLock)
{
invoker = (ServerInvoker) serverLocators.get(locator);
if(invoker != null)
{
return invoker;
}
Class cl = (Class) serverInvokers.get(locator.getProtocol());
if(cl == null)
{
throw new RuntimeException("Couldn't find valid server invoker class for transport '" + locator.getProtocol() + "'");
}
if(configuration != null)
{
Constructor ctor = cl.getConstructor(new Class[]{InvokerLocator.class, Map.class});
invoker = (ServerInvoker) ctor.newInstance(new Object[]{locator, configuration});
}
else
{
Constructor ctor = cl.getConstructor(new Class[]{InvokerLocator.class});
invoker = (ServerInvoker) ctor.newInstance(new Object[]{locator});
}
serverLocators.put(locator, invoker);
registeredLocators.add(invoker.getLocator());
}
try
{
return invoker;
}
catch(Exception ex)
{
serverLocators.remove(locator);
registeredLocators.remove(locator);
throw ex;
}
}
}