001    /**
002     *
003     * Copyright 2004 Hiram Chirino
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     * http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     *
017     **/
018    package org.activemq.ra;
019    
020    import javax.jms.JMSException;
021    import javax.resource.ResourceException;
022    import javax.resource.spi.LocalTransaction;
023    import javax.transaction.xa.XAException;
024    import javax.transaction.xa.XAResource;
025    import javax.transaction.xa.Xid;
026    
027    import org.activemq.TransactionContext;
028    
029    /**
030     * Used to provide a LocalTransaction and XAResource to a JMS session.
031     */
032    public class LocalAndXATransaction implements XAResource, LocalTransaction {
033    
034        final private TransactionContext transactionContext;
035        private boolean inManagedTx;
036        
037        public LocalAndXATransaction(TransactionContext transactionContext) {
038            this.transactionContext=transactionContext;
039        }
040    
041        public void setInManagedTx(boolean inManagedTx) throws JMSException {
042            this.inManagedTx=inManagedTx;
043        }
044    
045        public void begin() throws ResourceException {
046            try {
047                transactionContext.begin();
048                setInManagedTx(true);
049            } catch (JMSException e) {
050                throw new ResourceException("begin failed.", e);
051            }
052        }
053    
054        public void commit() throws ResourceException {
055            try {
056                transactionContext.commit();
057            } catch (JMSException e) {
058                throw new ResourceException("commit failed.", e);
059            } finally {
060                try {
061                    setInManagedTx(false);
062                } catch (JMSException e) {
063                    throw new ResourceException("commit failed.",e);
064                }            
065            }
066        }
067    
068        public void rollback() throws ResourceException {
069            try {
070                transactionContext.rollback();
071            } catch (JMSException e) {
072                throw new ResourceException("rollback failed.", e);
073            } finally {
074                try {
075                    setInManagedTx(false);
076                } catch (JMSException e) {
077                    throw new ResourceException("rollback failed.",e);
078                }            
079            }
080        }
081    
082        public void commit(Xid arg0, boolean arg1) throws XAException {
083            transactionContext.commit(arg0, arg1);
084        }
085    
086        public void end(Xid arg0, int arg1) throws XAException {
087            try {
088                transactionContext.end(arg0, arg1);
089            } finally {
090                try {
091                    setInManagedTx(false);
092                } catch (JMSException e) {
093                    throw (XAException)new XAException(XAException.XAER_PROTO).initCause(e);
094                }            
095            }
096        }
097    
098        public void forget(Xid arg0) throws XAException {
099            transactionContext.forget(arg0);
100        }
101    
102        public int getTransactionTimeout() throws XAException {
103            return transactionContext.getTransactionTimeout();
104        }
105    
106        public boolean isSameRM(XAResource xaresource) throws XAException {
107            if (xaresource == null)
108                return false;
109            // Do we have to unwrap?
110            if (xaresource instanceof LocalAndXATransaction) {
111                xaresource = ((LocalAndXATransaction)xaresource).transactionContext;
112            }
113            return transactionContext.isSameRM(xaresource);
114        }
115    
116        public int prepare(Xid arg0) throws XAException {
117            return transactionContext.prepare(arg0);
118        }
119    
120        public Xid[] recover(int arg0) throws XAException {
121            return transactionContext.recover(arg0);
122        }
123    
124        public void rollback(Xid arg0) throws XAException {
125            transactionContext.rollback(arg0);
126        }
127    
128        public boolean setTransactionTimeout(int arg0) throws XAException {
129            return transactionContext.setTransactionTimeout(arg0);
130        }
131    
132        public void start(Xid arg0, int arg1) throws XAException {
133            transactionContext.start(arg0, arg1);
134            try {
135                setInManagedTx(true);
136            } catch (JMSException e) {
137                throw (XAException)new XAException(XAException.XAER_PROTO).initCause(e);
138            }            
139        }
140    
141        public boolean isInManagedTx() {
142            return inManagedTx;
143        }
144    }