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 2019/12/09 14:08:12 UTC
[isis] branch master updated: ISIS-2158: some cleanup around domain
event action handling
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 ad4a6a1 ISIS-2158: some cleanup around domain event action handling
ad4a6a1 is described below
commit ad4a6a1f251eea18765c812b0fcf5f6422489ec8
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Dec 9 15:08:03 2019 +0100
ISIS-2158: some cleanup around domain event action handling
- move to and contain with, the complicated type inference stuff with
DomainEventHelper
---
.../isis/metamodel/facets/DomainEventHelper.java | 56 ++++-
.../invocation/ActionDomainEventFacetAbstract.java | 85 +++----
...ctionInvocationFacetForDomainEventAbstract.java | 276 ++++++++++-----------
...ionFacetForDomainEventFromActionAnnotation.java | 8 +-
...onInvocationFacetForDomainEventFromDefault.java | 9 +-
.../org/apache/isis/metamodel/util/EventUtil.java | 1 +
.../java/demoapp/dom/events/EventSubscriber.java | 5 +-
7 files changed, 221 insertions(+), 219 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/DomainEventHelper.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/DomainEventHelper.java
index b01260b..8630c74 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/DomainEventHelper.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/DomainEventHelper.java
@@ -35,7 +35,7 @@ import org.apache.isis.applib.events.domain.PropertyDomainEvent;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.metamodel.facetapi.IdentifiedHolder;
import org.apache.isis.metamodel.services.events.MetamodelEventService;
import org.apache.isis.metamodel.spec.ManagedObject;
@@ -44,6 +44,7 @@ import org.apache.isis.metamodel.spec.feature.ObjectActionParameter;
import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
+import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;
@@ -57,19 +58,52 @@ public class DomainEventHelper {
private final MetamodelEventService metamodelEventService;
- // -- postEventForAction, newActionDomainEvent
+ // -- postEventForAction
+
+ // variant using eventType and no existing event
+ public ActionDomainEvent<?> postEventForAction(
+ final AbstractDomainEvent.Phase phase,
+ @NonNull final Class<? extends ActionDomainEvent<?>> eventType,
+ final ObjectAction objectAction,
+ final IdentifiedHolder identified,
+ final ManagedObject targetAdapter,
+ final ManagedObject mixedInAdapter,
+ final ManagedObject[] argumentAdapters,
+ final Command command,
+ final ManagedObject resultAdapter) {
+
+ return postEventForAction(phase, uncheckedCast(eventType), /*existingEvent*/null, objectAction, identified,
+ targetAdapter, mixedInAdapter, argumentAdapters, command, resultAdapter);
+ }
+
+ // variant using existing event and not eventType (is derived from event)
+ public ActionDomainEvent<?> postEventForAction(
+ final AbstractDomainEvent.Phase phase,
+ @NonNull final ActionDomainEvent<?> existingEvent,
+ final ObjectAction objectAction,
+ final IdentifiedHolder identified,
+ final ManagedObject targetAdapter,
+ final ManagedObject mixedInAdapter,
+ final ManagedObject[] argumentAdapters,
+ final Command command,
+ final ManagedObject resultAdapter) {
+
+ return postEventForAction(phase,
+ uncheckedCast(existingEvent.getClass()), existingEvent, objectAction, identified,
+ targetAdapter, mixedInAdapter, argumentAdapters, command, resultAdapter);
+ }
- public <S> ActionDomainEvent<S> postEventForAction(
+ private <S> ActionDomainEvent<S> postEventForAction(
final AbstractDomainEvent.Phase phase,
final Class<? extends ActionDomainEvent<S>> eventType,
- final ActionDomainEvent<S> existingEvent,
- final ObjectAction objectAction,
- final IdentifiedHolder identified,
- final ManagedObject targetAdapter,
- final ManagedObject mixedInAdapter,
- final ManagedObject[] argumentAdapters,
- final Command command,
- final ManagedObject resultAdapter) {
+ final ActionDomainEvent<S> existingEvent,
+ final ObjectAction objectAction,
+ final IdentifiedHolder identified,
+ final ManagedObject targetAdapter,
+ final ManagedObject mixedInAdapter,
+ final ManagedObject[] argumentAdapters,
+ final Command command,
+ final ManagedObject resultAdapter) {
_Assert.assertTypeIsInstanceOf(eventType, ActionDomainEvent.class);
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
index 47c61fa..a07552e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionDomainEventFacetAbstract.java
@@ -27,10 +27,7 @@ import org.apache.isis.applib.services.wrapper.events.InteractionEvent;
import org.apache.isis.applib.services.wrapper.events.UsabilityEvent;
import org.apache.isis.applib.services.wrapper.events.ValidityEvent;
import org.apache.isis.applib.services.wrapper.events.VisibilityEvent;
-import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.base._Tuples.Tuple2;
-import org.apache.isis.metamodel.facetapi.Facet;
import org.apache.isis.metamodel.facetapi.FacetHolder;
import org.apache.isis.metamodel.facetapi.IdentifiedHolder;
import org.apache.isis.metamodel.facets.DomainEventHelper;
@@ -44,23 +41,23 @@ import org.apache.isis.metamodel.interactions.VisibilityContext;
import org.apache.isis.metamodel.spec.ManagedObject;
import org.apache.isis.metamodel.spec.feature.ObjectAction;
+import lombok.Getter;
+import lombok.Setter;
+
public abstract class ActionDomainEventFacetAbstract
-extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
+extends SingleClassValueFacetAbstract
+implements ActionDomainEventFacet {
- private Class<? extends ActionDomainEvent<?>> eventType;
+ @Getter @Setter private Class<? extends ActionDomainEvent<?>> eventType;
private final TranslationService translationService;
private final String translationContext;
-
- static Class<? extends Facet> type() {
- return ActionDomainEventFacet.class;
- }
-
private final DomainEventHelper domainEventHelper;
public ActionDomainEventFacetAbstract(
final Class<? extends ActionDomainEvent<?>> eventType,
- final FacetHolder holder) {
- super(type(), holder, eventType);
+ final FacetHolder holder) {
+
+ super(ActionDomainEventFacet.class, holder, eventType);
setEventType(eventType);
this.translationService = getTranslationService();
@@ -74,28 +71,14 @@ extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
public Class<?> value() {
return eventType;
}
-
- protected Class<?> eventType() {
- return eventType;
- }
-
- public <S> Class<? extends ActionDomainEvent<S>> getEventType() {
- return _Casts.uncheckedCast(eventType);
- }
- public void setEventType(final Class<? extends ActionDomainEvent<?>> eventType) {
- _Assert.assertTypeIsInstanceOf(eventType, ActionDomainEvent.class);
- this.eventType = eventType;
- }
-
-
-
+
@Override
public String hides(final VisibilityContext<? extends VisibilityEvent> ic) {
final ActionDomainEvent<?> event =
domainEventHelper.postEventForAction(
AbstractDomainEvent.Phase.HIDE,
- getEventType(), null,
+ getEventType(),
actionFrom(ic), getIdentified(),
ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic),
null,
@@ -112,7 +95,7 @@ extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
final ActionDomainEvent<?> event =
domainEventHelper.postEventForAction(
AbstractDomainEvent.Phase.DISABLE,
- getEventType(), null,
+ getEventType(),
actionFrom(ic), getIdentified(),
ic.getTarget(), ic.getMixedIn(), argumentAdaptersFrom(ic),
null,
@@ -128,26 +111,6 @@ extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
return null;
}
- private static ObjectAction actionFrom(final InteractionContext<?> ic) {
- if(!(ic instanceof ActionInteractionContext)) {
- throw new IllegalStateException(
- "Expecting ic to be of type ActionInteractionContext, instead was: " + ic);
- }
- return ((ActionInteractionContext) ic).getObjectAction();
- }
-
- private static ManagedObject[] argumentAdaptersFrom(final InteractionContext<? extends InteractionEvent> ic) {
- final Tuple2<Integer, ManagedObject> contributee = ic.getContributeeWithParamIndex();
-
- if(contributee!=null) {
- int paramIndex = contributee.get_1();
- ManagedObject adapter = contributee.get_2();
- return new ManagedObject[]{paramIndex==0 ? adapter : null};
- }
-
- return null;
- }
-
@Override
public String invalidates(final ValidityContext<? extends ValidityEvent> ic) {
@@ -155,7 +118,7 @@ extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
final ActionDomainEvent<?> event =
domainEventHelper.postEventForAction(
AbstractDomainEvent.Phase.VALIDATE,
- getEventType(), null,
+ getEventType(),
actionFrom(ic), getIdentified(),
ic.getTarget(), ic.getMixedIn(), aic.getArgs(),
null,
@@ -170,5 +133,27 @@ extends SingleClassValueFacetAbstract implements ActionDomainEventFacet {
return null;
}
+
+ // -- HELPER
+
+ private static ObjectAction actionFrom(final InteractionContext<?> ic) {
+ if(!(ic instanceof ActionInteractionContext)) {
+ throw new IllegalStateException(
+ "Expecting ic to be of type ActionInteractionContext, instead was: " + ic);
+ }
+ return ((ActionInteractionContext) ic).getObjectAction();
+ }
+
+ private static ManagedObject[] argumentAdaptersFrom(final InteractionContext<? extends InteractionEvent> ic) {
+ final Tuple2<Integer, ManagedObject> contributee = ic.getContributeeWithParamIndex();
+
+ if(contributee!=null) {
+ int paramIndex = contributee.get_1();
+ ManagedObject adapter = contributee.get_2();
+ return new ManagedObject[]{paramIndex==0 ? adapter : null};
+ }
+
+ return null;
+ }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 86d5e28..04b3901 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -21,7 +21,6 @@ package org.apache.isis.metamodel.facets.actions.action.invocation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -42,6 +41,7 @@ import org.apache.isis.applib.services.command.Command;
import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.applib.services.command.spi.CommandService;
import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.iactn.Interaction.ActionInvocation;
import org.apache.isis.applib.services.iactn.InteractionContext;
import org.apache.isis.applib.services.metamodel.MetaModelService;
import org.apache.isis.applib.services.metamodel.MetaModelService.Mode;
@@ -70,29 +70,28 @@ import org.apache.isis.metamodel.spec.ObjectSpecification;
import org.apache.isis.metamodel.spec.feature.ObjectAction;
import org.apache.isis.schema.ixn.v1.ActionInvocationDto;
-import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
-
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
import lombok.val;
public abstract class ActionInvocationFacetForDomainEventAbstract
extends ActionInvocationFacetAbstract
implements ImperativeFacet {
+ @Getter private final Class<? extends ActionDomainEvent<?>> eventType;
private final Method method;
- private final ObjectSpecification onType;
- private final ObjectSpecification returnType;
-
+ @Getter(onMethod = @__(@Override)) private final ObjectSpecification onType;
+ @Getter(onMethod = @__(@Override)) private final ObjectSpecification returnType;
private final ServiceRegistry serviceRegistry;
-
- private final Class<? extends ActionDomainEvent<?>> eventType;
private final DomainEventHelper domainEventHelper;
public ActionInvocationFacetForDomainEventAbstract(
final Class<? extends ActionDomainEvent<?>> eventType,
- final Method method,
- final ObjectSpecification onType,
- final ObjectSpecification returnType,
- final FacetHolder holder) {
+ final Method method,
+ final ObjectSpecification onType,
+ final ObjectSpecification returnType,
+ final FacetHolder holder) {
+
super(holder);
this.eventType = eventType;
this.method = method;
@@ -117,17 +116,6 @@ implements ImperativeFacet {
}
@Override
- public ObjectSpecification getReturnType() {
- return returnType;
- }
-
- @Override
- public ObjectSpecification getOnType() {
- return onType;
- }
-
-
- @Override
public ManagedObject invoke(
final ObjectAction owningAction,
final ManagedObject targetAdapter,
@@ -137,14 +125,31 @@ implements ImperativeFacet {
final ManagedObject executionResult =
getTransactionService().executeWithinTransaction(()->
- doInvoke(owningAction, targetAdapter, mixedInAdapter, argumentAdapters, interactionInitiatedBy));
+ doInvoke(owningAction, targetAdapter, mixedInAdapter, argumentAdapters,
+ interactionInitiatedBy));
//PersistableTypeGuard.instate(executionResult);
return executionResult;
}
- ManagedObject doInvoke(
+ @Override
+ public void appendAttributesTo(final Map<String, Object> attributeMap) {
+ super.appendAttributesTo(attributeMap);
+ ImperativeFacet.Util.appendAttributesTo(this, attributeMap);
+ attributeMap.put("onType", onType);
+ attributeMap.put("returnType", returnType);
+ attributeMap.put("eventType", eventType);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+ // -- HELPER
+
+ private ManagedObject doInvoke(
final ObjectAction owningAction,
final ManagedObject targetAdapter,
final ManagedObject mixedInAdapter,
@@ -192,92 +197,9 @@ implements ImperativeFacet {
new Interaction.ActionInvocation(interaction, actionId, mixinElseRegularPojo, argumentPojos, targetMember,
targetClass);
final Interaction.MemberExecutor<Interaction.ActionInvocation> callable =
- new Interaction.MemberExecutor<Interaction.ActionInvocation>() {
-
-
- @Override
- public Object execute(final Interaction.ActionInvocation currentExecution) {
-
-
- try {
-
- // update the current execution with the DTO (memento)
- final ActionInvocationDto invocationDto =
- getInteractionDtoServiceInternal().asActionInvocationDto(
- owningAction, mixinElseRegularAdapter, argumentAdapterList);
- currentExecution.setDto(invocationDto);
-
-
- // set the startedAt (and update command if this is the top-most member execution)
- // (this isn't done within Interaction#execute(...) because it requires the DTO
- // to have been set on the current execution).
- final Timestamp startedAt = getClockService().nowAsJavaSqlTimestamp();
- execution.setStartedAt(startedAt);
- if(command.getStartedAt() == null) {
- command.internal().setStartedAt(startedAt);
- }
-
-
- // ... post the executing event
-
- final ActionDomainEvent<?> event =
- domainEventHelper.postEventForAction(
- AbstractDomainEvent.Phase.EXECUTING,
- getEventType(), null,
- owningAction, owningAction,
- targetAdapter, mixedInAdapter, argumentAdapters,
- command,
- null);
-
- // set event onto the execution
- currentExecution.setEvent(event);
-
- // invoke method
- val resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
- ManagedObject resultAdapterPossiblyCloned = cloneIfViewModelCloneable(resultPojo, mixinElseRegularAdapter);
-
- // ... post the executed event
-
- //[ahuber] javac (jdk-8) won't compile this without the cast '(ActionDomainEvent)event',
- // while the eclipse compiler does ...
- domainEventHelper.postEventForAction(
- AbstractDomainEvent.Phase.EXECUTED,
- getEventType(), (ActionDomainEvent)event,
- owningAction, owningAction, targetAdapter, mixedInAdapter, argumentAdapters,
- command,
- resultAdapterPossiblyCloned);
-
- final Object returnValue = event.getReturnValue();
- if(returnValue != resultPojo) {
- resultAdapterPossiblyCloned = cloneIfViewModelCloneable(returnValue, mixinElseRegularAdapter);
- }
- return ManagedObject.unwrapPojo(resultAdapterPossiblyCloned);
-
- } catch (Exception e) {
-
- final Consumer<RecoverableException> recovery = recoverableException->{
-
- if (!getTransactionState().canCommit()) {
- // something severe has happened to the underlying transaction;
- // so escalate this exception to be non-recoverable
- final Throwable recoverableExceptionCause = recoverableException.getCause();
- Throwable nonRecoverableCause = recoverableExceptionCause != null
- ? recoverableExceptionCause
- : recoverableException;
-
- // trim to first 300 chars
- final String message = trim(nonRecoverableCause.getMessage(), 300);
-
- throw new NonRecoverableException(message, nonRecoverableCause);
- }
- };
-
- return ThrowableExtensions.handleInvocationException(e, method.getName(), recovery);
- }
-
-
- }
- };
+ new DomainEventMemberExecutor(
+ argumentAdapters, targetAdapter, argumentAdapterList, command, owningAction,
+ mixinElseRegularAdapter, mixedInAdapter, execution);
// sets up startedAt and completedAt on the execution, also manages the execution call graph
interaction.execute(callable, execution);
@@ -296,7 +218,6 @@ implements ImperativeFacet {
: new RuntimeException(executionExceptionIfAny);
}
-
final Object returnedPojo = priorExecution.getReturned();
returnedAdapter = getObjectManager().adapt(returnedPojo);
@@ -304,17 +225,13 @@ implements ImperativeFacet {
getInteractionDtoServiceInternal()
.updateResult(priorExecution.getDto(), owningAction, returnedPojo);
-
// update Command (if required)
setCommandResultIfEntity(command, returnedAdapter);
// publish (if not a contributed association, query-only mixin)
final PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
if (publishedActionFacet != null) {
-
- getPublishingServiceInternal().publishAction(
- priorExecution
- );
+ getPublishingServiceInternal().publishAction(priorExecution);
}
}
@@ -337,7 +254,7 @@ implements ImperativeFacet {
return message;
}
- protected Object invokeMethodElseFromCache(
+ private Object invokeMethodElseFromCache(
final ManagedObject targetAdapter, final ManagedObject[] arguments)
throws IllegalAccessException, InvocationTargetException {
@@ -362,7 +279,7 @@ implements ImperativeFacet {
}
}
- protected ManagedObject cloneIfViewModelCloneable(
+ private ManagedObject cloneIfViewModelCloneable(
final Object resultPojo,
final ManagedObject targetAdapter) {
@@ -391,7 +308,7 @@ implements ImperativeFacet {
}
- protected void setCommandResultIfEntity(final Command command, final ManagedObject resultAdapter) {
+ private void setCommandResultIfEntity(final Command command, final ManagedObject resultAdapter) {
if(command.getResult() != null) {
// don't trample over any existing result, eg subsequent mixins.
return;
@@ -429,7 +346,7 @@ implements ImperativeFacet {
return serviceRegistry.lookupServiceElseFail(BookmarkService.class);
}
- protected ManagedObject filteredIfRequired(
+ private ManagedObject filteredIfRequired(
final ManagedObject resultAdapter,
final InteractionInitiatedBy interactionInitiatedBy) {
@@ -471,28 +388,14 @@ implements ImperativeFacet {
}
}
- public <S> Class<? extends ActionDomainEvent<S>> getEventType() {
- return uncheckedCast(eventType);
- }
-
private static Object unwrap(final ManagedObject adapter) {
return adapter == null ? null : adapter.getPojo();
}
-
- @Override
- protected String toStringValues() {
- return "method=" + method;
- }
-
-
-
- // /////////////////////////////////////////////////////////
- // Dependencies (looked up)
- // /////////////////////////////////////////////////////////
-
+
private CommandContext getCommandContext() {
return serviceRegistry.lookupServiceElseFail(CommandContext.class);
}
+
private InteractionContext getInteractionContext() {
return serviceRegistry.lookupServiceElseFail(InteractionContext.class);
}
@@ -516,18 +419,99 @@ implements ImperativeFacet {
private InteractionDtoServiceInternal getInteractionDtoServiceInternal() {
return serviceRegistry.lookupServiceElseFail(InteractionDtoServiceInternal.class);
}
+
+ @RequiredArgsConstructor
+ private final class DomainEventMemberExecutor
+ implements Interaction.MemberExecutor<Interaction.ActionInvocation> {
+
+ private final ManagedObject[] argumentAdapters;
+ private final ManagedObject targetAdapter;
+ private final List<ManagedObject> argumentAdapterList;
+ private final Command command;
+ private final ObjectAction owningAction;
+ private final ManagedObject mixinElseRegularAdapter;
+ private final ManagedObject mixedInAdapter;
+ private final ActionInvocation execution;
+
+ @Override
+ public Object execute(final Interaction.ActionInvocation currentExecution) {
+
+ try {
+
+ // update the current execution with the DTO (memento)
+ val invocationDto = getInteractionDtoServiceInternal()
+ .asActionInvocationDto(owningAction, mixinElseRegularAdapter, argumentAdapterList);
+
+ currentExecution.setDto(invocationDto);
+
+
+ // set the startedAt (and update command if this is the top-most member execution)
+ // (this isn't done within Interaction#execute(...) because it requires the DTO
+ // to have been set on the current execution).
+ val startedAt = getClockService().nowAsJavaSqlTimestamp();
+ execution.setStartedAt(startedAt);
+ if(command.getStartedAt() == null) {
+ command.internal().setStartedAt(startedAt);
+ }
- // /////////////////////////////////////////////////////////
- // Dependencies (from constructor)
- // /////////////////////////////////////////////////////////
+ // ... post the executing event
+ //compiler: cannot use val here, because initializer expression does not have a representable type
+ final ActionDomainEvent<?> actionDomainEvent = domainEventHelper.postEventForAction(
+ AbstractDomainEvent.Phase.EXECUTING,
+ getEventType(),
+ owningAction, owningAction,
+ targetAdapter, mixedInAdapter, argumentAdapters,
+ command,
+ null);
+
+ // set event onto the execution
+ currentExecution.setEvent(actionDomainEvent);
+
+ // invoke method
+ val resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
+ ManagedObject resultAdapterPossiblyCloned =
+ cloneIfViewModelCloneable(resultPojo, mixinElseRegularAdapter);
+
+ // ... post the executed event
+
+ domainEventHelper.postEventForAction(
+ AbstractDomainEvent.Phase.EXECUTED,
+ actionDomainEvent,
+ owningAction, owningAction, targetAdapter, mixedInAdapter, argumentAdapters,
+ command,
+ resultAdapterPossiblyCloned);
+
+ final Object returnValue = actionDomainEvent.getReturnValue();
+ if(returnValue != resultPojo) {
+ resultAdapterPossiblyCloned =
+ cloneIfViewModelCloneable(returnValue, mixinElseRegularAdapter);
+ }
+ return ManagedObject.unwrapPojo(resultAdapterPossiblyCloned);
+ } catch (Exception e) {
- @Override public void appendAttributesTo(final Map<String, Object> attributeMap) {
- super.appendAttributesTo(attributeMap);
- ImperativeFacet.Util.appendAttributesTo(this, attributeMap);
- attributeMap.put("onType", onType);
- attributeMap.put("returnType", returnType);
- attributeMap.put("eventType", eventType);
+ final Consumer<RecoverableException> recovery = recoverableException->{
+
+ if (!getTransactionState().canCommit()) {
+ // something severe has happened to the underlying transaction;
+ // so escalate this exception to be non-recoverable
+ final Throwable recoverableExceptionCause = recoverableException.getCause();
+ Throwable nonRecoverableCause = recoverableExceptionCause != null
+ ? recoverableExceptionCause
+ : recoverableException;
+
+ // trim to first 300 chars
+ final String message = trim(nonRecoverableCause.getMessage(), 300);
+
+ throw new NonRecoverableException(message, nonRecoverableCause);
+ }
+ };
+
+ return ThrowableExtensions.handleInvocationException(e, method.getName(), recovery);
+ }
+
+
+ }
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromActionAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromActionAnnotation.java
index a689868..b03b081 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromActionAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromActionAnnotation.java
@@ -30,10 +30,10 @@ extends ActionInvocationFacetForDomainEventAbstract {
public ActionInvocationFacetForDomainEventFromActionAnnotation(
final Class<? extends ActionDomainEvent<?>> eventType,
- final Method method,
- final ObjectSpecification onType,
- final ObjectSpecification returnType,
- final FacetHolder holder) {
+ final Method method,
+ final ObjectSpecification onType,
+ final ObjectSpecification returnType,
+ final FacetHolder holder) {
super(eventType, method, onType, returnType, holder);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromDefault.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromDefault.java
index 3e505e7..f4b67d6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventFromDefault.java
@@ -30,10 +30,11 @@ extends ActionInvocationFacetForDomainEventAbstract {
public ActionInvocationFacetForDomainEventFromDefault(
final Class<? extends ActionDomainEvent<?>> eventType,
- final Method method,
- final ObjectSpecification onType,
- final ObjectSpecification returnType,
- final FacetHolder holder) {
+ final Method method,
+ final ObjectSpecification onType,
+ final ObjectSpecification returnType,
+ final FacetHolder holder) {
+
super(eventType, method, onType, returnType, holder);
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/metamodel/util/EventUtil.java b/core/metamodel/src/main/java/org/apache/isis/metamodel/util/EventUtil.java
index f777034..83c4e73 100644
--- a/core/metamodel/src/main/java/org/apache/isis/metamodel/util/EventUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/metamodel/util/EventUtil.java
@@ -29,6 +29,7 @@ public final class EventUtil {
final Class<? extends T> noopClass,
final Class<? extends T> defaultClass,
final boolean configurationPropertyValue) {
+
if (noopClass.isAssignableFrom(eventType)) {
return false;
}
diff --git a/examples/demo/src/main/java/demoapp/dom/events/EventSubscriber.java b/examples/demo/src/main/java/demoapp/dom/events/EventSubscriber.java
index a3abb62..e7f684e 100644
--- a/examples/demo/src/main/java/demoapp/dom/events/EventSubscriber.java
+++ b/examples/demo/src/main/java/demoapp/dom/events/EventSubscriber.java
@@ -24,14 +24,11 @@ import javax.inject.Named;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.events.domain.AbstractDomainEvent;
import org.apache.isis.applib.services.eventbus.EventBusService;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.springframework.stereotype.Service;
import static demoapp.utils.DemoUtils.emphasize;