You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by je...@apache.org on 2010/08/18 06:12:59 UTC

svn commit: r986561 [5/13] - in /ode/trunk: ./ axis2-war/ axis2-war/src/main/assembly/ axis2-war/src/test/java/org/apache/ode/axis2/ axis2-war/src/test/java/org/apache/ode/axis2/instancecleanup/ axis2-war/src/test/java/org/apache/ode/bpel/dao/ axis2-wa...

Modified: ode/trunk/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java (original)
+++ ode/trunk/bpel-test/src/main/java/org/apache/ode/test/BPELTestAbstract.java Wed Aug 18 04:12:49 2010
@@ -23,38 +23,26 @@ import java.io.FileInputStream;
 import java.io.InputStream;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.sql.Connection;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.Callable;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.geronimo.connector.outbound.GenericConnectionManager;
-import org.apache.geronimo.connector.outbound.connectionmanagerconfig.LocalTransactions;
-import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
-import org.apache.geronimo.connector.outbound.connectionmanagerconfig.SinglePool;
-import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionSupport;
-import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTracker;
-import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinator;
-import org.apache.geronimo.transaction.manager.RecoverableTransactionManager;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-import javax.resource.spi.ConnectionManager;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
 import javax.xml.namespace.QName;
 
-import org.apache.derby.jdbc.EmbeddedXADataSource;
 import org.apache.ode.bpel.common.evt.DebugBpelEventListener;
-import org.apache.ode.bpel.dao.BpelDAOConnectionFactory;
 import org.apache.ode.bpel.engine.BpelServerImpl;
+import org.apache.ode.bpel.iapi.EndpointReference;
+import org.apache.ode.bpel.iapi.EndpointReferenceContext;
 import org.apache.ode.bpel.iapi.Message;
 import org.apache.ode.bpel.iapi.MessageExchange;
 import org.apache.ode.bpel.iapi.MyRoleMessageExchange;
@@ -64,30 +52,27 @@ import org.apache.ode.bpel.iapi.ProcessS
 import org.apache.ode.bpel.iapi.MessageExchange.Status;
 import org.apache.ode.bpel.iapi.MyRoleMessageExchange.CorrelationStatus;
 import org.apache.ode.bpel.memdao.BpelDAOConnectionFactoryImpl;
-import org.apache.ode.il.EmbeddedGeronimoFactory;
+import org.apache.ode.dao.bpel.BpelDAOConnectionFactory;
+import org.apache.ode.dao.store.ConfStoreDAOConnectionFactory;
+import org.apache.ode.il.MockScheduler;
 import org.apache.ode.il.config.OdeConfigProperties;
+import org.apache.ode.il.dbutil.Database;
 import org.apache.ode.store.ProcessConfImpl;
 import org.apache.ode.store.ProcessStoreImpl;
 import org.apache.ode.utils.DOMUtils;
 import org.apache.ode.utils.GUID;
-import org.apache.ode.scheduler.simple.SimpleScheduler;
-import org.apache.ode.scheduler.simple.JdbcDelegate;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.w3c.dom.Element;
-import java.util.concurrent.*;
 
 public abstract class BPELTestAbstract {
-    public static final long WAIT_BEFORE_INVOKE_TIMEOUT = 2000;
-
-    private static final String SHOW_EVENTS_ON_CONSOLE = "no";
+	public static final long WAIT_BEFORE_INVOKE_TIMEOUT = 2000;
+	
+	private static final String SHOW_EVENTS_ON_CONSOLE = "no";
 
     protected BpelServerImpl _server;
 
-    public static TransactionManager _txManager = null;
-    public static DataSource _dataSource = null;
-    
     protected ProcessStore store;
 
     protected MessageExchangeContextImpl mexContext;
@@ -95,12 +80,12 @@ public abstract class BPELTestAbstract {
     protected EntityManager em;
 
     protected EntityManagerFactory emf;
-    
-    protected ExecutorService executorService = Executors.newFixedThreadPool(1);
 
-    protected SimpleScheduler scheduler;
+    protected MockScheduler scheduler;
 
-    protected BpelDAOConnectionFactory _cf;
+    protected BpelDAOConnectionFactory _bcf;
+    
+    protected ConfStoreDAOConnectionFactory _scf;
 
     /** Failures that have been detected. */
     protected List<Failure> _failures;
@@ -113,54 +98,77 @@ public abstract class BPELTestAbstract {
 
     /** What's actually been deployed. */
     private List<Deployment> _deployed;
+    
+    private MockTransactionManager _txm;
+    
+    private Database _db;
 
     @Before
     public void setUp() throws Exception {
-        EmbeddedGeronimoFactory factory = new EmbeddedGeronimoFactory();
-        if (_txManager == null) {
-            _txManager = createTransactionManager();
-            _dataSource = createDataSource(false);
-            {
-                _txManager.begin();
-                try {
-                    Connection c = _dataSource.getConnection();
-                    c.prepareStatement(org.apache.commons.io.IOUtils.toString(getClass().getResourceAsStream("/scheduler-schema.sql"))).execute();
-                    c.close();
-                } catch (Exception e) {
-                    
-                }
-                _txManager.commit();
-            }
-        }
-//        try {
-//            _dataSource.getConnection();
-//        } catch (Exception e) {
-//            
-//        }
-//        createDataSource(false);
         _failures = new CopyOnWriteArrayList<Failure>();
         _server = new BpelServerImpl();
-        Properties props = getConfigProperties();
-        _server.setConfigProperties(props);
         mexContext = new MessageExchangeContextImpl();
         _deployments = new ArrayList<Deployment>();
         _invocations = new ArrayList<Invocation>();
         _deployed = new ArrayList<Deployment>();
+        
+        _txm = new MockTransactionManager();
+        Properties props = new Properties();
+        props.setProperty(OdeConfigProperties.PROP_DAOCF_STORE, "org.apache.ode.dao.hib.store.ConfStoreDAOConnectionFactoryImpl");
+         OdeConfigProperties odeProps = new OdeConfigProperties(props,"");
+		_db = new Database(odeProps);
+        _db.setTransactionManager(_txm);
+        _db.start();
+
+        if (Boolean.getBoolean("org.apache.ode.test.persistent")) {
+        	_server.setDaoConnectionFactory(_bcf);
+            scheduler = new MockScheduler() {
+                @Override
+                public void beginTransaction() {
+                    super.beginTransaction();
+                    em.getTransaction().begin();
+                }
 
-        {
-            JdbcDelegate del = new JdbcDelegate(_dataSource);
-            scheduler = new SimpleScheduler("node", del, props);
-            scheduler.setTransactionManager(_txManager);
-            _cf = new BpelDAOConnectionFactoryImpl(scheduler);
-            _server.setDaoConnectionFactory(_cf);
+                @Override
+                public void commitTransaction() {
+                    super.commitTransaction();
+                    em.getTransaction().commit();
+                }
+
+                @Override
+                public void rollbackTransaction() {
+                    super.rollbackTransaction();
+                    em.getTransaction().rollback();
+                }
+
+            };
+        } else {
+            scheduler = new MockScheduler(_txm);
+            _bcf = new BpelDAOConnectionFactoryImpl(scheduler);
+            _bcf.init(null, _txm, _txm);
+            _server.setDaoConnectionFactory(_bcf);
         }
         _server.setInMemDaoConnectionFactory(new BpelDAOConnectionFactoryImpl(scheduler));
         _server.setScheduler(scheduler);
         _server.setBindingContext(new BindingContextImpl());
         _server.setMessageExchangeContext(mexContext);
         scheduler.setJobProcessor(_server);
-        scheduler.setExecutorService(executorService);
-        store = new ProcessStoreImpl(null, _dataSource, "hib", new OdeConfigProperties(new Properties(), ""), true);
+        final EndpointReferenceContext eprContext = new EndpointReferenceContext() {
+            public EndpointReference resolveEndpointReference(Element epr) {
+                return null;
+            }
+
+            public EndpointReference convertEndpoint(QName targetType, Element sourceEndpoint) {
+                return null;
+            }
+
+            public Map getConfigLookup(EndpointReference epr) {
+                return Collections.EMPTY_MAP;
+            }
+        };
+        
+        _scf = _db.createDaoStoreCF();
+        store = new ProcessStoreImpl(eprContext, _txm, _scf);
         store.registerListener(new ProcessStoreListener() {
             public void onProcessStoreEvent(ProcessStoreEvent event) {
                 // bounce the process
@@ -173,10 +181,10 @@ public abstract class BPELTestAbstract {
                 }
             }
         });
+        _server.setConfigProperties(getConfigProperties());
         _server.registerBpelEventListener(new DebugBpelEventListener());
         _server.init();
         _server.start();
-        scheduler.start();
     }
 
     @After
@@ -198,57 +206,7 @@ public abstract class BPELTestAbstract {
         _deployed = null;
         _deployments = null;
         _invocations = null;
-        
-
-    }
 
-    protected TransactionManager createTransactionManager() throws Exception {
-        EmbeddedGeronimoFactory factory = new EmbeddedGeronimoFactory();
-        TransactionManager _txManager = factory.getTransactionManager();
-        _txManager.setTransactionTimeout(30);
-        return _txManager;
-    }
-
-    protected DataSource createDataSource(boolean shutdown) throws Exception {
-        TransactionSupport transactionSupport = LocalTransactions.INSTANCE;
-        ConnectionTracker connectionTracker = new ConnectionTrackingCoordinator();
-
-        PoolingSupport poolingSupport = new SinglePool(
-                10,
-                0,
-                1000,
-                1,
-                true,
-                false,
-                false);
-
-        ConnectionManager connectionManager = new GenericConnectionManager(
-                    transactionSupport,
-                    poolingSupport,
-                    null,
-                    connectionTracker,
-                    (RecoverableTransactionManager) _txManager,
-                    getClass().getName(),
-                    getClass().getClassLoader());
-
-            org.tranql.connector.derby.EmbeddedLocalMCF mcf = new org.tranql.connector.derby.EmbeddedLocalMCF();
-            mcf.setCreateDatabase(true);
-            mcf.setDatabaseName("target/testdb");
-            mcf.setUserName("sa");
-            mcf.setPassword("");
-            if (shutdown) {
-                mcf.setShutdownDatabase("shutdown");
-            }
-            return (DataSource) mcf.createConnectionFactory(connectionManager);
-
-//        d = org.tranql.connector.jdbc.JDBCDriverMCF();
-//        EmbeddedXADataSource ds = new EmbeddedXADataSource();
-//        ds.setCreateDatabase("create");
-//        ds.setDatabaseName("target/testdb");
-//        ds.setUser("sa");
-//        ds.setPassword("");
-//        _dataSource = ds;
-//        return _dataSource;
     }
 
     protected void negative(String deployDir) throws Throwable {
@@ -308,7 +266,7 @@ public abstract class BPELTestAbstract {
             final String operation = testProps.getProperty("operation");
 
             Boolean sequential = Boolean.parseBoolean(testProps.getProperty("sequential", "false"));
-
+            
             Invocation last = null;
             for (int i = 1; testProps.getProperty("request" + i) != null; i++) {
                 final String in = testProps.getProperty("request" + i);
@@ -324,7 +282,7 @@ public abstract class BPELTestAbstract {
     protected Invocation addInvoke(String id, QName target, String operation, String request, String responsePattern) throws Exception {
         return addInvoke(id, target, operation, request, responsePattern, null);
     }
-
+    
     protected Invocation addInvoke(String id, QName target, String operation, String request, String responsePattern, Invocation synchronizeWith)
             throws Exception {
 
@@ -448,9 +406,9 @@ public abstract class BPELTestAbstract {
             testThread.join();
 
     }
-
+    
     protected long getWaitBeforeInvokeTimeout() {
-        return WAIT_BEFORE_INVOKE_TIMEOUT;
+    	return WAIT_BEFORE_INVOKE_TIMEOUT;
     }
 
     private void failure(Object where) {
@@ -489,7 +447,7 @@ public abstract class BPELTestAbstract {
     }
 
     /**
-     * Override this to provide configuration properties for Ode extensions
+     * Override this to provide configuration properties for Ode extensions 
      * like BpelEventListeners.
      *
      * @return
@@ -569,10 +527,10 @@ public abstract class BPELTestAbstract {
 
         /** for sync invocations */
         public Invocation synchronizeWith;
-
+        
         /** checking completion */
         public boolean done = false;
-
+        
         /** Name of the operation to invoke. */
         public String operation;
 
@@ -635,11 +593,7 @@ public abstract class BPELTestAbstract {
 
         public void run() {
             try {
-                try {
-                    run2();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
+                run2();
             } finally {
                 synchronized (_invocation) {
                     _invocation.done = true;
@@ -648,16 +602,16 @@ public abstract class BPELTestAbstract {
             }
         }
         
-        public void run2() throws Exception {
-            final MyRoleMessageExchange[] mex = new MyRoleMessageExchange[1];
-            final Future[] running = new Future[1];
+        public void run2() {
+            final MyRoleMessageExchange mex;
+            final Future<MessageExchange.Status> running;
 
             // Wait for it....
             try {
                 Thread.sleep(_invocation.invokeDelayMs);
             } catch (Exception ex) {
             }
-
+            
             if (_invocation.synchronizeWith != null) {
                 synchronized (_invocation.synchronizeWith) {
                     while (!_invocation.synchronizeWith.done) {
@@ -671,42 +625,40 @@ public abstract class BPELTestAbstract {
                 }
             }
 
-            scheduler.execTransaction(new Callable<Void>() {
-                public Void call() throws Exception {
-                    try {
-                        mex[0] = _server.getEngine().createMessageExchange(new GUID().toString(), _invocation.target, _invocation.operation);
-                        mexContext.clearCurrentResponse();
-
-                        Message request = mex[0].createMessage(_invocation.requestType);
-                        request.setMessage(_invocation.request);
-                        _invocation.invokeTime = System.currentTimeMillis();
-                        running[0] = mex[0].invoke(request);
-
-                        Status status = mex[0].getStatus();
-                        CorrelationStatus cstatus = mex[0].getCorrelationStatus();
-                        if (_invocation.expectedStatus != null && !status.equals(_invocation.expectedStatus))
-                            failure(_invocation, "Unexpected message exchange status", _invocation.expectedStatus, status);
-
-                        if (_invocation.expectedCorrelationStatus != null && !cstatus.equals(_invocation.expectedCorrelationStatus))
-                            failure(_invocation, "Unexpected correlation status", _invocation.expectedCorrelationStatus, cstatus);
-                        return null;
-
-                    } catch (Exception ex) {
-                        if (_invocation.expectedInvokeException == null)
-                            failure(_invocation, "Unexpected invocation exception.", ex);
-                        else if (_invocation.expectedInvokeException.isAssignableFrom(ex.getClass()))
-                            failure(_invocation, "Unexpected invocation exception.", _invocation.expectedInvokeException, ex.getClass());
+            scheduler.beginTransaction();
+            try {
+                mex = _server.getEngine().createMessageExchange(new GUID().toString(), _invocation.target, _invocation.operation);
+                mexContext.clearCurrentResponse();
 
-                        return null;
-                    }
-                }
-            });
+                Message request = mex.createMessage(_invocation.requestType);
+                request.setMessage(_invocation.request);
+                _invocation.invokeTime = System.currentTimeMillis();
+                running = mex.invoke(request);
+
+                Status status = mex.getStatus();
+                CorrelationStatus cstatus = mex.getCorrelationStatus();
+                if (_invocation.expectedStatus != null && !status.equals(_invocation.expectedStatus))
+                    failure(_invocation, "Unexpected message exchange status", _invocation.expectedStatus, status);
+
+                if (_invocation.expectedCorrelationStatus != null && !cstatus.equals(_invocation.expectedCorrelationStatus))
+                    failure(_invocation, "Unexpected correlation status", _invocation.expectedCorrelationStatus, cstatus);
+
+            } catch (Exception ex) {
+                if (_invocation.expectedInvokeException == null)
+                    failure(_invocation, "Unexpected invocation exception.", ex);
+                else if (_invocation.expectedInvokeException.isAssignableFrom(ex.getClass()))
+                    failure(_invocation, "Unexpected invocation exception.", _invocation.expectedInvokeException, ex.getClass());
+
+                return;
+            } finally {
+                scheduler.commitTransaction();
+            }
 
             if (isFailed())
                 return;
 
             try {
-                running[0].get(_invocation.maximumWaitMs, TimeUnit.MILLISECONDS);
+                running.get(_invocation.maximumWaitMs, TimeUnit.MILLISECONDS);
             } catch (Exception ex) {
                 failure(_invocation, "Exception on future object.", ex);
                 return;
@@ -724,32 +676,32 @@ public abstract class BPELTestAbstract {
                 return;
 
             if (_invocation.expectedResponsePattern != null) {
-                scheduler.execTransaction(new Callable<Void>() {
-                    public Void call() throws Exception {
-                        Status finalstat = mex[0].getStatus();
-                        if (_invocation.expectedFinalStatus != null && !_invocation.expectedFinalStatus.equals(finalstat))
-                            if (finalstat.equals(Status.FAULT)) {
-                                failure(_invocation, "Unexpected final message exchange status", _invocation.expectedFinalStatus, "FAULT: "
-                                        + mex[0].getFault() + " | " + mex[0].getFaultExplanation());
-                            } else {
-                                failure(_invocation, "Unexpected final message exchange status", _invocation.expectedFinalStatus, finalstat);
-                            }
-
-                        if (_invocation.expectedFinalCorrelationStatus != null
-                                && !_invocation.expectedFinalCorrelationStatus.equals(mex[0].getCorrelationStatus())) {
-                            failure(_invocation, "Unexpected final correlation status", _invocation.expectedFinalCorrelationStatus, mex[0]
-                                    .getCorrelationStatus());
+                scheduler.beginTransaction();
+                try {
+                    Status finalstat = mex.getStatus();
+                    if (_invocation.expectedFinalStatus != null && !_invocation.expectedFinalStatus.equals(finalstat))
+                        if (finalstat.equals(Status.FAULT)) {
+                            failure(_invocation, "Unexpected final message exchange status", _invocation.expectedFinalStatus, "FAULT: "
+                                    + mex.getFault() + " | " + mex.getFaultExplanation());
+                        } else {
+                            failure(_invocation, "Unexpected final message exchange status", _invocation.expectedFinalStatus, finalstat);
                         }
-                        if (mex[0].getResponse() == null)
-                            failure(_invocation, "Expected response, but got none.", null);
-                        String responseStr = DOMUtils.domToString(mex[0].getResponse().getMessage());
-                        //System.out.println("=>" + responseStr);
-                        Matcher matcher = _invocation.expectedResponsePattern.matcher(responseStr);
-                        if (!matcher.matches())
-                            failure(_invocation, "Response does not match expected pattern", _invocation.expectedResponsePattern, responseStr);
-                        return null;
+
+                    if (_invocation.expectedFinalCorrelationStatus != null
+                            && !_invocation.expectedFinalCorrelationStatus.equals(mex.getCorrelationStatus())) {
+                        failure(_invocation, "Unexpected final correlation status", _invocation.expectedFinalCorrelationStatus, mex
+                                .getCorrelationStatus());
                     }
-                });
+                    if (mex.getResponse() == null)
+                        failure(_invocation, "Expected response, but got none.", null);
+                    String responseStr = DOMUtils.domToString(mex.getResponse().getMessage());
+                    //System.out.println("=>" + responseStr);
+                    Matcher matcher = _invocation.expectedResponsePattern.matcher(responseStr);
+                    if (!matcher.matches())
+                        failure(_invocation, "Response does not match expected pattern", _invocation.expectedResponsePattern, responseStr);
+                } finally {
+                    scheduler.commitTransaction();
+                }
             }
         }
     }

Added: ode/trunk/bpel-test/src/main/java/org/apache/ode/test/MockTransactionManager.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/main/java/org/apache/ode/test/MockTransactionManager.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/bpel-test/src/main/java/org/apache/ode/test/MockTransactionManager.java (added)
+++ ode/trunk/bpel-test/src/main/java/org/apache/ode/test/MockTransactionManager.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,237 @@
+/*
+ * 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.ode.test;
+
+import java.util.ArrayList;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+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 javax.transaction.xa.XAResource;
+
+/**
+ * A minimal transaction manager that can be used for testing.
+ * 
+ * @author Maciej Szefler <mszefler at gmail dot com>
+ * 
+ */
+public class MockTransactionManager implements TransactionManager {
+    ThreadLocal<TX> _transaction = new ThreadLocal<TX>();
+
+    public void begin() throws NotSupportedException, SystemException {
+        if (_transaction.get() != null)
+            throw new NotSupportedException("Transaction active (nested tx not supported): " + _transaction.get());
+
+        _transaction.set(new TX());
+    }
+
+    public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException,
+            SecurityException, SystemException {
+        if (_transaction.get() == null)
+            throw new IllegalStateException("Transaction not active. ");
+
+        try {
+            _transaction.get().commit();
+        } finally {
+            _transaction.set(null);
+        }
+    }
+
+    public int getStatus() throws SystemException {
+        if (_transaction.get() == null)
+            return Status.STATUS_NO_TRANSACTION;
+
+        return _transaction.get().getStatus();
+
+    }
+
+    public Transaction getTransaction() throws SystemException {
+        return _transaction.get();
+    }
+
+    public void resume(Transaction tx) throws IllegalStateException, InvalidTransactionException, SystemException {
+        if (_transaction.get() != null)
+            throw new IllegalStateException("Transaction is active in current thread: " + _transaction.get());
+        try {
+            _transaction.set((TX) tx);
+        } catch (ClassCastException cce) {
+            throw new InvalidTransactionException();
+        }
+
+    }
+
+    public void rollback() throws IllegalStateException, SecurityException, SystemException {
+        if (_transaction.get() == null)
+            throw new IllegalStateException("Transaction not active. ");
+
+        try {
+            _transaction.get().rollback();
+        } finally {
+            _transaction.set(null);
+        }
+    }
+
+    public void setRollbackOnly() throws IllegalStateException, SystemException {
+        if (_transaction.get() == null)
+            throw new IllegalStateException("Transaction not active. ");
+
+        _transaction.get().setRollbackOnly();
+
+    }
+
+    public void setTransactionTimeout(int arg0) throws SystemException {
+        // TODO Auto-generated method stub
+
+    }
+
+    public Transaction suspend() throws SystemException {
+        try {
+            return _transaction.get();
+        } finally {
+            _transaction.set(null);
+        }
+    }
+    
+
+    protected void doBegin(TX tx) {}
+    protected void doCommit(TX tx) {}
+    protected void doRollback(TX tx){}
+
+    public class TX implements Transaction {
+
+        final ArrayList<XAResource> _resources = new ArrayList<XAResource>();
+
+        final ArrayList<Synchronization> _synchros = new ArrayList<Synchronization> ();
+
+        private int _status;
+
+        public void commit() throws HeuristicMixedException, HeuristicRollbackException, RollbackException, SecurityException,
+                SystemException {
+            switch (_status) {
+            case Status.STATUS_COMMITTED:
+                return;
+            case Status.STATUS_MARKED_ROLLBACK:
+                rollback();
+                throw new RollbackException("Transaction was marked for rollback!");
+            case Status.STATUS_ACTIVE:
+                fireBefore();
+                if (_status == Status.STATUS_MARKED_ROLLBACK) {
+                    rollback();
+                    throw new RollbackException("Transaction was marked for rollback in beforeCompletion handler.");
+                }
+                _status = Status.STATUS_COMMITTING;
+                try {
+                    doCommit(this);
+                    _status = Status.STATUS_COMMITTED;
+                } catch (Exception ex) {
+                    _status = Status.STATUS_ROLLEDBACK;
+                    throw new RollbackException("Transaction was rolled back due to commit failure." );
+                } finally {
+                    fireAfter();
+                }
+                break;
+            default:
+                throw new IllegalStateException("Unexpected transaction state.");
+            }
+        }
+
+        public boolean delistResource(XAResource arg0, int arg1) throws IllegalStateException, SystemException {
+            // TODO: perhaps we should do something with the resources?
+            _resources.remove(arg0);
+            return true;
+        }
+
+        public boolean enlistResource(XAResource r) throws IllegalStateException, RollbackException, SystemException {
+            return _resources.add(r);
+        }
+
+        public int getStatus() throws SystemException {
+            return _status;
+        }
+
+        public void registerSynchronization(Synchronization synch) throws IllegalStateException, RollbackException, SystemException {
+            _synchros.add(synch);
+        }
+
+        public void rollback() throws IllegalStateException, SystemException {
+            // TODO Auto-generated method stub
+            switch (_status) {
+            case Status.STATUS_ROLLEDBACK:
+                return;
+            case Status.STATUS_MARKED_ROLLBACK:
+            case Status.STATUS_ACTIVE:
+                _status = Status.STATUS_ROLLING_BACK;
+                try {
+                    doRollback(this);
+                } catch (Exception ex) {
+                    ex.printStackTrace();
+                } finally {
+                    _status = Status.STATUS_ROLLEDBACK;
+                    fireAfter();
+                }
+                break;
+            default:
+                throw new IllegalStateException("Unexpected transaction state.");
+            }
+        }
+
+        public void setRollbackOnly() throws IllegalStateException, SystemException {
+            switch (_status) {
+            case Status.STATUS_ACTIVE:
+            case Status.STATUS_MARKED_ROLLBACK:
+                _status = Status.STATUS_MARKED_ROLLBACK;
+                break;
+            case Status.STATUS_ROLLEDBACK:
+            case Status.STATUS_ROLLING_BACK:
+                break;
+            default:
+                throw new IllegalStateException();
+            }
+        }
+
+        private void fireBefore() {
+            for (Synchronization s : _synchros)
+                try {
+                    s.beforeCompletion();
+                } catch (Throwable t) {
+                    ; // ignore errors.
+                }
+
+        }
+
+        private void fireAfter() {
+            for (Synchronization s : _synchros)
+                try {
+                    s.afterCompletion(_status);
+                } catch (Throwable t) {
+                    ; // ignore errors.
+                }
+
+        }
+
+    }
+
+}

Modified: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BasicActivities20Test.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BasicActivities20Test.java?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BasicActivities20Test.java (original)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/BasicActivities20Test.java Wed Aug 18 04:12:49 2010
@@ -26,6 +26,7 @@ import javax.xml.namespace.QName;
 
 import org.apache.ode.bpel.iapi.ContextException;
 import org.apache.ode.bpel.iapi.MessageExchange;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class BasicActivities20Test extends BPELTestAbstract {
@@ -91,6 +92,7 @@ public class BasicActivities20Test exten
     /**
      * Test the wait "until" syntax.
      */
+    @Ignore("ODE-805,JPA refacotring leftover")
     @Test public void testWaitUntilPast() throws Throwable {
         deploy("/bpel/2.0/TestWaitUntil");
         DateFormat idf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

Modified: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/VersionedRedeployTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/VersionedRedeployTest.java?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/VersionedRedeployTest.java (original)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/VersionedRedeployTest.java Wed Aug 18 04:12:49 2010
@@ -24,6 +24,7 @@ import javax.xml.namespace.QName;
 import org.apache.ode.bpel.iapi.ProcessConf;
 import org.apache.ode.bpel.iapi.ProcessState;
 import org.junit.Assert;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -35,7 +36,7 @@ public class VersionedRedeployTest exten
     QName qName2 = new QName("http://ode/bpel/unit-test", "HelloWorld2-2");
     QName qName3 = new QName("http://ode/bpel/unit-test", "HelloWorld2-3");
 
-    @Test public void testRetireOld() throws Throwable {
+     @Test public void testRetireOld() throws Throwable {
         deploy("/bpel/2.0/TestVersionedRedeploy/HelloWorld-1");
         ProcessConf conf = store.getProcessConfiguration(qName1);
         Assert.assertEquals(ProcessState.ACTIVE, conf.getState());
@@ -57,32 +58,38 @@ public class VersionedRedeployTest exten
         Assert.assertEquals(ProcessState.RETIRED, conf.getState());
         conf = store.getProcessConfiguration(qName3);
         Assert.assertEquals(ProcessState.ACTIVE, conf.getState());
+        
     }
 
-    @Test public void testInstancePersistence() throws Throwable {
+     @Ignore("ODE-805, JPA refacotring leftover")
+     @Test public void testInstancePersistence() throws Throwable {
         // Checking for each step that all instances still exist and that each process got one execution
         // so no instance has been created after a process has been retired.
         go("/bpel/2.0/TestVersionedRedeploy/HelloWorld-1");
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName1).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName1).getNumInstances());
 
         // clean up deployment and invocations
         _deployments.clear();
         _invocations.clear();
 
         go("/bpel/2.0/TestVersionedRedeploy/HelloWorld-2");
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName1).getNumInstances());
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName2).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName1).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName2).getNumInstances());
 
         // clean up deployment and invocations
         _deployments.clear();
         _invocations.clear();
 
         go("/bpel/2.0/TestVersionedRedeploy/HelloWorld-3");
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName1).getNumInstances());
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName2).getNumInstances());
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName3).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName1).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName2).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName3).getNumInstances());
+        
+        _deployments.clear();
+        _invocations.clear();
     }
-
+     
+    @Ignore("ODE-805,JPA refacotring leftover") 
     @Test public void testVersionedUndeployDeploy() throws Throwable {
         go("/bpel/2.0/TestVersionedRedeploy/HelloWorld-1");
         doUndeployments();
@@ -95,7 +102,7 @@ public class VersionedRedeployTest exten
         Assert.assertNull(store.getProcessConfiguration(qName1));
         Assert.assertNull(store.getProcessConfiguration(qName3));
 
-        Assert.assertEquals(1, _cf.getConnection().getProcess(qName2).getNumInstances());
+        Assert.assertEquals(1, _bcf.getConnection().getProcess(qName2).getNumInstances());
     }
 
 }

Added: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/BaseTestDAO.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/BaseTestDAO.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/BaseTestDAO.java (added)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/BaseTestDAO.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,80 @@
+/*
+ * 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.ode.test.dao.bpel;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+
+import junit.framework.Assert;
+
+import org.apache.ode.dao.bpel.BpelDAOConnection;
+import org.apache.ode.dao.bpel.BpelDAOConnectionFactory;
+import org.apache.ode.il.EmbeddedGeronimoFactory;
+import org.apache.ode.il.config.OdeConfigProperties;
+import org.apache.ode.il.dbutil.Database;
+import org.hibernate.cfg.Environment;
+
+/**
+ * Testing BpelDAOConnectionImpl.listInstance. We're just producing a lot
+ * of different filter combinations and test if they execute ok. To really
+ * test that the result is the one expected would take a huge test database
+ * (with at least a process and an instance for every possible combination).
+ */
+public abstract class BaseTestDAO extends Assert{
+
+    protected BpelDAOConnection daoConn;
+    protected TransactionManager _txm;
+    private   Database _db;
+    protected BpelDAOConnectionFactory _factoryImpl;
+
+    protected void initTM() throws Exception {
+        _txm = new EmbeddedGeronimoFactory().getTransactionManager();
+        Properties props = new Properties();
+        props.setProperty(OdeConfigProperties.PROP_DAOCF, "org.apache.ode.dao.hib.bpel.BpelDAOConnectionFactoryImpl");
+        props.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
+        OdeConfigProperties odeProps = new OdeConfigProperties(props,"");
+		_db = new Database(odeProps);
+        _db.setTransactionManager(_txm);
+        _db.start();
+        //txm.begin();
+        
+        _factoryImpl = _db.createDaoCF();
+        
+        _txm.begin();
+        daoConn = _factoryImpl.getConnection();
+        
+    }
+
+    protected void stopTM() throws Exception {
+     _txm.commit();
+     daoConn.close();
+
+     _factoryImpl.shutdown();
+     _db.shutdown();
+      
+
+    }
+
+    protected TransactionManager getTransactionManager() {
+        return _txm;
+    }
+
+}
\ No newline at end of file

Added: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ListInstanceTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ListInstanceTest.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ListInstanceTest.java (added)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ListInstanceTest.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,115 @@
+/*
+ * 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.ode.test.dao.bpel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ode.bpel.common.InstanceFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Testing BpelDAOConnectionImpl.listInstance. We're just producing a lot
+ * of different filter combinations and test if they execute ok. To really
+ * test that the result is the one expected would take a huge test database
+ * (with at least a process and an instance for every possible combination).
+ */
+public class ListInstanceTest extends BaseTestDAO {
+
+  private Map<String, List> filterElmts;
+  private ArrayList<String> order;
+  
+  @Before
+  public void setUp() throws Exception {
+    initTM();
+    buildFilterElements();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    stopTM();
+  }
+
+  @Test
+  public void testListInstance() throws Exception {
+    for (int index = 0; index < 7; index++) {
+      StringBuffer filter = new StringBuffer();
+      for (Map.Entry<String, List> entry : filterElmts.entrySet()) {
+        filter.append(entry.getKey());
+        filter.append(entry.getValue().get((index < entry.getValue().size()) ? index : index % entry.getValue().size()));
+        InstanceFilter ifilter = new InstanceFilter(filter.toString(),
+                order.get((index < order.size()) ? index : index % order.size()), 0);
+        daoConn.instanceQuery(ifilter);
+      }
+    }
+  }
+
+  private void buildFilterElements() {
+    filterElmts = new HashMap<String, List>();
+    ArrayList<String> nameList = new ArrayList<String>();
+    nameList.add("=Hello* ");
+    nameList.add("=HelloWorld ");
+    filterElmts.put("name", nameList);
+
+    ArrayList<String> namespaceList = new ArrayList<String>();
+    namespaceList.add("=http://ode* ");
+    namespaceList.add("=http://ode ");
+    filterElmts.put("namespace", namespaceList);
+
+    ArrayList<String> statusList = new ArrayList<String>();
+    statusList.add("=active ");
+    statusList.add("=suspended ");
+    statusList.add("=error ");
+    statusList.add("=completed|terminated ");
+    statusList.add("=faulted|terminated ");
+    statusList.add("=error|active ");
+    filterElmts.put("status", statusList);
+
+    ArrayList<String> startedList = new ArrayList<String>();
+    startedList.add(">=2005-11-29T15:11 ");
+    startedList.add("<=2005-11-29T15:11 ");
+    startedList.add("<2005-11-29T15:11 started>=2005-11-29T15:11 ");
+    startedList.add(">2005-11-29T15:11 started<=2005-11-29T15:11 ");
+    startedList.add("=2005-11-29T15:11 ");
+    filterElmts.put("started", startedList);
+
+    ArrayList<String> lastActiveList = new ArrayList<String>();
+    lastActiveList.add(">=2005-11-29T15:11 ");
+    lastActiveList.add("<=2005-11-29T15:11 ");
+    lastActiveList.add("<2005-11-29T15:11 last-active>=2005-11-29T15:11 ");
+    lastActiveList.add(">2005-11-29T15:11 last-active<=2005-11-29T15:11 ");
+    lastActiveList.add("=2005-11-29T15:11 ");
+    filterElmts.put("last-active", lastActiveList);
+
+    order = new ArrayList<String>();
+    order.add("pid");
+    order.add("name pid");
+    order.add("namespace -name");
+    order.add("version -pid +name");
+    order.add("status namespace");
+    order.add("-started -version status");
+    order.add("+last-active name -pid +version -status namespace");
+  }
+
+}

Added: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/MexTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/MexTest.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/MexTest.java (added)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/MexTest.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,99 @@
+/*
+ * 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.ode.test.dao.bpel;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.bpel.common.CorrelationKeySet;
+import org.apache.ode.bpel.iapi.ProcessConf.CLEANUP_CATEGORY;
+import org.apache.ode.dao.bpel.CorrelatorDAO;
+import org.apache.ode.dao.bpel.MessageExchangeDAO;
+import org.apache.ode.dao.bpel.ProcessDAO;
+import org.apache.ode.dao.bpel.ProcessInstanceDAO;
+import org.apache.ode.dao.hib.SessionManager;
+import org.apache.ode.dao.hib.bpel.BpelDAOConnectionImpl;
+import org.apache.ode.dao.hib.bpel.CorrelatorDaoImpl;
+import org.apache.ode.dao.hib.bpel.hobj.HCorrelator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Testing BpelDAOConnectionImpl.listInstance. We're just producing a lot of
+ * different filter combinations and test if they execute ok. To really test
+ * that the result is the one expected would take a huge test database (with at
+ * least a process and an instance for every possible combination).
+ */
+public class MexTest extends BaseTestDAO {
+
+    private Map<String, List> filterElmts;
+    private ArrayList<String> order;
+
+    @Before
+    public void setUp() throws Exception {
+        initTM();
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+        stopTM();
+    }
+    
+    @Test
+    public void test() throws Exception {
+        MessageExchangeDAO mex = daoConn.createMessageExchange('M');
+        mex.lockPremieMessages();
+        
+        SessionManager sm = ((BpelDAOConnectionImpl) daoConn)._sm;
+        HCorrelator correlator = new HCorrelator();
+        correlator.setCorrelatorId("abc");
+        sm.getSession().save(correlator);
+        new CorrelatorDaoImpl(sm, correlator).dequeueMessage(new CorrelationKeySet("@2[12~a~b]"));
+    }
+    
+    @Test
+    public void testCleanup() throws Exception {
+        SessionManager sm = ((BpelDAOConnectionImpl) daoConn)._sm;
+        ProcessDAO p = daoConn.createProcess(QName.valueOf("abc"), QName.valueOf("abc"), "abc", 1);
+        CorrelatorDAO correlator = p.addCorrelator("abc");
+        ProcessInstanceDAO instance = p.createInstance(correlator);
+
+        MessageExchangeDAO mex = daoConn.createMessageExchange('M');
+        mex.setProperty("abc", "def");
+        mex.setInstance(instance);
+
+        _txm.commit();
+        _txm.begin();
+        assertEquals("1", sm.getSession().createSQLQuery("select count(*) from BPEL_MEX_PROPS").list().get(0).toString());
+        
+        Set<CLEANUP_CATEGORY> cleanupCategories = EnumSet.allOf(CLEANUP_CATEGORY.class);
+        instance.delete(cleanupCategories);
+        _txm.commit();
+        _txm.begin();
+
+        assertEquals("0", sm.getSession().createSQLQuery("select count(*) from BPEL_MEX_PROPS").list().get(0).toString());
+    }
+}

Added: ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ProcessManagementDaoTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ProcessManagementDaoTest.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ProcessManagementDaoTest.java (added)
+++ ode/trunk/bpel-test/src/test/java/org/apache/ode/test/dao/bpel/ProcessManagementDaoTest.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,83 @@
+/*
+ * 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.ode.test.dao.bpel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ode.bpel.common.InstanceFilter;
+import org.apache.ode.bpel.common.ProcessState;
+import org.apache.ode.dao.bpel.ProcessDAO;
+import org.apache.ode.dao.bpel.ProcessInstanceDAO;
+import org.apache.ode.dao.bpel.ProcessManagementDAO.FailedSummaryValue;
+import org.apache.ode.dao.bpel.ProcessManagementDAO.InstanceSummaryKey;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Testing BpelDAOConnectionImpl.listInstance. We're just producing a lot of
+ * different filter combinations and test if they execute ok. To really test
+ * that the result is the one expected would take a huge test database (with at
+ * least a process and an instance for every possible combination).
+ */
+public class ProcessManagementDaoTest extends BaseTestDAO {
+	
+	@Before
+    public void setUp() throws Exception {
+        initTM();
+    }
+	
+	@After
+    public void tearDown() throws Exception {
+        stopTM();
+    }
+	
+	@Test
+    public void testInstanceSummary() throws Exception {
+        Set<String> pids = new HashSet<String>();
+        QName pid = QName.valueOf("{ns}pid");
+        pids.add(pid.toString());
+        ProcessDAO p = daoConn.createProcess(pid, QName.valueOf("{ns}type"), "abc", 1);
+        ProcessInstanceDAO i = p.createInstance(p.addCorrelator("cor"));
+        i.setState(ProcessState.STATE_COMPLETED_OK);
+        Map<InstanceSummaryKey, Long> r = daoConn.getProcessManagement().countInstancesSummary(pids);
+        System.out.println("resultSummary:" + r);
+        assertEquals(1, r.size());
+    }
+	
+	@Test
+    public void testInstanceSummaryFailures() throws Exception {
+        Set<String> pids = new HashSet<String>();
+        QName pid = QName.valueOf("{ns}pid");
+        pids.add(pid.toString());
+        ProcessDAO p = daoConn.createProcess(pid, QName.valueOf("{ns}type"), "abc", 1);
+        ProcessInstanceDAO i = p.createInstance(p.addCorrelator("cor"));
+        Map<String, FailedSummaryValue> r = daoConn.getProcessManagement().findFailedCountAndLastFailedDateForProcessIds(pids);
+        System.out.println("resultSummary:" + r);
+        assertEquals(0, r.size());
+    }
+}

Modified: ode/trunk/dao-hibernate-db/build.xml
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate-db/build.xml?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/dao-hibernate-db/build.xml (original)
+++ ode/trunk/dao-hibernate-db/build.xml Wed Aug 18 04:12:49 2010
@@ -21,8 +21,7 @@
 
     <property name="db.scripts.dir" value="${basedir}/target" />
     <property name="sql.dir" value="${basedir}/src/main/sql"/>
-        <property name="dao-hibernate.classes" value="${basedir}/../dao-hibernate/target/classes" />
-    <property name="bpel-store.classes" value="${basedir}/../bpel-store/target/classes" />
+    <property name="dao-hibernate.classes" value="${basedir}/../dao-hibernate/target/classes" />
 
     <path id="classpath">
       <pathelement path="${maven.runtime.classpath}"/>
@@ -89,9 +88,6 @@
             <include name="**/*.hbm.xml"/>
                     <exclude name="**/HMessageExchangeProperty.hbm.xml" />
         </fileset>
-        <fileset dir="${bpel-store.classes}/">
-            <include name="**/*.hbm.xml"/>
-        </fileset>
         </schemaexport>
         <concat destfile="${db.scripts.dir}/@{db}.sql">
           <fileset file="${sql.dir}/common.sql"/>

Modified: ode/trunk/dao-hibernate-db/pom.xml
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate-db/pom.xml?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/dao-hibernate-db/pom.xml (original)
+++ ode/trunk/dao-hibernate-db/pom.xml Wed Aug 18 04:12:49 2010
@@ -33,7 +33,7 @@
     <dependencies>
         <dependency>
             <groupId>org.hibernate</groupId>
-            <artifactId>hibernate</artifactId>
+            <artifactId>hibernate-core</artifactId>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>

Modified: ode/trunk/dao-hibernate/pom.xml
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate/pom.xml?rev=986561&r1=986560&r2=986561&view=diff
==============================================================================
--- ode/trunk/dao-hibernate/pom.xml (original)
+++ ode/trunk/dao-hibernate/pom.xml Wed Aug 18 04:12:49 2010
@@ -43,8 +43,6 @@
     <dependency>
       <groupId>org.apache.ode</groupId>
       <artifactId>ode-bpel-epr</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>commons-pool</groupId>
@@ -57,16 +55,20 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>hsqldb</groupId>
-      <artifactId>hsqldb</artifactId>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
       <scope>test</scope>
     </dependency>
 
     <dependency>
       <groupId>org.hibernate</groupId>
-      <artifactId>hibernate</artifactId>
+      <artifactId>hibernate-core</artifactId>
     </dependency>
     <dependency>
+      <groupId>javassist</groupId>
+      <artifactId>javassist</artifactId>
+    </dependency>    
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <version>${slf4j.version}</version>
@@ -95,7 +97,7 @@
                  <hibernatedoclet excludedTags="@version,@author,@todo" verbose="true"
                    destdir="${project.build.outputDirectory}" force="true">
                    <hibernate version="3.0"/>
-                   <fileset dir="${project.build.sourceDirectory}" includes="org/apache/ode/daohib/bpel/hobj/*.java"/>
+                   <fileset dir="${project.build.sourceDirectory}" includes="org/apache/ode/dao/hib/bpel/hobj/*.java,org/apache/ode/dao/hib/store/hobj/*.java"/>
                  </hibernatedoclet>
                </tasks>
              </configuration>
@@ -115,11 +117,11 @@
              <configuration>
                <source>
                  import java.io.File
-                 def process_instance_hbm_file = new File(project.build.outputDirectory, 'org/apache/ode/daohib/bpel/hobj/HProcessInstance.hbm.xml')
+                 def process_instance_hbm_file = new File(project.build.outputDirectory, 'org/apache/ode/dao/hib/bpel/hobj/HProcessInstance.hbm.xml')
                  def contents = process_instance_hbm_file.text
                  if (!contents.contains('not-found="ignore"')) {
-                     process_instance_hbm_file.text = contents.replace('class="org.apache.ode.daohib.bpel.hobj.HProcess"',
-                         'not-found="ignore" class="org.apache.ode.daohib.bpel.hobj.HProcess"')
+                     process_instance_hbm_file.text = contents.replace('class="org.apache.ode.dao.hib.bpel.hobj.HProcess"',
+                         'not-found="ignore" class="org.apache.ode.dao.hib.bpel.hobj.HProcess"')
                  }
                </source>
              </configuration>

Added: ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/DataSourceConnectionProvider.java
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/DataSourceConnectionProvider.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/DataSourceConnectionProvider.java (added)
+++ ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/DataSourceConnectionProvider.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,61 @@
+/*
+ * 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.ode.dao.hib;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.ode.utils.DbIsolation;
+
+import org.hibernate.HibernateException;
+import org.hibernate.connection.ConnectionProvider;
+
+
+public class DataSourceConnectionProvider implements ConnectionProvider {
+
+  private Properties _props;
+  
+  public DataSourceConnectionProvider() {
+  }
+  
+  public void configure(Properties props) throws HibernateException {
+    _props = props;
+  }
+
+  public Connection getConnection() throws SQLException {
+    Connection c = SessionManager.getConnection(_props);
+    DbIsolation.setIsolationLevel(c);
+    return c;
+  }
+
+  public void closeConnection(Connection con) throws SQLException {
+    con.close();
+  }
+
+  public void close() throws HibernateException {
+
+  }
+
+  public boolean supportsAggressiveRelease() {
+    return true;
+  }
+
+}

Added: ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/HibernateTransactionManagerLookup.java
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/HibernateTransactionManagerLookup.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/HibernateTransactionManagerLookup.java (added)
+++ ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/HibernateTransactionManagerLookup.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.ode.dao.hib;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.hibernate.HibernateException;
+import org.hibernate.transaction.TransactionManagerLookup;
+
+/**
+ * Implementation of the {@link org.hibernate.transaction.TransactionManagerLookup} interface that
+ * uses {@link SessionManager} to obtain the JTA {@link TransactionManager} object.
+ */
+public class HibernateTransactionManagerLookup implements TransactionManagerLookup {
+
+	/** Constructor. */
+	public HibernateTransactionManagerLookup() {
+		super();
+	}
+
+	public TransactionManager getTransactionManager(Properties props)
+			throws HibernateException {
+		return SessionManager.getTransactionManager(props);
+	}
+
+	public String getUserTransactionName() {
+		return null;
+	}
+
+    public Object getTransactionIdentifier(Transaction transaction) {
+        return transaction;
+    }
+}

Added: ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransaction.java
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransaction.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransaction.java (added)
+++ ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransaction.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,360 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.apache.ode.dao.hib;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * {@link Transaction} implementation based on transaction management through
+ * a JTA {@link UserTransaction}.  Similar to {@link CMTTransaction}, except
+ * here we are actually managing the transactions through the Hibernate
+ * transaction mechanism.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ * 
+ * Scraped from org.hibernate
+ */
+public class JotmTransaction implements Transaction {
+    private static final Log log = LogFactory.getLog( JotmTransaction.class );
+
+    private final JDBCContext jdbcContext;
+    private final TransactionFactory.Context transactionContext;
+
+    private UserTransaction userTransaction;
+    private boolean newTransaction;
+    private boolean begun;
+    private boolean commitFailed;
+    private boolean commitSucceeded;
+    private boolean callback;
+
+    public JotmTransaction(
+            UserTransaction userTransaction,
+            JDBCContext jdbcContext,
+            TransactionFactory.Context transactionContext) {
+        this.jdbcContext = jdbcContext;
+        this.transactionContext = transactionContext;
+        this.userTransaction = userTransaction;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void begin() throws HibernateException {
+        if ( begun ) {
+            return;
+        }
+        if ( commitFailed ) {
+            throw new TransactionException( "cannot re-start transaction after failed commit" );
+        }
+
+        log.debug( "begin" );
+
+        try {
+            newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
+            if ( newTransaction ) {
+                userTransaction.begin();
+                log.debug( "Began a new JTA transaction" );
+            }
+        }
+        catch ( Exception e ) {
+            log.error( "JTA transaction begin failed", e );
+            throw new TransactionException( "JTA transaction begin failed", e );
+        }
+
+        /*if (newTransaction) {
+            // don't need a synchronization since we are committing
+            // or rolling back the transaction ourselves - assuming
+            // that we do no work in beforeTransactionCompletion()
+            synchronization = false;
+        }*/
+
+        boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
+
+        if ( !newTransaction && !synchronization ) {
+            log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
+        }
+
+        if ( !synchronization ) {
+            //if we could not register a synchronization,
+            //do the before/after completion callbacks
+            //ourself (but we need to let jdbcContext
+            //know that this is what we are going to
+            //do, so it doesn't keep trying to register
+            //synchronizations)
+            callback = jdbcContext.registerCallbackIfNecessary();
+        }
+
+        begun = true;
+        commitSucceeded = false;
+
+        jdbcContext.afterTransactionBegin( this );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void commit() throws HibernateException {
+        if ( !begun ) {
+            throw new TransactionException( "Transaction not successfully started" );
+        }
+
+        log.debug( "commit" );
+
+        boolean flush = !transactionContext.isFlushModeNever()
+                && ( callback || !transactionContext.isFlushBeforeCompletionEnabled() );
+
+        if ( flush ) {
+            transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
+        }
+
+        if ( callback && newTransaction ) {
+            jdbcContext.beforeTransactionCompletion( this );
+        }
+
+        closeIfRequired();
+
+        if ( newTransaction ) {
+            try {
+                userTransaction.commit();
+                commitSucceeded = true;
+                log.debug( "Committed JTA UserTransaction" );
+            }
+            catch ( Exception e ) {
+                commitFailed = true; // so the transaction is already rolled back, by JTA spec
+                log.error( "JTA commit failed", e );
+                throw new TransactionException( "JTA commit failed: ", e );
+            }
+            finally {
+                afterCommitRollback();
+            }
+        }
+        else {
+            // this one only really needed for badly-behaved applications!
+            // (if the TransactionManager has a Sychronization registered,
+            // its a noop)
+            // (actually we do need it for downgrading locks)
+            afterCommitRollback();
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rollback() throws HibernateException {
+        if ( !begun && !commitFailed ) {
+            throw new TransactionException( "Transaction not successfully started" );
+        }
+
+        log.debug( "rollback" );
+
+        try {
+            closeIfRequired();
+        }
+        catch ( Exception e ) {
+            // swallow it, and continue to roll back JTA transaction
+            log.error( "could not close session during rollback", e );
+        }
+
+        try {
+            if ( newTransaction ) {
+                if ( !commitFailed ) {
+                    userTransaction.rollback();
+                    log.debug( "Rolled back JTA UserTransaction" );
+                }
+            }
+            else {
+                userTransaction.setRollbackOnly();
+                log.debug( "set JTA UserTransaction to rollback only" );
+            }
+        }
+        catch ( Exception e ) {
+            log.error( "JTA rollback failed", e );
+            throw new TransactionException( "JTA rollback failed", e );
+        }
+        finally {
+            afterCommitRollback();
+        }
+    }
+
+    private static final int NULL = Integer.MIN_VALUE;
+
+    private void afterCommitRollback() throws TransactionException {
+
+        begun = false;
+        // this method is a noop if there is a Synchronization!
+        if ( callback ) {
+            if ( !newTransaction ) {
+                log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
+            }
+            int status = NULL;
+            try {
+                status = userTransaction.getStatus();
+            }
+            catch ( Exception e ) {
+                log.error( "Could not determine transaction status after commit", e );
+                throw new TransactionException( "Could not determine transaction status after commit", e );
+            }
+            finally {
+                jdbcContext.afterTransactionCompletion( status == Status.STATUS_COMMITTED, this );
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean wasRolledBack() throws TransactionException {
+        final int status;
+        try {
+            status = userTransaction.getStatus();
+        }
+        catch ( SystemException se ) {
+            log.error( "Could not determine transaction status", se );
+            throw new TransactionException( "Could not determine transaction status", se );
+        }
+        if ( status == Status.STATUS_UNKNOWN ) {
+            throw new TransactionException( "Could not determine transaction status" );
+        }
+        else {
+            return JTAHelper.isRollback( status );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean wasCommitted() throws TransactionException {
+        final int status;
+        try {
+            status = userTransaction.getStatus();
+        }
+        catch ( SystemException se ) {
+            log.error( "Could not determine transaction status", se );
+            throw new TransactionException( "Could not determine transaction status: ", se );
+        }
+        if ( status == Status.STATUS_UNKNOWN ) {
+            throw new TransactionException( "Could not determine transaction status" );
+        }
+        else {
+            return status == Status.STATUS_COMMITTED;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isActive() throws TransactionException {
+        if ( !begun || commitFailed || commitSucceeded ) {
+            return false;
+        }
+
+        final int status;
+        try {
+            status = userTransaction.getStatus();
+        }
+        catch ( SystemException se ) {
+            log.error( "Could not determine transaction status", se );
+            throw new TransactionException( "Could not determine transaction status: ", se );
+        }
+        if ( status == Status.STATUS_UNKNOWN ) {
+            throw new TransactionException( "Could not determine transaction status" );
+        }
+        else {
+            return status == Status.STATUS_ACTIVE;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void registerSynchronization(Synchronization sync) throws HibernateException {
+        if ( getTransactionManager() == null ) {
+            throw new IllegalStateException( "JTA TransactionManager not available" );
+        }
+        else {
+            try {
+                getTransactionManager().getTransaction().registerSynchronization( sync );
+            }
+            catch ( Exception e ) {
+                throw new TransactionException( "could not register synchronization", e );
+            }
+        }
+    }
+
+    /**
+     * Getter for property 'transactionManager'.
+     *
+     * @return Value for property 'transactionManager'.
+     */
+    private TransactionManager getTransactionManager() {
+        return transactionContext.getFactory().getTransactionManager();
+    }
+
+    private void closeIfRequired() throws HibernateException {
+        boolean close = callback &&
+                transactionContext.shouldAutoClose() &&
+                !transactionContext.isClosed();
+        if ( close ) {
+            transactionContext.managedClose();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setTimeout(int seconds) {
+        try {
+            userTransaction.setTransactionTimeout( seconds );
+        }
+        catch ( SystemException se ) {
+            throw new TransactionException( "could not set transaction timeout", se );
+        }
+    }
+
+    /**
+     * Getter for property 'userTransaction'.
+     *
+     * @return Value for property 'userTransaction'.
+     */
+    protected UserTransaction getUserTransaction() {
+        return userTransaction;
+    }
+}

Added: ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransactionFactory.java
URL: http://svn.apache.org/viewvc/ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransactionFactory.java?rev=986561&view=auto
==============================================================================
--- ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransactionFactory.java (added)
+++ ode/trunk/dao-hibernate/src/main/java/org/apache/ode/dao/hib/JotmTransactionFactory.java Wed Aug 18 04:12:49 2010
@@ -0,0 +1,309 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.apache.ode.dao.hib;
+
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.cfg.Environment;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.transaction.TransactionManagerLookup;
+import org.hibernate.transaction.TransactionManagerLookupFactory;
+import org.hibernate.util.NamingHelper;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * Factory for {@link JotmTransaction} instances.
+ * <p/>
+ * To be completely accurate to the JTA spec, JTA implementations should
+ * publish their contextual {@link UserTransaction} reference into JNDI.
+ * However, in practice there are quite a few <tt>stand-alone</tt>
+ * implementations intended for use outside of J2EE/JEE containers and
+ * which therefore do not publish their {@link UserTransaction} references
+ * into JNDI but which otherwise follow the aspects of the JTA specification.
+ * This {@link TransactionFactory} implementation can support both models.
+ * <p/>
+ * For complete JTA implementations (including dependence on JNDI), the
+ * {@link UserTransaction} reference is obtained by a call to
+ * {@link #resolveInitialContext}.  Hibernate will then attempt to locate the
+ * {@link UserTransaction} within this resolved
+ * {@link InitialContext} based on the namespace returned by
+ * {@link #resolveUserTransactionName}.
+ * <p/>
+ * For the so-called <tt>stand-alone</tt> implementations, we do not care at
+ * all about the JNDI aspects just described.  Here, the implementation would
+ * have a specific manner to obtain a reference to its contextual
+ * {@link UserTransaction}; usually this would be a static code reference, but
+ * again it varies.  Anyway, for each implementation the integration would need
+ * to override the {@link #getUserTransaction} method and return the appropriate
+ * thing.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ * 
+ * Scraped from org.hibernate
+ */
+public class JotmTransactionFactory implements TransactionFactory {
+    public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
+    private static final Log log = LogFactory.getLog( JotmTransactionFactory.class );
+
+    protected InitialContext initialContext;
+    protected String userTransactionName;
+
+    private TransactionManager txManager;
+    
+    /**
+     * Configure this transaction factory.  Specifically here we are attempting to
+     * resolve both an {@link #getInitialContext InitialContext} as well as the
+     * {@link #getUserTransactionName() JNDI namespace} for the {@link UserTransaction}.
+     *
+     * @param props The configuration properties
+     *
+     * @exception HibernateException
+     */
+    public void configure(Properties props) throws HibernateException {
+        this.initialContext = resolveInitialContext( props );
+        this.userTransactionName = resolveUserTransactionName( props );
+        log.debug( "Configured JTATransactionFactory to use [" + userTransactionName + "] for UserTransaction JDNI namespace" );
+        txManager = new HibernateTransactionManagerLookup().getTransactionManager(props);
+    }
+
+    /**
+     * Given the lot of Hibernate configuration properties, resolve appropriate
+     * reference to JNDI {@link InitialContext}.
+     * <p/>
+     * In general, the properties in which we are interested here all begin with
+     * <tt>hibernate.jndi</tt>.  Especially important depending on your
+     * environment are {@link Environment#JNDI_URL hibernate.jndi.url} and
+     *  {@link Environment#JNDI_CLASS hibernate.jndi.class}
+     *
+     * @param properties The Hibernate config properties.
+     * @return The resolved InitialContext.
+     */
+    protected final InitialContext resolveInitialContext(Properties properties) {
+        try {
+            return NamingHelper.getInitialContext( properties );
+        }
+        catch ( NamingException ne ) {
+            throw new HibernateException( "Could not obtain initial context", ne );
+        }
+    }
+
+    /**
+     * Given the lot of Hibernate configuration properties, resolve appropriate
+     * JNDI namespace to use for {@link UserTransaction} resolution.
+     * <p/>
+     * We determine the namespace to use by<ol>
+     * <li>Any specified {@link Environment#USER_TRANSACTION jta.UserTransaction} config property</li>
+     * <li>If a {@link TransactionManagerLookup} was indicated, use its
+     * {@link TransactionManagerLookup#getUserTransactionName}</li>
+     * <li>finally, as a last resort, we use {@link #DEFAULT_USER_TRANSACTION_NAME}</li>
+     * </ol>
+     *
+     * @param properties The Hibernate config properties.
+     * @return The resolved {@link UserTransaction} namespace
+     */
+    protected final String resolveUserTransactionName(Properties properties) {
+        String utName = properties.getProperty( Environment.USER_TRANSACTION );
+        if ( utName == null ) {
+            TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
+            if ( lookup != null ) {
+                utName = lookup.getUserTransactionName();
+            }
+        }
+        return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+            throws HibernateException {
+        /*
+         * JTA TransactionManager returns a JTA transaction. We need a user transaction to use
+         * hibernate's JTATransactionFactory.
+         */
+        // UserTransaction ut = getUserTransaction();
+        UserTransaction ut;
+        try {
+            ut = new UserTransaction() {
+                javax.transaction.Transaction transaction = txManager.getTransaction();
+                public void begin() throws NotSupportedException, SystemException {
+                    // TODO Auto-generated method stub
+                }
+
+                public void commit() throws HeuristicMixedException,
+                        HeuristicRollbackException, IllegalStateException,
+                        RollbackException, SecurityException, SystemException {
+                    transaction.commit();
+                }
+
+                public int getStatus() throws SystemException {
+                    // TODO Auto-generated method stub
+                    return transaction.getStatus();
+                }
+
+                public void rollback() throws IllegalStateException,
+                        SecurityException, SystemException {
+                    // TODO Auto-generated method stub
+                    transaction.rollback();
+                }
+
+                public void setRollbackOnly() throws IllegalStateException,
+                        SystemException {
+                    // TODO Auto-generated method stub
+                    transaction.setRollbackOnly();
+                }
+
+                public void setTransactionTimeout(int i) throws SystemException {
+                    // TODO Auto-generated method stub
+                }
+            };
+        } catch (SystemException e) {
+            throw new HibernateException(e);
+        }
+        
+        return new JotmTransaction( ut, jdbcContext, transactionContext );
+    }
+
+    /**
+     * Get the {@link UserTransaction} reference.
+     *
+     * @return The appropriate {@link UserTransaction} reference.
+     */
+    protected UserTransaction getUserTransaction() {
+        final String utName = getUserTransactionName();
+        log.debug( "Attempting to locate UserTransaction via JNDI [" + utName + "]");
+
+        try {
+            UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( utName );
+            if ( ut == null ) {
+                throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + utName +"]" );
+            }
+
+            log.trace( "Obtained UserTransaction" );
+
+            return ut;
+        }
+        catch ( NamingException ne ) {
+            throw new TransactionException( "Could not find UserTransaction in JNDI [" + utName + "]", ne );
+        }
+    }
+
+    /**
+     * Getter for property 'initialContext'.
+     *
+     * @return Value for property 'initialContext'.
+     */
+    protected InitialContext getInitialContext() {
+        return initialContext;
+    }
+
+    /**
+     * Getter for property 'userTransactionName'.
+     * The algorithm here is
+     *
+     * @return Value for property 'userTransactionName'.
+     */
+    protected String getUserTransactionName() {
+        return userTransactionName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ConnectionReleaseMode getDefaultReleaseMode() {
+        return ConnectionReleaseMode.AFTER_STATEMENT;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isTransactionManagerRequired() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean areCallbacksLocalToHibernateTransactions() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isTransactionInProgress(
+            JDBCContext jdbcContext,
+            Context transactionContext,
+            Transaction transaction) {
+        try {
+            // Essentially:
+            // 1) If we have a local (Hibernate) transaction in progress
+            //      and it already has the UserTransaction cached, use that
+            //      UserTransaction to determine the status.
+            // 2) If a transaction manager has been located, use
+            //      that transaction manager to determine the status.
+            // 3) Finally, as the last resort, try to lookup the
+            //      UserTransaction via JNDI and use that to determine the
+            //      status.
+            if ( transaction != null ) {
+                UserTransaction ut = ( ( JotmTransaction ) transaction ).getUserTransaction();
+                if ( ut != null ) {
+                    return JTAHelper.isInProgress( ut.getStatus() );
+                }
+            }
+
+            if ( jdbcContext.getFactory().getTransactionManager() != null ) {
+                return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
+            }
+            else {
+                UserTransaction ut = getUserTransaction();
+                return ut != null && JTAHelper.isInProgress( ut.getStatus() );
+            }
+        }
+        catch ( SystemException se ) {
+            throw new TransactionException( "Unable to check transaction status", se );
+        }
+    }
+
+}