Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/JtaTransaction.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/JtaTransaction.java (revision 6408) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/tx/JtaTransaction.java (working copy) @@ -34,11 +34,12 @@ /** * @author Tom Baeyens + * @author Huisheng Xu */ public class JtaTransaction extends AbstractTransaction implements Transaction { - + private static Log log = Log.getLog(JtaTransaction.class.getName()); - + public static final String JNDINAME_USERTRANSACTION_JBOSS_GLOBAL = "UserTransaction"; public static final String JNDINAME_TRANSACTIONMANAGER_JBOSS_GLOBAL = "java:/TransactionManager"; @@ -68,7 +69,7 @@ throw new JbpmException("couldn't register synchronization: "+e.getMessage(), e); } } - + public void begin() { try { lookupJeeUserTransaction().begin(); @@ -76,7 +77,7 @@ throw new JbpmException("couldn't begin transaction: "+e.getMessage(), e); } } - + public void rollback() { try { lookupJeeUserTransaction().rollback(); @@ -84,7 +85,7 @@ throw new JbpmException("couldn't rollback: "+e.getMessage(), e); } } - + public void commit() { try { flushDeserializedObjects(); @@ -94,7 +95,7 @@ throw new JbpmException("couldn't commit: "+e.getMessage(), e); } } - + public javax.transaction.Transaction suspend() { try { return lookupJeeTransactionManager().suspend(); @@ -102,7 +103,7 @@ throw new JbpmException("couldn't suspend: "+e.getMessage(), e); } } - + public void resume(javax.transaction.Transaction transaction) { try { lookupJeeTransactionManager().resume(transaction); @@ -110,9 +111,9 @@ throw new JbpmException("couldn't resume: "+e.getMessage(), e); } } - + // lookups ////////////////////////////////////////////////////////////////// - + public UserTransaction lookupJeeUserTransaction() { return (UserTransaction) lookupFromJndi(userTransactionJndiName); } @@ -129,7 +130,7 @@ public TransactionManager lookupJeeTransactionManager() { return (TransactionManager) lookupFromJndi(transactionManagerJndiName); } - + public static Object lookupFromJndi(String jndiName) { try { InitialContext initialContext = new InitialContext(); @@ -138,7 +139,7 @@ throw new JbpmException("couldn't lookup '"+jndiName+"' from jndi: "+e.getMessage()+": "+e.getMessage(), e); } } - + public static int getUserTransactionStatus(UserTransaction userTransaction) { int status = -1; try { @@ -149,4 +150,12 @@ log.trace("jta transaction status: "+JtaStatusHelper.toString(status)); return status; } + + public String getUserTransactionJndiName() { + return userTransactionJndiName; + } + + public String getTransactionManagerJndiName() { + return transactionManagerJndiName; + } } Index: modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/TransactionBinding.java =================================================================== --- modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/TransactionBinding.java (revision 6408) +++ modules/pvm/src/main/java/org/jbpm/pvm/internal/wire/binding/TransactionBinding.java (working copy) @@ -21,23 +21,32 @@ */ package org.jbpm.pvm.internal.wire.binding; +import org.jbpm.internal.log.Log; +import org.jbpm.pvm.internal.env.EnvironmentImpl; import org.jbpm.pvm.internal.tx.JtaTransaction; import org.jbpm.pvm.internal.tx.SpringTransaction; import org.jbpm.pvm.internal.tx.StandardTransaction; import org.jbpm.pvm.internal.tx.Transaction; import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor; +import org.jbpm.pvm.internal.wire.descriptor.StringDescriptor; +import org.jbpm.pvm.internal.wire.operation.FieldOperation; import org.jbpm.pvm.internal.xml.Parse; import org.jbpm.pvm.internal.xml.Parser; +import org.hibernate.cfg.Configuration; import org.w3c.dom.Element; + /** parses a descriptor for creating a {@link Transaction}. - * + * * See schema docs for more details. * * @author Tom Baeyens + * @author Huisheng Xu */ public class TransactionBinding extends WireDescriptorBinding { + private static Log log = Log.getLog(TransactionBinding.class.getName()); + public TransactionBinding() { super("transaction"); } @@ -49,17 +58,92 @@ if (element.hasAttribute("type")) { type = element.getAttribute("type"); } - + if ("standard".equals(type)) { transactionDescriptor = new ObjectDescriptor(StandardTransaction.class); } else if ("jta".equals(type)){ transactionDescriptor = new ObjectDescriptor(JtaTransaction.class); + + this.autoDetectOrParseAttribute(transactionDescriptor, element); } else if ("spring".equals(type)){ transactionDescriptor = new ObjectDescriptor(SpringTransaction.class); } else { parse.addProblem("unsupported transaction type: "+type, element); } - + return transactionDescriptor; } + + protected void autoDetectOrParseAttribute(ObjectDescriptor transactionDescriptor, Element element) { + if (element.hasAttribute("user-transaction")) { + String userTransactionValue = element.getAttribute("user-transaction"); + + if (log.isDebugEnabled()) { + log.debug("get user-transaction from xml: [" + userTransactionValue + "]"); + } + + this.parseFieldOperation(transactionDescriptor, element, + "userTransactionJndiName", userTransactionValue); + } else { + String userTransactionValue = this.autoDetectHibernateConfiguration("jta.UserTransaction"); + + if (userTransactionValue != null) { + if (log.isDebugEnabled()) { + log.debug("get user-transaction from hibernate configuration: [" + userTransactionValue + "]"); + } + + this.parseFieldOperation(transactionDescriptor, element, + "userTransactionJndiName", userTransactionValue); + } else { + if (log.isDebugEnabled()) { + log.debug("use default user-transaction: [" + + JtaTransaction.JNDINAME_USERTRANSACTION_JBOSS_GLOBAL + "]"); + } + } + } + + if (element.hasAttribute("transaction-manager")) { + String transactionManagerValue = element.getAttribute("transaction-manager"); + + if (log.isDebugEnabled()) { + log.debug("get transaction-manager from xml: [" + transactionManagerValue + "]"); + } + + this.parseFieldOperation(transactionDescriptor, element, + "transactionManagerJndiName", transactionManagerValue); + } else { + String transactionManagerValue = + this.autoDetectHibernateConfiguration("hibernate.transaction.manager_lookup_class"); + + if (log.isDebugEnabled()) { + log.debug("get transaction-manager from hibernate configuration: [" + transactionManagerValue + "]"); + } + + if (transactionManagerValue != null) { + this.parseFieldOperation(transactionDescriptor, element, + "transactionManagerJndiName", transactionManagerValue); + } else { + if (log.isDebugEnabled()) { + log.debug("use default transaction-manager: [" + + JtaTransaction.JNDINAME_TRANSACTIONMANAGER_JBOSS_GLOBAL + "]"); + } + } + } + } + + protected void parseFieldOperation(ObjectDescriptor objectDescriptor, + Element element, String fieldName, String fieldValue) { + FieldOperation fieldOperation = new FieldOperation(); + fieldOperation.setFieldName(fieldName); + fieldOperation.setDescriptor(new StringDescriptor(fieldValue)); + objectDescriptor.addOperation(fieldOperation); + } + + protected String autoDetectHibernateConfiguration(String propertyName) { + Configuration cfg = EnvironmentImpl.getFromCurrent(Configuration.class, false); + if (cfg == null) { + return null; + } + return cfg.getProperty(propertyName); + } } Index: modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/binding/TransactionBindingTest.java =================================================================== --- modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/binding/TransactionBindingTest.java (revision 0) +++ modules/pvm/src/test/java/org/jbpm/pvm/internal/wire/binding/TransactionBindingTest.java (revision 0) @@ -0,0 +1,81 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jbpm.pvm.internal.wire.binding; + +import java.util.List; +import org.jbpm.test.BaseJbpmTestCase; +import org.jbpm.pvm.internal.tx.JtaTransaction; +import org.jbpm.pvm.internal.xml.Parser; +import org.jbpm.pvm.internal.xml.Bindings; +import org.jbpm.pvm.internal.xml.Problem; +import org.jbpm.pvm.internal.wire.WireContext; +import org.jbpm.pvm.internal.wire.descriptor.ObjectDescriptor; + + +/** + * @author Huisheng Xu + */ +public class TransactionBindingTest extends BaseJbpmTestCase { + public void testDefaultJndiName() { + Parser parser = new Parser(); + Bindings bindings = new Bindings(); + parser.setBindings(bindings); + parser.getBindings().addBinding(new TransactionBinding()); + + // jndi for jboss + String xml = ""; + + ObjectDescriptor objectDescriptor = (ObjectDescriptor) parser + .createParse() + .setString(xml) + .execute() + .getDocumentObject(); + + JtaTransaction jtaTransaction = (JtaTransaction) WireContext.create(objectDescriptor); + + assertEquals("UserTransaction", jtaTransaction.getUserTransactionJndiName()); + assertEquals("java:/TransactionManager", jtaTransaction.getTransactionManagerJndiName()); + } + + public void testCustomJndiName() { + Parser parser = new Parser(); + Bindings bindings = new Bindings(); + parser.setBindings(bindings); + parser.getBindings().addBinding(new TransactionBinding()); + + // jndi for jotm on tomcat + String xml = ""; + + ObjectDescriptor objectDescriptor = (ObjectDescriptor) parser + .createParse() + .setString(xml) + .execute() + .getDocumentObject(); + + JtaTransaction jtaTransaction = (JtaTransaction) WireContext.create(objectDescriptor); + + assertEquals("java:comp/UserTransaction", jtaTransaction.getUserTransactionJndiName()); + assertEquals("java:comp/UserTransaction", jtaTransaction.getTransactionManagerJndiName()); + } +}