/* * Copyright 2007 The Topaz Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * Contributions: */ package org.mulgara.server.rmi; // Java 2 standard packages import java.io.Serializable; import java.rmi.RemoteException; import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; // Third party packages import org.apache.log4j.*; // Local packages import org.mulgara.server.ResourceManagerInstanceAdaptor; /** * Wraps an RMI RemoteXAResource and presents it as a pure XAResource. * * @created 2007-11-28 * @author Andrae Muys * @licence Apache License v2.0 */ class RemoteXAResourceWrapperXAResource implements XAResource, ResourceManagerInstanceAdaptor { /** logger */ private static final Logger logger = Logger.getLogger(RemoteXAResourceWrapperXAResource.class.getName()); /** * The wrapped instance. */ private RemoteXAResource remoteResource; /** * Wrap a {@link RemoteAnswer} to make it into an {@link org.mulgara.query.Answer}. * * @param remoteResource the instance to wrap * @throws IllegalArgumentException if <var>remoteAnswer</var> is <code>null</code> */ RemoteXAResourceWrapperXAResource(RemoteXAResource remoteResource) throws RemoteException { if (remoteResource == null) { throw new IllegalArgumentException("Null 'remoteResource' parameter"); } this.remoteResource = remoteResource; } // // Methods implementing XAResource // public void commit(Xid xid, boolean onePhase) throws XAException { try { remoteResource.commit(convertXid(xid), onePhase); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public void end(Xid xid, int flags) throws XAException { try { remoteResource.end(convertXid(xid), flags); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public void forget(Xid xid) throws XAException { try { remoteResource.forget(convertXid(xid)); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public int getTransactionTimeout() throws XAException { try { return remoteResource.getTransactionTimeout(); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public boolean isSameRM(XAResource xares) throws XAException { try { if (xares == this) { return true; } else if (xares instanceof ResourceManagerInstanceAdaptor) { try { return ((ResourceManagerInstanceAdaptor)xares).getRMId().equals(remoteResource.getRMId()); } catch (UnsupportedOperationException eu) { logger.debug("getRMId() unsupported on XAResource", eu); return false; } } else { return false; } } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public Serializable getRMId() { try { return remoteResource.getRMId(); } catch (RemoteException er) { throw new UnsupportedOperationException("Failed to obtain RMid", er); } } public int prepare(Xid xid) throws XAException { try { return remoteResource.prepare(convertXid(xid)); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public Xid[] recover(int flag) throws XAException { try { return remoteResource.recover(flag); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public void rollback(Xid xid) throws XAException { try { remoteResource.rollback(convertXid(xid)); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public boolean setTransactionTimeout(int seconds) throws XAException { try { return remoteResource.setTransactionTimeout(seconds); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } public void start(Xid xid, int flags) throws XAException { try { remoteResource.start(convertXid(xid), flags); } catch (RemoteException re) { logger.warn("RMI Error in XAResource", re); throw new XAException(XAException.XAER_RMFAIL); } } private SerializableXid convertXid(Xid xid) { return new SerializableXid(xid); } private static class SerializableXid implements Xid, Serializable { /** Generated UID */ private static final long serialVersionUID = 2421196761757350942L; private byte[] bq; private int fi; private byte[] gtid; public SerializableXid(Xid xid) { byte[] tbq = xid.getBranchQualifier(); byte[] tgtid = xid.getGlobalTransactionId(); this.bq = new byte[tbq.length]; this.fi = xid.getFormatId(); this.gtid = new byte[tgtid.length]; System.arraycopy(tbq, 0, this.bq, 0, tbq.length); System.arraycopy(tgtid, 0, this.gtid, 0, tgtid.length); } public byte[] getBranchQualifier() { return bq; } public int getFormatId() { return fi; } public byte[] getGlobalTransactionId() { return gtid; } } }