001: /*
002: * Copyright 2002-2006 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.springframework.transaction.jta;
018:
019: import javax.naming.NamingException;
020:
021: import org.objectweb.jotm.Current;
022: import org.objectweb.jotm.Jotm;
023:
024: import org.springframework.beans.factory.DisposableBean;
025: import org.springframework.beans.factory.FactoryBean;
026:
027: /**
028: * FactoryBean that retrieves the JTA UserTransaction/TransactionManager for
029: * 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: * <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
044: *
045: * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
046: * <property name="userTransaction" ref="jotm"/>
047: * </bean>
048: *
049: * <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
050: * <property name="transactionManager" ref="jotm"/>
051: * <property name="driverName" value="..."/>
052: * <property name="url" value="..."/>
053: * <property name="user" value="..."/>
054: * <property name="password" value="..."/>
055: * </bean>
056: *
057: * <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
058: * <property name="dataSource" ref="innerDataSource"/>
059: * <property name="user" value="..."/>
060: * <property name="password" value="..."/>
061: * <property name="maxSize" value="..."/>
062: * </bean></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: */
080: public class JotmFactoryBean implements FactoryBean, DisposableBean {
081:
082: private Current jotmCurrent;
083:
084: private Jotm jotm;
085:
086: public JotmFactoryBean() throws NamingException {
087: // Check for already active JOTM instance.
088: this .jotmCurrent = Current.getCurrent();
089:
090: // If none found, create new local JOTM instance.
091: if (this .jotmCurrent == null) {
092: // Only for use within the current Spring context:
093: // local, not bound to registry.
094: this .jotm = new Jotm(true, false);
095: this .jotmCurrent = Current.getCurrent();
096: }
097: }
098:
099: /**
100: * Set the default transaction timeout for the JOTM instance.
101: * <p>Should only be called for a local JOTM instance,
102: * not when accessing an existing (shared) JOTM instance.
103: */
104: public void setDefaultTimeout(int defaultTimeout) {
105: this .jotmCurrent.setDefaultTimeout(defaultTimeout);
106: }
107:
108: /**
109: * Return the JOTM instance created by this factory bean, if any.
110: * Will be <code>null</code> if an already active JOTM instance is used.
111: * <p>Application code should never need to access this.
112: */
113: public Jotm getJotm() {
114: return this .jotm;
115: }
116:
117: public Object getObject() {
118: return this .jotmCurrent;
119: }
120:
121: public Class getObjectType() {
122: return this .jotmCurrent.getClass();
123: }
124:
125: public boolean isSingleton() {
126: return true;
127: }
128:
129: /**
130: * Stop the local JOTM instance, if created by this FactoryBean.
131: */
132: public void destroy() {
133: if (this.jotm != null) {
134: this.jotm.stop();
135: }
136: }
137:
138: }
|