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 2009/04/29 17:05:00 UTC

svn commit: r769796 [3/3] - in /felix/sandbox/clement/ipojo-utils/transaction: ./ org.apache.felix.ipojo.transaction.test/ org.apache.felix.ipojo.transaction.test/src/ org.apache.felix.ipojo.transaction.test/src/main/ org.apache.felix.ipojo.transaction...

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,438 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestSupported {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File("FooImpl.jar"), new File("foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File("supported.jar"), new File("supported.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = ((CheckService) osgi.getServiceObject(ref));
+        cs.doSomethingGood();
+        // No transaction.
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad();
+    }
+    
+    @Test(expected=RollbackException.class)
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2();
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        
+        CheckService cs = (CheckService) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.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 = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.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());
+    }
+    
+
+    
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,79 @@
+package org.apache.felix.ipojo.transaction.test.component;
+
+import javax.transaction.Transaction;
+
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+
+public class FooDelegator implements CheckService {
+    
+    private Foo foo;
+    
+    private int commit;
+    
+    private int rollback;
+    
+    Transaction transaction;
+    
+    Transaction lastCommitted;
+    
+    Transaction lastRolledback;
+    
+    public void onCommit(String method) {
+        commit ++;
+    }
+    
+    public void onRollback(String method, Exception e) {
+        rollback ++;
+    }
+
+    public void doSomethingBad() throws NullPointerException {
+        foo.doSomethingBad();
+    }
+
+    public void doSomethingBad2() throws UnsupportedOperationException {
+       foo.doSomethingBad2();
+
+    }
+
+    public void doSomethingGood() {
+        foo.doSomethingGood();
+        System.out.println("==========> " + transaction);
+    }
+
+    public void doSomethingLong() {
+       foo.doSomethingLong();
+    }
+
+    public Transaction getCurrentTransaction() {
+       return transaction;
+    }
+
+    public int getNumberOfCommit() {
+       return commit;
+    }
+
+    public int getNumberOfRollback() {
+       return rollback;
+    }
+    
+    public Transaction getLastRolledBack() {
+        return lastRolledback;
+    }
+    
+    public Transaction getLastCommitted() {
+        return lastCommitted;
+    }
+    
+    public void onRollback(Transaction t) {
+        lastRolledback = t;
+        rollback ++;
+    }
+    
+
+    public void onCommit(Transaction t) {
+        lastCommitted = t;
+        commit ++;
+    }
+
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,28 @@
+package org.apache.felix.ipojo.transaction.test.component;
+
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+
+public class FooImpl implements Foo {
+
+    public void doSomethingBad() throws NullPointerException {
+       throw new NullPointerException("NULL");
+    }
+
+    public void doSomethingBad2() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("Expected exception");
+
+    }
+
+    public void doSomethingGood() {
+       // Good...
+    }
+
+    public void doSomethingLong() {
+        try {
+            Thread.sleep(5000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,25 @@
+package org.apache.felix.ipojo.transaction.test.service;
+
+import javax.transaction.Transaction;
+
+public interface CheckService {
+    
+    public void doSomethingGood();
+    
+    public void doSomethingBad() throws NullPointerException;
+    
+    public void doSomethingBad2() throws UnsupportedOperationException;
+    
+    public void doSomethingLong();
+    
+    public int getNumberOfCommit();
+    
+    public int getNumberOfRollback();
+    
+    public Transaction getCurrentTransaction();
+    
+    public Transaction getLastRolledBack();
+    
+    public Transaction getLastCommitted();
+
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,13 @@
+package org.apache.felix.ipojo.transaction.test.service;
+
+public interface Foo {
+    
+    public void doSomethingGood();
+    
+    public void doSomethingBad() throws NullPointerException;
+    
+    public void doSomethingBad2() throws UnsupportedOperationException;
+    
+    public void doSomethingLong();
+
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/supported.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/supported.xml?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/supported.xml (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/supported.xml Wed Apr 29 15:04:58 2009
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="supported-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="supported"/>
+			<transactionnal method="getCurrentTransaction" propagation="supported"/>
+			<transactionnal method="doSomethingBad" propagation="supported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="supported"/>
+			<transactionnal method="doSomethingLong" propagation="supported"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="supported-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="supported"/>
+			<transactionnal method="getCurrentTransaction" propagation="supported"/>
+			<transactionnal method="doSomethingBad" propagation="supported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="supported"/>
+			<transactionnal method="doSomethingLong" propagation="supported"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction.test/supported.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/pom.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/pom.xml?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/pom.xml (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/pom.xml Wed Apr 29 15:04:58 2009
@@ -0,0 +1,64 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <groupId>org.apache.felix</groupId>
+  <artifactId>org.apache.felix.ipojo.transaction</artifactId>
+  <version>1.3.0-SNAPSHOT</version>
+  <name>Apache Felix iPOJO Transaction</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>${pom.artifactId}</Bundle-SymbolicName>
+            <Private-Package>org.apache.felix.ipojo.transaction</Private-Package>
+            <Import-Package>*</Import-Package> <!-- YOUR_IMPORTED_PACKAGES -->
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+	      <groupId>org.apache.felix</groupId>
+	      <artifactId>maven-ipojo-plugin</artifactId>
+	      <version>1.3.0-SNAPSHOT</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>
+    </plugins>
+  </build>
+  
+  <dependencies>
+  	<dependency>
+  		<groupId>org.apache.felix</groupId>
+  		<artifactId>org.apache.felix.ipojo</artifactId>
+  		<version>1.3.0-SNAPSHOT</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.apache.felix</groupId>
+  		<artifactId>org.apache.felix.ipojo.metadata</artifactId>
+  		<version>1.3.0-SNAPSHOT</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.apache.felix</groupId>
+  		<artifactId>org.apache.felix.transaction</artifactId>
+  		<version>0.9.0-SNAPSHOT</version>
+  	</dependency>
+  </dependencies>
+</project>

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,294 @@
+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.RollbackException;
+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 TRANSACTIONNAL_ELEMENT = "transactionnal";
+        
+    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 = TransactionnalMethod.REQUIRES;
+    
+    
+    private TransactionManager m_transactionManager; // Service Dependency
+    
+    private List<TransactionnalMethod> m_methods = new ArrayList<TransactionnalMethod>();
+    
+    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(TRANSACTIONNAL_ELEMENT);
+        if (sub == null  || sub.length == 0) {
+            throw new ConfigurationException("The handler " + NAMESPACE + ":" + NAME + " must have " + TRANSACTIONNAL_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 transactionnal element must specified the method attribute");
+            }
+            MethodMetadata meta = this.getPojoMetadata().getMethod(method);
+            if (meta == null) {
+                throw new ConfigurationException("A transactionnal 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();
+            }
+            
+            TransactionnalMethod tm = new TransactionnalMethod(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 TransactionnalMethod.REQUIRES;
+           
+       } else if (propa.equalsIgnoreCase("mandatory")){
+           return TransactionnalMethod.MANDATORY;
+           
+       } else if (propa.equalsIgnoreCase("notsupported")) {
+           return TransactionnalMethod.NOT_SUPPORTED;
+           
+       } else if (propa.equalsIgnoreCase("supported")) {
+           return TransactionnalMethod.SUPPORTED;
+           
+       } else if (propa.equalsIgnoreCase("never")) {
+           return TransactionnalMethod.NEVER;
+       
+        } else if (propa.equalsIgnoreCase("requiresnew")) {
+            return TransactionnalMethod.REQUIRES_NEW;
+        }
+       
+       throw new ConfigurationException("Unknown propgation policy : " + propa);
+    }
+
+    public void start() {
+        // Set transaction managers.
+        for (TransactionnalMethod method : m_methods) {
+            method.setTransactionManager(m_transactionManager);
+        }
+    }
+
+    public void stop() {
+        // TODO Auto-generated method stub
+
+    }
+    
+    public synchronized void bind(TransactionManager tm) {
+        for (TransactionnalMethod method : m_methods) {
+            method.setTransactionManager(tm);
+        }
+    }
+    
+    public synchronized void unbind(TransactionManager tm) {
+        for (TransactionnalMethod 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 ownded 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) {
+        System.out.println("onGet on a transaction object !");
+        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;
+    }
+  
+
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionnalMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionnalMethod.java?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionnalMethod.java (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionnalMethod.java Wed Apr 29 15:04:58 2009
@@ -0,0 +1,289 @@
+package org.apache.felix.ipojo.transaction;
+
+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 TransactionnalMethod 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 TransactionnalMethod(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) {
+        System.out.println("Set transaction manager to " + 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 {
+                System.out.println("No transaction manager...");
+                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
+                    System.out.println("Begin a new transaction !");
+
+                    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 rolledback : " + 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());
+                try {
+                    transaction.commit(); // Commit the transaction
+                    m_owned.remove(Thread.currentThread());
+                    handler.transactionCommitted(transaction); // Manage potential notification.
+                    if (suspended != null) {
+                        manager.resume(suspended);
+                        suspended = null;
+                    }
+                 } catch ( RollbackException e) {
+                    m_owned.remove(Thread.currentThread());
+                    if (suspended != null) {
+                        manager.resume(suspended);
+                        suspended = null;
+                    }
+                    // The transaction was rolledback
+                    if (exceptionOnRollback) {
+                        throw new IllegalStateException("The transaction was rolledback : " + e.getMessage());
+                    }
+                    handler.transactionRolledback(transaction); // Manage potential notification.
+                }
+                
+            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 arg0, Method arg1, Object[] arg2) {
+        try {
+            onEntry();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+        }
+        
+    }
+
+    public void onError(Object arg0, Method arg1, Throwable arg2) {
+        try {
+            System.out.println("Error in  a TM " + arg1.getName() + " " + arg2.getMessage());
+            arg2.printStackTrace();
+
+            onError(arg2.getClass().getName());
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("An issue occurs during transaction management of " + method + " : " + e.getMessage());
+        }
+    }
+
+    public void onExit(Object arg0, Method arg1, Object arg2) {
+        // Wait for on finally.
+    }
+
+    public void onFinally(Object arg0, Method arg1) {
+        try {
+            System.out.println("Exits a TM " + arg1.getName());
+
+            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();
+    }
+    
+    
+}

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/java/org/apache/felix/ipojo/transaction/TransactionnalMethod.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/resources/metadata.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/resources/metadata.xml?rev=769796&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/resources/metadata.xml (added)
+++ felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/resources/metadata.xml Wed Apr 29 15:04:58 2009
@@ -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

Propchange: felix/sandbox/clement/ipojo-utils/transaction/org.apache.felix.ipojo.transaction/src/main/resources/metadata.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain