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

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


The following commit(s) were added to refs/heads/master by this push:
     new 38c9255  ISIS-2464: semantic renaming audit/dispatch -> publishing (5)
38c9255 is described below

commit 38c92555bab9d27ca836ab023b6944dd4f54c38b
Author: Andi Huber <[email protected]>
AuthorDate: Fri Nov 20 11:04:32 2020 +0100

    ISIS-2464: semantic renaming audit/dispatch -> publishing (5)
---
 .../services/publishing/log/CommandLogger.java     |  25 ++++-
 ...ctionInvocationFacetForDomainEventAbstract.java |   8 +-
 .../autocomplete/AutoCompleteFacetAbstract.java    |   8 +-
 ...tySetterOrClearFacetForDomainEventAbstract.java |   8 +-
 .../publish/ExecutionDispatchPropertyFacet.java    |   4 +-
 .../services/command/CommandPublisher.java         |  20 ----
 ...cutionDispatcher.java => CommandPublisher.java} |  31 ++++--
 ...tionDispatcher.java => ExecutionPublisher.java} |  13 ++-
 .../specimpl/OneToManyAssociationMixedIn.java      |   8 +-
 .../specimpl/OneToOneAssociationMixedIn.java       |   8 +-
 .../isis/core/runtime/IsisModuleCoreRuntime.java   |   2 -
 .../changetracking/EntityChangeTrackerDefault.java |  28 ++++--
 .../changetracking/EntityChangesPublisher.java     |   6 ++
 .../EntityPropertyChangeFactory.java               |  42 ++++++++
 .../EntityPropertyChangePublisher.java             | 107 +--------------------
 ....java => HasEnlistedEntityPropertyChanges.java} |  10 +-
 .../IsisModuleCoreRuntimeServices.java             |   8 +-
 .../publish}/CommandPublisherDefault.java          |  61 ++++++------
 .../publish/EntityChangesPublisherDefault.java     |   8 +-
 ...a => EntityPropertyChangePublisherDefault.java} |  55 ++++++-----
 ...Default.java => ExecutionPublisherDefault.java} |  44 +++++----
 .../persistence/IsisPersistenceSessionJdoBase.java |   2 +-
 22 files changed, 249 insertions(+), 257 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
index cc26abb..42fa526 100644
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/services/publishing/log/CommandLogger.java
@@ -1,3 +1,21 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
 package org.apache.isis.applib.services.publishing.log;
 
 import javax.inject.Named;
@@ -28,7 +46,12 @@ public class CommandLogger implements CommandSubscriber {
 
     @Override
     public void onCompleted(Command command) {
-        log.debug("completed: {}", command);
+        
+        log.debug("completed: {}, systemStateChanged {}",
+                command.getLogicalMemberIdentifier(),
+                command.isSystemStateChanged());
+        
+        //log.debug("completed: {}", command);
     }
 
 }
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 ac164fd..4907284 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
@@ -58,7 +58,7 @@ import 
org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFa
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import 
org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.UnwrapUtil;
@@ -218,7 +218,7 @@ implements ImperativeFacet {
         // publish (if not a contributed association, query-only mixin)
         val publishedActionFacet = 
getIdentified().getFacet(PublishedActionFacet.class);
         if (publishedActionFacet != null) {
-            getExecutionDispatcher().dispatchActionInvoking(priorExecution);
+            getExecutionDispatcher().publishActionInvocation(priorExecution);
         }
 
         return filteredIfRequired(returnedAdapter, interactionInitiatedBy);
@@ -372,8 +372,8 @@ implements ImperativeFacet {
         return serviceRegistry.lookupServiceElseFail(MetricsService.class);
     }
 
-    private ExecutionDispatcher getExecutionDispatcher() {
-        return 
serviceRegistry.lookupServiceElseFail(ExecutionDispatcher.class);
+    private ExecutionPublisher getExecutionDispatcher() {
+        return serviceRegistry.lookupServiceElseFail(ExecutionPublisher.class);
     }
 
     private InteractionDtoServiceInternal getInteractionDtoServiceInternal() {
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
index ff4d163..606ed71 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/autocomplete/AutoCompleteFacetAbstract.java
@@ -30,7 +30,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.param.autocomplete.MinLengthUtil;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 
@@ -75,7 +75,7 @@ implements AutoCompleteFacet {
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         val resultAdapter = getPublisherDispatchService()
-        .withDispatchSuppressed(()->{
+        .withPublishingSuppressed(()->{
                 final Object list = _Reflect.invokeMethodOn(repositoryMethod, 
getRepository(), search)
                         .onFailure(e->log.warn("failure while executing 
auto-complete", e))
                         .getOrElse(Collections::emptyList);
@@ -91,8 +91,8 @@ implements AutoCompleteFacet {
         return 
getServiceRegistry().lookupService(repositoryClass).orElse(null);
     }
 
-    private ExecutionDispatcher getPublisherDispatchService() {
-        return 
getServiceRegistry().lookupServiceElseFail(ExecutionDispatcher.class);
+    private ExecutionPublisher getPublisherDispatchService() {
+        return 
getServiceRegistry().lookupServiceElseFail(ExecutionPublisher.class);
     }
 
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index 6a50b0e..b4ca3b6 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -43,7 +43,7 @@ import 
org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyCle
 import 
org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacet;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import 
org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.UnwrapUtil;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
@@ -293,7 +293,7 @@ extends SingleValueFacetAbstract<Class<? extends 
PropertyDomainEvent<?,?>>> {
         // publish (if not a contributed association, query-only mixin)
         val publishedPropertyFacet = 
getIdentified().getFacet(ExecutionDispatchPropertyFacet.class);
         if (publishedPropertyFacet != null) {
-            getExecutionDispatcher().dispatchPropertyChanging(priorExecution);
+            getExecutionDispatcher().publishPropertyEdit(priorExecution);
         }
 
         return getObjectManager().adapt(targetPojo);
@@ -331,8 +331,8 @@ extends SingleValueFacetAbstract<Class<? extends 
PropertyDomainEvent<?,?>>> {
         return 
getServiceRegistry().lookupServiceElseFail(MetricsService.class);
     }
 
-    private ExecutionDispatcher getExecutionDispatcher() {
-        return 
getServiceRegistry().lookupServiceElseFail(ExecutionDispatcher.class);
+    private ExecutionPublisher getExecutionDispatcher() {
+        return 
getServiceRegistry().lookupServiceElseFail(ExecutionPublisher.class);
     }
 
     @Override public void appendAttributesTo(final Map<String, Object> 
attributeMap) {
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/publish/ExecutionDispatchPropertyFacet.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/publish/ExecutionDispatchPropertyFacet.java
index 4f35b0b..d8e43c2 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/publish/ExecutionDispatchPropertyFacet.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/publish/ExecutionDispatchPropertyFacet.java
@@ -23,14 +23,14 @@ import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 
 import lombok.NonNull;
 import lombok.val;
 
 /**
  * Indicates that editing of the property, captured by an {@link 
Interaction.Execution},
- * should be dispatched via {@link ExecutionDispatcher} to all subscribed 
+ * should be dispatched via {@link ExecutionPublisher} to all subscribed 
  * {@link ExecutionSubscriber}s.
  */
 public interface ExecutionDispatchPropertyFacet extends Facet {
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisher.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisher.java
deleted file mode 100644
index a02d7f3..0000000
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisher.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.apache.isis.core.metamodel.services.command;
-
-import org.apache.isis.applib.services.command.Command;
-
-import lombok.NonNull;
-
-public interface CommandPublisher {
-
-    /**
-     * &quot;Complete&quot; the command, providing an opportunity ot persist
-     * a memento of the command if the
-     * {@link Command#isSystemStateChanged() system state has changed}.
-     *
-     * <p>
-     *     The framework will automatically have set the {@link 
Command#getCompletedAt()} property.
-     * </p>
-     */
-    void complete(@NonNull Command command);
-
-}
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/CommandPublisher.java
similarity index 56%
copy from 
core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
copy to 
core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/CommandPublisher.java
index 14cbc45..fd2d67f 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/CommandPublisher.java
@@ -18,19 +18,30 @@
  */
 package org.apache.isis.core.metamodel.services.publishing;
 
-import java.util.function.Supplier;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
 
-import org.apache.isis.applib.services.iactn.Interaction;
+import lombok.NonNull;
 
-public interface ExecutionDispatcher {
-
-    void dispatchActionInvoking(Interaction.Execution<?,?> execution);
-
-    void dispatchPropertyChanging(Interaction.Execution<?,?> execution);
+/**
+ * Notifies {@link CommandSubscriber}s.
+ * @since 2.0
+ */
+//tag::refguide[]
+public interface CommandPublisher {
 
     /**
-     * Slightly hokey wormhole (anti)pattern to disable publishing for mixin 
associations.
+     * &quot;Complete&quot; the command, providing an opportunity ot persist
+     * a memento of the command if the
+     * {@link Command#isSystemStateChanged() system state has changed}.
+     *
+     * <p>
+     *     The framework will automatically have set the {@link 
Command#getCompletedAt()} property.
+     * </p>
      */
-    <T> T withDispatchSuppressed(Supplier<T> block);
-
+    // end::refguide[]
+    void complete(@NonNull Command command); // <.>
+    //tag::refguide[]
+    
 }
+// end::refguide[]
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
similarity index 74%
rename from 
core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
rename to 
core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
index 14cbc45..a5a6ebc 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionDispatcher.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/publishing/ExecutionPublisher.java
@@ -21,16 +21,21 @@ package org.apache.isis.core.metamodel.services.publishing;
 import java.util.function.Supplier;
 
 import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
 
-public interface ExecutionDispatcher {
+/**
+ * Notifies {@link ExecutionSubscriber}s.
+ * @since 2.0
+ */
+public interface ExecutionPublisher {
 
-    void dispatchActionInvoking(Interaction.Execution<?,?> execution);
+    void publishActionInvocation(Interaction.Execution<?,?> execution);
 
-    void dispatchPropertyChanging(Interaction.Execution<?,?> execution);
+    void publishPropertyEdit(Interaction.Execution<?,?> execution);
 
     /**
      * Slightly hokey wormhole (anti)pattern to disable publishing for mixin 
associations.
      */
-    <T> T withDispatchSuppressed(Supplier<T> block);
+    <T> T withPublishingSuppressed(Supplier<T> block);
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index ee3fdf5..c9bc5b6 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -36,7 +36,7 @@ import 
org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForCo
 import 
org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
 import 
org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -153,7 +153,7 @@ public class OneToManyAssociationMixedIn extends 
OneToManyAssociationDefault imp
             final ManagedObject ownerAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
         
-        return getPublishingServiceInternal().withDispatchSuppressed(
+        return getPublishingServiceInternal().withPublishingSuppressed(
                 () -> mixinAction.executeInternal(
                         headFor(ownerAdapter), Can.empty(), 
interactionInitiatedBy));
     }
@@ -188,8 +188,8 @@ public class OneToManyAssociationMixedIn extends 
OneToManyAssociationDefault imp
         return this.mixinAction == mixinAction;
     }
 
-    private ExecutionDispatcher getPublishingServiceInternal() {
-        return 
getServiceRegistry().lookupServiceElseFail(ExecutionDispatcher.class);
+    private ExecutionPublisher getPublishingServiceInternal() {
+        return 
getServiceRegistry().lookupServiceElseFail(ExecutionPublisher.class);
     }
 
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index bb5dfbc..e0f0dfb 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -34,7 +34,7 @@ import 
org.apache.isis.core.metamodel.facets.members.disabled.DisabledFacetForCo
 import 
org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
 import 
org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -139,7 +139,7 @@ public class OneToOneAssociationMixedIn extends 
OneToOneAssociationDefault imple
 
         val head = headFor(mixedInAdapter);
         
-        return getPublisherDispatchService().withDispatchSuppressed(
+        return getPublisherDispatchService().withPublishingSuppressed(
                 () -> mixinAction.executeInternal(head, Can.empty(), 
interactionInitiatedBy)
         );
     }
@@ -174,8 +174,8 @@ public class OneToOneAssociationMixedIn extends 
OneToOneAssociationDefault imple
         return this.mixinAction == mixinAction;
     }
 
-    private ExecutionDispatcher getPublisherDispatchService() {
-        return 
getServiceRegistry().lookupServiceElseFail(ExecutionDispatcher.class);
+    private ExecutionPublisher getPublisherDispatchService() {
+        return 
getServiceRegistry().lookupServiceElseFail(ExecutionPublisher.class);
     }
 
 
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
index 820331f..99a0b66 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisModuleCoreRuntime.java
@@ -27,7 +27,6 @@ import org.apache.isis.core.metamodel.IsisModuleCoreMetamodel;
 import org.apache.isis.core.runtime.events.RuntimeEventService;
 import org.apache.isis.core.runtime.events.persistence.TimestampService;
 import 
org.apache.isis.core.runtime.iactn.scope.IsisInteractionScopeBeanFactoryPostProcessor;
-import 
org.apache.isis.core.runtime.persistence.changetracking.EntityPropertyChangePublisher;
 import 
org.apache.isis.core.runtime.persistence.changetracking.EntityChangeTrackerDefault;
 
 @Configuration
@@ -38,7 +37,6 @@ import 
org.apache.isis.core.runtime.persistence.changetracking.EntityChangeTrack
         // @Service's
         RuntimeEventService.class,
         TimestampService.class,
-        EntityPropertyChangePublisher.class,
         EntityChangeTrackerDefault.class,
 
         // @Configuration's
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangeTrackerDefault.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangeTrackerDefault.java
index 1b652da..6b56262 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangeTrackerDefault.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangeTrackerDefault.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Function;
+import java.util.stream.Stream;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -43,7 +44,9 @@ import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.iactn.InteractionContext;
 import org.apache.isis.applib.services.metrics.MetricsService;
 import org.apache.isis.applib.services.publishing.spi.EntityChanges;
+import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
 import org.apache.isis.applib.services.user.UserService;
+import org.apache.isis.applib.services.xactn.TransactionId;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Sets;
@@ -89,13 +92,13 @@ implements
     TransactionScopeListener,
     MetricsService,
     EntityChangeTracker,
-    HasEnlistedEntityPropertyChangeRecords, 
+    HasEnlistedEntityPropertyChanges, 
     HasEnlistedEntityChanges {
 
     // end::refguide[]
     
-    @Inject private EntityPropertyChangePublisher entityAuditDispatcher;
-    @Inject private EntityChangesPublisher changingEntitiesDispatcher;
+    @Inject private EntityPropertyChangePublisher 
entityPropertyChangePublisher;
+    @Inject private EntityChangesPublisher entityChangesPublisher;
     @Inject private EventBusService eventBusService;
     @Inject private Provider<InteractionContext> interactionContextProvider;
     
@@ -149,9 +152,7 @@ implements
         enlistForPreAndPostValueAuditing(adapter, 
aap->PreAndPostValues.pre(aap.getPropertyValue()));
     }
 
-
-    @Override
-    public Set<PropertyChangeRecord> getPropertyChangeRecords() {
+    private Set<PropertyChangeRecord> getPropertyChangeRecords() {
         // this code path has side-effects, it locks the result for this 
transaction, 
         // such that cannot enlist on top of it
         return changedObjectPropertiesRef.get();
@@ -186,8 +187,8 @@ implements
         case AUDITING:
             log.debug("about to dispatch audit entries and entity changes");
             prepareAuditDispatching();
-            entityAuditDispatcher.publishEntityAudits(this);
-            changingEntitiesDispatcher.publishChangingEntities(this);
+            entityPropertyChangePublisher.publishChangedProperties(this);
+            entityChangesPublisher.publishChangingEntities(this);
             break;
         case POST_AUDITING:
             log.debug("purging auditing data");
@@ -408,6 +409,17 @@ implements
         }
     }
 
+    @Override
+    public Stream<EntityPropertyChange> streamPropertyChanges(
+            final java.sql.Timestamp timestamp,
+            final String user,
+            final TransactionId txId) {
+        
+        return getPropertyChangeRecords().stream()
+        .map(propertyChangeRecord->EntityPropertyChangeFactory
+                .createEntityPropertyChange(timestamp, user, txId, 
propertyChangeRecord));
+    }
+
 
 
 }
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangesPublisher.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangesPublisher.java
index b624cb6..4a75b47 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangesPublisher.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityChangesPublisher.java
@@ -18,6 +18,12 @@
  */
 package org.apache.isis.core.runtime.persistence.changetracking;
 
+import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
+
+/**
+ * Notifies {@link EntityChangesSubscriber}s.
+ * @since 2.0
+ */
 public interface EntityChangesPublisher {
 
     void publishChangingEntities(HasEnlistedEntityChanges 
hasEnlistedEntityChanges);
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangeFactory.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangeFactory.java
new file mode 100644
index 0000000..0810337
--- /dev/null
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangeFactory.java
@@ -0,0 +1,42 @@
+package org.apache.isis.core.runtime.persistence.changetracking;
+
+import java.util.UUID;
+
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
+import org.apache.isis.applib.services.xactn.TransactionId;
+import 
org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(staticName = "of")
+class EntityPropertyChangeFactory {
+    
+    public static EntityPropertyChange createEntityPropertyChange(
+            final java.sql.Timestamp timestamp,
+            final String user,
+            final TransactionId txId,
+            final PropertyChangeRecord propertyChangeRecord) {
+        
+        val adapterAndProperty = propertyChangeRecord.getAdapterAndProperty();
+        val spec = adapterAndProperty.getAdapter().getSpecification();
+
+        final Bookmark target = adapterAndProperty.getBookmark();
+        final String propertyId = adapterAndProperty.getPropertyId();
+        final String memberId = adapterAndProperty.getMemberId();
+
+        final PreAndPostValues papv = 
propertyChangeRecord.getPreAndPostValues();
+        final String preValue = papv.getPreString();
+        final String postValue = papv.getPostString();
+
+        final String targetClass = CommandUtil.targetClassNameFor(spec);
+
+        final UUID transactionId = txId.getUniqueId();
+        final int sequence = txId.getSequence();
+
+        return EntityPropertyChange.of(
+                transactionId, sequence, targetClass, target, 
+                memberId, propertyId, preValue, postValue, user, timestamp);
+    }
+}
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangePublisher.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangePublisher.java
index 588be88..dd63808 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangePublisher.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/EntityPropertyChangePublisher.java
@@ -18,113 +18,12 @@
  */
 package org.apache.isis.core.runtime.persistence.changetracking;
 
-import java.util.List;
-import java.util.UUID;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
-import 
org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber;
-import org.apache.isis.applib.services.user.UserService;
-import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.having.HasEnabling;
-import 
org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
-
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
 /**
  * Notifies {@link 
org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber}s.
+ * @since 2.0
  */
-@Service
-@Named("isisRuntime.EntityPropertyChangePublisher")
-@Order(OrderPrecedence.EARLY)
-@Primary
-@Qualifier("Default")
-@RequiredArgsConstructor(onConstructor_ = {@Inject})
-@Log4j2
-public class EntityPropertyChangePublisher {
-    
-    private final List<EntityPropertyChangeSubscriber> subscribers;
-    private final UserService userService;
-    private final ClockService clockService;
-    private final TransactionService transactionService;
-    
-    private Can<EntityPropertyChangeSubscriber> enabledSubscribers;
-    
-    @PostConstruct
-    public void init() {
-        enabledSubscribers = Can.ofCollection(subscribers)
-                .filter(HasEnabling::isEnabled);
-    }
-
-    public void publishEntityAudits(
-            final HasEnlistedEntityPropertyChangeRecords 
hasEnlistedEntityPropertyChangeRecords) {
-        
-        if(!canPublish()) { 
-            return; 
-        }
-        
-        val currentUser = userService.getUser().getName();
-        val currentTime = clockService.nowAsJavaSqlTimestamp();
-        val propertyChangeRecords = 
hasEnlistedEntityPropertyChangeRecords.getPropertyChangeRecords();
-    
-        log.debug("about to process {} property changes", 
()->propertyChangeRecords.size());
-        
-        for (val propertyChangeRecord : propertyChangeRecords) {
-            publishChangedProperty(currentTime, currentUser, 
propertyChangeRecord);
-        }
-    }
-
-    // -- HELPER
-    
-    private boolean canPublish() {
-        return enabledSubscribers.isNotEmpty();
-    }
-    
-    private void publishChangedProperty(
-            final java.sql.Timestamp timestamp,
-            final String user,
-            final PropertyChangeRecord propertyChangeRecord) {
-
-        val adapterAndProperty = propertyChangeRecord.getAdapterAndProperty();
-        val spec = adapterAndProperty.getAdapter().getSpecification();
-
-        final Bookmark target = adapterAndProperty.getBookmark();
-        final String propertyId = adapterAndProperty.getPropertyId();
-        final String memberId = adapterAndProperty.getMemberId();
-
-        final PreAndPostValues papv = 
propertyChangeRecord.getPreAndPostValues();
-        final String preValue = papv.getPreString();
-        final String postValue = papv.getPostString();
-
-        final String targetClass = CommandUtil.targetClassNameFor(spec);
-
-        val txId = transactionService.currentTransactionId();
-
-        final UUID transactionId = txId.getUniqueId();
-        final int sequence = txId.getSequence();
-
-        for (val subscriber : enabledSubscribers) {
-            subscriber.onChanging(
-                    EntityPropertyChange
-                        .of(transactionId, sequence, targetClass, target, 
-                                memberId, propertyId, preValue, postValue, 
user, timestamp));
-        }
-    }
-
+public interface EntityPropertyChangePublisher {
 
+    void publishChangedProperties(HasEnlistedEntityPropertyChanges 
hasEnlistedEntityPropertyChanges);
 
 }
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChangeRecords.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChanges.java
similarity index 71%
rename from 
core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChangeRecords.java
rename to 
core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChanges.java
index 7066d1a..ce986cd 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChangeRecords.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/changetracking/HasEnlistedEntityPropertyChanges.java
@@ -18,10 +18,14 @@
  */
 package org.apache.isis.core.runtime.persistence.changetracking;
 
-import java.util.Set;
+import java.sql.Timestamp;
+import java.util.stream.Stream;
 
-interface HasEnlistedEntityPropertyChangeRecords {
+import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
+import org.apache.isis.applib.services.xactn.TransactionId;
 
-    Set<PropertyChangeRecord> getPropertyChangeRecords();
+public interface HasEnlistedEntityPropertyChanges {
+
+    Stream<EntityPropertyChange> streamPropertyChanges(Timestamp timestamp, 
String user, TransactionId txId);
 
 }
diff --git 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/IsisModuleCoreRuntimeServices.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/IsisModuleCoreRuntimeServices.java
index d2de80a..3589976 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/IsisModuleCoreRuntimeServices.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/IsisModuleCoreRuntimeServices.java
@@ -27,7 +27,6 @@ import org.springframework.core.OrderComparator;
 import org.springframework.core.annotation.AnnotationAwareOrderComparator;
 
 import org.apache.isis.core.codegen.bytebuddy.IsisModuleCoreCodegenByteBuddy;
-import org.apache.isis.core.metamodel.services.command.CommandPublisherDefault;
 import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
 import org.apache.isis.core.runtimeservices.bookmarks.BookmarkServiceDefault;
 import 
org.apache.isis.core.runtimeservices.command.CommandDtoServiceInternalDefault;
@@ -45,8 +44,10 @@ import 
org.apache.isis.core.runtimeservices.jaxb.JaxbServiceDefault;
 import 
org.apache.isis.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault;
 import 
org.apache.isis.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3;
 import org.apache.isis.core.runtimeservices.message.MessageServiceDefault;
+import org.apache.isis.core.runtimeservices.publish.CommandPublisherDefault;
 import 
org.apache.isis.core.runtimeservices.publish.EntityChangesPublisherDefault;
-import org.apache.isis.core.runtimeservices.publish.ExecutionDispatcherDefault;
+import 
org.apache.isis.core.runtimeservices.publish.EntityPropertyChangePublisherDefault;
+import org.apache.isis.core.runtimeservices.publish.ExecutionPublisherDefault;
 import 
org.apache.isis.core.runtimeservices.queryresultscache.QueryResultsCacheDefault;
 import 
org.apache.isis.core.runtimeservices.repository.RepositoryServiceDefault;
 import org.apache.isis.core.runtimeservices.routing.RoutingServiceDefault;
@@ -71,6 +72,7 @@ import 
org.apache.isis.core.runtimeservices.xmlsnapshot.XmlSnapshotServiceDefaul
         // @Service's
         BookmarkServiceDefault.class,
         EntityChangesPublisherDefault.class,
+        EntityPropertyChangePublisherDefault.class,
         CommandDtoServiceInternalDefault.class,
         CommandExecutorServiceDefault.class,
         CommandPublisherDefault.class,
@@ -78,7 +80,7 @@ import 
org.apache.isis.core.runtimeservices.xmlsnapshot.XmlSnapshotServiceDefaul
         EmailNotificationServiceDefault.class,
         EmailServiceDefault.class,
         ExceptionRecognizerServiceDefault.class,
-        ExecutionDispatcherDefault.class,
+        ExecutionPublisherDefault.class,
         EventBusServiceSpring.class,
         FactoryServiceDefault.class,
         HomePageResolverServiceDefault.class,
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisherDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/CommandPublisherDefault.java
similarity index 62%
rename from 
core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisherDefault.java
rename to 
core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/CommandPublisherDefault.java
index c5ebbce..7b2e777 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandPublisherDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/CommandPublisherDefault.java
@@ -16,10 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.metamodel.services.command;
+package org.apache.isis.core.runtimeservices.publish;
 
 import java.util.List;
 
+import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -31,34 +32,38 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.publishing.spi.CommandSubscriber;
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.having.HasEnabling;
+import org.apache.isis.core.metamodel.services.publishing.CommandPublisher;
 
 import lombok.NonNull;
-import lombok.extern.log4j.Log4j2;
+import lombok.RequiredArgsConstructor;
 
 @Service
-@Named("isisMetaModel.CommandPublisher")
+@Named("isisRuntimeServices.CommandPublisherDefault")
 @Order(OrderPrecedence.MIDPOINT)
 @Primary
 @Qualifier("Internal")
-@Log4j2
-// tag::refguide[]
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
+//@Log4j2
 public class CommandPublisherDefault implements CommandPublisher {
+    
+    private final List<CommandSubscriber> subscribers;
+    
+    private Can<CommandSubscriber> enabledSubscribers;
+    
+    @PostConstruct
+    public void init() {
+        enabledSubscribers = Can.ofCollection(subscribers)
+                .filter(HasEnabling::isEnabled);
+    }
 
-    // end::refguide[]
-    /**
-     * &quot;Complete&quot; the command, providing an opportunity ot persist
-     * a memento of the command if the
-     * {@link Command#isSystemStateChanged() system state has changed}.
-     *
-     * <p>
-     *     The framework will automatically have set the {@link 
Command#getCompletedAt()} property.
-     * </p>
-     */
-    // tag::refguide[]
     @Override
-    public void complete(final @NonNull Command command) {   // <.>
-        // ...
-    // end::refguide[]
+    public void complete(final @NonNull Command command) { 
+        
+        if(!canPublish()) {
+            return;
+        }
 
         if(!command.isDispatchingEnabled()) {
             return;
@@ -68,15 +73,15 @@ public class CommandPublisherDefault implements 
CommandPublisher {
             return;
         }
 
-        log.debug("completed: {}, systemStateChanged {}",
-                command.getLogicalMemberIdentifier(),
-                command.isSystemStateChanged());
-
-    // tag::refguide[]
-        subscribers.forEach(commandListener -> 
commandListener.onCompleted(command));
+        subscribers.forEach(subscriber -> subscriber.onCompleted(command));
     }
-
-    @Inject List<CommandSubscriber> subscribers;
+    
+    // -- HELPER
+    
+    private boolean canPublish() {
+        return enabledSubscribers.isNotEmpty();
+    }
+    
 
 }
-// end::refguide[]
+
diff --git 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
index db18063..20fea8a 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
@@ -41,11 +41,8 @@ import 
org.apache.isis.core.runtime.persistence.changetracking.HasEnlistedEntity
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-/**
- * Wrapper around {@link 
org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber}.
- */
 @Service
-@Named("isisRuntime.EntityChangesPublisherDefault")
+@Named("isisRuntimeServices.EntityChangesPublisherDefault")
 @Order(OrderPrecedence.EARLY)
 @Primary
 @Qualifier("Default")
@@ -88,7 +85,4 @@ public class EntityChangesPublisherDefault implements 
EntityChangesPublisher {
         return enabledSubscribers.isNotEmpty();
     }
 
-
-
-
 }
diff --git 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityPropertyChangePublisherDefault.java
similarity index 63%
copy from 
core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
copy to 
core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityPropertyChangePublisherDefault.java
index db18063..cf1b6ff 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityChangesPublisherDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/EntityPropertyChangePublisherDefault.java
@@ -31,33 +31,32 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.clock.ClockService;
-import org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber;
+import 
org.apache.isis.applib.services.publishing.spi.EntityPropertyChangeSubscriber;
 import org.apache.isis.applib.services.user.UserService;
+import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.having.HasEnabling;
-import 
org.apache.isis.core.runtime.persistence.changetracking.EntityChangesPublisher;
-import 
org.apache.isis.core.runtime.persistence.changetracking.HasEnlistedEntityChanges;
+import 
org.apache.isis.core.runtime.persistence.changetracking.EntityPropertyChangePublisher;
+import 
org.apache.isis.core.runtime.persistence.changetracking.HasEnlistedEntityPropertyChanges;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-/**
- * Wrapper around {@link 
org.apache.isis.applib.services.publishing.spi.EntityChangesSubscriber}.
- */
 @Service
-@Named("isisRuntime.EntityChangesPublisherDefault")
+@Named("isisRuntimeServices.EntityPropertyChangePublisherDefault")
 @Order(OrderPrecedence.EARLY)
 @Primary
 @Qualifier("Default")
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 //@Log4j2
-public class EntityChangesPublisherDefault implements EntityChangesPublisher {
+public class EntityPropertyChangePublisherDefault implements 
EntityPropertyChangePublisher {
     
-    private final List<EntityChangesSubscriber> subscribers;
-    private final ClockService clockService;
+    private final List<EntityPropertyChangeSubscriber> subscribers;
     private final UserService userService;
+    private final ClockService clockService;
+    private final TransactionService transactionService;
     
-    private Can<EntityChangesSubscriber> enabledSubscribers;
+    private Can<EntityPropertyChangeSubscriber> enabledSubscribers;
     
     @PostConstruct
     public void init() {
@@ -65,23 +64,29 @@ public class EntityChangesPublisherDefault implements 
EntityChangesPublisher {
                 .filter(HasEnabling::isEnabled);
     }
 
-    public void publishChangingEntities(HasEnlistedEntityChanges 
hasEnlistedEntityChanges) {
-
-        if(!canPublish()) {
-            return;
-        }
-        
-        val entityChanges = 
hasEnlistedEntityChanges.getEntityChanges(clockService, userService);
+    @Override
+    public void publishChangedProperties(
+            final HasEnlistedEntityPropertyChanges 
hasEnlistedEntityPropertyChanges) {
         
-        if(entityChanges == null) {
-            return;
+        if(!canPublish()) { 
+            return; 
         }
         
-        for (val subscriber : enabledSubscribers) {
-            subscriber.onChanging(entityChanges);
-        }
+        val currentTime = clockService.nowAsJavaSqlTimestamp();
+        val currentUser = userService.getUser().getName();
+        val currentTransactionId = transactionService.currentTransactionId();
+        
+        hasEnlistedEntityPropertyChanges.streamPropertyChanges(
+                currentTime, 
+                currentUser,
+                currentTransactionId)
+        .forEach(propertyChange->{
+            for (val subscriber : enabledSubscribers) {
+                subscriber.onChanging(propertyChange);
+            }
+        });
     }
-    
+
     // -- HELPER
     
     private boolean canPublish() {
@@ -89,6 +94,4 @@ public class EntityChangesPublisherDefault implements 
EntityChangesPublisher {
     }
 
 
-
-
 }
diff --git 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionDispatcherDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
similarity index 66%
rename from 
core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionDispatcherDefault.java
rename to 
core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
index ff2c4bb..2d6474c 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionDispatcherDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/publish/ExecutionPublisherDefault.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Supplier;
 
+import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -35,39 +36,46 @@ import 
org.apache.isis.applib.annotation.IsisInteractionScope;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.applib.services.publishing.spi.ExecutionSubscriber;
-import org.apache.isis.core.metamodel.services.publishing.ExecutionDispatcher;
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.having.HasEnabling;
+import org.apache.isis.core.metamodel.services.publishing.ExecutionPublisher;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
 
-/**
- * Wrapper around {@link ExecutionSubscriber}.  Is a no-op if there is no 
injected service.
- */
 @Service
-@Named("isisRuntimeServices.ExecutionDispatcherDefault")
+@Named("isisRuntimeServices.ExecutionPublisherDefault")
 @Order(OrderPrecedence.MIDPOINT)
 @Primary
 @Qualifier("Default")
 @IsisInteractionScope
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 //@Log4j2
-public class ExecutionDispatcherDefault 
-implements ExecutionDispatcher {
+public class ExecutionPublisherDefault 
+implements ExecutionPublisher {
 
-    private final List<ExecutionSubscriber> executionListeners;
+    private final List<ExecutionSubscriber> subscribers;
+    
+    private Can<ExecutionSubscriber> enabledSubscribers;
+    
+    @PostConstruct
+    public void init() {
+        enabledSubscribers = Can.ofCollection(subscribers)
+                .filter(HasEnabling::isEnabled);
+    }
 
     @Override
-    public void dispatchActionInvoking(final Interaction.Execution<?,?> 
execution) {
-        notifyListeners(execution);
+    public void publishActionInvocation(final Interaction.Execution<?,?> 
execution) {
+        notifySubscribers(execution);
     }
 
     @Override
-    public void dispatchPropertyChanging(final Interaction.Execution<?,?> 
execution) {
-        notifyListeners(execution);
+    public void publishPropertyEdit(final Interaction.Execution<?,?> 
execution) {
+        notifySubscribers(execution);
     }
     
     @Override
-    public <T> T withDispatchSuppressed(final Supplier<T> block) {
+    public <T> T withPublishingSuppressed(final Supplier<T> block) {
         try {
             suppressionRequestCounter.increment();
             return block.get();
@@ -78,20 +86,20 @@ implements ExecutionDispatcher {
 
     // -- HELPERS
 
-    private void notifyListeners(final Interaction.Execution<?,?> execution) {
+    private void notifySubscribers(final Interaction.Execution<?,?> execution) 
{
         if(isSuppressed()) {
             return;
         }
-        for (val executionListener : executionListeners) {
-            executionListener.onExecution(execution);
+        for (val subscriber : enabledSubscribers) {
+            subscriber.onExecution(execution);
         }
     }
 
     private final LongAdder suppressionRequestCounter = new LongAdder();
     
     private boolean isSuppressed() {
-        return executionListeners == null 
-                || executionListeners.isEmpty() 
+        return enabledSubscribers == null 
+                || enabledSubscribers.isEmpty() 
                 || suppressionRequestCounter.intValue() > 0;
     }
     
diff --git 
a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/IsisPersistenceSessionJdoBase.java
 
b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/IsisPersistenceSessionJdoBase.java
index 37b4198..0f34610 100644
--- 
a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/IsisPersistenceSessionJdoBase.java
+++ 
b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/IsisPersistenceSessionJdoBase.java
@@ -36,7 +36,7 @@ import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.commons.ToString;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.services.command.CommandPublisher;
+import org.apache.isis.core.metamodel.services.publishing.CommandPublisher;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;

Reply via email to