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/08/08 20:15:47 UTC

[isis] branch v2 updated: ISIS-2158 extends the WrapperFactory API, to give users more control

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new b6007f5  ISIS-2158 extends the WrapperFactory API, to give users more control
b6007f5 is described below

commit b6007f54755549f7fde4e0970da922cbb5d30adc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Aug 8 22:15:29 2019 +0200

    ISIS-2158 extends the WrapperFactory API, to give users more control
    
    - when using the 'wrapper', the desired execution mode can now be
    controlled finer by combining ExectionMode options to an EnumSet, where
    now any possible combination is available to the user
    - also added a new ASYNC mode Option do be implemented later; idea is to
    allow for background execution via the WrapperFactory
---
 .../applib/services/wrapper/WrapperFactory.java    | 57 +++++++++++++---------
 .../applib/services/wrapper/WrappingObject.java    |  8 +--
 .../apache/isis/wrapper/WrapperFactoryDefault.java |  5 +-
 .../DelegatingInvocationHandlerDefault.java        |  7 +--
 .../handlers/DomainObjectInvocationHandler.java    | 42 ++++++++--------
 .../isis/wrapper/handlers/ProxyContextHandler.java |  3 +-
 .../isis/wrapper/WrapperFactoryDefaultTest.java    | 18 +++----
 .../fixtures/fixturescripts/FixtureScript.java     |  5 +-
 8 files changed, 81 insertions(+), 64 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
index 4fda1ce..0720f37 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrapperFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.applib.services.wrapper;
 
+import java.util.EnumSet;
 import java.util.List;
 
 import org.apache.isis.applib.services.factory.FactoryService;
@@ -76,41 +77,53 @@ public interface WrapperFactory {
      */
     @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
     public static enum ExecutionMode {
+        
         /**
-         * Validate all business rules and then execute. May throw exceptions in order to fail fast. 
+         * Skip all business rules.
          */
-        EXECUTE(true, true, true),
+        SKIP_RULE_VALIDATION,
         
         /**
-         * Validate all business rules and then execute, but don't throw an exception if validation 
-         * or execution fails.
+         * Skip execution.
          */
-        TRY(true, true, false),
+        SKIP_EXECUTION,
+        
+        /**
+         * Don't fail fast, swallow any exception during validation or execution.
+         */
+        SWALLOW_EXCEPTIONS,
+        
+        /**
+         * Validate/Execute in background.
+         */
+        ASYNC,
+        
+        ;
         
+        // -- PRESET ENUM SETS
+
+        /**
+         * Validate all business rules and then execute. May throw exceptions in order to fail fast. 
+         */
+        public static EnumSet<ExecutionMode> EXECUTE = EnumSet.noneOf(ExecutionMode.class); 
+
         /**
          * Skip all business rules and then execute, does throw an exception if execution fails.
          */
-        SKIP_RULES(false, true, true),
+        public static EnumSet<ExecutionMode> SKIP_RULES = EnumSet.of(SKIP_RULE_VALIDATION);
         
         /**
          * Validate all business rules but do not execute, throw an exception if validation 
          * fails. 
          */
-        NO_EXECUTE(true, false, true);
-
-        private final boolean enforceRules;
-        private final boolean execute;
-        private final boolean failFast;
-
-        public boolean shouldEnforceRules() {
-            return enforceRules;
-        }
-        public boolean shouldExecute() {
-            return execute;
-        }
-        public boolean shouldFailFast() {
-            return failFast;
-        }
+        public static EnumSet<ExecutionMode> NO_EXECUTE = EnumSet.of(SKIP_EXECUTION);
+        
+        /**
+         * Validate all business rules and then execute, but don't throw an exception if validation 
+         * or execution fails.
+         */
+        public static EnumSet<ExecutionMode> TRY = EnumSet.of(SWALLOW_EXCEPTIONS); 
+        
     }
 
     /**
@@ -153,7 +166,7 @@ public interface WrapperFactory {
      * Otherwise, will do all the validations (raise exceptions as required
      * etc.), but doesn't modify the model.
      */
-    <T> T wrap(T domainObject, ExecutionMode mode);
+    <T> T wrap(T domainObject, EnumSet<ExecutionMode> mode);
 
 
     /**
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrappingObject.java b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrappingObject.java
index 6b8577c..d469eb1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrappingObject.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/wrapper/WrappingObject.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.applib.services.wrapper;
 
+import java.util.EnumSet;
+
 /**
  * Implemented by all objects that have been viewed as per
  * {@link org.apache.isis.applib.services.wrapper.WrapperFactory#wrap(Object)}.
@@ -55,14 +57,14 @@ public interface WrappingObject {
     Object __isis_wrapped();
 
     /**
-     * The {@link org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode execution mode}
+     * The {@link EnumSet<WrapperFactory.ExecutionMode> execution mode}
      * with which this wrapper was
-     * {@link WrapperFactory#wrap(Object, org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode) created}.
+     * {@link WrapperFactory#wrap(Object, EnumSet) created}.
      *
      * <p>
      * NOTE: domain classes may not have a method with this name.  The <tt>__isis_</tt> prefix is
      * intended to reduce the risk of a collision.
      * </p>
      */
-    WrapperFactory.ExecutionMode __isis_executionMode();
+    EnumSet<WrapperFactory.ExecutionMode> __isis_executionMode();
 }
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/WrapperFactoryDefault.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/WrapperFactoryDefault.java
index 59b3218..a03958e 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/WrapperFactoryDefault.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/WrapperFactoryDefault.java
@@ -22,6 +22,7 @@ package org.apache.isis.wrapper;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -132,7 +133,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
     }
 
     @Override
-    public <T> T wrap(T domainObject, ExecutionMode mode) {
+    public <T> T wrap(T domainObject, EnumSet<ExecutionMode> mode) {
         if (domainObject instanceof WrappingObject) {
             val wrapperObject = (WrappingObject) domainObject;
             val executionMode = wrapperObject.__isis_executionMode();
@@ -145,7 +146,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
         return createProxy(domainObject, mode);
     }
 
-    protected <T> T createProxy(T domainObject, ExecutionMode mode) {
+    protected <T> T createProxy(T domainObject, EnumSet<ExecutionMode> mode) {
         
         return proxyContextHandler.proxy(domainObject, mode);
     }
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DelegatingInvocationHandlerDefault.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DelegatingInvocationHandlerDefault.java
index e5f1e92..d8d4b00 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DelegatingInvocationHandlerDefault.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DelegatingInvocationHandlerDefault.java
@@ -21,6 +21,7 @@ package org.apache.isis.wrapper.handlers;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.EnumSet;
 
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
@@ -34,7 +35,7 @@ public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocati
 
     private final T delegate;
     protected final WrapperFactory wrapperFactory;
-    private final ExecutionMode executionMode;
+    private final EnumSet<ExecutionMode> executionMode;
 
     protected final Method equalsMethod;
     protected final Method hashCodeMethod;
@@ -44,7 +45,7 @@ public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocati
 
     public DelegatingInvocationHandlerDefault(
             final T delegate,
-            final ExecutionMode executionMode) {
+            final EnumSet<ExecutionMode> executionMode) {
 
         if (delegate == null) {
             throw new IllegalArgumentException("delegate must not be null");
@@ -93,7 +94,7 @@ public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocati
         return delegate;
     }
 
-    public ExecutionMode getExecutionMode() {
+    public EnumSet<ExecutionMode> getExecutionMode() {
         return executionMode;
     }
 
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DomainObjectInvocationHandler.java
index 5785240..42240a4 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DomainObjectInvocationHandler.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -22,6 +22,7 @@ package org.apache.isis.wrapper.handlers;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -73,7 +74,7 @@ import lombok.val;
 public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
 
     private final ProxyContextHandler proxy;
-    private final ExecutionMode executionMode;
+    private final EnumSet<ExecutionMode> executionMode;
     private final MetaModelContext mmContext;
 
     /**
@@ -100,7 +101,7 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
 
     public DomainObjectInvocationHandler(
             final T delegate,
-            final ExecutionMode mode,
+            final EnumSet<ExecutionMode> mode,
             final ProxyContextHandler proxy) {
         
         super(delegate, mode);
@@ -283,7 +284,7 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
     }
 
     public InteractionInitiatedBy getInteractionInitiatedBy() {
-        return getExecutionMode().shouldEnforceRules()
+        return shouldEnforceRules()
                 ? InteractionInitiatedBy.USER
                         : InteractionInitiatedBy.FRAMEWORK;
     }
@@ -806,11 +807,23 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
 
     // -- HELPER
     
+    private boolean shouldEnforceRules() {
+        return !getExecutionMode().contains(ExecutionMode.SKIP_RULE_VALIDATION);
+    }
+    
+    private boolean shouldExecute() {
+        return !getExecutionMode().contains(ExecutionMode.SKIP_EXECUTION);
+    }
+    
+    private boolean shouldFailFast() {
+        return !getExecutionMode().contains(ExecutionMode.SWALLOW_EXCEPTIONS);
+    }
+    
     private void runValidationTask(Runnable task) {
-        if(!getExecutionMode().shouldEnforceRules()) {
+        if(!shouldEnforceRules()) {
             return;
         }
-        if(getExecutionMode().shouldFailFast()) {
+        if(shouldFailFast()) {
             task.run();
         } else {
             try {
@@ -821,26 +834,11 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
         }
     }
     
-//    private void runExecutionTask(Runnable task) {
-//        if(!getExecutionMode().shouldExecute()) {
-//            return;
-//        }
-//        if(getExecutionMode().shouldFailFast()) {
-//            task.run();
-//        } else {
-//            try {
-//                task.run();
-//            } catch(Exception ex) {
-//                // swallow
-//            }
-//        }
-//    }
-    
     private <X> X runExecutionTask(Supplier<X> task) {
-        if(!getExecutionMode().shouldExecute()) {
+        if(!shouldExecute()) {
             return null;
         }
-        if(getExecutionMode().shouldFailFast()) {
+        if(shouldFailFast()) {
             return task.get();
         } else {
             try {
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/ProxyContextHandler.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/ProxyContextHandler.java
index aec7332..e60e525 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/ProxyContextHandler.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/handlers/ProxyContextHandler.java
@@ -20,6 +20,7 @@
 package org.apache.isis.wrapper.handlers;
 
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Map;
 
 import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
@@ -35,7 +36,7 @@ public class ProxyContextHandler {
 
     @NonNull private final ProxyCreator proxyCreator;
 
-    public <T> T proxy(T domainObject, ExecutionMode mode) {
+    public <T> T proxy(T domainObject, EnumSet<ExecutionMode> mode) {
 
         val invocationHandler = new DomainObjectInvocationHandler<T>(
                 domainObject,
diff --git a/core/runtime-extensions/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest.java b/core/runtime-extensions/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest.java
index eed6af9..c63b805 100644
--- a/core/runtime-extensions/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest.java
+++ b/core/runtime-extensions/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.wrapper;
 
+import java.util.EnumSet;
+
 import org.jmock.auto.Mock;
 import org.junit.Before;
 import org.junit.Rule;
@@ -33,20 +35,18 @@ import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 
+import lombok.RequiredArgsConstructor;
+
 public class WrapperFactoryDefaultTest {
 
     private static class DomainObject {
     }
 
+    @RequiredArgsConstructor
     private static class WrappedDomainObject extends DomainObject implements WrappingObject {
 
         private final DomainObject wrappedObject;
-        private final WrapperFactory.ExecutionMode mode;
-
-        WrappedDomainObject(final DomainObject wrappedObject, WrapperFactory.ExecutionMode mode) {
-            this.wrappedObject = wrappedObject;
-            this.mode = mode;
-        }
+        private final EnumSet<WrapperFactory.ExecutionMode> mode;
 
         @Override
         public void __isis_save() {
@@ -58,7 +58,7 @@ public class WrapperFactoryDefaultTest {
         }
 
         @Override
-        public WrapperFactory.ExecutionMode __isis_executionMode() {
+        public EnumSet<WrapperFactory.ExecutionMode> __isis_executionMode() {
             return mode;
         }
     }
@@ -71,14 +71,14 @@ public class WrapperFactoryDefaultTest {
     private WrapperFactoryDefault wrapperFactory;
 
     private DomainObject createProxyCalledWithDomainObject;
-    private WrapperFactory.ExecutionMode createProxyCalledWithMode;
+    private EnumSet<WrapperFactory.ExecutionMode> createProxyCalledWithMode;
 
     @Before
     public void setUp() throws Exception {
         wrapperFactory = new WrapperFactoryDefault(mockProxyCreator) {
 
             @Override
-            protected <T> T createProxy(T domainObject, ExecutionMode mode) {
+            protected <T> T createProxy(T domainObject, EnumSet<WrapperFactory.ExecutionMode> mode) {
                 WrapperFactoryDefaultTest.this.createProxyCalledWithMode = mode;
                 WrapperFactoryDefaultTest.this.createProxyCalledWithDomainObject = (DomainObject) domainObject;
                 return domainObject;
diff --git a/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/fixturescripts/FixtureScript.java b/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/fixturescripts/FixtureScript.java
index b6d024f..0f8c24a 100644
--- a/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/fixturescripts/FixtureScript.java
+++ b/extensions/fixtures/src/main/java/org/apache/isis/extensions/fixtures/fixturescripts/FixtureScript.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 
@@ -952,9 +953,9 @@ extends AbstractViewModel {
     }
 
     /**
-     * Convenience method, simply delegates to {@link WrapperFactory#wrap(Object, WrapperFactory.ExecutionMode)}.
+     * Convenience method, simply delegates to {@link WrapperFactory#wrap(Object, EnumSet)}.
      */
-    protected <T> T wrap(final T domainObject, final WrapperFactory.ExecutionMode executionMode) {
+    protected <T> T wrap(final T domainObject, final EnumSet<WrapperFactory.ExecutionMode> executionMode) {
         return wrapperFactory.wrap(domainObject, executionMode);
     }