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 }