package org.jboss.invocation.jrmp.interfaces;
import java.io.IOException;
import java.io.Externalizable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.rmi.ConnectException;
import java.rmi.MarshalledObject;
import java.rmi.NoSuchObjectException;
import java.rmi.ServerException;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteStub;
import javax.transaction.TransactionRolledbackException;
import javax.transaction.SystemException;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.Invoker;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.tm.TransactionPropagationContextFactory;
import org.jboss.tm.TransactionPropagationContextUtil;
public class JRMPInvokerProxy
implements Invoker, Externalizable
{
private static final long serialVersionUID = -3713605626489646730L;
protected Invoker remoteInvoker;
public static int MAX_RETRIES = 10;
public JRMPInvokerProxy()
{
super();
}
public JRMPInvokerProxy(final Invoker remoteInvoker)
{
this.remoteInvoker = remoteInvoker;
}
public String getServerHostName() throws Exception
{
return remoteInvoker.getServerHostName();
}
public Object getTransactionPropagationContext()
throws SystemException
{
TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactoryClientSide();
return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
}
public Object invoke(Invocation invocation)
throws Exception
{
MarshalledInvocation mi = new MarshalledInvocation(invocation);
mi.setTransactionPropagationContext(getTransactionPropagationContext());
for (int i = 0; i < MAX_RETRIES; i++)
{
try
{
MarshalledObject result = (MarshalledObject) remoteInvoker.invoke(mi);
return result.get();
}
catch (ConnectException ce)
{
if (i + 1 < MAX_RETRIES)
{
Thread.sleep(1);
continue;
}
throw ce;
}
catch (ServerException ex)
{
if (ex.detail instanceof NoSuchObjectException)
{
throw (NoSuchObjectException) ex.detail;
}
if (ex.detail instanceof TransactionRolledbackException)
{
throw (TransactionRolledbackException) ex.detail;
}
throw ex;
}
}
throw new Exception("Unreachable statement");
}
public void writeExternal(final ObjectOutput out)
throws IOException
{
if( remoteInvoker instanceof RemoteStub )
{
out.writeObject(remoteInvoker);
}
else
{
Object replacement = RemoteObject.toStub(remoteInvoker);
out.writeObject(replacement);
}
}
public void readExternal(final ObjectInput in)
throws IOException, ClassNotFoundException
{
remoteInvoker = (Invoker) in.readObject();
}
}