package org.jboss.remoting;
import EDU.oswego.cs.dl.util.concurrent.Executor;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
import org.jboss.logging.Logger;
import org.jboss.remoting.invocation.InternalInvocation;
import org.jboss.remoting.invocation.OnewayInvocation;
import org.jboss.remoting.marshal.Marshaller;
import org.jboss.remoting.marshal.UnMarshaller;
import org.jboss.remoting.transport.ClientInvoker;
import org.jboss.util.id.GUID;
import java.util.List;
import java.util.Map;
public class Client
{
public static final int MAX_NUM_ONEWAY_THREADS = 10;
private static final Logger log = Logger.getLogger(Client.class);
private ClientInvoker invoker;
private ClassLoader classloader;
private String subsystem;
private String sessionId = new GUID().toString();
private static PooledExecutor onewayExecutor;
private static int onewayThreadCounter = 0;
public static final String RAW = "RAW_PAYLOAD";
public Client(InvokerLocator locator) throws Exception
{
this(locator, null);
}
public Client(InvokerLocator locator, String subsystem)
throws Exception
{
this(Thread.currentThread().getContextClassLoader(), locator, subsystem);
}
public Client(ClassLoader cl, InvokerLocator locator, String subsystem)
throws Exception
{
this(cl, InvokerRegistry.createClientInvoker(locator), subsystem);
}
public Client(ClassLoader cl, ClientInvoker invoker, String subsystem)
throws Exception
{
this.classloader = cl;
this.subsystem = subsystem == null ? null : subsystem.toUpperCase();
this.invoker = invoker;
}
public void setSessionId(String sessionId)
{
this.sessionId = sessionId;
}
public String getSessionId()
{
return this.sessionId;
}
public boolean isConnected()
{
return (this.invoker != null && this.invoker.isConnected());
}
public void connect() throws Exception
{
this.invoker.connect();
}
public void disconnect()
{
this.invoker.disconnect();
}
public ClientInvoker getInvoker()
{
return invoker;
}
public void setInvoker(ClientInvoker invoker)
{
this.invoker = invoker;
}
public String getSubsystem()
{
return subsystem;
}
public void setSubsystem(String subsystem)
{
this.subsystem = subsystem;
}
private void setClientLocator(InvokerLocator locator) throws Exception
{
if (invoker != null)
{
invoker.setClientLocator(locator);
}
else
{
throw new Exception("Can not set client locator because client invoker is null.");
}
}
public Object invoke(Object param) throws Throwable
{
return invoke(param, null);
}
public Object invoke(Object param, Map metadata)
throws Throwable
{
ClientInvoker localInvoker = invoker;
if (localInvoker != null)
{
if (localInvoker.isConnected() == false)
{
if (log.isDebugEnabled())
{
log.debug("invoke called, but our invoker is disconnected, discarding and fetching another fresh invoker for: " + invoker.getLocator());
}
localInvoker = InvokerRegistry.createClientInvoker(localInvoker.getLocator());
connect();
}
}
else
{
throw new Exception("Can not perform invoke because invoker is null.");
}
Object ret = localInvoker.invoke(new InvocationRequest(sessionId, subsystem, param, metadata, null, null));
this.invoker = localInvoker;
return ret;
}
public void invokeOneway(final Object param, final Map sendPayload, boolean clientSide) throws Throwable
{
if (clientSide)
{
Executor executor = getOnewayExecutor();
Runnable onewayRun = new Runnable()
{
public void run()
{
try
{
invoke(param, sendPayload);
}
catch (Throwable e)
{
log.error("Error executing client oneway invocation request: " + param, e);
}
}
};
executor.execute(onewayRun);
}
else
{
OnewayInvocation invocation = new OnewayInvocation(param);
invoke(invocation, sendPayload);
}
}
private synchronized static Executor getOnewayExecutor()
{
if (onewayExecutor == null)
{
onewayExecutor = new PooledExecutor(MAX_NUM_ONEWAY_THREADS);
onewayExecutor.setKeepAliveTime(3000);
onewayExecutor.waitWhenBlocked();
onewayExecutor.setThreadFactory(new ThreadFactory()
{
public Thread newThread(Runnable runnable)
{
return new Thread(runnable, "Remoting client oneway " + onewayThreadCounter++);
}
});
}
return onewayExecutor;
}
public void invokeOneway(Object param, Map sendPayload) throws Throwable
{
invokeOneway(param, sendPayload, false);
}
public void addListener(InvokerCallbackHandler callbackHandler) throws Throwable
{
addListener(callbackHandler, null);
}
public void addListener(InvokerCallbackHandler callbackHandler,
InvokerLocator clientLocator) throws Throwable
{
addListener(callbackHandler, clientLocator, null);
}
public void addListener(InvokerCallbackHandler callbackHandler,
InvokerLocator clientLocator, Object callbackHandlerObject) throws Throwable
{
invoker.setClientLocator(clientLocator);
if (clientLocator != null)
{
Client client = new Client(clientLocator, subsystem);
client.setSessionId(getSessionId());
client.connect();
client.invoke(new InternalInvocation(InternalInvocation.ADDCLIENTLISTENER,
new Object[]{callbackHandler, callbackHandlerObject}),
null);
client.disconnect();
}
invoke(new InternalInvocation(InternalInvocation.ADDLISTENER, null), null);
}
public void removeListener(InvokerCallbackHandler callbackHandler) throws Throwable
{
InvokerLocator locator = invoker.getClientLocator();
if (locator != null) {
Client client = new Client(locator, subsystem);
client.setSessionId(getSessionId());
client.connect();
client.invoke(new InternalInvocation(InternalInvocation.REMOVECLIENTLISTENER,
new Object[]{callbackHandler}),
null);
client.disconnect();
}
invoke(new InternalInvocation(InternalInvocation.REMOVELISTENER, null), null);
}
public List getCallbacks() throws Throwable
{
return (List) invoke(new InternalInvocation(InternalInvocation.GETCALLBACKS, null), null);
}
public void setMarshaller(Marshaller marshaller)
{
if (invoker != null && marshaller != null)
{
invoker.setMarshaller(marshaller);
}
}
public void setUnMarshaller(UnMarshaller unmarshaller)
{
if (invoker != null && unmarshaller != null)
{
invoker.setUnMarshaller(unmarshaller);
}
}
}