001    package org.apache.ojb.odmg;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
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    import java.util.Hashtable;
019    
020    import org.apache.ojb.broker.util.configuration.Configuration;
021    import org.odmg.TransactionNotInProgressException;
022    
023    /**
024     * In a non-appserver environment, without a transaction manager, we can
025     * safely associate the current ODMG transaction with the calling thread.
026     *
027     * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
028     * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
029     * @version $Id: LocalTxManager.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
030     */
031    public class LocalTxManager implements OJBTxManager
032    {
033        /**
034         * Internal table which provides mapping between threads and transactions.
035         * This is required because a Thread can join a Transaction already in
036         * progress.
037         * If the thread joins a transaction, then "getTransaction()" should return
038         * the apropriate one.  The only way we can ensure that is by keeping hold
039         * of the txTable.
040         */
041        private static TransactionTable tx_table = new TransactionTable();
042    
043        public LocalTxManager()
044        {
045    
046        }
047    
048        /**
049         * Returns the current transaction for the calling thread.
050         *
051         * @throws org.odmg.TransactionNotInProgressException
052         *          {@link org.odmg.TransactionNotInProgressException} if no transaction was found.
053         */
054        public TransactionImpl getCurrentTransaction()
055        {
056            TransactionImpl tx = tx_table.get(Thread.currentThread());
057            if(tx == null)
058            {
059                throw new TransactionNotInProgressException("Calling method needed transaction, but no transaction found for current thread :-(");
060            }
061            return tx;
062        }
063    
064        /**
065         * Returns the current transaction for the calling thread or <code>null</code>
066         * if no transaction was found.
067         */
068        public TransactionImpl getTransaction()
069        {
070            return  tx_table.get(Thread.currentThread());
071        }
072    
073        /**
074         * add the current transaction to the map key'd by the calling thread.
075         */
076        public void registerTx(TransactionImpl tx)
077        {
078            tx_table.put(Thread.currentThread(), tx);
079        }
080    
081        /**
082         * remove the current transaction from the map key'd by the calling thread.
083         */
084        public void deregisterTx(Object token)
085        {
086            tx_table.remove(Thread.currentThread());
087        }
088    
089        /**
090         * included to keep interface contract consistent.
091         */
092        public void abortExternalTx(TransactionImpl odmgTrans)
093        {
094            /**
095             * no op
096             */
097        }
098    
099        public void configure(Configuration config)
100        {
101    
102        }
103    
104    
105        //=======================================================
106        // inner class
107        //=======================================================
108        /**
109         * TransactionTable provides a mapping between the calling
110         * thread and the Transaction it is currently using.
111         * One thread can be joined with one transaction at
112         * a certain point in time. But a thread can join with
113         * different transactions subsequently.
114         * This mapping from threads to Transactions is based on ODMG.
115         *
116         * @author Thomas Mahler & David Dixon-Peugh
117         */
118        static final class TransactionTable
119        {
120            /**
121             * the internal Hashtable mapping Transactions to threads
122             */
123            private Hashtable m_table = new Hashtable();
124    
125            /**
126             * Creates new TransactionTable
127             */
128            public TransactionTable()
129            {
130            }
131    
132            /**
133             * Retreive a Transaction associated with a thread.
134             *
135             * @param key_thread The thread to lookup.
136             * @return The transaction associated with the thread.
137             */
138            public TransactionImpl get(Thread key_thread)
139            {
140                return (TransactionImpl) m_table.get(key_thread);
141            }
142    
143            /**
144             * Store the Thread/Transaction pair in the TransactionTable
145             *
146             * @param key_thread Thread that the transaction will be associated to
147             * @param value_tx   Transaction to be associated with the thread
148             */
149            public void put(Thread key_thread, TransactionImpl value_tx)
150            {
151                m_table.put(key_thread, value_tx);
152            }
153    
154            /**
155             * Remove the entry for the thread
156             *
157             * @param key_thread Thread to be removed.
158             */
159            public void remove(Thread key_thread)
160            {
161                m_table.remove(key_thread);
162            }
163        }
164    }