001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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 */
016package org.springframework.transaction.jta;
017
018import javax.naming.NamingException;
019import javax.transaction.SystemException;
020
021import org.objectweb.jotm.Current;
022import org.objectweb.jotm.Jotm;
023
024import org.springframework.beans.factory.DisposableBean;
025import org.springframework.beans.factory.FactoryBean;
026
027/**
028 * {@link FactoryBean} that retrieves the JTA UserTransaction/TransactionManager
029 * for ObjectWeb's <a href="http://jotm.objectweb.org">JOTM</a>. Will retrieve
030 * an already active JOTM instance if found (e.g. if running in JOnAS),
031 * else create a new local JOTM instance.
032 *
033 * <p>With JOTM, the same object implements both the
034 * {@link javax.transaction.UserTransaction} and the
035 * {@link javax.transaction.TransactionManager} interface,
036 * as returned by this FactoryBean.
037 *
038 * <p>A local JOTM instance is well-suited for working in conjunction with
039 * ObjectWeb's <a href="http://xapool.experlog.com">XAPool</a>, e.g. with bean
040 * definitions like the following:
041 *
042 * <pre class="code">
043 * &lt;bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/&gt;
044 *
045 * &lt;bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
046 *   &lt;property name="userTransaction" ref="jotm"/&gt;
047 * &lt;/bean&gt;
048 *
049 * &lt;bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
050 *   &lt;property name="transactionManager" ref="jotm"/&gt;
051 *   &lt;property name="driverName" value="..."/&gt;
052 *   &lt;property name="url" value="..."/&gt;
053 *   &lt;property name="user" value="..."/&gt;
054 *   &lt;property name="password" value="..."/&gt;
055 * &lt;/bean&gt;
056 *
057 * &lt;bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
058 *   &lt;property name="dataSource" ref="innerDataSource"/&gt;
059 *   &lt;property name="user" value="..."/&gt;
060 *   &lt;property name="password" value="..."/&gt;
061 *   &lt;property name="maxSize" value="..."/&gt;
062 * &lt;/bean&gt;</pre>
063 *
064 * Note that Spring's {@link JtaTransactionManager} will automatically detect
065 * that the passed-in UserTransaction reference also implements the
066 * TransactionManager interface. Hence, it is not necessary to specify a
067 * separate reference for JtaTransactionManager's "transactionManager" property.
068 *
069 * <p>Implementation note: This FactoryBean uses JOTM's static access method
070 * to obtain the JOTM {@link org.objectweb.jotm.Current} object, which
071 * implements both the UserTransaction and the TransactionManager interface,
072 * as mentioned above.
073 *
074 * @author Juergen Hoeller
075 * @since 21.01.2004
076 * @see JtaTransactionManager#setUserTransaction
077 * @see JtaTransactionManager#setTransactionManager
078 * @see org.objectweb.jotm.Current
079 */
080public class JotmFactoryBean implements FactoryBean, DisposableBean {
081
082        private Current jotmCurrent;
083
084        private Jotm jotm;
085
086
087        public JotmFactoryBean() throws NamingException {
088                // Check for already active JOTM instance.
089                this.jotmCurrent = Current.getCurrent();
090
091                // If none found, create new local JOTM instance.
092                if (this.jotmCurrent == null) {
093                        // Only for use within the current Spring context:
094                        // local, not bound to registry.
095                        this.jotm = new Jotm(true, false);
096                        this.jotmCurrent = Current.getCurrent();
097                }
098        }
099
100        /**
101         * Set the default transaction timeout for the JOTM instance.
102         * <p>Should only be called for a local JOTM instance,
103         * not when accessing an existing (shared) JOTM instance.
104         */
105        public void setDefaultTimeout(int defaultTimeout) {
106                this.jotmCurrent.setDefaultTimeout(defaultTimeout);
107                // The following is a JOTM oddity: should be used for demarcation transaction only,
108                // but is required here in order to actually get rid of JOTM's default (60 seconds).
109                try {
110                        this.jotmCurrent.setTransactionTimeout(defaultTimeout);
111                }
112                catch (SystemException ex) {
113                        // should never happen
114                }
115        }
116
117
118        /**
119         * Return the JOTM instance created by this factory bean, if any.
120         * Will be <code>null</code> if an already active JOTM instance is used.
121         * <p>Application code should never need to access this.
122         */
123        public Jotm getJotm() {
124                return this.jotm;
125        }
126
127        public Object getObject() {
128                return this.jotmCurrent;
129        }
130
131        public Class getObjectType() {
132                return this.jotmCurrent.getClass();
133        }
134
135        public boolean isSingleton() {
136                return true;
137        }
138
139
140        /**
141         * Stop the local JOTM instance, if created by this FactoryBean.
142         */
143        public void destroy() {
144                if (this.jotm != null) {
145                        this.jotm.stop();
146                }
147        }
148
149}