/* * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: * Florent Guillaume */ package org.nuxeo.ecm.core.storage.sql.jdbc; import static javax.transaction.xa.XAException.XAER_INVAL; import static javax.transaction.xa.XAException.XAER_PROTO; import static javax.transaction.xa.XAException.XAER_RMERR; import java.sql.SQLException; import javax.transaction.xa.XAException; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Adapter for a simple JDBC Connection that gives it the XAResource interface, without actually implementing XA * (prepare does nothing). * * @since 5.7 */ public class XAResourceConnectionAdapter implements XAResource { private static final Log log = LogFactory.getLog(XAResourceConnectionAdapter.class); protected JDBCConnection owner; protected Xid xid; public XAResourceConnectionAdapter(JDBCConnection connection) { owner = connection; } @Override public void start(Xid xid, int flag) throws XAException { if (flag == TMNOFLAGS) { if (this.xid != null) { throw newXAException(XAER_PROTO, "Already started"); } this.xid = xid; } else { // cannot support resume throw newXAException(XAER_INVAL, "Invalid flag: " + flag); } } @Override public void end(Xid xid, int flag) throws XAException { if (xid != this.xid) { throw newXAException(XAER_INVAL, "Invalid Xid"); } if (flag != TMSUCCESS && flag != TMFAIL) { throw newXAException(XAER_INVAL, "Invalid flag: " + flag); } } @Override public int prepare(Xid xid) throws XAException { return XA_OK; } @Override public void commit(Xid xid, boolean flag) throws XAException { if (this.xid == null || !this.xid.equals(xid)) { throw newXAException(XAER_INVAL, "Invalid Xid"); } this.xid = null; try { owner.connection.commit(); } catch (SQLException e) { throw newXAException(XAER_RMERR, "Cannot commit", e); } } @Override public void rollback(Xid xid) throws XAException { if (this.xid == null || !this.xid.equals(xid)) { throw newXAException(XAER_INVAL, "Invalid Xid"); } this.xid = null; try { owner.connection.rollback(); } catch (SQLException e) { throw newXAException(XAER_RMERR, "Cannot rollback", e); } } @Override public void forget(Xid xid) throws XAException { throw newXAException(XAER_PROTO, "Unsupported method"); } @Override public Xid[] recover(int n) throws XAException { return new Xid[0]; } @Override public int getTransactionTimeout() throws XAException { return 0; } @Override public boolean setTransactionTimeout(int txTimeout) throws XAException { return false; } @Override public boolean isSameRM(XAResource xares) throws XAException { return this == xares; } protected static XAException newXAException(int errorCode, String message, Exception cause) { return (XAException) newXAException(errorCode, message).initCause(cause); } protected static XAException newXAException(int errorCode, String message) { XAException e = new XAException(message); e.errorCode = errorCode; return e; } }