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 a7b85c2845217ddab8112725f25fc4642018806e Author: Andi Huber <[email protected]> AuthorDate: Sun Aug 28 21:42:28 2022 +0200 ISIS-3167: declare the new ManagedObject contracts --- .../isis/core/metamodel/object/ManagedObject.java | 199 ++++++++++++++++++++- .../core/metamodel/object/PackedManagedObject.java | 1 + .../metamodel/object/_ManagedObjectPacked.java | 10 ++ .../metamodel/object/_ManagedObjectSpecified.java | 7 + .../object/_ManagedObjectUnspecified.java | 9 + 5 files changed, 225 insertions(+), 1 deletion(-) 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 6a9858336f..172f71ec2b 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 @@ -25,6 +25,7 @@ import java.util.function.UnaryOperator; import org.springframework.lang.Nullable; import org.apache.isis.applib.services.bookmark.Bookmark; +import org.apache.isis.commons.collections.Can; import org.apache.isis.commons.internal.assertions._Assert; import org.apache.isis.commons.internal.collections._Collections; import org.apache.isis.commons.internal.exceptions._Exceptions; @@ -34,16 +35,212 @@ import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import org.apache.isis.core.metamodel.specloader.SpecificationLoader; +import lombok.Getter; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import lombok.val; /** * Represents an instance of some element of the meta-model managed by the framework, - * that is IoC-container provided beans, persistence-stack provided entities, view-models + * that is <i>Spring</i> managed beans, persistence-stack provided entities, view-models * or instances of value types. + * + * @since 2.0 {@index}} + * */ public interface ManagedObject extends HasMetaModelContext { + /** + * ManagedObject specializations have varying contract/behavior. + */ + @Getter + @RequiredArgsConstructor + enum Specialization { + /** + * <h1>Contract</h1><ul> + * <li>Specification (null, immutable)</li> + * <li>Bookmark (n/a)</li> + * <li>Pojo (null, immutable)</li> + * </ul> + * @implNote realized by a singleton (static) {@link ManagedObject} instance; + */ + UNSPECIFIED(TypePolicy.NO_TYPE, BookmarkPolicy.NO_BOOKMARK, PojoPolicy.NO_POJO), + + /** + * <h1>Contract</h1><ul> + * <li>Specification (immutable, allowed to correspond to abstract type)</li> + * <li>Bookmark (n/a)</li> + * <li>Pojo (null, immutable)</li> + * </ul> + */ + EMPTY(TypePolicy.ABSTRACT_TYPE_ALLOWED, BookmarkPolicy.NO_BOOKMARK, PojoPolicy.NO_POJO), + + /** + * <h1>Contract</h1><ul> + * <li>Specification (immutable, NOT allowed to correspond to abstract type)</li> + * <li>Bookmark (immutable)</li> + * <li>Pojo (immutable)</li> + * </ul> + */ + VALUE(TypePolicy.EXACT_TYPE_REQUIRED, BookmarkPolicy.IMMUTABLE, PojoPolicy.IMMUTABLE), + + /** + * <h1>Contract</h1><ul> + * <li>Specification (immutable, NOT allowed to correspond to abstract type)</li> + * <li>Bookmark (immutable)</li> + * <li>Pojo (immutable)</li> + * </ul> + */ + SERVICE(TypePolicy.EXACT_TYPE_REQUIRED, BookmarkPolicy.IMMUTABLE, PojoPolicy.IMMUTABLE), + + /** + * <h1>Contract</h1><ul> + * <li>Specification (immutable, NOT allowed to correspond to abstract type)</li> + * <li>Bookmark (refreshable, as VM state changes manifest in change of ID)</li> + * <li>Pojo (mutable, but immutable obj. ref.)</li> + * </ul> + */ + VIEWMODEL(TypePolicy.EXACT_TYPE_REQUIRED, BookmarkPolicy.REFRESHABLE, PojoPolicy.STATEFUL), + + /** + * <h1>Contract</h1><ul> + * <li>Specification (immutable, NOT allowed to correspond to abstract type)</li> + * <li>Bookmark (immutable, entity must be persistent, it must have an ID, fail otherwise)</li> + * <li>Pojo (refetchable)</li> + * </ul> + */ + ENTITY(TypePolicy.EXACT_TYPE_REQUIRED, BookmarkPolicy.IMMUTABLE, PojoPolicy.REFETCHABLE), + + /** + * <h1>Contract</h1><ul> + * <li>Element Specification (immutable, allowed to correspond to abstract type)</li> + * <li>Bookmark (n/a)</li> + * <li>Pojo (unmod. Collection of pojos)</li> + * </ul> + */ + PACKED(TypePolicy.ABSTRACT_TYPE_ALLOWED, BookmarkPolicy.NO_BOOKMARK, PojoPolicy.PACKED); + + static enum TypePolicy { + /** has no type information */ + NO_TYPE, + /** has type information, abstract types are allowed */ + ABSTRACT_TYPE_ALLOWED, + /** has type information, exact types are required */ + EXACT_TYPE_REQUIRED; + //// + /** has no type information */ + public boolean isNoType() { return this == NO_TYPE; } + /** has type information, abstract types are allowed */ + public boolean isAbstractTypeAllowed() { return this == ABSTRACT_TYPE_ALLOWED; } + /** has type information, exact types are required */ + public boolean isExactTypeRequired() { return this == EXACT_TYPE_REQUIRED; } + /** has type information */ + public boolean isTypeRequiredAny() { return !isNoType(); } + } + static enum BookmarkPolicy { + /** has no {@link Bookmark} */ + NO_BOOKMARK, + /** has an immutable {@link Bookmark} */ + IMMUTABLE, + /** has an refreshable {@link Bookmark}, that is a mutable object reference */ + REFRESHABLE; + //// + /** has no {@link Bookmark} */ + public boolean isNoBookmark() { return this == NO_BOOKMARK; } + /** has an immutable {@link Bookmark} */ + public boolean isImmutable() { return this == IMMUTABLE; } + /** has an refreshable {@link Bookmark}, that is a mutable object reference */ + public boolean isRefreshable() { return this == REFRESHABLE; } + } + static enum PojoPolicy { + /** has no pojo, immutable <code>null</code> */ + NO_POJO, + /** has a non-null pojo, immutable, with immutable object reference */ + IMMUTABLE, + /** has a stateful pojo, with immutable object reference */ + STATEFUL, + /** has a stateful pojo, with mutable object reference */ + REFETCHABLE, + /** has an unmodifiable collection of pojos; the collection's object reference is immutable; + * supports unpacking into a {@link Can} of {@link ManagedObject}s;*/ + PACKED; + //// + /** has no pojo, immutable <code>null</code> */ + public boolean isNoPojo() { return this == NO_POJO; } + /** has a non-null pojo, immutable, with immutable object reference */ + public boolean isImmutable() { return this == IMMUTABLE; } + /** has a stateful pojo, with immutable object reference */ + public boolean isStateful() { return this == STATEFUL; } + /** has a stateful pojo, with mutable object reference */ + public boolean isRefetchable() { return this == REFETCHABLE; } + /** has an unmodifiable collection of pojos; the collection's object reference is immutable; + * supports unpacking into a {@link Can} of {@link ManagedObject}s;*/ + public boolean isPacked() { return this == PACKED; } + } + + private final TypePolicy typePolicy; + private final BookmarkPolicy bookmarkPolicy; + private final PojoPolicy pojoPolicy; + + /** + * UNSPECIFIED + * @see TypePolicy#NO_TYPE + * @see BookmarkPolicy#NO_BOOKMARK + * @see PojoPolicy#NO_POJO + */ + public boolean isUnspecified() { return this == UNSPECIFIED; } + /** + * EMPTY + * @see TypePolicy#ABSTRACT_TYPE_ALLOWED + * @see BookmarkPolicy#NO_BOOKMARK + * @see PojoPolicy#NO_POJO + */ + public boolean isEmpty() { return this == EMPTY; } + /** + * VALUE + * @see TypePolicy#EXACT_TYPE_REQUIRED + * @see BookmarkPolicy#IMMUTABLE + * @see PojoPolicy#IMMUTABLE + */ + public boolean isValue() { return this == VALUE; } + /** + * SERVICE + * @see TypePolicy#EXACT_TYPE_REQUIRED + * @see BookmarkPolicy#IMMUTABLE + * @see PojoPolicy#IMMUTABLE + */ + public boolean isService() { return this == SERVICE; } + /** + * VIEWMODEL + * @see TypePolicy#EXACT_TYPE_REQUIRED + * @see BookmarkPolicy#REFRESHABLE + * @see PojoPolicy#STATEFUL + */ + public boolean isViewmodel() { return this == VIEWMODEL; } + /** + * ENTITY + * @see TypePolicy#EXACT_TYPE_REQUIRED + * @see BookmarkPolicy#IMMUTABLE + * @see PojoPolicy#REFETCHABLE + */ + public boolean isEntity() { return this == ENTITY; } + /** + * PACKED + * @see TypePolicy#ABSTRACT_TYPE_ALLOWED + * @see BookmarkPolicy#NO_BOOKMARK + * @see PojoPolicy#PACKED + */ + public boolean isPacked() { return this == PACKED; } + + } + + /** + * Returns the specific {@link Specialization} this {@link ManagedObject} implements, + * which governs this object's behavior. + * @implNote FIXME[ISIS-3167] not fully implemented yet + */ + Specialization getSpecialization(); + /** * Returns the specification that details the structure (meta-model) of this object. */ diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java index ed3fd10b3d..46c3d57574 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/PackedManagedObject.java @@ -23,6 +23,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification; /** * 'Collection' of {@link ManagedObject}s. + * @see ManagedObject.Specialization#PACKED */ public interface PackedManagedObject extends ManagedObject { diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java index d0fe434271..adbc6cf7f9 100644 --- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java +++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectPacked.java @@ -34,6 +34,10 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.ToString; +/** + * (package private) specialization corresponding to {@link Specialization#PACKED} + * @see ManagedObject.Specialization#PACKED + */ @RequiredArgsConstructor @ToString final class _ManagedObjectPacked @@ -43,6 +47,11 @@ implements PackedManagedObject { final @NonNull ObjectSpecification elementSpec; final @NonNull Can<ManagedObject> nonScalar; + @Override + public Specialization getSpecialization() { + return Specialization.PACKED; + } + @Override public ObjectSpecification getSpecification() { return elementSpec; @@ -50,6 +59,7 @@ implements PackedManagedObject { @Override public Object getPojo() { + // this algorithm preserves null pojos ... return Collections.unmodifiableList( nonScalar.stream() .map(ManagedObject::getPojo) 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 8536725ee7..49d2872b8e 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 @@ -20,11 +20,18 @@ package org.apache.isis.core.metamodel.object; import java.util.function.Supplier; +import org.apache.isis.commons.internal.exceptions._Exceptions; import org.apache.isis.core.metamodel.context.MetaModelContext; abstract class _ManagedObjectSpecified implements ManagedObject { + @Override + public Specialization getSpecialization() { + //FIXME[ISIS-3167] implement for various sub types + throw _Exceptions.notImplemented(); + } + @Override public final MetaModelContext getMetaModelContext() { return getSpecification().getMetaModelContext(); 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 49d6c014b1..84ba189070 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 @@ -28,11 +28,20 @@ import org.apache.isis.commons.internal.exceptions._Exceptions; import org.apache.isis.core.metamodel.context.MetaModelContext; import org.apache.isis.core.metamodel.spec.ObjectSpecification; +/** + * (package private) specialization corresponding to {@link Specialization#PACKED} + * @see ManagedObject.Specialization#PACKED + */ final class _ManagedObjectUnspecified implements ManagedObject { static final ManagedObject INSTANCE = new _ManagedObjectUnspecified(); + @Override + public Specialization getSpecialization() { + return Specialization.UNSPECIFIED; + } + @Override public ObjectSpecification getSpecification() { throw _Exceptions.unsupportedOperation();
