package org.jboss.invocation;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.UndeclaredThrowableException;
import javax.transaction.Transaction;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.Invoker;
import org.jboss.proxy.Interceptor;
import org.jboss.system.Registry;
import org.jboss.util.id.GUID;
public class InvokerInterceptor
extends Interceptor
implements Externalizable
{
private static final long serialVersionUID = 2548120545997920357L;
private GUID invokerID = Invoker.ID;
protected Invoker remoteInvoker;
protected static Invoker localInvoker;
protected static Class invokerProxyHA;
static
{
try
{
invokerProxyHA = Class.forName("org.jboss.invocation.InvokerProxyHA");
}
catch (Throwable ignored)
{
}
}
public static Invoker getLocal()
{
return localInvoker;
}
public static void setLocal(Invoker invoker)
{
localInvoker = invoker;
}
public InvokerInterceptor()
{
super();
}
public boolean isLocal()
{
return invokerID.equals(Invoker.ID);
}
public boolean isLocal(Invocation invocation)
{
if (localInvoker == null)
return false;
if (isLocal() == false)
{
if (isClustered(invocation) == false)
return false;
}
return hasLocalTarget(invocation);
}
public boolean isClustered(Invocation invocation)
{
if (invokerProxyHA == null)
return false;
InvocationContext ctx = invocation.getInvocationContext();
Invoker invoker = ctx.getInvoker();
return invoker != null && invokerProxyHA.isAssignableFrom(invoker.getClass());
}
public boolean hasLocalTarget(Invocation invocation)
{
return Registry.lookup(invocation.getObjectName()) != null;
}
public Object invoke(Invocation invocation)
throws Exception
{
if (isLocal(invocation))
return invokeLocal(invocation);
else
return invokeInvoker(invocation);
}
protected Object invokeLocal(Invocation invocation) throws Exception
{
return localInvoker.invoke(invocation);
}
protected Object invokeMarshalled(Invocation invocation) throws Exception
{
MarshalledInvocation mi = new MarshalledInvocation(invocation);
MarshalledValue copy = new MarshalledValue(mi);
Invocation invocationCopy = (Invocation) copy.get();
Transaction tx = invocation.getTransaction();
invocationCopy.setTransaction(tx);
try
{
Object rtnValue = localInvoker.invoke(invocationCopy);
MarshalledValue mv = new MarshalledValue(rtnValue);
return mv.get();
}
catch(Throwable t)
{
MarshalledValue mv = new MarshalledValue(t);
Throwable t2 = (Throwable) mv.get();
if( t2 instanceof Exception )
throw (Exception) t2;
else
throw new UndeclaredThrowableException(t2);
}
}
protected Object invokeInvoker(Invocation invocation) throws Exception
{
InvocationContext ctx = invocation.getInvocationContext();
Invoker invoker = ctx.getInvoker();
return invoker.invoke(invocation);
}
public void writeExternal(final ObjectOutput out)
throws IOException
{
out.writeObject(invokerID);
}
public void readExternal(final ObjectInput in)
throws IOException, ClassNotFoundException
{
invokerID = (GUID)in.readObject();
}
}