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.springframework.transaction.jta;
018:
019: import java.lang.reflect.InvocationTargetException;
020: import java.lang.reflect.Method;
021:
022: import javax.transaction.TransactionManager;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import org.springframework.beans.factory.FactoryBean;
028: import org.springframework.transaction.TransactionSystemException;
029:
030: /**
031: * FactoryBean that retrieves the JTA TransactionManager for IBM's
032: * WebSphere application servers (versions 6, 5.1, 5.0 and 4).
033: *
034: * <p>Uses WebSphere's static access methods to obtain the JTA TransactionManager,
035: * which is different for WebSphere 5.1+, 5.0 and 4.
036: *
037: * <p>In combination with Spring's JtaTransactionManager, this FactoryBean
038: * can be used to enable transaction suspension (PROPAGATION_REQUIRES_NEW,
039: * PROPAGATION_NOT_SUPPORTED) on WebSphere:
040: *
041: * <pre>
042: * <bean id="wsJtaTm" class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean"/>
043: *
044: * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
045: * <property name="transactionManager ref="wsJtaTm"/>
046: * </bean></pre>
047: *
048: * Note that Spring's JtaTransactionManager will continue to use the JTA
049: * UserTransaction for standard transaction demarcation, as defined by
050: * standard J2EE. It will only use the provided WebSphere TransactionManager
051: * in case of actual transaction suspension needs.
052: *
053: * @author Juergen Hoeller
054: * @since 21.01.2004
055: * @see JtaTransactionManager#setTransactionManager
056: * @see com.ibm.ws.Transaction.TransactionManagerFactory#getTransactionManager
057: * @see com.ibm.ejs.jts.jta.JTSXA#getTransactionManager
058: * @see com.ibm.ejs.jts.jta.TransactionManagerFactory#getTransactionManager
059: */
060: public class WebSphereTransactionManagerFactoryBean implements
061: FactoryBean {
062:
063: private static final String FACTORY_CLASS_5_1 = "com.ibm.ws.Transaction.TransactionManagerFactory";
064:
065: private static final String FACTORY_CLASS_5_0 = "com.ibm.ejs.jts.jta.TransactionManagerFactory";
066:
067: private static final String FACTORY_CLASS_4 = "com.ibm.ejs.jts.jta.JTSXA";
068:
069: protected final Log logger = LogFactory.getLog(getClass());
070:
071: private final TransactionManager transactionManager;
072:
073: /**
074: * This constructor retrieves the WebSphere TransactionManager factory class,
075: * so we can get access to the JTA TransactionManager.
076: */
077: public WebSphereTransactionManagerFactoryBean()
078: throws TransactionSystemException {
079: Class clazz;
080: try {
081: logger.debug("Trying WebSphere 5.1+: " + FACTORY_CLASS_5_1);
082: clazz = Class.forName(FACTORY_CLASS_5_1);
083: logger.info("Found WebSphere 5.1+: " + FACTORY_CLASS_5_1);
084: } catch (ClassNotFoundException ex) {
085: logger
086: .debug(
087: "Could not find WebSphere 5.1/6.0 TransactionManager factory class",
088: ex);
089: try {
090: logger.debug("Trying WebSphere 5.0: "
091: + FACTORY_CLASS_5_0);
092: clazz = Class.forName(FACTORY_CLASS_5_0);
093: logger
094: .info("Found WebSphere 5.0: "
095: + FACTORY_CLASS_5_0);
096: } catch (ClassNotFoundException ex2) {
097: logger
098: .debug(
099: "Could not find WebSphere 5.0 TransactionManager factory class",
100: ex2);
101: try {
102: logger.debug("Trying WebSphere 4: "
103: + FACTORY_CLASS_4);
104: clazz = Class.forName(FACTORY_CLASS_4);
105: logger
106: .info("Found WebSphere 4: "
107: + FACTORY_CLASS_4);
108: } catch (ClassNotFoundException ex3) {
109: logger
110: .debug(
111: "Could not find WebSphere 4 TransactionManager factory class",
112: ex3);
113: throw new TransactionSystemException(
114: "Could not find any WebSphere TransactionManager factory class, "
115: + "neither for WebSphere version 5.1+ nor 5.0 nor 4");
116: }
117: }
118: }
119:
120: try {
121: Method method = clazz.getMethod("getTransactionManager",
122: (Class[]) null);
123: this .transactionManager = (TransactionManager) method
124: .invoke(null, (Object[]) null);
125: } catch (InvocationTargetException ex) {
126: throw new TransactionSystemException(
127: "WebSphere's TransactionManagerFactory.getTransactionManager method failed",
128: ex.getTargetException());
129: } catch (Exception ex) {
130: throw new TransactionSystemException(
131: "Could not access WebSphere's TransactionManagerFactory.getTransactionManager method",
132: ex);
133: }
134: }
135:
136: public Object getObject() {
137: return this .transactionManager;
138: }
139:
140: public Class getObjectType() {
141: return this .transactionManager.getClass();
142: }
143:
144: public boolean isSingleton() {
145: return true;
146: }
147:
148: }
|