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 <[email protected]>
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