001    package org.apache.ojb.otm.transaction;
002    
003    /* Copyright 2003-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.HashMap;
019    
020    import javax.transaction.SystemException;
021    import javax.transaction.TransactionManager;
022    
023    import org.apache.ojb.broker.PBKey;
024    import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryFactory;
025    import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryException;
026    import org.apache.ojb.otm.OTMConnection;
027    import org.apache.ojb.otm.core.BaseConnection;
028    import org.apache.ojb.otm.core.Transaction;
029    import org.apache.ojb.otm.core.TransactionException;
030    
031    /**
032     * Factory for OTM Transactions within a managed environment (JTA).
033     *
034     * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
035     *
036     */
037    public abstract class ManagedTransactionFactory implements TransactionFactory
038    {
039    
040        private HashMap _transactionMap;
041        private TransactionManager tm;
042    
043            /**
044             * Constructor for ManagedTransactionFactory.
045             */
046            public ManagedTransactionFactory()
047            {
048                    _transactionMap = new HashMap();
049            }
050    
051    
052        //////////////////////////////////////////////////////
053        // TransactionFactory protocol
054        //////////////////////////////////////////////////////
055    
056            /**
057             * @see org.apache.ojb.otm.transaction.TransactionFactory#getTransactionForConnection(OTMConnection)
058             */
059            public Transaction getTransactionForConnection(OTMConnection connection)
060            {
061            if (!(connection instanceof BaseConnection))
062            {
063                throw new TransactionFactoryException("Unknown connection type");
064            }
065            BaseConnection baseConnection = (BaseConnection) connection;
066    
067                    javax.transaction.Transaction jtaTx = getJTATransaction();
068            if (jtaTx == null)
069            {
070                throw new TransactionFactoryException("Unable to get the JTA Transaction");
071            }
072    
073            Transaction tx = (Transaction) _transactionMap.get(jtaTx);
074            if (tx == null)
075            {
076                tx = new Transaction();
077                _transactionMap.put(jtaTx, tx);
078            }
079    
080            // ensure that this connection is registered into this transaction
081            tx.registerConnection(baseConnection);
082            return tx;
083            }
084    
085        /**
086         * @see org.apache.ojb.otm.transaction.TransactionFactory#acquireConnection
087         */
088        public OTMConnection acquireConnection(PBKey pbKey)
089        {
090            return new ManagedConnection(pbKey);
091        }
092    
093    
094        //////////////////////////////////////////
095        // Other operations
096        //////////////////////////////////////////
097    
098        public javax.transaction.Transaction getJTATransaction()
099        {
100            if(tm == null)
101            {
102                try
103                {
104                    tm = TransactionManagerFactoryFactory.instance().getTransactionManager();
105                }
106                catch (TransactionManagerFactoryException e)
107                {
108                    throw new TransactionFactoryException("Can't instantiate TransactionManagerFactory", e);
109                }
110            }
111            try
112            {
113                return tm.getTransaction();
114            }
115            catch(SystemException e)
116            {
117                throw new TransactionFactoryException("Error acquiring JTA Transaction", e);
118            }
119        }
120    
121        private static class ManagedConnection extends BaseConnection
122        {
123    
124            public ManagedConnection (PBKey pbKey)
125            {
126                super(pbKey);
127            }
128    
129            /**
130             * @see org.apache.ojb.otm.core.BaseConnection#transactionBegin()
131             */
132            public void transactionBegin() throws TransactionException
133            {
134                // Nothing to do!
135            }
136    
137            /**
138             * @see org.apache.ojb.otm.core.BaseConnection#transactionPrepare()
139             */
140            public void transactionPrepare() throws TransactionException
141            {
142                // Nothing to do, since all resources are managed by JTS and will be committed
143                // directly.
144            }
145    
146            /**
147             * @see org.apache.ojb.otm.core.BaseConnection#transactionCommit()
148             */
149            public void transactionCommit() throws TransactionException
150            {
151                // Nothing to do, since all resources are managed by JTS and will be committed
152                // directly.
153            }
154    
155            /**
156             * @see org.apache.ojb.otm.core.BaseConnection#transactionRollback()
157             */
158            public void transactionRollback() throws TransactionException
159            {
160                // Nothing to do, since all resources are managed by JTS and will be rolled back
161                // directly.
162            }
163    
164        }
165    }