package org.sef4j.jdbc.wrappers;
import java.sql.SQLException;
import javax.sql.XAConnection;
import javax.transaction.xa.XAResource;
import org.sef4j.callstack.LocalCallStack;
import org.sef4j.callstack.CallStackElt.StackPopper;
/**
* Proxy for java.sql.XAConnection + wrapp all calls with push()/pop() + return wrapped object
*
*/
public class SefXAConnectionProxy extends SefPooledConnectionProxy implements XAConnection {
private static final String CNAME = SefXAConnectionProxy.class.getName();
/** redundant with <code>(XAConnection)super.to</code> */
private XAConnection to;
protected SefXAResourceProxy cachedWrapperXAResource;
protected XAResource cachedTargetXAResource;
// ------------------------------------------------------------------------
public SefXAConnectionProxy(SefConnectionProxy ownerSefConnectionProxy, XAConnection to) {
super(to); // TOADD ... owner
this.to = to;
}
// ------------------------------------------------------------------------
public XAResource getXAResource() throws SQLException {
StackPopper toPop = LocalCallStack.meth(CNAME, "getXAResource").push();
try {
XAResource tmpres = to.getXAResource();
SefXAResourceProxy res = wrapOrReuseWrapper(tmpres);
return toPop.returnValue(res);
} catch(SQLException ex) {
throw toPop.returnException(ex);
} finally {
toPop.close();
}
}
private SefXAResourceProxy wrapOrReuseWrapper(XAResource tmpres) {
// wrap result or reuse last wrapper... TODO may use Map<XAResource,SefXAResourceProxy>
if (tmpres == null) return null; // should not occur
SefXAResourceProxy res;
if (cachedTargetXAResource == tmpres && cachedWrapperXAResource != null) {
res = cachedWrapperXAResource; // reuse same wrapper for same target return
} else {
cachedTargetXAResource = tmpres;
cachedWrapperXAResource = new SefXAResourceProxy(this, tmpres);
res = cachedWrapperXAResource;
}
return res;
}
// ------------------------------------------------------------------------
@Override
public String toString() {
return "SefXAConnectionProxy[to=" + to + "]";
}
}