You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/09/01 13:27:19 UTC
[isis] branch master updated: ISIS-3167: major work on EntityFacets
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 836d8c9669 ISIS-3167: major work on EntityFacets
new ae111b0b0d Merge remote-tracking branch 'origin/master'
836d8c9669 is described below
commit 836d8c9669c3a34e136d1f5a9767e82ae240ac98
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 1 11:01:16 2022 +0200
ISIS-3167: major work on EntityFacets
- introducing a new EntityState: NEW
- purging legacy ManageObject implementations
---
.../applib/services/repository/EntityState.java | 23 ++-
.../facets/object/entity/EntityFacet.java | 54 ++++++-
.../object/entity/_EntityFacetForTesting.java | 5 +-
.../isis/core/metamodel/object/ManagedObject.java | 102 ++++++++----
.../core/metamodel/object/MmAssertionUtil.java | 26 +++
.../isis/core/metamodel/object/MmEntityUtil.java | 82 ++--------
.../isis/core/metamodel/object/MmSpecUtil.java | 47 +++---
.../isis/core/metamodel/object/Refetchable.java | 27 ++++
.../object/_ManagedObjectEntityAttached.java | 156 ++++++++++++++++++
...tity.java => _ManagedObjectEntityDetached.java} | 56 ++++---
.../object/_ManagedObjectEntityHybrid.java | 144 +++++++++++++++++
.../core/metamodel/object/_ManagedObjectOther.java | 7 +-
.../metamodel/object/_ManagedObjectSpecified.java | 24 ++-
.../object/_ManagedObjectWithBookmark.java | 174 ---------------------
.../object/_ManagedObjectWithEagerSpec.java | 85 ----------
.../metamodel/objectmanager/ObjectManager.java | 44 +-----
.../detach/ObjectDetacher_builtinHandlers.java | 20 +--
.../identify/ObjectBookmarker_builtinHandlers.java | 54 +------
.../load/ObjectLoader_builtinHandlers.java | 14 +-
.../query/ObjectBulkLoader_builtinHandlers.java | 7 +-
.../refresh/ObjectRefresher_builtinHandlers.java | 20 +--
.../isis/core/metamodel/spec/Hierarchical.java | 5 +
.../core/metamodel/spec/ObjectSpecification.java | 23 ++-
.../specimpl/ObjectSpecificationAbstract.java | 35 +++++
.../title/TitleAnnotationFacetFactoryTest.java | 8 +-
.../core/metamodel/object/ManagedObjectTest.java | 4 +-
.../command/SchemaValueMarshallerDefault.java | 8 +-
.../executor/MemberExecutorServiceDefault.java | 4 +-
.../factory/FactoryServiceDefault.java | 8 +-
.../repository/RepositoryServiceDefault.java | 2 +-
.../handlers/DomainObjectInvocationHandler.java | 3 +-
.../xmlsnapshot/XmlSnapshotBuilder.java | 2 +-
.../xmlsnapshot/XmlSnapshotServiceDefault.java | 2 +-
.../wkt/viewer/EventProviderAbstract.java | 2 +-
.../graphql/viewer/source/ObjectTypeFactory.java | 2 +-
.../graphql/viewer/source/QueryFieldFactory.java | 7 +-
.../viewer/vaadin/ui/binding/BindingsVaa.java | 6 +-
.../changetracking/JdoLifecycleListener.java | 29 ++--
.../jdo/datanucleus/changetracking/_Utils.java | 21 +--
.../entities/DnEntityStateProvider.java | 9 +-
.../metamodel/facets/entity/JdoEntityFacet.java | 69 ++------
.../jpa/integration/entity/JpaEntityFacet.java | 49 ++----
.../DomainModelTest_usingGoodDomain.java | 4 +-
.../testdomain/interact/SimulatedUiChoices.java | 10 +-
.../testdomain/interact/SimulatedUiComponent.java | 2 +-
.../domainmodel/jdo/DomainModelTest.java | 3 +-
.../injecting/jdo/JdoEntityInjectingTest.java | 2 +-
.../persistence/jpa/JpaBootstrappingTest.java | 6 +-
...JpaNonGeneratedStringIdEntityLifecycleTest.java | 2 +
.../springdata/SpringDataJpaBootstrappingTest.java | 3 +-
.../isis/testdomain/value/ValueSemanticsTest.java | 2 +-
.../testdomain/value/ValueSemanticsTester.java | 4 +-
.../publishing/PublishingTestFactoryJdo.java | 2 +-
.../publishing/PublishingTestFactoryJpa.java | 2 +-
.../interaction/DomainObjectTesterFactory.java | 9 +-
.../binding/BindingConverterForManagedObject.java | 2 +-
.../viewer/wicket/model/models/BooleanModel.java | 2 +-
.../wicket/model/models/ManagedObjectModel.java | 3 +-
.../wicket/model/util/PageParameterUtils.java | 2 +-
.../components/tree/IsisToWicketTreeAdapter.java | 2 +-
.../viewer/services/DeepLinkServiceWicket.java | 2 +-
61 files changed, 779 insertions(+), 754 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/repository/EntityState.java b/api/applib/src/main/java/org/apache/isis/applib/services/repository/EntityState.java
index 1da34628ae..2ca6ae644b 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/repository/EntityState.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/repository/EntityState.java
@@ -38,6 +38,12 @@ public enum EntityState {
* the database.
*/
PERSISTABLE_ATTACHED,
+
+ /**
+ * DN/JDO specific on pre-store. Is attached, has no OID yet.
+ */
+ PERSISTABLE_NEW,
+
/**
* Object with this state is an entity but that is detached from a
* persistence session, in other words changes to the entity will <i>not</i>
@@ -65,6 +71,12 @@ public enum EntityState {
public boolean isAttached() {
return this == PERSISTABLE_ATTACHED;
}
+ /**
+ * DN/JDO specific on pre-store. Is attached, has no OID yet.
+ */
+ public boolean isNew() {
+ return this == PERSISTABLE_NEW;
+ }
/**
* Object with this state is an entity but that is detached from a
* persistence session, in other words changes to the entity will <i>not</i>
@@ -95,9 +107,16 @@ public enum EntityState {
* @apiNote 'removed' is only supported by JDO.
*/
public boolean isAttachedOrRemoved() {
- return this == PERSISTABLE_ATTACHED
- || this == PERSISTABLE_REMOVED;
+ return isAttached()
+ || isRemoved();
}
+ /**
+ * @apiNote 'new' is only supported by JDO.
+ */
+ public boolean isAttachedOrNew() {
+ return isAttached()
+ || isNew();
+ }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
index 548ba3b4f1..f3537fb078 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
@@ -19,15 +19,21 @@
package org.apache.isis.core.metamodel.facets.object.entity;
import java.lang.reflect.Method;
+import java.util.Optional;
+
+import org.springframework.lang.Nullable;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.repository.EntityState;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.beans.PersistenceStack;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.object.ManagedObject;
+import org.apache.isis.core.metamodel.object.MmSpecUtil;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
/**
* Indicates that this class is managed by a persistence context.
@@ -35,9 +41,51 @@ import org.apache.isis.core.metamodel.object.ManagedObject;
*/
public interface EntityFacet extends Facet {
- String identifierFor(Object pojo);
+ /**
+ * The {@link ObjectSpecification} of the entity type this
+ * facet is associated with.
+ */
+ default ObjectSpecification getEntitySpecification() {
+ return (ObjectSpecification)getFacetHolder();
+ }
+
+ /**
+ * Optionally the stringified OID,
+ * based on whether the entity has one associated.
+ * @throws IllegalArgumentException if the pojo's class is not recognized
+ * by the persistence layer
+ */
+ Optional<String> identifierFor(@Nullable Object pojo);
+
+ /**
+ * Optionally the {@link Bookmark},
+ * based on whether the entity has an OID associated.
+ * eg. it has not if not persisted yet
+ * @throws IllegalArgumentException if the pojo's class is not recognized
+ * by the persistence layer or does not exactly match the expected
+ */
+ default Optional<Bookmark> bookmarkFor(final @Nullable Object pojo) {
+ return identifierFor(pojo)
+ .map(id->Bookmark.forLogicalTypeAndIdentifier(
+ MmSpecUtil.quicklyResolveObjectSpecificationFor(
+ getEntitySpecification(),
+ pojo.getClass())
+ .getLogicalType(),
+ id));
+ }
+
+ default Bookmark bookmarkForElseFail(final @Nullable Object pojo) {
+ return bookmarkFor(pojo)
+ .orElseThrow(()->_Exceptions.noSuchElement("entity has no OID: %s",
+ getEntitySpecification().getLogicalType()));
+ }
- ManagedObject fetchByIdentifier(Bookmark bookmark);
+
+ /**
+ * Optionally the entity pojo corresponding to given {@link Bookmark},
+ * based on whether could be found.
+ */
+ Optional<Object> fetchByBookmark(Bookmark bookmark);
Can<ManagedObject> fetchByQuery(Query<?> query);
@@ -67,4 +115,6 @@ public interface EntityFacet extends Facet {
return new _EntityFacetForTesting(persistenceStandard, facetHolder);
}
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
index d4d1239f0b..97289b4ea2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
@@ -19,6 +19,7 @@
package org.apache.isis.core.metamodel.facets.object.entity;
import java.lang.reflect.Method;
+import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.isis.applib.query.Query;
@@ -55,12 +56,12 @@ class _EntityFacetForTesting implements EntityFacet {
}
@Override
- public String identifierFor(final Object pojo) {
+ public Optional<String> identifierFor(final Object pojo) {
throw _Exceptions.unsupportedOperation();
}
@Override
- public ManagedObject fetchByIdentifier(final Bookmark bookmark) {
+ public Optional<Object> fetchByBookmark(final Bookmark bookmark) {
throw _Exceptions.unsupportedOperation();
}
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 df2861b712..8997ef491a 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
@@ -24,9 +24,8 @@ import java.util.function.Supplier;
import org.springframework.lang.Nullable;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.repository.EntityState;
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;
import org.apache.isis.core.metamodel.context.HasMetaModelContext;
import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
@@ -41,9 +40,9 @@ import lombok.val;
import lombok.extern.log4j.Log4j2;
/**
- * Represents an instance of some element of the meta-model managed by the framework,
- * that is <i>Spring</i> managed beans, persistence-stack provided entities, view-models
- * or instances of value types.
+ * Represents an instance of some element of the meta-model recognized by the framework,
+ * that is <i>Spring</i> managed beans, persistence-stack provided entities, view-models,
+ * mixins or instances of value types.
*
* @since 2.0 {@index}}
*
@@ -325,6 +324,11 @@ extends
*/
Object getPojo();
+ @NonNull
+ default EntityState getEntityState() {
+ return EntityState.NOT_PERSISTABLE;
+ }
+
/**
* If the underlying domain object is a viewmodel, refreshes any referenced entities.
* (Acts as a no-op otherwise.)
@@ -434,23 +438,48 @@ extends
final @Nullable Object pojo,
final Optional<Bookmark> bookmarkIfKnown) {
return pojo != null
- ? bookmarkIfKnown.map(bookmark->bookmarked(spec, pojo, bookmark)) //FIXME
- .orElseGet(()->new _ManagedObjectWithEagerSpec(spec, pojo)) //FIXME
+ ? new _ManagedObjectViewmodel(spec, pojo, bookmarkIfKnown)
: empty(spec);
}
/**
* ENTITY
* @param spec - required
* @param pojo - if <code>null</code> maps to {@link #empty(ObjectSpecification)}
+ * @param bookmark
* @see ManagedObject.Specialization.TypePolicy#EXACT_TYPE_REQUIRED
* @see ManagedObject.Specialization.BookmarkPolicy#IMMUTABLE
* @see ManagedObject.Specialization.PojoPolicy#REFETCHABLE
*/
static ManagedObject entity(
+ final @NonNull ObjectSpecification spec,
+ final @Nullable Object pojo,
+ final @NonNull Optional<Bookmark> bookmarkIfKnown) {
+ if(pojo == null) {
+ return empty(spec);
+ }
+ val bookmarkIfAny = bookmarkIfKnown
+ .or(()->spec.entityFacetElseFail().bookmarkFor(pojo));
+ if(bookmarkIfAny.isPresent()) {
+ return entityAttached(spec, pojo, bookmarkIfAny);
+ } else {
+ return entityDetached(spec, pojo);
+ }
+ }
+ //FIXME java-doc
+ static ManagedObject entityAttached(
+ final @NonNull ObjectSpecification spec,
+ final @NonNull Object pojo,
+ final @NonNull Optional<Bookmark> bookmarkIfKnown) {
+ return new _ManagedObjectEntityHybrid(
+ new _ManagedObjectEntityAttached(spec, pojo, bookmarkIfKnown));
+ }
+ //FIXME java-doc
+ static ManagedObject entityDetached(
final @NonNull ObjectSpecification spec,
final @Nullable Object pojo) {
return pojo != null
- ? new _ManagedObjectWithEagerSpec(spec, pojo) //FIXME
+ ? new _ManagedObjectEntityHybrid(
+ new _ManagedObjectEntityDetached(spec, pojo))
: empty(spec);
}
/**
@@ -502,23 +531,44 @@ extends
* @param specLoader - required
* @param pojo - required, required non-scalar
*/
- static ManagedObject wrapScalar(
+ static ManagedObject adaptScalar(
final @NonNull SpecificationLoader specLoader,
final @NonNull Object pojo) {
if(pojo instanceof ManagedObject) {
return (ManagedObject)pojo;
}
val spec = specLoader.specForType(pojo.getClass()).orElse(null);
- return wrapScalarInternal(spec, pojo, Optional.empty());
+ return adaptScalarInternal(spec, pojo, Optional.empty());
+ }
+
+ static ManagedObject adaptScalar(
+ final @NonNull ObjectSpecification guess,
+ final @Nullable Object pojo) {
+ if(pojo instanceof ManagedObject) {
+ return (ManagedObject)pojo;
+ }
+ return adaptScalarInternal(guess, pojo, Optional.empty());
}
- private static ManagedObject wrapScalarInternal(
- final @Nullable ObjectSpecification spec,
+ static ManagedObject identified(
+ final @NonNull ObjectSpecification spec,
+ final @Nullable Object pojo,
+ final @NonNull Bookmark bookmark) {
+ return adaptScalarInternal(spec, pojo, Optional.of(bookmark));
+ }
+
+ // -- HELPER
+
+ /**
+ * spec and pojo don't need to be strictly in sync, we adapt if required
+ */
+ private static ManagedObject adaptScalarInternal(
+ final @Nullable ObjectSpecification guess,
final @NonNull Object pojo,
final @NonNull Optional<Bookmark> bookmarkIfAny) {
- _Assert.assertTrue(!_Collections.isCollectionOrArrayOrCanType(pojo.getClass()),
- ()->String.format("is scalar %s", pojo.getClass()));
+ MmAssertionUtil.assertPojoIsScalar(pojo);
+ val spec = MmSpecUtil.quicklyResolveObjectSpecificationFor(guess, pojo.getClass());
val specialization = spec!=null
? Specialization.inferFrom(spec, pojo)
@@ -534,7 +584,7 @@ extends
case VIEWMODEL:
return viewmodel(spec, pojo, bookmarkIfAny);
case ENTITY:
- return entity(spec, pojo);
+ return entity(spec, pojo, bookmarkIfAny);
case MIXIN:
return mixin(spec, pojo);
case OTHER:
@@ -549,18 +599,6 @@ extends
// -- FACTORIES LEGACY
- @Deprecated
- static ManagedObject notBookmarked(
- final ObjectSpecification spec,
- final Object pojo) {
- if(pojo instanceof ManagedObject) {
- return (ManagedObject)pojo;
- }
- return !_Collections.isCollectionOrArrayOrCanType(pojo.getClass())
- ? wrapScalarInternal(spec, pojo, Optional.empty())
- : new _ManagedObjectWithEagerSpec(spec, pojo);
- }
-
/**
* Optimized for cases, when the pojo's specification is already available.
* If {@code pojo} is an entity, automatically memoizes its bookmark.
@@ -572,7 +610,9 @@ extends
final @NonNull ObjectSpecification spec,
final @Nullable Object pojo) {
- MmAssertionUtil.assertPojoNotWrapped(pojo);
+ if(pojo instanceof ManagedObject) {
+ return (ManagedObject)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
@@ -589,9 +629,7 @@ extends
final @NonNull Object pojo,
final @NonNull Bookmark bookmark) {
- if(pojo!=null) {
- _Assert.assertFalse(_Collections.isCollectionOrArrayOrCanType(pojo.getClass()));
- }
+ MmAssertionUtil.assertPojoIsScalar(pojo);
if(!spec.getCorrespondingClass().isAssignableFrom(pojo.getClass())) {
throw _Exceptions.illegalArgument(
@@ -602,7 +640,7 @@ extends
spec.getCorrespondingClass(), pojo.getClass(), pojo.toString());
}
MmAssertionUtil.assertPojoNotWrapped(pojo);
- return _ManagedObjectWithEagerSpec.identified(spec, pojo, bookmark);
+ return ManagedObject.identified(spec, pojo, bookmark);
}
}
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
index b31317dfd3..f32da3b83d 100644
--- 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
@@ -24,6 +24,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.commons.internal.collections._Collections;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.commons.ClassUtil;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -51,6 +52,23 @@ public class MmAssertionUtil {
+ "does not exaclty match %s%n", actualSpec, requiredSpec));
}
+ /**
+ * Guard against incompatible type.
+ */
+ public @NonNull UnaryOperator<ObjectSpecification> assertTypeOf(
+ final @NonNull ObjectSpecification requiredSpec) {
+ return specUnderInvestigation -> {
+ _Assert.assertNotNull(specUnderInvestigation);
+ if(specUnderInvestigation.isOfTypeResolvePrimitive(requiredSpec)) {
+ return specUnderInvestigation;
+ }
+ throw _Exceptions.illegalArgument("Object has incompatible type %s, "
+ + "must be an instance of %s.",
+ specUnderInvestigation,
+ requiredSpec);
+ };
+ }
+
/**
* Guard against incompatible type.
*/
@@ -87,4 +105,12 @@ public class MmAssertionUtil {
}
}
+ public void assertPojoIsScalar(final @Nullable Object pojo) {
+ if(pojo==null) {
+ return;
+ }
+ _Assert.assertTrue(!_Collections.isCollectionOrArrayOrCanType(pojo.getClass()),
+ ()->String.format("is scalar %s", pojo.getClass()));
+ }
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
index 1305817bb1..715c8b812f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
@@ -24,13 +24,10 @@ import java.util.function.UnaryOperator;
import org.springframework.lang.Nullable;
import org.apache.isis.applib.services.repository.EntityState;
-import org.apache.isis.commons.functional.Try;
import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.beans.PersistenceStack;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
-import org.apache.isis.core.metamodel.objectmanager.load.ObjectLoader;
import lombok.NonNull;
import lombok.val;
@@ -49,45 +46,28 @@ public final class MmEntityUtil {
return Optional.empty();
}
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- return Optional.empty();
- }
-
- return Optional.of(entityFacet.getPersistenceStack());
+ return spec.entityFacet()
+ .map(EntityFacet::getPersistenceStack);
}
@NonNull
public static EntityState getEntityState(final @Nullable ManagedObject adapter) {
- if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) {
- return EntityState.NOT_PERSISTABLE;
- }
- val spec = adapter.getSpecification();
- val pojo = adapter.getPojo();
-
- if(!spec.isEntity()) {
- return EntityState.NOT_PERSISTABLE;
- }
-
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- throw _Exceptions.unrecoverable("Entity types must have an EntityFacet");
- }
-
- return entityFacet.getEntityState(pojo);
+ return adapter!=null
+ ? adapter.getEntityState()
+ : EntityState.NOT_PERSISTABLE;
}
public static void persistInCurrentTransaction(final ManagedObject managedObject) {
requiresEntity(managedObject);
val spec = managedObject.getSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
+ val entityFacet = spec.entityFacetElseFail();
entityFacet.persist(managedObject.getPojo());
}
public static void destroyInCurrentTransaction(final ManagedObject managedObject) {
requiresEntity(managedObject);
val spec = managedObject.getSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
+ val entityFacet = spec.entityFacetElseFail();
entityFacet.delete(managedObject.getPojo());
}
@@ -126,53 +106,8 @@ public final class MmEntityUtil {
return managedObject;
}
+ @Deprecated
public static ManagedObject refetch(final @Nullable ManagedObject managedObject) {
- if(ManagedObjects.isNullOrUnspecifiedOrEmpty(managedObject)) {
- return managedObject;
- }
- if(managedObject instanceof PackedManagedObject) {
- ((PackedManagedObject)managedObject).unpack().forEach(MmEntityUtil::refetch);
- return managedObject;
- }
- val entityState = MmEntityUtil.getEntityState(managedObject);
- if(!entityState.isPersistable()) {
- return managedObject;
- }
- if(!entityState.isDetached()) {
- return managedObject;
- }
-
- val spec = managedObject.getSpecification();
- val objectManager = managedObject.getObjectManager();
-
- val reattached = ManagedObjects.bookmark(managedObject)
- .map(bookmark->
- ObjectLoader.Request.of(
- spec,
- bookmark))
- .map(loadRequest->Try.call(
- ()->objectManager.loadObject(loadRequest)))
- .map(loadResult->
- // a valid scenario for entities: not found eg. after deletion,
- // which will fail the load request
- loadResult.isFailure()
- ? ManagedObject.empty(managedObject.getSpecification())
- : loadResult.getValue().get()
- )
- .orElse(managedObject);
-
- // handles deleted entities
- if(ManagedObjects.isNullOrUnspecifiedOrEmpty(reattached)) {
- // returns the 'emptied' ManagedObject from above
- return reattached;
- }
-
- val newState = MmEntityUtil.getEntityState(reattached);
- _Assert.assertTrue(newState.isAttached());
-
- _Casts.castTo(_ManagedObjectWithBookmark.class, managedObject)
- .ifPresent(obj->obj.replacePojo(old->reattached.getPojo()));
-
return managedObject;
}
@@ -236,4 +171,5 @@ public final class MmEntityUtil {
return adapter;
}
+
}
\ No newline at end of file
diff --git a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmSpecUtil.java
similarity index 53%
copy from viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java
copy to core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmSpecUtil.java
index 06b02e91c7..f3d40188eb 100644
--- a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmSpecUtil.java
@@ -16,34 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.isis.viewer.commons.model.binding;
+package org.apache.isis.core.metamodel.object;
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.metamodel.object.MmUnwrapUtil;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor(staticName = "of")
-public final class BindingConverterForManagedObject<T>
-implements BindingConverter<ManagedObject, T> {
-
- @Getter private final ObjectSpecification valueSpecification;
-
- @Override
- public ManagedObject toLeft(final T pojo) {
- return ManagedObject.of(getValueSpecification(), pojo);
- }
-
- @Override
- public T toRight(final ManagedObject adapter) {
- return _Casts.uncheckedCast(MmUnwrapUtil.single(adapter));
+import lombok.NonNull;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public final class MmSpecUtil {
+
+ /**
+ * optimized for the case when a specification that probably matches is known in advance
+ * the result must be an instance of guess
+ */
+ public ObjectSpecification quicklyResolveObjectSpecificationFor(
+ final @NonNull ObjectSpecification guess,
+ final @NonNull Class<?> requiredType) {
+ return guess.getCorrespondingClass().equals(requiredType)
+ // when successful guess
+ ? guess
+ // else lookup
+ : MmAssertionUtil.assertTypeOf(guess)
+ .apply(guess.getSpecificationLoader().specForTypeElseFail(requiredType));
}
-}
-
-
-
-
+}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/Refetchable.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/Refetchable.java
new file mode 100644
index 0000000000..f00463b887
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/Refetchable.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/** don't expose outside this package */
+interface Refetchable {
+
+ /** side-effect free for toString, equals and hashCode */
+ Object peekAtPojo();
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityAttached.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityAttached.java
new file mode 100644
index 0000000000..238e30a829
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityAttached.java
@@ -0,0 +1,156 @@
+/*
+ * 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.Optional;
+import java.util.function.Supplier;
+
+import org.springframework.lang.Nullable;
+
+import org.apache.isis.applib.exceptions.unrecoverable.ObjectNotFoundException;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.repository.EntityState;
+import org.apache.isis.commons.internal.debug._Debug;
+import org.apache.isis.commons.internal.debug.xray.XrayUi;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+
+import lombok.NonNull;
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+/**
+ * (package private) specialization corresponding to a attached {@link Specialization#ENTITY}
+ * @see ManagedObject.Specialization#ENTITY
+ */
+@Log4j2
+final class _ManagedObjectEntityAttached
+extends _ManagedObjectSpecified
+implements Refetchable {
+
+ private /*final*/ @Nullable Object pojo;
+ private final @NonNull Bookmark bookmark;
+
+ _ManagedObjectEntityAttached(
+ final ObjectSpecification spec,
+ final Object pojo,
+ final @NonNull Optional<Bookmark> bookmarkIfKnown) {
+ super(ManagedObject.Specialization.ENTITY, spec);
+ this.pojo = assertCompliance(pojo);
+ this.bookmark = bookmarkIfKnown
+ .orElseGet(this::createBookmark);
+ }
+
+ @Override
+ public Optional<Bookmark> getBookmark() {
+ return Optional.of(bookmark);
+ }
+
+ @Override
+ public Optional<Bookmark> getBookmarkRefreshed() {
+ return getBookmark(); // no-op for entities
+ }
+
+ @Override
+ public boolean isBookmarkMemoized() {
+ return true;
+ }
+
+ @Override
+ public void refreshViewmodel(final Supplier<Bookmark> bookmarkSupplier) {
+ // no-op for entities
+ }
+
+ @Override
+ public Object peekAtPojo() {
+ return pojo;
+ }
+
+ @Override
+ public Object getPojo() {
+
+ // refetch if required ...
+
+ val entityFacet = entityFacet();
+
+ val entityState = entityFacet.getEntityState(pojo);
+ if(!entityState.isPersistable()) {
+ throw _Exceptions.illegalState("not persistable %s", getSpecification());
+ }
+ if(!entityState.isDetached()) {
+ return pojo; // is attached
+ }
+
+ // throws on deleted entity
+ val reattached = entityFacet.fetchByBookmark(bookmark)
+ .orElseThrow(()->{
+ return new ObjectNotFoundException(""+bookmark);});
+
+ if(!entityFacet.getEntityState(reattached).isAttached()) {
+ throw _Exceptions.illegalState("entity not attached after refetch attempt %s", bookmark);
+ }
+
+ return this.pojo = assertCompliance(reattached);
+ }
+
+ @Override
+ public @NonNull EntityState getEntityState() {
+ val entityFacet = entityFacet();
+ return entityFacet.getEntityState(pojo);
+ }
+
+ // -- HELPER
+
+ private EntityFacet entityFacet() {
+ return getSpecification().entityFacetElseFail();
+ }
+
+ @SuppressWarnings("deprecation")
+ private Bookmark createBookmark() {
+ val entityFacet = entityFacet();
+
+ // fail early when detached entities are detected
+ // should have been re-fetched at start of this request-cycle
+ if(
+// && EntityUtil.getPersistenceStandard(managedObject)
+// .map(PersistenceStandard::isJdo)
+// .orElse(false)
+ !entityFacet.getEntityState(pojo).isAttached()) {
+
+ _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
+ _Debug.log("detached entity detected %s", pojo);
+ });
+
+ val msg = String.format(
+ "The persistence layer does not recognize given object %s, "
+ + "meaning the object has no identifier that associates it with the persistence layer. "
+ + "(most likely, because the object is detached, eg. was not persisted after being new-ed up)",
+ getSpecification());
+
+ // in case of the exception getting swallowed, also write a log
+ log.error(msg);
+
+ throw _Exceptions.illegalArgument(msg);
+ }
+
+ return entityFacet.bookmarkForElseFail(pojo);
+ }
+
+}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityDetached.java
similarity index 57%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityDetached.java
index 91b8c9192c..299c14fd29 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntity.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityDetached.java
@@ -18,65 +18,63 @@
*/
package org.apache.isis.core.metamodel.object;
-import java.util.Optional;
import java.util.function.Supplier;
-import org.springframework.lang.Nullable;
-
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.repository.EntityState;
+import org.apache.isis.commons.internal.assertions._Assert;
+import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.val;
+import lombok.experimental.Accessors;
/**
- * (package private) specialization corresponding to {@link Specialization#ENTITY}
+ * (package private) specialization corresponding to a detached {@link Specialization#ENTITY}
* @see ManagedObject.Specialization#ENTITY
*/
-final class _ManagedObjectEntity
-extends _ManagedObjectSpecified {
+final class _ManagedObjectEntityDetached
+extends _ManagedObjectSpecified
+implements Bookmarkable.NoBookmark, Refetchable {
- private /*final*/ @Nullable Object pojo;
- private final @NonNull Bookmark bookmark;
+ @Getter(onMethod_ = {@Override}) @Accessors(makeFinal = true)
+ private final @NonNull Object pojo;
- _ManagedObjectEntity(
+ _ManagedObjectEntityDetached(
final ObjectSpecification spec,
- final Object pojo,
- final @NonNull Bookmark bookmark) {
+ final Object pojo) {
super(ManagedObject.Specialization.ENTITY, spec);
+ _Assert.assertTrue(spec.isEntity());
this.pojo = assertCompliance(pojo);
- this.bookmark = bookmark;
}
@Override
- public Optional<Bookmark> getBookmark() {
- return Optional.of(bookmark);
- }
-
- @Override
- public Optional<Bookmark> getBookmarkRefreshed() {
- return getBookmark(); // no-op for entities
+ public void refreshViewmodel(final Supplier<Bookmark> bookmarkSupplier) {
+ // no-op for other
}
@Override
- public boolean isBookmarkMemoized() {
- return true;
+ public String getTitle() {
+ return "detached entity object";
}
@Override
- public void refreshViewmodel(final Supplier<Bookmark> bookmarkSupplier) {
- // no-op for entities
+ public Object peekAtPojo() {
+ return pojo;
}
@Override
- public Object getPojo() {
- // TODO refetch if required
- return pojo;
+ public @NonNull EntityState getEntityState() {
+ val entityFacet = entityFacet();
+ return entityFacet.getEntityState(pojo);
}
// -- HELPER
-// private EntityFacet entityFacet() {
-// return getSpecification().entityFacet().orElseThrow();
-// }
+ private EntityFacet entityFacet() {
+ return getSpecification().entityFacetElseFail();
+ }
}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityHybrid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityHybrid.java
new file mode 100644
index 0000000000..31da98859f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectEntityHybrid.java
@@ -0,0 +1,144 @@
+/*
+ * 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.Optional;
+import java.util.function.Supplier;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.repository.EntityState;
+import org.apache.isis.commons.functional.Either;
+import org.apache.isis.commons.internal.assertions._Assert;
+
+import lombok.NonNull;
+import lombok.Synchronized;
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+/**
+ * (package private) specialization corresponding to {@link Specialization#ENTITY}
+ * @see ManagedObject.Specialization#ENTITY
+ */
+@Log4j2
+final class _ManagedObjectEntityHybrid
+extends _ManagedObjectSpecified
+implements Refetchable {
+
+ /**
+ * dynamically mutates from one to the other based on pojos persistent state;
+ * however the pojo reference must be kept identical
+ */
+ private @NonNull Either<_ManagedObjectEntityDetached, _ManagedObjectEntityAttached>
+ eitherDetachedOrAttached;
+
+ private EntityState entityState;
+
+ _ManagedObjectEntityHybrid(
+ final @NonNull _ManagedObjectEntityDetached detached) {
+ super(ManagedObject.Specialization.ENTITY, detached.getSpecification());
+ this.eitherDetachedOrAttached = Either.left(detached);
+ this.entityState = EntityState.PERSISTABLE_DETACHED;
+ }
+
+ _ManagedObjectEntityHybrid(
+ final @NonNull _ManagedObjectEntityAttached attached) {
+ super(ManagedObject.Specialization.ENTITY, attached.getSpecification());
+ this.eitherDetachedOrAttached = Either.right(attached);
+ this.entityState = EntityState.PERSISTABLE_ATTACHED;
+ }
+
+ @Override
+ public Optional<Bookmark> getBookmark() {
+ return eitherDetachedOrAttached
+ .fold(ManagedObject::getBookmark, ManagedObject::getBookmark);
+ }
+
+ @Override
+ public Optional<Bookmark> getBookmarkRefreshed() {
+ return eitherDetachedOrAttached
+ .fold(ManagedObject::getBookmarkRefreshed, ManagedObject::getBookmarkRefreshed);
+ }
+
+ @Override
+ public boolean isBookmarkMemoized() {
+ return eitherDetachedOrAttached
+ .fold(ManagedObject::isBookmarkMemoized, ManagedObject::isBookmarkMemoized);
+ }
+
+ @Override
+ public @NonNull EntityState getEntityState() {
+
+ val entityState = eitherDetachedOrAttached
+ .fold(ManagedObject::getEntityState, ManagedObject::getEntityState);
+
+ if(this.entityState!=entityState) {
+ log.debug("about to morph {} -> {}", this.entityState, entityState);
+ this.entityState = entityState;
+ reassessVariant(entityState, peekAtPojo());
+ if(entityState.isAttached()) {
+ _Assert.assertTrue(eitherDetachedOrAttached.isRight());
+ } else {
+ _Assert.assertTrue(eitherDetachedOrAttached.isLeft());
+ }
+ }
+
+ return entityState;
+ }
+
+ @Override
+ public void refreshViewmodel(final Supplier<Bookmark> bookmarkSupplier) {
+ // no-op for entities
+ }
+
+ @Override
+ public Object getPojo() {
+ val pojo = eitherDetachedOrAttached
+ .fold(ManagedObject::getPojo, ManagedObject::getPojo);
+ getEntityState(); // triggers reassessment
+ return pojo;
+ }
+
+ // -- HELPER
+
+ @Override
+ public Object peekAtPojo() {
+ return eitherDetachedOrAttached
+ .fold(Refetchable::peekAtPojo, Refetchable::peekAtPojo);
+ }
+
+ @Synchronized
+ private void reassessVariant(final EntityState entityState, final Object pojo) {
+ if(eitherDetachedOrAttached.isLeft()
+ && entityState.isAttached()) {
+ // morph into attached
+ val bookmark = getSpecification().entityFacetElseFail().bookmarkFor(pojo);
+ eitherDetachedOrAttached = Either.right(
+ new _ManagedObjectEntityAttached(getSpecification(), pojo, bookmark));
+ return;
+ }
+ if(eitherDetachedOrAttached.isRight()
+ && !entityState.isAttached()) {
+ // morph into detached
+ eitherDetachedOrAttached = Either.left(
+ new _ManagedObjectEntityDetached(getSpecification(), pojo));
+ return;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java
index 4618fad95a..17f71f1aeb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectOther.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.object;
import java.util.function.Supplier;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import lombok.Getter;
@@ -42,9 +43,9 @@ implements Bookmarkable.NoBookmark {
final ObjectSpecification spec,
final Object pojo) {
super(ManagedObject.Specialization.OTHER, spec);
- //_Assert.assertTrue(spec.isOther()); //TODO later
- //this.pojo = assertCompliance(pojo); //TODO later
- this.pojo = pojo;
+ _Assert.assertTrue(!spec.isValue());
+ _Assert.assertTrue(!spec.isEntityOrViewModel());
+ this.pojo = assertCompliance(pojo);
}
@Override
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 65d1d0871c..76a9f9efe7 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
@@ -67,6 +67,9 @@ implements ManagedObject {
if(specialization.getTypePolicy().isExactTypeRequired()) {
MmAssertionUtil.assertExactType(specification, pojo);
}
+ if(getSpecification().isEntityOrViewModel()) {
+ getServiceInjector().injectServicesInto(pojo); // might be redundant
+ }
return pojo;
}
@@ -94,16 +97,22 @@ implements ManagedObject {
if(!this.getSpecification().equals(other.getSpecification())) {
return false;
}
- val canGetPojosWithoutSideeffect = !this.getSpecialization().getPojoPolicy().isRefetchable();
+ val canGetPojosWithoutSideeffect = !getSpecialization().getPojoPolicy().isRefetchable();
if(canGetPojosWithoutSideeffect) {
// expected to work for packed variant just fine, as it compares lists
return Objects.equals(this.getPojo(), other.getPojo());
}
- // objects are considered equal if their bookmarks match
- _Assert.assertTrue(other.isBookmarkMemoized()); // guarantee no side-effects on other
- return Objects.equals(
- sideEffectFreeBookmark(),
- other.getBookmark().orElseThrow(_Exceptions::unexpectedCodeReach));
+
+ if(this.isBookmarkMemoized()
+ && other.isBookmarkMemoized()) {
+ return Objects.equals(
+ sideEffectFreeBookmark(),
+ other.getBookmark().orElseThrow(_Exceptions::unexpectedCodeReach));
+ }
+
+ val a = (Refetchable) this;
+ val b = (Refetchable) this;
+ return Objects.equals(a.peekAtPojo(), b.peekAtPojo());
}
@Override
@@ -124,7 +133,7 @@ implements ManagedObject {
getSpecification(),
!getSpecialization().getPojoPolicy().isRefetchable()
? getPojo() // its safe to get pojo side-effect free
- : !getSpecialization().getBookmarkPolicy().isNoBookmark()
+ : isBookmarkMemoized()
? String.format("(refetchable, %s)", sideEffectFreeBookmark())
: "(refetchable, suppressed to not cause side effects)");
}
@@ -132,7 +141,6 @@ implements ManagedObject {
// -- HELPER
private Bookmark sideEffectFreeBookmark() {
- _Assert.assertFalse(getSpecialization().getBookmarkPolicy().isNoBookmark());
_Assert.assertTrue(isBookmarkMemoized());
return getBookmark().orElseThrow(_Exceptions::unexpectedCodeReach);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java
deleted file mode 100644
index b928865fde..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithBookmark.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.Objects;
-import java.util.Optional;
-import java.util.UUID;
-import java.util.function.Supplier;
-import java.util.function.UnaryOperator;
-
-import org.springframework.lang.Nullable;
-
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.internal.base._Lazy;
-import org.apache.isis.commons.internal.debug._XrayEvent;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-
-import lombok.NonNull;
-import lombok.val;
-
-abstract class _ManagedObjectWithBookmark
-extends _ManagedObjectSpecifiedLegacy {
-
- protected final _Lazy<Optional<Bookmark>> bookmarkLazy =
- _Lazy.threadSafe(()->bookmark(this));
-
- protected _ManagedObjectWithBookmark(final Specialization specialization) {
- super(specialization);
- }
-
- @Override
- public final Optional<Bookmark> getBookmark() {
- return bookmarkLazy.get();
- }
-
- @Override
- public final boolean isBookmarkMemoized() {
- return bookmarkLazy.isMemoized();
- }
-
- @Override
- public final Optional<Bookmark> getBookmarkRefreshed() {
- // silently ignore invalidation, when the pojo is an entity
- if(!getSpecification().isEntity()) {
- bookmarkLazy.clear();
- }
- return getBookmark();
- }
-
- private void replaceBookmark(final UnaryOperator<Bookmark> replacer) {
- final Bookmark old = bookmarkLazy.isMemoized()
- ? bookmarkLazy.get().orElse(null)
- : null;
- bookmarkLazy.clear();
- bookmarkLazy.set(Optional.ofNullable(replacer.apply(old)));
- }
-
- // guards against non-identifiable objects;
- // historically, we allowed non-identifiable to be handled by the objectManager,
- // which as a fallback creates 'random' UUIDs
- private Optional<Bookmark> bookmark(final @Nullable ManagedObject adapter) {
-
- if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)
- || adapter.getSpecification().isValue()
- || !ManagedObjects.isIdentifiable(adapter)) {
- return Optional.empty();
- }
-
- return ManagedObjects.spec(adapter)
- .map(ObjectSpecification::getMetaModelContext)
- .map(MetaModelContext::getObjectManager)
- .map(objectManager->objectManager.bookmarkObject(adapter));
- }
-
- // -- REFRESH OPTIMIZATION
-
- private UUID interactionIdDuringWhichRefreshed = null;
-
- @Override
- public final void refreshViewmodel(final @Nullable Supplier<Bookmark> bookmarkSupplier) {
- val spec = getSpecification();
- if(spec.isViewModel()) {
- val viewModelFacet = spec.getFacet(ViewModelFacet.class);
- if(viewModelFacet.containsEntities()) {
-
- val shouldRefresh = spec.getMetaModelContext().getInteractionProvider().getInteractionId()
- .map(this::shouldRefresh)
- .orElse(true); // if there is no current interaction, refresh regardless; unexpected state, might fail later
-
- if(!shouldRefresh) {
- return;
- }
-
- if(isBookmarkMemoized()) {
- reloadViewmodelFromMemoizedBookmark();
- } else {
- val bookmark = bookmarkSupplier!=null
- ? bookmarkSupplier.get()
- : null;
- if(bookmark!=null) {
- reloadViewmodelFromBookmark(bookmark);
- }
- }
- }
- }
- }
-
- private boolean shouldRefresh(final @NonNull UUID interactionId) {
- if(Objects.equals(this.interactionIdDuringWhichRefreshed, interactionId)) {
- return false; // already refreshed within current interaction
- }
- this.interactionIdDuringWhichRefreshed = interactionId;
- return true;
- }
-
- /**
- * Reload current viewmodel object from memoized bookmark, otherwise does nothing.
- */
- private void reloadViewmodelFromMemoizedBookmark() {
- val spec = getSpecification();
- if(isBookmarkMemoized()
- && spec.isViewModel()) {
-
- val bookmark = getBookmark().get();
- val viewModelClass = spec.getCorrespondingClass();
-
- val recreatedViewmodel =
- getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
-
- _XrayEvent.event("Viewmodel '%s' recreated from memoized bookmark.", viewModelClass.getName());
-
- replacePojo(old->recreatedViewmodel);
- }
- }
-
- private void reloadViewmodelFromBookmark(final @NonNull Bookmark bookmark) {
- val spec = getSpecification();
- if(spec.isViewModel()) {
- val viewModelClass = spec.getCorrespondingClass();
-
- val recreatedViewmodel =
- getMetaModelContext().getFactoryService().viewModel(viewModelClass, bookmark);
-
- _XrayEvent.event("Viewmodel '%s' recreated from provided bookmark.", viewModelClass.getName());
-
- replacePojo(old->recreatedViewmodel);
- replaceBookmark(old->bookmark);
- }
- }
-
- /**
- * Introduced, so we can re-fetch detached entity pojos in place.
- */
- abstract void replacePojo(UnaryOperator<Object> replacer);
-
-}
\ No newline at end of file
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
deleted file mode 100644
index fdf49ed4f3..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/_ManagedObjectWithEagerSpec.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.Optional;
-import java.util.function.UnaryOperator;
-
-import org.springframework.lang.Nullable;
-
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.collections._Collections;
-import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.ToString;
-import lombok.val;
-
-@Deprecated
-@EqualsAndHashCode(of = "pojo", callSuper = false)
-@ToString(of = {"specification", "pojo"}) //ISIS-2317 make sure toString() is without side-effects
-@Getter
-final class _ManagedObjectWithEagerSpec
-extends _ManagedObjectWithBookmark {
-
- public static ManagedObject identified(
- final @NonNull ObjectSpecification spec,
- final @Nullable Object pojo,
- final @NonNull Bookmark bookmark) {
-
- if(pojo!=null) {
- _Assert.assertFalse(_Collections.isCollectionOrArrayOrCanType(pojo.getClass()));
- }
-
- val managedObject = new _ManagedObjectWithEagerSpec(spec, pojo);
- managedObject.bookmarkLazy.set(Optional.of(bookmark));
- return managedObject;
- }
-
- _ManagedObjectWithEagerSpec(
- final ObjectSpecification spec,
- final Object pojo) {
- super(ManagedObject.Specialization.inferFrom(spec, pojo));
- //_Assert.assertFalse(getSpecialization().isValue()); // VALUE already migrated
- _Assert.assertFalse(getSpecialization().isService()); // SERVICE already migrated
- _Assert.assertFalse(getSpecialization().isMixin()); // MIXIN already migrated
-
- this.specification = spec;
- this.pojo = pojo;
- }
-
- @NonNull private final ObjectSpecification specification;
- @Nullable private /*final*/ Object pojo;
-
- @Override
- public void replacePojo(final UnaryOperator<Object> replacer) {
- pojo = assertCompliance(replacer.apply(pojo));
- }
-
- @Override
- public final String getTitle() {
- return _InternalTitleUtil.titleString(
- TitleRenderRequest.forObject(this));
- }
-
-}
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
index 07b9b73210..165b141cfa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/ObjectManager.java
@@ -27,7 +27,6 @@ import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.objectmanager.create.ObjectCreator;
import org.apache.isis.core.metamodel.objectmanager.detach.ObjectDetacher;
@@ -115,26 +114,12 @@ public interface ObjectManager {
// -- ADAPTING POJOS
- enum EntityAdaptingMode {
- MEMOIZE_BOOKMARK,
- SKIP_MEMOIZATION;
- public boolean isMemoize() { return this == MEMOIZE_BOOKMARK;}
- }
-
/**
* Not suitable for adapting a non-scalar
* If {@code pojo} is an entity, automatically memoizes its bookmark.
*/
public default ManagedObject adapt(final @Nullable Object pojo) {
- return adapt(pojo, ()->specForType(Object.class).orElseThrow(), EntityAdaptingMode.MEMOIZE_BOOKMARK);
- }
-
- /**
- * Not suitable for adapting a non-scalar.
- * If {@code pojo} is an entity, memoizes its bookmark based on policy {@code bookmarking}.
- */
- public default ManagedObject adapt(final @Nullable Object pojo, final EntityAdaptingMode bookmarking) {
- return adapt(pojo, ()->specForType(Object.class).orElseThrow(), bookmarking);
+ return adapt(pojo, ()->specForType(Object.class).orElseThrow());
}
/**
@@ -143,8 +128,7 @@ public interface ObjectManager {
*/
public default ManagedObject adapt(
final @Nullable Object pojo,
- final @NonNull Supplier<ObjectSpecification> fallbackElementType,
- final EntityAdaptingMode entityAdaptingMode) {
+ final @NonNull Supplier<ObjectSpecification> fallbackElementType) {
if(pojo==null) {
return ManagedObject.unspecified();
}
@@ -158,11 +142,11 @@ public interface ObjectManager {
return ManagedObject.unspecified();
}
return spec.isScalar()
- ? managedObjectEagerlyBookmarkedIfRequired(spec, pojo, entityAdaptingMode)
+ ? managedObjectEagerlyBookmarkedIfRequired(spec, pojo)
: ManagedObject.packed(
spec.getElementSpecification().orElseGet(fallbackElementType),
_NullSafe.streamAutodetect(pojo)
- .map(element->adapt(element, entityAdaptingMode))
+ .map(element->adapt(element))
.collect(Can.toCan()));
}
@@ -190,7 +174,7 @@ public interface ObjectManager {
// if actual type matches spec's, we assume, that we don't need to reload,
// so this is a shortcut for performance reasons
? managedObjectEagerlyBookmarkedIfRequired(
- proposedSpec, pojo, EntityAdaptingMode.MEMOIZE_BOOKMARK)
+ proposedSpec, pojo)
// fallback, ignoring proposedSpec
: adapt(pojo);
return adapter;
@@ -200,26 +184,14 @@ public interface ObjectManager {
/**
* {@link ManagedObject} factory, that in case of given pojo representing an entity
- * and the entityAdaptingMode equals {@link EntityAdaptingMode#isMemoize()},
+ * and the entityAdaptingMode equals {@link EntityAdaptingMode#isBookmarkable()},
* then tries to memoize its {@link Bookmark} eagerly
* (otherwise its {@link Bookmark} is lazily resolved).
*/
private static ManagedObject managedObjectEagerlyBookmarkedIfRequired(
final ObjectSpecification spec,
- final Object pojo,
- final EntityAdaptingMode entityAdaptingMode) {
-
- if(entityAdaptingMode.isMemoize()
- && spec.isEntity()) {
- val entityFacet = spec.getFacet(EntityFacet.class);
- val state = entityFacet.getEntityState(pojo);
- if(state.isAttached()) {
- val id = entityFacet.identifierFor(pojo);
- val bookmark = Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), id);
- return ManagedObject.bookmarked(spec, pojo, bookmark);
- }
- }
- return ManagedObject.notBookmarked(spec, pojo);
+ final Object pojo) {
+ return ManagedObject.adaptScalar(spec, pojo);
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/detach/ObjectDetacher_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/detach/ObjectDetacher_builtinHandlers.java
index 39b9b71b53..b20094fd28 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/detach/ObjectDetacher_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/detach/ObjectDetacher_builtinHandlers.java
@@ -18,9 +18,7 @@
*/
package org.apache.isis.core.metamodel.objectmanager.detach;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import lombok.Data;
@@ -41,7 +39,7 @@ final class ObjectDetacher_builtinHandlers {
private MetaModelContext metaModelContext;
@Override
- public boolean isHandling(ManagedObject managedObject) {
+ public boolean isHandling(final ManagedObject managedObject) {
if(managedObject==null || managedObject.getPojo()==null) {
return true;
@@ -51,7 +49,7 @@ final class ObjectDetacher_builtinHandlers {
}
@Override
- public ManagedObject handle(ManagedObject managedObject) {
+ public ManagedObject handle(final ManagedObject managedObject) {
return null; // noop
}
@@ -63,20 +61,16 @@ final class ObjectDetacher_builtinHandlers {
private final MetaModelContext metaModelContext;
@Override
- public boolean isHandling(ManagedObject request) {
+ public boolean isHandling(final ManagedObject request) {
val spec = request.getSpecification();
return spec.isEntity();
}
@Override
- public ManagedObject handle(ManagedObject request) {
+ public ManagedObject handle(final ManagedObject request) {
val spec = request.getSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- throw _Exceptions.illegalArgument(
- "ObjectSpecification is missing an EntityFacet: %s", spec);
- }
+ val entityFacet = spec.entityFacetElseFail();
Object detachedPojo = entityFacet.detach(request.getPojo());
@@ -92,13 +86,13 @@ final class ObjectDetacher_builtinHandlers {
public static class DetachOther implements ObjectDetacher.Handler {
@Override
- public boolean isHandling(ManagedObject request) {
+ public boolean isHandling(final ManagedObject request) {
// if no one else feels responsible, we do
return true;
}
@Override
- public ManagedObject handle(ManagedObject request) {
+ public ManagedObject handle(final ManagedObject request) {
return request;
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
index ef74f4bff2..9130d1b88d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
@@ -26,10 +26,7 @@ import org.apache.isis.applib.services.bookmark.Oid;
import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
import org.apache.isis.commons.internal.base._Bytes;
import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.debug._Debug;
-import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.PackedManagedObject;
@@ -37,7 +34,6 @@ import org.apache.isis.core.metamodel.objectmanager.identify.ObjectBookmarker.Ha
import lombok.SneakyThrows;
import lombok.val;
-import lombok.extern.log4j.Log4j2;
class ObjectBookmarker_builtinHandlers {
@@ -63,67 +59,25 @@ class ObjectBookmarker_builtinHandlers {
@Override
public boolean isHandling(final ManagedObject managedObject) {
- return managedObject.getSpecification().isInjectable();
+ return managedObject.getSpecialization().isService();
}
@Override
public Bookmark handle(final ManagedObject managedObject) {
- final String identifier = SERVICE_IDENTIFIER;
- return Bookmark.forLogicalTypeAndIdentifier(
- managedObject.getSpecification().getLogicalType(),
- identifier);
+ return managedObject.getBookmark().orElseThrow();
}
-
}
- @Log4j2
static class BookmarkForEntities implements Handler {
@Override
public boolean isHandling(final ManagedObject managedObject) {
- return managedObject.getSpecification().isEntity();
+ return managedObject.getSpecialization().isEntity();
}
@Override
public Bookmark handle(final ManagedObject managedObject) {
- val spec = managedObject.getSpecification();
- val entityPojo = managedObject.getPojo();
- if(entityPojo==null) {
- val msg = String.format("entity '%s' is null, cannot identify", managedObject);
- throw _Exceptions.unrecoverable(msg);
- }
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- val msg = String.format("entity '%s' has no EntityFacet associated", managedObject);
- throw _Exceptions.unrecoverable(msg);
- }
-
- // fail early when detached entities are detected
- // should have been re-fetched at start of this request-cycle
- if(!managedObject.isBookmarkMemoized()
-// && EntityUtil.getPersistenceStandard(managedObject)
-// .map(PersistenceStandard::isJdo)
-// .orElse(false)
- && !entityFacet.getEntityState(entityPojo).isAttached()) {
-
- _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
- _Debug.log("detached entity detected %s", entityPojo);
- });
-
- val msg = String.format(
- "The persistence layer does not recognize given object %s, "
- + "meaning the object has no identifier that associates it with the persistence layer. "
- + "(most likely, because the object is detached, eg. was not persisted after being new-ed up)",
- managedObject);
-
- // in case of the exception getting swallowed, also write a log
- log.error(msg);
-
- throw _Exceptions.illegalArgument(msg);
- }
-
- val identifier = entityFacet.identifierFor(entityPojo);
- return Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), identifier);
+ return managedObject.getBookmark().orElseThrow();
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
index 88581e4e1b..4b0116eb1f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
@@ -24,7 +24,6 @@ import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.commons.internal.ioc._ManagedBeanAdapter;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
@@ -179,15 +178,14 @@ final class ObjectLoader_builtinHandlers {
public ManagedObject handle(final ObjectLoader.Request objectLoadRequest) {
val spec = objectLoadRequest.getObjectSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- throw _Exceptions.illegalArgument(
- "ObjectSpecification is missing an EntityFacet: %s", spec);
- }
+ val entityFacet = spec.entityFacetElseFail();
val bookmark = objectLoadRequest.getBookmark();
- val entity = entityFacet.fetchByIdentifier(bookmark);
- return entity;
+ val entityPojoIfAny = entityFacet.fetchByBookmark(bookmark);
+
+ return entityPojoIfAny
+ .map(entityPojo->ManagedObject.entity(spec, entityPojo, Optional.of(bookmark)))
+ .orElseGet(()->ManagedObject.empty(spec));
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
index 7eb33b8e98..e632428813 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.objectmanager.query;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import lombok.NonNull;
@@ -85,11 +84,7 @@ final class ObjectBulkLoader_builtinHandlers {
public Can<ManagedObject> handle(final ObjectBulkLoader.Request objectQuery) {
val spec = objectQuery.getObjectSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- throw _Exceptions.illegalArgument(
- "ObjectSpecification is missing an EntityFacet: %s", spec.getCorrespondingClass());
- }
+ val entityFacet = spec.entityFacetElseFail();
val entities = entityFacet.fetchByQuery(objectQuery.getQuery());
val serviceInjector = metaModelContext.getServiceInjector();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/refresh/ObjectRefresher_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/refresh/ObjectRefresher_builtinHandlers.java
index 9f6f80a93f..3cecee0d22 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/refresh/ObjectRefresher_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/refresh/ObjectRefresher_builtinHandlers.java
@@ -18,9 +18,7 @@
*/
package org.apache.isis.core.metamodel.objectmanager.refresh;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import lombok.Data;
@@ -41,7 +39,7 @@ final class ObjectRefresher_builtinHandlers {
private MetaModelContext metaModelContext;
@Override
- public boolean isHandling(ManagedObject managedObject) {
+ public boolean isHandling(final ManagedObject managedObject) {
if(managedObject==null || managedObject.getPojo()==null) {
return true;
@@ -51,7 +49,7 @@ final class ObjectRefresher_builtinHandlers {
}
@Override
- public Void handle(ManagedObject managedObject) {
+ public Void handle(final ManagedObject managedObject) {
return null; // noop
}
@@ -61,20 +59,16 @@ final class ObjectRefresher_builtinHandlers {
public static class RefreshEntity implements ObjectRefresher.Handler {
@Override
- public boolean isHandling(ManagedObject request) {
+ public boolean isHandling(final ManagedObject request) {
val spec = request.getSpecification();
return spec.isEntity();
}
@Override
- public Void handle(ManagedObject request) {
+ public Void handle(final ManagedObject request) {
val spec = request.getSpecification();
- val entityFacet = spec.getFacet(EntityFacet.class);
- if(entityFacet==null) {
- throw _Exceptions.illegalArgument(
- "ObjectSpecification is missing an EntityFacet: %s", spec);
- }
+ val entityFacet = spec.entityFacetElseFail();
entityFacet.refresh(request.getPojo());
@@ -90,13 +84,13 @@ final class ObjectRefresher_builtinHandlers {
public static class RefreshOther implements ObjectRefresher.Handler {
@Override
- public boolean isHandling(ManagedObject request) {
+ public boolean isHandling(final ManagedObject request) {
// if no one else feels responsible, we do
return true;
}
@Override
- public Void handle(ManagedObject request) {
+ public Void handle(final ManagedObject request) {
return null; // noop
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
index 1915659ba5..c6225b2ffb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Hierarchical.java
@@ -45,6 +45,11 @@ public interface Hierarchical {
*/
boolean isOfType(ObjectSpecification other);
+ /**
+ * Same as {@link #isOfType(ObjectSpecification)}, except treating wrapper/primitive the same.
+ */
+ boolean isOfTypeResolvePrimitive(ObjectSpecification other);
+
public static enum Depth {
DIRECT,
TRANSITIVE
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index 847ea7f3d7..a220b5adde 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -440,13 +440,13 @@ extends
default boolean isEntity() {
return getBeanSort().isEntity()
|| (getBeanSort().isAbstract()
- && lookupFacet(EntityFacet.class).isPresent());
+ && entityFacet().isPresent());
}
default boolean isViewModel() {
return getBeanSort().isViewModel()
|| (getBeanSort().isAbstract()
- && lookupFacet(ViewModelFacet.class).isPresent());
+ && viewmodelFacet().isPresent());
}
default boolean isEntityOrViewModel() {
@@ -629,5 +629,24 @@ extends
/** introduced for lookup optimization / allow memoization */
@SuppressWarnings("rawtypes")
Optional<ValueFacet> valueFacet();
+ @SuppressWarnings("rawtypes")
+ default ValueFacet valueFacetElseFail() {
+ return valueFacet().orElseThrow(()->
+ _Exceptions.unrecoverable("Value type %s must have a ValueFacet", toString()));
+ }
+
+ /** introduced for lookup optimization / allow memoization */
+ Optional<EntityFacet> entityFacet();
+ default EntityFacet entityFacetElseFail() {
+ return entityFacet().orElseThrow(()->
+ _Exceptions.unrecoverable("Entity type %s must have an EntityFacet", toString()));
+ }
+
+ /** introduced for lookup optimization / allow memoization */
+ Optional<ViewModelFacet> viewmodelFacet();
+ default ViewModelFacet viewmodelFacetElseFail() {
+ return viewmodelFacet().orElseThrow(()->
+ _Exceptions.unrecoverable("ViewModel type %s must have a ViewModelFacet", toString()));
+ }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index 76296c1606..af88318689 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -29,6 +29,8 @@ import java.util.stream.Stream;
import javax.enterprise.inject.Vetoed;
+import org.springframework.util.ClassUtils;
+
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.Introspection.IntrospectionPolicy;
import org.apache.isis.applib.id.LogicalType;
@@ -60,6 +62,7 @@ import org.apache.isis.core.metamodel.facets.all.named.ObjectNamedFacet;
import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaFacet;
import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaFactory;
+import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.facets.object.icon.IconFacet;
import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
@@ -70,6 +73,7 @@ import org.apache.isis.core.metamodel.facets.object.parented.ParentedCollectionF
import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.interactions.InteractionContext;
import org.apache.isis.core.metamodel.interactions.InteractionUtils;
import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
@@ -181,6 +185,8 @@ implements ObjectSpecification {
private ObjectSpecification superclassSpec;
private ValueFacet valueFacet;
+ private EntityFacet entityFacet;
+ private ViewModelFacet viewmodelFacet;
private TitleFacet titleFacet;
private IconFacet iconFacet;
private NavigableParentFacet navigableParentFacet;
@@ -394,6 +400,24 @@ implements ObjectSpecification {
return Optional.ofNullable(valueFacet);
}
+ @Override
+ public final Optional<EntityFacet> entityFacet() {
+ // deliberately don't memoize lookup misses, because could be too early
+ if(entityFacet==null) {
+ entityFacet = getFacet(EntityFacet.class);
+ }
+ return Optional.ofNullable(entityFacet);
+ }
+
+ @Override
+ public final Optional<ViewModelFacet> viewmodelFacet() {
+ // deliberately don't memoize lookup misses, because could be too early
+ if(viewmodelFacet==null) {
+ viewmodelFacet = getFacet(ViewModelFacet.class);
+ }
+ return Optional.ofNullable(viewmodelFacet);
+ }
+
@Override
public String getTitle(final TitleRenderRequest titleRenderRequest) {
if (titleFacet != null) {
@@ -466,6 +490,17 @@ implements ObjectSpecification {
|| otherClass.isAssignableFrom(thisClass);
}
+ @Override
+ public boolean isOfTypeResolvePrimitive(final ObjectSpecification other) {
+
+ val thisClass = ClassUtils.resolvePrimitiveIfNecessary(this.getCorrespondingClass());
+ val otherClass = ClassUtils.resolvePrimitiveIfNecessary(other.getCorrespondingClass());
+
+ return thisClass == otherClass
+ || otherClass.isAssignableFrom(thisClass);
+ }
+
+
// -- NAME, DESCRIPTION, PERSISTABILITY
@Override
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ident/title/TitleAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ident/title/TitleAnnotationFacetFactoryTest.java
index dc2e7c70d3..c0c13c4e43 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ident/title/TitleAnnotationFacetFactoryTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/ident/title/TitleAnnotationFacetFactoryTest.java
@@ -132,7 +132,7 @@ extends AbstractFacetFactoryJUnit4TestCase {
}
final Customer2 customer = new Customer2();
- val objectAdapter = ManagedObject.wrapScalar(specificationLoader, customer);
+ val objectAdapter = ManagedObject.adaptScalar(specificationLoader, customer);
final String title = titleFacetViaTitleAnnotation.title(objectAdapter);
assertThat(title, is("titleElement1. titleElement3,titleElement2"));
@@ -198,9 +198,9 @@ extends AbstractFacetFactoryJUnit4TestCase {
public void titleAnnotatedMethodsSomeOfWhichReturnNulls() throws Exception {
{ // check prerequisites
- val wThree = ManagedObject.wrapScalar(specificationLoader, Integer.valueOf(3));
+ val wThree = ManagedObject.adaptScalar(specificationLoader, Integer.valueOf(3));
assertEquals("3", wThree.getTitle());
- val pThree = ManagedObject.wrapScalar(specificationLoader, 3);
+ val pThree = ManagedObject.adaptScalar(specificationLoader, 3);
assertEquals("3", pThree.getTitle());
}
@@ -208,7 +208,7 @@ extends AbstractFacetFactoryJUnit4TestCase {
.forTesting(Customer4.class, mockMethodRemover, facetedMethod));
final Customer4 customer = new Customer4();
- val objectAdapter = ManagedObject.wrapScalar(specificationLoader, customer);
+ val objectAdapter = ManagedObject.adaptScalar(specificationLoader, customer);
assertThat(objectAdapter.getTitle(),
is("titleElement1 titleElement3 titleElement5 3 this needs to be trimmed"));
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/object/ManagedObjectTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/object/ManagedObjectTest.java
index 3bfdf8587a..02de16d75d 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/object/ManagedObjectTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/object/ManagedObjectTest.java
@@ -84,7 +84,7 @@ class ManagedObjectTest {
val emptyObject = ManagedObject.empty(spec);
assertNotNull(emptyObject);
- val presentObject = ManagedObject.wrapScalar(specLoader, 3);
+ val presentObject = ManagedObject.adaptScalar(specLoader, 3);
assertEquals(Specialization.VALUE, presentObject.getSpecialization());
presentObject.assertCompliance(6);
@@ -113,7 +113,7 @@ class ManagedObjectTest {
val constructor = cls.getConstructor(_Constants.emptyClasses);
val pojo = constructor.newInstance(_Constants.emptyObjects);
- val presentObject = ManagedObject.wrapScalar(specLoader, pojo);
+ val presentObject = ManagedObject.adaptScalar(specLoader, pojo);
assertEquals(Specialization.VIEWMODEL, presentObject.getSpecialization());
presentObject.assertCompliance(pojo);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
index 357262c9de..3f8a406b1f 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/SchemaValueMarshallerDefault.java
@@ -146,13 +146,7 @@ extends SchemaValueMarshallerAbstract {
? fromTypedTuple(context, valueDto.getComposite())
: context.getSemantics().compose(ValueDecomposition.ofFundamental(valueDto));
- if(recoveredValueAsPojo==null) {
- return ManagedObject.empty(context.getElementType());
- }
-
- val recoveredValue = recoveredValueAsPojo!=null
- ? ManagedObject.of(elementSpec, recoveredValueAsPojo)
- : ManagedObject.empty(context.getElementType());
+ val recoveredValue = ManagedObject.value(elementSpec, recoveredValueAsPojo);
return recoveredValue;
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index 4cc45784e3..68692ac664 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -62,7 +62,6 @@ import org.apache.isis.core.metamodel.object.MmUnwrapUtil;
import org.apache.isis.core.metamodel.object.MmVisibilityUtil;
import org.apache.isis.core.metamodel.object.PackedManagedObject;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
-import org.apache.isis.core.metamodel.objectmanager.ObjectManager.EntityAdaptingMode;
import org.apache.isis.core.metamodel.services.events.MetamodelEventService;
import org.apache.isis.core.metamodel.services.ixn.InteractionDtoFactory;
import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
@@ -177,7 +176,7 @@ implements MemberExecutorService {
val returnedPojo = priorExecution.getReturned();
val returnedAdapter = objectManager.adapt(
- returnedPojo, owningAction::getElementType, EntityAdaptingMode.MEMOIZE_BOOKMARK);
+ returnedPojo, owningAction::getElementType);
// sync DTO with result
interactionDtoFactory
@@ -279,6 +278,7 @@ implements MemberExecutorService {
}
val entityState = MmEntityUtil.getEntityState(resultAdapter);
+ //FIXME what to do with new state
if(entityState.isDetached()) {
// ensure that any still-to-be-persisted adapters get persisted to DB.
getTransactionService().flushTransaction();
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
index 0211ddb2c6..0e0fb5cb0b 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/factory/FactoryServiceDefault.java
@@ -33,7 +33,6 @@ import org.apache.isis.applib.annotation.PriorityPrecedence;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.iactnlayer.InteractionService;
-import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
@@ -56,7 +55,6 @@ public class FactoryServiceDefault implements FactoryService {
@Inject InteractionService interactionService; // dependsOn
@Inject private SpecificationLoader specificationLoader;
- @Inject private ServiceInjector serviceInjector;
@Inject private IsisSystemEnvironment isisSystemEnvironment;
@Inject private Provider<ObjectLifecyclePublisher> objectLifecyclePublisherProvider;
private ObjectLifecyclePublisher objectLifecyclePublisher() { return objectLifecyclePublisherProvider.get(); }
@@ -95,8 +93,7 @@ public class FactoryServiceDefault implements FactoryService {
throw _Exceptions.illegalArgument("Type '%s' is not recogniced as an entity type by the framework.",
entityClass);
}
- serviceInjector.injectServicesInto(entityPojo);
- objectLifecyclePublisher().onPostCreate(ManagedObject.of(spec, entityPojo));
+ objectLifecyclePublisher().onPostCreate(ManagedObject.entityDetached(spec, entityPojo));
return entityPojo;
}
@@ -124,8 +121,7 @@ public class FactoryServiceDefault implements FactoryService {
throw _Exceptions.illegalArgument("Type '%s' is not recogniced as a ViewModel by the framework.",
viewModelClass);
}
- serviceInjector.injectServicesInto(viewModelPojo);
- objectLifecyclePublisher().onPostCreate(ManagedObject.of(spec, viewModelPojo));
+ objectLifecyclePublisher().onPostCreate(ManagedObject.viewmodel(spec, viewModelPojo, Optional.empty()));
return viewModelPojo;
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/repository/RepositoryServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/repository/RepositoryServiceDefault.java
index 22dd0420c9..c605a71ac4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/repository/RepositoryServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/repository/RepositoryServiceDefault.java
@@ -97,7 +97,7 @@ public class RepositoryServiceDefault implements RepositoryService {
if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) {
throw new PersistFailedException("Object not known to framework (unable to create/obtain an adapter)");
}
- // only persist detached entities, otherwise skip
+ // only persist detached or new entities, otherwise skip
val entityState = MmEntityUtil.getEntityState(adapter);
if(!entityState.isPersistable()
|| entityState.isAttached()) {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
index 84ed080cfb..107e227938 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -127,8 +127,7 @@ extends DelegatingInvocationHandlerDefault<T> {
nsme);
}
- entityFacet = targetAdapter.getSpecification()
- .getFacet(EntityFacet.class);
+ entityFacet = targetAdapter.getSpecification().entityFacet().orElse(null);
this.mixeeAdapter = mixeeAdapter;
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotBuilder.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotBuilder.java
index ac1bae20da..75e698543a 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotBuilder.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotBuilder.java
@@ -79,7 +79,7 @@ public class XmlSnapshotBuilder {
}
public XmlSnapshot build() {
- final ManagedObject adapter = ManagedObject.wrapScalar(specificationLoader, domainObject);
+ final ManagedObject adapter = ManagedObject.adaptScalar(specificationLoader, domainObject);
final XmlSnapshot snapshot = (schema != null)
? new XmlSnapshot(adapter, schema)
: new XmlSnapshot(adapter);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotServiceDefault.java
index 669b1ae402..f8ec1e95f6 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xmlsnapshot/XmlSnapshotServiceDefault.java
@@ -86,7 +86,7 @@ public class XmlSnapshotServiceDefault implements XmlSnapshotService {
*/
@Override
public XmlSnapshotService.Snapshot snapshotFor(final Object domainObject) {
- final ManagedObject adapter = ManagedObject.wrapScalar(specificationLoader, domainObject);
+ final ManagedObject adapter = ManagedObject.adaptScalar(specificationLoader, domainObject);
return new XmlSnapshot(adapter);
}
diff --git a/extensions/vw/fullcalendar/wicket/ui/src/main/java/org/apache/isis/extensions/fullcalendar/wkt/viewer/EventProviderAbstract.java b/extensions/vw/fullcalendar/wicket/ui/src/main/java/org/apache/isis/extensions/fullcalendar/wkt/viewer/EventProviderAbstract.java
index 012cacff38..8715a7db0f 100644
--- a/extensions/vw/fullcalendar/wicket/ui/src/main/java/org/apache/isis/extensions/fullcalendar/wkt/viewer/EventProviderAbstract.java
+++ b/extensions/vw/fullcalendar/wicket/ui/src/main/java/org/apache/isis/extensions/fullcalendar/wkt/viewer/EventProviderAbstract.java
@@ -121,7 +121,7 @@ public abstract class EventProviderAbstract implements EventProvider {
final Object dereferencedObject = dereference(commonContext, domainObjectPojo);
val dereferencedManagedObject =
- ManagedObject.wrapScalar(commonContext.getSpecificationLoader(), dereferencedObject);
+ ManagedObject.adaptScalar(commonContext.getSpecificationLoader(), dereferencedObject);
val oid = ManagedObjects.bookmark(dereferencedManagedObject).orElse(null);
if(oid!=null) {
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
index d0b7c46a3e..4f15234a8c 100644
--- a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
+++ b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/ObjectTypeFactory.java
@@ -414,7 +414,7 @@ public class ObjectTypeFactory {
Class<?> domainObjectInstanceClass = domainObjectInstance.getClass();
ObjectSpecification specification = specificationLoader.loadSpecification(domainObjectInstanceClass);
- ManagedObject owner = ManagedObject.of(specification, domainObjectInstance);
+ ManagedObject owner = ManagedObject.adaptScalar(specification, domainObjectInstance);
ManagedObject managedObject = otom.get(owner);
diff --git a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/QueryFieldFactory.java b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/QueryFieldFactory.java
index 2c84794a57..d800229253 100644
--- a/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/QueryFieldFactory.java
+++ b/incubator/viewers/graphql/viewer/src/main/java/org/apache/isis/viewer/graphql/viewer/source/QueryFieldFactory.java
@@ -123,7 +123,7 @@ public class QueryFieldFactory {
ObjectSpecification specification = specificationLoader
.loadSpecification(domainObjectInstanceClass);
- ManagedObject owner = ManagedObject.of(specification, domainObjectInstance);
+ ManagedObject owner = ManagedObject.adaptScalar(specification, domainObjectInstance);
ActionInteractionHead actionInteractionHead = objectAction.interactionHead(owner);
@@ -133,10 +133,7 @@ public class QueryFieldFactory {
Object argumentValue = arguments.get(oap.getId());
ObjectSpecification elementType = oap.getElementType();
- if (argumentValue == null)
- return ManagedObject.empty(elementType);
- return ManagedObject.of(elementType, argumentValue);
-
+ return ManagedObject.adaptScalar(elementType, argumentValue);
}).collect(Can.toCan());
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/binding/BindingsVaa.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/binding/BindingsVaa.java
index d95e499217..389d0063bc 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/binding/BindingsVaa.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/binding/BindingsVaa.java
@@ -20,8 +20,6 @@ package org.apache.isis.incubator.viewer.vaadin.ui.binding;
import java.util.function.UnaryOperator;
-import org.springframework.lang.Nullable;
-
import com.vaadin.flow.component.HasValidation;
import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.data.binder.Binder;
@@ -30,6 +28,8 @@ import com.vaadin.flow.data.binder.Setter;
import com.vaadin.flow.data.converter.Converter;
import com.vaadin.flow.function.ValueProvider;
+import org.springframework.lang.Nullable;
+
import org.apache.isis.commons.binding.Bindable;
import org.apache.isis.commons.binding.Observable;
import org.apache.isis.commons.internal.base._Casts;
@@ -361,7 +361,7 @@ public final class BindingsVaa {
//SETTER
@Override
public void accept(@NonNull final Bindable<ManagedObject> target, final V fieldValue) {
- target.setValue(ManagedObject.of(valueSpec, fieldValue));
+ target.setValue(ManagedObject.adaptScalar(valueSpec, fieldValue));
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/JdoLifecycleListener.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/JdoLifecycleListener.java
index 410d455401..8be754c905 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/JdoLifecycleListener.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/JdoLifecycleListener.java
@@ -31,11 +31,11 @@ import javax.jdo.listener.StoreLifecycleListener;
import org.datanucleus.enhancement.Persistable;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facets.object.publish.entitychange.EntityChangePublishingFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.metamodel.objectmanager.ObjectManager.EntityAdaptingMode;
import org.apache.isis.core.metamodel.services.objectlifecycle.ObjectLifecyclePublisher;
import org.apache.isis.persistence.jdo.datanucleus.entities.DnObjectProviderForIsis;
@@ -89,7 +89,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
public void postLoad(final InstanceLifecycleEvent event) {
log.debug("postLoad {}", ()->_Utils.debug(event));
final Persistable pojo = _Utils.persistableFor(event);
- val entity = adaptEntityAndInjectServices(pojo, EntityAdaptingMode.MEMOIZE_BOOKMARK);
+ val entity = adaptEntity(pojo);
objectLifecyclePublisher.onPostLoad(entity);
@@ -101,10 +101,11 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
final Persistable pojo = _Utils.persistableFor(event);
- /* Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
+ /* Called either when an entity is initially persisted,
+ * or when an entity is updated; fires the appropriate
* lifecycle callback. So filter for those events when initially persisting. */
if(pojo.dnGetStateManager().isNew(pojo)) {
- val entity = adaptEntity(pojo, EntityAdaptingMode.SKIP_MEMOIZATION);
+ val entity = adaptEntity(pojo);
objectLifecyclePublisher.onPrePersist(entity);
}
}
@@ -114,7 +115,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
log.debug("postStore {}", ()->_Utils.debug(event));
final Persistable pojo = _Utils.persistableFor(event);
- val entity = adaptEntityAndInjectServices(pojo, EntityAdaptingMode.MEMOIZE_BOOKMARK);
+ val entity = adaptEntity(pojo);
if(EntityChangePublishingFacet.isPublishingEnabled(entity.getSpecification())) {
@@ -150,7 +151,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
}
private final void doPreDirty(final Persistable pojo) {
- val entity = adaptEntity(pojo, EntityAdaptingMode.MEMOIZE_BOOKMARK);
+ val entity = adaptEntity(pojo);
objectLifecyclePublisher.onPreUpdate(entity, null);
}
@@ -164,7 +165,10 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
log.debug("preDelete {}", ()->_Utils.debug(event));
final Persistable pojo = _Utils.persistableFor(event);
- val entity = adaptEntity(pojo, EntityAdaptingMode.SKIP_MEMOIZATION);
+
+ _Assert.assertNotNull(pojo.dnGetObjectId());
+ //val entity = adaptEntity(pojo, EntityAdaptingMode.NOT_YET_BOOKMARKABLE);
+ val entity = adaptEntity(pojo);
objectLifecyclePublisher.onPreRemove(entity);
}
@@ -204,15 +208,8 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
// -- HELPER
private ManagedObject adaptEntity(
- final @NonNull Persistable pojo,
- final @NonNull EntityAdaptingMode bookmarking) {
- return _Utils.adaptEntity(metaModelContext, pojo, bookmarking);
- }
-
- private ManagedObject adaptEntityAndInjectServices(
- final @NonNull Persistable pojo,
- final @NonNull EntityAdaptingMode bookmarking) {
- return _Utils.adaptEntityAndInjectServices(metaModelContext, pojo, bookmarking);
+ final @NonNull Persistable pojo) {
+ return _Utils.adaptEntity(metaModelContext, pojo);
}
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/_Utils.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/_Utils.java
index 6fa5f63e90..cd46eb93c0 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/_Utils.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/changetracking/_Utils.java
@@ -29,7 +29,6 @@ import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
-import org.apache.isis.core.metamodel.objectmanager.ObjectManager.EntityAdaptingMode;
import lombok.NonNull;
import lombok.val;
@@ -64,40 +63,36 @@ final class _Utils {
ManagedObject adaptEntity(
final @NonNull MetaModelContext mmc,
- final @NonNull Object entityPojo,
- final @NonNull EntityAdaptingMode bookmarking) {
+ final @NonNull Object entityPojo) {
val objectManager = mmc.getObjectManager();
- val entity = objectManager.adapt(entityPojo, bookmarking);
+ val entity = objectManager.adapt(entityPojo);
_Assert.assertTrue(entity.getSpecification().isEntity());
return entity;
}
ManagedObject adaptNullableEntity(
final @NonNull MetaModelContext mmc,
- final @Nullable Object entityPojo,
- final @NonNull EntityAdaptingMode bookmarking) {
+ final @Nullable Object entityPojo) {
return entityPojo == null
? ManagedObject.unspecified()
- : adaptEntity(mmc, entityPojo, bookmarking);
+ : adaptEntity(mmc, entityPojo);
}
ManagedObject adaptNullableAndInjectServices(
final @NonNull MetaModelContext mmc,
- final @Nullable Object entityPojo,
- final @NonNull EntityAdaptingMode bookmarking) {
+ final @Nullable Object entityPojo) {
return entityPojo == null
? ManagedObject.unspecified()
- : adaptEntityAndInjectServices(mmc, entityPojo, bookmarking);
+ : adaptEntityAndInjectServices(mmc, entityPojo);
}
ManagedObject adaptEntityAndInjectServices(
final @NonNull MetaModelContext mmc,
- final @NonNull Object entityPojo,
- final @NonNull EntityAdaptingMode bookmarking) {
- return injectServices(mmc, adaptEntity(mmc, entityPojo, bookmarking));
+ final @NonNull Object entityPojo) {
+ return injectServices(mmc, adaptEntity(mmc, entityPojo));
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
index f1d894d971..0e2fa29a70 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
@@ -21,9 +21,8 @@ package org.apache.isis.persistence.jdo.datanucleus.entities;
import java.lang.reflect.Method;
import java.util.Set;
-import org.springframework.lang.Nullable;
-
import org.datanucleus.enhancement.Persistable;
+import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.apache.isis.applib.services.repository.EntityState;
@@ -76,7 +75,9 @@ public class DnEntityStateProvider implements JdoFacetContext {
}
val isPersistent = persistable.dnIsPersistent();
if(isPersistent) {
- return EntityState.PERSISTABLE_ATTACHED;
+ return persistable.dnGetObjectId()!=null
+ ? EntityState.PERSISTABLE_ATTACHED
+ : EntityState.PERSISTABLE_NEW;
}
return EntityState.PERSISTABLE_DETACHED;
}
@@ -100,7 +101,7 @@ public class DnEntityStateProvider implements JdoFacetContext {
}
@Override
- public EntityFacet createEntityFacet(final FacetHolder facetHolder, Class<?> entityClass) {
+ public EntityFacet createEntityFacet(final FacetHolder facetHolder, final Class<?> entityClass) {
return new JdoEntityFacet(facetHolder, entityClass);
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index ac2b3741e3..6865d76cd1 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -21,6 +21,7 @@ package org.apache.isis.persistence.jdo.datanucleus.metamodel.facets.entity;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
@@ -46,8 +47,6 @@ import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.commons.internal.debug._Debug;
-import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.beans.PersistenceStack;
import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
@@ -56,7 +55,6 @@ import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.metamodel.services.objectlifecycle.ObjectLifecyclePublisher;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
import org.apache.isis.persistence.jdo.datanucleus.entities.DnEntityStateProvider;
import org.apache.isis.persistence.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacetFactory;
@@ -98,48 +96,22 @@ implements EntityFacet {
}
@Override
- public String identifierFor(final Object pojo) {
+ public Optional<String> identifierFor(final Object pojo) {
- if(pojo==null) {
- throw _Exceptions.illegalArgument(
- "The persistence layer cannot identify a pojo that is null (given type %s)",
- entityClass.getName());
- }
-
- if(!isPersistableType(pojo.getClass())) {
- throw _Exceptions.illegalArgument(
- "The persistence layer does not recognize given type %s",
- pojo.getClass().getName());
+ if (!getEntityState(pojo).isAttached()) {
+ return Optional.empty();
}
val pm = getPersistenceManager();
- var primaryKey = pm.getObjectId(pojo);
-
-// if(primaryKey==null) {
-// pm.makePersistent(pojo);
-// primaryKey = pm.getObjectId(pojo);
-// }
-
- if(primaryKey==null) {
-
- _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
- _Debug.log("detached entity detected %s", pojo);
- });
-
- throw _Exceptions.illegalArgument(
- "The persistence layer does not recognize given object of type %s, "
- + "meaning the object has no identifier that associates it with the persistence layer. "
- + "(most likely, because the object is detached, eg. was not persisted after being new-ed up)",
- pojo.getClass().getName());
- }
+ var primaryKeyIfAny = pm.getObjectId(pojo);
- return idStringifierService.enstringPrimaryKey(primaryKey.getClass(), primaryKey);
+ return Optional.ofNullable(primaryKeyIfAny)
+ .map(primaryKey->
+ idStringifierService.enstringPrimaryKey(primaryKey.getClass(), primaryKey));
}
-
@Override
- public ManagedObject fetchByIdentifier(
- final @NonNull Bookmark bookmark) {
+ public Optional<Object> fetchByBookmark(final @NonNull Bookmark bookmark) {
log.debug("fetchEntity; bookmark={}", bookmark);
@@ -166,14 +138,7 @@ implements EntityFacet {
throw e;
}
- if (entityPojo == null) {
- throw new ObjectNotFoundException(""+bookmark);
- }
-
- val actualEntitySpec = getSpecificationLoader().specForTypeElseFail(entityPojo.getClass());
- getServiceInjector().injectServicesInto(entityPojo); // might be redundant
- //TODO integrate with entity change tracking
- return ManagedObject.bookmarked(actualEntitySpec, entityPojo, bookmark);
+ return Optional.ofNullable(entityPojo);
}
private Map<Class<?>, Class<?>> primaryKeyClassByEntityClass = new ConcurrentHashMap<>();
@@ -209,11 +174,6 @@ implements EntityFacet {
}
}
- private ObjectSpecification getEntitySpec() {
- return getSpecificationLoader().specForType(entityClass)
- .orElseThrow(() -> new IllegalStateException(String.format("Could not load specification for entity class '%s'", entityClass)));
- }
-
@Override
public Can<ManagedObject> fetchByQuery(final Query<?> query) {
@@ -294,7 +254,7 @@ implements EntityFacet {
if(pojo==null
|| !isPersistableType(pojo.getClass())
- || DnEntityStateProvider.entityState(pojo).isAttached()) {
+ || DnEntityStateProvider.entityState(pojo).isAttachedOrNew()) {
return; // nothing to do
}
@@ -404,7 +364,8 @@ implements EntityFacet {
private Can<ManagedObject> fetchWithinTransaction(final Supplier<List<?>> fetcher) {
- val objectLifecyclePublisher = getFacetHolder().getServiceRegistry().lookupServiceElseFail(ObjectLifecyclePublisher.class);
+ val objectLifecyclePublisher = getFacetHolder().getServiceRegistry()
+ .lookupServiceElseFail(ObjectLifecyclePublisher.class);
return getTransactionalProcessor().callWithinCurrentTransactionElseCreateNew(
()->_NullSafe.stream(fetcher.get())
@@ -413,7 +374,9 @@ implements EntityFacet {
.getValue().orElseThrow();
}
- private ManagedObject adopt(final ObjectLifecyclePublisher objectLifecyclePublisher, final Object fetchedObject) {
+ private ManagedObject adopt(
+ final ObjectLifecyclePublisher objectLifecyclePublisher,
+ final Object fetchedObject) {
// handles lifecycle callbacks and injects services
// ought not to be necessary, however for some queries it seems that the
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
index adc42ad8dc..7c764ec931 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
@@ -28,8 +28,8 @@ import javax.persistence.metamodel.EntityType;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.springframework.data.jpa.repository.JpaContext;
+import org.springframework.lang.Nullable;
-import org.apache.isis.applib.exceptions.unrecoverable.ObjectNotFoundException;
import org.apache.isis.applib.query.AllInstancesQuery;
import org.apache.isis.applib.query.NamedQuery;
import org.apache.isis.applib.query.Query;
@@ -45,7 +45,6 @@ import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.runtime.idstringifier.IdStringifierService;
import lombok.NonNull;
@@ -80,32 +79,23 @@ public class JpaEntityFacet
}
@Override
- public String identifierFor(final Object pojo) {
+ public Optional<String> identifierFor(final @Nullable Object pojo) {
- if (pojo == null) {
- throw _Exceptions.illegalArgument(
- "The persistence layer cannot identify a pojo that is null (given type %s)",
- entityClass.getName());
+ if (!getEntityState(pojo).isAttached()) {
+ return Optional.empty();
}
val entityManager = getEntityManager();
val persistenceUnitUtil = getPersistenceUnitUtil(entityManager);
- val primaryKey = persistenceUnitUtil.getIdentifier(pojo);
-
- if (primaryKey == null) {
- throw _Exceptions.illegalArgument(
- "The persistence layer does not recognize given object of type %s, "
- + "meaning the object has no identifier that associates it with the persistence layer. "
- + "(most likely, because the object is detached, eg. was not persisted after being new-ed up)",
- pojo.getClass().getName());
- }
+ val primaryKeyIfAny = persistenceUnitUtil.getIdentifier(pojo);
- return idStringifierService.enstringPrimaryKey(getPrimaryKeyType(), primaryKey);
+ return Optional.ofNullable(primaryKeyIfAny)
+ .map(primaryKey->
+ idStringifierService.enstringPrimaryKey(getPrimaryKeyType(), primaryKey));
}
@Override
- public ManagedObject fetchByIdentifier(
- final @NonNull Bookmark bookmark) {
+ public Optional<Object> fetchByBookmark(final @NonNull Bookmark bookmark) {
log.debug("fetchEntity; bookmark={}", bookmark);
@@ -114,18 +104,7 @@ public class JpaEntityFacet
val entityManager = getEntityManager();
val entityPojo = entityManager.find(entityClass, primaryKey);
-
- if (entityPojo == null) {
- throw new ObjectNotFoundException("" + bookmark);
- }
-
- final ObjectSpecification entitySpec = getEntitySpec();
- return ManagedObject.bookmarked(entitySpec, entityPojo, bookmark);
- }
-
- private ObjectSpecification getEntitySpec() {
- return getSpecificationLoader().specForType(entityClass)
- .orElseThrow(() -> new IllegalStateException(String.format("Could not load specification for entity class '%s'", entityClass)));
+ return Optional.ofNullable(entityPojo);
}
private Class<?> getPrimaryKeyType() {
@@ -164,10 +143,10 @@ public class JpaEntityFacet
typedQuery.setMaxResults(range.getLimitAsInt());
}
- val spec = getEntitySpec();
+ val entitySpec = getEntitySpecification();
return Can.ofStream(
typedQuery.getResultStream()
- .map(entity -> ManagedObject.of(spec, entity)));
+ .map(entity -> ManagedObject.adaptScalar(entitySpec, entity)));
} else if (query instanceof NamedQuery) {
@@ -191,10 +170,10 @@ public class JpaEntityFacet
.forEach((paramName, paramValue) ->
namedQuery.setParameter(paramName, paramValue));
- val spec = getEntitySpec();
+ val entitySpec = getEntitySpecification();
return Can.ofStream(
namedQuery.getResultStream()
- .map(entity -> ManagedObject.of(spec, entity)));
+ .map(entity -> ManagedObject.adaptScalar(entitySpec, entity)));
}
diff --git a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
index 82a33d1151..cffab3a342 100644
--- a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
+++ b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
@@ -262,7 +262,7 @@ class DomainModelTest_usingGoodDomain {
assertEquals("inherited title", titleService.titleOf(instance));
assertEquals("inherited icon", titleService.iconNameOf(instance));
- val domainObject = ManagedObject.of(spec, instance);
+ val domainObject = ManagedObject.adaptScalar(spec, instance);
assertEquals("inherited title", domainObject.getTitle());
assertEquals("inherited icon", iconFacet.iconName(domainObject));
}
@@ -538,7 +538,7 @@ class DomainModelTest_usingGoodDomain {
val objectSpec = specificationLoader.specForTypeElseFail(ProperMemberSupport.class);
val member = objectSpec.getMemberElseFail(memberId);
- val sampleObject = ManagedObject.of(objectSpec, new ProperMemberSupport());
+ val sampleObject = ManagedObject.adaptScalar(objectSpec, new ProperMemberSupport());
assertEquals(named, member.getFriendlyName(()->sampleObject));
assertEquals(described, member.getDescription(()->sampleObject).orElse(null));
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiChoices.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiChoices.java
index d747b60c54..9608666727 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiChoices.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiChoices.java
@@ -74,13 +74,9 @@ public class SimulatedUiChoices extends HasValueValidation {
* @param choiceIndices
*/
public void simulateMultiChoiceSelect(final int ... choiceIndices) {
- val newValuePojos = choiceBox.getValue()
- .pickByIndex(choiceIndices)
- .map(ManagedObject::getPojo);
- val newValue = ManagedObject.of(
- valueSpecification,
- newValuePojos.toList());
- selectedItem.setValue(newValue);
+ val newValues = choiceBox.getValue()
+ .pickByIndex(choiceIndices);
+ selectedItem.setValue(ManagedObject.packed(valueSpecification, newValues));
}
public ManagedObject getValue() {
diff --git a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiComponent.java b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiComponent.java
index c97fce05e6..4525ca2023 100644
--- a/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiComponent.java
+++ b/regressiontests/stable-interact/src/test/java/org/apache/isis/testdomain/interact/SimulatedUiComponent.java
@@ -44,7 +44,7 @@ public class SimulatedUiComponent extends HasValueValidation {
}
public void simulateValueChange(final Object newValue) {
- value.setValue(ManagedObject.of(valueSpec, newValue));
+ value.setValue(ManagedObject.adaptScalar(valueSpec, newValue));
}
public ManagedObject getValue() {
diff --git a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
index de7f9e704a..9a4a137e4d 100644
--- a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
+++ b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
@@ -33,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.apache.isis.applib.services.metamodel.BeanSort;
import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.persistence.jdo.provider.metamodel.facets.object.datastoreidentity.JdoDatastoreIdentityFacet;
import org.apache.isis.persistence.jdo.provider.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet;
@@ -95,7 +94,7 @@ class DomainModelTest {
val entitySpec = specificationLoader.loadSpecification(JdoEntityMetaAnnotated.class);
assertEquals(BeanSort.ENTITY, entitySpec.getBeanSort());
- assertNotNull(entitySpec.getFacet(EntityFacet.class));
+ assertNotNull(entitySpec.entityFacetElseFail());
//@PersistenceCapable(identityType = IdentityType.DATASTORE)
val persistenceCapableFacet = entitySpec.getFacet(JdoPersistenceCapableFacet.class);
diff --git a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/injecting/jdo/JdoEntityInjectingTest.java b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/injecting/jdo/JdoEntityInjectingTest.java
index fe8cc62357..46a3c06cb2 100644
--- a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/injecting/jdo/JdoEntityInjectingTest.java
+++ b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/injecting/jdo/JdoEntityInjectingTest.java
@@ -71,7 +71,7 @@ class JdoEntityInjectingTest extends IsisIntegrationTestAbstract {
void init() {
// given
jdoTestFixtures.reinstall(()->kvStore.clear(JdoBook.class));
- assertInjectCountRange(3, 9); //TODO there is some injection redundancy
+ assertInjectCountRange(3, 12); //TODO there is some injection redundancy
}
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
index 1f409f9306..3589d7ae9e 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
@@ -29,7 +29,6 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.PlatformTransactionManager;
@@ -43,7 +42,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.testdomain.conf.Configuration_usingJpa;
import org.apache.isis.testdomain.jdo.JdoTestFixtures;
@@ -101,11 +99,11 @@ class JpaBootstrappingTest extends IsisIntegrationTestAbstract {
void jpaEntities_shouldBeRecognisedAsSuch() {
val productSpec = specLoader.loadSpecification(JpaProduct.class);
assertTrue(productSpec.isEntity());
- assertNotNull(productSpec.getFacet(EntityFacet.class));
+ assertNotNull(productSpec.entityFacetElseFail());
val inventorySpec = specLoader.loadSpecification(JpaInventory.class);
assertTrue(inventorySpec.isEntity());
- assertNotNull(inventorySpec.getFacet(EntityFacet.class));
+ assertNotNull(inventorySpec.entityFacetElseFail());
}
@Test @Order(1) @Rollback(false)
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
index 2cad44d6b7..f9405155ea 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
@@ -90,6 +90,8 @@ class JpaNonGeneratedStringIdEntityLifecycleTest {
repository.persist(entity.getPojo());
+ System.err.printf("entity %s%n", entity);
+
assertEquals(
EntityState.PERSISTABLE_ATTACHED,
MmEntityUtil.getEntityState(entity));
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/springdata/SpringDataJpaBootstrappingTest.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/springdata/SpringDataJpaBootstrappingTest.java
index b780d2dbe3..e9ec920458 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/springdata/SpringDataJpaBootstrappingTest.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/springdata/SpringDataJpaBootstrappingTest.java
@@ -42,7 +42,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.core.config.presets.IsisPresets;
-import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.testdomain.conf.Configuration_usingSpringDataJpa;
import org.apache.isis.testdomain.jpa.springdata.Employee;
@@ -111,7 +110,7 @@ class SpringDataJpaBootstrappingTest extends IsisIntegrationTestAbstract {
void jpaEntities_shouldBeRecognisedAsSuch() {
val productSpec = specLoader.loadSpecification(Employee.class);
assertTrue(productSpec.isEntity());
- assertNotNull(productSpec.getFacet(EntityFacet.class));
+ assertNotNull(productSpec.entityFacetElseFail());
}
@Test @Order(1) @Rollback(false)
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
index fa82d0061d..e2016a76af 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTest.java
@@ -205,7 +205,7 @@ class ValueSemanticsTest {
val spec = specLoader.specForTypeElseFail(valueMixin.getClass());
val interaction = ActionInteraction
- .start(ManagedObject.of(spec, valueMixin), "act", Where.ANYWHERE);
+ .start(ManagedObject.mixin(spec, valueMixin), "act", Where.ANYWHERE);
val pendingParams = interaction
.startParameterNegotiation()
diff --git a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
index e4c1db52e7..da62128771 100644
--- a/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
+++ b/regressiontests/stable-value/src/test/java/org/apache/isis/testdomain/value/ValueSemanticsTester.java
@@ -115,10 +115,10 @@ public class ValueSemanticsTester<T> {
val command = interactionService.currentInteractionElseFail().getCommand();
val propInteraction = PropertyInteraction
- .wrap(ManagedProperty.of(ManagedObject.of(objSpec, domainObject), prop, Where.OBJECT_FORMS));
+ .wrap(ManagedProperty.of(ManagedObject.adaptScalar(objSpec, domainObject), prop, Where.OBJECT_FORMS));
propInteraction.modifyProperty(managedProp->
- ManagedObject.of(managedProp.getElementType(), newProperyValueProvider.apply(managedProp)));
+ ManagedObject.adaptScalar(managedProp.getElementType(), newProperyValueProvider.apply(managedProp)));
probe.testCommand(context, command);
});
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
index afdebc781d..b734d06fc5 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJdo.java
@@ -227,7 +227,7 @@ extends PublishingTestFactoryAbstract {
val managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement());
val propertyModel = managedProperty.startNegotiation();
val propertySpec = managedProperty.getElementType();
- propertyModel.getValue().setValue(ManagedObject.of(propertySpec, "Book #2"));
+ propertyModel.getValue().setValue(ManagedObject.value(propertySpec, "Book #2"));
propertyModel.submit();
});
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
index 3e58308d07..ca7c5402b9 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryJpa.java
@@ -223,7 +223,7 @@ extends PublishingTestFactoryAbstract {
val managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement());
val propertyModel = managedProperty.startNegotiation();
val propertySpec = managedProperty.getElementType();
- propertyModel.getValue().setValue(ManagedObject.of(propertySpec, "Book #2"));
+ propertyModel.getValue().setValue(ManagedObject.value(propertySpec, "Book #2"));
propertyModel.submit();
});
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
index 09424fb3b2..f47b5fb5cd 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/util/interaction/DomainObjectTesterFactory.java
@@ -625,7 +625,9 @@ public class DomainObjectTesterFactory {
@SuppressWarnings("unchecked")
static void updatePojo(final ManagedValue managedValue, final UnaryOperator replacer) {
- managedValue.update(v->ManagedObject.of(v.getSpecification(), replacer.apply(v.getPojo())));
+ managedValue.update(v->ManagedObject.adaptScalar(
+ v.getSpecification(),
+ replacer.apply(v.getPojo())));
}
@SneakyThrows
@@ -1128,7 +1130,10 @@ public class DomainObjectTesterFactory {
protected Tester<T> init() {
this.objectSpecification = specificationLoader.specForTypeElseFail(domainObjectType);
- this.vm = ManagedObject.of(objectSpecification, factoryService.viewModel(domainObjectType));
+ this.vm = ManagedObject.viewmodel(
+ objectSpecification,
+ factoryService.viewModel(domainObjectType),
+ Optional.empty());
return this;
}
diff --git a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java
index 06b02e91c7..13e480f34c 100644
--- a/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java
+++ b/viewers/commons/model/src/main/java/org/apache/isis/viewer/commons/model/binding/BindingConverterForManagedObject.java
@@ -34,7 +34,7 @@ implements BindingConverter<ManagedObject, T> {
@Override
public ManagedObject toLeft(final T pojo) {
- return ManagedObject.of(getValueSpecification(), pojo);
+ return ManagedObject.value(getValueSpecification(), pojo);
}
@Override
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BooleanModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BooleanModel.java
index b903f15afb..2b0d5a5a88 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BooleanModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/BooleanModel.java
@@ -59,7 +59,7 @@ extends ChainingModel<Boolean> {
@Override
public void setObject(final Boolean value) {
- val adaptedValue = ManagedObject.of(
+ val adaptedValue = ManagedObject.value(
scalarModel().getScalarTypeSpec(),
(value==null
&& isPrimitive)
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
index eb204fc3df..bc0a884369 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ManagedObjectModel.java
@@ -27,7 +27,6 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.collections._Collections;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
import org.apache.isis.core.metamodel.object.PackedManagedObject;
@@ -83,7 +82,7 @@ extends ModelAbstract<ManagedObject> {
super.setObject(adapter);
- if(_Collections.isCollectionOrArrayOrCanType(adapter.getPojo().getClass())) {
+ if(adapter instanceof PackedManagedObject) {
setObjectCollection((PackedManagedObject)adapter);
} else {
memento = super.getMementoService().mementoForSingle(adapter);
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
index a68acc0863..44075d5f0b 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/util/PageParameterUtils.java
@@ -229,7 +229,7 @@ public class PageParameterUtils {
}
if(objSpec.isValue()) {
- return ManagedObject.of(objSpec,
+ return ManagedObject.value(objSpec,
Facets.valueSerializerElseFail(objSpec, objSpec.getCorrespondingClass())
.fromEncodedString(Format.JSON, encoded));
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
index 621dfb6fcb..e205c9a0a3 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/IsisToWicketTreeAdapter.java
@@ -259,7 +259,7 @@ class IsisToWicketTreeAdapter {
this.commonContext = commonContext;
this.factoryService = commonContext.lookupServiceElseFail(FactoryService.class);
this.pojoToAdapter = pojo ->
- ManagedObject.wrapScalar(commonContext.getSpecificationLoader(), pojo);
+ ManagedObject.adaptScalar(commonContext.getSpecificationLoader(), pojo);
}
private TreeAdapter wrappedTreeAdapter() {
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
index bbfdde5944..db3751d98c 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/services/DeepLinkServiceWicket.java
@@ -58,7 +58,7 @@ public class DeepLinkServiceWicket implements DeepLinkService {
@Override
public URI deepLinkFor(final Object domainObject) {
- final ManagedObject objectAdapter = ManagedObject.wrapScalar(specificationLoader, domainObject);
+ final ManagedObject objectAdapter = ManagedObject.adaptScalar(specificationLoader, domainObject);
final PageParameters pageParameters = PageParameterUtils.createPageParametersForObject(objectAdapter);