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 [1/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...
Author: arminw
Date: Sat Aug 5 05:18:12 2006
New Revision: 428990
URL: http://svn.apache.org/viewvc?rev=428990&view=rev
Log:
move OTM layer to archive
Added:
db/ojb/trunk/proposals/otm/
db/ojb/trunk/proposals/otm/java/
db/ojb/trunk/proposals/otm/java/org/
db/ojb/trunk/proposals/otm/java/org/apache/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/EditingContext.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/Kit.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMConnection.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMKit.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/CloneableObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/MetadataObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/NoOpObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/OjbCloneable.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ReflectiveObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/BaseConnection.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/ConcreteEditingContext.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/ConnectionException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/LockingPassthruException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/OTMGenericException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/QueryPreparationRuntimeException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/Transaction.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/TransactionAbortedException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/TransactionException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/TransactionInProgressException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/TransactionListener.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/TransactionNotInProgressException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/kit/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/kit/SimpleKit.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/IsolationFactory.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/LockListener.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/LockManager.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/LockType.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/LockingException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/ObjectLock.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/UnknownIsolationException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/AbstractIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/ReadCommittedIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/ReadUncommittedIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/RepeatableReadIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/SerializableIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/isolation/TransactionIsolation.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/map/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/map/InMemoryLockMap.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/map/LockMap.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/ConcurrentModificationException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/DeadlockException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/LockWaitStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/NoWaitStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/lock/wait/TimeoutStrategy.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/Hollow.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/IllegalObjectStateException.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/PersistentClean.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/PersistentDeleted.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/PersistentDirty.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/PersistentNew.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/PersistentNewDeleted.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/State.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/states/Transient.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/CopySwizzling.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/NoSwizzling.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/swizzle/Swizzling.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/LocalTransactionFactory.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/ManagedTransactionFactory.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactory.java
db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/transaction/TransactionFactoryException.java
db/ojb/trunk/proposals/otm/repository_junit_otm.xml
db/ojb/trunk/proposals/otm/test/
db/ojb/trunk/proposals/otm/test/org/
db/ojb/trunk/proposals/otm/test/org/apache/
db/ojb/trunk/proposals/otm/test/org/apache/ojb/
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AbstractPerson.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Address2.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AddressDesc.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/AllTests.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/CopyTest.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Debitor.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/DependentTests.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LegalPerson.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestBase.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestCommittedReads.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestRepeatableReads.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestSerializable.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/LockTestUncommittedReads.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/MtoNTest.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/MultipleConnectionsTest.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/NaturalPerson.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/OtmExamples.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/Person.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/SwizzleTests.java
db/ojb/trunk/proposals/otm/test/org/apache/ojb/otm/TestKit.java
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/EditingContext.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/EditingContext.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/EditingContext.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/EditingContext.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,88 @@
+package org.apache.ojb.otm;
+
+/* 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.Identity;
+import org.apache.ojb.otm.lock.LockingException;
+import org.apache.ojb.otm.states.State;
+
+import java.util.Collection;
+
+/**
+ *
+ * The EditingContext contains and manages the set of object read/edited within the context of a
+ * transaction. Logically, this could be considered similar to a document that is being edited.
+ * During commit, all objects within this transaction that are marked as being written to (ones
+ * with a write lock) are written back to the persistent store.
+ *
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ *
+ */
+public interface EditingContext
+{
+
+ /**
+ *
+ * Insert the given object into the EditingContext, acquiring the specified lock.
+ *
+ * @param oid the identity of the object to be inserted
+ * @param userObject the object to insert, for user operations
+ * @param lock the lock to be acquired.
+ * @throws LockingException thrown by the Lock Manager to avoid deadlocks. The insertion
+ * could be re-attempted if the lock fails.
+ *
+ */
+ public void insert (Identity oid, Object userObject, int lock)
+ throws LockingException;
+
+ /**
+ *
+ * Remove a managed object from the management of this EditingContext. All edits on the object
+ * will be lost. All locks kept by this object will be released.
+ *
+ * @param oid the Identity of the object to be removed from this context.
+ *
+ */
+ public void remove (Identity oid);
+
+ /**
+ *
+ * Lookup object with the given oid in the Context.
+ *
+ * @param oid the oid of the object to lookup
+ *
+ */
+ public Object lookup (Identity oid)
+ throws LockingException;
+
+ /**
+ * lookup the state of an object, given the oid, in the context
+ * @param oid
+ * @return the state of that object in the context, null if the object is not in the context
+ * @throws LockingException
+ */
+ State lookupState(Identity oid)
+ throws LockingException;
+
+ void setState(Identity oid, State state);
+
+ Collection getAllObjectsInContext();
+
+ /**
+ * Rollback all changes made during this transaction to the given object.
+ */
+ public void refresh(Identity oid, Object object);
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/Kit.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/Kit.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/Kit.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/Kit.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,71 @@
+package org.apache.ojb.otm;
+
+/* 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.Identity;
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.otm.copy.ObjectCopyStrategy;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.lock.map.LockMap;
+import org.apache.ojb.otm.lock.wait.LockWaitStrategy;
+import org.apache.ojb.otm.swizzle.Swizzling;
+
+/**
+ * The Kit provides the point of entry for any OTM client
+ *
+ * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
+ */
+public interface Kit
+{
+ /**
+ * Acquire an open OTMConnection
+ *
+ * @param persistenceConf
+ * @return
+ */
+ OTMConnection acquireConnection(PersistenceConfiguration persistenceConf);
+
+ /**
+ * Obtain the transaction this connection is bound to
+ */
+ Transaction getTransaction(OTMConnection conn);
+
+ /**
+ * @todo document
+ */
+ Swizzling getSwizzlingStrategy();
+
+ /**
+ * @todo document
+ */
+ LockWaitStrategy getLockWaitStrategy();
+
+ /**
+ * @todo document
+ */
+ LockMap getLockMap();
+
+ /**
+ * @todo document
+ */
+ ObjectCopyStrategy getCopyStrategy(Identity oid);
+
+ /**
+ * @todo document
+ */
+ boolean isImplicitLockingUsed();
+
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMConnection.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMConnection.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMConnection.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMConnection.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,266 @@
+package org.apache.ojb.otm;
+
+/* 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.Collection;
+import java.util.Iterator;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.cache.ObjectCache;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.otm.lock.LockingException;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.odmg.oql.EnhancedOQLQuery;
+import org.odmg.OQLQuery;
+
+/**
+ *
+ * A OTMConnection within the given Environment
+ *
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ */
+public interface OTMConnection
+{
+
+ /**
+ *
+ * Make the given object persistent by inserting it into the database.
+ * Also read locks the object (OTM will automatically lock
+ * it for write on transaction commit if the object will appear
+ * to be modified).
+ *
+ * @param object the object to be made persistent
+ *
+ */
+ public void makePersistent(Object object)
+ throws LockingException;
+
+ /**
+ * Obtain the Transaction this connection is associated with
+ */
+ public Transaction getTransaction();
+
+ /**
+ * Associate this connection with a given transaction.
+ */
+ public void setTransaction(Transaction tx);
+
+ /**
+ *
+ * Mark the given object for deletion from the persistent store. The object would then become
+ * a transient object, rather than a persistent one.
+ *
+ * @param obj the object to delete
+ *
+ */
+ public void deletePersistent(Object obj)
+ throws LockingException;
+
+ /**
+ *
+ * Lock the given object for Write. Only write locked objects are persisted back to the
+ * database. Changes to read objects are not inserted back into the database.
+ *
+ * @param object the object to be locked for write.
+ *
+ */
+ public void lockForWrite(Object object)
+ throws LockingException;
+
+ /**
+ *
+ * Get the object with the given Identity from the persistent store. By default, the fetch is
+ * for read. (OTM will automatically lock it for write on transaction commit
+ * if the object will appear to be modified).
+ *
+ * @param oid the Identity of the object to fetch
+ * @return the object from the persistent store.
+ * @throws LockingException thrown by the LockManager to avoid deadlocks. The fetch could be
+ * re-submitted.
+ *
+ */
+ public Object getObjectByIdentity(Identity oid)
+ throws LockingException;
+
+ /**
+ *
+ * Get the object with the given Identity from the persistent store with the given lock value.
+ *
+ * @param oid the Identity of the object to fetch
+ * @param lock the lock that need to be acquired on the object
+ * Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
+ * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
+ * in this case the lock will be automatically upgraded to the write lock on transaction commit;
+ * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
+ *
+ * @return the object from the persistent store.
+ * @throws LockingException thrown by the LockManager to avoid a deadlock.
+ *
+ */
+ public Object getObjectByIdentity(Identity oid, int lock)
+ throws LockingException;
+
+ /**
+ * @param query The query to execute
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByQuery(Query query);
+
+ /**
+ * @param query The query to execute
+ * @param lock the lock that need to be acquired on the object
+ * Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
+ * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
+ * in this case the lock will be automatically upgraded to the write lock on transaction commit;
+ * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked with the given lock value.
+ */
+ public Iterator getIteratorByQuery(Query query, int lock);
+
+ /**
+ * @param query The OQL query to execute
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByOQLQuery(OQLQuery query);
+
+ /**
+ * @param query The OQL query to execute
+ * @param lock the lock that need to be acquired on the object
+ * Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
+ * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
+ * in this case the lock will be automatically upgraded to the write lock on transaction commit;
+ * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByOQLQuery(OQLQuery query, int lock);
+
+ /**
+ * @param query The query to execute
+ * @param lock the lock that need to be acquired on the object
+ * Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
+ * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
+ * in this case the lock will be automatically upgraded to the write lock on transaction commit;
+ * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked with the given lock value.
+ */
+ public Collection getCollectionByQuery(Query query, int lock);
+
+ /**
+ * @param query The query to execute
+ * @return an Iterator that iterates Objects of class c if calling the .next()
+ * method. The returned objects are locked for read.
+ */
+ public Collection getCollectionByQuery(Query query);
+
+ /**
+ * Get the identity of the object
+ * @param object The object
+ * @return the identity of the object
+ */
+ public Identity getIdentity(Object object);
+
+ public ClassDescriptor getDescriptorFor(Class clazz);
+
+ /**
+ *
+ * Get the EditingContext associated with the transaction to which this connection belongs.
+ * EditingContext contains and manages the set of objects read/edited within the current
+ * transaction.
+ *
+ * @return EditingContext associated with current Transaction
+ *
+ */
+ public EditingContext getEditingContext();
+
+ /**
+ * In the case if the program need to change the objects
+ * via direct JDBC call, it should first call invalidate()
+ * for the object, which will lock the object for write
+ * and tell OJB OTM that it must be re-read from the database,
+ * only after that you shold perform JDBC operation.
+ * NOTE: it is not recommended to use read-uncommitted isolation
+ * if you want this feature to work correctly.
+ */
+ public void invalidate(Identity oid)
+ throws LockingException;
+
+ /**
+ * clear the underlying caches
+ */
+ public void invalidateAll()
+ throws LockingException;
+
+ /**
+ * returns a new OQL Query. This OQL query is Enhanced, meaning it does
+ * the ODMG functionality as well as some additional OJB specific, non
+ * portable functionality.
+ * @return the new OQLQuery
+ */
+ public EnhancedOQLQuery newOQLQuery();
+
+ /**
+ * returns a new OQL Query. This OQL query is Enhanced, meaning it does
+ * the ODMG functionality as well as some additional OJB specific, non
+ * portable functionality.
+ * @param lock the lock that need to be acquired on the object
+ * Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to database;
+ * LockType.READ_LOCK (aka optimistic lock) - changes to the object will be written to the database,
+ * in this case the lock will be automatically upgraded to the write lock on transaction commit;
+ * LockType.WRITE_LOCK (aka pessimistic lock) - changes to the object will be written to the database.
+ * @return the new OQLQuery
+ */
+ public EnhancedOQLQuery newOQLQuery(int lock);
+
+ /**
+ * return the number of objects that would be returned from this query
+ * @param query
+ * @return the number of objects that would be returned from this query
+ */
+ int getCount(Query query);
+
+ /**
+ * Close the OTMConnection
+ */
+ void close();
+
+ /**
+ * check if the OTMConnection is closed
+ */
+
+ boolean isClosed();
+
+ /**
+ * get the global cache
+ * @return
+ */
+ ObjectCache serviceObjectCache();
+
+ /**
+ * Updates the values in the object from the data in data store.
+ * The state of the object becomes "Persistent-clean".
+ */
+ void refresh(Object object);
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMKit.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMKit.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMKit.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/OTMKit.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,91 @@
+package org.apache.ojb.otm;
+
+/* 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.Identity;
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.otm.copy.ObjectCopyStrategy;
+import org.apache.ojb.otm.core.Transaction;
+import org.apache.ojb.otm.lock.map.LockMap;
+import org.apache.ojb.otm.lock.wait.LockWaitStrategy;
+import org.apache.ojb.otm.swizzle.Swizzling;
+import org.apache.ojb.otm.transaction.TransactionFactory;
+
+/**
+ *
+ * OTMKit implementations provide the initial point of entry
+ * into the OTM layer.
+ *
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah</a>
+ *
+ */
+public abstract class OTMKit implements Kit
+{
+ /**
+ * Obtain an OTMConnection for the given persistence broker key
+ */
+ public OTMConnection acquireConnection(PersistenceConfiguration persistenceConf)
+ {
+ TransactionFactory txFactory = getTransactionFactory();
+
+ return txFactory.acquireConnection(persistenceConf);
+ }
+
+ /**
+ * Obtain the transaction which <code>conn</code> is currently
+ * bound to.
+ */
+ public Transaction getTransaction(OTMConnection conn)
+ {
+ TransactionFactory txFactory = getTransactionFactory();
+ Transaction tx = txFactory.getTransactionForConnection(conn);
+ tx.setKit(this);
+ return tx;
+ }
+
+ ////////////////////////////
+ // Abstract Methods
+ ////////////////////////////
+
+ protected abstract TransactionFactory getTransactionFactory();
+
+ public abstract Swizzling getSwizzlingStrategy();
+
+ public abstract LockWaitStrategy getLockWaitStrategy();
+
+ public abstract LockMap getLockMap();
+
+ public abstract ObjectCopyStrategy getCopyStrategy(Identity oid);
+
+ /**
+ * Should OTM implicitely read lock all objects that are reachable
+ * from the explicitely locked object? The updates to the read locked
+ * objects are automatically stored to the database at the end
+ * of transaction.
+ **/
+ public abstract boolean isImplicitLockingUsed();
+
+ /**
+ * Should OTM verify each inserted object for presence in the database?
+ **/
+ public abstract boolean isInsertVerified();
+
+ /**
+ * Should OTM perform INSERTs for the given object eagerly or during commit?
+ **/
+ public abstract boolean isEagerInsert(Object obj);
+
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/CloneableObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/CloneableObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/CloneableObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/CloneableObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,57 @@
+package org.apache.ojb.otm.copy;
+
+/* 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.PersistenceBroker;
+
+
+/**
+ * @author matthew.baird
+ */
+public class CloneableObjectCopyStrategy implements ObjectCopyStrategy
+{
+ /**
+ * If users want to implement clone on all their objects, we can use this
+ * to make copies. This is hazardous as user may mess it up, but it is also
+ * potentially the fastest way of making a copy.
+ *
+ * Usually the OjbCloneable interface should just be delegating to the clone()
+ * operation that the user has implemented.
+ *
+ * @see org.apache.ojb.otm.copy.ObjectCopyStrategy#copy(Object)
+ *
+ */
+ public Object copy(Object obj, PersistenceBroker broker)
+ throws ObjectCopyException
+ {
+ if (obj instanceof OjbCloneable)
+ {
+ try
+ {
+ return ((OjbCloneable) obj).ojbClone();
+ }
+ catch (Exception e)
+ {
+ throw new ObjectCopyException(e);
+ }
+ }
+ else
+ {
+ throw new ObjectCopyException("Object must implement OjbCloneable in order to use the"
+ + " CloneableObjectCopyStrategy");
+ }
+ }
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/MetadataObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/MetadataObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/MetadataObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/MetadataObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,216 @@
+package org.apache.ojb.otm.copy;
+
+/* 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.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.core.proxy.CollectionProxy;
+import org.apache.ojb.broker.core.proxy.ProxyFactory;
+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;
+import org.apache.ojb.broker.util.IdentityMapFactory;
+
+/**
+ * recursively copies an object based on the ClassDescriptor
+ * User: matthew.baird
+ * Date: Jul 7, 2003
+ * Time: 1:41:58 PM
+ */
+public final class MetadataObjectCopyStrategy implements ObjectCopyStrategy
+{
+ private static final ReflectiveObjectCopyStrategy _reflective = new ReflectiveObjectCopyStrategy();
+ private static final SerializeObjectCopyStrategy _serialize = new SerializeObjectCopyStrategy();
+
+ /**
+ * Uses an IdentityMap to make sure we don't recurse infinitely on the same object in a cyclic object model.
+ * Proxies
+ * @param obj
+ * @return
+ */
+ public Object copy(final Object obj, final PersistenceBroker broker)
+ {
+ return clone(obj, IdentityMapFactory.getIdentityMap(), broker);
+ }
+
+ private static Object clone(final Object toCopy, final Map objMap, final PersistenceBroker broker)
+ {
+ /**
+ * first, check to make sure we aren't recursing to some object that we've already copied.
+ * if the toCopy is in the objMap, just return it.
+ */
+ if (objMap.containsKey(toCopy)) return objMap.get(toCopy);
+ /**
+ * if null, return null, duh
+ */
+ if (toCopy == null)
+ return null;
+
+ /**
+ * if this is a proxy, just copy the proxy, don't materialize it, and stop recursing
+ */
+ ProxyFactory proxyFactory = broker.getConfiguration().getOjb().getProxyFactory();
+ if (proxyFactory.isVirtualOjbProxy(toCopy))
+ {
+ return _reflective.copy(toCopy, null);
+ }
+ else if (proxyFactory.isNormalOjbProxy(toCopy))
+ {
+ return _serialize.copy(toCopy, null);
+ }
+
+ /**
+ * if no classdescriptor exists for this object, just return this object, we
+ * can't copy it.
+ */
+ final ClassDescriptor cld = broker.getClassDescriptor(toCopy.getClass());
+ if (cld == null)
+ {
+ return _reflective.copy(toCopy, null);
+ }
+
+ final Object retval;
+ try
+ {
+ FieldDescriptor[] argFields = cld.getCreationArgumentFields();
+ Object[] args = new Object[argFields.length];
+
+ for (int idx = 0; idx < argFields.length; idx++)
+ {
+ args[idx] = _serialize.copy(argFields[idx].getPersistentField().get(toCopy), null);
+ }
+ retval = broker.getConfiguration().getObjectFactory().newInstance(cld, args, null);
+ objMap.put(toCopy,retval);
+ }
+ catch (Exception e)
+ {
+ throw new ObjectCopyException("InstantiationException", e);
+ }
+
+ /**
+ * first copy all the fields
+ * fields are not mapped objects (ie ObjectReferenceDescriptors)
+ */
+ final FieldDescriptor[] fieldDescs = cld.getFieldDescriptions();
+// final BrokerHelper brokerHelper = broker.serviceBrokerHelper();
+ for (int i = 0; i < fieldDescs.length; i++)
+ {
+ final FieldDescriptor fd = fieldDescs[i];
+ final PersistentField f = fd.getPersistentField();
+ Object fieldValue = f.get(toCopy);
+/*
+arminw:
+TODO: ensure that the autoincrement values be assigned before the copy was done
+If possible we should avoid to declare BrokerHelper#getAutoIncrementValue public and
+if we copy an object user don't expect the change of fields.
+*/
+// // If the field is auto increment, assign its value before copying!
+// if (fd.isAutoIncrement())
+// {
+// fieldValue = brokerHelper.getAutoIncrementValue(fd, toCopy, fieldValue);
+// }
+
+ f.set(retval, fieldValue);
+ }
+
+ /**
+ * then copy all the 1:1 references
+ */
+ final Collection refDescsCol = cld.getObjectReferenceDescriptors();
+ final ObjectReferenceDescriptor[] rds = (ObjectReferenceDescriptor[]) refDescsCol.toArray(new ObjectReferenceDescriptor[refDescsCol.size()]);
+ for (int i = 0; i < rds.length; i++)
+ {
+ final ObjectReferenceDescriptor rd = rds[i];
+ final PersistentField f = rd.getPersistentField();
+ /**
+ * recursively copy the referenced objects
+ * register in the objMap first
+ */
+ final Object object = f.get(toCopy);
+ final Object clone = clone(object, objMap, broker);
+ objMap.put(object, clone);
+ f.set(retval, clone);
+ }
+ /**
+ * then copy all the 1:M and M:N references
+ */
+ final Collection colDescsCol = cld.getCollectionDescriptors();
+ final Iterator it = colDescsCol.iterator();
+ while (it.hasNext())
+ {
+ final CollectionDescriptor cd = (CollectionDescriptor) it.next();
+ final PersistentField f = cd.getPersistentField();
+ final Object collection = f.get(toCopy);
+ /**
+ * handle collection proxies where the entire Collection is a big proxy
+ * (vs all the elements in the collection are proxies
+ */
+ if (collection == null)
+ {
+ f.set(retval, null);
+ }
+ else if (collection instanceof CollectionProxy)
+ {
+ f.set(retval, _reflective.copy(collection, null));
+ }
+ else if (collection instanceof Collection)
+ {
+ try
+ {
+ final Collection newCollection = (Collection) collection.getClass().newInstance();
+ final Iterator tempIter = ((Collection) collection).iterator();
+ Object obj;
+ while (tempIter.hasNext())
+ {
+ obj = tempIter.next();
+ /**
+ * if this is a proxy, just copy the proxy, don't materialize it, and stop recursing
+ */
+ if (proxyFactory.isNormalOjbProxy(obj)) // tomdz: what about VirtualProxy ?
+ {
+ newCollection.add(obj);
+ }
+ else
+ {
+ final Object clone = clone(obj, objMap, broker);
+ objMap.put(obj, clone);
+ newCollection.add(clone);
+ }
+ }
+ f.set(retval, newCollection);
+ }
+ catch (InstantiationException e)
+ {
+ throw new ObjectCopyException("InstantiationException", e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ObjectCopyException("IllegalAccessException", e);
+ }
+ }
+ else
+ {
+ throw new java.lang.UnsupportedOperationException("MetadataObjectCopyStrategy cannot handle Collection of type: " + collection.getClass().getName());
+ }
+ }
+ return retval;
+ }
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/NoOpObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/NoOpObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/NoOpObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/NoOpObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,42 @@
+package org.apache.ojb.otm.copy;
+
+
+/* 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.PersistenceBroker;
+
+/**
+ * The NoOpObjectCopyStrategy does not make a copy. It merely returns the same object.
+ *
+ * For backwards compatability with OJB 0.9, we include a way to no-op copy
+ * the object into the transactional context. This means that we are operating
+ * on a live object, and can potentially mess stuff up. This is essentially
+ * supporting a uncommitted-read only strategy.
+ *
+ * @author matthew.baird
+ */
+public class NoOpObjectCopyStrategy implements ObjectCopyStrategy
+{
+ /**
+ * @see org.apache.ojb.otm.copy.ObjectCopyStrategy#copy(Object)
+ *
+ */
+ public Object copy(Object obj, PersistenceBroker broker)
+ throws ObjectCopyException
+ {
+ return obj;
+ }
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyException.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyException.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyException.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyException.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,58 @@
+package org.apache.ojb.otm.copy;
+
+import org.apache.ojb.otm.core.OTMGenericException;
+
+/* 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 ObjectCopyException extends OTMGenericException
+{
+
+ /**
+ * Constructor for ObjectCopyException.
+ */
+ public ObjectCopyException()
+ {
+ super();
+ }
+
+ /**
+ * Constructor for ObjectCopyException.
+ * @param msg
+ */
+ public ObjectCopyException(String msg)
+ {
+ super(msg);
+ }
+
+ /**
+ * Constructor for ObjectCopyException.
+ * @param cause
+ */
+ public ObjectCopyException(Throwable cause)
+ {
+ super(cause);
+ }
+
+ /**
+ * Constructor for ObjectCopyException.
+ * @param msg
+ * @param cause
+ */
+ public ObjectCopyException(String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,33 @@
+package org.apache.ojb.otm.copy;
+
+
+/* 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.PersistenceBroker;
+
+public interface ObjectCopyStrategy
+{
+
+ /**
+ *
+ * Make a copy of the given object
+ *
+ * @param obj object to be copied
+ * @return Object the copy of the object
+ */
+ public Object copy(Object obj, PersistenceBroker broker);
+
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/OjbCloneable.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/OjbCloneable.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/OjbCloneable.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/OjbCloneable.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,28 @@
+package org.apache.ojb.otm.copy;
+
+/* 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.
+ */
+
+/**
+ * @author matthew.baird
+ */
+
+public interface OjbCloneable
+{
+ /**
+ * Probably just a delegation to the clone() method of object.
+ */
+ Object ojbClone();
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ReflectiveObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ReflectiveObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ReflectiveObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/ReflectiveObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,297 @@
+package org.apache.ojb.otm.copy;
+
+/* 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.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.util.IdentityMapFactory;
+
+/**
+ * User: matthew.baird
+ * Date: Jul 7, 2003
+ * Time: 3:05:22 PM
+ */
+public final class ReflectiveObjectCopyStrategy implements ObjectCopyStrategy
+{
+ private static final Set FINAL_IMMUTABLE_CLASSES;
+ private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+ private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+ private static final SerializeObjectCopyStrategy _serialize = new SerializeObjectCopyStrategy();
+
+ static
+ {
+ FINAL_IMMUTABLE_CLASSES = new HashSet(17);
+ FINAL_IMMUTABLE_CLASSES.add(String.class);
+ FINAL_IMMUTABLE_CLASSES.add(Byte.class);
+ FINAL_IMMUTABLE_CLASSES.add(Short.class);
+ FINAL_IMMUTABLE_CLASSES.add(Integer.class);
+ FINAL_IMMUTABLE_CLASSES.add(Long.class);
+ FINAL_IMMUTABLE_CLASSES.add(Float.class);
+ FINAL_IMMUTABLE_CLASSES.add(Double.class);
+ FINAL_IMMUTABLE_CLASSES.add(Character.class);
+ FINAL_IMMUTABLE_CLASSES.add(Boolean.class);
+ }
+
+ /**
+ * makes a deep clone of the object, using reflection.
+ * @param toCopy the object you want to copy
+ * @return
+ */
+ public final Object copy(final Object toCopy, PersistenceBroker broker)
+ {
+ return clone(toCopy, IdentityMapFactory.getIdentityMap(), new HashMap());
+ }
+
+ /*
+ * class used to cache class metadata info
+ */
+ private static final class ClassMetadata
+ {
+ Constructor m_noArgConstructor;
+ Field[] m_declaredFields;
+ boolean m_noArgConstructorAccessible;
+ boolean m_fieldsAccessible;
+ boolean m_hasNoArgConstructor = true;
+ }
+
+ private static Object clone(final Object toCopy, final Map objMap, final Map metadataMap)
+ {
+ /**
+ * first, check to make sure we aren't recursing to some object that we've already copied.
+ * if the toCopy is in the objMap, just return it.
+ */
+ if (objMap.containsKey(toCopy)) return objMap.get(toCopy);
+ final Class objClass = toCopy.getClass();
+ final Object retval;
+ if (objClass.isArray())
+ {
+ retval = handleArray(toCopy, objMap, objClass, metadataMap);
+ }
+ else if (FINAL_IMMUTABLE_CLASSES.contains(objClass))
+ {
+ objMap.put(toCopy, toCopy);
+ retval = toCopy;
+ }
+ else
+ {
+ retval = handleObjectWithNoArgsConstructor(metadataMap, objClass, objMap, toCopy);
+ }
+ return retval;
+ }
+
+ private static Object handleObjectWithNoArgsConstructor(final Map metadataMap, final Class objClass, final Map objMap, final Object toCopy)
+ {
+ Object retval = null;
+ ClassMetadata metadata = (ClassMetadata) metadataMap.get(objClass);
+ if (metadata == null)
+ {
+ metadata = new ClassMetadata();
+ metadataMap.put(objClass, metadata);
+ }
+ Constructor noArg = metadata.m_noArgConstructor;
+ if (metadata.m_hasNoArgConstructor)
+ {
+ if (noArg == null)
+ {
+ try
+ {
+ noArg = objClass.getDeclaredConstructor(EMPTY_CLASS_ARRAY);
+ metadata.m_noArgConstructor = noArg;
+ }
+ catch (Exception e)
+ {
+ metadata.m_hasNoArgConstructor = false;
+ // throw new ObjectCopyException("class [" + objClass.getName() + "] has no noArg constructor: " + e.toString(), e);
+ }
+ }
+ }
+ if (metadata.m_hasNoArgConstructor)
+ {
+ if (!metadata.m_noArgConstructorAccessible && (Modifier.PUBLIC & noArg.getModifiers()) == 0)
+ {
+ try
+ {
+ noArg.setAccessible(true);
+ }
+ catch (SecurityException e)
+ {
+ throw new ObjectCopyException("cannot access noArg constructor [" + noArg + "] of class [" + objClass.getName() + "]: " + e.toString(), e);
+ }
+ metadata.m_noArgConstructorAccessible = true;
+ }
+ try
+ {
+ /**
+ * create the return value via the default no argument constructor
+ */
+ retval = noArg.newInstance(EMPTY_OBJECT_ARRAY);
+ objMap.put(toCopy, retval);
+ }
+ catch (Exception e)
+ {
+ throw new ObjectCopyException("cannot instantiate class [" + objClass.getName() + "] using noArg constructor: " + e.toString(), e);
+ }
+ for (Class c = objClass; c != Object.class; c = c.getSuperclass())
+ {
+ copyClass(metadataMap, c, toCopy, retval, objMap);
+ }
+ }
+ else
+ {
+ retval = _serialize.copy(toCopy, null);
+ }
+ return retval;
+ }
+
+ private static void copyClass(final Map metadataMap, final Class c, final Object obj, final Object retval, final Map objMap)
+ {
+ ClassMetadata metadata;
+ metadata = (ClassMetadata) metadataMap.get(c);
+ if (metadata == null)
+ {
+ metadata = new ClassMetadata();
+ metadataMap.put(c, metadata);
+ }
+ Field[] declaredFields = metadata.m_declaredFields;
+ if (declaredFields == null)
+ {
+ declaredFields = c.getDeclaredFields();
+ metadata.m_declaredFields = declaredFields;
+ }
+ setFields(obj, retval, declaredFields, metadata.m_fieldsAccessible, objMap, metadataMap);
+ metadata.m_fieldsAccessible = true;
+ }
+
+ private static Object handleArray(final Object obj, final Map objMap, final Class objClass, final Map metadataMap)
+ {
+ final Object retval;
+ final int arrayLength = Array.getLength(obj);
+ /**
+ * immutable
+ */
+ if (arrayLength == 0)
+ {
+ objMap.put(obj, obj);
+ retval = obj;
+ }
+ else
+ {
+ final Class componentType = objClass.getComponentType();
+ /**
+ * even though arrays implicitly have a public clone(), it
+ * cannot be invoked reflectively, so need to do copy construction
+ */
+ retval = Array.newInstance(componentType, arrayLength);
+ objMap.put(obj, retval);
+ if (componentType.isPrimitive() || FINAL_IMMUTABLE_CLASSES.contains(componentType))
+ {
+ System.arraycopy(obj, 0, retval, 0, arrayLength);
+ }
+ else
+ {
+ for (int i = 0; i < arrayLength; ++i)
+ {
+ /**
+ * recursively clone each array slot:
+ */
+ final Object slot = Array.get(obj, i);
+ if (slot != null)
+ {
+ final Object slotClone = clone(slot, objMap, metadataMap);
+ Array.set(retval, i, slotClone);
+ }
+ }
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * copy all fields from the "from" object to the "to" object.
+ *
+ * @param from source object
+ * @param to from's clone
+ * @param fields fields to be populated
+ * @param accessible 'true' if all 'fields' have been made accessible during
+ * traversal
+ */
+ private static void setFields(final Object from, final Object to,
+ final Field[] fields, final boolean accessible,
+ final Map objMap, final Map metadataMap)
+ {
+ for (int f = 0, fieldsLength = fields.length; f < fieldsLength; ++f)
+ {
+ final Field field = fields[f];
+ final int modifiers = field.getModifiers();
+ if ((Modifier.STATIC & modifiers) != 0) continue;
+ if ((Modifier.FINAL & modifiers) != 0)
+ throw new ObjectCopyException("cannot set final field [" + field.getName() + "] of class [" + from.getClass().getName() + "]");
+ if (!accessible && ((Modifier.PUBLIC & modifiers) == 0))
+ {
+ try
+ {
+ field.setAccessible(true);
+ }
+ catch (SecurityException e)
+ {
+ throw new ObjectCopyException("cannot access field [" + field.getName() + "] of class [" + from.getClass().getName() + "]: " + e.toString(), e);
+ }
+ }
+ try
+ {
+ cloneAndSetFieldValue(field, from, to, objMap, metadataMap);
+ }
+ catch (Exception e)
+ {
+ throw new ObjectCopyException("cannot set field [" + field.getName() + "] of class [" + from.getClass().getName() + "]: " + e.toString(), e);
+ }
+ }
+ }
+
+ private static void cloneAndSetFieldValue(final Field field, final Object src, final Object dest, final Map objMap, final Map metadataMap) throws IllegalAccessException
+ {
+ Object value = field.get(src);
+ if (value == null)
+ {
+ /**
+ * null is a valid type, ie the object may initialize this field to a different value,
+ * so we must explicitely set all null fields.
+ */
+ field.set(dest, null);
+ }
+ else
+ {
+ final Class valueType = value.getClass();
+ if (!valueType.isPrimitive() && !FINAL_IMMUTABLE_CLASSES.contains(valueType))
+ {
+ /**
+ * recursively call clone on value as it could be an object reference, an array,
+ * or some mutable type
+ */
+ value = clone(value, objMap, metadataMap);
+ }
+ field.set(dest, value);
+ }
+ }
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/copy/SerializeObjectCopyStrategy.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,75 @@
+package org.apache.ojb.otm.copy;
+
+/* 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.io.*;
+import org.apache.ojb.broker.PersistenceBroker;
+
+/**
+ * Does in-memory serialization to achieve a copy of the object graph.
+ *
+ * @author matthew.baird
+ * @see ObjectCopyStrategy
+ */
+public final class SerializeObjectCopyStrategy implements ObjectCopyStrategy
+{
+ /**
+ * This implementation will probably be slower than the metadata
+ * object copy, but this was easier to implement.
+ * @see org.apache.ojb.otm.copy.ObjectCopyStrategy#copy(Object)
+ */
+ public Object copy(final Object obj, PersistenceBroker broker)
+ throws ObjectCopyException
+ {
+ ObjectOutputStream oos = null;
+ ObjectInputStream ois = null;
+ try
+ {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(bos);
+ // serialize and pass the object
+ oos.writeObject(obj);
+ oos.flush();
+ final ByteArrayInputStream bin =
+ new ByteArrayInputStream(bos.toByteArray());
+ ois = new ObjectInputStream(bin);
+ // return the new object
+ return ois.readObject();
+ }
+ catch (Exception e)
+ {
+ throw new ObjectCopyException(e);
+ }
+ finally
+ {
+ try
+ {
+ if (oos != null)
+ {
+ oos.close();
+ }
+ if (ois != null)
+ {
+ ois.close();
+ }
+ }
+ catch (IOException ioe)
+ {
+ // ignore
+ }
+ }
+ }
+}
Added: db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/BaseConnection.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/BaseConnection.java?rev=428990&view=auto
==============================================================================
--- db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/BaseConnection.java (added)
+++ db/ojb/trunk/proposals/otm/java/org/apache/ojb/otm/core/BaseConnection.java Sat Aug 5 05:18:12 2006
@@ -0,0 +1,701 @@
+package org.apache.ojb.otm.core;
+
+/* 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.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.PersistenceBrokerInternal;
+import org.apache.ojb.broker.PersistenceConfiguration;
+import org.apache.ojb.broker.accesslayer.OJBIterator;
+import org.apache.ojb.broker.cache.ObjectCache;
+import org.apache.ojb.broker.metadata.ClassDescriptor;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.ReportQuery;
+import org.apache.ojb.odmg.collections.DListImpl;
+import org.apache.ojb.odmg.oql.EnhancedOQLQuery;
+import org.apache.ojb.odmg.oql.OQLQueryImpl;
+import org.apache.ojb.otm.EditingContext;
+import org.apache.ojb.otm.OTMConnection;
+import org.apache.ojb.otm.copy.ObjectCopyStrategy;
+import org.apache.ojb.otm.lock.LockType;
+import org.apache.ojb.otm.lock.LockingException;
+import org.odmg.OQLQuery;
+
+/**
+ *
+ * <javadoc>
+ *
+ * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird </a>
+ * @author <a href="mailto:rraghuram@hotmail.com">Raghu Rajah </a>
+ * @version $Id: BaseConnection.java 364932 2005-08-27 14:29:03 +0200 (Sa, 27 Aug 2005) arminw $
+ *
+ */
+public abstract class BaseConnection implements OTMConnection
+{
+
+ private PersistenceBrokerInternal _pb;
+ private Transaction _tx;
+ private ConcreteEditingContext _editingContext;
+
+ /**
+ * Constructor for BaseConnection.
+ *
+ */
+ public BaseConnection(PersistenceConfiguration persistenceConf)
+ {
+ _pb = (PersistenceBrokerInternal)persistenceConf.createPersistenceBroker();
+ }
+
+ public void close()
+ {
+ _pb.close();
+ _pb = null;
+ }
+
+ public boolean isClosed()
+ {
+ if (_pb == null)
+ return true;
+ else
+ return _pb.isClosed();
+ }
+
+ public PersistenceBroker getKernelBroker()
+ {
+ return _pb;
+ }
+
+ public void setTransaction(Transaction transaction)
+ {
+ if (transaction == null)
+ {
+ _editingContext = null;
+ }
+ else if (_tx != null)
+ {
+ throw new IllegalStateException("OTMConnection is already bound to the transacaction "
+ + _tx);
+ }
+ else
+ {
+ _editingContext = new ConcreteEditingContext(transaction, _pb);
+ }
+ _tx = transaction;
+ }
+
+ public Transaction getTransaction()
+ {
+ return _tx;
+ }
+
+ //////////////////////////////////////
+ // OTMConnection protocol
+ //////////////////////////////////////
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#getObjectByIdentity(Identity, int)
+ */
+ public Object getObjectByIdentity(Identity oid, int lock) throws LockingException
+ {
+ checkTransaction("getObjectByIdentity");
+ Object userObject;
+ Object cacheObject;
+
+ cacheObject = _pb.getObjectByIdentity(oid);
+ if (cacheObject == null)
+ {
+ // Possibly the object was inserted in this transaction
+ // and was not stored to database yet
+ userObject = _editingContext.lookup(oid);
+ }
+ else
+ {
+ userObject = getUserObject(oid, cacheObject);
+ // userObject from editing context may be proxy
+ userObject = _pb.getProxyFactory().getRealObject(userObject);
+ _editingContext.insert(oid, userObject, lock);
+ }
+ return userObject;
+ }
+
+ private void checkTransaction(String methodBeingCalled)
+ {
+ if (null == _tx)
+ {
+ throw new TransactionNotInProgressException(
+ methodBeingCalled
+ + " requires a valid transaction. Please make sure you have created a new transaction, and called begin() on it.");
+ }
+ if (!_tx.isInProgress())
+ {
+ throw new TransactionNotInProgressException(methodBeingCalled
+ + " cannot be called before transaction begin() is called");
+ }
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#getObjectByIdentity(Identity)
+ */
+ public Object getObjectByIdentity(Identity oid) throws LockingException
+ {
+ return getObjectByIdentity(oid, LockType.READ_LOCK);
+ }
+
+ /**
+ * @param query The query to execute
+ * @return an Iterator that iterates Objects. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByQuery(Query query)
+ {
+ return getIteratorByQuery(query, LockType.READ_LOCK);
+ }
+
+ /**
+ * @param query The query to execute
+ * @param lock the lock that need to be acquired on the object Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to
+ * database; LockType.READ_LOCK (aka optimistic lock) - changes to the object will
+ * be written to the database, in this case the lock will be automatically upgraded
+ * to the write lock on transaction commit; LockType.WRITE_LOCK (aka pessimistic
+ * lock) - changes to the object will be written to the database.
+ * @return an Iterator that iterates Objects of class c if calling the .next() method. The
+ * returned objects are locked with the given lock value.
+ */
+ public Iterator getIteratorByQuery(Query query, int lock)
+ {
+ checkTransaction("getIteratorByQuery");
+ return new OTMIterator( _pb.getIteratorByQuery(query), lock, null);
+ }
+
+ /**
+ * @param query The OQL query to execute. Use this method if you don't want to load all the
+ * collection at once as OQLQuery.execute() does.
+ * @return an Iterator that iterates Objects. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByOQLQuery(OQLQuery query)
+ {
+ return getIteratorByOQLQuery(query, LockType.READ_LOCK);
+ }
+
+ /**
+ * @param query The OQL query to execute. Use this method if you don't want to load all the
+ * collection at once as OQLQuery.execute() does.
+ * @return an Iterator that iterates Objects. The returned objects are locked for read.
+ */
+ public Iterator getIteratorByOQLQuery(OQLQuery query, int lock)
+ {
+ checkTransaction("getIteratorByOQLQuery");
+ if (query instanceof OTMOQLQueryImpl)
+ {
+ OTMOQLQueryImpl q = (OTMOQLQueryImpl) query;
+ return new OTMIterator(_pb.getIteratorByQuery(q.getQuery()), lock, q);
+ }
+ else
+ {
+ throw new IllegalArgumentException("The OQLQuery where created not via OTM API");
+ }
+ }
+
+ /**
+ * @param query The query to execute
+ * @param lock the lock that need to be acquired on the object Possible values are:
+ * LockType.NO_LOCK (aka read only) - changes to the object will not be written to
+ * database; LockType.READ_LOCK (aka optimistic lock) - changes to the object will
+ * be written to the database, in this case the lock will be automatically upgraded
+ * to the write lock on transaction commit; LockType.WRITE_LOCK (aka pessimistic
+ * lock) - changes to the object will be written to the database.
+ * @return an Iterator that iterates Objects of class c if calling the .next() method. The
+ * returned objects are locked with the given lock value.
+ */
+ public Collection getCollectionByQuery(Query query, int lock)
+ {
+ checkTransaction("getCollectionByQuery");
+ Collection col = _pb.getCollectionByQuery(query);
+ Collection result = createCollectionOfTheSameClass(col);
+ for (Iterator it = col.iterator(); it.hasNext();)
+ {
+ result.add(insertObject(it.next(), lock));
+ }
+ return result;
+ }
+
+ /**
+ * @param query The query to execute
+ * @return an Iterator that iterates Objects of class c if calling the .next() method. The
+ * returned objects are locked for read.
+ */
+ public Collection getCollectionByQuery(Query query)
+ {
+ return getCollectionByQuery(query, LockType.READ_LOCK);
+ }
+
+ /**
+ * Get the identity of the object
+ *
+ * @param object The object
+ * @return the identity of the object
+ */
+ public Identity getIdentity(Object object)
+ {
+ return new Identity(object, _pb);
+ }
+
+ /**
+ * Get the class descriptor
+ *
+ * @param clazz The class
+ * @return the descriptor of the class
+ */
+ public ClassDescriptor getDescriptorFor(Class clazz)
+ {
+ return _pb.getClassDescriptor(clazz);
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#invalidate(Identity)
+ */
+ public void invalidate(Identity oid) throws LockingException
+ {
+ if (null == _tx)
+ {
+ throw new TransactionNotInProgressException(
+ "invalidate requires a valid transaction. Please make sure you have created a new transaction, and called begin() on it.");
+ }
+ // mark as invalidated in the editing context, if it's found there
+ _editingContext.insert(oid, null, LockType.READ_LOCK);
+
+ // remove from the cache
+ _pb.serviceObjectCache().remove(oid);
+
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#serviceObjectCache()
+ */
+ public ObjectCache serviceObjectCache()
+ {
+ return _pb.serviceObjectCache();
+ }
+
+ /**
+ * TODO remove all from editing context.
+ *
+ * @throws LockingException
+ */
+ public void invalidateAll() throws LockingException
+ {
+ _pb.serviceObjectCache().clear();
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#lockForWrite(Object)
+ */
+ public void lockForWrite(Object object) throws LockingException
+ {
+ checkTransaction("lockForWrite");
+ makePersistent(object);
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#makePersistent(Object)
+ */
+ public void makePersistent(Object userObject) throws LockingException
+ {
+ checkTransaction("makePersistent");
+ Identity oid = new Identity(userObject, _pb);
+ Object cacheObject = _pb.getObjectByIdentity(oid);
+
+ if ((cacheObject != null) && (_editingContext.lookup(oid) == null))
+ {
+ // The object exists in the database, but is not yet in the editing
+ // context, so we need to put it to the editing context in its
+ // old state, then we will put the modified userObject.
+ // This will allow the editing context to find changes
+ ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid);
+ Object origUserObject = copyStrategy.copy(cacheObject, _pb);
+ _editingContext.insert(oid, origUserObject, LockType.WRITE_LOCK);
+ }
+ _editingContext.insert(oid, userObject, LockType.WRITE_LOCK);
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#deletePersistent(Object)
+ */
+ public void deletePersistent(Object userObject) throws LockingException
+ {
+ checkTransaction("deletePersistent");
+ Identity oid = new Identity(userObject, _pb);
+ Object cacheObject = _pb.getObjectByIdentity(oid);
+ if (cacheObject == null)
+ {
+ // Possibly the object was inserted in this transaction
+ // and was not stored to database yet, so we simply remove it
+ // from editing context.
+ _editingContext.remove(oid);
+ }
+ else
+ {
+ if (_editingContext.lookup(oid) == null)
+ {
+ // The object exists in the database, but is not yet in the editing
+ // context, so we need to put it to the editing context
+ ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid);
+ Object origUserObject = copyStrategy.copy(cacheObject, _pb);
+ _editingContext.insert(oid, origUserObject, LockType.WRITE_LOCK);
+ }
+ _editingContext.deletePersistent(oid, userObject);
+ }
+ }
+
+ /**
+ * @see org.apache.ojb.otm.OTMConnection#refresh(Object)
+ */
+ public void refresh(Object userObject)
+ {
+ checkTransaction("refresh");
+ Identity oid = new Identity(userObject, _pb);
+ _editingContext.refresh(oid, userObject);
+ }
+
+ public EditingContext getEditingContext()
+ {
+ return _editingContext;
+ }
+
+ public EnhancedOQLQuery newOQLQuery()
+ {
+ return newOQLQuery(LockType.READ_LOCK);
+ }
+
+ public EnhancedOQLQuery newOQLQuery(int lock)
+ {
+ checkTransaction("newOQLQuery");
+
+ // TODO: How do we get the oqlCollectionClass value
+ return new OTMOQLQueryImpl(_pb.getConfiguration(), DListImpl.class, lock);
+ }
+
+ public int getCount(Query query)
+ {
+ checkTransaction("getCount");
+ return _pb.getCount(query);
+ }
+
+ private Object insertObject(Object cacheObject, int lock)
+ {
+ Object ctxObject;
+ Identity oid;
+ Object userObject;
+
+
+ oid = getIdentity(cacheObject);
+ userObject = getUserObject(oid, cacheObject);
+ try
+ {
+ _editingContext.insert(oid, userObject, lock);
+ }
+ catch (LockingException ex)
+ {
+ throw new LockingPassthruException(ex);
+ }
+
+ return userObject;
+ }
+
+ /**
+ * Get user object (from the editing context) with the given oid.
+ * If not found, then create it as a copy of cacheObject.
+ * User object and cache object must be separate.
+ * @param oid The identity
+ * @param cacheObject the object for user
+ */
+ private Object getUserObject(Identity oid, Object cacheObject)
+ {
+ Object userObject = _editingContext.lookup(oid);
+
+ if (userObject == null)
+ {
+ ObjectCopyStrategy copyStrategy = _tx.getKit().getCopyStrategy(oid);
+ userObject = copyStrategy.copy(cacheObject, _pb);
+ }
+ return userObject;
+ }
+
+ private Collection createCollectionOfTheSameClass(Collection col)
+ {
+ try
+ {
+ return (Collection) col.getClass().newInstance();
+ }
+ catch (Throwable ex)
+ {
+ return new ArrayList();
+ }
+ }
+
+ ///////////////////////////////////////
+ // Transaction Notifications
+ ///////////////////////////////////////
+
+ /**
+ *
+ * Notification issued by the driving transaction to begin this transaction
+ *
+ */
+ public abstract void transactionBegin() throws TransactionException;
+
+ /**
+ *
+ * Prepare for a commit. As part of a two phase commit protocol of the transaction.
+ *
+ */
+ public abstract void transactionPrepare() throws TransactionException;
+
+ /**
+ *
+ * Notification issued by the driving transaction to commit resources held by this connection.
+ *
+ */
+ public abstract void transactionCommit() throws TransactionException;
+
+ /**
+ *
+ * Notification issued by the driving transaction to rollback resources held by this
+ * connection.
+ *
+ */
+ public abstract void transactionRollback() throws TransactionException;
+
+ ///////////////////////////////////////
+ // Inner classes
+ ///////////////////////////////////////
+
+ private class OTMIterator implements OJBIterator
+ {
+ private final OJBIterator _it;
+ private final int _lock;
+ private final OTMOQLQueryImpl _oqlQuery;
+
+ OTMIterator(OJBIterator it, int lock, OTMOQLQueryImpl oqlQuery)
+ {
+ _it = it;
+ _lock = lock;
+ _oqlQuery = oqlQuery;
+ }
+
+ public void setAutoRelease(boolean autoRelease)
+ {
+ _it.setAutoRelease(autoRelease);
+ }
+
+ public boolean hasNext()
+ {
+ boolean res = _it.hasNext();
+
+ // once the result set is finished, close it
+ if (!res)
+ {
+ done();
+ }
+
+ return res;
+ }
+
+ public Object next()
+ {
+ Object object = _it.next();
+ object = insertObject(object, _lock);
+ return object;
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void done()
+ {
+ releaseDbResources();
+ if (_oqlQuery != null)
+ {
+ _oqlQuery.resetBindIterator();
+ }
+ }
+
+ protected void finalize()
+ {
+ done();
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#absolute(int)
+ */
+ public boolean absolute(int row) throws PersistenceBrokerException
+ {
+ return _it.absolute(row);
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#fullSize()
+ */
+ public int fullSize() throws PersistenceBrokerException
+ {
+ return _it.fullSize();
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#relative(int)
+ */
+ public boolean relative(int row) throws PersistenceBrokerException
+ {
+ return _it.relative(row);
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#releaseDbResources()
+ */
+ public void releaseDbResources()
+ {
+ _it.releaseDbResources();
+ }
+
+ public boolean isClosed()
+ {
+ return _it.isClosed();
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#size()
+ */
+ public int size() throws PersistenceBrokerException
+ {
+ return _it.size();
+ }
+
+ /**
+ * @see org.apache.ojb.broker.accesslayer.OJBIterator#disableLifeCycleEvents()
+ */
+ public void disableLifeCycleEvents()
+ {
+ _it.disableLifeCycleEvents();
+ }
+
+ }
+
+ private class OTMOQLQueryImpl extends OQLQueryImpl
+ {
+ int _lock;
+ Class collectionClass;
+
+ public OTMOQLQueryImpl(PersistenceConfiguration persistenceConf, Class collectionClass, int lock)
+ {
+ // no transaction manager because we override the execute method anyway
+ super(null);
+ this.collectionClass = collectionClass;
+ _lock = lock;
+ }
+
+ public Class getCollectionClass()
+ {
+ return this.collectionClass;
+ }
+
+ /**
+ * Execute the query. After executing a query, the parameter list is reset.
+ *
+ * @return The object that represents the result of the query. The returned data, whatever
+ * its OQL type, is encapsulated into an object. For instance, when OQL returns an
+ * integer, the result is put into an <code>Integer</code> object. When OQL
+ * returns a collection (literal or object), the result is always a Java collection
+ * object of the same kind (for instance, a <code>DList</code>).
+ * @exception org.odmg.QueryException An exception has occurred while executing the query.
+ */
+ public Object execute() throws org.odmg.QueryException
+ {
+ Collection result;
+ Iterator iter = null;
+ Query query = getQuery();
+
+ try
+ {
+ if (!(query instanceof ReportQuery))
+ {
+ Collection res0 = _pb.getCollectionByQuery(query);
+ result = createCollectionOfTheSameClass(res0);
+ for (iter = res0.iterator(); iter.hasNext();)
+ {
+ result.add(insertObject(iter.next(), _lock));
+ }
+ }
+ else
+ {
+ result = new ArrayList();
+ iter = _pb.getReportQueryIteratorByQuery(query);
+ while (iter.hasNext())
+ {
+ Object[] res = (Object[]) iter.next();
+
+ if (res.length == 1)
+ {
+ if (res[0] != null) // skip null values
+ {
+ result.add(res[0]);
+ }
+ }
+ else
+ {
+ // skip null tuples
+ for (int i = 0; i < res.length; i++)
+ {
+ if (res[i] != null)
+ {
+ result.add(res);
+ break;
+ }
+ }
+ }
+ }
+ }
+ resetBindIterator();
+ }
+ finally
+ {
+ if ((iter != null) && (iter instanceof OJBIterator))
+ {
+ ((OJBIterator) iter).releaseDbResources();
+ }
+ }
+ return result;
+ }
+
+ void resetBindIterator()
+ {
+ // reset iterator to start of list so we can reuse this query
+ ListIterator it = getBindIterator();
+ while (it.hasPrevious())
+ {
+ it.previous();
+ }
+ }
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org