Skip to content

Commit e22707a

Browse files
committed
CAUSEWAY-3859: flattens PackedManagedObject into a record
and seals the ManagedObject interface
1 parent 081f691 commit e22707a

21 files changed

+191
-188
lines changed

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObject.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.apache.causeway.commons.internal.exceptions._Exceptions;
3333
import org.apache.causeway.core.metamodel.context.HasMetaModelContext;
3434
import org.apache.causeway.core.metamodel.facets.object.icon.ObjectIcon;
35-
import org.apache.causeway.core.metamodel.object.ManagedObject.Specialization.BookmarkPolicy;
3635
import org.apache.causeway.core.metamodel.spec.HasObjectSpecification;
3736
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
3837
import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
@@ -51,11 +50,20 @@
5150
* @since 2.0 {@index}}
5251
*
5352
*/
54-
public interface ManagedObject
53+
public sealed interface ManagedObject
5554
extends
5655
Bookmarkable,
5756
HasMetaModelContext,
58-
HasObjectSpecification {
57+
HasObjectSpecification
58+
permits
59+
ManagedObjectEmpty,
60+
ManagedObjectUnspecified,
61+
ManagedObjectMixin,
62+
ManagedObjectOther,
63+
ManagedObjectValue,
64+
ManagedObjectService,
65+
_ManagedObjectSpecified,
66+
PackedManagedObject {
5967

6068
/**
6169
* ManagedObject specializations have varying contract/behavior.
@@ -319,7 +327,7 @@ public static Specialization inferFrom(
319327

320328
@Deprecated default Specialization getSpecialization() { return specialization(); }
321329

322-
@Override default BookmarkPolicy getBookmarkPolicy() {
330+
@Override default Specialization.BookmarkPolicy getBookmarkPolicy() {
323331
return specialization().getBookmarkPolicy();
324332
}
325333

@@ -339,12 +347,6 @@ default EntityState getEntityState() {
339347
return EntityState.NOT_PERSISTABLE;
340348
}
341349

342-
/**
343-
* Unary operator asserting that {@code pojo} and {@link #objSpec()} are
344-
* compliant with the policies from {@link #specialization()}.
345-
*/
346-
<T> T assertCompliance(@NonNull T pojo);
347-
348350
// -- TITLE
349351

350352
/**
@@ -531,7 +533,7 @@ private static ManagedObject other(
531533
static PackedManagedObject packed(
532534
final @NonNull ObjectSpecification elementSpec,
533535
final @Nullable Can<ManagedObject> nonScalar) {
534-
return new _ManagedObjectPacked(elementSpec, nonScalar);
536+
return new PackedManagedObject(elementSpec, nonScalar);
535537
}
536538

537539
/**

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectEmpty.java

-7
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,4 @@ public String getTitle() {
4545
return "empty " + objSpec().logicalTypeName();
4646
}
4747

48-
// -- HELPER
49-
50-
@Override
51-
public <T> T assertCompliance(@NonNull final T pojo) {
52-
return null; // no-op
53-
}
54-
5548
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectMixin.java

+1-8
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ record ManagedObjectMixin(
3838
final Object pojo) {
3939
_Assert.assertTrue(objSpec.isMixin());
4040
this.objSpec = objSpec;
41-
this.pojo = assertCompliance(pojo);
41+
this.pojo = _Compliance.assertCompliance(objSpec, specialization(), pojo);
4242
}
4343

4444
@Override
@@ -57,11 +57,4 @@ public Object getPojo() {
5757
return pojo;
5858
}
5959

60-
// -- HELPER
61-
62-
@Override
63-
public <T> T assertCompliance(@NonNull final T pojo) {
64-
return _Compliance.assertCompliance(objSpec, specialization(), pojo);
65-
}
66-
6760
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectOther.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ record ManagedObjectOther(
3838
this.objSpec = objSpec;
3939
_Assert.assertTrue(!objSpec.isValue());
4040
_Assert.assertTrue(!objSpec.isEntityOrViewModel());
41-
this.pojo = assertCompliance(pojo);
41+
this.pojo = _Compliance.assertCompliance(objSpec, specialization(), pojo);
4242
}
4343

4444
@Override
@@ -51,11 +51,6 @@ public Specialization specialization() {
5151
return ManagedObject.Specialization.OTHER;
5252
}
5353

54-
@Override
55-
public <T> T assertCompliance(@NonNull final T pojo) {
56-
return _Compliance.assertCompliance(objSpec, specialization(), pojo);
57-
}
58-
5954
@Override
6055
public Object getPojo() {
6156
return pojo;

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectService.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ record ManagedObjectService(
4545
final Object pojo) {
4646
this(objSpec, pojo, Bookmark.forLogicalTypeAndIdentifier(objSpec.logicalType(), "1"));
4747
assertInjectable(objSpec);
48-
assertCompliance(pojo);
48+
_Compliance.assertCompliance(objSpec, specialization(), pojo);
4949
}
5050

5151
@Override
@@ -104,9 +104,4 @@ private void assertInjectable(final ObjectSpecification spec) {
104104
.formatted(pojo.getClass(), spec.getBeanSort()));
105105
}
106106

107-
@Override
108-
public <T> T assertCompliance(@NonNull final T pojo) {
109-
return _Compliance.assertCompliance(objSpec, specialization(), pojo);
110-
}
111-
112107
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectUnspecified.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ public Object getPojo() {
4646
return null;
4747
}
4848

49-
@Override
50-
public <T> T assertCompliance(final T pojo) {
51-
return pojo; // no-op
52-
}
53-
5449
@Override
5550
public String getTitle() {
5651
return "unspecified object";
@@ -68,7 +63,7 @@ public int hashCode() {
6863

6964
@Override
7065
public final String toString() {
71-
return "ManagedObject(UNSPECIFIED)";
66+
return "ManagedObjectUnspecified";
7267
}
7368

7469
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/ManagedObjectValue.java

+1-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ record ManagedObjectValue(
4747
final Object pojo) {
4848
this(objSpec, pojo, _Lazy.threadSafe(()->createBookmark(objSpec, pojo)));
4949
_Assert.assertTrue(objSpec.isValue());
50-
assertCompliance(pojo);
50+
_Compliance.assertCompliance(objSpec, specialization(), pojo);
5151
}
5252

5353
@Override
@@ -106,9 +106,4 @@ private static Bookmark createBookmark(final ObjectSpecification objSpec, final
106106
return Bookmark.forLogicalTypeAndIdentifier(objSpec.logicalType(), urlSafeIdentifier);
107107
}
108108

109-
@Override
110-
public <T> T assertCompliance(@NonNull final T pojo) {
111-
return _Compliance.assertCompliance(objSpec, specialization(), pojo);
112-
}
113-
114109
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/PackedManagedObject.java

+60-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,72 @@
1818
*/
1919
package org.apache.causeway.core.metamodel.object;
2020

21+
import java.util.ArrayList;
22+
import java.util.Optional;
23+
import java.util.stream.Collectors;
24+
25+
import org.jspecify.annotations.NonNull;
26+
import org.jspecify.annotations.Nullable;
27+
2128
import org.apache.causeway.commons.collections.Can;
29+
import org.apache.causeway.commons.internal.assertions._Assert;
30+
import org.apache.causeway.core.metamodel.objectmanager.memento.ObjectMemento;
31+
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
2232

2333
/**
2434
* 'Collection' of {@link ManagedObject}s.
2535
* @see ManagedObject.Specialization#PACKED
2636
*/
27-
public interface PackedManagedObject
28-
extends ManagedObject {
37+
public record PackedManagedObject(
38+
/** element spec */
39+
@NonNull ObjectSpecification objSpec,
40+
@NonNull Can<ManagedObject> nonScalar)
41+
implements
42+
ManagedObject, Bookmarkable.NoBookmark {
43+
44+
public PackedManagedObject(
45+
final ObjectSpecification objSpec,
46+
final @Nullable Can<ManagedObject> nonScalar) {
47+
this.objSpec = objSpec;
48+
this.nonScalar = nonScalar!=null
49+
? nonScalar
50+
: Can.empty();
51+
_Assert.assertTrue(objSpec().isSingular(), "a PackedManagedObject cannot containt non-scalars");
52+
}
53+
54+
@Override
55+
public String getTitle() {
56+
return nonScalar.stream()
57+
.map(ManagedObject::getTitle)
58+
.collect(Collectors.joining(","));
59+
}
60+
61+
@Override
62+
public Object getPojo() {
63+
// this algorithm preserves null pojos ...
64+
return nonScalar.stream()
65+
.map(ManagedObject::getPojo)
66+
.toList();
67+
}
68+
69+
@Override
70+
public Optional<ObjectMemento> getMemento() {
71+
var listOfMementos = nonScalar.stream()
72+
.map(scalar->scalar.getMementoElseFail())
73+
.collect(Collectors.toCollection(ArrayList::new)); // ArrayList is serializable
74+
var memento = ObjectMemento.packed(
75+
logicalType(),
76+
listOfMementos);
77+
return Optional.of(memento);
78+
}
79+
80+
public Can<ManagedObject> unpack(){
81+
return nonScalar;
82+
}
2983

30-
Can<ManagedObject> unpack();
84+
@Override
85+
public Specialization specialization() {
86+
return Specialization.PACKED;
87+
}
3188

3289
}

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectPacked.java

-73
This file was deleted.

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectSpecified.java

+3-18
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
*/
1919
package org.apache.causeway.core.metamodel.object;
2020

21-
import java.util.ArrayList;
2221
import java.util.Optional;
23-
import java.util.stream.Collectors;
24-
2522
import org.jspecify.annotations.NonNull;
2623
import org.jspecify.annotations.Nullable;
2724

@@ -35,7 +32,7 @@
3532
import lombok.experimental.Accessors;
3633

3734
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
38-
abstract class _ManagedObjectSpecified
35+
abstract non-sealed class _ManagedObjectSpecified
3936
implements ManagedObject {
4037

4138
@Getter(onMethod_ = {@Override}) @Accessors(fluent = true, makeFinal = true)
@@ -44,8 +41,7 @@ abstract class _ManagedObjectSpecified
4441
@Getter(onMethod_ = {@Override}) @Accessors(fluent = true, makeFinal = true)
4542
private final @NonNull ObjectSpecification objSpec;
4643

47-
@Override
48-
public final <T> T assertCompliance(final @NonNull T pojo) {
44+
final <T> T assertCompliance(final @NonNull T pojo) {
4945
return _Compliance.assertCompliance(objSpec, specialization, pojo);
5046
}
5147

@@ -57,9 +53,7 @@ public String getTitle() {
5753

5854
@Override
5955
public Optional<ObjectMemento> getMemento() {
60-
return this instanceof PackedManagedObject
61-
? Optional.ofNullable(mementoForPacked((PackedManagedObject)this))
62-
: Optional.ofNullable(mementoForScalar(this));
56+
return Optional.ofNullable(mementoForScalar(this));
6357
}
6458

6559
private ObjectMemento mementoForScalar(final @Nullable ManagedObject adapter) {
@@ -71,15 +65,6 @@ private ObjectMemento mementoForScalar(final @Nullable ManagedObject adapter) {
7165
: null);
7266
}
7367

74-
private ObjectMemento mementoForPacked(final @NonNull PackedManagedObject packedAdapter) {
75-
var listOfMementos = packedAdapter.unpack().stream()
76-
.map(this::mementoForScalar)
77-
.collect(Collectors.toCollection(ArrayList::new)); // ArrayList is serializable
78-
return ObjectMemento.packed(
79-
packedAdapter.logicalType(),
80-
listOfMementos);
81-
}
82-
8368
@Override
8469
public final boolean equals(final Object obj) {
8570
return _Compliance.equals(this, obj);

0 commit comments

Comments
 (0)