aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From z..@apache.org
Subject svn commit: r1075109 [3/3] - in /aries/tags/transaction-0.1-incubating: ./ transaction-blueprint/ transaction-blueprint/src/ transaction-blueprint/src/main/ transaction-blueprint/src/main/java/ transaction-blueprint/src/main/java/org/ transaction-bluep...
Date Sun, 27 Feb 2011 18:37:14 GMT
Added: aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/Activator.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/Activator.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/Activator.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/Activator.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.HashMap;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.cm.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ */
+public class Activator implements BundleActivator, ManagedServiceFactory {
+
+    private static final Logger log = LoggerFactory.getLogger("org.apache.aries.transaction");
+
+    private BundleContext bundleContext;
+    private Map managers = new HashMap<String, TransactionManagerService>();
+
+    public void start(BundleContext bundleContext) throws Exception {
+        this.bundleContext = bundleContext;
+        Hashtable props = new Hashtable();
+        props.put(Constants.SERVICE_PID, getName());
+        bundleContext.registerService(ManagedServiceFactory.class.getName(), this, props);
+
+        Hashtable ht = new Hashtable();
+        updated("initial", ht);
+    }
+
+    private void set(Hashtable ht, String key) {
+        String o = bundleContext.getProperty(key);
+        if (o == null) {
+            o = System.getenv(key.toUpperCase().replaceAll(".", "_"));
+            if (o == null) {
+                return;
+            }
+        }
+        ht.put(key, o);
+    }
+
+    public void stop(BundleContext context) throws Exception {
+        for (Iterator w = managers.values().iterator(); w.hasNext();) {
+            try {
+                TransactionManagerService mgr = (TransactionManagerService) w.next();
+                w.remove();
+                mgr.close();
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+    }
+
+    public String getName() {
+        return "org.apache.aries.transaction";
+    }
+
+    public void updated(String pid, Dictionary properties) throws ConfigurationException {
+        deleted(pid);
+        TransactionManagerService mgr = new TransactionManagerService(pid, properties, bundleContext);
+        managers.put(pid, mgr);
+        try {
+            mgr.start();
+        } catch (Exception e) {
+            log.error("Error starting transaction manager", e);
+        }
+    }
+
+    public void deleted(String pid) {
+        TransactionManagerService mgr = (TransactionManagerService) managers.remove(pid);
+        if (mgr != null) {
+            try {
+                mgr.close();
+            } catch (Exception e) {
+                log.error("Error stopping transaction manager", e);
+            }
+        }
+    }
+
+}
\ No newline at end of file

Added: aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/GeronimoPlatformTransactionManager.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/GeronimoPlatformTransactionManager.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/GeronimoPlatformTransactionManager.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/GeronimoPlatformTransactionManager.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction;
+
+import java.util.Map;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.transaction.Transaction;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.xa.XAException;
+
+import org.apache.geronimo.transaction.manager.GeronimoTransactionManager;
+import org.apache.geronimo.transaction.manager.TransactionLog;
+import org.apache.geronimo.transaction.manager.XidFactory;
+import org.apache.geronimo.transaction.manager.TransactionManagerMonitor;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionException;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.jta.JtaTransactionManager;
+
+/**
+ */
+public class GeronimoPlatformTransactionManager extends GeronimoTransactionManager implements PlatformTransactionManager {
+
+    private final PlatformTransactionManager platformTransactionManager;
+    private final Map<Transaction, SuspendedResourcesHolder> suspendedResources = new ConcurrentHashMap<Transaction, SuspendedResourcesHolder>();
+
+    public GeronimoPlatformTransactionManager() throws XAException {
+        platformTransactionManager = new JtaTransactionManager(this, this);
+        registerTransactionAssociationListener();
+    }
+
+    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds) throws XAException {
+        super(defaultTransactionTimeoutSeconds);
+        platformTransactionManager = new JtaTransactionManager(this, this);
+        registerTransactionAssociationListener();
+    }
+
+    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds, TransactionLog transactionLog) throws XAException {
+        super(defaultTransactionTimeoutSeconds, transactionLog);
+        platformTransactionManager = new JtaTransactionManager(this, this);
+        registerTransactionAssociationListener();
+    }
+
+    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds, XidFactory xidFactory, TransactionLog transactionLog) throws XAException {
+        super(defaultTransactionTimeoutSeconds, xidFactory, transactionLog);
+        platformTransactionManager = new JtaTransactionManager(this, this);
+        registerTransactionAssociationListener();
+    }
+
+    public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
+        return platformTransactionManager.getTransaction(definition);
+    }
+
+    public void commit(TransactionStatus status) throws TransactionException {
+        platformTransactionManager.commit(status);
+    }
+
+    public void rollback(TransactionStatus status) throws TransactionException {
+        platformTransactionManager.rollback(status);
+    }
+
+    protected void registerTransactionAssociationListener() {
+        addTransactionAssociationListener(new TransactionManagerMonitor() {
+            public void threadAssociated(Transaction transaction) {
+                try {
+                    if (transaction.getStatus() == Status.STATUS_ACTIVE) {
+                        SuspendedResourcesHolder holder = suspendedResources.remove(transaction);
+                        if (holder != null && holder.getSuspendedSynchronizations() != null) {
+                            TransactionSynchronizationManager.setActualTransactionActive(true);
+                            TransactionSynchronizationManager.setCurrentTransactionReadOnly(holder.isReadOnly());
+                            TransactionSynchronizationManager.setCurrentTransactionName(holder.getName());
+                            TransactionSynchronizationManager.initSynchronization();
+                            for (Iterator<?> it = holder.getSuspendedSynchronizations().iterator(); it.hasNext();) {
+                                TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
+                                synchronization.resume();
+                                TransactionSynchronizationManager.registerSynchronization(synchronization);
+                            }
+                        }
+                    }
+                } catch (SystemException e) {
+                    return;
+                }
+            }
+            public void threadUnassociated(Transaction transaction) {
+                try {
+                    if (transaction.getStatus() == Status.STATUS_ACTIVE) {
+                        if (TransactionSynchronizationManager.isSynchronizationActive()) {
+                            List<?> suspendedSynchronizations = TransactionSynchronizationManager.getSynchronizations();
+                            for (Iterator<?> it = suspendedSynchronizations.iterator(); it.hasNext();) {
+                                ((TransactionSynchronization) it.next()).suspend();
+                            }
+                            TransactionSynchronizationManager.clearSynchronization();
+                            String name = TransactionSynchronizationManager.getCurrentTransactionName();
+                            TransactionSynchronizationManager.setCurrentTransactionName(null);
+                            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+                            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
+                            TransactionSynchronizationManager.setActualTransactionActive(false);
+                            SuspendedResourcesHolder holder = new SuspendedResourcesHolder(null, suspendedSynchronizations, name, readOnly);
+                            suspendedResources.put(transaction, holder);
+                        }
+                    }
+                } catch (SystemException e) {
+                    return;
+                }
+            }
+        });
+    }
+
+    /**
+     * Holder for suspended resources.
+     * Used internally by <code>suspend</code> and <code>resume</code>.
+     */
+    private static class SuspendedResourcesHolder {
+
+        private final Object suspendedResources;
+
+        private final List<?> suspendedSynchronizations;
+
+        private final String name;
+
+        private final boolean readOnly;
+
+        public SuspendedResourcesHolder(
+                Object suspendedResources, List<?> suspendedSynchronizations, String name, boolean readOnly) {
+
+            this.suspendedResources = suspendedResources;
+            this.suspendedSynchronizations = suspendedSynchronizations;
+            this.name = name;
+            this.readOnly = readOnly;
+        }
+
+        public Object getSuspendedResources() {
+            return suspendedResources;
+        }
+
+        public List<?> getSuspendedSynchronizations() {
+            return suspendedSynchronizations;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean isReadOnly() {
+            return readOnly;
+        }
+    }
+
+}

Added: aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/TransactionManagerService.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/TransactionManagerService.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/TransactionManagerService.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-manager/src/main/java/org/apache/aries/transaction/TransactionManagerService.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction;
+
+import java.util.Dictionary;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Properties;
+import java.io.File;
+import java.io.IOException;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.UserTransaction;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.apache.geronimo.transaction.manager.GeronimoTransactionManager;
+import org.apache.geronimo.transaction.manager.TransactionLog;
+import org.apache.geronimo.transaction.manager.XidFactory;
+import org.apache.geronimo.transaction.manager.XidFactoryImpl;
+import org.apache.geronimo.transaction.manager.RecoverableTransactionManager;
+import org.apache.geronimo.transaction.log.HOWLLog;
+import org.apache.geronimo.transaction.log.UnrecoverableLog;
+import org.objectweb.howl.log.LogConfigurationException;
+
+/**
+ */
+public class TransactionManagerService {
+
+    public static final String TRANSACTION_TIMEOUT = "aries.transaction.timeout";
+    public static final String RECOVERABLE = "aries.transaction.recoverable";
+    public static final String HOWL_BUFFER_CLASS_NAME = "aries.transaction.howl.bufferClassName";
+    public static final String HOWL_BUFFER_SIZE = "aries.transaction.howl.bufferSize";
+    public static final String HOWL_CHECKSUM_ENABLED = "aries.transaction.howl.checksumEnabled";
+    public static final String HOWL_ADLER32_CHECKSUM = "aries.transaction.howl.adler32Checksum";
+    public static final String HOWL_FLUSH_SLEEP_TIME = "aries.transaction.howl.flushSleepTime";
+    public static final String HOWL_LOG_FILE_EXT = "aries.transaction.howl.logFileExt";
+    public static final String HOWL_LOG_FILE_NAME = "aries.transaction.howl.logFileName";
+    public static final String HOWL_MAX_BLOCKS_PER_FILE = "aries.transaction.howl.maxBlocksPerFile";
+    public static final String HOWL_MAX_LOG_FILES = "aries.transaction.howl.maxLogFiles";
+    public static final String HOWL_MAX_BUFFERS = "aries.transaction.howl.maxBuffers";
+    public static final String HOWL_MIN_BUFFERS = "aries.transaction.howl.minBuffers";
+    public static final String HOWL_THREADS_WAITING_FORCE_THRESHOLD = "aries.transaction.howl.threadsWaitingForceThreshold";
+    public static final String HOWL_LOG_FILE_DIR = "aries.transaction.howl.logFileDir";
+
+    public static final int DEFAULT_TRANSACTION_TIMEOUT = 600; // 600 seconds -> 10 minutes
+    public static final boolean DEFAULT_RECOVERABLE = false;   // not recoverable by default
+
+    private static final String PLATFORM_TRANSACTION_MANAGER_CLASS = "org.springframework.transaction.PlatformTransactionManager";
+
+    private final String pid;
+    private final Dictionary properties;
+    private final BundleContext bundleContext;
+    private boolean useSpring;
+    private GeronimoTransactionManager transactionManager;
+    private TransactionLog transactionLog;
+    private ServiceRegistration serviceRegistration;
+
+    public TransactionManagerService(String pid, Dictionary properties, BundleContext bundleContext) throws ConfigurationException {
+        this.pid = pid;
+        this.properties = properties;
+        this.bundleContext = bundleContext;
+        // Transaction timeout
+        int transactionTimeout = getInt(TRANSACTION_TIMEOUT, DEFAULT_TRANSACTION_TIMEOUT);
+        if (transactionTimeout <= 0) {
+            throw new ConfigurationException(TRANSACTION_TIMEOUT, "Property " + TRANSACTION_TIMEOUT + " must be > 0");
+        }
+        // XID factory
+        XidFactory xidFactory = new XidFactoryImpl(pid.getBytes());
+        // Transaction log
+        if (getBool(RECOVERABLE, DEFAULT_RECOVERABLE)) {
+            String bufferClassName = getString(HOWL_BUFFER_CLASS_NAME, "org.objectweb.howl.log.BlockLogBuffer");
+            int bufferSizeKBytes = getInt(HOWL_BUFFER_SIZE, 32);
+            if (bufferSizeKBytes < 1 || bufferSizeKBytes > 32) {
+                throw new ConfigurationException(HOWL_BUFFER_SIZE, "bufferSize must be between 1 and 32");
+            }
+            boolean checksumEnabled = getBool(HOWL_CHECKSUM_ENABLED, true);
+            boolean adler32Checksum = getBool(HOWL_ADLER32_CHECKSUM, true);
+            int flushSleepTimeMilliseconds = getInt(HOWL_FLUSH_SLEEP_TIME, 50);
+            String logFileExt = getString(HOWL_LOG_FILE_EXT, "log");
+            String logFileName = getString(HOWL_LOG_FILE_NAME, "transaction");
+            int maxBlocksPerFile = getInt(HOWL_MAX_BLOCKS_PER_FILE, -1);
+            int maxLogFiles = getInt(HOWL_MAX_LOG_FILES, 2);
+            int minBuffers = getInt(HOWL_MIN_BUFFERS, 4);
+            if (minBuffers < 0) {
+                throw new ConfigurationException(HOWL_MIN_BUFFERS, "minBuffers must be > 0");
+            }
+            int maxBuffers = getInt(HOWL_MAX_BUFFERS, 0);
+            if (maxBuffers > 0 && minBuffers < maxBuffers) {
+                throw new ConfigurationException(HOWL_MAX_BUFFERS, "minBuffers must be <= maxBuffers");
+            }
+            int threadsWaitingForceThreshold = getInt(HOWL_THREADS_WAITING_FORCE_THRESHOLD, -1);
+            String logFileDir = getString(HOWL_LOG_FILE_DIR, null);
+            if (logFileDir == null || logFileDir.length() == 0 || !new File(logFileDir).isAbsolute()) {
+                throw new ConfigurationException(HOWL_LOG_FILE_DIR, "Property should be set to an absolute directory");
+            }
+            try {
+                transactionLog = new HOWLLog(bufferClassName,
+                                             bufferSizeKBytes,
+                                             checksumEnabled,
+                                             adler32Checksum,
+                                             flushSleepTimeMilliseconds,
+                                             logFileDir,
+                                             logFileExt,
+                                             logFileName,
+                                             maxBlocksPerFile,
+                                             maxBuffers,
+                                             maxLogFiles,
+                                             minBuffers,
+                                             threadsWaitingForceThreshold,
+                                             xidFactory != null ? xidFactory : new XidFactoryImpl(),
+                                             null);
+            } catch (LogConfigurationException e) {
+                // This should not really happen as we've checked properties earlier
+                throw new ConfigurationException(null, null, e);
+            } catch (IOException e) {
+                // This should not really happen as we've checked properties earlier
+                throw new ConfigurationException(null, null, e);
+            }
+        } else {
+            transactionLog =  new UnrecoverableLog();
+        }
+        // Create transaction manager
+        try {
+            try {
+                transactionManager = new SpringTransactionManagerCreator().create(transactionTimeout, xidFactory, transactionLog);
+                useSpring = true;
+            } catch (NoClassDefFoundError e) {
+                transactionManager = new GeronimoTransactionManager(transactionTimeout, xidFactory, transactionLog);
+            }
+        } catch (XAException e) {
+            throw new RuntimeException("Error recovering transaction log", e);
+        }
+    }
+
+    public void start() throws Exception {
+        if (transactionLog instanceof HOWLLog) {
+            ((HOWLLog) transactionLog).doStart();
+        }
+        List<String> clazzes = new ArrayList<String>();
+        clazzes.add(TransactionManager.class.getName());
+        clazzes.add(TransactionSynchronizationRegistry.class.getName());
+        clazzes.add(UserTransaction.class.getName());
+        clazzes.add(RecoverableTransactionManager.class.getName());
+        if (useSpring) {
+            clazzes.add(PLATFORM_TRANSACTION_MANAGER_CLASS);
+        }
+        serviceRegistration = bundleContext.registerService(clazzes.toArray(new String[clazzes.size()]), transactionManager, new Properties());
+    }
+
+    public void close() throws Exception {
+        if (serviceRegistration != null) {
+            serviceRegistration.unregister();
+        }
+        if (transactionLog instanceof HOWLLog) {
+            ((HOWLLog) transactionLog).doStop();
+        }
+    }
+
+    private String getString(String property, String dflt) throws ConfigurationException {
+        String value = (String) properties.get(property);
+        if (value != null) {
+            return value;
+        }
+        return dflt;
+    }
+
+    private int getInt(String property, int dflt) throws ConfigurationException {
+        String value = (String) properties.get(property);
+        if (value != null) {
+            try {
+                return Integer.parseInt(value);
+            } catch (Exception e) {
+                throw new ConfigurationException(property, "Error parsing " + property + "(" + value + ") property as an integer", e);
+            }
+        }
+        return dflt;
+    }
+
+    private boolean getBool(String property, boolean dflt) throws ConfigurationException {
+        String value = (String) properties.get(property);
+        if (value != null) {
+            try {
+                return Boolean.parseBoolean(value);
+            } catch (Exception e) {
+                throw new ConfigurationException(property, "Error parsing " + property + "(" + value + ") property as a boolean", e);
+            }
+        }
+        return dflt;
+    }
+
+    /**
+     * We use an inner static class to decouple this class from the spring-tx classes
+     * in order to not have NoClassDefFoundError if those are not present.
+     */
+    public static class SpringTransactionManagerCreator {
+
+        public GeronimoTransactionManager create(int defaultTransactionTimeoutSeconds, XidFactory xidFactory, TransactionLog transactionLog) throws XAException {
+            return new GeronimoPlatformTransactionManager(defaultTransactionTimeoutSeconds, xidFactory, transactionLog);
+        }
+
+    }
+}

Added: aries/tags/transaction-0.1-incubating/transaction-testbundle/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testbundle/pom.xml?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testbundle/pom.xml (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testbundle/pom.xml Sun Feb 27 18:37:11 2011
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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">
+  <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.transaction</groupId>
+        <artifactId>transaction</artifactId>
+        <version>0.1-incubating</version>
+    </parent>
+  <groupId>org.apache.aries.transaction</groupId>
+  <artifactId>org.apache.aries.transaction.testbundle</artifactId>
+  <packaging>bundle</packaging>
+  <name>Apache Aries Transaction Test Bundle</name>
+
+  <properties>
+    <aries.osgi.export.pkg>
+      org.apache.aries.transaction.test
+    </aries.osgi.export.pkg>
+    <aries.osgi.private.pkg>
+      org.apache.aries.transaction.test.impl
+    </aries.osgi.private.pkg>
+  </properties>
+
+</project>

Added: aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/TestBean.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/TestBean.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/TestBean.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/TestBean.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction.test;
+
+import java.sql.SQLException;
+
+/**
+ * This interface is used by the transactions integration tests
+ *
+ */
+public interface TestBean {
+    public void insertRow(String name, int value) throws SQLException;
+    
+    public void insertRow(String name, int value, boolean delegate) throws SQLException;
+    
+    public void insertRow(String name, int value, Exception e) throws SQLException;
+
+    public int countRows() throws SQLException;
+    
+    public void throwApplicationException() throws SQLException;
+    
+    public void throwRuntimeException();
+}

Added: aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/TestBeanImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/TestBeanImpl.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/TestBeanImpl.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/TestBeanImpl.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction.test.impl;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.DataSource;
+
+import org.apache.aries.transaction.test.TestBean;
+
+public class TestBeanImpl implements TestBean {
+    private DataSource xads;
+
+    private DataSource ds;
+
+    private String user;
+
+    private String password;
+    
+    private TestBean bean;
+
+    public TestBeanImpl() {
+    }
+
+    public void initialize() {
+        Connection conn = null;
+        Statement stmt = null;
+
+        try {
+            conn = ds.getConnection(user, password);
+            conn.setAutoCommit(true);
+            stmt = conn.createStatement();
+            stmt.executeUpdate("DROP TABLE TESTTABLE");
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+        finally {
+            try {
+                if (stmt != null)
+                    stmt.close();
+            } catch (SQLException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            try {
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        try {
+            conn = ds.getConnection(user, password);
+            conn.setAutoCommit(true);
+            stmt = conn.createStatement();
+            stmt.executeUpdate("CREATE TABLE TESTTABLE (NAME VARCHAR(64), VALUE INTEGER, PRIMARY KEY(NAME, VALUE))");
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+        finally {
+            try {
+                if (stmt != null)
+                    stmt.close();
+            } catch (SQLException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+
+            try {
+                if (conn != null)
+                    conn.close();
+            } catch (SQLException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void insertRow(String name, int value) throws SQLException {
+        insertRow(name, value, false);
+    }
+
+    public void insertRow(String name, int value, Exception e) throws SQLException {
+        insertRow(name, value, false);
+        
+        if (e instanceof SQLException)
+            throw (SQLException) e;
+        else if (e instanceof RuntimeException)
+            throw (RuntimeException) e;
+    }
+
+    public void insertRow(String name, int value, boolean delegate) throws SQLException {
+        if (delegate) {
+            bean.insertRow(name, value);
+        }
+        else {
+            Connection conn = null;
+            PreparedStatement stmt = null;
+
+            try {
+                conn = xads.getConnection(user, password);
+                stmt = conn.prepareStatement("INSERT INTO TESTTABLE VALUES (?, ?)");
+                stmt.setString(1, name);
+                stmt.setInt(2, value);
+                stmt.executeUpdate();
+            }
+            finally {
+                if (stmt != null)
+                    stmt.close();
+
+                if (conn != null)
+                    conn.close();
+            }
+        }
+    }
+
+    public int countRows() throws SQLException {
+        Connection conn = null;
+        PreparedStatement stmt = null;
+        ResultSet rs = null;
+        int count = -1;
+
+        try {
+            conn = ds.getConnection(user, password);
+            stmt = conn.prepareStatement("SELECT * FROM TESTTABLE", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+            rs = stmt.executeQuery();
+            rs.last();
+            count = rs.getRow();
+        }
+        finally {
+            if (rs != null)
+                rs.close();
+
+            if (stmt != null)
+                stmt.close();
+
+            if (conn != null)
+                conn.close();
+        }
+
+        return count;
+    }
+
+    public void throwApplicationException() throws SQLException {
+        throw new SQLException("Test exception");
+    }
+
+    public void throwRuntimeException() {
+        throw new RuntimeException("Test exception");
+    }
+
+    public void setEnlistingDataSource(DataSource xads) {
+        this.xads = xads;
+    }
+
+    public void setDataSource(DataSource ds) {
+        this.ds = ds;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+    
+    public void setTestBean(TestBean bean) {
+        this.bean = bean;
+    }
+}

Added: aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml Sun Feb 27 18:37:11 2011
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ 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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
+           default-activation="lazy">
+
+   <bean id="notSupportedBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="*" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+       <property name="testBean" ref="mandatoryBeanImpl"/>
+   </bean>
+   
+   <service id="notSupportedBean" ref="notSupportedBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="NotSupported"/>
+       </service-properties>
+   </service>
+
+   <bean id="requiredBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="insertRow throw*" value="Required"/>
+       <tx:transaction method="countRows" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+   </bean>
+   
+   <service id="requiredBean" ref="requiredBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="Required"/>
+       </service-properties>
+   </service>
+
+   <bean id="supportsBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="*" value="Supports"/>
+       <tx:transaction method="countRows" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+       <property name="testBean" ref="mandatoryBeanImpl"/>
+   </bean>
+   
+   <service id="supportsBean" ref="supportsBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="Supports"/>
+       </service-properties>
+   </service>
+
+   <bean id="requiresNewBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="insertRow throw*" value="RequiresNew"/>
+       <tx:transaction method="countRows" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+   </bean>
+   
+   <service id="requiresNewBean" ref="requiresNewBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="RequiresNew"/>
+       </service-properties>
+   </service>
+
+   <bean id="mandatoryBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="insertRow throw*" value="Mandatory"/>
+       <tx:transaction method="countRows" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+   </bean>
+   
+   <service id="mandatoryBean" ref="mandatoryBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="Mandatory"/>
+       </service-properties>
+   </service>
+
+   <bean id="neverBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="insertRow" value="Never"/>
+       <tx:transaction method="countRows" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+       <property name="testBean" ref="mandatoryBeanImpl"/>
+   </bean>
+   
+   <service id="neverBean" ref="neverBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="Never"/>
+       </service-properties>
+   </service>
+
+   <bean id="invalidBeanImpl" class="org.apache.aries.transaction.test.impl.TestBeanImpl" init-method="initialize">
+       <tx:transaction method="ins*" value="Never"/>
+       <tx:transaction method="*Row" value="NotSupported"/>
+       <property name="enlistingDataSource" ref="enlistingDataSource"/>
+       <property name="dataSource" ref="dataSource"/>
+       <property name="user" value="user"/>
+       <property name="password" value="password"/>
+   </bean>
+   
+   <service id="invalidBean" ref="invalidBeanImpl" interface="org.apache.aries.transaction.test.TestBean">
+       <service-properties>
+           <entry key="tranStrategy" value="Invalid"/>
+       </service-properties>
+   </service>
+   
+   <reference id="enlistingDataSource" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=jdbc/xads)"/>
+   
+   <reference id="dataSource" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=jdbc/nonxads)"/>
+</blueprint>

Added: aries/tags/transaction-0.1-incubating/transaction-testds/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testds/pom.xml?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testds/pom.xml (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testds/pom.xml Sun Feb 27 18:37:11 2011
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+	<!--
+		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">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.aries.transaction</groupId>
+		<artifactId>transaction</artifactId>
+		<version>0.1-incubating</version>
+	</parent>
+	<groupId>org.apache.aries.transaction</groupId>
+	<artifactId>org.apache.aries.transaction.testds</artifactId>
+	<name>Apache Aries Transaction Test Datasource Configuration</name>
+	<packaging>bundle</packaging>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+		</dependency>
+	</dependencies>
+</project>

Added: aries/tags/transaction-0.1-incubating/transaction-testds/src/main/resources/OSGI-INF/blueprint/dataSource.xml
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-testds/src/main/resources/OSGI-INF/blueprint/dataSource.xml?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-testds/src/main/resources/OSGI-INF/blueprint/dataSource.xml (added)
+++ aries/tags/transaction-0.1-incubating/transaction-testds/src/main/resources/OSGI-INF/blueprint/dataSource.xml Sun Feb 27 18:37:11 2011
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            default-activation="lazy">
+  
+  <bean id="derbyXADataSource" class="org.apache.derby.jdbc.EmbeddedXADataSource">
+    <property name="databaseName" value="TESTDB"/>
+    <property name="createDatabase" value="create"/>
+  </bean>
+
+  <service ref="derbyXADataSource" interface="javax.sql.XADataSource">
+   <service-properties>
+     <entry key="osgi.jndi.service.name" value="jdbc/xads"/>
+   </service-properties>
+  </service>
+  
+  <bean id="derbyDataSource" class="org.apache.derby.jdbc.EmbeddedDataSource">
+    <property name="databaseName" value="TESTDB"/>
+    <property name="createDatabase" value="create"/>
+  </bean>
+  
+  <service ref="derbyDataSource" interface="javax.sql.DataSource">
+   <service-properties>
+     <entry key="osgi.jndi.service.name" value="jdbc/nonxads"/>
+   </service-properties>
+  </service>
+</blueprint>
\ No newline at end of file

Added: aries/tags/transaction-0.1-incubating/transaction-wrappers/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-wrappers/pom.xml?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-wrappers/pom.xml (added)
+++ aries/tags/transaction-0.1-incubating/transaction-wrappers/pom.xml Sun Feb 27 18:37:11 2011
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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">
+  <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.transaction</groupId>
+        <artifactId>transaction</artifactId>
+        <version>0.1-incubating</version>
+    </parent>
+  <groupId>org.apache.aries.transaction</groupId>
+  <artifactId>org.apache.aries.transaction.wrappers</artifactId>
+  <name>Apache Aries Transaction Enlisting JDBC Datasource</name>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <aries.osgi.export.pkg>
+      !org.apache.aries.transaction.jdbc
+    </aries.osgi.export.pkg>
+    <aries.osgi.private.pkg>
+      org.apache.aries.transaction.jdbc
+    </aries.osgi.private.pkg>
+    <aries.osgi.activator>
+      org.apache.aries.transaction.jdbc.Activator
+    </aries.osgi.activator>
+  </properties>
+
+  <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.transaction</groupId>
+            <artifactId>org.apache.aries.transaction.manager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+  </dependencies>
+
+</project>

Added: aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/Activator.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/Activator.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/Activator.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/Activator.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction.jdbc;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import java.util.Hashtable;
+import javax.sql.DataSource;
+import javax.sql.XADataSource;
+import javax.transaction.TransactionManager;
+
+public class Activator implements BundleActivator, ServiceTrackerCustomizer, ServiceListener
+{
+  private TransactionManager tm;
+  private ServiceTracker t;
+  private ServiceReference ref;
+  private BundleContext context;
+  
+  public void start(BundleContext ctx)
+  {
+    context = ctx;
+    
+    t = new ServiceTracker(ctx, javax.sql.XADataSource.class.getName(), this);
+    
+    try {
+      ctx.addServiceListener(this, "(objectClass=javax.transaction.TransactionManager)");
+    } catch (InvalidSyntaxException e) {
+    }
+    ref = ctx.getServiceReference(TransactionManager.class.getName());
+    if (ref != null) {
+      tm = (TransactionManager) ctx.getService(ref);
+    }
+    
+    if (tm != null) {
+      t.open();
+    }
+  }
+
+  public void stop(BundleContext ctx)
+  {
+      // it is possible these are not cleaned by serviceChanged method when the
+      // tm service is still active
+      if (t != null) {
+          t.close();
+      }
+      if (ref != null) {
+          context.ungetService(ref);
+      }
+  }
+
+  public Object addingService(ServiceReference ref)
+  {
+    BundleContext ctx = ref.getBundle().getBundleContext();
+
+    Hashtable<String, Object> map = new Hashtable<String, Object>();
+    for (String key : ref.getPropertyKeys()) {
+      map.put(key, ref.getProperty(key));
+    }
+    map.put("aries.xa.aware", "true");
+
+    XADatasourceEnlistingWrapper wrapper = new XADatasourceEnlistingWrapper();
+    wrapper.setTxManager(tm);
+    wrapper.setDataSource((XADataSource) ctx.getService(ref));
+
+    ServiceRegistration reg = ctx.registerService(DataSource.class.getName(), wrapper, map); 
+
+    return reg;
+  }
+ 
+  public void modifiedService(ServiceReference ref, Object service)
+  {
+    ServiceRegistration reg = (ServiceRegistration) service;
+    
+    Hashtable<String, Object> map = new Hashtable<String, Object>();
+    for (String key : ref.getPropertyKeys()) {
+      map.put(key, ref.getProperty(key));
+    }
+    map.put("aries.xa.aware", "true");
+
+    reg.setProperties(map);
+  }
+
+  public void removedService(ServiceReference ref, Object service)
+  {
+    ((ServiceRegistration)service).unregister();
+  }
+
+  public void serviceChanged(ServiceEvent event)
+  {
+    if (event.getType() == ServiceEvent.REGISTERED && tm == null) {
+      ref = event.getServiceReference();
+      tm = (TransactionManager) context.getService(ref);
+      
+      if (tm == null) ref = null;
+      else t.open();
+    } else if (event.getType() == ServiceEvent.UNREGISTERING && tm != null &&
+        ref.getProperty("service.id").equals(event.getServiceReference().getProperty("service.id"))) {
+      t.close();
+      context.ungetService(ref);
+      ref = null;
+      tm = null;
+    }
+  }
+}

Added: aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/ConnectionWrapper.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/ConnectionWrapper.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/ConnectionWrapper.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/ConnectionWrapper.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,312 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction.jdbc;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.XAConnection;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+/**
+ * This class is a wrapper around a {@link Connection} that performs
+ * enlistment/delistment of an {@link XAResource} from a transaction.
+ * 
+ * @see XADatasourceEnlistingWrapper
+ */
+public class ConnectionWrapper implements Connection {
+    private Connection connection;
+    
+    private XAConnection xaConnection;
+    
+    private TransactionManager tm;
+    
+    public ConnectionWrapper(XAConnection xaConnection, TransactionManager tm) {
+        try {
+            this.xaConnection = xaConnection;
+            this.tm = tm;
+            this.connection = xaConnection.getConnection();
+            
+            if (tm.getStatus() == Status.STATUS_ACTIVE) {
+                Transaction tx = tm.getTransaction();
+                tx.enlistResource(xaConnection.getXAResource());
+            }
+        } catch (Exception e) {
+            try {
+                if (tm != null)
+                    tm.setRollbackOnly();
+            } catch (IllegalStateException e1) {
+                e1.printStackTrace();
+            } catch (SystemException e1) {
+                e1.printStackTrace();
+            }
+        }
+    }
+
+    public void clearWarnings() throws SQLException {
+        connection.clearWarnings();
+    }
+
+    public void close() throws SQLException {
+        try {
+            if (tm.getStatus() == Status.STATUS_ACTIVE) {
+                Transaction tx = tm.getTransaction();
+                tx.delistResource(xaConnection.getXAResource(), XAResource.TMSUCCESS);
+            }
+        } catch (Exception e) {
+            try {
+                if (tm != null)
+                    tm.setRollbackOnly();
+            } catch (IllegalStateException e1) {
+                e1.printStackTrace();
+            } catch (SystemException e1) {
+                e1.printStackTrace();
+            }
+        }
+        
+        connection.close();
+    }
+
+    public void commit() throws SQLException {
+        connection.commit();
+    }
+
+    public Array createArrayOf(String typeName, Object[] elements)
+            throws SQLException {
+        return connection.createArrayOf(typeName, elements);
+    }
+
+    public Blob createBlob() throws SQLException {
+        return connection.createBlob();
+    }
+
+    public Clob createClob() throws SQLException {
+        return connection.createClob();
+    }
+
+    public NClob createNClob() throws SQLException {
+        return connection.createNClob();
+    }
+
+    public SQLXML createSQLXML() throws SQLException {
+        return connection.createSQLXML();
+    }
+
+    public Statement createStatement() throws SQLException {
+        return connection.createStatement();
+    }
+
+    public Statement createStatement(int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
+        return connection.createStatement(resultSetType, resultSetConcurrency,
+                resultSetHoldability);
+    }
+
+    public Statement createStatement(int resultSetType, int resultSetConcurrency)
+            throws SQLException {
+        return connection.createStatement(resultSetType, resultSetConcurrency);
+    }
+
+    public Struct createStruct(String typeName, Object[] attributes)
+            throws SQLException {
+        return connection.createStruct(typeName, attributes);
+    }
+
+    public boolean getAutoCommit() throws SQLException {
+        return connection.getAutoCommit();
+    }
+
+    public String getCatalog() throws SQLException {
+        return connection.getCatalog();
+    }
+
+    public Properties getClientInfo() throws SQLException {
+        return connection.getClientInfo();
+    }
+
+    public String getClientInfo(String name) throws SQLException {
+        return connection.getClientInfo(name);
+    }
+
+    public int getHoldability() throws SQLException {
+        return connection.getHoldability();
+    }
+
+    public DatabaseMetaData getMetaData() throws SQLException {
+        return connection.getMetaData();
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+        return connection.getTransactionIsolation();
+    }
+
+    public Map<String, Class<?>> getTypeMap() throws SQLException {
+        return connection.getTypeMap();
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+        return connection.getWarnings();
+    }
+
+    public boolean isClosed() throws SQLException {
+        return connection.isClosed();
+    }
+
+    public boolean isReadOnly() throws SQLException {
+        return connection.isReadOnly();
+    }
+
+    public boolean isValid(int timeout) throws SQLException {
+        return connection.isValid(timeout);
+    }
+
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return connection.isWrapperFor(iface);
+    }
+
+    public String nativeSQL(String sql) throws SQLException {
+        return connection.nativeSQL(sql);
+    }
+
+    public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
+        return connection.prepareCall(sql, resultSetType, resultSetConcurrency,
+                resultSetHoldability);
+    }
+
+    public CallableStatement prepareCall(String sql, int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+        return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+    }
+
+    public CallableStatement prepareCall(String sql) throws SQLException {
+        return connection.prepareCall(sql);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+            int resultSetConcurrency, int resultSetHoldability)
+            throws SQLException {
+        return connection.prepareStatement(sql, resultSetType,
+                resultSetConcurrency, resultSetHoldability);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+            int resultSetConcurrency) throws SQLException {
+        return connection.prepareStatement(sql, resultSetType,
+                resultSetConcurrency);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+            throws SQLException {
+        return connection.prepareStatement(sql, autoGeneratedKeys);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+            throws SQLException {
+        return connection.prepareStatement(sql, columnIndexes);
+    }
+
+    public PreparedStatement prepareStatement(String sql, String[] columnNames)
+            throws SQLException {
+        return connection.prepareStatement(sql, columnNames);
+    }
+
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+        return connection.prepareStatement(sql);
+    }
+
+    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        connection.releaseSavepoint(savepoint);
+    }
+
+    public void rollback() throws SQLException {
+        connection.rollback();
+    }
+
+    public void rollback(Savepoint savepoint) throws SQLException {
+        connection.rollback(savepoint);
+    }
+
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        connection.setAutoCommit(autoCommit);
+    }
+
+    public void setCatalog(String catalog) throws SQLException {
+        connection.setCatalog(catalog);
+    }
+
+    public void setClientInfo(Properties properties)
+            throws SQLClientInfoException {
+        connection.setClientInfo(properties);
+    }
+
+    public void setClientInfo(String name, String value)
+            throws SQLClientInfoException {
+        connection.setClientInfo(name, value);
+    }
+
+    public void setHoldability(int holdability) throws SQLException {
+        connection.setHoldability(holdability);
+    }
+
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        connection.setReadOnly(readOnly);
+    }
+
+    public Savepoint setSavepoint() throws SQLException {
+        return connection.setSavepoint();
+    }
+
+    public Savepoint setSavepoint(String name) throws SQLException {
+        return connection.setSavepoint(name);
+    }
+
+    public void setTransactionIsolation(int level) throws SQLException {
+        connection.setTransactionIsolation(level);
+    }
+
+    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        connection.setTypeMap(map);
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return connection.unwrap(iface);
+    }
+}

Added: aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/XADatasourceEnlistingWrapper.java
URL: http://svn.apache.org/viewvc/aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/XADatasourceEnlistingWrapper.java?rev=1075109&view=auto
==============================================================================
--- aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/XADatasourceEnlistingWrapper.java (added)
+++ aries/tags/transaction-0.1-incubating/transaction-wrappers/src/main/java/org/apache/aries/transaction/jdbc/XADatasourceEnlistingWrapper.java Sun Feb 27 18:37:11 2011
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+package org.apache.aries.transaction.jdbc;
+
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import javax.transaction.TransactionManager;
+
+/**
+ * This class allows JDBC XA data sources to participate in global transactions,
+ * via the {@link ConnectionWrapper} that is returned. The only service provided
+ * is enlistment/delistment of the associated {@link XAResource} in transactions.
+ * Important consideration such as connection pooling and error handling are
+ * completely ignored.
+ *
+ */
+public class XADatasourceEnlistingWrapper implements DataSource, Serializable {
+    /** The serial version UID */
+    private static final long serialVersionUID = -3200389791205501228L;
+
+    private XADataSource wrappedDS;
+    
+    private transient TransactionManager tm;
+    
+    public Connection getConnection() throws SQLException
+    {
+      XAConnection xaConn = wrappedDS.getXAConnection();
+      Connection conn = getEnlistedConnection(xaConn);
+      
+      return conn;
+    }
+
+    public Connection getConnection(String username, String password) throws SQLException
+    {
+      XAConnection xaConn = wrappedDS.getXAConnection(username, password);
+      Connection conn = getEnlistedConnection(xaConn);
+      
+      return conn;
+    }
+
+    public PrintWriter getLogWriter() throws SQLException
+    {
+      return wrappedDS.getLogWriter();
+    }
+
+    public int getLoginTimeout() throws SQLException
+    {
+      return wrappedDS.getLoginTimeout();
+    }
+
+    public void setLogWriter(PrintWriter out) throws SQLException
+    {
+      wrappedDS.setLogWriter(out);
+    }
+
+    public void setLoginTimeout(int seconds) throws SQLException
+    {
+      wrappedDS.setLoginTimeout(seconds);
+    }
+
+    private Connection getEnlistedConnection(XAConnection xaConn) throws SQLException
+    {
+        return new ConnectionWrapper(xaConn, tm);
+    }
+
+    public void setDataSource(XADataSource dsToWrap)
+    {
+      wrappedDS = dsToWrap;
+    }
+
+
+    public void setTxManager(TransactionManager txMgr)
+    {
+      tm = txMgr;
+    }
+    
+    @Override
+    public boolean equals(Object other)
+    {
+      if (other == this) return true;
+      if (other == null) return false;
+      
+      if (other.getClass() == this.getClass()) {
+        return wrappedDS.equals(((XADatasourceEnlistingWrapper)other).wrappedDS);
+      }
+      
+      return false;
+    }
+    
+    @Override
+    public int hashCode()
+    {
+      return wrappedDS.hashCode();
+    }
+
+    public boolean isWrapperFor(Class<?> arg0) throws SQLException
+    {
+      return false;
+    }
+
+    public <T> T unwrap(Class<T> arg0) throws SQLException
+    {
+      return null;
+    }
+}



Mime
View raw message