You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2016/04/22 11:47:48 UTC
[13/14] isis git commit: ISIS-1374: moved setupXxx functionality out
of ActionInvocationFacet,
and into ObjectActionDefault. Removed duplication with ObjectActionMixedIn and
ObjectActionContributee.
ISIS-1374: moved setupXxx functionality out of ActionInvocationFacet, and into ObjectActionDefault. Removed duplication with ObjectActionMixedIn and ObjectActionContributee.
Also:
- removed unnecessary guards for CommandContext or Command being null (they never will)
- removed (after all) the idea of CommandMento
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/46089a20
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/46089a20
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/46089a20
Branch: refs/heads/ISIS-1291
Commit: 46089a2037e829f1b387a78b17f2e3a1d73cc923
Parents: 6da1e31
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Apr 22 09:34:20 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Apr 22 09:34:20 2016 +0100
----------------------------------------------------------------------
...onInvocationFacetForDomainEventAbstract.java | 525 +++++++++----------
.../PropertySetterFacetViaModifyMethod.java | 36 +-
.../services/command/CommandMementoService.java | 4 +-
.../metamodel/spec/feature/ObjectAction.java | 18 +-
.../specimpl/ObjectActionContributee.java | 55 +-
.../specimpl/ObjectActionDefault.java | 190 ++++++-
.../specimpl/ObjectActionMixedIn.java | 109 +---
.../background/BackgroundServiceDefault.java | 18 +-
8 files changed, 504 insertions(+), 451 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index 99f0ca4..bac5458 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -34,18 +34,18 @@ import org.slf4j.LoggerFactory;
import org.apache.isis.applib.NonRecoverableException;
import org.apache.isis.applib.RecoverableException;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.annotation.InvokedOn;
import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.services.actinvoc.ActionInvocationContext;
-import org.apache.isis.applib.services.background.ActionInvocationMemento;
import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
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.eventbus.AbstractDomainEvent;
import org.apache.isis.applib.services.eventbus.ActionDomainEvent;
+import org.apache.isis.applib.services.metamodel.MetaModelService2;
import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
+import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -62,21 +62,16 @@ import org.apache.isis.core.metamodel.facets.DomainEventHelper;
import org.apache.isis.core.metamodel.facets.ImperativeFacet;
import org.apache.isis.core.metamodel.facets.actcoll.typeof.ElementSpecificationProviderFromTypeOfFacet;
import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
-import org.apache.isis.core.metamodel.facets.actions.bulk.BulkFacet;
-import org.apache.isis.core.metamodel.facets.actions.command.CommandFacet;
import org.apache.isis.core.metamodel.facets.actions.publish.PublishedActionFacet;
import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFacet;
import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
-import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.specloader.ReflectiveActionException;
import org.apache.isis.core.metamodel.transactions.TransactionState;
import org.apache.isis.core.metamodel.transactions.TransactionStateProvider;
-import org.apache.isis.schema.cmd.v1.CommandMementoDto;
-import org.apache.isis.schema.utils.CommandMementoDtoUtils;
public abstract class ActionInvocationFacetForDomainEventAbstract
extends ActionInvocationFacetAbstract
@@ -196,7 +191,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
final InteractionInitiatedBy interactionInitiatedBy) {
final CommandContext commandContext = getCommandContext();
- final Command command = commandContext != null ? commandContext.getCommand() : null;
+ final Command command = commandContext.getCommand();
// ... post the executing event
final ActionDomainEvent<?> event =
@@ -207,214 +202,55 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
command,
null);
- // ... invoke the action
- InvocationResult result1;
-
- try {
-
- final Object[] executionParameters = new Object[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- executionParameters[i] = unwrap(arguments[i]);
- }
-
- final Object targetPojo = unwrap(targetAdapter);
-
- final BulkFacet bulkFacet = getFacetHolder().getFacet(BulkFacet.class);
- if (bulkFacet != null) {
- final ActionInvocationContext actionInvocationContext = getActionInvocationContext();
- if (actionInvocationContext != null &&
- actionInvocationContext.getInvokedOn() == null) {
-
- actionInvocationContext.setInvokedOn(InvokedOn.OBJECT);
- actionInvocationContext.setDomainObjects(Collections.singletonList(targetPojo));
- }
-
- final Bulk.InteractionContext bulkInteractionContext = getBulkInteractionContext();
-
- if (bulkInteractionContext != null &&
- bulkInteractionContext.getInvokedAs() == null) {
-
- bulkInteractionContext.setInvokedAs(Bulk.InteractionContext.InvokedAs.REGULAR);
- actionInvocationContext.setDomainObjects(Collections.singletonList(targetPojo));
- }
- }
-
- if(command != null && command.getExecutor() == Command.Executor.USER && owningAction != null) {
-
- if(command.getTarget() != null) {
- // already set up by a ObjectActionContributee or edit form;
- // don't overwrite
- } else {
- command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
- command.setTargetAction(CommandUtil.targetActionNameFor(owningAction));
- command.setArguments(CommandUtil.argDescriptionFor(owningAction, arguments));
-
- final Bookmark targetBookmark = CommandUtil.bookmarkFor(targetAdapter);
- command.setTarget(targetBookmark);
- }
-
- if(Command.ACTION_IDENTIFIER_FOR_EDIT.equals(command.getMemberIdentifier())) {
- // special case for edit properties
- } else {
-
- if(command.getMemberIdentifier() == null) {
- // any contributed/mixin actions will fire after the main action
- // the guard here prevents them from trashing the command's memberIdentifier
- command.setMemberIdentifier(CommandUtil.actionIdentifierFor(owningAction));
- }
-
- if(command.getMemento() == null) {
- // similarly, guard here to deal with subsequent or prior contributed/mixin actions.
-
- final CommandMementoService commandMementoService = getCommandMementoService();
-
- final Object targetObject = unwrap(targetAdapter);
- final Object[] args = CommandUtil.objectsFor(arguments);
-
- final CommandMementoDto dto = commandMementoService.asCommandMemento(
- Collections.singletonList(targetAdapter),
- owningAction, arguments);
-
- if(dto != null) {
- // the default implementation will always return a dto. The guard is to allow
- // for the default implementation to be replaced with a version that returns null
- // allowing a fallback to the original API (using ActionInvocationMemento rather than
- // CommandMementoDto).
- final String mementoXml = CommandMementoDtoUtils.toXml(dto);
- command.setMemento(mementoXml);
- } else {
-
- // fallback to old behaviour
- ActionInvocationMemento aim = commandMementoService
- .asActionInvocationMemento(method, targetObject, args);
- if(aim != null) {
- command.setMemento(aim.asMementoString());
-
- } else {
- String actionIdentifier = owningAction.getIdentifier().toClassAndNameIdentityString();
- throw new IsisException(
- "Unable to build memento for action " + actionIdentifier);
- }
- }
- }
- }
-
- // copy over the command execution 'context' (if available)
- final CommandFacet commandFacet = getFacetHolder().getFacet(CommandFacet.class);
- if(commandFacet != null && !commandFacet.isDisabled()) {
- command.setExecuteIn(commandFacet.executeIn());
- command.setPersistence(commandFacet.persistence());
- } else {
- // if no facet, assume do want to execute right now, but only persist (eventually) if hinted.
- command.setExecuteIn(org.apache.isis.applib.annotation.Command.ExecuteIn.FOREGROUND);
- command.setPersistence(org.apache.isis.applib.annotation.Command.Persistence.IF_HINTED);
- }
- }
+ final InvocationResult invocationResult = invoke(owningAction, targetAdapter, arguments);
+ final ObjectAdapter invocationResultAdapter = invocationResult.getAdapter();
- ObjectAdapter resultAdapter;
+ // ... post the executed event
+ if (invocationResult.getWhetherInvoked()) {
+ // perhaps the Action was not properly invoked (i.e. an exception was raised).
+ // If invoked ok, then post to the event bus
+ domainEventHelper.postEventForAction(
+ AbstractDomainEvent.Phase.EXECUTED,
+ eventType, verify(event),
+ owningAction, targetAdapter, arguments,
+ command,
+ invocationResultAdapter);
+ }
- if( command != null &&
- command.getExecutor() == Command.Executor.USER &&
- command.getExecuteIn() == org.apache.isis.applib.annotation.Command.ExecuteIn.BACKGROUND) {
+ if (invocationResultAdapter == null) {
+ return null;
+ }
- // deal with background commands
+ return filteredIfRequired(invocationResultAdapter, interactionInitiatedBy);
- // persist command so can be this command can be in the 'background'
- final CommandService commandService = getCommandService();
- if (!commandService.persistIfPossible(command)) {
- throw new IsisException(
- "Unable to schedule action '"
- + owningAction.getIdentifier().toClassAndNameIdentityString() + "' to run in background: "
- + "CommandService does not support persistent commands " );
- }
- resultAdapter = getAdapterManager().adapterFor(command);
+ }
- } else {
+ protected InvocationResult invoke(
+ final ObjectAction owningAction,
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments) {
- // otherwise, go ahead and execute action in the 'foreground'
- if(command != null) {
- command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
- }
+ final CommandContext commandContext = getCommandContext();
+ final Command command = commandContext.getCommand();
- final ActionSemanticsFacet semanticsFacet = getFacetHolder().getFacet(ActionSemanticsFacet.class);
- final boolean cacheable = semanticsFacet != null && semanticsFacet.value().isSafeAndRequestCacheable();
-
- Object result11;
- if(cacheable) {
- final QueryResultsCache queryResultsCache = getQueryResultsCache();
- final Object[] targetPojoPlusExecutionParameters = ArrayExtensions.appendT(executionParameters, targetPojo);
- result11 = queryResultsCache.execute(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- return method.invoke(targetPojo, executionParameters);
- }
- }, targetPojo.getClass(), method.getName(), targetPojoPlusExecutionParameters);
- } else {
- result11 = method.invoke(targetPojo, executionParameters);
- }
+ try {
+ setupActionInvocationContext(owningAction, targetAdapter);
- if (LOG.isDebugEnabled()) {
- LOG.debug(" action result " + result11);
- }
- if (result11 == null) {
-
- if(targetAdapter.getSpecification().isViewModelCloneable(targetAdapter)) {
- // if this was a void method on cloneable view model, then (to save boilerplate in the domain)
- // automatically do the clone and return the clone instead.
- final ViewModelFacet facet1 = targetAdapter.getSpecification().getFacet(ViewModelFacet.class);
- final Object clone = facet1.clone(targetAdapter.getObject());
- final ObjectAdapter clonedAdapter = getAdapterManager().adapterFor(clone);
-
- resultAdapter = clonedAdapter;
-
- } else {
- resultAdapter = null;
- }
-
- } else {
-
- resultAdapter = getAdapterManager().adapterFor(result11);
-
- if(resultAdapter.getSpecification().isViewModelCloneable(resultAdapter)) {
- // if the object returned is cloneable, then
- // (to save boilerplate in the domain) automatically do the clone.
- final ViewModelFacet facet1 = resultAdapter.getSpecification().getFacet(ViewModelFacet.class);
- result11 = facet1.clone(result11);
- resultAdapter = getAdapterManager().adapterFor(result11);
- }
-
-
- // copy over TypeOfFacet if required
- final TypeOfFacet typeOfFacet = getFacetHolder().getFacet(TypeOfFacet.class);
- resultAdapter.setElementSpecificationProvider(ElementSpecificationProviderFromTypeOfFacet.createFrom(typeOfFacet));
-
- if(command != null) {
- if(!resultAdapter.getSpecification().containsDoOpFacet(ViewModelFacet.class)) {
- final Bookmark bookmark = CommandUtil.bookmarkFor(resultAdapter);
- command.setResult(bookmark);
- }
- }
-
- if(currentInvocation.get() == null) {
- final PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
- if(publishedActionFacet != null) {
- currentInvocation.set(new CurrentInvocation(targetAdapter, owningAction, getIdentified(),
- arguments, resultAdapter, command));
- }
- }
- }
+ owningAction.setupCommand(targetAdapter, arguments);
- }
+ ObjectAdapter resultAdapter = invokeThruCommand(owningAction, targetAdapter, arguments, command);
- result1 = InvocationResult.forActionThatReturned(resultAdapter);
+ return InvocationResult.forActionThatReturned(resultAdapter);
} catch (final IllegalArgumentException e) {
throw e;
} catch (final InvocationTargetException e) {
final Throwable targetException = e.getTargetException();
if (targetException instanceof IllegalStateException) {
- throw new ReflectiveActionException("IllegalStateException thrown while executing " + method + " " + targetException.getMessage(), targetException);
+ throw new ReflectiveActionException( String.format(
+ "IllegalStateException thrown while executing %s %s",
+ method, targetException.getMessage()), targetException);
}
if(targetException instanceof RecoverableException) {
if (!getTransactionState().canCommit()) {
@@ -424,13 +260,7 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
Throwable nonRecoverableCause = targetExceptionCause != null? targetExceptionCause: targetException;
// trim to first 300 chars
- String message = nonRecoverableCause.getMessage();
- if(!Strings.isNullOrEmpty(message)) {
- message = message.substring(0, Math.min(message.length(), 300));
- if(message.length() == 300) {
- message += " ...";
- }
- }
+ final String message = trim(nonRecoverableCause.getMessage(), 300);
throw new NonRecoverableException(message, nonRecoverableCause);
}
@@ -439,63 +269,236 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
ThrowableExtensions.throwWithinIsisException(e, "Exception executing " + method);
// Action was not invoked (an Exception was thrown)
- result1 = InvocationResult.forActionNotInvoked();
+ return InvocationResult.forActionNotInvoked();
+
} catch (final IllegalAccessException e) {
throw new ReflectiveActionException("Illegal access of " + method, e);
}
- final InvocationResult invocationResult = result1;
- final ObjectAdapter invocationResultAdapter = invocationResult.getAdapter();
+ }
- // ... post the executed event
- if (invocationResult.getWhetherInvoked()) {
- // perhaps the Action was not properly invoked (i.e. an exception was raised).
- // If invoked ok, then post to the event bus
- domainEventHelper.postEventForAction(
- AbstractDomainEvent.Phase.EXECUTED,
- eventType, verify(event),
- owningAction, targetAdapter, arguments,
- command,
- invocationResultAdapter);
+ private static String trim(String message, final int maxLen) {
+ if(!Strings.isNullOrEmpty(message)) {
+ message = message.substring(0, Math.min(message.length(), maxLen));
+ if(message.length() == maxLen) {
+ message += " ...";
+ }
}
+ return message;
+ }
- if (invocationResultAdapter == null) {
- return null;
+ protected void setupActionInvocationContext(
+ final ObjectAction owningAction,
+ final ObjectAdapter targetAdapter) {
+
+ owningAction.setupActionInvocationContext(targetAdapter);
+ }
+
+ protected ObjectAdapter invokeThruCommand(
+ final ObjectAction owningAction,
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments, final Command command)
+ throws IllegalAccessException, InvocationTargetException {
+ final ObjectAdapter resultAdapter;
+ if( command.getExecutor() == Command.Executor.USER &&
+ command.getExecuteIn() == org.apache.isis.applib.annotation.Command.ExecuteIn.BACKGROUND) {
+
+ // deal with background commands
+
+ // persist command so can be this command can be in the 'background'
+ final CommandService commandService = getCommandService();
+ if (!commandService.persistIfPossible(command)) {
+ throw new IsisException(
+ "Unable to schedule action '"
+ + owningAction.getIdentifier().toClassAndNameIdentityString() + "' to run in background: "
+ + "CommandService does not support persistent commands " );
+ }
+ resultAdapter = getAdapterManager().adapterFor(command);
+
+ } else {
+
+ // otherwise, go ahead and execute action in the 'foreground'
+ command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
+
+ final Object resultPojo = invokeMethodElseFromCache(targetAdapter, arguments);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(" action result " + resultPojo);
+ }
+
+ resultAdapter = cloneIfViewModelCloneable(resultPojo, targetAdapter);
+
+ setCommandResultIfEntity(command, resultAdapter);
+ captureCurrentInvocationForPublishing(owningAction, targetAdapter, arguments, command, resultAdapter);
}
+ return resultAdapter;
+ }
- boolean filterForVisibility = getConfiguration().getBoolean("isis.reflector.facet.filterVisibility", true);
- if(filterForVisibility) {
- final Object result = invocationResultAdapter.getObject();
- if(result instanceof Collection || result.getClass().isArray()) {
- final CollectionFacet facet = CollectionFacet.Utils.getCollectionFacetFromSpec(invocationResultAdapter);
-
- final Iterable<ObjectAdapter> adapterList = facet.iterable(invocationResultAdapter);
- final List<ObjectAdapter> visibleAdapters =
- ObjectAdapter.Util.visibleAdapters(
- adapterList,
- interactionInitiatedBy);
- final Object visibleObjects =
- CollectionUtils.copyOf(
- Lists.transform(visibleAdapters, ObjectAdapter.Functions.getObject()),
- method.getReturnType());
- if (visibleObjects != null) {
- return getAdapterManager().adapterFor(visibleObjects);
- }
- // would be null if unable to take a copy (unrecognized return type)
- // fallback to returning the original adapter, without filtering for visibility
-
- } else {
- boolean visible =
- ObjectAdapter.Util.isVisible(
- invocationResultAdapter,
- interactionInitiatedBy);
- if(!visible) {
- return null;
+
+ protected Object invokeMethodElseFromCache(
+ final ObjectAdapter targetAdapter, final ObjectAdapter[] arguments)
+ throws IllegalAccessException, InvocationTargetException {
+
+ final Object[] executionParameters = new Object[arguments.length];
+ for (int i = 0; i < arguments.length; i++) {
+ executionParameters[i] = unwrap(arguments[i]);
+ }
+
+ final Object targetPojo = unwrap(targetAdapter);
+
+ final ActionSemanticsFacet semanticsFacet = getFacetHolder().getFacet(ActionSemanticsFacet.class);
+ final boolean cacheable = semanticsFacet != null && semanticsFacet.value().isSafeAndRequestCacheable();
+ if(cacheable) {
+ final QueryResultsCache queryResultsCache = getQueryResultsCache();
+ final Object[] targetPojoPlusExecutionParameters = ArrayExtensions.appendT(executionParameters, targetPojo);
+ return queryResultsCache.execute(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ return method.invoke(targetPojo, executionParameters);
}
+ }, targetPojo.getClass(), method.getName(), targetPojoPlusExecutionParameters);
+
+ } else {
+ return method.invoke(targetPojo, executionParameters);
+ }
+ }
+
+ protected ObjectAdapter cloneIfViewModelCloneable(
+ final Object resultPojo,
+ final ObjectAdapter targetAdapter) {
+
+ // to remove boilerplate from the domain, we automatically clone the returned object if it is a view model.
+
+ if (resultPojo != null) {
+ final ObjectAdapter resultAdapter = getAdapterManager().adapterFor(resultPojo);
+ return cloneIfViewModelElse(resultAdapter, resultAdapter);
+ } else {
+ // if void or null, attempt to clone the original target, else return null.
+ return cloneIfViewModelElse(targetAdapter, null);
+ }
+ }
+
+ private ObjectAdapter cloneIfViewModelElse(final ObjectAdapter adapter, final ObjectAdapter dfltAdapter) {
+
+ if (!adapter.getSpecification().isViewModelCloneable(adapter)) {
+ return dfltAdapter;
+ }
+
+ final ViewModelFacet viewModelFacet = adapter.getSpecification().getFacet(ViewModelFacet.class);
+ final Object clone = viewModelFacet.clone(adapter.getObject());
+
+ final ObjectAdapter clonedAdapter = getAdapterManager().adapterFor(clone);
+
+ // copy over TypeOfFacet if required
+ final TypeOfFacet typeOfFacet = getFacetHolder().getFacet(TypeOfFacet.class);
+ clonedAdapter.setElementSpecificationProvider(ElementSpecificationProviderFromTypeOfFacet.createFrom(typeOfFacet));
+
+ return clonedAdapter;
+ }
+
+
+ protected void setCommandResultIfEntity(final Command command, final ObjectAdapter resultAdapter) {
+ if(command.getResult() != null) {
+ // don't trample over any existing result, eg subsequent mixins.
+ return;
+ }
+ if (resultAdapter == null) {
+ return;
+ }
+
+ final Class<?> domainType = resultAdapter.getSpecification().getCorrespondingClass();
+ final MetaModelService2.Sort sort = getMetaModelService().sortOf(domainType);
+ switch (sort) {
+ case JDO_ENTITY:
+ final Object domainObject = resultAdapter.getObject();
+ // ensure that any still-to-be-persisted adapters get persisted to DB.
+ if(!getRepositoryService().isPersistent(domainObject)) {
+ getTransactionService().flushTransaction();
}
+ if(getRepositoryService().isPersistent(domainObject)) {
+ BookmarkService bookmarkService = getBookmarkService();
+ Bookmark bookmark = bookmarkService.bookmarkFor(domainObject);
+ command.setResult(bookmark);
+ }
+ break;
+ default:
+ // ignore all other sorts of objects
+ break;
+ }
+ }
+
+ private MetaModelService2 getMetaModelService() {
+ return lookupService(MetaModelService2.class);
+ }
+
+ private TransactionService getTransactionService() {
+ return lookupService(TransactionService.class);
+ }
+
+ private BookmarkService getBookmarkService() {
+ return lookupService(BookmarkService.class);
+ }
+
+ private RepositoryService getRepositoryService() {
+ return lookupService(RepositoryService.class);
+ }
+
+ protected void captureCurrentInvocationForPublishing(
+ final ObjectAction owningAction,
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments,
+ final Command command,
+ final ObjectAdapter resultAdapter) {
+
+ // TODO: should instead be using the top-level ActionInvocationMemento associated with command.
+
+ final PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
+ if (publishedActionFacet != null && currentInvocation.get() == null) {
+ final CurrentInvocation currentInvocation = new CurrentInvocation(
+ targetAdapter, owningAction, getIdentified(),
+ arguments, resultAdapter, command);
+ ActionInvocationFacet.currentInvocation.set(currentInvocation);
+ }
+ }
+
+ protected ObjectAdapter filteredIfRequired(
+ final ObjectAdapter resultAdapter,
+ final InteractionInitiatedBy interactionInitiatedBy) {
+
+ final boolean filterForVisibility = getConfiguration().getBoolean("isis.reflector.facet.filterVisibility", true);
+ if (!filterForVisibility) {
+ return resultAdapter;
+ }
+
+ final Object result = resultAdapter.getObject();
+
+ if(result instanceof Collection || result.getClass().isArray()) {
+ final CollectionFacet facet = CollectionFacet.Utils.getCollectionFacetFromSpec(resultAdapter);
+
+ final Iterable<ObjectAdapter> adapterList = facet.iterable(resultAdapter);
+ final List<ObjectAdapter> visibleAdapters =
+ ObjectAdapter.Util.visibleAdapters(
+ adapterList,
+ interactionInitiatedBy);
+ final Object visibleObjects =
+ CollectionUtils.copyOf(
+ Lists.transform(visibleAdapters, ObjectAdapter.Functions.getObject()),
+ method.getReturnType());
+ if (visibleObjects != null) {
+ return getAdapterManager().adapterFor(visibleObjects);
+ }
+
+ // would be null if unable to take a copy (unrecognized return type)
+ // fallback to returning the original adapter, without filtering for visibility
+
+ return resultAdapter;
+
+ } else {
+ boolean visible = ObjectAdapter.Util.isVisible(resultAdapter, interactionInitiatedBy);
+ return visible ? resultAdapter : null;
}
- return invocationResultAdapter;
}
+
/**
* Optional hook to allow the facet implementation for the deprecated {@link org.apache.isis.applib.annotation.PostsActionInvokedEvent} annotation
* to discard the event if the domain event is of a different type (specifically if was installed by virtue of a no
@@ -528,7 +531,11 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
// /////////////////////////////////////////////////////////
private CommandContext getCommandContext() {
- return lookupService(CommandContext.class);
+ CommandContext commandContext = lookupService(CommandContext.class);
+ if (commandContext == null) {
+ throw new IllegalStateException("The CommandContext service is not registered!");
+ }
+ return commandContext;
}
private QueryResultsCache getQueryResultsCache() {
@@ -539,18 +546,6 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
return lookupService(CommandService.class);
}
- private CommandMementoService getCommandMementoService() {
- return lookupService(CommandMementoService.class);
- }
-
- private Bulk.InteractionContext getBulkInteractionContext() {
- return lookupService(Bulk.InteractionContext.class);
- }
-
- private ActionInvocationContext getActionInvocationContext() {
- return lookupService(ActionInvocationContext.class);
- }
-
private <T> T lookupService(final Class<T> serviceClass) {
return getServicesInjector().lookupService(serviceClass);
}
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
index 9339274..32865c5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaModifyMethod.java
@@ -64,24 +64,20 @@ public class PropertySetterFacetViaModifyMethod extends PropertySetterFacetAbstr
final InteractionInitiatedBy interactionInitiatedBy) {
final CommandContext commandContext = getServicesInjector().lookupService(CommandContext.class);
- final Command command;
+ final Command command = commandContext.getCommand();
- if (commandContext != null) {
- command = commandContext.getCommand();
+ // cf similar code in ActionInvocationFacetForDomainEventFacet
+ command.setExecutor(Command.Executor.USER);
- // cf similar code in ActionInvocationFacetForDomainEventFacet
- command.setExecutor(Command.Executor.USER);
+ command.setTarget(CommandUtil.bookmarkFor(targetAdapter));
+ command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
+ command.setTargetAction(Command.ACTION_IDENTIFIER_FOR_EDIT);
+ command.setMemberIdentifier(Command.ACTION_IDENTIFIER_FOR_EDIT);
- command.setTarget(CommandUtil.bookmarkFor(targetAdapter));
- command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
- command.setTargetAction(Command.ACTION_IDENTIFIER_FOR_EDIT);
- command.setMemberIdentifier(Command.ACTION_IDENTIFIER_FOR_EDIT);
+ command.setExecuteIn(org.apache.isis.applib.annotation.Command.ExecuteIn.FOREGROUND);
+ command.setPersistence(org.apache.isis.applib.annotation.Command.Persistence.IF_HINTED);
- command.setExecuteIn(org.apache.isis.applib.annotation.Command.ExecuteIn.FOREGROUND);
- command.setPersistence(org.apache.isis.applib.annotation.Command.Persistence.IF_HINTED);
-
- command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
- }
+ command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
ObjectAdapter.InvokeUtils.invoke(method, targetAdapter, valueAdapter);
}
@@ -96,4 +92,16 @@ public class PropertySetterFacetViaModifyMethod extends PropertySetterFacetAbstr
return servicesInjector;
}
+ private <T> T lookupService(final Class<T> serviceClass) {
+ return getServicesInjector().lookupService(serviceClass);
+ }
+
+ protected CommandContext getCommandContext() {
+ CommandContext commandContext = lookupService(CommandContext.class);
+ if (commandContext == null) {
+ throw new IllegalStateException("The CommandContext service is not registered!");
+ }
+ return commandContext;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
index acbec29..713d2de 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandMementoService.java
@@ -41,8 +41,8 @@ public interface CommandMementoService {
ActionInvocationMemento asActionInvocationMemento(Method m, Object domainObject, Object[] args);
/**
- * The default implementation returns a non-null value. If a custom implementation returns <tt>null</tt>, then
- * the framework will fall back to using the deprecated {@link #asActionInvocationMemento(Method, Object, Object[])}.
+ * Returns a JAXB DTO (hence convertible to XML) that represents the intention to invoke an action on an action
+ * (or possible many, for bulk actions). The action can be a mixin action or a contributed action.
*/
@Programmatic
CommandMementoDto asCommandMemento(
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index 659c5dc..cf50c4b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -17,7 +17,6 @@
package org.apache.isis.core.metamodel.spec.feature;
-import java.lang.reflect.Method;
import java.util.List;
import com.google.common.base.Predicate;
@@ -52,7 +51,8 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
public interface ObjectAction extends ObjectMember {
- // //////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////
// semantics, realTarget, getOnType
// //////////////////////////////////////////////////////
@@ -186,6 +186,20 @@ public interface ObjectAction extends ObjectMember {
final InteractionInitiatedBy interactionInitiatedBy);
+
+ /**
+ * internal API
+ */
+ void setupActionInvocationContext(
+ final ObjectAdapter targetAdapter);
+
+ /**
+ * internal API
+ */
+ void setupCommand(
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments);
+
// //////////////////////////////////////////////////////
// Utils
// //////////////////////////////////////////////////////
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
index 4d9d782..59a0048 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
@@ -17,21 +17,13 @@
package org.apache.isis.core.metamodel.specloader.specimpl;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import com.google.common.collect.Lists;
import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.annotation.InvokedOn;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.applib.services.actinvoc.ActionInvocationContext;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.Command.Executor;
-import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.core.commons.lang.ObjectExtensions;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.consent.Consent;
@@ -41,8 +33,6 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
import org.apache.isis.core.metamodel.facetapi.MultiTypedFacet;
-import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
-import org.apache.isis.core.metamodel.facets.actions.bulk.BulkFacet;
import org.apache.isis.core.metamodel.interactions.InteractionUtils;
import org.apache.isis.core.metamodel.interactions.UsabilityContext;
import org.apache.isis.core.metamodel.interactions.VisibilityContext;
@@ -199,53 +189,14 @@ public class ObjectActionContributee extends ObjectActionDefault implements Cont
final ObjectAdapter[] arguments,
final InteractionInitiatedBy interactionInitiatedBy) {
- // this code also exists in ActionInvocationFacetViaMethod
- // we need to repeat it here because the target adapter should be the contributee, not the contributing service.
+ setupActionInvocationContext(contributee);
+ setupCommandTarget(contributee, arguments);
- final BulkFacet bulkFacet = getFacet(BulkFacet.class);
- if (bulkFacet != null) {
-
- final ActionInvocationContext actionInvocationContext = getServicesInjector().lookupService(ActionInvocationContext.class);
- if (actionInvocationContext != null &&
- actionInvocationContext.getInvokedOn() == null) {
-
- actionInvocationContext.setInvokedOn(InvokedOn.OBJECT);
- actionInvocationContext.setDomainObjects(Collections.singletonList(contributee.getObject()));
- }
-
- final Bulk.InteractionContext bulkInteractionContext = getServicesInjector().lookupService(Bulk.InteractionContext.class);
- if (bulkInteractionContext != null &&
- bulkInteractionContext.getInvokedAs() == null) {
-
- bulkInteractionContext.setInvokedAs(Bulk.InteractionContext.InvokedAs.REGULAR);
- bulkInteractionContext.setDomainObjects(Collections.singletonList(contributee.getObject()));
- }
-
-
- }
-
- final CommandContext commandContext = getServicesInjector().lookupService(CommandContext.class);
- final Command command = commandContext != null ? commandContext.getCommand() : null;
-
- if(command != null && command.getExecutor() == Executor.USER) {
-
- if (command.getTarget() != null) {
- // already set up by a edit form
- // don't overwrite
- } else {
- command.setTargetClass(CommandUtil.targetClassNameFor(contributee));
- command.setTargetAction(CommandUtil.targetActionNameFor(this));
- command.setArguments(CommandUtil.argDescriptionFor(this, arguments));
-
- final Bookmark targetBookmark = CommandUtil.bookmarkFor(contributee);
- command.setTarget(targetBookmark);
- }
- }
-
return serviceAction.execute(getServiceAdapter(), argsPlusContributee(contributee, arguments),
interactionInitiatedBy);
}
+
private ObjectAdapter[] argsPlusContributee(final ObjectAdapter contributee, final ObjectAdapter[] arguments) {
return addElementToArray(arguments, contributeeParam, contributee, new ObjectAdapter[]{});
}
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index 7060cf1..bcc0f03 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -19,6 +19,7 @@
package org.apache.isis.core.metamodel.specloader.specimpl;
+import java.util.Collections;
import java.util.List;
import com.google.common.base.Objects;
@@ -29,8 +30,13 @@ import org.slf4j.LoggerFactory;
import org.apache.isis.applib.RecoverableException;
import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.annotation.InvokedOn;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.core.commons.debug.DebugString;
import org.apache.isis.core.commons.exceptions.UnknownTypeException;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -44,6 +50,9 @@ import org.apache.isis.core.metamodel.facets.FacetedMethod;
import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
import org.apache.isis.core.metamodel.facets.TypedHolder;
import org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacet;
+import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+import org.apache.isis.core.metamodel.facets.actions.bulk.BulkFacet;
+import org.apache.isis.core.metamodel.facets.actions.command.CommandFacet;
import org.apache.isis.core.metamodel.facets.actions.debug.DebugFacet;
import org.apache.isis.core.metamodel.facets.actions.defaults.ActionDefaultsFacet;
import org.apache.isis.core.metamodel.facets.actions.exploration.ExplorationFacet;
@@ -59,12 +68,15 @@ import org.apache.isis.core.metamodel.interactions.InteractionUtils;
import org.apache.isis.core.metamodel.interactions.UsabilityContext;
import org.apache.isis.core.metamodel.interactions.ValidityContext;
import org.apache.isis.core.metamodel.interactions.VisibilityContext;
+import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.core.metamodel.spec.ActionType;
import org.apache.isis.core.metamodel.spec.DomainModelException;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.core.metamodel.spec.feature.ObjectMemberDependencies;
+import org.apache.isis.schema.cmd.v1.CommandMementoDto;
+import org.apache.isis.schema.utils.CommandMementoDtoUtils;
public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectAction {
@@ -353,15 +365,15 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
@Override
public ObjectAdapter execute(
- final ObjectAdapter target,
+ final ObjectAdapter targetAdapter,
final ObjectAdapter[] arguments,
final InteractionInitiatedBy interactionInitiatedBy) {
if(LOG.isDebugEnabled()) {
- LOG.debug("execute action " + target + "." + getId());
+ LOG.debug("execute action " + targetAdapter + "." + getId());
}
final ActionInvocationFacet facet = getFacet(ActionInvocationFacet.class);
- return facet.invoke(this, target, arguments,
- interactionInitiatedBy);
+
+ return facet.invoke(this, targetAdapter, arguments, interactionInitiatedBy);
}
protected ActionInvocationFacet getActionInvocationFacet() {
@@ -412,10 +424,8 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
}
final ObjectAdapter[] parameterDefaultAdapters = new ObjectAdapter[parameterCount];
- if (parameterDefaultPojos != null) {
- for (int i = 0; i < parameterCount; i++) {
- parameterDefaultAdapters[i] = adapterFor(parameterDefaultPojos[i]);
- }
+ for (int i = 0; i < parameterCount; i++) {
+ parameterDefaultAdapters[i] = adapterFor(parameterDefaultPojos[i]);
}
return parameterDefaultAdapters;
@@ -494,6 +504,141 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
return parameterChoicesAdapters;
}
+
+ /**
+ * Internal API
+ */
+ @Override
+ public void setupActionInvocationContext(final ObjectAdapter targetAdapter) {
+
+ final Object targetPojo = unwrap(targetAdapter);
+
+ final BulkFacet bulkFacet = getFacetHolder().getFacet(BulkFacet.class);
+ if (bulkFacet != null) {
+ final org.apache.isis.applib.services.actinvoc.ActionInvocationContext actionInvocationContext = getActionInvocationContext();
+ if (actionInvocationContext != null && actionInvocationContext.getInvokedOn() == null) {
+
+ actionInvocationContext.setInvokedOn(InvokedOn.OBJECT);
+ actionInvocationContext.setDomainObjects(Collections.singletonList(targetPojo));
+ }
+
+ final Bulk.InteractionContext bulkInteractionContext = getBulkInteractionContext();
+
+ if (bulkInteractionContext != null && bulkInteractionContext.getInvokedAs() == null) {
+
+ bulkInteractionContext.setInvokedAs(Bulk.InteractionContext.InvokedAs.REGULAR);
+ bulkInteractionContext.setDomainObjects(Collections.singletonList(targetPojo));
+ }
+ }
+ }
+
+ /**
+ * Internal API
+ */
+ @Override
+ public void setupCommand(
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments) {
+
+ setupCommandTarget(targetAdapter, arguments);
+ setupCommandMemberIdentifier();
+ setupCommandMementoAndExecutionContext(targetAdapter, arguments);
+ }
+
+
+ protected void setupCommandTarget(
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments) {
+
+ final CommandContext commandContext = getCommandContext();
+ final Command command = commandContext.getCommand();
+
+ if (command.getExecutor() != Command.Executor.USER) {
+ return;
+ }
+
+ if(command.getTarget() != null) {
+ // already set up by a ObjectActionContributee or edit form;
+ // don't overwrite
+ return;
+ }
+
+ command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
+ command.setTargetAction(CommandUtil.targetActionNameFor(this));
+ command.setArguments(CommandUtil.argDescriptionFor(this, arguments));
+
+ final Bookmark targetBookmark = CommandUtil.bookmarkFor(targetAdapter);
+ command.setTarget(targetBookmark);
+ }
+
+ protected void setupCommandMemberIdentifier() {
+
+ final CommandContext commandContext = getCommandContext();
+ final Command command = commandContext.getCommand();
+
+ if (command.getExecutor() != Command.Executor.USER) {
+ return;
+ }
+
+ if(Command.ACTION_IDENTIFIER_FOR_EDIT.equals(command.getMemberIdentifier())) {
+ // special case for edit properties, don't overwrite
+ return;
+ }
+
+ if (command.getMemberIdentifier() != null) {
+ // any contributed/mixin actions will fire after the main action
+ // the guard here prevents them from trashing the command's memberIdentifier
+ return;
+ }
+
+ command.setMemberIdentifier(CommandUtil.actionIdentifierFor(this));
+ }
+
+ protected void setupCommandMementoAndExecutionContext(
+ final ObjectAdapter targetAdapter,
+ final ObjectAdapter[] arguments) {
+
+ final CommandContext commandContext = getCommandContext();
+ final Command command = commandContext.getCommand();
+
+
+ if (command.getExecutor() != Command.Executor.USER) {
+ return;
+ }
+
+ if(Command.ACTION_IDENTIFIER_FOR_EDIT.equals(command.getMemberIdentifier())) {
+ // special case for edit properties, don't overwrite
+ return;
+ }
+
+ if (command.getMemento() != null) {
+ // guard here to prevent subsequent contributed/mixin actions from
+ // trampling over the command's memento and execution context
+ return;
+ }
+
+ // memento
+ final CommandMementoService commandMementoService = getCommandMementoService();
+ final CommandMementoDto dto = commandMementoService.asCommandMemento(
+ Collections.singletonList(targetAdapter),
+ this, arguments);
+
+ final String mementoXml = CommandMementoDtoUtils.toXml(dto);
+ command.setMemento(mementoXml);
+
+ // copy over the command execution 'context' (if available)
+ final CommandFacet commandFacet = getFacetHolder().getFacet(CommandFacet.class);
+ if(commandFacet != null && !commandFacet.isDisabled()) {
+ command.setExecuteIn(commandFacet.executeIn());
+ command.setPersistence(commandFacet.persistence());
+ } else {
+ // if no facet, assume do want to execute right now, but only persist (eventually) if hinted.
+ command.setExecuteIn(org.apache.isis.applib.annotation.Command.ExecuteIn.FOREGROUND);
+ command.setPersistence(org.apache.isis.applib.annotation.Command.Persistence.IF_HINTED);
+ }
+
+ }
+
//endregion
//region > debug, toString
@@ -528,4 +673,33 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
//endregion
+ private static Object unwrap(final ObjectAdapter adapter) {
+ return adapter == null ? null : adapter.getObject();
+ }
+
+ private <T> T lookupService(final Class<T> serviceClass) {
+ return getServicesInjector().lookupService(serviceClass);
+ }
+
+ protected CommandContext getCommandContext() {
+ CommandContext commandContext = lookupService(CommandContext.class);
+ if (commandContext == null) {
+ throw new IllegalStateException("The CommandContext service is not registered!");
+ }
+ return commandContext;
+ }
+
+ protected CommandMementoService getCommandMementoService() {
+ return lookupService(CommandMementoService.class);
+ }
+
+ protected Bulk.InteractionContext getBulkInteractionContext() {
+ return lookupService(Bulk.InteractionContext.class);
+ }
+
+ protected org.apache.isis.applib.services.actinvoc.ActionInvocationContext getActionInvocationContext() {
+ return lookupService(org.apache.isis.applib.services.actinvoc.ActionInvocationContext.class);
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index 9bdb98e..3490efd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -16,7 +16,6 @@
*/
package org.apache.isis.core.metamodel.specloader.specimpl;
-import java.util.Collections;
import java.util.List;
import com.google.common.base.Objects;
@@ -24,13 +23,8 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.annotation.Bulk;
-import org.apache.isis.applib.annotation.InvokedOn;
import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.services.actinvoc.ActionInvocationContext;
-import org.apache.isis.applib.services.bookmark.Bookmark;
import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.Command.Executor;
import org.apache.isis.applib.services.command.CommandContext;
import org.apache.isis.core.commons.lang.ObjectExtensions;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -39,18 +33,13 @@ import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FacetHolderImpl;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
-import org.apache.isis.core.metamodel.facets.actions.bulk.BulkFacet;
import org.apache.isis.core.metamodel.facets.all.named.NamedFacetInferred;
import org.apache.isis.core.metamodel.interactions.InteractionUtils;
import org.apache.isis.core.metamodel.interactions.UsabilityContext;
import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import org.apache.isis.core.metamodel.services.command.CommandMementoService;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.isis.core.metamodel.spec.feature.ObjectMemberDependencies;
-import org.apache.isis.schema.cmd.v1.CommandMementoDto;
-import org.apache.isis.schema.utils.CommandMementoDtoUtils;
public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInMember2 {
@@ -154,7 +143,7 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
final Where where) {
final VisibilityContext<?> ic =
mixinAction.createVisibleInteractionContext(
- mixinAdapterFor(mixinType, mixedInAdapter), interactionInitiatedBy, where);
+ mixinAdapterFor(mixedInAdapter), interactionInitiatedBy, where);
ic.putContributee(0, mixedInAdapter);
return InteractionUtils.isVisibleResult(this, ic).createConsent();
}
@@ -165,28 +154,32 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
final InteractionInitiatedBy interactionInitiatedBy, final Where where) {
final UsabilityContext<?> ic =
mixinAction.createUsableInteractionContext(
- mixinAdapterFor(mixinType, mixedInAdapter), interactionInitiatedBy, where);
+ mixinAdapterFor(mixedInAdapter), interactionInitiatedBy, where);
ic.putContributee(0, mixedInAdapter);
return InteractionUtils.isUsableResult(this, ic).createConsent();
}
@Override
public ObjectAdapter[] getDefaults(final ObjectAdapter mixedInAdapter) {
- return mixinAction.getDefaults(mixinAdapterFor(mixinType, mixedInAdapter));
+ return mixinAction.getDefaults(mixinAdapterFor(mixedInAdapter));
}
@Override
public ObjectAdapter[][] getChoices(
final ObjectAdapter mixedInAdapter,
final InteractionInitiatedBy interactionInitiatedBy) {
- return mixinAction.getChoices(mixinAdapterFor(mixinType, mixedInAdapter), interactionInitiatedBy);
+ return mixinAction.getChoices(mixinAdapterFor(mixedInAdapter), interactionInitiatedBy);
+ }
+
+ protected ObjectAdapter mixinAdapterFor(final ObjectAdapter mixedInAdapter) {
+ return mixinAdapterFor(mixinType, mixedInAdapter);
}
public Consent isProposedArgumentSetValid(
final ObjectAdapter mixedInAdapter,
final ObjectAdapter[] proposedArguments,
final InteractionInitiatedBy interactionInitiatedBy) {
- return mixinAction.isProposedArgumentSetValid(mixinAdapterFor(mixinType, mixedInAdapter), proposedArguments, interactionInitiatedBy);
+ return mixinAction.isProposedArgumentSetValid(mixinAdapterFor(mixedInAdapter), proposedArguments, interactionInitiatedBy);
}
@Override
@@ -198,73 +191,17 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
// this code also exists in ActionInvocationFacetViaMethod
// we need to repeat it here because the target adapter should be the mixedInAdapter, not the mixin
- final BulkFacet bulkFacet = getFacet(BulkFacet.class);
- if (bulkFacet != null) {
-
- final ActionInvocationContext actionInvocationContext =
- getServicesInjector().lookupService(ActionInvocationContext.class);
- if (actionInvocationContext != null &&
- actionInvocationContext.getInvokedOn() == null) {
+ setupActionInvocationContext(mixedInAdapter);
- actionInvocationContext.setInvokedOn(InvokedOn.OBJECT);
- actionInvocationContext.setDomainObjects(Collections.singletonList(mixedInAdapter.getObject()));
- }
-
- final Bulk.InteractionContext bulkInteractionContext = getServicesInjector().lookupService(Bulk.InteractionContext.class);
- if (bulkInteractionContext != null &&
- bulkInteractionContext.getInvokedAs() == null) {
+ final CommandContext commandContext = getCommandContext();
+ final Command command = commandContext.getCommand();
- bulkInteractionContext.setInvokedAs(Bulk.InteractionContext.InvokedAs.REGULAR);
- actionInvocationContext.setDomainObjects(Collections.singletonList(mixedInAdapter.getObject()));
- }
- }
+ setupCommandTarget(mixedInAdapter, arguments);
+ setupCommandMementoAndExecutionContext(mixedInAdapter, arguments);
- final CommandContext commandContext = getServicesInjector().lookupService(CommandContext.class);
- final Command command = commandContext != null ? commandContext.getCommand() : null;
-
- if(command != null && command.getExecutor() == Executor.USER) {
-
- if (command.getTarget() != null) {
- // already set up by a edit form
- // don't overwrite
- } else {
- command.setTargetClass(CommandUtil.targetClassNameFor(mixedInAdapter));
- command.setTargetAction(CommandUtil.targetActionNameFor(this));
- command.setArguments(CommandUtil.argDescriptionFor(this, arguments));
-
- final Bookmark targetBookmark = CommandUtil.bookmarkFor(mixedInAdapter);
- command.setTarget(targetBookmark);
-
- }
-
- if(command.getMemento() == null) {
- // similarly, guard here to deal with subsequent or prior contributed/mixin actions.
-
- final CommandMementoService commandMementoService = getCommandMementoService();
-
- final CommandMementoDto dto = commandMementoService.asCommandMemento(
- Collections.singletonList(mixedInAdapter),
- this, arguments);
-
- if(dto != null) {
- // the default implementation will always return a dto. The guard is to allow
- // for the default implementation to be replaced with a version that returns null
- // allowing a fallback to the original API (using ActionInvocationMemento rather than
- // CommandMementoDto).
- final String mementoXml = CommandMementoDtoUtils.toXml(dto);
- command.setMemento(mementoXml);
- } else {
- // no fallback to old behaviour is required; mixin actions were simply not correctly supported.
- }
- }
-
-
- }
-
- return mixinAction.execute(mixinAdapterFor(mixinType, mixedInAdapter), arguments, interactionInitiatedBy);
+ return mixinAction.execute(mixinAdapterFor(mixedInAdapter), arguments, interactionInitiatedBy);
}
-
//region > facetHolder
@Override
protected FacetHolder getFacetHolder() {
@@ -272,15 +209,6 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
}
//endregion
-
- ObjectAdapter mixinAdapterFor(final ObjectAdapter mixedInAdapter) {
- return mixinAdapterFor(mixinType, mixedInAdapter);
- }
-
- private static Object unwrap(final ObjectAdapter adapter) {
- return adapter == null ? null : adapter.getObject();
- }
-
/* (non-Javadoc)
* @see org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract#getIdentifier()
*/
@@ -299,12 +227,5 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
// //////////////////////////////////////
- private CommandMementoService getCommandMementoService() {
- return lookupService(CommandMementoService.class);
- }
-
- private <T> T lookupService(final Class<T> serviceClass) {
- return getServicesInjector().lookupService(serviceClass);
- }
}
http://git-wip-us.apache.org/repos/asf/isis/blob/46089a20/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
index 845d7ff..b758e65 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
@@ -129,9 +129,7 @@ public class BackgroundServiceDefault implements BackgroundService {
proxyObject.setHandler(methodHandler);
return newInstance;
- } catch (final InstantiationException e) {
- throw new IsisException(e);
- } catch (final IllegalAccessException e) {
+ } catch (final InstantiationException | IllegalAccessException e) {
throw new IsisException(e);
}
}
@@ -170,20 +168,13 @@ public class BackgroundServiceDefault implements BackgroundService {
final Command command = commandContext.getCommand();
if(backgroundCommandService instanceof BackgroundCommandService2) {
- final BackgroundCommandService2 backgroundCommandService2 =
- (BackgroundCommandService2) backgroundCommandService;
+ final BackgroundCommandService2 bcs2 = (BackgroundCommandService2) backgroundCommandService;
final CommandMementoDto dto = commandMementoService
.asCommandMemento(Collections.singletonList(targetAdapter), action, argAdapters);
- if(dto != null) {
- // the default implementation returns a non-null value. This guard is to allow a different
- // implementation to be configured that returns null, thereby falling through to the
- // original behaviour (of using ActionInvocationMemento instead of CommandMementoDto).
- backgroundCommandService2.schedule(dto, command, targetClassName, targetActionName, targetArgs);
-
- return null;
- }
+ bcs2.schedule(dto, command, targetClassName, targetActionName, targetArgs);
+ return null;
}
// fallback
@@ -191,7 +182,6 @@ public class BackgroundServiceDefault implements BackgroundService {
.asActionInvocationMemento(proxyMethod, domainObject, args);
backgroundCommandService.schedule(aim, command, targetClassName, targetActionName, targetArgs);
-
return null;
}