You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/03/12 10:12:31 UTC
svn commit: r1455460 [3/3] - in /felix/trunk/ipojo/handler/transaction: ./
src/ transaction-handler-it/ transaction-handler-it/src/
transaction-handler-it/src/it/ transaction-handler-it/src/it/transaction-it/
transaction-handler-it/src/it/transaction-i...
Added: felix/trunk/ipojo/handler/transaction/transaction-handler-it/src/it/transaction-it/src/test/java/org/apache/felix/ipojo/handler/transaction/test/TestSupported.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/transaction/transaction-handler-it/src/it/transaction-it/src/test/java/org/apache/felix/ipojo/handler/transaction/test/TestSupported.java?rev=1455460&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/transaction/transaction-handler-it/src/it/transaction-it/src/test/java/org/apache/felix/ipojo/handler/transaction/test/TestSupported.java (added)
+++ felix/trunk/ipojo/handler/transaction/transaction-handler-it/src/it/transaction-it/src/test/java/org/apache/felix/ipojo/handler/transaction/test/TestSupported.java Tue Mar 12 09:12:28 2013
@@ -0,0 +1,392 @@
+package org.apache.felix.ipojo.handler.transaction.test;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.handler.transaction.components.FooDelegator;
+import org.apache.felix.ipojo.handler.transaction.components.FooImpl;
+import org.apache.felix.ipojo.handler.transaction.services.CheckService;
+import org.apache.felix.ipojo.handler.transaction.services.Foo;
+import org.junit.Assert;
+import org.junit.Test;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+import javax.transaction.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ow2.chameleon.testing.tinybundles.ipojo.IPOJOStrategy.withiPOJO;
+
+@ExamReactorStrategy(PerClass.class)
+public class TestSupported extends Common {
+
+
+ public static final File TEST = new File("src/main/resources");
+
+ @Configuration
+ public Option[] config() throws IOException {
+ Option[] options = super.config();
+
+
+ InputStream service = TinyBundles.bundle()
+ .add(CheckService.class)
+ .add(Foo.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "Service")
+ .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.handler.transaction.services")
+ .build();
+
+ InputStream fooimpl = TinyBundles.bundle()
+ .add(FooImpl.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "Foo Provider")
+ .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.handler.transaction.services")
+ .build(withiPOJO(new File(TEST, "foo.xml")));
+
+ InputStream test = TinyBundles.bundle()
+ .add(FooDelegator.class)
+ .set(Constants.BUNDLE_SYMBOLICNAME, "SupportedTransactionPropagation")
+ .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.handler.transaction.services, javax.transaction;version=1.1")
+ .build(withiPOJO(new File(TEST, "supported.xml")));
+
+ return OptionUtils.combine(
+ options,
+ provision(
+ service,
+ fooimpl,
+ test
+ ));
+ }
+
+ @Test
+ public void testOkOutsideTransaction() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ CheckService cs = ((CheckService) osgiHelper.getServiceObject(ref));
+ cs.doSomethingGood();
+ // No transaction.
+ }
+
+ @Test
+ public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ cs.doSomethingGood();
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ t.commit();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testExceptionOutsideTransaction() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ ((CheckService) osgiHelper.getServiceObject(ref)).doSomethingBad();
+ }
+
+ @Test(expected = RollbackException.class)
+ public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ try {
+ cs.doSomethingBad();
+ Assert.fail("NullPointerException expected");
+ } catch (Exception e) {
+ Assert.assertTrue(e instanceof NullPointerException);
+ }
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+
+ t.commit(); // Throw a rollback exception.
+ }
+
+ @Test
+ public void testExceptionInsideTransactionRB() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ try {
+ cs.doSomethingBad();
+ Assert.fail("NullPointerException expected");
+ } catch (Exception e) {
+ Assert.assertTrue(e instanceof NullPointerException);
+ }
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+
+ t.rollback();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testExpectedExceptionOutsideTransaction() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ ((CheckService) osgiHelper.getServiceObject(ref)).doSomethingBad2();
+ }
+
+ @Test
+ public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-ok");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ try {
+ cs.doSomethingBad2();
+ Assert.fail("UnsupportedOperationException expected");
+ } catch (Exception e) {
+ Assert.assertTrue(e instanceof UnsupportedOperationException);
+ }
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+
+ t.commit();
+ }
+
+ @Test
+ public void testOkOutsideTransactionWithCallback() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+
+ cs.doSomethingGood();
+
+ Assert.assertNull(cs.getLastRolledBack());
+ Assert.assertNull(cs.getLastCommitted());
+ Assert.assertEquals(0, cs.getNumberOfCommit());
+ Assert.assertEquals(0, cs.getNumberOfRollback());
+ }
+
+ @Test
+ public void testOkInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ cs.doSomethingGood();
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ t.commit();
+
+ Assert.assertNull(cs.getLastRolledBack());
+ Assert.assertNotNull(cs.getLastCommitted());
+ Assert.assertEquals(1, cs.getNumberOfCommit());
+ Assert.assertEquals(0, cs.getNumberOfRollback());
+
+ Assert.assertSame(t, cs.getLastCommitted());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testExceptionOutsideTransactionWithCallback() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+
+ cs.doSomethingBad();
+
+ Assert.assertNull(cs.getLastRolledBack());
+ Assert.assertNull(cs.getLastCommitted());
+ Assert.assertEquals(0, cs.getNumberOfCommit());
+ Assert.assertEquals(0, cs.getNumberOfRollback());
+ }
+
+ @Test
+ public void testExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ try {
+ cs.doSomethingBad();
+ Assert.fail("NullPointerException expected");
+ } catch (Exception e) {
+ Assert.assertTrue(e instanceof NullPointerException);
+ }
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+
+ try {
+ t.commit(); // Throw a rollback exception.
+ } catch (RollbackException e) {
+ // Expected
+ } catch (Throwable e) {
+ Assert.fail(e.getMessage()); // Unexpected
+ }
+
+ Assert.assertNotNull(cs.getLastRolledBack());
+ Assert.assertNull(cs.getLastCommitted());
+ Assert.assertEquals(0, cs.getNumberOfCommit());
+ Assert.assertEquals(1, cs.getNumberOfRollback());
+
+ Assert.assertSame(t, cs.getLastRolledBack());
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testExpectedExceptionOutsideTransactionWithCallback() {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+
+ cs.doSomethingBad2();
+
+ Assert.assertNull(cs.getLastRolledBack());
+ Assert.assertNull(cs.getLastCommitted());
+ Assert.assertEquals(0, cs.getNumberOfCommit());
+ Assert.assertEquals(0, cs.getNumberOfRollback());
+ }
+
+ @Test
+ public void testExpectedExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+ ComponentInstance prov = ipojoHelper.createComponentInstance("org.apache.felix.ipojo.handler.transaction.components.FooImpl");
+ ComponentInstance under = ipojoHelper.createComponentInstance("supported-cb");
+
+ Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+ Assert.assertEquals(ComponentInstance.VALID, under.getState());
+
+ ServiceReference ref = ipojoHelper.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+ Assert.assertNotNull(ref);
+
+ osgiHelper.waitForService(TransactionManager.class.getName(), null, 5000);
+ CheckService cs = (CheckService) osgiHelper.getServiceObject(ref);
+ TransactionManager tm = (TransactionManager) osgiHelper.getServiceObject(TransactionManager.class.getName(), null);
+ tm.begin();
+ Transaction t = tm.getTransaction();
+ try {
+ cs.doSomethingBad2();
+ Assert.fail("UnsupportedOperationException expected");
+ } catch (Exception e) {
+ Assert.assertTrue(e instanceof UnsupportedOperationException);
+ }
+ Transaction t2 = cs.getCurrentTransaction();
+ Assert.assertSame(t2, t);
+ Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+
+ t.commit();
+
+ Assert.assertNull(cs.getLastRolledBack());
+ Assert.assertNotNull(cs.getLastCommitted());
+ Assert.assertEquals(1, cs.getNumberOfCommit());
+ Assert.assertEquals(0, cs.getNumberOfRollback());
+
+ Assert.assertSame(t, cs.getLastCommitted());
+ }
+
+
+}
Added: felix/trunk/ipojo/handler/transaction/transaction-handler/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/transaction/transaction-handler/pom.xml?rev=1455460&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/transaction/transaction-handler/pom.xml (added)
+++ felix/trunk/ipojo/handler/transaction/transaction-handler/pom.xml Tue Mar 12 09:12:28 2013
@@ -0,0 +1,116 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>felix-parent</artifactId>
+ <version>1.2.1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>bundle</packaging>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo.handler.transaction
+ </artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <name>Apache Felix iPOJO Transaction Handler</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.4.3</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Private-Package>org.apache.felix.ipojo.transaction</Private-Package>
+ <Import-Package>javax.transaction;version=1.1, *</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-ipojo-plugin</artifactId>
+ <version>1.8.4</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>ipojo-bundle</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>rat-maven-plugin</artifactId>
+ <configuration>
+ <excludeSubProjects>false</excludeSubProjects>
+ <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
+ <useMavenDefaultExcludes>true</useMavenDefaultExcludes>
+ <excludes>
+ <param>doc/**/*</param>
+ <param>maven-eclipse.xml</param>
+ <param>.checkstyle</param>
+ <param>.externalToolBuilders/*</param>
+ <param>LICENSE.asm</param>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <enableRulesSummary>false</enableRulesSummary>
+ <violationSeverity>warning</violationSeverity>
+ <configLocation>
+ http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml
+ </configLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo</artifactId>
+ <version>1.9.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+ <version>1.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>geronimo-spec</groupId>
+ <artifactId>geronimo-spec-jta</artifactId>
+ <version>1.0-M1</version>
+ </dependency>
+ </dependencies>
+</project>
Added: felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java?rev=1455460&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java (added)
+++ felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java Tue Mar 12 09:12:28 2013
@@ -0,0 +1,291 @@
+package org.apache.felix.ipojo.transaction;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.util.Callback;
+
+public class TransactionHandler extends PrimitiveHandler implements Synchronization {
+
+ public static final String NAMESPACE= "org.apache.felix.ipojo.transaction";
+
+ public static final String NAME= "transaction";
+
+ private static final String FIELD_ATTRIBUTE= "field";
+
+ private static final String ONCOMMIT_ATTRIBUTE= "oncommit";
+
+ private static final String ONROLLBACK_ATTRIBUTE= "onrollback";
+
+ private static final String TRANSACTIONAL_ELEMENT = "transactional";
+
+ private static final String METHOD_ATTRIBUTE = "method";
+
+ private static final String TIMEOUT_ATTRIBUTE = "timeout";
+
+ private static final String PROPAGATION_ATTRIBUTE = "propagation";
+
+ private static final String EXCEPTIONONROLLBACK_ATTRIBUTE = "exceptiononrollback";
+
+ private static final String NOROLLBACKFOR_ATTRIBUTE = "norollbackfor";
+
+ public static final int DEFAULT_PROPAGATION = TransactionalMethod.REQUIRES;
+
+
+ private TransactionManager m_transactionManager; // Service Dependency
+
+ private List<TransactionalMethod> m_methods = new ArrayList<TransactionalMethod>();
+
+ private Callback m_onRollback;
+
+ private Callback m_onCommit;
+
+ private List<Transaction> m_transactions = new ArrayList<Transaction>();
+
+
+ public void configure(Element arg0, Dictionary arg1)
+ throws ConfigurationException {
+ Element[] elements = arg0.getElements(NAME, NAMESPACE);
+ if (elements.length > 1) {
+ throw new ConfigurationException("The handler " + NAMESPACE + ":" + NAME + " cannot be declared several times");
+ }
+
+ String field = elements[0].getAttribute(FIELD_ATTRIBUTE);
+ if (field != null) {
+ FieldMetadata meta = getPojoMetadata().getField(field);
+ if (meta == null) {
+ throw new ConfigurationException("The transaction field does not exist in the pojo class : " + field);
+ }
+ if (! meta.getFieldType().equals(Transaction.class.getName())) {
+ throw new ConfigurationException("The transaction field type must be " + Transaction.class.getName());
+ }
+ // Register the interceptor
+ getInstanceManager().register(meta, this);
+
+ }
+
+ String oncommit = elements[0].getAttribute(ONCOMMIT_ATTRIBUTE);
+ if (oncommit != null) {
+ m_onCommit = new Callback(oncommit, new String[] { Transaction.class.getName() }, false, getInstanceManager());
+ }
+
+ String onrollback = elements[0].getAttribute(ONROLLBACK_ATTRIBUTE);
+ if (onrollback != null) {
+ m_onRollback = new Callback(onrollback, new String[] { Transaction.class.getName() }, false, getInstanceManager());
+ }
+
+
+ Element[] sub = elements[0].getElements(TRANSACTIONAL_ELEMENT);
+ if (sub == null || sub.length == 0) {
+ throw new ConfigurationException("The handler " + NAMESPACE + ":" + NAME + " must have " + TRANSACTIONAL_ELEMENT + " subelement");
+ }
+
+ for (int i = 0; i < sub.length; i++) {
+ String method = sub[i].getAttribute(METHOD_ATTRIBUTE);
+ String to = sub[i].getAttribute(TIMEOUT_ATTRIBUTE);
+ String propa = sub[i].getAttribute(PROPAGATION_ATTRIBUTE);
+ String nrbf = sub[i].getAttribute(NOROLLBACKFOR_ATTRIBUTE);
+ String eorb = sub[i].getAttribute(EXCEPTIONONROLLBACK_ATTRIBUTE);
+
+ if (method == null) {
+ throw new ConfigurationException("A transactional element must specified the method attribute");
+ }
+ MethodMetadata meta = this.getPojoMetadata().getMethod(method);
+ if (meta == null) {
+ throw new ConfigurationException("A transactional method is not in the pojo class : " + method);
+ }
+
+ int timeout = 0;
+ if (to != null) {
+ timeout = new Integer(to).intValue();
+ }
+
+ int propagation = DEFAULT_PROPAGATION;
+ if (propa != null) {
+ propagation = parsePropagation(propa);
+ }
+
+ List<String> exceptions = new ArrayList<String>();
+ if (nrbf != null) {
+ exceptions = (List<String>) ParseUtils.parseArraysAsList(nrbf);
+ }
+
+ boolean exceptionOnRollback = false;
+ if (eorb != null) {
+ exceptionOnRollback = new Boolean(eorb).booleanValue();
+ }
+
+ TransactionalMethod tm = new TransactionalMethod(method, propagation, timeout, exceptions, exceptionOnRollback, this);
+ m_methods.add(tm);
+ this.getInstanceManager().register(meta, tm);
+ }
+
+ }
+
+ private int parsePropagation(String propa) throws ConfigurationException {
+ if (propa.equalsIgnoreCase("requires")) {
+ return TransactionalMethod.REQUIRES;
+
+ } else if (propa.equalsIgnoreCase("mandatory")){
+ return TransactionalMethod.MANDATORY;
+
+ } else if (propa.equalsIgnoreCase("notsupported")) {
+ return TransactionalMethod.NOT_SUPPORTED;
+
+ } else if (propa.equalsIgnoreCase("supported")) {
+ return TransactionalMethod.SUPPORTED;
+
+ } else if (propa.equalsIgnoreCase("never")) {
+ return TransactionalMethod.NEVER;
+
+ } else if (propa.equalsIgnoreCase("requiresnew")) {
+ return TransactionalMethod.REQUIRES_NEW;
+ }
+
+ throw new ConfigurationException("Unknown propgation policy : " + propa);
+ }
+
+ public void start() {
+ // Set transaction managers.
+ for (TransactionalMethod method : m_methods) {
+ method.setTransactionManager(m_transactionManager);
+ }
+ }
+
+ public void stop() {
+ // Nothing to do.
+ }
+
+ public synchronized void bind(TransactionManager tm) {
+ for (TransactionalMethod method : m_methods) {
+ method.setTransactionManager(tm);
+ }
+ }
+
+ public synchronized void unbind(TransactionManager tm) {
+ for (TransactionalMethod method : m_methods) {
+ method.setTransactionManager(null);
+ }
+ }
+
+ public void transactionRolledback(Transaction t) {
+ if (m_onRollback != null) {
+ try {
+ m_onRollback.call(new Object[] { t });
+ } catch (NoSuchMethodException e1) {
+ error("Cannot invoke the onRollback method, method not found",
+ e1);
+ } catch (IllegalAccessException e1) {
+ error(
+ "Cannot invoke the onRollback method,cannot access the method",
+ e1);
+ } catch (InvocationTargetException e1) {
+ error(
+ "Cannot invoke the onRollback method,the method thrown an exception",
+ e1.getTargetException());
+ }
+ }
+ }
+
+ public void transactionCommitted(Transaction t) {
+ if (m_onRollback != null) {
+ try {
+ m_onCommit.call(new Object[] { t });
+ } catch (NoSuchMethodException e1) {
+ error("Cannot invoke the onCommit callback, method not found",
+ e1);
+ } catch (IllegalAccessException e1) {
+ error(
+ "Cannot invoke the onCommit callback,cannot access the method",
+ e1);
+ } catch (InvocationTargetException e1) {
+ error(
+ "Cannot invoke the onCommit callback,the method thrown an exception",
+ e1.getTargetException());
+ }
+ }
+
+ }
+
+ public void stateChanged(int newState) {
+ if (newState == ComponentInstance.INVALID) {
+ // rollback all owned transactions.
+ for (int i = 0; i < m_methods.size(); i++) {
+ m_methods.get(i).rollbackOwnedTransactions();
+ }
+
+ for (int i =0; i < m_transactions.size(); i++) {
+ try {
+ m_transactions.get(i).setRollbackOnly();
+ } catch (Exception e) {
+ error("Cannot set rollback only on a transaction : " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ public synchronized Object onGet(Object pojo, String fieldName, Object value) {
+ try {
+ if (m_transactionManager != null) {
+ return m_transactionManager.getTransaction();
+ } else {
+ return null;
+ }
+ } catch (SystemException e) {
+ error("Cannot get the current transaction, internal error", e);
+ return null;
+ }
+ }
+
+ public void afterCompletion(int arg0) {
+ try {
+ if (m_transactionManager.getTransaction() != null) {
+ m_transactions .remove(m_transactionManager.getTransaction());
+ if (arg0 == Status.STATUS_ROLLEDBACK) {
+ transactionRolledback(m_transactionManager.getTransaction());
+ } else if (arg0 == Status.STATUS_COMMITTED) {
+ transactionCommitted(m_transactionManager.getTransaction());
+ }
+ }
+ } catch (SystemException e) {
+ error("Cannot remove the transaction from the transaction list : " + e.getMessage());
+ }
+ }
+
+ public void beforeCompletion() {
+
+ }
+
+ public void addTransaction(Transaction transaction) {
+ if (m_transactions.contains(transaction)) {
+ return;
+ }
+ try {
+ transaction.registerSynchronization(this);
+ m_transactions.add(transaction);
+ } catch (Exception e) {
+ error("Cannot add the transaction to the transaction list : " + e.getMessage());
+ }
+ }
+
+ public List<Transaction> getTransactions() {
+ return m_transactions;
+ }
+
+
+}
Added: felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionalMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionalMethod.java?rev=1455460&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionalMethod.java (added)
+++ felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/java/org/apache/felix/ipojo/transaction/TransactionalMethod.java Tue Mar 12 09:12:28 2013
@@ -0,0 +1,287 @@
+package org.apache.felix.ipojo.transaction;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.MethodInterceptor;
+
+public class TransactionalMethod implements MethodInterceptor {
+
+ public static final int REQUIRES = 0;
+
+ public static final int REQUIRES_NEW = 1;
+
+ public static final int MANDATORY = 2;
+
+ public static final int SUPPORTED = 3;
+
+ public static final int NOT_SUPPORTED = 4;
+
+ public static final int NEVER = 5;
+
+ private String method;
+
+ private int propagation;
+
+ private int timeout;
+
+ private List<String> exceptions;
+
+ private TransactionManager manager;
+
+ private Map <Thread, Transaction> m_owned = new HashMap<Thread, Transaction>();
+
+ private boolean exceptionOnRollback;
+
+
+ private TransactionHandler handler;
+
+ private Transaction suspended;
+
+ public TransactionalMethod(String method, int propagation, int timeout, List<String> exception, boolean exceptionOnRollback, TransactionHandler handler) {
+ this.method = method;
+ this.propagation = propagation;
+ this.timeout = timeout;
+ this.exceptions = exception;
+ this.exceptionOnRollback = exceptionOnRollback;
+ this.handler = handler;
+ }
+
+ public synchronized void setTransactionManager(TransactionManager tm) {
+ manager = tm;
+ if (manager == null) {
+ // Clear stored transactions.
+ m_owned.clear();
+
+ }
+ }
+
+
+ public void onEntry() throws SystemException, NotSupportedException {
+ TransactionManager manager = null;
+ synchronized (this) {
+ if (this.manager != null) {
+ manager = this.manager; // Stack confinement
+ } else {
+ return; // Nothing can be done...
+ }
+ }
+
+ Transaction transaction = manager.getTransaction();
+ switch (propagation) {
+ case REQUIRES:
+ // Are we already in a transaction?
+ if (transaction == null) {
+ // No, create one
+ if (timeout > 0) {
+ manager.setTransactionTimeout(timeout);
+ }
+ manager.begin();
+ m_owned.put(Thread.currentThread(), manager.getTransaction());
+ } else {
+ // Add the transaction to the transaction list
+ handler.addTransaction(transaction);
+ }
+ break;
+ case MANDATORY:
+ if (transaction == null) {
+ // Error
+ throw new IllegalStateException("The method " + method + " must be called inside a transaction");
+ } else {
+ // Add the transaction to the transaction list
+ handler.addTransaction(transaction);
+ }
+ break;
+ case SUPPORTED:
+ // if transaction != null, register the callback, else do nothing
+ if (transaction != null) {
+ handler.addTransaction(transaction);
+ } // Else do nothing.
+ break;
+ case NOT_SUPPORTED:
+ // Do nothing.
+ break;
+ case NEVER:
+ if (transaction != null) {
+ throw new IllegalStateException("The method " + method + " must never be called inside a transaction");
+ }
+ break;
+ case REQUIRES_NEW:
+ if (transaction == null) {
+ // No current transaction, Just creates a new one
+ if (timeout > 0) {
+ manager.setTransactionTimeout(timeout);
+ }
+ manager.begin();
+ m_owned.put(Thread.currentThread(), manager.getTransaction());
+ } else {
+ if (suspended == null) {
+ suspended = manager.suspend();
+ if (timeout > 0) {
+ manager.setTransactionTimeout(timeout);
+ }
+ manager.begin();
+ m_owned.put(Thread.currentThread(), manager.getTransaction());
+ } else {
+ throw new IllegalStateException("The method " + method + " requires to suspend a second times a transaction");
+ }
+ }
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown or unsupported propagation policy for " + method + " :" + propagation);
+
+ }
+ }
+
+ public void onExit() throws SecurityException, HeuristicMixedException, HeuristicRollbackException, SystemException, InvalidTransactionException, IllegalStateException {
+ switch (propagation) {
+ case REQUIRES:
+ // Are we the owner of the transaction?
+ Transaction transaction = m_owned.get(Thread.currentThread());
+ if (transaction != null) { // Owner.
+ try {
+ transaction.commit(); // Commit the transaction
+ m_owned.remove(Thread.currentThread());
+ handler.transactionCommitted(transaction); // Manage potential notification.
+ } catch ( RollbackException e) {
+ m_owned.remove(Thread.currentThread());
+ // The transaction was rolledback
+ if (exceptionOnRollback) {
+ throw new IllegalStateException("The transaction was rolled back : " + e.getMessage());
+ }
+ handler.transactionRolledback(transaction); // Manage potential notification.
+ }
+ } // Else wait for commit.
+ break;
+ case MANDATORY:
+ // We are never the owner, so just exits the transaction.
+ break;
+ case SUPPORTED:
+ // Do nothing.
+ break;
+ case NOT_SUPPORTED:
+ // Do nothing.
+ break;
+ case NEVER:
+ // Do nothing.
+ break;
+ case REQUIRES_NEW:
+ // We're necessary the owner.
+ transaction = m_owned.get(Thread.currentThread());
+ if (transaction == null) {
+ throw new RuntimeException("Cannot apply the REQUIRES NEW propagation, we're not the transaction owner!");
+ }
+ try {
+ transaction.commit(); // Commit the transaction
+ m_owned.remove(Thread.currentThread());
+ handler.transactionCommitted(transaction); // Manage potential notification.
+ if (suspended != null) {
+ manager.suspend(); // suspend the completed transaction.
+ manager.resume(suspended);
+ suspended = null;
+ }
+ } catch ( RollbackException e) { // The transaction was rolledback rather than committed
+ m_owned.remove(Thread.currentThread());
+ if (suspended != null) {
+ manager.suspend(); // suspend the completed transaction.
+ manager.resume(suspended); // The resume transaction is not rolledback, they are independent.
+ suspended = null;
+ }
+ // The transaction was rolledback
+ if (exceptionOnRollback) {
+ throw new IllegalStateException("The transaction was rolled back : " + e.getMessage());
+ }
+ handler.transactionRolledback(transaction); // Manage potential notification.
+ }
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown or unsupported propagation policy for " + method + " :" + propagation);
+
+ }
+ }
+
+ public void onError(String exception) throws SystemException {
+ TransactionManager manager = null;
+ synchronized (this) {
+ if (this.manager != null) {
+ manager = this.manager; // Stack confinement
+ } else {
+ return; // Nothing can be done...
+ }
+ }
+
+ // is the error something to exclude, and are we inside the transaction (owner or participant)?
+ if (! exceptions.contains(exception)) {
+ Transaction tr = manager.getTransaction();
+ if (m_owned.containsValue(tr) || handler.getTransactions().contains(tr)) {
+ // Set the transaction to rollback only
+ manager.getTransaction().setRollbackOnly();
+ }
+ }
+ }
+
+ public void onEntry(Object o, Member member, Object[] objects) {
+ try {
+ onEntry();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+ }
+
+ }
+
+ public void onError(Object o, Member member, Throwable throwable) {
+ try {
+ throwable.printStackTrace();
+
+ onError(throwable.getClass().getName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+ }
+ }
+
+ public void onExit(Object o, Member member, Object o1) {
+ // Wait for on finally.
+ }
+
+ public void onFinally(Object o, Member member) {
+ try {
+ onExit();
+ } catch (IllegalStateException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+ }
+ }
+
+ public void rollbackOwnedTransactions() {
+ Iterator<Entry<Thread, Transaction>> entries = m_owned.entrySet().iterator();
+ while(entries.hasNext()) {
+ Entry<Thread, Transaction> entry = entries.next();
+ try {
+ entry.getValue().rollback();
+ } catch (IllegalStateException e) {
+ throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+ } catch (SystemException e) {
+ throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+ }
+ }
+ m_owned.clear();
+ }
+
+}
Added: felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/resources/metadata.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/resources/metadata.xml?rev=1455460&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/resources/metadata.xml (added)
+++ felix/trunk/ipojo/handler/transaction/transaction-handler/src/main/resources/metadata.xml Tue Mar 12 09:12:28 2013
@@ -0,0 +1,13 @@
+<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/CURRENT/core.xsd"
+ xmlns="org.apache.felix.ipojo">
+
+ <handler name="transaction" namespace="org.apache.felix.ipojo.transaction"
+ classname="org.apache.felix.ipojo.transaction.TransactionHandler">
+ <requires field="m_transactionManager">
+ <callback type="bind" method="bind"/>
+ <callback type="unbind" method="unbind"/>
+ </requires>
+ </handler>
+
+</ipojo>
\ No newline at end of file