package org.jboss.tm.usertx.server;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.Context;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.tm.usertx.client.ClientUserTransaction;
import org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory;
import org.jboss.tm.usertx.interfaces.UserTransactionSession;
import org.jboss.tm.TransactionPropagationContextUtil;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;
public class ClientUserTransactionService
extends ServiceMBeanSupport
implements ClientUserTransactionServiceMBean
{
public static String JNDI_NAME = "UserTransaction";
private Map marshalledInvocationMapping = new HashMap();
private ObjectName txProxyName;
private Object txProxy;
public void setTxProxyName(ObjectName proxyName)
{
this.txProxyName = proxyName;
}
public Object invoke(Invocation invocation) throws Exception
{
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try
{
if( UserTransactionSessionFactory.class.isAssignableFrom(method.getDeclaringClass()) )
{
value = txProxy;
}
else if( method.getName().equals("begin") )
{
Integer timeout = (Integer) args[0];
UserTransactionSession session = UserTransactionSessionImpl.getInstance();
value = session.begin(timeout.intValue());
}
else if( method.getName().equals("destroy"))
{
}
else
{
UserTransactionSession session = UserTransactionSessionImpl.getInstance();
value = method.invoke(session, args);
}
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
}
protected void startService()
throws Exception
{
Context ctx = new InitialContext();
ctx.bind(JNDI_NAME, ClientUserTransaction.getSingleton());
txProxy = getServer().getAttribute(txProxyName, "Proxy");
HashMap tmpMap = new HashMap(13);
Method[] methods = UserTransactionSession.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);
}
methods = UserTransactionSessionFactory.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()
{
try
{
Context ctx = new InitialContext();
ctx.unbind(JNDI_NAME);
}
catch (Exception e)
{
log.warn("Failed to unbind "+JNDI_NAME, e);
}
}
}