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 428d694d8a ISIS-3263: ManagedObjects#isNullOrUnspecifiedOrEmpty: 
handle the 'deleted' / 'not found' case gracefully
428d694d8a is described below

commit 428d694d8adbee99e755c1f9ca766457fef2b23c
Author: Andi Huber <[email protected]>
AuthorDate: Wed Oct 26 11:52:35 2022 +0200

    ISIS-3263: ManagedObjects#isNullOrUnspecifiedOrEmpty: handle the
    'deleted' / 'not found' case gracefully
---
 .../core/metamodel/object/ManagedObjects.java      | 33 ++++++++++++++++++----
 .../object/_ManagedObjectEntityBookmarked.java     |  3 +-
 .../CssClassFacetMethodWithProblemTest.java        | 10 ++-----
 .../object/ident/icon/IconFacetMethodTest.java     | 12 +++-----
 .../object/ident/layout/LayoutFacetMethodTest.java | 11 +++-----
 .../ident/title/TitleFacetViaMethodTest.java       | 14 ++++-----
 6 files changed, 46 insertions(+), 37 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjects.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjects.java
index 3d297fbd0d..271dd338b7 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjects.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjects.java
@@ -57,15 +57,29 @@ public final class ManagedObjects {
 
     // -- CATEGORISATION
 
-    /** is null or has neither an ObjectSpecification and a value (pojo) */
+    /** is null or has no ObjectSpecification or has no value (pojo) */
     public static boolean isNullOrUnspecifiedOrEmpty(final @Nullable 
ManagedObject adapter) {
         if(adapter==null
-                || adapter==ManagedObject.unspecified()) {
+                || adapter==ManagedObject.unspecified()
+                || adapter.getSpecialization()==null
+                || adapter.getSpecialization().isEmpty()) {
             return true;
         }
-        return adapter instanceof PackedManagedObject
-                ? ((PackedManagedObject)adapter).unpack().isEmpty()
-                : adapter.getPojo()==null;
+        if(adapter instanceof PackedManagedObject) {
+            return ((PackedManagedObject)adapter).unpack().isEmpty();
+        }
+        // calling getPojo on entities has side-effects, so do null check with 
special care!
+        if(adapter.getSpecialization().isEntity()
+                && adapter.isBookmarkMemoized()) {
+            // handle the 'deleted' / 'not found' case gracefully
+            try {
+                return adapter.getPojo()==null;
+            } catch (Throwable e) {
+                // if anything goes wrong retrieving the pojo, report as 
missing
+                return true;
+            }
+        }
+        return adapter.getPojo()==null;
     }
 
     /**
@@ -324,11 +338,18 @@ public final class ManagedObjects {
             : adapter;
     }
 
+    /**
+     * Only applies to value types, otherwise acts as identity operation.
+     * <p>
+     * @implNote TODO this implementation ignores any registered 
value-semantics,
+     *  which should be used for the non-primitive, mandatory case instead
+     */
     public static ManagedObject emptyToDefault(
             final ObjectSpecification elementSpec,
             final boolean mandatory,
             final @NonNull ManagedObject input) {
-        if(!isSpecified(input)) {
+        if(!isSpecified(input)
+                || !elementSpec.isValue()) {
             return input;
         }
         if(input.getPojo()!=null) {
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
index ab96e9a10e..4c9bcb898b 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
@@ -103,7 +103,8 @@ implements _Refetchable {
         val refetchedPojo = refetchedIfSuccess.get();
 
         if(!entityFacet.getEntityState(refetchedPojo).hasOid()) {
-            throw _Exceptions.illegalState("entity not attached after refetch 
attempt %s", bookmark);
+            throw new ObjectNotFoundException(""+bookmark);
+            //throw _Exceptions.illegalState("entity not attached after 
refetch attempt %s", bookmark);
         }
 
         _XrayEvent.event("Entity %s refetched from persistence.", 
getSpecification());
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/cssclass/CssClassFacetMethodWithProblemTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/cssclass/CssClassFacetMethodWithProblemTest.java
index 424d79a055..d5959b5a18 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/cssclass/CssClassFacetMethodWithProblemTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/cssclass/CssClassFacetMethodWithProblemTest.java
@@ -23,10 +23,7 @@ import java.lang.reflect.Method;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -36,12 +33,10 @@ import 
org.apache.causeway.core.metamodel.facetapi.FacetHolder;
 import 
org.apache.causeway.core.metamodel.facets.object.cssclass.method.CssClassFacetViaCssClassMethod;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 
-@ExtendWith(MockitoExtension.class)
 class CssClassFacetMethodWithProblemTest {
 
     private CssClassFacetViaCssClassMethod facet;
-    @Mock FacetHolder mockFacetHolder;
-    @Mock ManagedObject mockOwningAdapter;
+    private ManagedObject mockOwningAdapter;
 
     private DomainObjectWithProblemInCssClassMethod pojo;
 
@@ -58,9 +53,10 @@ class CssClassFacetMethodWithProblemTest {
 
         final Method iconNameMethod = 
DomainObjectWithProblemInCssClassMethod.class.getMethod("cssClass");
         facet = (CssClassFacetViaCssClassMethod) CssClassFacetViaCssClassMethod
-                .create(iconNameMethod, mockFacetHolder)
+                .create(iconNameMethod, Mockito.mock(FacetHolder.class))
                 .orElse(null);
 
+        mockOwningAdapter = Mockito.mock(ManagedObject.class);
         Mockito.when(mockOwningAdapter.getPojo()).thenReturn(pojo);
     }
 
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/icon/IconFacetMethodTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/icon/IconFacetMethodTest.java
index 65134f29e7..08e50ce951 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/icon/IconFacetMethodTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/icon/IconFacetMethodTest.java
@@ -23,10 +23,7 @@ import java.lang.reflect.Method;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -36,12 +33,10 @@ import 
org.apache.causeway.core.metamodel.facetapi.FacetHolder;
 import 
org.apache.causeway.core.metamodel.facets.object.icon.method.IconFacetViaIconNameMethod;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 
-@ExtendWith(MockitoExtension.class)
 class IconFacetMethodTest {
 
     private IconFacetViaIconNameMethod facet;
-    @Mock FacetHolder mockFacetHolder;
-    @Mock ManagedObject mockOwningAdapter;
+    private ManagedObject mockOwningAdapter;
 
     private DomainObjectWithProblemInIconNameMethod pojo;
 
@@ -55,12 +50,13 @@ class IconFacetMethodTest {
     public void setUp() throws Exception {
 
         pojo = new DomainObjectWithProblemInIconNameMethod();
-
         final Method iconNameMethod = 
DomainObjectWithProblemInIconNameMethod.class.getMethod("iconName");
+
         facet = (IconFacetViaIconNameMethod) IconFacetViaIconNameMethod
-                .create(iconNameMethod, mockFacetHolder)
+                .create(iconNameMethod, Mockito.mock(FacetHolder.class))
                 .orElse(null);
 
+        mockOwningAdapter = Mockito.mock(ManagedObject.class);
         Mockito.when(mockOwningAdapter.getPojo()).thenReturn(pojo);
     }
 
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/layout/LayoutFacetMethodTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/layout/LayoutFacetMethodTest.java
index 0e32cea14f..065a8d53ac 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/layout/LayoutFacetMethodTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/layout/LayoutFacetMethodTest.java
@@ -23,10 +23,7 @@ import java.lang.reflect.Method;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.junit.jupiter.MockitoExtension;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -36,12 +33,10 @@ import 
org.apache.causeway.core.metamodel.facetapi.FacetHolder;
 import 
org.apache.causeway.core.metamodel.facets.object.layout.LayoutFacetViaLayoutMethod;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 
-@ExtendWith(MockitoExtension.class)
 class LayoutFacetMethodTest {
 
     private LayoutFacetViaLayoutMethod facet;
-    @Mock FacetHolder mockFacetHolder;
-    @Mock ManagedObject mockOwningAdapter;
+    private ManagedObject mockOwningAdapter;
 
     private DomainObjectWithProblemInLayoutMethod pojo;
 
@@ -55,11 +50,13 @@ class LayoutFacetMethodTest {
     public void setUp() throws Exception {
 
         pojo = new DomainObjectWithProblemInLayoutMethod();
+
         final Method iconNameMethod = 
DomainObjectWithProblemInLayoutMethod.class.getMethod("layout");
         facet = (LayoutFacetViaLayoutMethod) LayoutFacetViaLayoutMethod
-                    .create(iconNameMethod, mockFacetHolder)
+                    .create(iconNameMethod, Mockito.mock(FacetHolder.class))
                     .orElse(null);
 
+        mockOwningAdapter = Mockito.mock(ManagedObject.class);
         Mockito.when(mockOwningAdapter.getPojo()).thenReturn(pojo);
     }
 
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/title/TitleFacetViaMethodTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/title/TitleFacetViaMethodTest.java
index 60cb75624e..0ea9e9c5a6 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/title/TitleFacetViaMethodTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/ident/title/TitleFacetViaMethodTest.java
@@ -39,7 +39,7 @@ extends AbstractFacetFactoryJupiterTestCase {
 
     private TitleFacetViaTitleMethod facet;
 
-    private ManagedObject mockOwningAdapter;
+    private ManagedObject stubAdapter;
     private DomainObjectWithProblemInItsTitleMethod pojo;
     private MetaModelContext metaModelContext;
 
@@ -55,6 +55,9 @@ extends AbstractFacetFactoryJupiterTestCase {
         metaModelContext = MetaModelContext_forTesting.builder()
                 .build();
 
+        mockFacetHolder = Mockito.mock(FacetHolder.class);
+        
Mockito.when(mockFacetHolder.getMetaModelContext()).thenReturn(metaModelContext);
+
         pojo = new DomainObjectWithProblemInItsTitleMethod();
         //mockFacetHolder = mockery.mock(FacetHolder.class);
         //mockOwningAdapter = mockery.mock(ManagedObject.class);
@@ -63,17 +66,12 @@ extends AbstractFacetFactoryJupiterTestCase {
                 .create(iconNameMethod, mockFacetHolder)
                 .orElse(null);
 
-
-        mockOwningAdapter = Mockito.mock(ManagedObject.class);
-        Mockito.when(mockOwningAdapter.getPojo()).thenReturn(pojo);
-
-        mockFacetHolder = Mockito.mock(FacetHolder.class);
-        
Mockito.when(mockFacetHolder.getMetaModelContext()).thenReturn(metaModelContext);
+        stubAdapter = metaModelContext.getObjectManager().adapt(pojo);
     }
 
     @Test
     public void testTitleThrowsException() {
-        final String title = facet.title(mockOwningAdapter);
+        final String title = facet.title(stubAdapter);
         assertThat(title, is("Failed Title"));
     }
 

Reply via email to