001    /*
002     * Copyright 2002-2005 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jencks.factory;
018    
019    import java.util.HashSet;
020    
021    import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinator;
022    import org.apache.geronimo.transaction.DefaultInstanceContext;
023    import org.apache.geronimo.transaction.context.OnlineUserTransaction;
024    import org.apache.geronimo.transaction.context.TransactionContextManager;
025    import org.apache.geronimo.transaction.context.UserTransactionImpl;
026    import org.springframework.beans.factory.FactoryBean;
027    import org.springframework.beans.factory.InitializingBean;
028    
029    import javax.resource.ResourceException;
030    import javax.transaction.HeuristicMixedException;
031    import javax.transaction.HeuristicRollbackException;
032    import javax.transaction.NotSupportedException;
033    import javax.transaction.RollbackException;
034    import javax.transaction.SystemException;
035    import javax.transaction.UserTransaction;
036    
037    /**
038     * This FactoryBean creates and configures the Geronimo implementation
039     * of the UserTransaction interface.
040     * <p/>
041     * This factory is based on the Geronimo Transaction Context Manager
042     * and Connection Tracking Coordinator.
043     *
044     * @deprecated Use GeronimoTransactionManagerFactoryBean instead
045     * @author ttemplier
046     * @see UserTransactionImpl#setUp(TransactionContextManager, org.apache.geronimo.transaction.TrackedConnectionAssociator)
047     * @see UserTransactionImpl#setOnline(boolean)
048     * @see GeronimoTransactionManagerFactoryBean
049     */
050    public class UserTransactionFactoryBean implements FactoryBean, InitializingBean {
051    
052        private TransactionContextManager transactionContextManager;
053        private ConnectionTrackingCoordinator connectionTrackingCoordinator;
054    
055        private UserTransaction userTransaction;
056    
057        public Object getObject() throws Exception {
058            return userTransaction;
059        }
060    
061        public Class getObjectType() {
062            return UserTransaction.class;
063        }
064    
065        public boolean isSingleton() {
066            return true;
067        }
068    
069        /**
070         * Set the transaction context manager to configure the user transaction.
071         */
072        public void setTransactionContextManager(TransactionContextManager manager) {
073            transactionContextManager = manager;
074        }
075    
076        /**
077         * Set the connection tracking coordinator to configure the user transaction.
078         */
079        public void setConnectionTrackingCoordinator(ConnectionTrackingCoordinator coordinator) {
080            connectionTrackingCoordinator = coordinator;
081        }
082    
083        /**
084         * This method instanciates the Geronimo user transaction implementation
085         * and sets up it with the transaction context manager used and a connection
086         * tracking coordinator.
087         *
088         * It then sets the online property to true in order that the application
089         * can used it.
090         */
091        public void afterPropertiesSet() throws Exception {
092            this.userTransaction = new GeronimoUserTransaction();
093        }
094        
095        /**
096         * This wrapper around the OnlineUserTransaction performs per-thread
097         * initialization of the geronimo transaction layer.
098         * 
099         * @author gnt
100         */
101        public class GeronimoUserTransaction implements UserTransaction {
102            
103            private OnlineUserTransaction userTransaction;
104            
105            public GeronimoUserTransaction() {
106                    this.userTransaction = new OnlineUserTransaction();
107                    this.userTransaction.setUp(transactionContextManager,
108                    connectionTrackingCoordinator);
109            }
110    
111                    public void begin() throws NotSupportedException, SystemException {
112                            ensureContext();
113                            userTransaction.begin();
114                    }
115    
116                    public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException, SecurityException, SystemException {
117                            ensureContext();
118                            userTransaction.commit();
119                    }
120    
121                    public int getStatus() throws SystemException {
122                            ensureContext();
123                            return userTransaction.getStatus();
124                    }
125    
126                    public void rollback() throws IllegalStateException, SecurityException, SystemException {
127                            ensureContext();
128                            userTransaction.rollback();
129                    }
130    
131                    public void setRollbackOnly() throws IllegalStateException, SystemException {
132                            ensureContext();
133                            userTransaction.setRollbackOnly();
134                    }
135    
136                    public void setTransactionTimeout(int arg0) throws SystemException {
137                            ensureContext();
138                            userTransaction.setTransactionTimeout(arg0);
139                    }
140    
141                    private void ensureContext() throws SystemException {
142                            if (transactionContextManager.getContext() == null) {
143                                    try {
144                                            transactionContextManager.newUnspecifiedTransactionContext();
145                                            connectionTrackingCoordinator.enter(new DefaultInstanceContext(new HashSet(), new HashSet()));
146                                    } catch (ResourceException e) {
147                                            throw (SystemException) new SystemException().initCause(e);
148                                    }
149                            }
150                    }
151        }
152    
153    
154    }