001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.activemq.ra;
018    
019    import javax.jms.JMSException;
020    import javax.transaction.xa.XAException;
021    import javax.transaction.xa.XAResource;
022    import javax.transaction.xa.Xid;
023    
024    import org.apache.activemq.TransactionContext;
025    import org.apache.activemq.command.TransactionId;
026    import org.apache.activemq.transaction.Synchronization;
027    
028    /**
029     * Allows us to switch between using a shared transaction context, or using a
030     * local transaction context.
031     * 
032     * 
033     */
034    public class ManagedTransactionContext extends TransactionContext {
035    
036        private final TransactionContext sharedContext;
037        private boolean useSharedTxContext;
038    
039        public ManagedTransactionContext(TransactionContext sharedContext) {
040            super(sharedContext.getConnection());
041            this.sharedContext = sharedContext;
042            setLocalTransactionEventListener(sharedContext.getLocalTransactionEventListener());
043        }
044    
045        public void setUseSharedTxContext(boolean enable) throws JMSException {
046            if (isInLocalTransaction() || isInXATransaction()) {
047                throw new JMSException("The resource is already being used in transaction context.");
048            }
049            useSharedTxContext = enable;
050        }
051    
052        public void begin() throws JMSException {
053            if (useSharedTxContext) {
054                sharedContext.begin();
055            } else {
056                super.begin();
057            }
058        }
059    
060        public void commit() throws JMSException {
061            if (useSharedTxContext) {
062                sharedContext.commit();
063            } else {
064                super.commit();
065            }
066        }
067    
068        public void commit(Xid xid, boolean onePhase) throws XAException {
069            if (useSharedTxContext) {
070                sharedContext.commit(xid, onePhase);
071            } else {
072                super.commit(xid, onePhase);
073            }
074        }
075    
076        public void end(Xid xid, int flags) throws XAException {
077            if (useSharedTxContext) {
078                sharedContext.end(xid, flags);
079            } else {
080                super.end(xid, flags);
081            }
082        }
083    
084        public void forget(Xid xid) throws XAException {
085            if (useSharedTxContext) {
086                sharedContext.forget(xid);
087            } else {
088                super.forget(xid);
089            }
090        }
091    
092        public TransactionId getTransactionId() {
093            if (useSharedTxContext) {
094                return sharedContext.getTransactionId();
095            } else {
096                return super.getTransactionId();
097            }
098        }
099    
100        public int getTransactionTimeout() throws XAException {
101            if (useSharedTxContext) {
102                return sharedContext.getTransactionTimeout();
103            } else {
104                return super.getTransactionTimeout();
105            }
106        }
107    
108        public boolean isInLocalTransaction() {
109            if (useSharedTxContext) {
110                return sharedContext.isInLocalTransaction();
111            } else {
112                return super.isInLocalTransaction();
113            }
114        }
115    
116        public boolean isInXATransaction() {
117            if (useSharedTxContext) {
118                // context considers endesd XA transactions as active, so just check for presence
119                // of tx when it is shared
120                return sharedContext.isInTransaction();
121            } else {
122                return super.isInXATransaction();
123            }
124        }
125    
126        @Override
127        public boolean isInTransaction() {
128            return isInXATransaction() || isInLocalTransaction();
129        }
130     
131        public boolean isSameRM(XAResource xaResource) throws XAException {
132            if (useSharedTxContext) {
133                return sharedContext.isSameRM(xaResource);
134            } else {
135                return super.isSameRM(xaResource);
136            }
137        }
138    
139        public int prepare(Xid xid) throws XAException {
140            if (useSharedTxContext) {
141                return sharedContext.prepare(xid);
142            } else {
143                return super.prepare(xid);
144            }
145        }
146    
147        public Xid[] recover(int flag) throws XAException {
148            if (useSharedTxContext) {
149                return sharedContext.recover(flag);
150            } else {
151                return super.recover(flag);
152            }
153        }
154    
155        public void rollback() throws JMSException {
156            if (useSharedTxContext) {
157                sharedContext.rollback();
158            } else {
159                super.rollback();
160            }
161        }
162    
163        public void rollback(Xid xid) throws XAException {
164            if (useSharedTxContext) {
165                sharedContext.rollback(xid);
166            } else {
167                super.rollback(xid);
168            }
169        }
170    
171        public boolean setTransactionTimeout(int seconds) throws XAException {
172            if (useSharedTxContext) {
173                return sharedContext.setTransactionTimeout(seconds);
174            } else {
175                return super.setTransactionTimeout(seconds);
176            }
177        }
178    
179        public void start(Xid xid, int flags) throws XAException {
180            if (useSharedTxContext) {
181                sharedContext.start(xid, flags);
182            } else {
183                super.start(xid, flags);
184            }
185        }
186    
187        public void addSynchronization(Synchronization s) {
188            if (useSharedTxContext) {
189                sharedContext.addSynchronization(s);
190            } else {
191                super.addSynchronization(s);
192            }
193        }
194    }