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/07 19:39:08 UTC

[isis] branch v2 updated: ISIS-2158 minor code cleanup

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 f795f8a  ISIS-2158 minor code cleanup
f795f8a is described below

commit f795f8a32fe90067547c579520a139a57aefd5e6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Aug 7 21:38:50 2019 +0200

    ISIS-2158 minor code cleanup
---
 .../applib/services/wrapper/WrapperFactory.java    | 105 --------
 .../WrapperFactoryDefaultTest_wrappedObject.java   |   1 -
 ...FactoryDefaultTest_wrappedObject_transient.java |   1 -
 .../apache/isis/wrapper/WrapperFactoryDefault.java | 274 ++++++---------------
 .../InteractionEventDispatcherTypeSafe.java        |   7 +-
 .../handlers/DomainObjectInvocationHandler.java    |  29 +--
 .../isis/wrapper/handlers/ProxyContextHandler.java |  45 ++--
 .../apache/isis/wrapper/proxy/ProxyCreator.java    |  10 +-
 .../isis/wrapper/WrapperFactoryDefaultTest.java    |   3 +-
 .../background/BackgroundServiceDefault.java       |   3 -
 .../commandexecution/BackgroundExecutionTest.java  |  23 +-
 .../TransactionRollbackTest_withTransactional.java |   2 +
 12 files changed, 147 insertions(+), 356 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 b7240b9..b0d6971 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,12 +19,8 @@
 
 package org.apache.isis.applib.services.wrapper;
 
-import java.util.Collections;
 import java.util.List;
 
-import javax.inject.Inject;
-
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.wrapper.events.InteractionEvent;
 import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
@@ -114,80 +110,6 @@ public interface WrapperFactory {
         }
     }
 
-    WrapperFactory NOOP = new WrapperFactory(){
-
-        @Override
-        public <T> T wrap(T domainObject) {
-            return domainObject;
-        }
-
-        @Override public <T> T w(final T domainObject) {
-            return wrap(domainObject);
-        }
-
-        @Inject
-        FactoryService factoryService;
-
-        @Override
-        public <T> T wm(final Class<T> mixinClass, final Object mixedIn) {
-            return wrapMixin(mixinClass, mixedIn);
-        }
-
-        @Override
-        public <T> T wrapMixin(final Class<T> mixinClass, final Object mixedIn) {
-            return wrap(factoryService.mixin(mixinClass, mixedIn));
-        }
-
-        @Override
-        public <T> T wrapTry(T domainObject) {
-            return domainObject;
-        }
-
-        @Override
-        public <T> T wrapNoExecute(T domainObject) {
-            return domainObject;
-        }
-
-        @Override
-        public <T> T wrapSkipRules(T domainObject) {
-            return domainObject;
-        }
-
-        @Override
-        public <T> T wrap(T domainObject, ExecutionMode mode) {
-            return domainObject;
-        }
-
-        @Override
-        public <T> T unwrap(T possibleWrappedDomainObject) {
-            return possibleWrappedDomainObject;
-        }
-
-        @Override
-        public <T> boolean isWrapper(T possibleWrappedDomainObject) {
-            return false;
-        }
-
-        @Override
-        public List<InteractionListener> getListeners() {
-            return Collections.emptyList();
-        }
-
-        @Override
-        public boolean addInteractionListener(InteractionListener listener) {
-            return false;
-        }
-
-        @Override
-        public boolean removeInteractionListener(InteractionListener listener) {
-            return false;
-        }
-
-        @Override
-        public void notifyListeners(InteractionEvent ev) {
-        }
-    };
-
     /**
      * Provides the &quot;wrapper&quot; of the underlying domain object.
      *
@@ -195,46 +117,29 @@ public interface WrapperFactory {
      * If the object has (see {@link #isWrapper(Object)} already been wrapped),
      * then should just return the object back unchanged.
      */
-    @Programmatic
     <T> T wrap(T domainObject);
 
     /**
-     * Alias for {@link #wrap(Object)}.
-     */
-    @Programmatic
-    <T> T w(T domainObject);
-
-    /**
-     * Alias for {@link #wrapMixin(Class, Object)}
-     */
-    @Programmatic
-    <T> T wm(Class<T> mixinClass, Object mixedIn);
-
-    /**
      * {@link #wrap(Object) wraps} a {@link FactoryService#mixin(Class, Object) mixin}.
      */
-    @Programmatic
     <T> T wrapMixin(Class<T> mixinClass, Object mixedIn);
 
     /**
      * Convenience method for {@link #wrap(Object, ExecutionMode)} with {@link ExecutionMode#TRY},
      * to make this feature more discoverable.
      */
-    @Programmatic
     <T> T wrapTry(T domainObject);
 
     /**
      * Convenience method for {@link #wrap(Object, ExecutionMode)} with {@link ExecutionMode#NO_EXECUTE},
      * to make this feature more discoverable.
      */
-    @Programmatic
     <T> T wrapNoExecute(T domainObject);
 
     /**
      * Convenience method for {@link #wrap(Object, ExecutionMode)} with {@link ExecutionMode#SKIP_RULES},
      * to make this feature more discoverable.
      */
-    @Programmatic
     <T> T wrapSkipRules(T domainObject);
 
     /**
@@ -245,7 +150,6 @@ public interface WrapperFactory {
      * Otherwise, will do all the validations (raise exceptions as required
      * etc.), but doesn't modify the model.
      */
-    @Programmatic
     <T> T wrap(T domainObject, ExecutionMode mode);
 
 
@@ -256,7 +160,6 @@ public interface WrapperFactory {
      * If the object {@link #isWrapper(Object) is not wrapped}, then
      * should just return the object back unchanged.
      */
-    @Programmatic
     <T> T unwrap(T possibleWrappedDomainObject);
 
 
@@ -268,17 +171,12 @@ public interface WrapperFactory {
      *            - object that might or might not be a wrapper.
      * @return
      */
-    @Programmatic
     <T> boolean isWrapper(T possibleWrappedDomainObject);
 
-
-
-
     /**
      * All {@link InteractionListener}s that have been registered using
      * {@link #addInteractionListener(InteractionListener)}.
      */
-    @Programmatic
     List<InteractionListener> getListeners();
 
     /**
@@ -294,7 +192,6 @@ public interface WrapperFactory {
      * @param listener
      * @return
      */
-    @Programmatic
     public boolean addInteractionListener(InteractionListener listener);
 
     /**
@@ -310,10 +207,8 @@ public interface WrapperFactory {
      * @param listener
      * @return
      */
-    @Programmatic
     public boolean removeInteractionListener(InteractionListener listener);
 
-    @Programmatic
     public void notifyListeners(InteractionEvent ev);
 
 }
diff --git a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject.java b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject.java
index 8b9fe69..874330a 100644
--- a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject.java
+++ b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject.java
@@ -231,7 +231,6 @@ public class WrapperFactoryDefaultTest_wrappedObject {
 
 
         wrapperFactory.persistenceSessionServiceInternal = mockPersistenceSessionServiceInternal;
-        wrapperFactory.isisSessionFactory = mockIsisSessionFactory;
         wrapperFactory.authenticationSessionProvider = mockAuthenticationSessionProvider;
 
         final Method employeeGetNameMethod = methodOf(Employee.class, "getName");
diff --git a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
index 116633f..708f075 100644
--- a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
+++ b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
@@ -137,7 +137,6 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
 
         wrapperFactory.authenticationSessionProvider = mockAuthenticationSessionProvider;
         wrapperFactory.persistenceSessionServiceInternal = mockPersistenceSessionServiceInternal;
-        wrapperFactory.isisSessionFactory = mockIsisSessionFactory;
 
         context.checking(new Expectations() {
             {
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 8622f8e..59b3218 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
@@ -21,14 +21,15 @@ package org.apache.isis.wrapper;
 
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.BiConsumer;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrappingObject;
@@ -51,243 +52,114 @@ import org.apache.isis.applib.services.wrapper.events.PropertyUsabilityEvent;
 import org.apache.isis.applib.services.wrapper.events.PropertyVisibilityEvent;
 import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
 import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.metamodel.services.persistsession.PersistenceSessionServiceInternal;
-import org.apache.isis.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.security.authentication.AuthenticationSessionProvider;
 import org.apache.isis.wrapper.dispatchers.InteractionEventDispatcher;
 import org.apache.isis.wrapper.dispatchers.InteractionEventDispatcherTypeSafe;
 import org.apache.isis.wrapper.handlers.ProxyContextHandler;
 import org.apache.isis.wrapper.proxy.ProxyCreator;
 
+import lombok.val;
+
 /**
- * This service provides the ability to &quot;wrap&quot; of a domain object such that it can
- * be interacted with while enforcing the hide/disable/validate rules implies by
+ * This service provides the ability to 'wrap' a domain object such that it can
+ * be interacted with, while enforcing the hide/disable/validate rules as implied by
  * the Isis programming model.
- *
- * <p>
- * This implementation has no UI-visible actions and is the supported implementation, so it is annotated with
- * {@link org.apache.isis.applib.annotation.DomainService}.   This means that by including
- * <tt>o.a.i.core:isis-core-wrapper</tt> on the classpath, the service is automatically registered; no further
- * configuration is required.
  */
 @Singleton
 public class WrapperFactoryDefault implements WrapperFactory {
 
     private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
-    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> dispatchersByEventClass = new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
-
-
     private final ProxyContextHandler proxyContextHandler;
+    private final Map<Class<? extends InteractionEvent>, InteractionEventDispatcher> 
+        dispatchersByEventClass = 
+            new HashMap<Class<? extends InteractionEvent>, InteractionEventDispatcher>();
 
     public WrapperFactoryDefault() {
         this(new ProxyCreator());
     }
-    WrapperFactoryDefault(final ProxyCreator proxyCreator) {
+    
+    WrapperFactoryDefault(ProxyCreator proxyCreator) {
 
         proxyContextHandler = new ProxyContextHandler(proxyCreator);
-
-        dispatchersByEventClass.put(ObjectTitleEvent.class, new InteractionEventDispatcherTypeSafe<ObjectTitleEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectTitleEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectTitleRead(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<PropertyUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyAccessEvent.class, new InteractionEventDispatcherTypeSafe<PropertyAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(PropertyModifyEvent.class, new InteractionEventDispatcherTypeSafe<PropertyModifyEvent>() {
-            @Override
-            public void dispatchTypeSafe(final PropertyModifyEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.propertyModified(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<CollectionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAccessEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAccessEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAccessEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAccessed(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionAddToEvent.class, new InteractionEventDispatcherTypeSafe<CollectionAddToEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionAddToEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionAddedTo(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionRemoveFromEvent.class, new InteractionEventDispatcherTypeSafe<CollectionRemoveFromEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionRemoveFromEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionRemovedFrom(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionVisibilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionVisibilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionVisibilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionVisible(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionUsabilityEvent.class, new InteractionEventDispatcherTypeSafe<ActionUsabilityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionUsabilityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionUsable(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionArgumentEvent.class, new InteractionEventDispatcherTypeSafe<ActionArgumentEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionArgumentEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionArgument(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ActionInvocationEvent.class, new InteractionEventDispatcherTypeSafe<ActionInvocationEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ActionInvocationEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.actionInvoked(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(ObjectValidityEvent.class, new InteractionEventDispatcherTypeSafe<ObjectValidityEvent>() {
-            @Override
-            public void dispatchTypeSafe(final ObjectValidityEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.objectPersisted(interactionEvent);
-                }
-            }
-        });
-        dispatchersByEventClass.put(CollectionMethodEvent.class, new InteractionEventDispatcherTypeSafe<CollectionMethodEvent>() {
-            @Override
-            public void dispatchTypeSafe(final CollectionMethodEvent interactionEvent) {
-                for (final InteractionListener l : getListeners()) {
-                    l.collectionMethodInvoked(interactionEvent);
-                }
-            }
-        });
+        
+        putDispatcher(ObjectTitleEvent.class, (listener, event)->listener.objectTitleRead(event));
+        putDispatcher(PropertyVisibilityEvent.class, (listener, event)->listener.propertyVisible(event));
+        putDispatcher(PropertyUsabilityEvent.class, (listener, event)->listener.propertyUsable(event));
+        putDispatcher(PropertyAccessEvent.class, (listener, event)->listener.propertyAccessed(event));
+        putDispatcher(PropertyModifyEvent.class, (listener, event)->listener.propertyModified(event));
+        putDispatcher(CollectionVisibilityEvent.class, (listener, event)->listener.collectionVisible(event));
+        putDispatcher(CollectionUsabilityEvent.class, (listener, event)->listener.collectionUsable(event));
+        putDispatcher(CollectionAccessEvent.class, (listener, event)->listener.collectionAccessed(event));
+        putDispatcher(CollectionAddToEvent.class, (listener, event)->listener.collectionAddedTo(event));
+        putDispatcher(CollectionRemoveFromEvent.class, (listener, event)->listener.collectionRemovedFrom(event));
+        putDispatcher(ActionVisibilityEvent.class, (listener, event)->listener.actionVisible(event));
+        putDispatcher(ActionUsabilityEvent.class, (listener, event)->listener.actionUsable(event));
+        putDispatcher(ActionArgumentEvent.class, (listener, event)->listener.actionArgument(event));
+        putDispatcher(ActionInvocationEvent.class, (listener, event)->listener.actionInvoked(event));
+        putDispatcher(ObjectValidityEvent.class, (listener, event)->listener.objectPersisted(event));
+        putDispatcher(CollectionMethodEvent.class, (listener, event)->listener.collectionMethodInvoked(event));
     }
 
     // /////////////////////////////////////////////////////////////
     // wrap and unwrap
     // /////////////////////////////////////////////////////////////
-
-    @Override
-    public <T> T wm(final Class<T> mixinClass, final Object mixedIn) {
-        return w(factoryService.mixin(mixinClass, mixedIn));
-    }
-
+    
     @Override
-    public <T> T wrapMixin(final Class<T> mixinClass, final Object mixedIn) {
-        return w(factoryService.mixin(mixinClass, mixedIn));
-    }
-
-    @Override
-    public <T> T w(final T domainObject) {
-        return wrap(domainObject, ExecutionMode.EXECUTE);
+    public <T> T wrapMixin(Class<T> mixinClass, Object mixedIn) {
+        return wrap(factoryService.mixin(mixinClass, mixedIn));
     }
 
     @Override
-    public <T> T wrap(final T domainObject) {
+    public <T> T wrap(T domainObject) {
         return wrap(domainObject, ExecutionMode.EXECUTE);
     }
 
     @Override
-    public <T> T wrapTry(final T domainObject) {
+    public <T> T wrapTry(T domainObject) {
         return wrap(domainObject, ExecutionMode.TRY);
     }
 
     @Override
-    public <T> T wrapNoExecute(final T domainObject) {
+    public <T> T wrapNoExecute(T domainObject) {
         return wrap(domainObject, ExecutionMode.NO_EXECUTE);
     }
 
     @Override
-    public <T> T wrapSkipRules(final T domainObject) {
+    public <T> T wrapSkipRules(T domainObject) {
         return wrap(domainObject, ExecutionMode.SKIP_RULES);
     }
 
     @Override
-    public <T> T wrap(final T domainObject, final ExecutionMode mode) {
+    public <T> T wrap(T domainObject, ExecutionMode mode) {
         if (domainObject instanceof WrappingObject) {
-            final WrappingObject wrapperObject = (WrappingObject) domainObject;
-            final ExecutionMode wrapperMode = wrapperObject.__isis_executionMode();
-            if(wrapperMode != mode) {
-                final Object underlyingDomainObject = wrapperObject.__isis_wrapped();
-                return _Casts.uncheckedCast(createProxy(underlyingDomainObject, mode, isisSessionFactory));
+            val wrapperObject = (WrappingObject) domainObject;
+            val executionMode = wrapperObject.__isis_executionMode();
+            if(executionMode != mode) {
+                val underlyingDomainObject = wrapperObject.__isis_wrapped();
+                return _Casts.uncheckedCast(createProxy(underlyingDomainObject, mode));
             }
             return domainObject;
         }
-        return createProxy(domainObject, mode, isisSessionFactory);
+        return createProxy(domainObject, mode);
     }
 
-    protected <T> T createProxy(
-            final T domainObject,
-            final ExecutionMode mode,
-            final IsisSessionFactory isisSessionFactory) {
-        return proxyContextHandler.proxy(domainObject, mode, isisSessionFactory);
+    protected <T> T createProxy(T domainObject, ExecutionMode mode) {
+        
+        return proxyContextHandler.proxy(domainObject, mode);
     }
 
     @Override
-    public boolean isWrapper(final Object possibleWrappedDomainObject) {
+    public boolean isWrapper(Object possibleWrappedDomainObject) {
         return possibleWrappedDomainObject instanceof WrappingObject;
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    @Programmatic
     public <T> T unwrap(T possibleWrappedDomainObject) {
         if(isWrapper(possibleWrappedDomainObject)) {
-            final WrappingObject wrappingObject = (WrappingObject) possibleWrappedDomainObject;
-            return (T) wrappingObject.__isis_wrapped();
+            val wrappingObject = (WrappingObject) possibleWrappedDomainObject;
+            return _Casts.uncheckedCast(wrappingObject.__isis_wrapped());
         }
         return possibleWrappedDomainObject;
     }
@@ -298,39 +170,51 @@ public class WrapperFactoryDefault implements WrapperFactory {
 
     @Override
     public List<InteractionListener> getListeners() {
-        return listeners;
+        return Collections.unmodifiableList(listeners);
     }
 
     @Override
-    public boolean addInteractionListener(final InteractionListener listener) {
+    public boolean addInteractionListener(InteractionListener listener) {
         return listeners.add(listener);
     }
 
     @Override
-    public boolean removeInteractionListener(final InteractionListener listener) {
+    public boolean removeInteractionListener(InteractionListener listener) {
         return listeners.remove(listener);
     }
 
     @Override
-    public void notifyListeners(final InteractionEvent interactionEvent) {
-        final InteractionEventDispatcher dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
+    public void notifyListeners(InteractionEvent interactionEvent) {
+        val dispatcher = dispatchersByEventClass.get(interactionEvent.getClass());
         if (dispatcher == null) {
-            throw new RuntimeException("Unknown InteractionEvent - register into dispatchers map");
+            val msg = String.format("Unknown InteractionEvent %s - "
+                    + "needs registering into dispatchers map", interactionEvent.getClass());
+            throw _Exceptions.unrecoverable(msg);
         }
         dispatcher.dispatch(interactionEvent);
     }
+    
+    // -- HELPER - SETUP
+    
+    private <T extends InteractionEvent> void putDispatcher(
+            Class<T> type, BiConsumer<InteractionListener, T> onDispatch) {
+    
+        val dispatcher = new InteractionEventDispatcherTypeSafe<T>() {
+            @Override
+            public void dispatchTypeSafe(T interactionEvent) {
+                for (InteractionListener l : listeners) {
+                    onDispatch.accept(l, interactionEvent);
+                }
+            }
+        };
+        
+        dispatchersByEventClass.put(type, dispatcher);
+    }
+    
+    // -- DEPENDENCES
 
-
-    @Inject
-    AuthenticationSessionProvider authenticationSessionProvider;
-
-    @Inject
-    PersistenceSessionServiceInternal persistenceSessionServiceInternal;
-
-    @Inject
-    IsisSessionFactory isisSessionFactory;
-
-    @Inject
-    FactoryService factoryService;
+    @Inject AuthenticationSessionProvider authenticationSessionProvider;
+    @Inject PersistenceSessionServiceInternal persistenceSessionServiceInternal;
+    @Inject FactoryService factoryService;
 
 }
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/dispatchers/InteractionEventDispatcherTypeSafe.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/dispatchers/InteractionEventDispatcherTypeSafe.java
index 615bf42..714b8fc 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/dispatchers/InteractionEventDispatcherTypeSafe.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/dispatchers/InteractionEventDispatcherTypeSafe.java
@@ -20,15 +20,16 @@
 package org.apache.isis.wrapper.dispatchers;
 
 import org.apache.isis.applib.services.wrapper.events.InteractionEvent;
+import org.apache.isis.commons.internal.base._Casts;
 
-public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> implements InteractionEventDispatcher {
+public abstract class InteractionEventDispatcherTypeSafe<T extends InteractionEvent> 
+implements InteractionEventDispatcher {
 
     public abstract void dispatchTypeSafe(T interactionEvent);
 
     @Override
-    @SuppressWarnings("unchecked")
     public void dispatch(final InteractionEvent interactionEvent) {
-        dispatchTypeSafe((T) interactionEvent);
+        dispatchTypeSafe(_Casts.<T>uncheckedCast(interactionEvent));
     }
 
 }
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 68cfd82..d06577b 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
@@ -69,20 +69,15 @@ import org.apache.isis.metamodel.specloader.specimpl.ObjectActionContributee;
 import org.apache.isis.metamodel.specloader.specimpl.ObjectActionMixedIn;
 import org.apache.isis.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
 import org.apache.isis.runtime.system.context.IsisContext;
-import org.apache.isis.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.security.authentication.AuthenticationSession;
-import org.apache.isis.security.authentication.AuthenticationSessionProvider;
 
 import lombok.val;
 
 public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandlerDefault<T> {
 
-    private final AuthenticationSessionProvider authenticationSessionProvider;
-    private final ObjectAdapterProvider objectAdapterProvider;
-
     private final ProxyContextHandler proxy;
     private final ExecutionMode executionMode;
-    private final IsisSessionFactory isisSessionFactory;
+    private final MetaModelContext mmContext;
 
     /**
      * The <tt>title()</tt> method; may be <tt>null</tt>.
@@ -109,19 +104,13 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
     public DomainObjectInvocationHandler(
             final T delegate,
             final ExecutionMode mode,
-            final ProxyContextHandler proxy,
-            final IsisSessionFactory isisSessionFactory) {
+            final ProxyContextHandler proxy) {
+        
         super(delegate, mode);
 
+        this.mmContext = MetaModelContext.current();
         this.proxy = proxy;
         this.executionMode = mode;
-        this.isisSessionFactory = isisSessionFactory;
-
-        final MetaModelContext context = MetaModelContext.current();
-
-        this.authenticationSessionProvider = context.getAuthenticationSessionProvider(); 
-        this.objectAdapterProvider = context.getObjectAdapterProvider();
-
 
         try {
             titleMethod = delegate.getClass().getMethod("title", new Class[]{});
@@ -947,18 +936,14 @@ public class DomainObjectInvocationHandler<T> extends DelegatingInvocationHandle
     // /////////////////////////////////////////////////////////////////
 
     protected SpecificationLoader getSpecificationLoader() {
-        return IsisContext.getSpecificationLoader();
-    }
-
-    public AuthenticationSessionProvider getAuthenticationSessionProvider() {
-        return authenticationSessionProvider;
+        return mmContext.getSpecificationLoader();
     }
 
     protected AuthenticationSession getAuthenticationSession() {
-        return getAuthenticationSessionProvider().getAuthenticationSession();
+        return mmContext.getAuthenticationSession();
     }
 
     protected ObjectAdapterProvider getObjectAdapterProvider() {
-        return objectAdapterProvider;
+        return mmContext.getObjectAdapterProvider();
     }
 }
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 3c65567..aec7332 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
@@ -24,25 +24,23 @@ import java.util.Map;
 
 import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
 import org.apache.isis.metamodel.spec.feature.OneToManyAssociation;
-import org.apache.isis.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.wrapper.proxy.ProxyCreator;
 
-public class ProxyContextHandler {
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
 
-    private final ProxyCreator proxyCreator;
+@RequiredArgsConstructor
+public class ProxyContextHandler {
 
-    public ProxyContextHandler(final ProxyCreator proxyCreator) {
-        this.proxyCreator = proxyCreator;
-    }
+    @NonNull private final ProxyCreator proxyCreator;
 
-    public <T> T proxy(
-            final T domainObject,
-            final ExecutionMode mode,
-            final IsisSessionFactory isisSessionFactory) {
+    public <T> T proxy(T domainObject, ExecutionMode mode) {
 
-        final DomainObjectInvocationHandler<T> invocationHandler = new DomainObjectInvocationHandler<T>(domainObject,
+        val invocationHandler = new DomainObjectInvocationHandler<T>(
+                domainObject,
                 mode,
-                this, isisSessionFactory);
+                this);
 
         return proxyCreator.instantiateProxy(invocationHandler);
     }
@@ -51,10 +49,16 @@ public class ProxyContextHandler {
      * Whether to execute or not will be picked up from the supplied parent
      * handler.
      */
-    public <T, E> Collection<E> proxy(final Collection<E> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
+    public <T, E> Collection<E> proxy(
+            final Collection<E> collectionToProxy, 
+            final String collectionName, 
+            final DomainObjectInvocationHandler<T> handler, 
+            final OneToManyAssociation otma) {
 
-        final CollectionInvocationHandler<T, Collection<E>> collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(collectionToProxy, collectionName, handler, otma);
-        collectionInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
+        val collectionInvocationHandler = new CollectionInvocationHandler<T, Collection<E>>(
+                        collectionToProxy, collectionName, handler, otma);
+        collectionInvocationHandler.setResolveObjectChangedEnabled(
+                handler.isResolveObjectChangedEnabled());
 
         return proxyCreator.instantiateProxy(collectionInvocationHandler);
     }
@@ -63,9 +67,14 @@ public class ProxyContextHandler {
      * Whether to execute or not will be picked up from the supplied parent
      * handler.
      */
-    public <T, P, Q> Map<P, Q> proxy(final Map<P, Q> collectionToProxy, final String collectionName, final DomainObjectInvocationHandler<T> handler, final OneToManyAssociation otma) {
-
-        final MapInvocationHandler<T, Map<P, Q>> mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(collectionToProxy, collectionName, handler, otma);
+    public <T, P, Q> Map<P, Q> proxy(
+            final Map<P, Q> collectionToProxy, 
+            final String collectionName, 
+            final DomainObjectInvocationHandler<T> handler, 
+            final OneToManyAssociation otma) {
+
+        val mapInvocationHandler = new MapInvocationHandler<T, Map<P, Q>>(
+                collectionToProxy, collectionName, handler, otma);
         mapInvocationHandler.setResolveObjectChangedEnabled(handler.isResolveObjectChangedEnabled());
 
         return proxyCreator.instantiateProxy(mapInvocationHandler);
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/proxy/ProxyCreator.java b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/proxy/ProxyCreator.java
index 64a3b6d..8b77c99 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/proxy/ProxyCreator.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/wrapper/proxy/ProxyCreator.java
@@ -32,18 +32,18 @@ import org.apache.isis.commons.internal.plugins.codegen.ProxyFactory;
 import org.apache.isis.metamodel.specloader.classsubstitutor.ProxyEnhanced;
 import org.apache.isis.wrapper.handlers.DelegatingInvocationHandler;
 
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
 public class ProxyCreator {
 
-    private final Map<Class<?>, ProxyFactory<?>> proxyFactoryByClass;
+    @NonNull private final Map<Class<?>, ProxyFactory<?>> proxyFactoryByClass;
 
     public ProxyCreator() {
         this(Collections.synchronizedMap(new WeakHashMap<>()));
     }
 
-    public ProxyCreator(Map<Class<?>, ProxyFactory<?>> proxyFactoryByClass) {
-        this.proxyFactoryByClass = proxyFactoryByClass;
-    }
-
     public <T> T instantiateProxy(final DelegatingInvocationHandler<T> handler) {
 
         final T toProxy = handler.getDelegate();
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 ac60a7d..eed6af9 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
@@ -25,7 +25,6 @@ import org.junit.Test;
 
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.wrapper.WrappingObject;
-import org.apache.isis.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.unittestsupport.jmocking.JUnitRuleMockery2;
 import org.apache.isis.wrapper.proxy.ProxyCreator;
 
@@ -79,7 +78,7 @@ public class WrapperFactoryDefaultTest {
         wrapperFactory = new WrapperFactoryDefault(mockProxyCreator) {
 
             @Override
-            protected <T> T createProxy(T domainObject, ExecutionMode mode, final IsisSessionFactory isisSessionFactory) {
+            protected <T> T createProxy(T domainObject, ExecutionMode mode) {
                 WrapperFactoryDefaultTest.this.createProxyCalledWithMode = mode;
                 WrapperFactoryDefaultTest.this.createProxyCalledWithDomainObject = (DomainObject) domainObject;
                 return domainObject;
diff --git a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/background/BackgroundServiceDefault.java b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/background/BackgroundServiceDefault.java
index e7ec856..1ecdce3 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/runtime/services/background/BackgroundServiceDefault.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/runtime/services/background/BackgroundServiceDefault.java
@@ -147,7 +147,4 @@ public class BackgroundServiceDefault implements BackgroundService {
     @Inject private TransactionService transactionService;
 
 
-
-
-
 }
diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/commandexecution/BackgroundExecutionTest.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/commandexecution/BackgroundExecutionTest.java
index 3299d45..fb99a65 100644
--- a/examples/smoketests/src/test/java/org/apache/isis/testdomain/commandexecution/BackgroundExecutionTest.java
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/commandexecution/BackgroundExecutionTest.java
@@ -33,6 +33,7 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.services.background.BackgroundService;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.extensions.fixtures.fixturescripts.FixtureScripts;
 import org.apache.isis.testdomain.jdo.InventoryManager;
 import org.apache.isis.testdomain.jdo.JdoTestDomainModule;
@@ -62,6 +63,7 @@ class BackgroundExecutionTest {
     @Inject RepositoryService repository;
     @Inject BackgroundService backgroundService;
     @Inject FactoryService facoryService;
+    @Inject WrapperFactory wrapperFactory;
     @Inject ActionDomainEventListener actionDomainEventListener;
 
     @BeforeEach
@@ -105,6 +107,25 @@ class BackgroundExecutionTest {
 
         assertEquals(123d, product.getPrice(), 1E-6);
     }
+    
+    @Test
+    void testWrapper_waitingOnDomainEvent() throws InterruptedException, ExecutionException {
+
+        val inventoryManager = facoryService.viewModel(InventoryManager.class);
+        val product = repository.allInstances(Product.class).get(0);
+
+        assertEquals(99d, product.getPrice(), 1E-6);
+
+        actionDomainEventListener.prepareLatch();
+
+        wrapperFactory.wrap(inventoryManager).updateProductPrice(product, 123);
+
+        assertTrue(
+                actionDomainEventListener.getCountDownLatch()
+                .await(5, TimeUnit.SECONDS));
+
+        assertEquals(123d, product.getPrice(), 1E-6);
+    }
 
 
     @Service
@@ -115,7 +136,7 @@ class BackgroundExecutionTest {
         @EventListener(InventoryManager.UpdateProductPriceEvent.class)
         public void hi(InventoryManager.UpdateProductPriceEvent event) {
             //FIXME[2125] not triggered yet
-            System.err.println("!!!!!!!!!!!! hiho");
+            System.err.println("!!!!!!!!!!!! event " + event.getEventPhase());
             countDownLatch.countDown();
         }
 
diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/transactions/TransactionRollbackTest_withTransactional.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/transactions/TransactionRollbackTest_withTransactional.java
index 334a578..8df6b91 100644
--- a/examples/smoketests/src/test/java/org/apache/isis/testdomain/transactions/TransactionRollbackTest_withTransactional.java
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/transactions/TransactionRollbackTest_withTransactional.java
@@ -77,6 +77,8 @@ class TransactionRollbackTest_withTransactional {
     @Test @Order(2)
     void previousTest_shouldHaveBeenRolledBack() {
         
+        
+        
         // expected condition
         assertEquals(0, repository.allInstances(Book.class).size());
     }