Repository: isis
Updated Branches:
  refs/heads/master 4dd4a435e -> e7d7ab5f3


ISIS-1435: fixes infinite recursion for updating()

... as demonstrated by public void updating() { setName(getName() + " - 
updating"; }

We now only call the updating() callback, and also the domain event lifecycle 
callback, if it hasn't previously been called.  We figure that out by looking 
asking the ChangedObjectsService (new API) as to whether the object was 
previously changed or not (if so, then don't fire the callbacks).


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/e7d7ab5f
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/e7d7ab5f
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/e7d7ab5f

Branch: refs/heads/master
Commit: e7d7ab5f3a578f7c5434e2694c2fad8f2f97a2e0
Parents: 4dd4a43
Author: Dan Haywood <d...@haywood-associates.co.uk>
Authored: Thu Jun 23 18:42:03 2016 +0100
Committer: Dan Haywood <d...@haywood-associates.co.uk>
Committed: Thu Jun 23 18:42:03 2016 +0100

----------------------------------------------------------------------
 .../changes/ChangedObjectsServiceInternal.java  | 24 +++++++++-----------
 .../system/persistence/PersistenceSession.java  | 11 +++++++--
 2 files changed, 20 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/e7d7ab5f/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
index 9aa6d63..ffd5721 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/changes/ChangedObjectsServiceInternal.java
@@ -24,7 +24,6 @@ import java.util.Set;
 
 import javax.enterprise.context.RequestScoped;
 
-import com.google.common.base.Predicate;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
@@ -33,11 +32,12 @@ import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.PublishedObject;
 import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.applib.services.WithTransactionScope;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
-import org.apache.isis.applib.services.WithTransactionScope;
 
 @DomainService(nature = NatureOfService.DOMAIN)
 @RequestScoped
@@ -66,6 +66,12 @@ public class ChangedObjectsServiceInternal implements 
WithTransactionScope {
     // used for publishing
     private final Map<ObjectAdapter,PublishedObject.ChangeKind> 
changeKindByEnlistedAdapter = Maps.newLinkedHashMap();
 
+    @Programmatic
+    public boolean isEnlisted(ObjectAdapter adapter) {
+        return changeKindByEnlistedAdapter.containsKey(adapter);
+    }
+
+
     /**
      * Auditing and publishing support: for object stores to enlist an object 
that has just been created,
      * capturing a dummy value <tt>'[NEW]'</tt> for the pre-modification value.
@@ -172,9 +178,6 @@ public class ChangedObjectsServiceInternal implements 
WithTransactionScope {
 
 
     /**
-     *
-     * @param adapter
-     * @param current
      * @return <code>true</code> if successfully enlisted, <code>false</code> 
if was already enlisted
      */
     private boolean enlistForPublishing(final ObjectAdapter adapter, final 
PublishedObject.ChangeKind current) {
@@ -247,15 +250,10 @@ public class ChangedObjectsServiceInternal implements 
WithTransactionScope {
                 Sets.filter(processedObjectProperties1.entrySet(), 
PreAndPostValues.Predicates.CHANGED));
     }
 
-    private static final Predicate<ObjectAdapter> IS_TRANSACTION_ID = new 
Predicate<ObjectAdapter>() {
-        @Override
-        public boolean apply(ObjectAdapter input) {
-            return 
HasTransactionId.class.isAssignableFrom(input.getSpecification().getCorrespondingClass());
-        }
-    };
-
     protected boolean shouldIgnore(final ObjectAdapter adapter) {
-        return IS_TRANSACTION_ID.apply(adapter);
+        final ObjectSpecification adapterSpec = adapter.getSpecification();
+        final Class<?> adapterClass = adapterSpec.getCorrespondingClass();
+        return HasTransactionId.class.isAssignableFrom(adapterClass);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/e7d7ab5f/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
----------------------------------------------------------------------
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 9d47b80..1f21a5c 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -2283,11 +2283,18 @@ public class PersistenceSession implements
             return;
         }
 
-        CallbackFacet.Util.callCallback(adapter, UpdatingCallbackFacet.class);
-        postLifecycleEventIfRequired(adapter, 
UpdatingLifecycleEventFacet.class);
+        final boolean wasAlreadyEnlisted = 
changedObjectsServiceInternal.isEnlisted(adapter);
 
+        // we call this come what may;
+        // additional properties may now have been changed, and the changeKind 
for publishing might also be modified
         changedObjectsServiceInternal.enlistUpdating(adapter);
 
+        if(!wasAlreadyEnlisted) {
+            // prevent an infinite loop... don't call the 'updating()' 
callback on this object if we have already done so
+            CallbackFacet.Util.callCallback(adapter, 
UpdatingCallbackFacet.class);
+            postLifecycleEventIfRequired(adapter, 
UpdatingLifecycleEventFacet.class);
+        }
+
         ensureRootObject(pojo);
     }
 

Reply via email to