You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2006/08/05 14:18:15 UTC

svn commit: r428990 [4/5] - in /db/ojb/trunk/proposals/otm: ./ java/ java/org/ java/org/apache/ java/org/apache/ojb/ java/org/apache/ojb/otm/ java/org/apache/ojb/otm/copy/ java/org/apache/ojb/otm/core/ java/org/apache/ojb/otm/kit/ java/org/apache/ojb/o...

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/CopySwizzling.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/CopySwizzling.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/CopySwizzling.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/CopySwizzling.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,207 @@
+package org.apache.ojb.otm.swizzle;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.cache.ObjectCache;
+import org.apache.ojb.broker.core.proxy.CollectionProxy;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.metadata.CollectionDescriptor;
+import org.apache.ojb.broker.metadata.FieldDescriptor;
+import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
+import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class CopySwizzling implements Swizzling
+{
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#swizzle(Object, Object, PersistenceBroker, ObjectCache)
+     */
+    public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb,
+                          ObjectCache cache)
+    {
+        if (newObj == null) // invalidating
+        {
+            return null;
+        }
+
+        if (oldObj == null)
+        {
+            return newObj;
+        }
+
+        if (!newObj.getClass().equals(oldObj.getClass()))
+        {
+            System.err.println("Cannot swizzle objects of different classes: "
+                    + newObj.getClass() + " and " + oldObj.getClass());
+            return newObj;
+        }
+
+        ClassDescriptor mif = pb.getClassDescriptor(newObj.getClass());
+        FieldDescriptor[] fieldDescs = mif.getFieldDescriptions();
+
+        for (int i = 0; i < fieldDescs.length; i++)
+        {
+            FieldDescriptor fd = fieldDescs[i];
+            PersistentField f = fd.getPersistentField();
+            f.set(oldObj, f.get(newObj));
+        }
+
+        // N:1 relations
+        Iterator iter = mif.getObjectReferenceDescriptors().iterator();
+        ObjectReferenceDescriptor rds;
+        PersistentField field;
+        Object newRelObj;
+        Identity newRelOid;
+        Object oldRelObj;
+
+        while (iter.hasNext())
+        {
+            rds = (ObjectReferenceDescriptor) iter.next();
+            field = rds.getPersistentField();
+            newRelObj = field.get(newObj);
+            oldRelObj = field.get(oldObj);
+            if ((newRelObj == null) && (oldRelObj != null))
+            {
+                field.set(oldObj, null);
+            }
+            else if (newRelObj != null)
+            {
+                newRelOid = new Identity(newRelObj, pb);
+                if ((oldRelObj == null) ||
+                        !newRelOid.equals(new Identity(oldRelObj, pb)))
+                {
+                    // seek for existing old object with the new identity
+                    oldRelObj = cache.lookup(newRelOid);
+                    if (oldRelObj == null)
+                    {
+                        throw new IllegalStateException("Related object not found in the context: " + newRelOid);
+                    }
+                    field.set(oldObj, oldRelObj);
+                }
+            }
+        }
+
+        // 1:N relations
+        Iterator collections = mif.getCollectionDescriptors().iterator();
+        CollectionDescriptor collectionDescriptor;
+
+        while (collections.hasNext())
+        {
+            collectionDescriptor = (CollectionDescriptor) collections.next();
+            field = collectionDescriptor.getPersistentField();
+            if (Collection.class.isAssignableFrom(field.getType()))
+            {
+                Collection newCol;
+                Collection oldCol;
+
+                newCol = (Collection) field.get(newObj);
+                if (newCol == null)
+                {
+                    field.set(oldObj, null);
+                    continue;
+                }
+
+                oldCol = (Collection) field.get(oldObj);
+                if (newCol instanceof CollectionProxy)
+                {
+                    CollectionProxy cp = (CollectionProxy) newCol;
+                    oldCol = (Collection)((PersistenceBrokerInternal)pb).getProxyFactory().createCollectionProxy(pb.getConfiguration(), cp.getContext());
+
+                    if (!((CollectionProxy) newCol).isLoaded())
+                    {
+                        field.set(oldObj, oldCol);
+                        continue;
+                    }
+                    oldCol.clear();
+                }
+                else
+                {
+                    try
+                    {
+                        oldCol = (Collection) newCol.getClass().newInstance();
+                    }
+                    catch (Exception ex)
+                    {
+                        System.err.println("Cannot instantiate collection field which is neither Collection nor array: " + field);
+                        ex.printStackTrace();
+                        return newObj;
+                    }
+                }
+                field.set(oldObj, oldCol);
+                for (Iterator it = newCol.iterator(); it.hasNext(); )
+                {
+                    newRelObj = it.next();
+                    newRelOid = new Identity(newRelObj, pb);
+                    oldRelObj = cache.lookup(newRelOid);
+                    if (oldRelObj == null)
+                    {
+                        oldRelObj = newRelObj;
+                    }
+                    oldCol.add(oldRelObj);
+                }
+            }
+            else if (field.getType().isArray())
+            {
+                Object newArray = field.get(newObj);
+                int length = Array.getLength(newArray);
+                Object oldArray =
+                        Array.newInstance(field.getType().getComponentType(), length);
+
+                for (int i = 0; i < length; i++)
+                {
+                    newRelObj = Array.get(newArray, i);
+                    newRelOid = new Identity(newRelObj, pb);
+                    oldRelObj = cache.lookup(newRelOid);
+                    if (oldRelObj == null)
+                    {
+                        throw new IllegalStateException("Related object not found for swizzle: " + newRelOid);
+                    }
+                    Array.set(oldArray, i, oldRelObj);
+                }
+                field.set(oldObj, oldArray);
+            }
+            else
+            {
+                throw new IllegalStateException("Cannot swizzle collection field: " + field);
+            }
+        }
+
+        return oldObj;
+    }
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#isSameInstance(Object, Object)
+     */
+    public boolean isSameInstance(Object swizzledObject, Object object)
+    {
+        return (swizzledObject == object);
+    }
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#getRealTarget(Object)
+     */
+    public Object getRealTarget(Object swizzledObject)
+    {
+        return swizzledObject;
+    }
+
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/NoSwizzling.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/NoSwizzling.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/NoSwizzling.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/NoSwizzling.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,48 @@
+package org.apache.ojb.otm.swizzle;
+
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.cache.ObjectCache;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class NoSwizzling implements Swizzling
+{
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#swizzle(Object, Object, PersistenceBroker)
+     */
+    public Object swizzle(Object newObj, Object oldObj,
+                          PersistenceBroker pb, ObjectCache cache)
+    {
+        return newObj;
+    }
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#isSameInstance(Object, Object)
+     */
+    public boolean isSameInstance(Object swizzledObject, Object object)
+    {
+        return (swizzledObject == object);
+    }
+
+    /**
+     * @see org.apache.ojb.otm.swizzle.Swizzling#getRealTarget(Object)
+     */
+    public Object getRealTarget(Object swizzledObject)
+    {
+        return swizzledObject;
+    }
+
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/Swizzling.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/Swizzling.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/Swizzling.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/Swizzling.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,69 @@
+package org.apache.ojb.otm.swizzle;
+
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.cache.ObjectCache;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @todo document
+ */
+public interface Swizzling
+{
+
+    /**
+     *
+     * Swizzle object references.
+     *
+     * @param newObj    the object being inserted into the EditingContext,
+     * is null if the object is being invalidated
+     * @param oldObj    the object present in the EditingContext,
+     * is null if no object is present
+     * @param pb        the PersistenceBroker that is used to get
+     * persistent class info
+     * @param cache     the "cache" of old objects, only lookup() method
+     * can be used by the Swizzling implementation to seek for old objects
+     * that should be set as a new value of relations.
+     *
+     * @return          the Swizzled Object
+     *
+     */
+    public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb,
+                          ObjectCache cache);
+
+    /**
+     *
+     * Test if the given swizzled object is the same as the given object. By same object we mean,
+     * that the System.identityHashCode() of the given object is the same as that of the object
+     * represented by the swizzled object.
+     *
+     * @param swizzledObject        The swizzled object
+     * @param object                The other object to be compared to
+     * @return                      true, if they are the same. false, otherwise.
+     *
+     */
+    public boolean isSameInstance(Object swizzledObject, Object object);
+
+    /**
+     *
+     * Get the real object associated with the given swizzled object.
+     *
+     * @param   swizzledObject      the swizzled object
+     * @return                      the real object
+     *
+     */
+    public Object getRealTarget(Object swizzledObject);
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/LocalTransactionFactory.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/LocalTransactionFactory.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/LocalTransactionFactory.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/LocalTransactionFactory.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,132 @@
+package org.apache.ojb.otm.transaction;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.PBKey;
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.otm.OTMConnection;
+import org.apache.ojb.otm.core.BaseConnection;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.core.TransactionException;
+
+import java.util.HashMap;
+
+/**
+ *
+ * Factory for local transactions. Each OTMConnection is associated with exactly one transaction.
+ *
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ *
+ */
+public class LocalTransactionFactory implements TransactionFactory
+{
+
+    private HashMap _transactionMap;
+
+    public LocalTransactionFactory ()
+    {
+        _transactionMap = new HashMap();
+    }
+
+    /**
+     * @see org.apache.ojb.otm.transaction.TransactionFactory#getTransactionForConnection(OTMConnection)
+     */
+    public Transaction getTransactionForConnection (OTMConnection connection)
+    {
+        if (!(connection instanceof BaseConnection))
+        {
+			StringBuffer msg = new StringBuffer();
+			msg.append("Unknown connection type: ");
+			if (connection != null)
+				msg.append(connection.getClass().getName());
+			else
+				msg.append(" null. Make sure you pass a non-null OTMConnection to this method. An OTMConnection can be acquired by calling acquireConnection (PBKey pbKey)");
+            throw new TransactionFactoryException(msg.toString());
+        }
+
+        Transaction tx = (Transaction) _transactionMap.get(connection);
+        if (tx == null)
+        {
+            tx = new Transaction();
+            _transactionMap.put(connection, tx);
+        }
+        // ensure that this connection is registered into this transaction
+        tx.registerConnection(connection);
+        return tx;
+    }
+
+
+    /**
+     * @see org.apache.ojb.otm.transaction.TransactionFactory#acquireConnection(PBKey)
+     */
+    public OTMConnection acquireConnection(PersistenceConfiguration persistenceConf)
+    {
+        OTMConnection newConnection = new LocalConnection(persistenceConf);
+        // Ensure the transaction is established for this connection.
+        getTransactionForConnection(newConnection);
+        return newConnection;
+    }
+
+    /**
+     *
+     * Represents a local connection. This is a private static inner class to restrict visibility
+     * to others.
+     *
+     * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+     *
+     */
+    private static class LocalConnection extends BaseConnection
+    {
+        public LocalConnection(PersistenceConfiguration persistenceConf)
+        {
+            super(persistenceConf);
+        }
+
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionBegin()
+         */
+        public void transactionBegin() throws TransactionException
+        {
+            getKernelBroker().beginTransaction();
+        }
+        
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionPrepare()
+         */
+        public void transactionPrepare() throws TransactionException
+        {
+            // Nothing to do!
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionCommit()
+         */
+        public void transactionCommit() throws TransactionException
+        {
+            getKernelBroker().commitTransaction();
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionRollback()
+         */
+        public void transactionRollback() throws TransactionException
+        {
+            getKernelBroker().abortTransaction();
+        }
+
+    }
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/ManagedTransactionFactory.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/ManagedTransactionFactory.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/ManagedTransactionFactory.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/ManagedTransactionFactory.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,172 @@
+package org.apache.ojb.otm.transaction;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.apache.ojb.broker.PersistenceBrokerFactory;
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.broker.transaction.tm.TransactionManagerFactory;
+import org.apache.ojb.broker.transaction.tm.TransactionManagerFactoryException;
+import org.apache.ojb.otm.OTMConnection;
+import org.apache.ojb.otm.core.BaseConnection;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.core.TransactionException;
+
+/**
+ * Factory for OTM Transactions within a managed environment (JTA).
+ *
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ *
+ */
+public abstract class ManagedTransactionFactory implements TransactionFactory
+{
+
+    private HashMap _transactionMap;
+    private TransactionManager tm;
+    /** Factory for transaction managers */
+    private TransactionManagerFactory transactionManagerFactory;
+
+	/**
+	 * Constructor for ManagedTransactionFactory.
+	 */
+	public ManagedTransactionFactory()
+	{
+		_transactionMap = new HashMap();
+        // TODO: Hack to acquire a transaction manager factory instance
+        //       OTM needs a connection to the core OJB i.e. via an OJB
+        //       instance in the Kit
+        transactionManagerFactory = (TransactionManagerFactory)PersistenceBrokerFactory.getOjb().
+                                         getComponentContainer().getInstance(TransactionManagerFactory.class);
+	}
+
+
+    //////////////////////////////////////////////////////
+    // TransactionFactory protocol
+    //////////////////////////////////////////////////////
+
+	/**
+	 * @see org.apache.ojb.otm.transaction.TransactionFactory#getTransactionForConnection(OTMConnection)
+	 */
+	public Transaction getTransactionForConnection(OTMConnection connection)
+	{
+        if (!(connection instanceof BaseConnection))
+        {
+            throw new TransactionFactoryException("Unknown connection type");
+        }
+        BaseConnection baseConnection = (BaseConnection) connection;
+
+		javax.transaction.Transaction jtaTx = getJTATransaction();
+        if (jtaTx == null)
+        {
+            throw new TransactionFactoryException("Unable to get the JTA Transaction");
+        }
+
+        Transaction tx = (Transaction) _transactionMap.get(jtaTx);
+        if (tx == null)
+        {
+            tx = new Transaction();
+            _transactionMap.put(jtaTx, tx);
+        }
+
+        // ensure that this connection is registered into this transaction
+        tx.registerConnection(baseConnection);
+        return tx;
+	}
+
+    /**
+     * @see org.apache.ojb.otm.transaction.TransactionFactory#acquireConnection
+     */
+    public OTMConnection acquireConnection(PersistenceConfiguration persistenceConf)
+    {
+        return new ManagedConnection(persistenceConf);
+    }
+
+
+    //////////////////////////////////////////
+    // Other operations
+    //////////////////////////////////////////
+
+    public javax.transaction.Transaction getJTATransaction()
+    {
+        if(tm == null)
+        {
+            try
+            {
+                tm = transactionManagerFactory.getTransactionManager();
+            }
+            catch (TransactionManagerFactoryException e)
+            {
+                throw new TransactionFactoryException("Can't instantiate TransactionManagerFactory", e);
+            }
+        }
+        try
+        {
+            return tm.getTransaction();
+        }
+        catch(SystemException e)
+        {
+            throw new TransactionFactoryException("Error acquiring JTA Transaction", e);
+        }
+    }
+
+    private static class ManagedConnection extends BaseConnection
+    {
+        public ManagedConnection(PersistenceConfiguration persistenceConf)
+        {
+            super(persistenceConf);
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionBegin()
+         */
+        public void transactionBegin() throws TransactionException
+        {
+            // Nothing to do!
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionPrepare()
+         */
+        public void transactionPrepare() throws TransactionException
+        {
+            // Nothing to do, since all resources are managed by JTS and will be committed
+            // directly.
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionCommit()
+         */
+        public void transactionCommit() throws TransactionException
+        {
+            // Nothing to do, since all resources are managed by JTS and will be committed
+            // directly.
+        }
+
+        /**
+         * @see org.apache.ojb.otm.core.BaseConnection#transactionRollback()
+         */
+        public void transactionRollback() throws TransactionException
+        {
+            // Nothing to do, since all resources are managed by JTS and will be rolled back
+            // directly.
+        }
+
+    }
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactory.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactory.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactory.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactory.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,51 @@
+package org.apache.ojb.otm.transaction;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.otm.OTMConnection;
+import org.apache.ojb.otm.core.Transaction;
+
+/**
+ *
+ * Factory to fetch current transaction. The various implementations will handle
+ * the different implementation sceanrios, like managed and unmanaged platforms. 
+ * 
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ * 
+ */
+public interface TransactionFactory
+{
+    
+    /**
+     * 
+     *  Get the current Transaction.
+     * 
+     *  @return     the current Transaction
+     * 
+     */
+    public Transaction getTransactionForConnection(OTMConnection connection);
+    
+    /**
+     * 
+     *  Acquire new connection. Creates a new connection. Depending on the implementation of the
+     *  factory the connection could be associated to an existing transaction, or not.
+     * 
+     *  @return     new connection
+     * 
+     */
+    public OTMConnection acquireConnection(PersistenceConfiguration persistenceConf);
+}

Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactoryException.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactoryException.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactoryException.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactoryException.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,58 @@
+package org.apache.ojb.otm.transaction;
+
+import org.apache.ojb.otm.core.TransactionException;
+
+/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class TransactionFactoryException extends TransactionException
+{
+
+	/**
+	 * Constructor for TransactionFactoryException.
+	 */
+	public TransactionFactoryException()
+	{
+		super();
+	}
+
+	/**
+	 * Constructor for TransactionFactoryException.
+	 * @param msg
+	 */
+	public TransactionFactoryException(String msg)
+	{
+		super(msg);
+	}
+
+	/**
+	 * Constructor for TransactionFactoryException.
+	 * @param cause
+	 */
+	public TransactionFactoryException(Throwable cause)
+	{
+		super(cause);
+	}
+
+	/**
+	 * Constructor for TransactionFactoryException.
+	 * @param msg
+	 * @param cause
+	 */
+	public TransactionFactoryException(String msg, Throwable cause)
+	{
+		super(msg, cause);
+	}
+
+}

Added: db/ojb/trunk/proposals/otm/repository_junit_otm.xml
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/repository_junit_otm.xml?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/repository_junit_otm.xml (added)
+++ db/ojb/trunk/proposals/otm/repository_junit_otm.xml Sat Aug  5 05:18:12 2006
@@ -0,0 +1,219 @@
+<!-- Mapping of classes used in junit tests -->
+<!-- @version $Id: repository_junit_otm.xml 363589 2004-04-05 15:59:01 +0200 (Mo, 05 Apr 2004) brianm $ -->
+<!--
+#/* Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<!-- ************************************************* -->
+<!--      Classes for OTM dependent objects test       -->
+<!-- ************************************************* -->
+
+   <class-descriptor
+  class="org.apache.ojb.otm.Person"
+  table="OTM_PERSON"
+   >
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="firstname"
+     column="FIRSTNAME"
+     jdbc-type="VARCHAR"
+  />
+  <field-descriptor
+     name="lastname"
+     column="LASTNAME"
+     jdbc-type="VARCHAR"
+  />
+  <field-descriptor
+     name="mainAddressId"
+     column="MAIN_ADDRESS_ID"
+     jdbc-type="INTEGER"
+  />
+  <reference-descriptor
+     name="mainAddress"
+     class-ref="org.apache.ojb.otm.Address"
+     otm-dependent="true"
+  >
+     <foreignkey field-ref="mainAddressId"/>
+  </reference-descriptor>
+  <collection-descriptor
+     name="otherAddresses"
+     element-class-ref="org.apache.ojb.otm.AddressDesc"
+     collection-class="org.apache.ojb.broker.util.collections.ManageableArrayList"
+     otm-dependent="true"
+  >
+     <inverse-foreignkey field-ref="personId"/>
+  </collection-descriptor>
+   </class-descriptor>
+
+
+
+   <class-descriptor
+  class="org.apache.ojb.otm.Address"
+  table="OTM_ADDRESS"
+   >
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="country"
+     column="COUNTRY"
+     jdbc-type="VARCHAR"
+  />
+  <field-descriptor
+     name="city"
+     column="CITY"
+     jdbc-type="VARCHAR"
+  />
+  <field-descriptor
+     name="street"
+     column="STREET"
+     jdbc-type="VARCHAR"
+  />
+   </class-descriptor>
+
+
+
+   <class-descriptor
+  class="org.apache.ojb.otm.AddressDesc"
+  table="OTM_ADDRESS_DESC"
+   >
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="desc"
+     column="DESCRIPTION"
+     jdbc-type="VARCHAR"
+  />
+  <field-descriptor
+     name="personId"
+     column="PERSON_ID"
+     jdbc-type="INTEGER"
+  />
+  <field-descriptor
+     name="addressId"
+     column="ADDRESS_ID"
+     jdbc-type="INTEGER"
+  />
+  <reference-descriptor
+     name="person"
+     class-ref="org.apache.ojb.otm.Person"
+  >
+     <foreignkey field-ref="personId"/>
+  </reference-descriptor>
+  <reference-descriptor
+     name="address"
+     class-ref="org.apache.ojb.otm.Address"
+     otm-dependent="true"
+  >
+     <foreignkey field-ref="addressId"/>
+  </reference-descriptor>
+   </class-descriptor>
+
+<class-descriptor class="org.apache.ojb.otm.AbstractPerson">
+    <extent-class class-ref="org.apache.ojb.otm.LegalPerson"/>
+    <extent-class class-ref="org.apache.ojb.otm.NaturalPerson"/>
+</class-descriptor>
+
+<class-descriptor class="org.apache.ojb.otm.Debitor"
+        table="OTM_DEBITOR">
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor name="personId"
+                    column="PERSON_ID"
+                    jdbc-type="INTEGER"/>
+  <reference-descriptor name="abstractPerson"
+                        class-ref="org.apache.ojb.otm.AbstractPerson"
+                        otm-dependent="true">
+    <foreignkey field-ref="personId"/>
+  </reference-descriptor>
+</class-descriptor>
+
+<class-descriptor class="org.apache.ojb.otm.Address2"
+        table="OTM_ADDRESS2">
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor name="personId"
+                    column="PERSON_ID"
+                    jdbc-type="INTEGER"/>
+</class-descriptor>
+
+<class-descriptor class="org.apache.ojb.otm.LegalPerson"
+        table="OTM_PERSON2">
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="name"
+     column="NAME"
+     jdbc-type="VARCHAR"
+  />
+  <collection-descriptor name="addresses"
+                         element-class-ref="org.apache.ojb.otm.Address2"
+                         otm-dependent="true">
+    <inverse-foreignkey field-ref="personId"/>
+  </collection-descriptor>
+</class-descriptor>
+
+<class-descriptor class="org.apache.ojb.otm.NaturalPerson"
+        table="OTM_PERSON3">
+  <field-descriptor
+     name="id"
+     column="ID"
+     jdbc-type="INTEGER"
+     primarykey="true"
+     autoincrement="true"
+  />
+  <field-descriptor
+     name="name"
+     column="NAME"
+     jdbc-type="VARCHAR"
+  />
+  <collection-descriptor name="addresses"
+                         element-class-ref="org.apache.ojb.otm.Address2"
+                         otm-dependent="true">
+    <inverse-foreignkey field-ref="personId"/>
+  </collection-descriptor>
+</class-descriptor>
+
+<!-- Mapping of classes used in junit tests and tutorials ends here -->

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AbstractPerson.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AbstractPerson.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AbstractPerson.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AbstractPerson.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,41 @@
+package org.apache.ojb.otm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class AbstractPerson
+{
+    private int id;
+    protected Collection addresses = new ArrayList();
+    protected String name;
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public Collection getAddresses()
+    {
+        return addresses;
+    }
+
+    public void setAddresses(Collection addresses)
+    {
+        this.addresses = addresses;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,78 @@
+package org.apache.ojb.otm;
+
+/* Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+
+public class Address implements Serializable
+{
+
+    private int id;
+    private String country;
+    private String city;
+    private String street;
+
+    public Address()
+    {
+    }
+
+    public Address(String country, String city, String street)
+    {
+        this.country = country;
+        this.city = city;
+        this.street = street;
+    }
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public String getCountry()
+    {
+        return country;
+    }
+
+    public void setCountry(String country)
+    {
+        this.country = country;
+    }
+
+    public String getCity()
+    {
+        return city;
+    }
+
+    public void setCity(String city)
+    {
+        this.city = city;
+    }
+
+    public String getStreet()
+    {
+        return street;
+    }
+
+    public void setStreet(String street)
+    {
+        this.street = street;
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address2.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address2.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address2.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address2.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,39 @@
+package org.apache.ojb.otm;
+
+public class Address2
+{
+
+    private int id;
+    private int personId;
+    private Person person;
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public int getPersonId()
+    {
+        return personId;
+    }
+
+    public void setPersonId(int personId)
+    {
+        this.personId = personId;
+    }
+
+    public Person getPerson()
+    {
+        return person;
+    }
+
+    public void setPerson(Person person)
+    {
+        this.person = person;
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AddressDesc.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AddressDesc.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AddressDesc.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AddressDesc.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,100 @@
+package org.apache.ojb.otm;
+
+/* Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+
+public class AddressDesc implements Serializable
+{
+
+    private int id;
+    private String desc;
+    private int personId;
+    private Person person;
+    private int addressId;
+    private Address address;
+
+    public AddressDesc()
+    {
+    }
+
+    public AddressDesc(String desc, Address address)
+    {
+        this.desc = desc;
+        this.address = address;
+    }
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    public void setDesc(String desc)
+    {
+        this.desc = desc;
+    }
+
+    public int getPersonId()
+    {
+        return personId;
+    }
+
+    public void setPersonId(int personId)
+    {
+        this.personId = personId;
+    }
+
+    public Person getPerson()
+    {
+        return person;
+    }
+
+    public void setPerson(Person person)
+    {
+        this.person = person;
+    }
+
+    public int getAddressId()
+    {
+        return addressId;
+    }
+
+    public void setAddressId(int addressId)
+    {
+        this.addressId = addressId;
+    }
+
+    public Address getAddress()
+    {
+        return address;
+    }
+
+    public void setAddress(Address address)
+    {
+        this.address = address;
+    }
+
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AllTests.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AllTests.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AllTests.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AllTests.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,47 @@
+package org.apache.ojb.otm;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.ojb.broker.HsqldbShutdown;
+
+/**
+ * the facade to all TestCases in this package.
+ *
+ * @author Thomas Mahler
+ */
+public class AllTests extends junit.framework.TestSuite
+{
+    /** static reference to .class.
+     * Java does not provide any way to obtain the Class object from
+     * static method without naming it.
+     */
+    private static Class CLASS = AllTests.class;
+
+    /**
+     * runs the suite in a junit.textui.TestRunner.
+     */
+    public static void main(String[] args)
+    {
+        String[] arr = {CLASS.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+
+    /** build a TestSuite from all the TestCases in this package*/
+    public static Test suite()
+    {
+        TestSuite suite = new TestSuite();
+        suite.addTest(new TestSuite(OtmExamples.class));
+        suite.addTest(new TestSuite(LockTestUncommittedReads.class));
+        suite.addTest(new TestSuite(LockTestCommittedReads.class));
+        suite.addTest(new TestSuite(LockTestRepeatableReads.class));
+        suite.addTest(new TestSuite(LockTestSerializable.class));
+        suite.addTest(new TestSuite(SwizzleTests.class));
+        suite.addTest(new TestSuite(CopyTest.class));
+        suite.addTest(new TestSuite(DependentTests.class));
+
+        // BRJ: ensure shutdown of hsqldb
+        suite.addTestSuite(HsqldbShutdown.class);
+        return suite;
+    }
+
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/CopyTest.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/CopyTest.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/CopyTest.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/CopyTest.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,315 @@
+package org.apache.ojb.otm;
+
+/* Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.BidirectionalAssociationObjectA;
+import org.apache.ojb.broker.BidirectionalAssociationObjectB;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.Mammal;
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.Reptile;
+import org.apache.ojb.broker.Zoo;
+import org.apache.ojb.junit.OJBTestCase;
+import org.apache.ojb.odmg.shared.TestClassA;
+import org.apache.ojb.odmg.shared.TestClassB;
+import org.apache.ojb.otm.copy.MetadataObjectCopyStrategy;
+import org.apache.ojb.otm.copy.ObjectCopyStrategy;
+import org.apache.ojb.otm.copy.ReflectiveObjectCopyStrategy;
+import org.apache.ojb.otm.copy.SerializeObjectCopyStrategy;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.lock.LockingException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: matthew.baird
+ * Date: Jul 7, 2003
+ * Time: 2:10:49 PM
+ */
+public class CopyTest extends OJBTestCase
+{
+	private static Class CLASS = CopyTest.class;
+	private PersistenceBroker m_pb;
+	private static final int ITERATIONS = 10000;
+	private ObjectCopyStrategy m_mdcs = new MetadataObjectCopyStrategy();
+	private ObjectCopyStrategy m_scs = new SerializeObjectCopyStrategy();
+	private ObjectCopyStrategy m_rcs = new ReflectiveObjectCopyStrategy();
+	private TestKit _kit;
+	private OTMConnection _conn;
+	private Zoo m_zoo;
+	private TestClassA m_tca;
+	private BidirectionalAssociationObjectA m_baoa;
+
+	public CopyTest(String name)
+	{
+		super(name);
+	}
+
+	public void setUp() throws Exception
+	{
+		super.setUp();
+        ojbChangeReferenceSetting(TestClassA.class, "b", true, true, true, false);
+		ojbChangeReferenceSetting(TestClassB.class, "a", true, true, true, false);
+        m_pb = ojb.lookupBroker();
+		_kit = TestKit.getTestInstance();
+		_conn = _kit.acquireConnection(ojb.getDefaultConfiguration());
+	}
+
+	public void tearDown() throws Exception
+	{
+		m_pb.close();
+		_conn.close();
+		_conn = null;
+        super.tearDown();
+	}
+
+	public static void main(String[] args)
+	{
+		String[] arr = {CLASS.getName()};
+		junit.textui.TestRunner.main(arr);
+	}
+
+	public void testMetadataCopy() throws LockingException
+	{
+		TestClassA tca = generateTestData();
+		TestClassB tcb = tca.getB();
+		internalTest(m_mdcs, tca, tcb);
+	}
+
+	public void testSerializedCopy() throws LockingException
+	{
+		TestClassA tca = generateTestData();
+		TestClassB tcb = tca.getB();
+		internalTest(m_scs, tca, tcb);
+	}
+
+	public void testReflectiveCopy() throws LockingException
+	{
+		TestClassA tca = generateTestData();
+		TestClassB tcb = tca.getB();
+		internalTest(m_rcs, tca, tcb);
+	}
+
+	private void internalTest(ObjectCopyStrategy strategy, TestClassA a, TestClassB b)
+	{
+		TestClassA copy = (TestClassA) strategy.copy(a, m_pb);
+		assertTrue(a != copy);
+		assertTrue(copy.getOid().equals("someoid"));
+		assertTrue(copy.getValue1().equals("abc"));
+		assertTrue(copy.getValue2().equals("123"));
+		assertTrue(copy.getValue3() == 5);
+		assertTrue(copy.getB() != b);
+		assertTrue(copy.getB().getOid().equals("boid"));
+		assertTrue(copy.getB().getValue1().equals("hi there"));
+	}
+
+	public void testMetadataCopy2() throws LockingException
+	{
+		Zoo zoo = generateZoo();
+		internalTest2(m_mdcs, zoo);
+	}
+
+	public void testSerializeCopy2() throws LockingException
+	{
+		Zoo zoo = generateZoo();
+		internalTest2(m_scs, zoo);
+	}
+
+	public void testReflectiveCopy2() throws LockingException
+	{
+		Zoo zoo = generateZoo();
+		internalTest2(m_rcs, zoo);
+	}
+
+	/**
+	 * tests for recursion handling
+	 */
+	public void testMetadataCopy3() throws LockingException
+	{
+		BidirectionalAssociationObjectA a = generateBidirectional();
+		internalTest3(m_mdcs, a);
+	}
+
+	public void testSerializeCopy3() throws LockingException
+	{
+		BidirectionalAssociationObjectA a = generateBidirectional();
+		internalTest3(m_scs, a);
+	}
+
+	public void testReflectiveCopy3() throws LockingException
+	{
+		BidirectionalAssociationObjectA a = generateBidirectional();
+		internalTest3(m_rcs, a);
+	}
+
+	private void internalTest3(ObjectCopyStrategy strategy, BidirectionalAssociationObjectA a)
+	{
+		BidirectionalAssociationObjectA copy = (BidirectionalAssociationObjectA) strategy.copy(a, m_pb);
+		assertTrue(a != copy);
+		assertTrue(copy.getPk().equals("abc123"));
+		assertTrue(copy.getRelatedB().getPk().equals("xyz987"));
+	}
+
+	private void internalTest2(ObjectCopyStrategy strategy, Zoo zoo)
+	{
+		Zoo copy = (Zoo) strategy.copy(zoo, m_pb);
+		assertTrue(zoo != copy);
+		assertTrue(zoo.getAnimals().size() == copy.getAnimals().size());
+	}
+
+	private BidirectionalAssociationObjectA generateBidirectional() throws LockingException
+	{
+		if (m_baoa != null)
+		{
+			return m_baoa;
+		}
+		else
+		{
+			Transaction tx = _kit.getTransaction(_conn);
+			tx.begin();
+			BidirectionalAssociationObjectA a = new BidirectionalAssociationObjectA();
+			a.setPk("abc123");
+			Identity oid = _conn.getIdentity(a);
+			a = (BidirectionalAssociationObjectA) _conn.getObjectByIdentity(oid);
+			if (a == null)
+			{
+				a = new BidirectionalAssociationObjectA();
+				a.setPk("abc123");
+				_conn.makePersistent(a);
+				BidirectionalAssociationObjectB b = new BidirectionalAssociationObjectB();
+				b.setPk("xyz987");
+				_conn.makePersistent(b);
+				a.setRelatedB(b);
+				b.setRelatedA(a);
+			}
+			tx.commit();
+			m_baoa = a;
+			return m_baoa;
+		}
+	}
+
+
+	private Zoo generateZoo() throws LockingException
+	{
+		if (m_zoo != null)
+		{
+			return m_zoo;
+		}
+		else
+		{
+			Transaction tx = _kit.getTransaction(_conn);
+			tx.begin();
+            Zoo zoo;
+            try
+            {
+                zoo = new Zoo();
+                zoo.setZooId(1234);
+                Identity oid = _conn.getIdentity(zoo);
+                zoo = (Zoo) _conn.getObjectByIdentity(oid);
+                if (zoo == null)
+                {
+                    zoo = new Zoo();
+                    zoo.setZooId(1234);
+                    _conn.makePersistent(zoo);
+                    Mammal mammal = new Mammal();
+                    mammal.setName("molly");
+                    mammal.setNumLegs(4);
+                    mammal.setAge(55);
+                    zoo.addAnimal(mammal);
+                    _conn.makePersistent(mammal);
+                    Reptile reptile = new Reptile();
+                    reptile.setColor("green");
+                    reptile.setName("hubert");
+                    reptile.setAge(51);
+                    zoo.addAnimal(reptile);
+                    _conn.makePersistent(reptile);
+                }
+                tx.commit();
+            }
+            catch(RuntimeException e)
+            {
+                tx.rollback();
+                throw e;
+            }
+            m_zoo = zoo;
+			return m_zoo;
+		}
+	}
+
+	public void testPerformance() throws LockingException
+	{
+		long start = System.currentTimeMillis();
+		for (int i = 0; i < ITERATIONS; i++)
+		{
+			TestClassA tca = generateTestData();
+			TestClassB tcb = tca.getB();
+			TestClassA copy = (TestClassA) m_scs.copy(tca, m_pb);
+		}
+		long stop = System.currentTimeMillis();
+		System.out.println("testSerializedCopy took: " + (stop - start));
+		start = System.currentTimeMillis();
+		for (int i = 0; i < ITERATIONS; i++)
+		{
+			TestClassA tca = generateTestData();
+			TestClassB tcb = tca.getB();
+			TestClassA copy = (TestClassA) m_mdcs.copy(tca, m_pb);
+		}
+		stop = System.currentTimeMillis();
+		System.out.println("testMetadataCopy took: " + (stop - start));
+		start = System.currentTimeMillis();
+		for (int i = 0; i < ITERATIONS; i++)
+		{
+			TestClassA tca = generateTestData();
+			TestClassB tcb = tca.getB();
+			TestClassA copy = (TestClassA) m_rcs.copy(tca, m_pb);
+		}
+		stop = System.currentTimeMillis();
+		System.out.println("testReflectiveCopy took: " + (stop - start));
+	}
+
+	private TestClassA generateTestData() throws LockingException
+	{
+		if (m_tca != null)
+		{
+			return m_tca;
+		}
+		else
+		{
+			Transaction tx = _kit.getTransaction(_conn);
+			tx.begin();
+			TestClassA tca = new TestClassA();
+			tca.setOid("someoid");
+			Identity oid = _conn.getIdentity(tca);
+			tca = (TestClassA) _conn.getObjectByIdentity(oid);
+			if (tca == null)
+			{
+				tca = new TestClassA();
+				tca.setOid("someoid");
+				tca.setValue1("abc");
+				tca.setValue2("123");
+				tca.setValue3(5);
+				_conn.makePersistent(tca);
+				TestClassB tcb = new TestClassB();
+				tcb.setOid("boid");
+				tcb.setValue1("hi there");
+				_conn.makePersistent(tcb);
+				tca.setB(tcb);
+			}
+			tx.commit();
+			m_tca = tca;
+			return m_tca;
+		}
+	}
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Debitor.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Debitor.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Debitor.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Debitor.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,38 @@
+package org.apache.ojb.otm;
+
+public class Debitor
+{
+    private int id;
+    private AbstractPerson abstractPerson;
+    private int personId;
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+
+    public AbstractPerson getAbstractPerson()
+    {
+        return abstractPerson;
+    }
+
+    public void setAbstractPerson(AbstractPerson abstractPerson)
+    {
+        this.abstractPerson = abstractPerson;
+    }
+
+    public int getPersonId()
+    {
+        return personId;
+    }
+
+    public void setPersonId(int personId)
+    {
+        this.personId = personId;
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/DependentTests.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/DependentTests.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/DependentTests.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/DependentTests.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,272 @@
+package org.apache.ojb.otm;
+
+import java.util.Iterator;
+
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryFactory;
+import org.apache.ojb.junit.OJBTestCase;
+import org.apache.ojb.otm.core.Transaction;
+
+public class DependentTests extends OJBTestCase
+{
+    private TestKit _kit;
+    private OTMConnection _conn;
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _kit = TestKit.getTestInstance();
+        _conn = _kit.acquireConnection(ojb.getDefaultConfiguration());
+    }
+
+    public void tearDown() throws Exception
+    {
+        _conn.close();
+        _conn = null;
+        super.tearDown();
+    }
+
+    public static void main(String[] args)
+    {
+        String[] arr = {DependentTests.class.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+
+    public void testDependent() throws Exception
+    {
+        Person person = new Person("Ostap", "Bender");
+        Address address1 = new Address("Ukraine", "Odessa", "Deribasovskaya");
+        Address address2 = new Address("Ukraine", "Odessa", "Malaya Arnautskaya");
+        Address address3 = new Address("Brasil", "Rio de Janeiro", "Rua Professor Azevedo Marques");
+        Criteria emptyCriteria = new Criteria();
+        Query q;
+        Iterator it;
+
+        Transaction tx = _kit.getTransaction(_conn);
+        tx.begin();
+        // prepare tables for the test - empty them
+        q = QueryFactory.newQuery(AddressDesc.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        q = QueryFactory.newQuery(Person.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        q = QueryFactory.newQuery(Address.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        tx.commit();
+
+        person.setMainAddress(address1);
+        person.addOtherAddress("work", address2);
+        person.addOtherAddress("dream", address3);
+
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        // Cascade create
+        _conn.makePersistent(person);
+        tx.commit();
+
+        Identity oid = _conn.getIdentity(person);
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        person = (Person) _conn.getObjectByIdentity(oid);
+        assertTrue("person exists", (person != null));
+        assertTrue("main Address exists", (person.getMainAddress() != null));
+        assertEquals("main Address is correct", address1.getStreet(), person.getMainAddress().getStreet());
+        assertEquals("two other Addresses", 2, person.getOtherAddresses().size());
+        AddressDesc desc1 = (AddressDesc) person.getOtherAddresses().get(0);
+        assertEquals("1st other Address has correct description", "work", desc1.getDesc());
+        assertEquals("1st other Address is correct", address2.getStreet(), desc1.getAddress().getStreet());
+        AddressDesc desc2 = (AddressDesc) person.getOtherAddresses().get(1);
+        assertEquals("2nd other Address has correct description", "dream", desc2.getDesc());
+        assertEquals("2nd other Address is correct", address3.getStreet(), desc2.getAddress().getStreet());
+
+        // Delete dependent
+        person.setMainAddress(null);
+        person.getOtherAddresses().remove(1);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        person = (Person) _conn.getObjectByIdentity(oid);
+        assertTrue("main Address doesn't exist", (person.getMainAddress() == null));
+        assertEquals("one other Address", 1, person.getOtherAddresses().size());
+        desc2 = (AddressDesc) person.getOtherAddresses().get(0);
+        assertEquals("the other Address has correct description", "work", desc1.getDesc());
+        assertEquals("the other Address is correct", address2.getStreet(), desc1.getAddress().getStreet());
+
+        // Create dependent
+        person.setMainAddress(address1);
+        person.addOtherAddress("dream", address3);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        person = (Person) _conn.getObjectByIdentity(oid);
+        assertTrue("main Address exists", (person.getMainAddress() != null));
+        assertEquals("main Address is correct", address1.getStreet(), person.getMainAddress().getStreet());
+        assertEquals("two other Addresses", 2, person.getOtherAddresses().size());
+        desc1 = (AddressDesc) person.getOtherAddresses().get(0);
+        assertEquals("1st other Address has correct description", "work", desc1.getDesc());
+        assertEquals("1st other Address is correct", address2.getStreet(), desc1.getAddress().getStreet());
+        desc2 = (AddressDesc) person.getOtherAddresses().get(1);
+        assertEquals("2nd other Address has correct description", "dream", desc2.getDesc());
+        assertEquals("2nd other Address is correct", address3.getStreet(), desc2.getAddress().getStreet());
+
+        // Cascade delete
+        _conn.deletePersistent(person);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        person = (Person) _conn.getObjectByIdentity(oid);
+        assertTrue("person doesn't exist", (person == null));
+        q = QueryFactory.newQuery(AddressDesc.class, emptyCriteria);
+        it = _conn.getIteratorByQuery(q);
+        assertTrue("address descriptions don't exist", !it.hasNext());
+        q = QueryFactory.newQuery(Address.class, emptyCriteria);
+        it = _conn.getIteratorByQuery(q);
+        assertTrue("addresses don't exist", !it.hasNext());
+        tx.commit();
+    }
+
+    public void testDependent2() throws Exception
+    {
+        AbstractPerson person = new LegalPerson();
+        Debitor debitor = new Debitor();
+        Address2 address = new Address2();
+        Criteria emptyCriteria = new Criteria();
+        Query q;
+        Iterator it;
+
+        Transaction tx = _kit.getTransaction(_conn);
+        tx.begin();
+        // prepare tables for the test - empty them
+        q = QueryFactory.newQuery(Debitor.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        q = QueryFactory.newQuery(AbstractPerson.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        q = QueryFactory.newQuery(Address2.class, emptyCriteria);
+        for (it = _conn.getIteratorByQuery(q); it.hasNext(); ) {
+            _conn.deletePersistent(it.next());
+        }
+        tx.commit();
+
+        person.getAddresses().add(address);
+        debitor.setAbstractPerson(person);
+
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        // Cascade create
+        _conn.makePersistent(debitor);
+        tx.commit();
+
+        Identity debitorOid = _conn.getIdentity(debitor);
+        Identity personOid = _conn.getIdentity(person);
+        int addrId = address.getId();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        debitor = (Debitor) _conn.getObjectByIdentity(debitorOid);
+        assertNotNull("debitor does not exist", debitor);
+        person = debitor.getAbstractPerson();
+        assertNotNull("person does not exist", person);
+        assertTrue("person has not the expected type", (person instanceof LegalPerson));
+        assertEquals("address does not exist", 1, person.getAddresses().size());
+        address = (Address2) person.getAddresses().iterator().next();
+        assertEquals("addressid is not correct", addrId, address.getId());
+
+        // Delete dependent
+        person.getAddresses().clear();
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        debitor = (Debitor) _conn.getObjectByIdentity(debitorOid);
+        person = (LegalPerson) debitor.getAbstractPerson();
+        assertEquals("address was not deleted", person.getAddresses().size(), 0);
+
+        // Create dependent
+        person.getAddresses().add(address);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        debitor = (Debitor) _conn.getObjectByIdentity(debitorOid);
+        person = (LegalPerson) debitor.getAbstractPerson();
+        assertEquals("address does not exist", person.getAddresses().size(), 1);
+        tx.commit();
+
+        // Change dependent reference, should delete old dependant
+        person = new NaturalPerson();
+        person.setName("before");
+        debitor.setAbstractPerson(person);
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        _conn.makePersistent(debitor);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        assertTrue("old person has not been deleted", (_conn.getObjectByIdentity(personOid) == null));
+        q = QueryFactory.newQuery(Address2.class, emptyCriteria);
+        it = _conn.getIteratorByQuery(q);
+        assertTrue("old address has not been deleted", !it.hasNext());
+        person = debitor.getAbstractPerson();
+        assertTrue("new person has unexpected type", (person instanceof NaturalPerson));
+        assertTrue("person does not have correct name", "before".equals(person.getName()));
+        tx.commit();
+
+        person.setName("after");
+        assertTrue("name of person was not saved", "after".equals(debitor.getAbstractPerson().getName()));
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        _conn.makePersistent(debitor);
+        tx.commit();
+        assertTrue("name of person was not saved: " + debitor.getAbstractPerson().getName(),
+                   "after".equals(debitor.getAbstractPerson().getName()));
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        debitor = (Debitor) _conn.getObjectByIdentity(debitorOid);
+        person = debitor.getAbstractPerson();
+        assertTrue("name of person was not saved: " + debitor.getAbstractPerson().getName(),
+                   "after".equals(debitor.getAbstractPerson().getName()));
+        // Cascade delete
+        _conn.deletePersistent(debitor);
+        tx.commit();
+
+        _conn.invalidateAll();
+        tx = _kit.getTransaction(_conn);
+        tx.begin();
+        debitor = (Debitor) _conn.getObjectByIdentity(debitorOid);
+        assertNull("debitor still exists", debitor);
+        q = QueryFactory.newQuery(AbstractPerson.class, emptyCriteria);
+        it = _conn.getIteratorByQuery(q);
+        assertTrue("persons still exist", !it.hasNext());
+        tx.commit();
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LegalPerson.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LegalPerson.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LegalPerson.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LegalPerson.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,5 @@
+package org.apache.ojb.otm;
+
+public class LegalPerson extends AbstractPerson
+{
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestBase.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestBase.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestBase.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestBase.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,123 @@
+package org.apache.ojb.otm;
+
+/* Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.ojb.broker.Article;
+import org.apache.ojb.junit.OJBTestCase;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.lock.LockingException;
+import org.apache.ojb.otm.lock.ObjectLock;
+import org.apache.ojb.otm.lock.isolation.TransactionIsolation;
+import org.apache.ojb.otm.lock.wait.NoWaitStrategy;
+import org.apache.ojb.otm.lock.wait.TimeoutStrategy;
+
+/**
+ * This is the base abstract class for all isolation TestSuites
+ * based on the ODMG locking documentation
+ */
+public abstract class LockTestBase extends OJBTestCase
+{
+    protected TestKit _kit;
+    protected OTMConnection _conn1;
+    protected OTMConnection _conn2;
+    protected Transaction _tx1;
+    protected Transaction _tx2;
+    protected ObjectLock _lock;
+    protected TransactionIsolation _isolation;
+
+    public LockTestBase(String name)
+    {
+        super(name);
+    }
+
+    protected abstract TransactionIsolation newIsolation();
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _kit = TestKit.getTestInstance();
+        _kit.setLockWaitStrategy(new NoWaitStrategy());
+        _isolation = newIsolation();
+        try
+        {
+            _conn1 = _kit.acquireConnection(ojb.getDefaultConfiguration());
+            _tx1 = _kit.getTransaction(_conn1);
+            _tx1.begin();
+
+            _conn2 = _kit.acquireConnection(ojb.getDefaultConfiguration());
+            _tx2 = _kit.getTransaction(_conn2);
+            _tx2.begin();
+
+            Article obj =  Article.createInstance();
+            _lock = new ObjectLock(_conn1.getIdentity(obj));
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    public void tearDown() throws Exception
+    {
+        try
+        {
+            _tx1.rollback();
+	    _conn1.close();
+            _conn1 = null;
+
+            _tx2.rollback();
+	    _conn2.close();
+            _conn2 = null;
+        }
+        catch (Throwable t)
+        {
+        }
+        _kit.setLockWaitStrategy(new TimeoutStrategy());
+        super.tearDown();
+    }
+
+    protected boolean readLock(Transaction tx)
+    {
+        try
+        {
+            _isolation.readLock(tx, _lock);
+            return true;
+        }
+        catch (LockingException ex)
+        {
+            return false;
+        }
+    }
+
+    protected boolean writeLock(Transaction tx)
+    {
+        try
+        {
+            _isolation.writeLock(tx, _lock);
+            return true;
+        }
+        catch (LockingException ex)
+        {
+            return false;
+        }
+    }
+
+    protected boolean releaseLock(Transaction tx)
+    {
+        _lock.releaseLock(tx);
+        return true;
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestCommittedReads.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestCommittedReads.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestCommittedReads.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestCommittedReads.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,147 @@
+package org.apache.ojb.otm;
+
+/**
+ * This is the TestSuite based on the ODMG locking documentation
+ */
+import org.apache.ojb.otm.lock.isolation.TransactionIsolation;
+import org.apache.ojb.otm.lock.isolation.ReadCommittedIsolation;
+
+public class LockTestCommittedReads extends LockTestBase
+{
+    private static Class CLASS = LockTestCommittedReads.class;
+
+    public LockTestCommittedReads(String name)
+    {
+        super(name);
+    }
+
+    protected TransactionIsolation newIsolation()
+    {
+        return new ReadCommittedIsolation();
+    }
+
+    /**
+     * Test 1
+     */
+    public void testSingleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test3
+     */
+    public void testReadThenWrite()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 4
+     */
+    public void testSingleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 5
+     */
+    public void testWriteThenRead()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test 6
+     */
+    public void testMultipleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+    }
+
+    /**
+     * Test 8
+     */
+    public void testWriteWithExistingReader()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 10
+     */
+    public void testWriteWithMultipleReaders()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 12
+     */
+    public void testWriteWithMultipleReadersOn1()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 13
+     */
+    public void testReadWithExistingWriter()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!readLock(_tx2));
+    }
+
+    /**
+     * Test 14
+     */
+    public void testMultipleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 15
+     */
+    public void testReleaseReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 17
+     */
+    public void testReleaseWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 18
+     */
+    public void testReadThenRead()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    public static void main(String[] args)
+    {
+        String[] arr = {CLASS.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestRepeatableReads.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestRepeatableReads.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestRepeatableReads.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestRepeatableReads.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,147 @@
+package org.apache.ojb.otm;
+
+/**
+ * This is the TestSuite based on the ODMG locking documentation
+ */
+import org.apache.ojb.otm.lock.isolation.TransactionIsolation;
+import org.apache.ojb.otm.lock.isolation.RepeatableReadIsolation;
+
+public class LockTestRepeatableReads extends LockTestBase
+{
+    private static Class CLASS = LockTestRepeatableReads.class;
+
+    public LockTestRepeatableReads(String name)
+    {
+        super(name);
+    }
+
+    protected TransactionIsolation newIsolation()
+    {
+        return new RepeatableReadIsolation();
+    }
+
+    /**
+     * Test 1
+     */
+    public void testSingleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test3
+     */
+    public void testReadThenWrite()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 4
+     */
+    public void testSingleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 5
+     */
+    public void testWriteThenRead()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test 6
+     */
+    public void testMultipleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+    }
+
+    /**
+     * Test 8
+     */
+    public void testWriteWithExistingReader()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 10
+     */
+    public void testWriteWithMultipleReaders()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 12
+     */
+    public void testWriteWithMultipleReadersOn1()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(!writeLock(_tx1));
+    }
+
+    /**
+     * Test 13
+     */
+    public void testReadWithExistingWriter()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!readLock(_tx2));
+    }
+
+    /**
+     * Test 14
+     */
+    public void testMultipleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 15
+     */
+    public void testReleaseReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 17
+     */
+    public void testReleaseWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 18
+     */
+    public void testReadThenRead()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    public static void main(String[] args)
+    {
+        String[] arr = {CLASS.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestSerializable.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestSerializable.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestSerializable.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestSerializable.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,148 @@
+package org.apache.ojb.otm;
+
+/**
+ * This is the TestSuite based on the ODMG locking documentation
+ */
+import org.apache.ojb.otm.lock.isolation.TransactionIsolation;
+import org.apache.ojb.otm.lock.isolation.SerializableIsolation;
+
+public class LockTestSerializable extends LockTestBase
+{
+    private static Class CLASS = LockTestSerializable.class;
+
+    public LockTestSerializable(String name)
+    {
+        super(name);
+    }
+
+    protected TransactionIsolation newIsolation()
+    {
+        return new SerializableIsolation();
+    }
+
+    /**
+     * Test 1
+     */
+    public void testSingleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test3
+     */
+    public void testReadThenWrite()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 4
+     */
+    public void testSingleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 5
+     */
+    public void testWriteThenRead()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test 6
+     */
+    public void testMultipleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(!readLock(_tx2));
+    }
+
+    /**
+     * Test 8
+     */
+    public void testWriteWithExistingReader()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 10
+     */
+    public void testWriteWithMultipleReaders()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(!readLock(_tx2));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 12
+     */
+    public void testWriteWithMultipleReadersOn1()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(!readLock(_tx2));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 13
+     */
+    public void testReadWithExistingWriter()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!readLock(_tx2));
+    }
+
+    /**
+     * Test 14
+     */
+    public void testMultipleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 15
+     */
+    public void testReleaseReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 17
+     */
+    public void testReleaseWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 18
+     */
+    public void testReadThenRead()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    public static void main(String[] args)
+    {
+        String[] arr = {CLASS.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+
+}

Added: db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestUncommittedReads.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestUncommittedReads.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestUncommittedReads.java (added)
+++ db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestUncommittedReads.java Sat Aug  5 05:18:12 2006
@@ -0,0 +1,147 @@
+package org.apache.ojb.otm;
+
+/**
+ * This is the TestSuite based on the ODMG locking documentation
+ */
+import org.apache.ojb.otm.lock.isolation.TransactionIsolation;
+import org.apache.ojb.otm.lock.isolation.ReadUncommittedIsolation;
+
+public class LockTestUncommittedReads extends LockTestBase
+{
+    private static Class CLASS = LockTestUncommittedReads.class;
+
+    public LockTestUncommittedReads(String name)
+    {
+        super(name);
+    }
+
+    protected TransactionIsolation newIsolation()
+    {
+        return new ReadUncommittedIsolation();
+    }
+
+    /**
+     * Test 1
+     */
+    public void testSingleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test3
+     */
+    public void testReadThenWrite()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 4
+     */
+    public void testSingleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 5
+     */
+    public void testWriteThenRead()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    /**
+     * Test 6
+     */
+    public void testMultipleReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+    }
+
+    /**
+     * Test 8
+     */
+    public void testWriteWithExistingReader()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 10
+     */
+    public void testWriteWithMultipleReaders()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 12
+     */
+    public void testWriteWithMultipleReadersOn1()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx2));
+        assertTrue(writeLock(_tx1));
+    }
+
+    /**
+     * Test 13
+     */
+    public void testReadWithExistingWriter()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(readLock(_tx2));
+    }
+
+    /**
+     * Test 14
+     */
+    public void testMultipleWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(!writeLock(_tx2));
+    }
+
+    /**
+     * Test 15
+     */
+    public void testReleaseReadLock()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 17
+     */
+    public void testReleaseWriteLock()
+    {
+        assertTrue(writeLock(_tx1));
+        assertTrue(releaseLock(_tx1));
+        assertTrue(writeLock(_tx2));
+    }
+
+    /**
+     * Test 18
+     */
+    public void testReadThenRead()
+    {
+        assertTrue(readLock(_tx1));
+        assertTrue(readLock(_tx1));
+    }
+
+    public static void main(String[] args)
+    {
+        String[] arr = {CLASS.getName()};
+        junit.textui.TestRunner.main(arr);
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org