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();

Reply via email to