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 fc8ab413d0 ISIS-3167: move MM assertion utils into own class and 
implement compliance checks
fc8ab413d0 is described below

commit fc8ab413d0447ddc8b23228db07dee333b477997
Author: Andi Huber <ahu...@apache.org>
AuthorDate: Tue Aug 30 07:53:02 2022 +0200

    ISIS-3167: move MM assertion utils into own class and implement
    compliance checks
---
 .../managed/ParameterNegotiationModel.java         |  3 +-
 .../managed/PropertyNegotiationModel.java          |  3 +-
 .../isis/core/metamodel/object/ManagedObject.java  | 12 +--
 .../isis/core/metamodel/object/ManagedObjects.java | 36 +--------
 .../core/metamodel/object/MmAssertionUtil.java     | 86 ++++++++++++++++++++++
 .../metamodel/object/_ManagedObjectSpecified.java  | 32 ++++----
 .../object/_ManagedObjectSpecifiedLegacy.java      | 16 +---
 .../object/_ManagedObjectUnspecified.java          |  5 +-
 .../core/metamodel/object/_ManagedObjectValue.java |  5 +-
 .../object/_ManagedObjectWithEagerSpec.java        |  3 +-
 10 files changed, 125 insertions(+), 76 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
index 48b556da16..9f1549aa01 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ParameterNegotiationModel.java
@@ -40,6 +40,7 @@ import 
org.apache.isis.core.metamodel.consent.InteractionResult;
 import 
org.apache.isis.core.metamodel.interactions.managed._BindingUtil.TargetFormat;
 import org.apache.isis.core.metamodel.object.ManagedObject;
 import org.apache.isis.core.metamodel.object.ManagedObjects;
+import org.apache.isis.core.metamodel.object.MmAssertionUtil;
 import org.apache.isis.core.metamodel.object.MmEntityUtil;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
@@ -296,7 +297,7 @@ public class ParameterNegotiationModel {
             bindableParamValueDirtyFlag = _Bindables.forBoolean(false);
 
             bindableParamValue.setValueRefiner(MmEntityUtil::refetch);
-            
bindableParamValue.setValueGuard(ManagedObjects.assertInstanceOf(metaModel.getElementType()));
+            
bindableParamValue.setValueGuard(MmAssertionUtil.assertInstanceOf(metaModel.getElementType()));
             bindableParamValue.addListener((event, oldValue, newValue)->{
                 if(newValue==null) {
                     // lift null to empty ...
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyNegotiationModel.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyNegotiationModel.java
index 97afc730a4..13b5e99bad 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyNegotiationModel.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/PropertyNegotiationModel.java
@@ -33,6 +33,7 @@ import 
org.apache.isis.core.metamodel.interactions.managed._BindingUtil.TargetFo
 import org.apache.isis.core.metamodel.object.MmEntityUtil;
 import org.apache.isis.core.metamodel.object.ManagedObject;
 import org.apache.isis.core.metamodel.object.ManagedObjects;
+import org.apache.isis.core.metamodel.object.MmAssertionUtil;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.NonNull;
@@ -69,7 +70,7 @@ public class PropertyNegotiationModel implements ManagedValue 
{
 
         proposedValue = _Bindables.forValue(defaultValue);
         proposedValue.setValueRefiner(MmEntityUtil::refetch);
-        
proposedValue.setValueGuard(ManagedObjects.assertInstanceOf(propMeta.getElementType()));
+        
proposedValue.setValueGuard(MmAssertionUtil.assertInstanceOf(propMeta.getElementType()));
         proposedValue.addListener((e,o,n)->{
             invalidateChoicesAndValidation();
         });
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
index dc2659ac09..7851dd2569 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObject.java
@@ -348,8 +348,11 @@ public interface ManagedObject extends HasMetaModelContext 
{
 
     Supplier<ManagedObject> asSupplier();
 
-    @Deprecated
-    void assertSpecIsInSyncWithPojo();
+    /**
+     * Unary operator asserting that {@code pojo} and {@link 
#getSpecification()} are
+     * compliant with the policies from {@link #getSpecialization()}.
+     */
+    <T> T assertCompliance(@NonNull T pojo);
 
     // -- TITLE
 
@@ -583,12 +586,11 @@ public interface ManagedObject extends 
HasMetaModelContext {
             final @NonNull ObjectSpecification spec,
             final @Nullable Object pojo) {
 
-        ManagedObjects.assertPojoNotWrapped(pojo);
+        MmAssertionUtil.assertPojoNotWrapped(pojo);
 
         //ISIS-2430 Cannot assume Action Param Spec to be correct when eagerly 
loaded
         //actual type in use (during runtime) might be a sub-class of the 
above, so re-adapt with hinting spec
         val adapter = 
spec.getMetaModelContext().getObjectManager().adapt(pojo, spec);
-        adapter.assertSpecIsInSyncWithPojo();
         return adapter;
     }
 
@@ -613,7 +615,7 @@ public interface ManagedObject extends HasMetaModelContext {
                     "pojo.toString() = %s",
                     spec.getCorrespondingClass(), pojo.getClass(), 
pojo.toString());
         }
-        ManagedObjects.assertPojoNotWrapped(pojo);
+        MmAssertionUtil.assertPojoNotWrapped(pojo);
         return _ManagedObjectWithEagerSpec.identified(spec, pojo, bookmark);
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
index 977e275cba..ee6f7b2be3 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
@@ -23,7 +23,6 @@ import java.util.Comparator;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Supplier;
-import java.util.function.UnaryOperator;
 
 import org.springframework.lang.Nullable;
 import org.springframework.util.ClassUtils;
@@ -147,23 +146,6 @@ public final class ManagedObjects {
         return upperBound.isAssignableFrom(objectActualType);
     }
 
-    /**
-     * Guard against incompatible type.
-     */
-    public static @NonNull UnaryOperator<ManagedObject> assertInstanceOf(final 
ObjectSpecification elementType) {
-        return object -> {
-            if(isInstanceOf(object, elementType)) {
-                return object;
-            }
-            val upperBound = 
ClassUtils.resolvePrimitiveIfNecessary(elementType.getCorrespondingClass());
-            val objectActualType = 
ClassUtils.resolvePrimitiveIfNecessary(object.getSpecification().getCorrespondingClass());
-            throw _Exceptions.illegalArgument("Object has incompatible type 
%s, "
-                    + "must be an instance of %s.",
-                    objectActualType.getName(),
-                    upperBound.getName());
-        };
-    }
-
     // -- IDENTIFICATION
 
     public static Optional<ObjectSpecification> spec(final @Nullable 
ManagedObject managedObject) {
@@ -386,23 +368,7 @@ public final class ManagedObjects {
         .collect(Can.toCan());
     }
 
-    /**
-     * eg. in order to prevent wrapping an object that is already wrapped
-     */
-    public static void assertPojoNotWrapped(final @Nullable Object pojo) {
-        // can do this check only when the pojo is not null, otherwise is 
always considered valid
-        if(pojo==null) {
-            return;
-        }
-
-        if(pojo instanceof ManagedObject) {
-            throw _Exceptions.illegalArgument(
-                    "Cannot adapt a pojo of type ManagedObject, " +
-                    "pojo.getClass() = %s, " +
-                    "pojo.toString() = %s",
-                    pojo.getClass(), pojo.toString());
-        }
-    }
+    
 
     // -- IMPERATIVE TEXT UTILITY
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmAssertionUtil.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmAssertionUtil.java
new file mode 100644
index 0000000000..eee5b2f32f
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmAssertionUtil.java
@@ -0,0 +1,86 @@
+/*
+ *  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.isis.core.metamodel.object;
+
+import java.util.function.UnaryOperator;
+
+import org.springframework.lang.Nullable;
+import org.springframework.util.ClassUtils;
+
+import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+import lombok.NonNull;
+import lombok.val;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class MmAssertionUtil {
+
+    public static void assertExactType(
+            final @Nullable ObjectSpecification requiredSpec,
+            final @Nullable Object pojo) {
+        if(pojo==null
+                || requiredSpec==null) {
+            return;
+        }
+        val actualSpec = 
requiredSpec.getSpecificationLoader().specForType(pojo.getClass()).orElse(null);
+        _Assert.assertEquals(requiredSpec, actualSpec, ()->
+            String.format("pojo's actual ObjectSpecification %s "
+                    + "does not exaclty match %s%n", actualSpec, 
requiredSpec));
+    }
+
+    /**
+     * Guard against incompatible type.
+     */
+    public static @NonNull UnaryOperator<ManagedObject> assertInstanceOf(
+            final ObjectSpecification elementType) {
+        return object -> {
+            if(ManagedObjects.isInstanceOf(object, elementType)) {
+                return object;
+            }
+            val upperBound = 
ClassUtils.resolvePrimitiveIfNecessary(elementType.getCorrespondingClass());
+            val objectActualType = 
ClassUtils.resolvePrimitiveIfNecessary(object.getSpecification().getCorrespondingClass());
+            throw _Exceptions.illegalArgument("Object has incompatible type 
%s, "
+                    + "must be an instance of %s.",
+                    objectActualType.getName(),
+                    upperBound.getName());
+        };
+    }
+
+    /**
+     * eg. in order to prevent wrapping an object that is already wrapped
+     */
+    public static void assertPojoNotWrapped(final @Nullable Object pojo) {
+        // can do this check only when the pojo is not null, otherwise is 
always considered valid
+        if(pojo==null) {
+            return;
+        }
+
+        if(pojo instanceof ManagedObject) {
+            throw _Exceptions.illegalArgument(
+                    "Cannot adapt a pojo of type ManagedObject, " +
+                            "pojo.getClass() = %s, " +
+                            "pojo.toString() = %s",
+                            pojo.getClass(), pojo.toString());
+        }
+    }
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecified.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecified.java
index 5b351e01b0..2071aad5ce 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecified.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecified.java
@@ -29,11 +29,9 @@ import 
org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 import lombok.Getter;
 import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.experimental.Accessors;
 
-@RequiredArgsConstructor
 abstract class _ManagedObjectSpecified
 implements ManagedObject {
 
@@ -43,6 +41,13 @@ implements ManagedObject {
     @Getter(onMethod_ = {@Override}) @Accessors(makeFinal = true)
     private final @NonNull ObjectSpecification specification;
 
+    protected _ManagedObjectSpecified(
+            final @NonNull Specialization specialization,
+            final @NonNull ObjectSpecification specification) {
+        this.specialization = specialization;
+        this.specification = specification;
+    }
+
     @Override
     public final MetaModelContext getMetaModelContext() {
         return getSpecification().getMetaModelContext();
@@ -53,20 +58,16 @@ implements ManagedObject {
         return ()->this;
     }
 
-    /** debug */
     @Override
-    public final void assertSpecIsInSyncWithPojo() {
-//        val pojo = getPojo();
-//        val spec = getSpecification();
-//        if(pojo==null
-//                || spec==null) {
-//            return;
-//        }
-//        val actualSpec = 
spec.getSpecificationLoader().specForType(pojo.getClass()).orElse(null);
-//        if(!Objects.equals(spec,  actualSpec)) {
-//            System.err.printf("spec mismatch %s %s%n", spec, actualSpec);
-//        }
-        //_Assert.assertEquals(spec, actualSpec);
+    public final <T> T assertCompliance(final @NonNull T pojo) {
+        MmAssertionUtil.assertPojoNotWrapped(pojo);
+        if(specification.isAbstract()) {
+            
_Assert.assertFalse(specialization.getTypePolicy().isExactTypeRequired());
+        }
+        if(specialization.getTypePolicy().isExactTypeRequired()) {
+            MmAssertionUtil.assertExactType(specification, pojo);
+        }
+        return pojo;
     }
 
     //XXX compares pojos by their 'equals' semantics -
@@ -130,5 +131,4 @@ implements ManagedObject {
         return getBookmark().orElseThrow(_Exceptions::unexpectedCodeReach);
     }
 
-
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecifiedLegacy.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecifiedLegacy.java
index b170889113..05e17541ca 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecifiedLegacy.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectSpecifiedLegacy.java
@@ -23,6 +23,7 @@ import java.util.function.Supplier;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.experimental.Accessors;
 
@@ -43,20 +44,9 @@ implements ManagedObject {
         return ()->this;
     }
 
-    /** debug */
     @Override
-    public void assertSpecIsInSyncWithPojo() {
-//        val pojo = getPojo();
-//        val spec = getSpecification();
-//        if(pojo==null
-//                || spec==null) {
-//            return;
-//        }
-//        val actualSpec = 
spec.getSpecificationLoader().specForType(pojo.getClass()).orElse(null);
-//        if(!Objects.equals(spec,  actualSpec)) {
-//            System.err.printf("spec mismatch %s %s%n", spec, actualSpec);
-//        }
-        //_Assert.assertEquals(spec, actualSpec);
+    public final <T> T assertCompliance(final @NonNull T pojo) {
+        return pojo; // legacy implementation - don't check
     }
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
index e26f76eeff..b8ac3a0ac5 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectUnspecified.java
@@ -29,6 +29,8 @@ import 
org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
+import lombok.NonNull;
+
 /**
  * (package private) specialization corresponding to {@link 
Specialization#UNSPECIFIED}
  * @see ManagedObject.Specialization#UNSPECIFIED
@@ -85,7 +87,8 @@ implements ManagedObject {
     }
 
     @Override
-    public void assertSpecIsInSyncWithPojo() {
+    public <T> T assertCompliance(final @NonNull T pojo) {
+        return pojo; // no-op
     }
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
index bbc9ea9c63..2a6e1be759 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectValue.java
@@ -52,8 +52,7 @@ extends _ManagedObjectSpecified {
             final Object pojo) {
         super(ManagedObject.Specialization.VALUE, spec);
         _Assert.assertTrue(spec.isValue());
-        _Assert.assertFalse(spec.isAbstract());
-        this.pojo = pojo;
+        this.pojo = assertCompliance(pojo);
     }
 
     @Override
@@ -83,6 +82,8 @@ extends _ManagedObjectSpecified {
     }
 
     private Bookmark createBookmark() {
+        //TODO if value semantics providers are enforced to provide an 
IdStringifier,
+        // we could use that instead (to generate the second argument)!
         return Bookmark.forLogicalTypeAndIdentifier(
                 getSpecification().getLogicalType(),
                 valueFacet().toEncodedString(Format.JSON, 
_Casts.uncheckedCast(getPojo())));
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
index d5aab332cf..7729755a90 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
@@ -68,8 +68,7 @@ extends _ManagedObjectWithBookmark {
 
     @Override
     public void replacePojo(final UnaryOperator<Object> replacer) {
-        pojo = replacer.apply(pojo);
-        assertSpecIsInSyncWithPojo();
+        pojo = assertCompliance(replacer.apply(pojo));
     }
 
 }
\ No newline at end of file

Reply via email to