You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/12/07 07:27:45 UTC

[isis] 01/03: ISIS-2911: make ManagedObject.pojo non-final

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2f45c2b5e17737c17d9306cf1e7e24291bfb0a11
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Dec 7 08:17:13 2021 +0100

    ISIS-2911: make ManagedObject.pojo non-final
    
    - for the sole purpose of allowing in-place pojo replacement for
    re-attaching entity pojos
---
 .../interactions/managed/ManagedMember.java        |  5 ++--
 .../isis/core/metamodel/spec/ManagedObject.java    | 29 +++++++++++++++-----
 .../isis/core/metamodel/spec/ManagedObjects.java   | 31 +++++++++++++++++-----
 3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
index e69e381..a49995e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedMember.java
@@ -96,9 +96,10 @@ implements ManagedFeature {
 
     @NonNull private ManagedObject owner;
     public ManagedObject getOwner() {
-        //XXX this is a hack,
+        //XXX this is a safeguard
         // see also org.apache.isis.core.metamodel.interactions.managed.ManagedProperty.ManagedProperty(ManagedObject, OneToOneAssociation, Where)
-        return owner = EntityUtil.reattach(owner);
+        EntityUtil.reattach(owner);
+        return owner;
     }
 
     @Getter @NonNull private final Where where;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index 26b627f..e0f8bbb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -35,12 +35,11 @@ import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
 import lombok.ToString;
-import lombok.Value;
 import lombok.val;
 
 /**
@@ -62,6 +61,13 @@ public interface ManagedObject {
     Object getPojo();
 
     /**
+     * Introduced, so we can re-attach detached entity pojos in place.
+     * @apiNote should be package private, and not publicly exposed
+     * (but the <i>Java</i> language is not there yet)
+     */
+    void replacePojo(UnaryOperator<Object> replacer);
+
+    /**
      * Returns the object's bookmark as identified by the ObjectManager.
      * Bookmarks are considered immutable, hence will be memoized once fetched.
      */
@@ -220,10 +226,12 @@ public interface ManagedObject {
 
     // -- SIMPLE
 
-    @Value
-    @RequiredArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
+    //@Value
+    //@RequiredArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
+    @AllArgsConstructor(staticName="of", access = AccessLevel.PRIVATE)
     @EqualsAndHashCode(of = "pojo")
     @ToString(of = {"specification", "pojo"}) //ISIS-2317 make sure toString() is without side-effects
+    @Getter
     static final class SimpleManagedObject implements ManagedObject {
 
         public static ManagedObject identified(
@@ -236,7 +244,7 @@ public interface ManagedObject {
         }
 
         @NonNull private final ObjectSpecification specification;
-        @Nullable private final Object pojo;
+        @Nullable private /*final*/ Object pojo;
 
         @Override
         public Optional<Bookmark> getBookmark() {
@@ -261,6 +269,11 @@ public interface ManagedObject {
             return bookmarkLazy.isMemoized();
         }
 
+        @Override
+        public void replacePojo(final UnaryOperator<Object> replacer) {
+            pojo = replacer.apply(pojo);
+        }
+
     }
 
     // -- LAZY
@@ -270,7 +283,7 @@ public interface ManagedObject {
 
         @NonNull private final Function<Class<?>, ObjectSpecification> specLoader;
 
-        @Getter @NonNull private final Object pojo;
+        @Getter @NonNull private /*final*/ Object pojo;
 
         @Override
         public Optional<Bookmark> getBookmark() {
@@ -323,6 +336,10 @@ public interface ManagedObject {
             return specLoader.apply(pojo.getClass());
         }
 
+        @Override
+        public void replacePojo(final UnaryOperator<Object> replacer) {
+            pojo = replacer.apply(pojo);
+        }
 
 
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
index e6cf411..6773ca5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
@@ -337,7 +337,7 @@ public final class ManagedObjects {
 
         return _NullSafe.streamAutodetect(collectionOrArray)
         .map(pojo->ManagedObject.of(elementSpec, pojo)) // pojo is nullable here
-        .map(ManagedObjects.EntityUtil::reattach)
+        .peek(ManagedObjects.EntityUtil::reattach)
         .filter(ManagedObjects.VisibilityUtil.filterOn(interactionInitiatedBy))
         .collect(Can.toCan());
     }
@@ -424,6 +424,10 @@ public final class ManagedObjects {
             return false;
         }
 
+        @Override
+        public void replacePojo(final UnaryOperator<Object> replacer) {
+        }
+
     };
 
     // -- TITLE UTILITIES
@@ -614,28 +618,41 @@ public final class ManagedObjects {
             return managedObject;
         }
 
-        @Nullable
-        public static ManagedObject reattach(final @Nullable ManagedObject managedObject) {
+        //@Nullable
+        public static void reattach(final @Nullable ManagedObject managedObject) {
             if(isNullOrUnspecifiedOrEmpty(managedObject)) {
-                return managedObject;
+                //return managedObject;
+                return;
             }
             val entityState = EntityUtil.getEntityState(managedObject);
             if(!entityState.isPersistable()) {
-                return managedObject;
+                //return managedObject;
+                return;
             }
             if(!entityState.isDetached()) {
-                return managedObject;
+                //return managedObject;
+                return;
             }
 
             val spec = managedObject.getSpecification();
             val objectManager = managedObject.getObjectManager();
 
-            return bookmark(managedObject)
+            val reattached = bookmark(managedObject)
             .map(bookmark->objectManager.loadObject(
                     ObjectLoader.Request.of(
                                     spec,
                                     bookmark)))
             .orElse(managedObject);
+
+
+            val state = EntityUtil.getEntityState(reattached);
+            if(state.isPersistable()) {
+                _Assert.assertTrue(state.isAttached());
+            }
+
+            managedObject.replacePojo(old->reattached.getPojo());
+
+            //return reattached;
         }
 
         public static void requiresWhenFirstIsBookmarkableSecondIsAttached(