package org.jboss.tm;
import java.util.HashMap;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.jboss.util.NestedRuntimeException;
import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
public class TransactionLocalDelegateImpl
implements TransactionLocalDelegate
{
protected TransactionManager manager;
protected static ConcurrentHashMap synchronizationsByTransaction = new ConcurrentHashMap();
protected static TransactionLocalSynchronization getSynchronization(Transaction tx, boolean create)
{
TransactionLocalSynchronization result = (TransactionLocalSynchronization) synchronizationsByTransaction.get(tx);
if (result == null && create == true)
{
result = new TransactionLocalSynchronization(tx);
try
{
tx.registerSynchronization(result);
}
catch (RollbackException e)
{
throw new IllegalStateException("Transaction already rolled back or marked for rollback");
}
catch (SystemException e)
{
throw new NestedRuntimeException(e);
}
synchronizationsByTransaction.put(tx, result);
}
return result;
}
protected static void removeSynchronization(Transaction tx)
{
synchronizationsByTransaction.remove(tx);
}
public TransactionLocalDelegateImpl(TransactionManager manager)
{
this.manager = manager;
}
public Object getValue(TransactionLocal unused, Transaction tx)
{
TransactionLocalSynchronization sync = getSynchronization(tx, false);
if (sync == null)
return null;
return sync.getValue(this);
}
public void storeValue(TransactionLocal unused, Transaction tx, Object value)
{
TransactionLocalSynchronization sync = getSynchronization(tx, true);
sync.setValue(this, value);
}
public boolean containsValue(TransactionLocal unused, Transaction tx)
{
TransactionLocalSynchronization sync = getSynchronization(tx, false);
if (sync == null)
return false;
return sync.containsValue(this);
}
protected static class TransactionLocalSynchronization
implements Synchronization
{
protected Transaction tx;
protected HashMap valuesByLocal = new HashMap();
public TransactionLocalSynchronization(Transaction tx)
{
this.tx = tx;
}
public void beforeCompletion()
{
}
public void afterCompletion(int status)
{
removeSynchronization(tx);
valuesByLocal.clear(); }
public Object getValue(Object local)
{
return valuesByLocal.get(local);
}
public void setValue(Object local, Object value)
{
valuesByLocal.put(local, value);
}
public boolean containsValue(Object local)
{
return valuesByLocal.containsKey(local);
}
}
}