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/03 06:20:21 UTC
[isis] 01/01: ISIS-3202: fail early if executor result adapter has no bookmark
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch ISIS-3202_exec.not.persistent
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 3bbf6777b132cfc901648b48769e6bc3f8ffffbe
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Sep 3 08:20:14 2022 +0200
ISIS-3202: fail early if executor result adapter has no bookmark
---
.../facets/object/callbacks/CallbackFacet.java | 2 +-
.../managed/nonscalar/DataTableModel.java | 5 ++-
.../isis/core/metamodel/object/ManagedObjects.java | 26 ++++++++++++++--
.../executor/MemberExecutorServiceDefault.java | 36 ++++++++++++----------
.../factory/FactoryServiceDefault.java | 3 +-
.../publish/LifecycleCallbackNotifier.java | 2 +-
6 files changed, 48 insertions(+), 26 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacet.java
index 38ae297090..18575bf85a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacet.java
@@ -37,7 +37,7 @@ extends ImperativeFacet {
final ManagedObject object,
final Class<? extends CallbackFacet> callbackFacetType) {
- ManagedObjects.whenSpecified(object)
+ ManagedObjects.asSpecified(object)
.map(ManagedObject::getSpecification)
.flatMap(spec->spec.lookupFacet(callbackFacetType))
.ifPresent(callbackFacet->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
index 8d49908696..decb8f7e50 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/nonscalar/DataTableModel.java
@@ -46,11 +46,11 @@ import org.apache.isis.core.metamodel.interactions.managed.ActionInteraction;
import org.apache.isis.core.metamodel.interactions.managed.CollectionInteraction;
import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
import org.apache.isis.core.metamodel.interactions.managed.ManagedAction.MementoForArgs;
-import org.apache.isis.core.metamodel.object.ManagedObject;
-import org.apache.isis.core.metamodel.object.PackedManagedObject;
import org.apache.isis.core.metamodel.interactions.managed.ManagedCollection;
import org.apache.isis.core.metamodel.interactions.managed.ManagedMember;
import org.apache.isis.core.metamodel.interactions.managed.MultiselectChoices;
+import org.apache.isis.core.metamodel.object.ManagedObject;
+import org.apache.isis.core.metamodel.object.PackedManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
@@ -126,7 +126,6 @@ implements MultiselectChoices {
dataElements.getValue().stream()
//XXX future extension: filter by searchArgument
.filter(this::ignoreHidden)
- //FIXME[ISIS-3167] entities might be detached
.sorted(managedMember.getMetaModel().getElementComparator()
.orElseGet(()->(a, b)->0)) // else don't sort (no-op comparator for streams)
.map(domainObject->new DataRow(this, domainObject))
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
index 0964effb90..b74f2ea9f8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/ManagedObjects.java
@@ -78,19 +78,41 @@ public final class ManagedObjects {
/** whether has at least a spec */
public static boolean isSpecified(final @Nullable ManagedObject adapter) {
- return adapter!=null && adapter!=ManagedObject.unspecified();
+ return adapter!=null
+ && adapter!=ManagedObject.unspecified();
}
/**
* Optionally given adapter, based on whether it is specified
* (even if empty, that is, representing null.)
+ * @return SPECIFIED
*/
- public static Optional<ManagedObject> whenSpecified(final ManagedObject adapter) {
+ public static Optional<ManagedObject> asSpecified(final @Nullable ManagedObject adapter) {
return isSpecified(adapter)
? Optional.of(adapter)
: Optional.empty();
}
+ /**
+ * Optionally given adapter, based on whether it is specified and scalar (not packed)
+ * (even if empty, that is, representing null.)
+ * @return SCALAR or EMTPY
+ */
+ public static Optional<ManagedObject> asScalar(final @Nullable ManagedObject adapter) {
+ return asSpecified(adapter)
+ .filter(obj->!obj.getSpecialization().isPacked());
+ }
+
+ /**
+ * Optionally given adapter, based on whether it is specified
+ * (even if empty, that is, representing null.)
+ * @return SCALAR and NOT_EMTPY
+ */
+ public static Optional<ManagedObject> asScalarNonEmpty(final @Nullable ManagedObject adapter) {
+ return asScalar(adapter)
+ .filter(obj->!obj.getSpecialization().isEmpty());
+ }
+
/**
* whether the corresponding type can be mapped onto a REFERENCE (schema) or an Oid,
* that is, the type is 'identifiable' (aka 'referencable' or 'bookmarkable')
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 68692ac664..4a0b60dbe8 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
@@ -57,7 +57,6 @@ import org.apache.isis.core.metamodel.facets.properties.property.modify.Property
import org.apache.isis.core.metamodel.interactions.InteractionHead;
import org.apache.isis.core.metamodel.object.ManagedObject;
import org.apache.isis.core.metamodel.object.ManagedObjects;
-import org.apache.isis.core.metamodel.object.MmEntityUtil;
import org.apache.isis.core.metamodel.object.MmUnwrapUtil;
import org.apache.isis.core.metamodel.object.MmVisibilityUtil;
import org.apache.isis.core.metamodel.object.PackedManagedObject;
@@ -178,6 +177,14 @@ implements MemberExecutorService {
val returnedAdapter = objectManager.adapt(
returnedPojo, owningAction::getElementType);
+ // assert has bookmark, unless non-scalar
+ ManagedObjects.asScalarNonEmpty(returnedAdapter)
+ .filter(scalarNonEmpty->!scalarNonEmpty.getSpecialization().isOther()) // don't care
+ .ifPresent(scalarNonEmpty->{
+ _Assert.assertTrue(scalarNonEmpty.getBookmark().isPresent(), ()->String.format(
+ "bookmark required for non-empty scalars %s", scalarNonEmpty.getSpecification()));
+ });
+
// sync DTO with result
interactionDtoFactory
.updateResult(priorExecution.getDto(), owningAction, returnedAdapter);
@@ -276,27 +283,22 @@ implements MemberExecutorService {
if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) {
return;
}
-
- val entityState = MmEntityUtil.getEntityState(resultAdapter);
- //FIXME what to do with new state
+ val entityState = resultAdapter.getEntityState();
+ if(!entityState.isPersistable()) {
+ return;
+ }
if(entityState.isDetached()) {
// ensure that any still-to-be-persisted adapters get persisted to DB.
getTransactionService().flushTransaction();
}
- if(entityState.isAttached()) {
- resultAdapter.getBookmark()
- .ifPresent(bookmark->
- command.updater().setResult(Try.success(bookmark))
- );
- } else {
- if(entityState.isPersistable()) {
- log.warn("was unable to get a bookmark for the command result, "
- + "which is an entity: {}", resultAdapter);
- }
+ val entityState2 = resultAdapter.getEntityState();
+ if(!entityState2.isDetached()) {
+ val bookmark = ManagedObjects.bookmarkElseFail(resultAdapter);
+ command.updater().setResult(Try.success(bookmark));
+ return;
}
-
- // ignore all other sorts of objects
-
+ log.warn("was unable to get a bookmark for the command result, "
+ + "which is an entity: {}", resultAdapter);
}
private ManagedObject resultFilteredHonoringVisibility(
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 0e0fb5cb0b..0c028485a8 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
@@ -92,8 +92,7 @@ public class FactoryServiceDefault implements FactoryService {
if(!spec.isEntity()) {
throw _Exceptions.illegalArgument("Type '%s' is not recogniced as an entity type by the framework.",
entityClass);
- }
- objectLifecyclePublisher().onPostCreate(ManagedObject.entityDetached(spec, entityPojo));
+ } objectLifecyclePublisher().onPostCreate(ManagedObject.entity(spec, entityPojo, Optional.empty()));
return entityPojo;
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/LifecycleCallbackNotifier.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/LifecycleCallbackNotifier.java
index 20826aad27..bfc9bdf331 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/LifecycleCallbackNotifier.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/LifecycleCallbackNotifier.java
@@ -123,7 +123,7 @@ public class LifecycleCallbackNotifier {
private void postLifecycleEventIfRequired(
final ManagedObject object,
final Class<? extends LifecycleEventFacet> lifecycleEventFacetClass) {
- ManagedObjects.whenSpecified(object)
+ ManagedObjects.asSpecified(object)
.map(ManagedObject::getSpecification)
.ifPresent(spec->{