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 2020/06/30 15:29:14 UTC

[isis] branch master updated: ISIS-2383: fail earlier (more informative exception message)

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


The following commit(s) were added to refs/heads/master by this push:
     new ff35d90  ISIS-2383: fail earlier (more informative exception message)
ff35d90 is described below

commit ff35d90f4f93944a2ba519f62ee6b9caa2584e1b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jun 30 17:28:56 2020 +0200

    ISIS-2383: fail earlier (more informative exception message)
---
 .../isis/core/metamodel/spec/ManagedObject.java    | 26 ++++++++++++--
 .../metamodel/spec/ManagedObjectInternalUtil.java  |  5 +++
 .../isis/core/metamodel/spec/ManagedObjects.java   | 13 ++++---
 .../datanucleus5/objectadapter/PojoAdapter.java    |  5 +++
 .../mementos/ObjectMementoServiceWicket.java       | 40 +++++++++++-----------
 5 files changed, 62 insertions(+), 27 deletions(-)

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 d93fd75..06ef176 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
@@ -61,6 +61,8 @@ public interface ManagedObject {
      */
     Optional<RootOid> getRootOid();
     
+    boolean isRootOidMemoized();
+    
     // -- TITLE
 
     public default String titleString() {
@@ -176,14 +178,19 @@ public interface ManagedObject {
         @NonNull private final ObjectSpecification specification;
         @Nullable private final Object pojo;
 
+        @Override
         public Optional<RootOid> getRootOid() {
             return rootOidLazy.get();
         }
         
         // -- LAZY ID HANDLING
         private final _Lazy<Optional<RootOid>> rootOidLazy = 
-                _Lazy.threadSafe(()->ManagedObjectInternalUtil.identify(this));  
+                _Lazy.threadSafe(()->ManagedObjectInternalUtil.identify(this));
 
+        @Override
+        public boolean isRootOidMemoized() {
+            return rootOidLazy.isMemoized();
+        }  
         
     }
 
@@ -196,8 +203,19 @@ public interface ManagedObject {
 
         @Getter @NonNull private final Object pojo;
         
-        @Getter(lazy=true, onMethod = @__(@Override)) 
-        private final Optional<RootOid> rootOid = ManagedObjectInternalUtil.identify(this);
+        @Override
+        public Optional<RootOid> getRootOid() {
+            return rootOidLazy.get();
+        }
+        
+        // -- LAZY ID HANDLING
+        private final _Lazy<Optional<RootOid>> rootOidLazy = 
+                _Lazy.threadSafe(()->ManagedObjectInternalUtil.identify(this));
+        
+        @Override
+        public boolean isRootOidMemoized() {
+            return rootOidLazy.isMemoized();
+        }  
 
         private final _Lazy<ObjectSpecification> specification = _Lazy.threadSafe(this::loadSpec);
 
@@ -229,4 +247,6 @@ public interface ManagedObject {
 
     }
 
+    
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjectInternalUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjectInternalUtil.java
index 74dc02f..72933ee 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjectInternalUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjectInternalUtil.java
@@ -54,6 +54,11 @@ final class ManagedObjectInternalUtil {
         public Optional<RootOid> getRootOid() {
             return Optional.empty();
         }
+
+        @Override
+        public boolean isRootOidMemoized() {
+            return false;
+        }
         
     };
 
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 f168d72..b89bb4e 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
@@ -258,7 +258,7 @@ public final class ManagedObjects {
     // -- ADABT UTILITIES
     
     public static Can<ManagedObject> adaptMultipleOfType(
-            @NonNull final ObjectSpecification elementSpec,
+            @NonNull  final ObjectSpecification elementSpec,
             @Nullable final Object collectionOrArray) {
         
         return _NullSafe.streamAutodetect(collectionOrArray)
@@ -270,13 +270,13 @@ public final class ManagedObjects {
      * used eg. to adapt the result of supporting methods, that return choice pojos
      */
     public static Can<ManagedObject> adaptMultipleOfTypeThenAttachThenFilterByVisibility(
-            @NonNull final ObjectSpecification elementSpec,
+            @NonNull  final ObjectSpecification elementSpec,
             @Nullable final Object collectionOrArray, 
             @NonNull  final InteractionInitiatedBy interactionInitiatedBy) {
         
         return _NullSafe.streamAutodetect(collectionOrArray)
         .map(pojo->ManagedObject.of(elementSpec, pojo)) // pojo is nullable here
-//        .map(ManagedObjects.EntityUtil::reattach)
+        .map(ManagedObjects.EntityUtil::reattach)
         .filter(ManagedObjects.VisibilityUtil.filterOn(interactionInitiatedBy))
         .collect(Can.toCan());
     }
@@ -380,7 +380,12 @@ public final class ManagedObjects {
                 return managedObject;
             }
             
-            //TODO identification fails, on detached object, if rootOid was not previously memoized 
+            // identification fails, on detached object, if rootOid was not previously memoized
+            if(!managedObject.isRootOidMemoized()) {
+                throw _Exceptions.illegalState("entity %s is required to have a memoized ID, "
+                        + "otherwise cannot re-attach", 
+                        managedObject.getSpecification().getSpecId());
+            }
             
             val objectIdentifier = identify(managedObject)
                     .map(RootOid::getIdentifier);
diff --git a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/objectadapter/PojoAdapter.java b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/objectadapter/PojoAdapter.java
index d917343..382190b 100644
--- a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/objectadapter/PojoAdapter.java
+++ b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/objectadapter/PojoAdapter.java
@@ -140,5 +140,10 @@ public final class PojoAdapter implements ObjectAdapter {
         return Optional.empty();
     }
 
+    @Override
+    public boolean isRootOidMemoized() {
+        return true; // oid is immutable
+    }
+
 
 }
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
index 74cff48..962d582 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/mementos/ObjectMementoServiceWicket.java
@@ -33,7 +33,6 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.core.commons.internal.base._NullSafe;
-import org.apache.isis.core.commons.internal.debug._Probe;
 import org.apache.isis.core.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
@@ -68,7 +67,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
 
     @Override
     public ObjectMemento mementoForRootOid(@NonNull RootOid rootOid) {
-        _Probe.errOut("mementoForRootOid %s", rootOid);
+//        _Probe.errOut("mementoForRootOid %s", rootOid);
         val mementoAdapter = ObjectMementoLegacy.createPersistent(rootOid, specificationLoader);
         return ObjectMementoAdapter.of(mementoAdapter);
     }
@@ -76,7 +75,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
     @Override
     public ObjectMemento mementoForObject(@Nullable ManagedObject adapter) {
         assertSingleton(adapter);
-        _Probe.errOut("mementoForObject %s", adapter);
+//        _Probe.errOut("mementoForObject %s", adapter);
         val mementoAdapter = ObjectMementoLegacy.createOrNull(adapter);
         if(mementoAdapter==null) {
             // sonar-ignore-on (fails to detect this as null guard)
@@ -90,7 +89,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
     
     @Override
     public ObjectMemento mementoForParameter(@NonNull ManagedObject paramAdapter) {
-        _Probe.errOut("mementoForParameter %s", paramAdapter);
+//        _Probe.errOut("mementoForParameter %s", paramAdapter);
         assertSingleton(paramAdapter);
         val mementoAdapter = ObjectMementoLegacy.createOrNull(paramAdapter);
         if(mementoAdapter==null) {
@@ -102,7 +101,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
 
     @Override
     public ObjectMemento mementoForPojo(Object pojo) {
-        _Probe.errOut("mementoForPojo %s", ""+pojo);
+//        _Probe.errOut("mementoForPojo %s", ""+pojo);
         assertSingleton(pojo);
         
         val managedObject = objectManager.adapt(pojo);
@@ -111,7 +110,7 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
     
     @Override
     public ObjectMemento mementoForPojos(Iterable<Object> iterablePojos, ObjectSpecId specId) {
-        _Probe.errOut("mementoForPojos");
+//        _Probe.errOut("mementoForPojos");
         val listOfMementos = _NullSafe.stream(iterablePojos)
                 .map(pojo->mementoForPojo(pojo))
                 .collect(Collectors.toCollection(ArrayList::new)); // ArrayList is serializable
@@ -153,24 +152,25 @@ public class ObjectMementoServiceWicket implements ObjectMementoService {
 
         throw _Exceptions.unrecoverableFormatted("unsupported ObjectMemento type %s", memento.getClass());
     }
-    
+
+//TODO 2x remove if no longer required for debugging ...    
     private void assertSingleton(ManagedObject adapter) {
-        if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) {
-            return;
-        }
-        val pojo = ManagedObjects.UnwrapUtil.single(adapter);
-        assertSingleton(pojo);
-        val spec = adapter.getSpecification();
-        if(!spec.isNotCollection()) {
-            throw _Exceptions.illegalArgument("unexpected spec type %s for %s (elementSpec=%s)", 
-                    spec, spec.getFullIdentifier(), spec.getElementSpecification());
-        }
+//        if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) {
+//            return;
+//        }
+//        val pojo = ManagedObjects.UnwrapUtil.single(adapter);
+//        assertSingleton(pojo);
+//        val spec = adapter.getSpecification();
+//        if(!spec.isNotCollection()) {
+//            throw _Exceptions.illegalArgument("unexpected spec type %s for %s (elementSpec=%s)", 
+//                    spec, spec.getFullIdentifier(), spec.getElementSpecification());
+//        }
     }
     
     private void assertSingleton(Object pojo) {
-        if(_NullSafe.streamAutodetect(pojo).limit(2).count()>1L) {
-            throw _Exceptions.illegalArgument("cardinality 0 or 1 expect");
-        }
+//        if(_NullSafe.streamAutodetect(pojo).limit(2).count()>1L) {
+//            throw _Exceptions.illegalArgument("cardinality 0 or 1 expect");
+//        }
     }
 
     @RequiredArgsConstructor(staticName = "of")