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/07/15 16:28:05 UTC
svn commit: r422235 [1/3] - in /db/ojb/trunk/src: java/org/apache/ojb/odmg/
java/org/apache/ojb/odmg/oql/ java/org/apache/ojb/odmg/states/
java/org/odmg/ jdori/org/apache/ojb/jdori/sql/
samples/org/apache/ojb/tutorials/
Author: arminw
Date: Sat Jul 15 07:28:03 2006
New Revision: 422235
URL: http://svn.apache.org/viewvc?rev=422235&view=rev
Log:
merge trunk with 1.0.x
Modified:
db/ojb/trunk/src/java/org/apache/ojb/odmg/NamedRootsMap.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeTable.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/PBCapsule.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/RuntimeObject.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionAbortedExceptionOJB.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionAware.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionExt.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TransactionImpl.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/TxUtil.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/oql/OQLQueryImpl.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/ModificationState.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateNewClean.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateNewDelete.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateNewDirty.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateOldClean.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateOldDelete.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateOldDirty.java
db/ojb/trunk/src/java/org/apache/ojb/odmg/states/StateTransient.java
db/ojb/trunk/src/java/org/odmg/Implementation.java
db/ojb/trunk/src/jdori/org/apache/ojb/jdori/sql/OjbStoreManager.java
db/ojb/trunk/src/samples/org/apache/ojb/tutorials/PBExample.java
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/NamedRootsMap.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/NamedRootsMap.java?rev=422235&r1=422234&r2=422235&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/NamedRootsMap.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/NamedRootsMap.java Sat Jul 15 07:28:03 2006
@@ -1,6 +1,6 @@
package org.apache.ojb.odmg;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -28,6 +28,7 @@
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.ojb.broker.util.ObjectModification;
import org.odmg.ClassNotPersistenceCapableException;
import org.odmg.ObjectNameNotFoundException;
import org.odmg.ObjectNameNotUniqueException;
@@ -40,14 +41,13 @@
* therefore the NamedRootsMap underlies the same transaction management
* as all other persistent objects
*
- * @author Thomas Mahler
* @version $Id$
*/
public class NamedRootsMap
{
private Logger log = LoggerFactory.getLogger(NamedRootsMap.class);
- private TransactionImpl tx;
- private HashMap tempBindings;
+ private final TransactionImpl tx;
+ private final HashMap tempBindings;
private Map deletionMap;
private Map insertMap;
@@ -77,6 +77,16 @@
}
/**
+ * Returns <em>true</em> if this class manage objects
+ * to persist/delete in datastore.
+ */
+ public boolean needsCommit()
+ {
+ return (insertMap != null && insertMap.size() > 0)
+ || (deletionMap != null && deletionMap.size() > 0);
+ }
+
+ /**
* Have to be performed after the "normal" objects be written
* to DB and before method {@link #performInsert()}.
*/
@@ -108,15 +118,16 @@
{
NamedEntry namedEntry = (NamedEntry) it.next();
namedEntry.prepareForStore(broker);
- broker.store(namedEntry, org.apache.ojb.broker.OJB.INSERT);
+ broker.store(namedEntry, ObjectModification.INSERT);
}
}
}
- public void afterWriteCleanup()
+ public void cleanup()
{
- if(deletionMap != null) deletionMap.clear();
- if(insertMap != null) insertMap.clear();
+ if(deletionMap != null && deletionMap.size() > 0) deletionMap.clear();
+ if(insertMap != null && insertMap.size() > 0) insertMap.clear();
+ if(tempBindings.size() > 0) insertMap.clear();
}
private void localBind(String key, NamedEntry entry) throws ObjectNameNotUniqueException
@@ -178,7 +189,7 @@
result = tx.getBroker().getObjectByIdentity(objectIdentity);
// lock the persistance capable object
RuntimeObject rt = new RuntimeObject(result, objectIdentity, tx, false);
- tx.lockAndRegister(rt, Transaction.READ, tx.getRegistrationList());
+ tx.lockAndRegister(rt, Transaction.READ);
}
else
{
@@ -215,8 +226,9 @@
{
cld = broker.getClassDescriptor(broker.getProxyFactory().getRealClass(object));
}
- catch(PersistenceBrokerException e)
+ catch(PersistenceBrokerException ignore)
{
+ // ignore
}
// if null a non-persistent capable object was specified
@@ -238,7 +250,7 @@
// else persist the specified named object
if(!rt.isNew())
{
- tx.lockAndRegister(rt, Transaction.READ, tx.getRegistrationList());
+ tx.lockAndRegister(rt, Transaction.READ);
}
else
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java?rev=422235&r1=422234&r2=422235&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/NarrowTransaction.java Sat Jul 15 07:28:03 2006
@@ -1,10 +1,5 @@
package org.apache.ojb.odmg;
-import org.apache.ojb.broker.Identity;
-import org.apache.ojb.broker.PersistenceBroker;
-import org.apache.ojb.broker.PersistenceBrokerException;
-import org.odmg.LockNotGrantedException;
-
/* Copyright 2002-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,6 +15,11 @@
* limitations under the License.
*/
+import org.odmg.LockNotGrantedException;
+import org.apache.ojb.broker.PersistenceBroker;
+import org.apache.ojb.broker.Identity;
+import org.apache.ojb.broker.PersistenceBrokerException;
+
/**
* Wraps {@link org.odmg.Transaction} in managed environments.
*
@@ -185,15 +185,15 @@
tx.setOrdering(ordering);
}
- public boolean isNoteUserOrder()
- {
- return tx.isNoteUserOrder();
- }
-
- public void setNoteUserOrder(boolean noteUserOrder)
- {
- tx.setNoteUserOrder(noteUserOrder);
- }
+// public boolean isNoteUserOrder()
+// {
+// return tx.isNoteUserOrder();
+// }
+//
+// public void setNoteUserOrder(boolean noteUserOrder)
+// {
+// tx.setNoteUserOrder(noteUserOrder);
+// }
public boolean isDeleted(Identity id)
{
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java?rev=422235&r1=422234&r2=422235&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelope.java Sat Jul 15 07:28:03 2006
@@ -1,6 +1,6 @@
package org.apache.ojb.odmg;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -14,51 +14,43 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- *
- * @author <a href="mailto:thma@apache.org">Thomas Mahler</a>
- * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
- *
- */
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.Identity;
-import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PersistenceBrokerInternal;
-import org.apache.ojb.broker.core.proxy.CollectionProxy;
-import org.apache.ojb.broker.core.proxy.CollectionProxyListener;
import org.apache.ojb.broker.core.proxy.IndirectionHandler;
+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.FieldType;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.broker.util.BrokerHelper;
import org.apache.ojb.broker.util.ObjectModification;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
-import org.apache.ojb.odmg.link.LinkEntry;
-import org.apache.ojb.odmg.link.LinkEntryOneToN;
-import org.apache.ojb.odmg.link.LinkEntryOneToOne;
import org.apache.ojb.odmg.states.ModificationState;
import org.apache.ojb.odmg.states.StateNewDirty;
import org.apache.ojb.odmg.states.StateOldClean;
import org.apache.ojb.odmg.states.StateOldDirty;
+import org.apache.ojb.odmg.link.LinkEntry;
+import org.apache.ojb.odmg.link.LinkEntryOneToOne;
+import org.apache.ojb.odmg.link.LinkEntryOneToN;
/**
* ObjectEnvelope is used during ODMG transactions as a wrapper for a
* persistent objects declaration
*
*/
-public class ObjectEnvelope implements ObjectModification
+public class ObjectEnvelope implements ObjectModification, Image.ImageListener
{
private Logger log = LoggerFactory.getLogger(ObjectEnvelope.class);
@@ -75,6 +67,8 @@
private Identity oid;
private Boolean hasChanged;
private boolean writeLocked;
+ private boolean markedForCascadingInsert;
+ private boolean markedForCascadingDelete;
/**
* myObj holds the object we are wrapping.
@@ -84,7 +78,7 @@
/**
* beforeImage holds a mapping between field
* names and values at the start of the transaction.
- * afterImage holds the mapping at the
+ * currentImage holds the mapping at the
* end of the transaction.
*/
private Map beforeImage;
@@ -94,21 +88,22 @@
private List linkEntryList;
/**
- *
* Create a wrapper by providing an Object.
*/
- public ObjectEnvelope(ObjectEnvelopeTable buffer, Identity oid, Object obj, boolean isNewObject)
+ ObjectEnvelope(ObjectEnvelopeTable buffer, Identity oid, Object obj, boolean isNewObject)
{
this.linkEntryList = new ArrayList();
this.buffer = buffer;
this.oid = oid;
// TODO: do we really need to materialize??
- myObj = buffer.getTransaction().getBrokerInternal().getProxyFactory().getRealObject(obj);
- /*
- if object is new don't make an image, because we know it needs insert
- */
- if(!isNewObject) refreshObjectImage();
+ myObj = getProxyFactory().getRealObject(obj);
prepareInitialState(isNewObject);
+ beforeImage = buildObjectImage(getBroker(), isNewObject);
+ }
+
+ private ProxyFactory getProxyFactory()
+ {
+ return buffer.getTransaction().getBrokerInternal().getProxyFactory();
}
public PersistenceBrokerInternal getBroker()
@@ -126,7 +121,7 @@
return buffer;
}
- public Map getBeforeImage()
+ private Map getBeforeImage()
{
if(beforeImage == null)
{
@@ -135,56 +130,67 @@
return beforeImage;
}
- public Map getCurrentImage()
+ private Map getCurrentImage()
{
if(currentImage == null)
{
- currentImage = buildObjectImage(getBroker());
+ currentImage = buildObjectImage(getBroker(), needsInsert());
}
return currentImage;
}
/**
- * This method should be called before commit method/ transaction ends
+ * This method should be called before transaction ends
* to allow cleanup of used resources, e.g. remove proxy listener objects
* to avoid invoke of registered objects after tx end.
*/
- public void cleanup(boolean reuse)
+ public void cleanup(boolean reuse, boolean wasInsert)
{
if(currentImage != null)
{
- Iterator iterator = currentImage.values().iterator();
- while(iterator.hasNext())
- {
- EqualsBase base = (EqualsBase) iterator.next();
- if(base != null) base.cleanup(reuse);
- }
+ performImageCleanup(currentImage, reuse);
}
if(beforeImage != null)
{
- Iterator iterator = beforeImage.values().iterator();
- while(iterator.hasNext())
- {
- EqualsBase base = (EqualsBase) iterator.next();
- // we always free resources of the old image
- if(base != null) base.cleanup(false);
- }
+ // we always free all resources of the old image
+ performImageCleanup(beforeImage, false);
+ }
+ if(reuse)
+ {
+ refreshObjectImage(wasInsert);
+ // on reuse of this object, we have to clear the link list
+ if(linkEntryList.size() > 0) linkEntryList.clear();
+ }
+ else
+ {
+ myObj = null;
}
- if(!reuse) myObj = null;
}
- public void refreshObjectImage()
+ private void performImageCleanup(Map imageMap, boolean reuse)
+ {
+ Iterator iterator = imageMap.values().iterator();
+ while(iterator.hasNext())
+ {
+ Image base = (Image) iterator.next();
+ if(base != null) base.cleanup(reuse);
+ }
+ }
+
+ private void refreshObjectImage(boolean wasNewObject)
{
- PersistenceBroker broker = getBroker();
try
{
+ markedForCascadingInsert = false;
+ markedForCascadingDelete = false;
+
// if an image already exists we
// replace the Identity too, maybe a temporary
// used PK value was replaced by the real one,
// see in docs SequenceManagerNativeImpl
- if(beforeImage != null)
+ if(getIdentity().isTransient())
{
- oid = broker.serviceIdentity().buildIdentity(myObj);
+ refreshIdentity();
}
if(currentImage != null)
{
@@ -194,24 +200,75 @@
{
if(beforeImage == null)
{
- beforeImage = buildObjectImage(getBroker());
+ beforeImage = buildObjectImage(getBroker(), wasNewObject);
}
}
currentImage = null;
hasChanged = null;
+ if(wasNewObject)
+ {
+ /*
+ on insert we have to replace the PK fields and the version fields, because
+ they populated after the object was written to DB, thus replace all field image values
+ */
+ // refreshPKFields();
+ buildImageForFields(beforeImage, getClassDescriptor());
+ }
+ // TODO: How to handle version fields incremented by the DB?
+ // always refresh the version fields, because these fields will change when written to DB
+ refreshLockingFields();
}
- catch(Exception ex)
+ catch(PersistenceBrokerException e)
{
beforeImage = null;
currentImage = null;
hasChanged = null;
- log.error("Can't refresh object image", ex);
- throw new org.odmg.ClassNotPersistenceCapableException(ex.toString());
+ log.error("Can't refresh object image for " + getIdentity(), e);
+ throw e;
}
}
+// TODO: Is it possible that PK fields change? If a FK is part of a coumpound PK wouldn't it possible?
+// private void refreshPKFields()
+// {
+// FieldDescriptor[] flds = getClassDescriptor().getPkFields();
+// for(int i = 0; i < flds.length; i++)
+// {
+// FieldDescriptor fld = flds[i];
+// addFieldImage(beforeImage, fld);
+// }
+// }
+
+ private void refreshLockingFields()
+ {
+ if(getClassDescriptor().isLocking())
+ {
+ FieldDescriptor[] flds = getClassDescriptor().getLockingFields();
+ for(int i = 0; i < flds.length; i++)
+ {
+ FieldDescriptor fld = flds[i];
+ addFieldImage(beforeImage, fld);
+ }
+ }
+ }
+
+ /**
+ * Replace the current with a new generated identity object and
+ * returns the old one.
+ */
+ public Identity refreshIdentity()
+ {
+ Identity oldOid = getIdentity();
+ this.oid = getBroker().serviceIdentity().buildIdentity(myObj);
+ return oldOid;
+ }
+
public Identity getIdentity()
{
+ if(oid == null)
+ {
+ oid = getBroker().serviceIdentity().buildIdentity(getObject());
+ }
return oid;
}
@@ -223,6 +280,11 @@
return myObj;
}
+ public Object getRealObject()
+ {
+ return getProxyFactory().getRealObject(myObj);
+ }
+
public void refreshObjectIfNeeded(Object obj)
{
if(this.myObj != obj)
@@ -297,117 +359,95 @@
/**
* buildObjectImage() will return the image of the Object.
*/
- private Map buildObjectImage(PersistenceBrokerInternal broker) throws PersistenceBrokerException
+ private Map buildObjectImage(PersistenceBroker broker) throws PersistenceBrokerException
{
- Map fieldValues = new HashMap();
- ClassDescriptor mif = broker.getClassDescriptor(getObject().getClass());
+ return buildObjectImage(broker, false);
+ }
+
+ private Map buildObjectImage(PersistenceBroker broker, boolean isNew) throws PersistenceBrokerException
+ {
+ Map imageMap = new HashMap();
+ ClassDescriptor cld = broker.getClassDescriptor(getObject().getClass());
//System.out.println("++++ build image: " + getObject());
+ // register 1:1 references in image
+ buildImageForSingleReferences(imageMap, cld);
+ // put object values to image map, skip this for new objects
+ if(!isNew) buildImageForFields(imageMap, cld);
+ // register 1:n and m:n references in image
+ buildImageForCollectionReferences(imageMap, cld);
+ return imageMap;
+ }
- /**
- * MBAIRD
- * 1. register all 1:1 references
- * field changes to 1:1 mapped objects should also be registered in the map,
- * so that alterations to those related objects will trigger an object to be
- * marked "dirty", otherwise attaching or detaching a 1:1 referenced object will
- * not be updated in ODMG.
- */
- Iterator iter = mif.getObjectReferenceDescriptors(true).iterator();
+ private void buildImageForSingleReferences(Map imageMap, ClassDescriptor cld)
+ {
+ // register all 1:1 references
+ Iterator iter = cld.getObjectReferenceDescriptors(true).iterator();
ObjectReferenceDescriptor rds;
while(iter.hasNext())
{
- Object referenceObject;
- EqualsRefHelper erh;
rds = (ObjectReferenceDescriptor) iter.next();
-
- /*
- synchronize on myObj so the ODMG-layer can take a snapshot only of
- fully cached (i.e. with all references + collections) objects
- arminw:
- The PB-api only return full materialized objects, thus it's not
- needed to sync.
- */
-// synchronized(myObj)
-// {
-// referenceObject = rds.getPersistentField().get(myObj);
-// }
- referenceObject = rds.getPersistentField().get(myObj);
-
- /**
- * MBAIRD
- * In the case of a proxy, we check if it has been materialized
- * if it's been materialized, we put it in the map, because it could change.
- * if it hasn't been materialized, it hasn't changed.
- *
- * Also handles virtual proxies.
- *
- * arminw:
- * wrap Object or Identity with a helper class. The main object will get
- * dirty when the 1:1 reference change: add or replaced by another object or deleted
- */
- IndirectionHandler handler = broker.getProxyFactory().getIndirectionHandler(referenceObject);
- // if it is a not materialized proxy, use the Identity
- if(handler != null)
- {
- erh = handler.alreadyMaterialized()
- ? new EqualsRefHelper(handler.getRealSubject())
- : new EqualsRefHelper(handler.getIdentity());
- }
- else
- {
/*
arminw:
- if object was serialized and anonymous FK are used in the main object, the FK
- values are null, we have to refresh (re-assign) this values before building field images
+ if a "super-reference" is matched (a 1:1 reference used to represent a super class)
+ we don't handle it, because this will be done by the PB-api and will never be change
*/
- if(referenceObject != null
- && BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
+ if(!rds.isSuperReferenceDescriptor())
{
- getBroker().serviceBrokerHelper().link(myObj, rds, false);
- }
- erh = new EqualsRefHelper(referenceObject);
+ Object referenceObject = rds.getPersistentField().get(myObj);
+
+ IndirectionHandler handler = getProxyFactory().getIndirectionHandler(referenceObject);
+ /*
+ arminw:
+ if object was serialized and anonymous FK are used in the main object, the FK
+ values are null, we have to refresh (re-assign) these values before building field images.
+ This will not touch the main object itself, because we only reassign anonymous FK fields.
+ */
+ if(handler == null && referenceObject != null
+ && BrokerHelper.hasAnonymousKeyReference(rds.getClassDescriptor(), rds))
+ {
+ getBroker().serviceBrokerHelper().link(myObj, rds, false);
+ }
+ Image.SingleRef singleRef = new Image.SingleRef(this, rds, referenceObject);
+ imageMap.put(rds, singleRef);
}
- /*
- register the Identity for 1:1 relations only, if change we have
- to update the main object
- */
- fieldValues.put(rds, erh);
}
+ }
-
- /**
- * MBAIRD
- * 2. register all fields of object (with inherited fields) that aren't collections or references
- */
- FieldDescriptor[] fieldDescs = mif.getFieldDescriptor(true);
+ private void buildImageForFields(Map imageMap, ClassDescriptor cld)
+ {
+ // register all non reference fields of object (with inherited fields)
+ FieldDescriptor[] fieldDescs = cld.getFieldDescriptor(true);
for(int i = 0; i < fieldDescs.length; i++)
{
- FieldDescriptor fld = fieldDescs[i];
- // map copies of all field values
- Object value = fld.getPersistentField().get(myObj);
- // get the real sql type value
- value = fld.getFieldConversion().javaToSql(value);
- // make copy of the sql type value
- value = fld.getJdbcType().getFieldType().copy(value);
- // buffer in image the field name and the sql type value
- // wrapped by a helper class
- fieldValues.put(fld.getPersistentField().getName(), new EqualsFieldHelper(fld.getJdbcType().getFieldType(), value));
+ addFieldImage(imageMap, fieldDescs[i]);
}
+ }
+ private void addFieldImage(Map imageMap, FieldDescriptor fld)
+ {
+ // register copies of all field values
+ Object value = fld.getPersistentField().get(myObj);
+ // get the real sql type value
+ value = fld.getFieldConversion().javaToSql(value);
+ // make copy of the sql type value
+ value = fld.getJdbcType().getFieldType().copy(value);
+ // buffer in image the field name and the sql type value
+ // wrapped by a helper class
+ imageMap.put(fld.getPersistentField().getName(), new Image.Field(fld.getJdbcType().getFieldType(), value));
+ }
- /**
- * MBAIRD
- * 3. now let's register the collection descriptors
- */
- Iterator collections = mif.getCollectionDescriptors(true).iterator();
+ private void buildImageForCollectionReferences(Map imageMap, ClassDescriptor cld)
+ {
+ // register the 1:n and m:n references
+ Iterator collections = cld.getCollectionDescriptors(true).iterator();
CollectionDescriptor cds;
while(collections.hasNext())
{
cds = (CollectionDescriptor) collections.next();
Object collectionOrArray = cds.getPersistentField().get(myObj);
- EqualsColHelper ech = new EqualsColHelper(cds, collectionOrArray);
- fieldValues.put(cds, ech);
+ Image.MultipleRef colRef = new Image.MultipleRef(this, cds, collectionOrArray);
+ imageMap.put(cds, colRef);
}
- return fieldValues;
}
/**
@@ -471,7 +511,7 @@
initialState = StateOldClean.getInstance();
}
// remember it:
- modificationState = initialState;
+ this.modificationState = initialState;
}
/**
@@ -494,18 +534,18 @@
*/
public void setModificationState(ModificationState newModificationState)
{
- if(newModificationState != modificationState)
+ if(newModificationState != this.modificationState)
{
if(log.isDebugEnabled())
{
log.debug("object state transition for object " + this.oid + " ("
- + modificationState + " --> " + newModificationState + ")");
+ + this.modificationState + " --> " + newModificationState + ")");
// try{throw new Exception();}catch(Exception e)
// {
// e.printStackTrace();
// }
}
- modificationState = newModificationState;
+ this.modificationState = newModificationState;
}
}
@@ -517,7 +557,7 @@
{
ToStringBuilder buf = new ToStringBuilder(this);
buf.append("Identity", oid)
- .append("ModificationState", modificationState.toString());
+ .append("ModificationState", (modificationState != null ? modificationState.toString() : "invalid"));
return buf.toString();
}
@@ -531,17 +571,42 @@
*/
public boolean hasChanged(PersistenceBroker broker)
{
- try
- {
- currentImage = getCurrentImage();
- }
- catch(Exception e)
- {
- log.warn("Could not verify object changes, return hasChanged 'true'", e);
- }
if(hasChanged == null)
{
- hasChanged = (beforeImage != null && beforeImage.equals(currentImage) ? Boolean.FALSE : Boolean.TRUE);
+ Map current = null;
+ try
+ {
+ current = getCurrentImage();
+ }
+ catch(Exception e)
+ {
+ log.warn("Could not verify object changes, mark dirty: " + getIdentity(), e);
+ }
+ if(beforeImage != null && current != null)
+ {
+ Iterator it = beforeImage.entrySet().iterator();
+ hasChanged = Boolean.FALSE;
+ while(it.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) it.next();
+ Image imageBefore = (Image) entry.getValue();
+ Image imageCurrent = (Image) current.get(entry.getKey());
+ if(imageBefore.modified(imageCurrent))
+ {
+ hasChanged = Boolean.TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ hasChanged = Boolean.TRUE;
+ }
+ if(log.isDebugEnabled())
+ {
+ log.debug("State detection for " + getIdentity() + " --> object "
+ + (hasChanged.booleanValue() ? "has changed" : "unchanged"));
+ }
}
return hasChanged.booleanValue();
}
@@ -553,7 +618,7 @@
void markReferenceElements(PersistenceBroker broker)
{
// these cases will be handled by ObjectEnvelopeTable#cascadingDependents()
- if(getModificationState().needsInsert() || getModificationState().needsDelete()) return;
+ // if(getModificationState().needsInsert() || getModificationState().needsDelete()) return;
Map oldImage = getBeforeImage();
Map newImage = getCurrentImage();
@@ -562,193 +627,13 @@
while (iter.hasNext())
{
Map.Entry entry = (Map.Entry) iter.next();
- // CollectionDescriptor extends ObjectReferenceDescriptor
- // we have to search for XXXDescriptor
- if(entry.getKey() instanceof ObjectReferenceDescriptor)
- {
- if (entry.getKey() instanceof CollectionDescriptor)
- {
- CollectionDescriptor cds = (CollectionDescriptor) entry.getKey();
- EqualsColHelper oldEch = (EqualsColHelper) oldImage.get(cds);
- EqualsColHelper newEch = (EqualsColHelper) entry.getValue();
-//System.out.println("");
-//System.out.println("mark-oldEch: " + oldEch);
-//System.out.println("mark-newEch: " + newEch);
-
- markDelete(cds, oldEch, newEch);
- markNew(cds, oldEch, newEch);
- }
- else
- {
- /*
- check for new 1:1 reference object
- */
- ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) entry.getKey();
- EqualsRefHelper oldEh = (EqualsRefHelper) oldImage.get(rds);
- EqualsRefHelper newEh = (EqualsRefHelper) newImage.get(rds);
- if(!oldEh.equals(newEh))
- {
- // the main objects needs link/unlink of the FK to 1:1 reference,
- // so mark this dirty
- setModificationState(getModificationState().markDirty());
- // if the new reference helper value is not null
- // Lock the object, because it can be a new unregistered object.
- // in other cases it can be an unmaterialized proxy and we
- // don't need to materialize
- if(newEh.value != null)
- {
- // if the object is already registered, OJB knows about
- // else lock and register object, get read lock, because we
- // don't know if the object is new or moved from an existing other object
- ObjectEnvelope oe = buffer.getByIdentity(newEh.oid);
- if(oe == null)
- {
- RuntimeObject rt = new RuntimeObject(newEh.value, getTx());
- getTx().lockAndRegister(rt, TransactionExt.READ, false, getTx().getRegistrationList());
- }
- // in any case we need to link the main object
- addLinkOneToOne(rds, false);
- }
- // if the new image doesn't contain a reference object, the
- // reference is deleted, so lookup the old reference object
- // and mark for delete
- else if(newEh.isNull())
- {
- ObjectEnvelope oldRefMod = buffer.getByIdentity(oldEh.oid);
- // only delete when the reference wasn't assigned with another object
- if(!buffer.isNewAssociatedObject(oldEh.oid))
- {
- // if cascading delete is enabled, remove the 1:1 reference
- // because it was removed from the main object
- if(buffer.getTransaction().cascadeDeleteFor(rds))
- {
- oldRefMod.setModificationState(oldRefMod.getModificationState().markDelete());
- }
- // in any case we have to unlink the main object
- addLinkOneToOne(rds, true);
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Mark object for delete if it's not available in the new Collection.
- */
- private void markDelete(CollectionDescriptor cds, EqualsColHelper oldEch, EqualsColHelper newEch)
- {
- if (oldEch.references.size() == 0)
- {
- return;
- }
- Iterator oldIter = oldEch.references.entrySet().iterator();
- Map newRefs = newEch.references;
- while (oldIter.hasNext())
- {
- Map.Entry entry = (Map.Entry) oldIter.next();
- Identity oldOid = (Identity) entry.getKey();
- if (!newRefs.containsKey(oldOid) && newEch.status != IS_UNMATERIALIZED_PROXY)
- {
- ObjectEnvelope mod = buffer.getByIdentity(oldOid);
- // if this object is associated with another object it's
- // not allowed to remove it
- if(!buffer.isNewAssociatedObject(oldOid))
- {
- if(mod != null)
- {
- boolean cascade = buffer.getTransaction().cascadeDeleteFor(cds);
- if(cascade)
- {
- mod.setModificationState(mod.getModificationState().markDelete());
- buffer.addForDeletionDependent(mod);
- }
- if(cds.isMtoNRelation())
- {
- buffer.addM2NUnlinkEntry(cds, getObject(), entry.getValue());
- }
- else
- {
- // when cascade 'true' we remove all dependent objects, so no need to unlink
- if(!cascade)
- {
- mod.setModificationState(mod.getModificationState().markDirty());
- mod.addLinkOneToN(cds, getObject(), true);
- }
- }
- }
- else
- {
- throw new ImageExcetion("Unexpected behaviour, unregistered object to delete: "
- + oldOid + ", main object is " + getIdentity());
- }
- }
- }
- }
- }
-
- /**
- * Mark object for insert if it's not available in the old Collection.
- */
- private void markNew(CollectionDescriptor cds, EqualsColHelper oldEch, EqualsColHelper newEch)
- {
- if (newEch.references.size() == 0)
- {
- return;
- }
-
- Iterator newIter = newEch.references.entrySet().iterator();
- Map oldRefs = oldEch.references;
- while (newIter.hasNext())
- {
- Map.Entry entry = (Map.Entry) newIter.next();
- Identity newOid = (Identity) entry.getKey();
- Object newObj = entry.getValue();
-
- /*
- search for new objects: if in the old reference collection an object
- of the new reference collection is not contained
- */
- if ((oldRefs == null) || !oldRefs.containsKey(newOid))
- {
- ObjectEnvelope mod = buffer.getByIdentity(newOid);
- if(mod == null) mod = buffer.get(newOid, newObj, true);
- // if the object was deleted in an previous action, mark as new
- // to avoid deletion, else mark object as dirty to assign the FK of
- // the main object
- if(mod.needsDelete())
- {
- mod.setModificationState(mod.getModificationState().markNew());
- }
- else
- {
- /*
- arminw: if the reference is a m:n relation and the object state is
- old clean, no need to update the reference.
- */
- if(!(cds.isMtoNRelation() && mod.getModificationState().equals(StateOldClean.getInstance())))
- {
- mod.setModificationState(mod.getModificationState().markDirty());
- }
- }
- // buffer this object as "new" in a list to prevent deletion
- // when object was moved from one collection to another
- buffer.addNewAssociatedIdentity(newOid);
- // new referenced object found, so register all m:n relation for "linking"
- if(cds.isMtoNRelation())
- {
- buffer.addM2NLinkEntry(cds, getObject(), newObj);
- }
- else
- {
- // we have to link the new object
- mod.addLinkOneToN(cds, getObject(), false);
- }
- if(mod.needsInsert())
- {
- buffer.addForInsertDependent(mod);
- }
+ Object key = entry.getKey();
+ // we only interested in references
+ if(key instanceof ObjectReferenceDescriptor)
+ {
+ Image oldRefImage = (Image) oldImage.get(key);
+ Image newRefImage = (Image) entry.getValue();
+ newRefImage.performReferenceDetection(oldRefImage);
}
}
}
@@ -765,6 +650,8 @@
if(log.isDebugEnabled()) log.debug("Start INSERT action for " + getIdentity());
performLinkEntries();
getBroker().store(getObject(), getIdentity(), getClassDescriptor(), true, true);
+ Identity oldOid = refreshIdentity();
+ buffer.replaceRegisteredIdentity(getIdentity(), oldOid);
}
public void doDelete()
@@ -779,26 +666,45 @@
getBroker().removeFromCache(getIdentity());
}
- public boolean isWriteLocked()
+ boolean isWriteLocked()
{
return writeLocked;
}
- public void setWriteLocked(boolean writeLocked)
+ void setWriteLocked(boolean writeLocked)
{
this.writeLocked = writeLocked;
}
+ boolean isMarkedForCascadingInsert()
+ {
+ return markedForCascadingInsert;
+ }
+
+ void markForCascadingInsert()
+ {
+ this.markedForCascadingInsert = true;
+ }
+
+ boolean isMarkedForCascadingDelete()
+ {
+ return markedForCascadingDelete;
+ }
+
+ void markForCascadingDelete()
+ {
+ this.markedForCascadingDelete = true;
+ }
+
ClassDescriptor getClassDescriptor()
{
- return getBroker().getClassDescriptor(getBroker().getProxyFactory().getRealClass(getObject()));
+ return getBroker().getClassDescriptor(getProxyFactory().getRealClass(getObject()));
}
void addLinkOneToOne(ObjectReferenceDescriptor ord, boolean unlink)
{
LinkEntry entry = new LinkEntryOneToOne(ord, getObject(), unlink);
linkEntryList.add(entry);
- //setModificationState(getModificationState().markDirty());
}
void addLinkOneToN(CollectionDescriptor col, Object source, boolean unlink)
@@ -806,7 +712,6 @@
if(col.isMtoNRelation()) throw new OJBRuntimeException("Expected an 1:n relation, but specified a m:n");
LinkEntry entry = new LinkEntryOneToN(source, col, getObject(), unlink);
linkEntryList.add(entry);
- //setModificationState(getModificationState().markDirty());
}
private void performLinkEntries()
@@ -819,326 +724,132 @@
}
}
-
- //====================================================
- // inner class
- //====================================================
- /**
- * Help to compare field values.
- */
- abstract class EqualsBase
- {
- /**
- * This method is called before committing the transaction
- * to allow cleanup of used resources, e.g. remove proxy listener objects
- * to avoid invoke of registered objects after tx end.
- */
- abstract void cleanup(boolean reuse);
- }
-
- //====================================================
- // inner class
- //====================================================
- /**
- * Help to compare field values.
- */
- class EqualsFieldHelper extends EqualsBase
+ public void addedOneToOne(ObjectReferenceDescriptor ord, Object refObjOrProxy, Identity oid)
{
- FieldType type;
- Object value;
-
- public EqualsFieldHelper(FieldType type, Object value)
- {
- this.type = type;
- this.value = value;
- }
-
- void cleanup(boolean reuse)
+ // the main objects needs link/unlink of the FK to 1:1 reference,
+ // so mark this dirty
+ setModificationState(getModificationState().markDirty());
+ // if the object is already registered, OJB knows about
+ // else lock and register object, get read lock, because we
+ // don't know if the object is new or moved from an existing other object
+ ObjectEnvelope oe = buffer.getByIdentity(oid);
+ if(oe == null)
{
+ RuntimeObject rt = new RuntimeObject(refObjOrProxy, getTx());
+ // we don't use cascade locking, because new reference object
+ // will be detected by ObjectEnvelopeTable#cascadeMarkedForInsert()
+ getTx().lockAndRegister(rt, TransactionExt.READ, false);
}
+ // in any case we need to link the main object
+ addLinkOneToOne(ord, false);
+ }
- public boolean equals(Object valueNew)
+ public void deletedOneToOne(ObjectReferenceDescriptor ord, Object refObjOrProxy, Identity oid, boolean needsUnlink)
+ {
+ // the main objects needs link/unlink of the FK to 1:1 reference,
+ // so mark this dirty
+ setModificationState(getModificationState().markDirty());
+ ObjectEnvelope oldRefMod = buffer.getByIdentity(oid);
+ // only delete when the reference wasn't assigned with another object
+ if(!buffer.isNewAssociatedObject(oid))
{
- boolean result = false;
- if(this==valueNew)
+ // if cascading delete is enabled, remove the 1:1 reference
+ // because it was removed from the main object
+ if(buffer.getTransaction().cascadeDeleteFor(ord))
{
- result = true;
- }
- else
- {
- if(valueNew instanceof EqualsFieldHelper)
- {
- result = type.equals(value, ((EqualsFieldHelper) valueNew).value);
- }
+ oldRefMod.setModificationState(oldRefMod.getModificationState().markDelete());
}
-// if(!result)
-// {
-// System.out.println("** changed field: " + getIdentity() + ", this="+this + ", other=" + valueNew);
-// }
- return result;
- }
-
- public String toString()
- {
- return "EqualsFieldHelper[type=" + type + "->value=" + value + "]";
+ // unlink the main object
+ if(needsUnlink) addLinkOneToOne(ord, true);
}
}
- //====================================================
- // inner class
- //====================================================
- /**
- * Help to compare 1:1 references of the main object.
- */
- class EqualsRefHelper extends EqualsBase
+ public void addedXToN(CollectionDescriptor cod, Object refObjOrProxy, Identity oid)
{
- Identity oid;
- Object value;
-
- public EqualsRefHelper(Object refObject)
- {
- this.value = refObject;
- }
-
- public EqualsRefHelper(Identity oid)
+ ObjectEnvelope mod = buffer.getByIdentity(oid);
+ // if the object isn't registered already, it can be 'new' or already 'persistent'
+ if(mod == null)
{
- this.oid = oid;
+ boolean isNew = getTx().isTransient(null, refObjOrProxy, oid);
+ mod = buffer.get(oid, refObjOrProxy, isNew);
}
-
- void cleanup(boolean reuse)
+ // if the object was deleted in an previous action, mark as new
+ // to avoid deletion, else mark object as dirty to assign the FK of
+ // the main object
+ if(mod.needsDelete())
{
+ mod.setModificationState(mod.getModificationState().markNew());
}
-
- /**
- * The reference is <em>null</em> when both Identity and Object attribute
- * is null.
- */
- public boolean isNull()
- {
- return oid == null && value == null;
- }
-
- public boolean equals(Object toCompare)
+ else
{
- boolean result = false;
- if(this==toCompare)
- {
- result = true;
- }
- else
+ /*
+ arminw: if the reference is a m:n relation and the object state is
+ old clean, no need to update the reference.
+ */
+ if(!(cod.isMtoNRelation() && mod.getModificationState().equals(StateOldClean.getInstance())))
{
- if(toCompare instanceof EqualsRefHelper)
- {
- EqualsRefHelper other = (EqualsRefHelper) toCompare;
- if(oid == null)
- {
- if(value != null)
- {
- oid = getBroker().serviceIdentity().buildIdentity(value);
- }
- }
- if(other.oid == null)
- {
- if(other.value != null)
- {
- other.oid = getBroker().serviceIdentity().buildIdentity(other.value);
- }
- }
- // return oid != null ? oid.equals(other.oid) : other.oid == null;
- result = oid != null ? oid.equals(other.oid) : other.oid == null;
- }
+ mod.setModificationState(mod.getModificationState().markDirty());
}
-// if(!result)
-// {
-// System.out.println("** changed 1:1: " + getIdentity() + ", ref: " + oid);
-// }
- return result;
- }
- }
-
- //====================================================
- // inner class
- //====================================================
- /**
- * Help to compare 1:n / m:n references of the main object.
- */
- class EqualsColHelper extends EqualsBase implements CollectionProxyListener
- {
- private CollectionDescriptor des;
- private CollectionProxy collectionHandler;
- private int status;
- private Map references;
-
- public EqualsColHelper(CollectionDescriptor des, Object collOrArray)
- {
- this.des = des;
- references = new HashMap();
- assignReferenceObject(collOrArray);
- }
-
- public String toString()
- {
- return new ToStringBuilder(this)
- .append("main class", des.getClassDescriptor().getClassNameOfObject())
- .append("reference name", des.getPersistentField().getName())
- .append("reference class", des.getItemClassName())
- .append("status", status)
- .append("references", references)
- .toString();
}
-
- /**
- * Always returns true, because changes in 1:n or m:n relations
- * do not influence main object, no need for update main object
- * thus return always true.
- */
- public boolean equals(Object obj)
+ // buffer this object as "new" in a list to prevent deletion
+ // when object was moved from one collection to another
+ buffer.addNewAssociatedIdentity(oid);
+ // new referenced object found, so register all m:n relation for "linking"
+ if(cod.isMtoNRelation())
{
- return (obj instanceof EqualsColHelper);
+ buffer.addM2NLinkEntry(cod, getObject(), refObjOrProxy);
}
-
- void cleanup(boolean reuse)
+ else
{
- if(!reuse && collectionHandler != null)
- {
- collectionHandler.removeListener(this);
- collectionHandler = null;
- }
+ // we have to link the new object
+ mod.addLinkOneToN(cod, getObject(), false);
}
+// arminw: this object will be matched again in ObjectEnvelopeTable#cascadingDependents()
+// and then be added
+// if(mod.needsInsert())
+// {
+// buffer.addForInsertDependent(mod);
+// }
+ }
- void assignReferenceObject(Object collOrArray)
+ public void deletedXToN(CollectionDescriptor cod, Object refObjOrProxy, Identity oid)
+ {
+ ObjectEnvelope mod = buffer.getByIdentity(oid);
+ // if this object is associated with another object it's
+ // not allowed to remove it, thus nothing will change
+ if(!buffer.isNewAssociatedObject(oid))
{
- CollectionProxy colProxy = getBroker().getProxyFactory().getCollectionProxy(collOrArray);
- if(colProxy != null)
+ if(mod != null)
{
- if(colProxy.isLoaded())
- {
- status = IS_MATERIALIZED_PROXY;
- /*
- TODO: how will Arrays be handled?
- */
- handleCollection(colProxy.iterator());
- }
- else
+ boolean cascade = buffer.getTransaction().cascadeDeleteFor(cod);
+ if(cascade)
{
- status = IS_UNMATERIALIZED_PROXY;
-// TODO: ObjectEnvelopeTable#register take care of proxy objects/collection, no need to handle proxy objects??
- colProxy.addListener(this);
- collectionHandler = colProxy;
+ mod.setModificationState(mod.getModificationState().markDelete());
+ // arminw: this object will be matched again in ObjectEnvelopeTable#cascadingDependents()
+ // and then be added
+ //buffer.addForDeletionDependent(mod);
}
- }
- else
- {
- status = IS_MATERIALIZED_OBJECT;
- if(collOrArray != null)
+ if(cod.isMtoNRelation())
{
- Iterator it = BrokerHelper.getCollectionIterator(getBroker(), collOrArray);
- handleCollection(it);
+ buffer.addM2NUnlinkEntry(cod, getObject(), refObjOrProxy);
}
- }
- }
-
- public void beforeLoading(CollectionProxy colProxy)
- {
- //noop
- }
-
- public void afterLoading(CollectionProxy colProxy)
- {
- if(status == IS_UNMATERIALIZED_PROXY)
- {
- //System.out.println("**** materialize " + this + " ->> data: " + colProxy.getData());
- // reference to the proxy data
- handleMaterializedCollectionProxy(colProxy);
- status = IS_MATERIALIZED_PROXY;
- colProxy.removeListener(this);
- collectionHandler = null;
- }
- }
-
- void addReference(Identity oid, Object obj)
- {
- references.put(oid, obj);
- }
-
- void handleCollection(Iterator it)
- {
- if(it == null) return;
- Object obj;
- while(it.hasNext())
- {
- obj = it.next();
- addReference(getBroker().serviceIdentity().buildIdentity(obj), obj);
- }
- }
-
- void handleMaterializedCollectionProxy(CollectionProxy colProxy)
- {
- if(colProxy == null || colProxy.size() == 0)
- {
- // nothing to do
- return;
- }
- // if the object materialize outside of a running tx (should not happen), we have to lookup
- // a broker instance itself, so use PBCapsule to handle this
- PBCapsule capsule = new PBCapsule(getTx().getBrokerInternal().getConfiguration(), getTx());
- try
- {
- PersistenceBroker broker = capsule.getBroker();
- Iterator it = colProxy.iterator();
- Object tempObj;
- IndirectionHandler tempHandler;
- while(it.hasNext())
+ else
{
- tempObj = it.next();
- // the referenced objects can be proxy objects too
- tempHandler = getBroker().getProxyFactory().getIndirectionHandler(tempObj);
- if(tempHandler != null)
+ // when cascade 'true' we remove all dependent objects, so no need
+ // to unlink, else we have to unlink all referenced objects of this
+ // object
+ if(!cascade)
{
- addReference(tempHandler.getIdentity(), tempObj);
- }
- else
- {
- addReference(broker.serviceIdentity().buildIdentity(tempObj), tempObj);
+ mod.setModificationState(mod.getModificationState().markDirty());
+ mod.addLinkOneToN(cod, getObject(), true);
}
}
}
- finally
+ else
{
- capsule.destroy();
+ throw new Image.ImageException("Unexpected behaviour, unregistered object to delete: "
+ + oid + ", main object is " + getIdentity()+ ", envelope object is " + this.toString());
}
}
}
-
-
- //====================================================
- // inner class
- //====================================================
- /**
- * Thrown if something unexpected is happen when handling the
- * object images for state detection.
- */
- public static class ImageExcetion extends OJBRuntimeException
- {
- public ImageExcetion()
- {
- }
-
- public ImageExcetion(String msg)
- {
- super(msg);
- }
-
- public ImageExcetion(Throwable cause)
- {
- super(cause);
- }
-
- public ImageExcetion(String msg, Throwable cause)
- {
- super(msg, cause);
- }
- }
-
-
}
Modified: db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java
URL: http://svn.apache.org/viewvc/db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java?rev=422235&r1=422234&r2=422235&view=diff
==============================================================================
--- db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java (original)
+++ db/ojb/trunk/src/java/org/apache/ojb/odmg/ObjectEnvelopeOrdering.java Sat Jul 15 07:28:03 2006
@@ -1,6 +1,6 @@
package org.apache.ojb.odmg;
-/* Copyright 2002-2004 The Apache Software Foundation
+/* Copyright 2002-2005 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.
@@ -18,12 +18,12 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.PersistenceBrokerInternal;
+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.ObjectReferenceDescriptor;
@@ -86,28 +86,20 @@
private static Logger log = LoggerFactory.getLogger(ObjectEnvelopeOrdering.class);
private List originalOrder;
- private Map envelopes;
private Vertex[] vertices;
private List edgeList;
- private int newOrderIndex;
- private Identity[] newOrder;
-
- private PersistenceBrokerInternal broker;
+ private ObjectEnvelope[] newOrder;
/**
* Creates an object envelope ordering based on an original ordering
* of Identity objects and an Identity->ObjectEnvelope map
* @param originalOrder a list of Identity objects
- * @param envelopes a map with ObjectEnvelope-s with their respective
- * Identity-s as key
*/
- public ObjectEnvelopeOrdering(PersistenceBrokerInternal broker, List originalOrder, Map envelopes)
+ public ObjectEnvelopeOrdering(List originalOrder)
{
this.originalOrder = originalOrder;
- this.envelopes = envelopes;
- this.broker = broker;
}
/**
@@ -117,13 +109,14 @@
*/
public void reorder()
{
- long t1 = 0, t2 = 0, t3 = 0;
+ int newOrderIndex = 0;
+ long t1 = 0, t2 = 0, t3;
+
if (log.isDebugEnabled())
{
t1 = System.currentTimeMillis();
}
- newOrder = new Identity[originalOrder.size()];
- newOrderIndex = 0;
+ newOrder = new ObjectEnvelope[originalOrder.size()];
if(log.isDebugEnabled()) log.debug("Orginal order: " + originalOrder);
// set up the vertex array in the order the envelopes were added
@@ -131,7 +124,7 @@
// int vertexIndex = 0;
for (Iterator it = originalOrder.iterator(); it.hasNext();)
{
- ObjectEnvelope envelope = (ObjectEnvelope) envelopes.get(it.next());
+ ObjectEnvelope envelope = (ObjectEnvelope) it.next();
if (envelope.needsUpdate() || envelope.needsInsert() || envelope.needsDelete())
{
Vertex vertex = new Vertex(envelope);
@@ -144,7 +137,7 @@
else
{
// envelope is clean - just add identity to new order
- newOrder[newOrderIndex++] = envelope.getIdentity();
+ newOrder[newOrderIndex++] = envelope;
if (log.isDebugEnabled())
{
log.debug("Add unmodified object "+envelope.getIdentity()+" to new OrderList");
@@ -213,7 +206,7 @@
Vertex vertex = vertices[i];
if (!vertex.isProcessed() && vertex.getIncomingEdgeWeight() == minIncomingEdgeWeight)
{
- newOrder[newOrderIndex++] = vertex.getEnvelope().getIdentity();
+ newOrder[newOrderIndex++] = vertex.getEnvelope();
vertex.markProcessed();
processCount++;
if (log.isDebugEnabled())
@@ -247,7 +240,7 @@
* @return an array of Identity objects representing the opimized sequence
* of database operations
*/
- public Identity[] getOrdering()
+ public ObjectEnvelope[] getOrdering()
{
if (newOrder == null)
{
@@ -286,7 +279,7 @@
*/
private void addObjectReferenceEdges(Vertex vertex, ObjectReferenceDescriptor rds)
{
- Object refObject = rds.getPersistentField().get(vertex.getEnvelope().getObject());
+ Object refObject = rds.getPersistentField().get(vertex.getEnvelope().getRealObject());
Class refClass = rds.getItemClass();
for (int i = 0; i < vertices.length; i++)
{
@@ -294,13 +287,13 @@
// ObjectEnvelope envelope = vertex.getEnvelope();
Vertex refVertex = vertices[i];
ObjectEnvelope refEnvelope = refVertex.getEnvelope();
- if (refObject == refEnvelope.getObject())
+ if (refObject == refEnvelope.getRealObject())
{
- edge = buildConcrete11Edge(vertex, refVertex, rds.hasForeignKey());
+ edge = buildConcrete11Edge(vertex, refVertex, rds.hasConstraint());
}
- else if (refClass.isInstance(refVertex.getEnvelope().getObject()))
+ else if (refClass.isInstance(refVertex.getEnvelope().getRealObject()))
{
- edge = buildPotential11Edge(vertex, refVertex, rds.hasForeignKey());
+ edge = buildPotential11Edge(vertex, refVertex, rds.hasConstraint());
}
if (edge != null)
{
@@ -325,16 +318,16 @@
private void addCollectionEdges(Vertex vertex, CollectionDescriptor cds)
{
ObjectEnvelope envelope = vertex.getEnvelope();
- Object col = cds.getPersistentField().get(envelope.getObject());
+ Object col = cds.getPersistentField().get(envelope.getRealObject());
Object[] refObjects;
- if (col == null || (broker.getProxyFactory().isCollectionProxy(col)
- && !broker.getProxyFactory().getCollectionProxy(col).isLoaded()))
+ ProxyFactory pf = envelope.getBroker().getProxyFactory();
+ if (col == null || (pf.isCollectionProxy(col) && !pf.getCollectionProxy(col).isLoaded()))
{
refObjects = EMPTY_OBJECT_ARRAY;
}
else
{
- refObjects = BrokerHelper.getCollectionArray(broker, col);
+ refObjects = BrokerHelper.getCollectionArray(envelope.getBroker(), col);
}
Class refClass = cds.getItemClass();
@@ -344,9 +337,9 @@
Vertex refVertex = vertices[i];
ObjectEnvelope refEnvelope = refVertex.getEnvelope();
- if (refClass.isInstance(refEnvelope.getObject()))
+ if (refClass.isInstance(refEnvelope.getRealObject()))
{
- if (containsObject(refEnvelope.getObject(), refObjects))
+ if (containsObject(refEnvelope.getRealObject(), refObjects))
{
if (cds.isMtoNRelation())
{
---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org