Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 7666 invoked from network); 2 Feb 2006 10:02:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 2 Feb 2006 10:02:17 -0000 Received: (qmail 39407 invoked by uid 500); 2 Feb 2006 10:02:15 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 39310 invoked by uid 500); 2 Feb 2006 10:02:14 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 39278 invoked by uid 99); 2 Feb 2006 10:02:14 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Feb 2006 02:02:14 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 02 Feb 2006 02:02:11 -0800 Received: (qmail 7384 invoked by uid 65534); 2 Feb 2006 10:01:51 -0000 Message-ID: <20060202100151.7383.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r374335 - in /geronimo/trunk/modules/spring: ./ src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/geronimo/ src/java/org/apache/geronimo/spring/ src/java/org/apache/geronimo/spring/transaction/ Date: Thu, 02 Feb 2006 10:01:50 -0000 To: scm@geronimo.apache.org From: djencks@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: djencks Date: Thu Feb 2 02:01:47 2006 New Revision: 374335 URL: http://svn.apache.org/viewcvs?rev=374335&view=rev Log: GERONIMO-1574 untested spring transaction manager wrapper around our TransactionContextManager Added: geronimo/trunk/modules/spring/ geronimo/trunk/modules/spring/LICENSE.txt geronimo/trunk/modules/spring/NOTICE.txt geronimo/trunk/modules/spring/project.xml geronimo/trunk/modules/spring/src/ geronimo/trunk/modules/spring/src/java/ geronimo/trunk/modules/spring/src/java/org/ geronimo/trunk/modules/spring/src/java/org/apache/ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/SpringTransactionManager.java Added: geronimo/trunk/modules/spring/LICENSE.txt URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/LICENSE.txt?rev=374335&view=auto ============================================================================== --- geronimo/trunk/modules/spring/LICENSE.txt (added) +++ geronimo/trunk/modules/spring/LICENSE.txt Thu Feb 2 02:01:47 2006 @@ -0,0 +1,20 @@ +The Bouncy Castle License + +Copyright (c) 2000-2005 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + Added: geronimo/trunk/modules/spring/NOTICE.txt URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/NOTICE.txt?rev=374335&view=auto ============================================================================== --- geronimo/trunk/modules/spring/NOTICE.txt (added) +++ geronimo/trunk/modules/spring/NOTICE.txt Thu Feb 2 02:01:47 2006 @@ -0,0 +1,4 @@ +"ASN1 codec suppllied by {package name} from : + + Copyright (c) 2000-2005 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + Added: geronimo/trunk/modules/spring/project.xml URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/project.xml?rev=374335&view=auto ============================================================================== --- geronimo/trunk/modules/spring/project.xml (added) +++ geronimo/trunk/modules/spring/project.xml Thu Feb 2 02:01:47 2006 @@ -0,0 +1,97 @@ + + + + + + + 3 + ../../etc/project.xml + + + + + + Geronimo :: Spring + geronimo-spring + Geronimo Spring integration + Spring wrappers for geronimo components + http://incubator.apache.org/projects/geronimo/spring/ + /www/incubator.apache.org/projects/geronimo/spring + /www/incubator.apache.org/projects/geronimo/builds/ + + org.apache.geronimo.spring + + + + + + + + + geronimo + geronimo-transaction + ${geronimo_version} + + + + geronimo + geronimo-kernel + ${geronimo_version} + + + + org.apache.geronimo.specs + geronimo-jta_1.0.1B_spec + ${geronimo_spec_jta_version} + + + + mx4j + mx4j + ${mx4j_version} + + + + springframework + spring + ${spring_version} + + + + + + + + ${basedir}/src/java + + **/*.xml + **/*.properties + + + + + + **/*Test.java + + + **/Abstract*.java + + + + + Added: geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/SpringTransactionManager.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/SpringTransactionManager.java?rev=374335&view=auto ============================================================================== --- geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/SpringTransactionManager.java (added) +++ geronimo/trunk/modules/spring/src/java/org/apache/geronimo/spring/transaction/SpringTransactionManager.java Thu Feb 2 02:01:47 2006 @@ -0,0 +1,239 @@ +/** + * + * Copyright 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.spring.transaction; + +import org.springframework.transaction.support.AbstractPlatformTransactionManager; +import org.springframework.transaction.support.DefaultTransactionStatus; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionSystemException; +import org.springframework.transaction.NestedTransactionNotSupportedException; +import org.springframework.transaction.IllegalTransactionStateException; +import org.springframework.transaction.UnexpectedRollbackException; +import org.springframework.transaction.HeuristicCompletionException; +import org.apache.geronimo.transaction.context.TransactionContextManager; +import org.apache.geronimo.transaction.context.TransactionContext; +import org.apache.geronimo.kernel.Kernel; +import org.apache.geronimo.kernel.KernelRegistry; +import org.apache.geronimo.kernel.proxy.ProxyManager; + +import javax.management.ObjectName; +import javax.management.MalformedObjectNameException; +import javax.transaction.NotSupportedException; +import javax.transaction.SystemException; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.RollbackException; +import javax.transaction.InvalidTransactionException; +import javax.transaction.Synchronization; +import javax.transaction.Status; +import java.util.List; +import java.util.Iterator; + +/** + * Wrap our TransactionContextManager in a spring idea of a transaction manager. + * + * @version $Rev:$ $Date:$ + */ +public class SpringTransactionManager extends AbstractPlatformTransactionManager { + + private final TransactionContextManager transactionContextManager; + + + /** + * Construct the spring transaction manager wrapper around our transaction context manager. + * @param kernelName normally "geronimo" + * @param transactionContextManagerName normally "geronimo.server:J2EEApplication=null,J2EEModule=geronimo/j2ee-server/1.1-SNAPSHOT/car,J2EEServer=geronimo,j2eeType=TransactionContextManager,name=TransactionContextManager" + * although the version may change. + * @throws MalformedObjectNameException + */ + public SpringTransactionManager(String kernelName, String transactionContextManagerName) throws MalformedObjectNameException { + + ObjectName transactionContextManagerObjectName = ObjectName.getInstance(transactionContextManagerName); + Kernel kernel = KernelRegistry.getKernel(kernelName); + ProxyManager proxyManager = kernel.getProxyManager(); + transactionContextManager = (TransactionContextManager) proxyManager.createProxy(transactionContextManagerObjectName, TransactionContextManager.class); + + } + + protected Object doGetTransaction() throws TransactionException { + return new TransactionContextWrapper(transactionContextManager.getContext()); + } + + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) transaction; + int timeoutSeconds = definition.getTimeout(); + TransactionContext newTransactionContext; + try { + newTransactionContext = transactionContextManager.newBeanTransactionContext(timeoutSeconds * 1000); + } catch (NotSupportedException e) { + throw new NestedTransactionNotSupportedException("Nested Transaction not supported", e); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + transactionContextWrapper.setTransactionContext(newTransactionContext); + } + + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) status.getTransaction(); + if (transactionContextWrapper == null) { + throw new IllegalTransactionStateException("No transaction present in statns"); + } + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + try { + transactionContext.commit(); + } catch (HeuristicMixedException e) { + throw new HeuristicCompletionException(HeuristicCompletionException.STATE_MIXED, e); + } catch (HeuristicRollbackException e) { + throw new HeuristicCompletionException(HeuristicCompletionException.STATE_ROLLED_BACK, e); + } catch (RollbackException e) { + throw new UnexpectedRollbackException("Rollback exception", e); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + transactionContextWrapper.setTransactionContext(transactionContextManager.getContext()); + } + + protected void doRollback(DefaultTransactionStatus status) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) status.getTransaction(); + if (transactionContextWrapper == null) { + throw new IllegalTransactionStateException("No transaction present in statns"); + } + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + try { + transactionContext.rollback(); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + transactionContextWrapper.setTransactionContext(transactionContextManager.getContext()); + } + + //stuff we actually need to overide the default implementations of + + protected boolean isExistingTransaction(Object transaction) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) transaction; + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + return transactionContext.isActive(); + } + + protected boolean useSavepointForNestedTransaction() { + return false; + } + + protected Object doSuspend(Object transaction) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) transaction; + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + try { + transactionContext.suspend(); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + return transactionContext; + } + + protected void doResume(Object transaction, Object suspendedResources) throws TransactionException { + TransactionContext transactionContext = (TransactionContext) suspendedResources; + try { + transactionContext.resume(); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } catch (InvalidTransactionException e) { + throw new IllegalTransactionStateException("Invalid transaction", e); + } + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) transaction; + transactionContextWrapper.setTransactionContext(transactionContext); + } + + protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) status.getTransaction(); + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + try { + transactionContext.setRollbackOnly(); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + } + + protected void registerAfterCompletionWithExistingTransaction(Object transaction, List synchronizations) + throws TransactionException { + TransactionContextWrapper transactionContextWrapper = (TransactionContextWrapper) transaction; + TransactionContext transactionContext = transactionContextWrapper.getTransactionContext(); + Synchronization synchronization = new AfterCompletionSynchronization(synchronizations); + try { + transactionContext.registerSynchronization(synchronization); + } catch (RollbackException e) { + throw new UnexpectedRollbackException("Rollback exception", e); + } catch (SystemException e) { + throw new TransactionSystemException("System exception", e); + } + } + + private static class AfterCompletionSynchronization implements Synchronization { + + private final List synchronizations; + + public AfterCompletionSynchronization(List synchronizations) { + this.synchronizations = synchronizations; + } + + public void beforeCompletion() { + } + + public void afterCompletion(int status) { + if (status == Status.STATUS_COMMITTED) { + springAfterCompletion(TransactionSynchronization.STATUS_COMMITTED); + } else if (status == Status.STATUS_ROLLEDBACK) { + springAfterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK); + } else { + throw new IllegalArgumentException("Unexpected status in afterCompletion: " + status); + } + } + + private void springAfterCompletion(int statusCommitted) { + for (Iterator iterator = synchronizations.iterator(); iterator.hasNext();) { + TransactionSynchronization transactionSynchronization = (TransactionSynchronization) iterator.next(); + try { + transactionSynchronization.afterCompletion(statusCommitted); + } catch(Throwable t) { + //ignore?? + } + } + } + } + + /** + * The spring javadoc does not make clear to me if this class is needed (spring transaction object is expected to + * change which transaction it represents) or superfluous (a new spring transaction object is created whenever + * a new transaction begins). + */ + private static class TransactionContextWrapper { + private TransactionContext transactionContext; + + protected TransactionContextWrapper(TransactionContext transactionContext) { + this.transactionContext = transactionContext; + } + + protected TransactionContext getTransactionContext() { + return transactionContext; + } + + protected void setTransactionContext(TransactionContext transactionContext) { + this.transactionContext = transactionContext; + } + } +}