cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r1234419 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util: DeepMergeOperation.java ObjectContextQueryAction.java ShallowMergeOperation.java
Date Sat, 21 Jan 2012 21:15:44 GMT
Author: aadamchik
Date: Sat Jan 21 21:15:43 2012
New Revision: 1234419

URL: http://svn.apache.org/viewvc?rev=1234419&view=rev
Log:
CAY-1616 Remove internal dependencies on deprecated ObjectContext.localObject

splitting merge method into an action class: ShallowMergeOperation
it is possible as now it no longer depends on the context implementation

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ShallowMergeOperation.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/DeepMergeOperation.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/DeepMergeOperation.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/DeepMergeOperation.java?rev=1234419&r1=1234418&r2=1234419&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/DeepMergeOperation.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/DeepMergeOperation.java
Sat Jan 21 21:15:43 2012
@@ -37,19 +37,21 @@ import org.apache.cayenne.reflect.ToMany
 import org.apache.cayenne.reflect.ToOneProperty;
 
 /**
- * An operation that performs object graph deep merge, terminating merge at unresolved
- * nodes.
+ * An operation that merges changes from an object graph, whose objects are registered in
+ * some ObjectContext, to peer objects in an ObjectConext that is a child of that context.
+ * The merge terminates at hollow nodes in the parent context to avoid tripping over
+ * unresolved relationships.
  * 
  * @since 1.2
  */
 public class DeepMergeOperation {
 
-    protected ObjectContext context;
-    protected Map<ObjectId, Persistent> seen;
+    private Map<ObjectId, Persistent> seen;
+    private ShallowMergeOperation shallowMergeOperation;
 
     public DeepMergeOperation(ObjectContext context) {
-        this.context = context;
         this.seen = new HashMap<ObjectId, Persistent>();
+        this.shallowMergeOperation = new ShallowMergeOperation(context);
     }
 
     public void reset() {
@@ -75,7 +77,7 @@ public class DeepMergeOperation {
             return seenTarget;
         }
 
-        final Persistent target = context.localObject(id, source);
+        final Persistent target = shallowMergeOperation.merge(source);
         seen.put(id, target);
 
         descriptor = descriptor.getSubclassDescriptor(source.getClass());
@@ -101,17 +103,17 @@ public class DeepMergeOperation {
             public boolean visitToMany(ToManyProperty property) {
                 if (!property.isFault(source)) {
                     Object value = property.readProperty(source);
-                    Object targetValue; 
-                    
+                    Object targetValue;
+
                     if (property instanceof ToManyMapProperty) {
                         Map<?, ?> map = (Map) value;
                         Map targetMap = new HashMap();
-                        
+
                         for (Entry entry : map.entrySet()) {
                             Object destinationSource = entry.getValue();
-                            Object destinationTarget = destinationSource != null
-                                ? merge(destinationSource, property.getTargetDescriptor())
-                                    : null;
+                            Object destinationTarget = destinationSource != null ? merge(
+                                    destinationSource,
+                                    property.getTargetDescriptor()) : null;
 
                             targetMap.put(entry.getKey(), destinationTarget);
                         }
@@ -122,9 +124,9 @@ public class DeepMergeOperation {
                         Collection targetCollection = new ArrayList(collection.size());
 
                         for (Object destinationSource : collection) {
-                            Object destinationTarget = destinationSource != null
-                                    ? merge(destinationSource, property.getTargetDescriptor())
-                                    : null;
+                            Object destinationTarget = destinationSource != null ? merge(
+                                    destinationSource,
+                                    property.getTargetDescriptor()) : null;
 
                             targetCollection.add(destinationTarget);
                         }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java?rev=1234419&r1=1234418&r2=1234419&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ObjectContextQueryAction.java
Sat Jan 21 21:15:43 2012
@@ -48,7 +48,7 @@ import org.apache.cayenne.reflect.ClassD
  * <p>
  * <i>Intended for internal use only.</i>
  * </p>
- *
+ * 
  * @since 1.2
  */
 public abstract class ObjectContextQueryAction {
@@ -120,6 +120,7 @@ public abstract class ObjectContextQuery
             // rewrite response to contain objects from the query context
 
             GenericResponse childResponse = new GenericResponse();
+            ShallowMergeOperation merger = null;
 
             for (response.reset(); response.next();) {
                 if (response.isList()) {
@@ -130,6 +131,10 @@ public abstract class ObjectContextQuery
                     }
                     else {
 
+                        if (merger == null) {
+                            merger = new ShallowMergeOperation(targetContext);
+                        }
+
                         // TODO: Andrus 1/31/2006 - IncrementalFaultList is not properly
                         // transferred between contexts....
 
@@ -137,8 +142,7 @@ public abstract class ObjectContextQuery
                         Iterator it = objects.iterator();
                         while (it.hasNext()) {
                             Persistent object = (Persistent) it.next();
-                            childObjects.add(targetContext.localObject(object
-                                    .getObjectId(), object));
+                            childObjects.add(merger.merge(object));
                         }
 
                         childResponse.addResultList(childObjects);
@@ -245,17 +249,17 @@ public abstract class ObjectContextQuery
                         }
 
                         /**
-                         * Workaround for CAY-1183. If a Relationship query is being sent
from
-                         * child context, we assure that local object is not NEW and relationship
- unresolved
-                         * (this way exception will occur). This helps when faulting objects
that
-                         * were committed to parent context (this), but not to database.
-                         *
-                         * Checking type of context's channel is the only way to ensure that
we are
-                         * on the top level of context hierarchy (there might be more than
one-level-deep
+                         * Workaround for CAY-1183. If a Relationship query is being sent
+                         * from child context, we assure that local object is not NEW and
+                         * relationship - unresolved (this way exception will occur). This
+                         * helps when faulting objects that were committed to parent
+                         * context (this), but not to database. Checking type of context's
+                         * channel is the only way to ensure that we are on the top level
+                         * of context hierarchy (there might be more than one-level-deep
                          * nested contexts).
                          */
                         if (((Persistent) object).getPersistenceState() == PersistenceState.NEW
-                            && !(actingContext.getChannel() instanceof BaseContext))
{
+                                && !(actingContext.getChannel() instanceof BaseContext))
{
                             this.response = new ListResponse();
                             return DONE;
                         }

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ShallowMergeOperation.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ShallowMergeOperation.java?rev=1234419&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ShallowMergeOperation.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/util/ShallowMergeOperation.java
Sat Jan 21 21:15:43 2012
@@ -0,0 +1,95 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.util;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.PersistenceState;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.graph.GraphManager;
+import org.apache.cayenne.reflect.ClassDescriptor;
+
+/**
+ * An operation that merges changes from a single object registered in some ObjectContext,
+ * to a peer object in an ObjectConext that is a child of that context.
+ * 
+ * @since 3.1
+ */
+public class ShallowMergeOperation {
+
+    private final ObjectContext context;
+
+    public ShallowMergeOperation(ObjectContext context) {
+        this.context = context;
+    }
+
+    public Persistent merge(Persistent peerInParentContext) {
+
+        if (peerInParentContext == null) {
+            throw new IllegalArgumentException("Null peerInParentContext");
+        }
+
+        // handling of HOLLOW peer state is here for completeness... Wonder if we ever
+        // have a case where it is applicable.
+        int peerState = peerInParentContext.getPersistenceState();
+
+        ObjectId id = peerInParentContext.getObjectId();
+
+        ClassDescriptor descriptor = context.getEntityResolver().getClassDescriptor(
+                id.getEntityName());
+
+        GraphManager graphManager = context.getGraphManager();
+
+        // have to synchronize almost the entire method to prevent multiple threads from
+        // messing up dataobjects per CAY-845.
+        synchronized (graphManager) {
+            Persistent object = (Persistent) graphManager.getNode(id);
+
+            // merge into an existing object
+            if (object == null) {
+                object = (Persistent) descriptor.createObject();
+                object.setObjectContext(context);
+                object.setObjectId(id);
+
+                if (peerState == PersistenceState.HOLLOW) {
+                    object.setPersistenceState(PersistenceState.HOLLOW);
+                }
+                else {
+                    object.setPersistenceState(PersistenceState.COMMITTED);
+                }
+
+                graphManager.registerNode(id, object);
+            }
+
+            // TODO: Andrus, 1/24/2006 implement smart merge for modified objects...
+            if (peerState != PersistenceState.HOLLOW
+                    && object.getPersistenceState() != PersistenceState.MODIFIED
+                    && object.getPersistenceState() != PersistenceState.DELETED)
{
+
+                descriptor.shallowMerge(peerInParentContext, object);
+
+                if (object.getPersistenceState() == PersistenceState.HOLLOW) {
+                    object.setPersistenceState(PersistenceState.COMMITTED);
+                }
+            }
+
+            return object;
+        }
+    }
+}



Mime
View raw message