001    /**
002     * 
003     * Copyright 2004 Hiram Chirino
004     * Copyright 2004 Protique Ltd
005     * 
006     * Licensed under the Apache License, Version 2.0 (the "License"); 
007     * you may not use this file except in compliance with the License. 
008     * You may obtain a copy of the License at 
009     * 
010     * http://www.apache.org/licenses/LICENSE-2.0
011     * 
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS, 
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
015     * See the License for the specific language governing permissions and 
016     * limitations under the License. 
017     * 
018     **/
019    package org.activemq.store.jdbc;
020    
021    import java.sql.Connection;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    
026    /**
027     * Helps keep track of the current transaction/JDBC connection.
028     *
029     * @version $Revision: 1.1 $
030     */
031    public class TransactionContext {
032        private static final Log log = LogFactory.getLog(TransactionContext.class);
033        private static ThreadLocal threadLocalTxn = new ThreadLocal();
034        
035        /**
036         * Pops off the current Connection from the stack
037         */
038        public static Connection popConnection() {
039            Connection[] tx = (Connection[]) threadLocalTxn.get();
040            if (tx == null || tx[0]==null) {
041                log.warn("Attempt to pop connection when no transaction in progress");
042                return null;
043            }
044            else {
045                    Connection answer = tx[0];
046                    tx[0]=null;
047                    return answer;
048            }
049        }
050    
051        /**
052         * Sets the current transaction, possibly including nesting
053         */
054        public static void pushConnection(Connection connection) {
055            Connection[] tx = (Connection[]) threadLocalTxn.get();
056            if (tx == null) {
057                tx = new Connection[]{null};
058                threadLocalTxn.set(tx);
059            }
060            if (tx[0] != null) {
061                throw new IllegalStateException("A transaction is allready in progress");
062            }
063            tx[0] = connection;
064        }
065    
066        /**
067         * @return the current thread local connection that is associated
068         *  with the JMS transaction or null if there is no 
069         *  transaction in progress.
070         */
071        public static Connection peekConnection() {
072            Connection tx[] = (Connection[]) threadLocalTxn.get();
073            if (tx != null && tx[0]!=null ) {
074                return tx[0];
075            }
076            return null;
077        }
078    
079    }