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/05/04 09:11:54 UTC

[2/8] isis git commit: ISIS-1389: simplifying code of ActionInvocationFacet by inlining, improving error handling, only broadcast events once an InteractionContext.currentExecution is defined.

ISIS-1389: simplifying code of ActionInvocationFacet by inlining, improving error handling, only broadcast events once an InteractionContext.currentExecution is defined.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/82a0dab7
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/82a0dab7
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/82a0dab7

Branch: refs/heads/ISIS-1291
Commit: 82a0dab74aec6afea8859b2488aefeb434dda453
Parents: 362350c
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue May 3 20:33:37 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue May 3 20:33:37 2016 +0100

----------------------------------------------------------------------
 ...onInvocationFacetForDomainEventAbstract.java | 231 +++++++------------
 1 file changed, 78 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/82a0dab7/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 77fbcc9..cc72d27 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
@@ -152,50 +152,12 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
     }
 
 
-    /**
-     * Introduced to disambiguate the meaning of <tt>null</tt> as a return value of
-     * {@link ActionInvocationFacet#invoke(ObjectAction, ObjectAdapter, ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)}
-     */
-    public static class InvocationResult {
-
-        public static InvocationResult forActionThatReturned(final ObjectAdapter resultAdapter) {
-            return new InvocationResult(true, resultAdapter);
-        }
-
-        public static InvocationResult forActionNotInvoked() {
-            return new InvocationResult(false, null);
-        }
-
-        private final boolean whetherInvoked;
-        private final ObjectAdapter adapter;
-
-        private InvocationResult(final boolean whetherInvoked, final ObjectAdapter result) {
-            this.whetherInvoked = whetherInvoked;
-            this.adapter = result;
-        }
-
-        public boolean getWhetherInvoked() {
-            return whetherInvoked;
-        }
-
-        /**
-         * Returns the result, or null if either the action invocation returned null or
-         * if the action was never invoked in the first place.
-         *
-         * <p>
-         * Use {@link #getWhetherInvoked()} to distinguish between these two cases.
-         */
-        public ObjectAdapter getAdapter() {
-            return adapter;
-        }
-    }
-
     @Override
     public ObjectAdapter invoke(
             final ObjectAction owningAction,
             final ObjectAdapter targetAdapter,
             final ObjectAdapter mixedInAdapter,
-            final ObjectAdapter[] arguments,
+            final ObjectAdapter[] argumentAdapters,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         // similar code in PropertySetterOrClearFacetFDEA
@@ -203,105 +165,8 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
         final CommandContext commandContext = getCommandContext();
         final Command command = commandContext.getCommand();
 
-        // ... post the executing event
-        final ActionDomainEvent<?> event =
-                domainEventHelper.postEventForAction(
-                        AbstractDomainEvent.Phase.EXECUTING,
-                        eventType, null,
-                        owningAction, owningAction, targetAdapter, mixedInAdapter, arguments,
-                        command,
-                        null);
-
-        final InvocationResult invocationResult = invokeInternal(owningAction, targetAdapter, arguments);
-        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, owningAction, targetAdapter, mixedInAdapter, arguments,
-                    command,
-                    invocationResultAdapter);
-        }
+        owningAction.setupCommand(targetAdapter, argumentAdapters);
 
-        if (invocationResultAdapter == null) {
-            return null;
-        }
-
-        return filteredIfRequired(invocationResultAdapter, interactionInitiatedBy);
-    }
-
-    private InvocationResult invokeInternal(
-            final ObjectAction owningAction,
-            final ObjectAdapter targetAdapter,
-            final ObjectAdapter[] argumentAdapters) {
-
-        // similar code in PropertySetterOrClearFacetFDEA
-
-        try {
-            owningAction.setupActionInvocationContext(targetAdapter);
-            owningAction.setupCommand(targetAdapter, argumentAdapters);
-
-            ObjectAdapter resultAdapter = invokeThruCommand(owningAction, targetAdapter, argumentAdapters);
-
-            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( String.format(
-                        "IllegalStateException thrown while executing %s %s",
-                        method, targetException.getMessage()), targetException);
-            }
-            if(targetException instanceof RecoverableException) {
-                if (!getTransactionState().canCommit()) {
-                    // something severe has happened to the underlying transaction;
-                    // so escalate this exception to be non-recoverable
-                    final Throwable targetExceptionCause = targetException.getCause();
-                    Throwable nonRecoverableCause = targetExceptionCause != null? targetExceptionCause: targetException;
-
-                    // trim to first 300 chars
-                    final String message = trim(nonRecoverableCause.getMessage(), 300);
-
-                    throw new NonRecoverableException(message, nonRecoverableCause);
-                }
-            }
-
-            ThrowableExtensions.throwWithinIsisException(e, "Exception executing " + method);
-
-            // Action was not invoked (an Exception was thrown)
-            return InvocationResult.forActionNotInvoked();
-
-        } catch (final IllegalAccessException e) {
-            throw new ReflectiveActionException("Illegal access of " + method, e);
-        }
-    }
-
-    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;
-    }
-
-    protected ObjectAdapter invokeThruCommand(
-            final ObjectAction owningAction,
-            final ObjectAdapter targetAdapter,
-            final ObjectAdapter[] argumentAdapters)
-            throws IllegalAccessException, InvocationTargetException {
-
-        // similar code in PropertySetterOrClearFacetFDEA
-
-        final CommandContext commandContext = getCommandContext();
-        final Command command = commandContext.getCommand();
 
         final InteractionContext interactionContext = getInteractionContext();
         final Interaction interaction = interactionContext.getInteraction();
@@ -326,45 +191,87 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
         } else {
 
             // otherwise, go ahead and execute action in the 'foreground'
+            owningAction.setupActionInvocationContext(targetAdapter);
 
-            final Object target = ObjectAdapter.Util.unwrap(targetAdapter);
-            final List<Object> arguments = ObjectAdapter.Util.unwrap(Arrays.asList(argumentAdapters));
+            final Object targetPojo = ObjectAdapter.Util.unwrap(targetAdapter);
+            final List<Object> argumentPojos = ObjectAdapter.Util.unwrap(Arrays.asList(argumentAdapters));
 
-            final Interaction.ActionArgs actionArgs = new Interaction.ActionArgs(actionId, target, arguments);
+            final Interaction.ActionArgs actionArgs = new Interaction.ActionArgs(actionId, targetPojo, argumentPojos);
             final Interaction.MemberCallable callable = new Interaction.MemberCallable<Interaction.ActionArgs>() {
+
                 @Override
                 public Object call(
                         final Interaction.Execution currentExecution,
                         final Interaction.ActionArgs actionArgs) {
 
                     try {
-                        final Object resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
+                        // ... post the executing event
+                        final ActionDomainEvent<?> event =
+                                domainEventHelper.postEventForAction(
+                                        AbstractDomainEvent.Phase.EXECUTING,
+                                        eventType, null,
+                                        owningAction, owningAction,
+                                        targetAdapter, mixedInAdapter, argumentAdapters,
+                                        command,
+                                        null);
 
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug(" action result " + resultPojo);
-                        }
 
-                        ObjectAdapter resultAdapter = cloneIfViewModelCloneable(resultPojo, targetAdapter);
+                        final Object resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
+
+                        final ObjectAdapter resultAdapterPossiblyCloned = cloneIfViewModelCloneable(resultPojo, targetAdapter);
 
-                        // update the current execution
+                        // update the current execution with the DTO (memento)
                         final List<ObjectAdapter> parameterAdapters = Arrays.asList(argumentAdapters);
                         final ActionInvocationDto invocationDto =
                                 getInteractionDtoServiceInternal().asActionInvocationDto(
-                                    owningAction, targetAdapter, parameterAdapters, resultAdapter);
+                                        owningAction, targetAdapter, parameterAdapters, resultAdapterPossiblyCloned);
 
                         currentExecution.setDto(invocationDto);
 
-                        return resultAdapter != null ? resultAdapter.getObject() : null;
+                        // ... post the executed event
+                        domainEventHelper.postEventForAction(
+                                AbstractDomainEvent.Phase.EXECUTED,
+                                eventType, verify(event),
+                                owningAction, owningAction, targetAdapter, mixedInAdapter, argumentAdapters,
+                                command,
+                                resultAdapterPossiblyCloned);
+
+                        return ObjectAdapter.Util.unwrap(resultAdapterPossiblyCloned);
+
+                    } catch (IllegalAccessException ex) {
+                        throw new ReflectiveActionException("Illegal access of " + method, ex);
+                    } catch (InvocationTargetException ex) {
+
+                        final Throwable targetException = ex.getTargetException();
+                        if (targetException instanceof IllegalStateException) {
+                            throw new ReflectiveActionException( String.format(
+                                    "IllegalStateException thrown while executing %s %s",
+                                    method, targetException.getMessage()), targetException);
+                        }
+
+                        if(targetException instanceof RecoverableException) {
+                            if (!getTransactionState().canCommit()) {
+                                // something severe has happened to the underlying transaction;
+                                // so escalate this exception to be non-recoverable
+                                final Throwable targetExceptionCause = targetException.getCause();
+                                Throwable nonRecoverableCause = targetExceptionCause != null
+                                        ? targetExceptionCause
+                                        : targetException;
 
-                    } catch (InvocationTargetException | IllegalAccessException e) {
-                        throw new RuntimeException(e);
+                                // trim to first 300 chars
+                                final String message = trim(nonRecoverableCause.getMessage(), 300);
+
+                                throw new NonRecoverableException(message, nonRecoverableCause);
+                            }
+                        }
+
+                        ThrowableExtensions.throwWithinIsisException(ex, "Exception executing " + method);
+                        return null; // never executed, previous line throws
                     }
                 }
             };
 
-
             interaction.execute(callable, actionArgs, getClockService(), command);
-
             final Interaction.Execution priorExecution = interaction.getPriorExecution();
 
             final RuntimeException executionExceptionIfAny = priorExecution.getThrew();
@@ -373,6 +280,9 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
             }
 
             resultAdapter = getAdapterManager().adapterFor(priorExecution.getReturned());
+
+
+            // update Command (if required)
             setCommandResultIfEntity(command, resultAdapter);
 
             final PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
@@ -387,9 +297,20 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
                         targetAdapter, parameterAdapters,
                         resultAdapter);
             }
+        }
+
+
+        return filteredIfRequired(resultAdapter, interactionInitiatedBy);
+    }
 
+    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 resultAdapter;
+        return message;
     }
 
     protected Object invokeMethodElseFromCache(
@@ -504,6 +425,10 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
             final ObjectAdapter resultAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
+        if (resultAdapter == null) {
+            return null;
+        }
+
         final boolean filterForVisibility = getConfiguration().getBoolean("isis.reflector.facet.filterVisibility", true);
         if (!filterForVisibility) {
             return resultAdapter;