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

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

commit 6e1bd09f5159765cd829c6e816b2dadc68534123
Author: danhaywood <[email protected]>
AuthorDate: Sun Apr 2 19:08:46 2023 +0100

    CAUSEWAY-2485: wip, @DomainObject#xxxDomainEvent
---
 .../ActionDomainEventPage-description.adoc         |   2 +-
 .../ActionDomainEventPage_controlStrategy.java     |   1 +
 .../ActionDomainEventPage_updateText.java          |   9 +-
 ...tionDomainEventPage_updateTextNotAnnotated.java |  10 +-
 .../collections/Collection/CollectionMenu.java     |   2 -
 .../domainEvent/CollectionDomainEventPage.java     |   1 -
 .../child/CollectionDomainEventChildVm.java        |   6 +-
 .../child/CollectionDomainEventChildVm.layout.xml  |  18 +--
 .../objects/DomainObject/DomainObjectMenu.java     |   7 +-
 .../DomainObjectXxxDomainEventControlStrategy.java | 166 +++++++++++++++++++++
 ...mainObjectXxxDomainEventControlSubscriber.java} |  33 ++--
 ...DomainObjectXxxDomainEventPage-description.adoc | 124 ++++++++++-----
 .../DomainObjectXxxDomainEventPage.java            |  77 ++++++++--
 .../DomainObjectXxxDomainEventPage.layout.xml      |  33 +++-
 ...tXxxDomainEventPage_changeControlStrategy.java} |  39 ++---
 ...nObjectXxxDomainEventPage_controlStrategy.java} |  15 +-
 ...nObjectXxxDomainEventPage_updateTextMixin.java} |  21 +--
 ...ainObjectXxxDomainEventChildVm-description.adoc |   4 +
 .../DomainObjectXxxDomainEventChildVm.java}        |  36 +++--
 .../DomainObjectXxxDomainEventChildVm.layout.xml}  |  13 +-
 20 files changed, 462 insertions(+), 155 deletions(-)

diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage-description.adoc
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage-description.adoc
index 561ed4096f..7c6d8b547e 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage-description.adoc
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage-description.adoc
@@ -7,7 +7,7 @@ Domain service subscribers can influence this interaction, 
either by:
 * disabling the action
 * validating arguments of the action invocation
 * performing arbitrary operations before the action has been invoked 
(including modifying the argument values to be used)
-* performing arbitrary operations after the action has been modified 
(including changing the apparent return value of the action)
+* performing arbitrary operations after the action has been invoked (including 
changing the apparent return value of the action)
 
 The 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/Action.html#domainevent[@Action#actionDomainEvent]
 element specifies the class to be emitted; the class specified must be a 
subclass of the abstract 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/events/domain/ActionDomainEvent.html[ActionDomainEvent]
 class.
 
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
index b7825b38fe..1bd693de15 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
@@ -32,6 +32,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ActionDomainEventPage_controlStrategy {
 
+    @SuppressWarnings("unused")
     private final ActionDomainEventPage page;
 
     public ActionDomainEventControlStrategy prop() {
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
index a74663ce36..119f510e14 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
@@ -19,7 +19,6 @@
 package demoapp.dom.domain.actions.Action.domainEvent;
 
 import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
 import org.apache.causeway.applib.annotation.MemberSupport;
 import org.apache.causeway.applib.events.domain.ActionDomainEvent;
 
@@ -36,14 +35,14 @@ public class ActionDomainEventPage_updateText {
     // ...
 //end::class[]
 
-    private final ActionDomainEventPage actionDomainEventVm;
+    private final ActionDomainEventPage page;
 
     @MemberSupport public ActionDomainEventPage act(final String text) {
-        actionDomainEventVm.setText(text);
-        return actionDomainEventVm;
+        page.setText(text);
+        return page;
     }
     @MemberSupport public String default0Act() {
-        return actionDomainEventVm.getText();
+        return page.getText();
     }
 //tag::class[]
 }
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
index 03c15987ae..67d34c5f06 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
@@ -21,9 +21,7 @@ package demoapp.dom.domain.actions.Action.domainEvent;
 import lombok.RequiredArgsConstructor;
 
 import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
 import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.events.domain.ActionDomainEvent;
 
 
 //tag::class[]
@@ -33,14 +31,14 @@ public class ActionDomainEventPage_updateTextNotAnnotated {
     // ...
 //end::class[]
 
-    private final ActionDomainEventPage actionDomainEventVm;
+    private final ActionDomainEventPage page;
 
     @MemberSupport public ActionDomainEventPage act(final String text) {
-        actionDomainEventVm.setText(text);
-        return actionDomainEventVm;
+        page.setText(text);
+        return page;
     }
     @MemberSupport public String default0Act() {
-        return actionDomainEventVm.getText();
+        return page.getText();
     }
 //tag::class[]
 }
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java
index 658f10c044..3063227745 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/CollectionMenu.java
@@ -53,11 +53,9 @@ public class CollectionMenu {
         page.addChild("#1");
         page.addChild("#2");
         page.addChild("#3");
-
         page.addOtherChild("#1");
         page.addOtherChild("#2");
         page.addOtherChild("#3");
-
         return page;
     }
 
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/CollectionDomainEventPage.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/CollectionDomainEventPage.java
index 9f2959eb81..ffa669142a 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/CollectionDomainEventPage.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/CollectionDomainEventPage.java
@@ -47,7 +47,6 @@ import 
org.apache.causeway.applib.events.domain.CollectionDomainEvent;
 public class CollectionDomainEventPage implements HasAsciiDocDescription {
     // ...
 //end::class[]
-    int lastChildNumberAdded;
 
     @ObjectSupport public String title() {
         return "@Collection#domainEvent";
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.java
index 214021f40b..1d5540ac9f 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.java
@@ -37,12 +37,11 @@ import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 //tag::class[]
-@XmlRootElement(name = "child")
+@XmlRootElement(name = "demo.CollectionDomainEventChildVm")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @Named("demo.CollectionDomainEventChildVm")
-@DomainObject(
-        nature=Nature.VIEW_MODEL)
+@DomainObject(nature=Nature.VIEW_MODEL)
 @NoArgsConstructor
 public class CollectionDomainEventChildVm implements HasAsciiDocDescription {
 
@@ -54,7 +53,6 @@ public class CollectionDomainEventChildVm implements 
HasAsciiDocDescription {
 //tag::class[]
     @Title
     @Property()
-    @PropertyLayout(fieldSetId = "properties", sequence = "1")
     @XmlElement(required = true)
     @Getter @Setter
     private String value;
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.layout.xml
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.layout.xml
index 5f64b9631a..a5d295bce2 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.layout.xml
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/collections/Collection/domainEvent/child/CollectionDomainEventChildVm.layout.xml
@@ -28,25 +28,25 @@
                <bs3:col span="6">
                        <bs3:row>
                                <bs3:col span="12">
-                                       <cpt:fieldSet name="Properties" 
id="properties"/>
+                                       <cpt:fieldSet name="Properties" 
id="properties">
+                                               <cpt:property id="value"/>
+                                       </cpt:fieldSet>
                                        <cpt:fieldSet name="Other" id="other" 
unreferencedProperties="true"/>
                                </bs3:col>
                        </bs3:row>
-                       <bs3:row>
-                               <bs3:col span="12">
-                                       <cpt:collection id="events"/>
-                               </bs3:col>
-                       </bs3:row>
                </bs3:col>
                <bs3:col span="6">
                        <cpt:fieldSet name="Description" id="description" >
                                <cpt:action id="clearHints" position="PANEL" />
-                               <cpt:action id="downloadLayoutXml"  
position="PANEL_DROPDOWN"/>
                                <cpt:action id="rebuildMetamodel" 
position="PANEL"/>
-                               <cpt:action id="downloadMetamodelXml"  
position="PANEL_DROPDOWN"/>
+                               <cpt:action id="downloadLayout"  
position="PANEL_DROPDOWN"/>
                                <cpt:action id="inspectMetamodel"  
position="PANEL_DROPDOWN"/>
+                               <cpt:action id="downloadMetamodelXml"  
position="PANEL_DROPDOWN"/>
+                               <cpt:action id="downloadJdoMetamodel"  
position="PANEL_DROPDOWN"/>
                 <cpt:action id="recentCommands"  position="PANEL_DROPDOWN"/>
-                               <cpt:action id="downloadJdoMetadata"  
position="PANEL_DROPDOWN"/>
+                <cpt:action id="recentExecutions"  position="PANEL_DROPDOWN"/>
+                <cpt:action id="recentAuditTrailEntries"  
position="PANEL_DROPDOWN"/>
+                               <cpt:action id="impersonateWithRoles"  
position="PANEL_DROPDOWN"/>
                                <cpt:action id="openRestApi" 
position="PANEL_DROPDOWN" />
                                <cpt:property id="description"/>
                        </cpt:fieldSet>
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/DomainObjectMenu.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/DomainObjectMenu.java
index 29aa7593b0..541f28f8e6 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/DomainObjectMenu.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/DomainObjectMenu.java
@@ -29,6 +29,7 @@ import 
demoapp.dom.domain.objects.DomainObject.nature.DomainObjectNaturePage;
 import 
demoapp.dom.domain.objects.DomainObject.xxxDomainEvent.DomainObjectXxxDomainEventPage;
 import 
demoapp.dom.domain.objects.DomainObject.xxxLifecycleEvent.DomainObjectXxxLifecyleEventPage;
 import lombok.RequiredArgsConstructor;
+import lombok.val;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -94,7 +95,11 @@ public class DomainObjectMenu {
     @Action(semantics = SemanticsOf.SAFE)
     @ActionLayout(cssClassFa="fa-asterisk", describedAs = "Default class of 
the domain event emitted when interacting with the domain object's actions, 
properties or collections")
     public DomainObjectXxxDomainEventPage domainEvents() {
-        return new DomainObjectXxxDomainEventPage();
+        val page = new DomainObjectXxxDomainEventPage("change me");
+        page.addChild("#1");
+        page.addChild("#2");
+        page.addChild("#3");
+        return page;
     }
 
     @Action(semantics = SemanticsOf.SAFE)
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlStrategy.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlStrategy.java
new file mode 100644
index 0000000000..78ff55b70a
--- /dev/null
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlStrategy.java
@@ -0,0 +1,166 @@
+/*
+ *  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 demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
+
+import lombok.val;
+
+import java.util.List;
+
+import org.apache.causeway.applib.events.domain.AbstractDomainEvent;
+import org.apache.causeway.applib.events.domain.ActionDomainEvent;
+import org.apache.causeway.applib.services.message.MessageService;
+import org.apache.causeway.applib.services.registry.ServiceRegistry;
+
+// tag::class[]
+enum DomainObjectXxxDomainEventControlStrategy {
+
+    DO_NOTHING{
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+        }
+    },
+    // ...
+// end::class[]
+
+// tag::hide[]
+    HIDE {
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+            if (ev instanceof AbstractDomainEvent) {
+                AbstractDomainEvent domainEvent = (AbstractDomainEvent) ev;
+                switch (domainEvent.getEventPhase()) {
+                    case HIDE:
+                        domainEvent.hide();
+                        break;
+                }
+            }
+        }
+    },
+// end::hide[]
+// tag::disable[]
+    DISABLE {
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+            if (ev instanceof AbstractDomainEvent) {
+                AbstractDomainEvent domainEvent = (AbstractDomainEvent) ev;
+                switch (domainEvent.getEventPhase()) {
+                    case DISABLE:
+                        domainEvent.disable("ControlStrategy set to DISABLE");
+                        break;
+                }
+            }
+        }
+    },
+// end::disable[]
+// tag::validate[]
+    VALIDATE_MUST_BE_UPPER_CASE{
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+            if (ev instanceof DomainObjectXxxDomainEventPage.ActionEvent) {
+                val actionEvent = (DomainObjectXxxDomainEventPage.ActionEvent) 
ev;
+                switch (actionEvent.getEventPhase()) {
+                    case VALIDATE:
+                        String argument = (String) 
actionEvent.getArguments().get(0);
+                        if (!argument.toUpperCase().equals(argument)) {
+                            actionEvent.invalidate("must be upper case");
+                        }
+                        break;
+                }
+            }
+            if (ev instanceof DomainObjectXxxDomainEventPage.PropertyEvent) {
+                val propertyEvent = 
(DomainObjectXxxDomainEventPage.PropertyEvent) ev;
+                switch (propertyEvent.getEventPhase()) {
+                    case VALIDATE:
+                        Object newValue = propertyEvent.getNewValue();
+                        
if(!newValue.toString().toUpperCase().equals(newValue)) {
+                            propertyEvent.invalidate("must be upper case");
+                        }
+                        break;
+                }
+            }
+        }
+    },
+// end::validate[]
+// tag::executing[]
+    EXECUTING_FORCE_UPPER_CASE{
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+            if (ev instanceof DomainObjectXxxDomainEventPage.ActionEvent) {
+                val actionEvent = (DomainObjectXxxDomainEventPage.ActionEvent) 
ev;
+                switch (actionEvent.getEventPhase()) {
+                    case EXECUTING:
+                        List<Object> arguments = actionEvent.getArguments();
+                        String newValue = ((String) 
arguments.get(0)).toUpperCase();
+                        arguments.set(0, newValue);
+                        break;
+                }
+            }
+            if (ev instanceof DomainObjectXxxDomainEventPage.PropertyEvent) {
+                val propertyEvent = 
(DomainObjectXxxDomainEventPage.PropertyEvent) ev;
+                switch (propertyEvent.getEventPhase()) {
+                    case EXECUTING:
+                        String newValue = 
propertyEvent.getNewValue().toString().toUpperCase();
+                        propertyEvent.setNewValue(newValue);
+                        break;
+                }
+            }
+        }
+    },
+// end::executing[]
+// tag::executed[]
+    EXECUTED_ANNOUNCE{
+        @Override
+        void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry) {
+            if (ev instanceof DomainObjectXxxDomainEventPage.ActionEvent) {
+                val actionEvent = (DomainObjectXxxDomainEventPage.ActionEvent) 
ev;
+                switch (actionEvent.getEventPhase()) {
+                    case EXECUTED:
+                        serviceRegistry
+                            .lookupService(MessageService.class)
+                            .ifPresent(ms ->
+                                    ms.informUser("Changed using updateText")
+                            );
+                        break;
+                }
+            }
+            if (ev instanceof DomainObjectXxxDomainEventPage.PropertyEvent) {
+                val propertyEvent = 
(DomainObjectXxxDomainEventPage.PropertyEvent) ev;
+                switch (propertyEvent.getEventPhase()) {
+                    case EXECUTED:
+                        serviceRegistry
+                            .lookupService(MessageService.class)
+                            .ifPresent(ms ->
+                                    ms.informUser(
+                                            String.format("Changed from %s to 
%s"
+                                                    , 
propertyEvent.getOldValue()
+                                                    , 
propertyEvent.getNewValue()))
+
+                            );
+                        break;
+                }
+            }
+        }
+    }
+// end::executed[]
+
+// tag::class[]
+    ;
+    abstract void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev, 
ServiceRegistry serviceRegistry);
+}
+// end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlSubscriber.java
similarity index 52%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlSubscriber.java
index b7825b38fe..6c40104b3c 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventControlSubscriber.java
@@ -16,28 +16,29 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.actions.Action.domainEvent;
+package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
+
+import lombok.RequiredArgsConstructor;
 
 import javax.inject.Inject;
 
-import org.apache.causeway.applib.annotation.Property;
-import org.apache.causeway.applib.annotation.PropertyLayout;
+import org.apache.causeway.applib.services.registry.ServiceRegistry;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Service;
 
-import lombok.RequiredArgsConstructor;
+// tag::class[]
+@Service
+@RequiredArgsConstructor(onConstructor_ = {@Inject})
+class DomainObjectXxxDomainEventControlSubscriber {
 
+    final ServiceRegistry serviceRegistry;
 
-//tag::class[]
-@Property()
-@PropertyLayout(fieldSetId = "contributed", sequence = "1")
-@RequiredArgsConstructor
-public class ActionDomainEventPage_controlStrategy {
+    DomainObjectXxxDomainEventControlStrategy controlStrategy =
+            DomainObjectXxxDomainEventControlStrategy.DO_NOTHING;           // 
<.>
 
-    private final ActionDomainEventPage page;
-
-    public ActionDomainEventControlStrategy prop() {
-        return eventActionDomainEventControlService.controlStrategy;
+    @EventListener(DomainObjectXxxDomainEventPage.DomainEventMarker.class)  // 
<.>
+    public void on(DomainObjectXxxDomainEventPage.DomainEventMarker ev) {
+        controlStrategy.on(ev, serviceRegistry);                            // 
<.>
     }
-
-    @Inject ActionDomainEventControlSubscriber 
eventActionDomainEventControlService;
 }
-//end::class[]
+// end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage-description.adoc
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage-description.adoc
index 21d6014a98..7f436d8809 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage-description.adoc
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage-description.adoc
@@ -1,61 +1,111 @@
 :Notice: 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 ag [...]
 
-[#actionDomainEvent]
-== actionDomainEvent
+Usually a domain event is emitted by the framework to emit whenever the user 
interacts with an object member, in other words an action, property or 
collection.
+Domain service subscribers can influence this interaction, either by:
 
-Indicates that an invocation of _any_ action of the domain object (that do not 
themselves specify their own `@Action(domainEvent=...)` should be posted to the 
_org.apache.causeway.applib.services.eventbus.EventBusService event bus_ using 
the specified custom (subclass of) 
https://causeway.apache.org/refguide/${CAUSEWAY_VERSION}/applib/index/events/domain/ActionDomainEvent.html[ActionDomainEvent]
 .
+* hiding the action, property or collection
+* disabling the action or property.
+(This does not apply to collections as they cannot be modified directly).
+* validating arguments of the action invocation or property edit
+* performing arbitrary operations before the action has been invoked / 
property edited (including modifying the argument values to be used)
+* performing arbitrary operations after the action has been invoked / property 
edited
 
-For example:
+Most commonly the domain event to emit is specified at the member level, using 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/Action.html#domainevent[@Action#actionDomainEvent],
 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/Property.html#domainevent[@Property#actionDomainEvent]
 or 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/Collection.html#domainevent[@Collection#actionDomainEvent].
+But as a fallback the `domainEvent` can also be at the class level using 
link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#actiondomainevent[@DomainObject#actionDomainEvent].
 
-----
-
-@DomainObject(actionDomainEvent=SomeObject.GenericActionDomainEvent.class)
-public class SomeObject{
-    public static class GenericActionDomainEvent extends 
ActionDomainEvent<Object> { ... }
-
-    public void changeStartDate(final Date startDate) { ...}
-    ...
-}
-----
-
-This will result in all actions as a more specific type to use) to emit this 
event.
 
-This subclass must provide a no-arg constructor; the fields are set 
reflectively. It must also use `Object` as its generic type. This is to allow 
mixins to also emit the same event.
+=== How this demo works
 
-[#propertyDomainEvent]
-== propertyDomainEvent
+This page object has a single (editable) property, `text`, an action to update 
it, and a collection.
+None of these domain members are annotated with a domainEvent directly, but 
their containing page object _is_ annotated.
 
-Indicates that changes to _any_ property of the domain object (that do not 
themselves specify their own `@Property(domainEvent=...)` should be posted to 
the _org.apache.causeway.applib.services.eventbus.EventBusService event bus_ 
using the specified custom (subclass of) 
https://causeway.apache.org/refguide/${CAUSEWAY_VERSION}/applib/index/events/domain/PropertyDomainEvent.html[PropertyDomainEvent]
 .
+The interactions with these members can be controlled using the "change 
control strategy" action, influencing whether they are hidden, disabled, and so 
on.
 
-For example:
+In terms of code:
 
+* this page object defines a set of domain event classes:
++
+[source,java]
+.DomainObjectXxxDomainEventPage.java
 ----
-
-@DomainObject(propertyDomainEvent=SomeObject.GenericPropertyDomainEvent.class)
-public class SomeObject{
-
-   public LocalDate getStartDate() { ...}
-}
+include::DomainObjectXxxDomainEventPage.java[tags=class]
+----
+<.> the action domain event class to emit (if not annotated at the member 
level)
+<.> the property domain event class to emit (if not annotated at the member 
level)
+<.> the collection domain event class to emit (if not annotated at the member 
level)
+<.> marker interface.
+All the domain event classes implement this interface, and the subscriber (see 
below) subscribes on this type
+<.> the property can be edited directly (and can also be modified using a 
action (see below)
+
+* the mixin action to update the property
++
+[source,java]
+.DomainObjectXxxDomainEventPage_updateText.java
+----
+include::DomainObjectXxxDomainEventPage_updateText.java[tags=class]
 ----
 
-This subclass must provide a no-arg constructor; the fields are set 
reflectively. It must also use `Object` as its generic type. This is to allow 
mixins to also emit the same event.
 
-[#collectionDomainEvent]
-== collectionDomainEvent
+* the subscriber that listens to the events:
++
+[source,java]
+.DomainObjectXxxDomainEventControlSubscriber.java
+----
+include::DomainObjectXxxDomainEventControlSubscriber.java[tags=class]
+----
+<.> currently selected strategy
+<.> listens to the custom event (marker interface)
+<.> dispatches to the currently selected control strategy (see below)
+
+* the action that selects the strategy in effect:
++
+[source,java]
+.DomainObjectXxxDomainEventPage_changeControlStrategy
+----
+include::DomainObjectXxxDomainEventPage_changeControlStrategy.java[tags=class]
+----
 
-Indicates that changes to _any_ collection of the domain object (that do not 
themselves specify their own `@Collection(domainEvent=...)` should be posted to 
the 
https://causeway.apache.org/refguide/${CAUSEWAY_VERSION}/applib/index/services/eventbus/EventBusService.html[EventBusService]
 event bus_ using a custom (subclass of) 
https://causeway.apache.org/refguide/${CAUSEWAY_VERSION}/applib/index/events/domain/CollectionDomainEvent.html[CollectionDomainEvent]
 .
+* the different strategies:
 
-For example:
+** do nothing
++
+[source,java]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=class]
+----
 
+** hide
++
+[source,java,indent=0]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=hide]
 ----
 
-@DomainObject(collectionDomainEvent=Order.GenericCollectionDomainEvent.class)
-public class Order {
+** disable
++
+[source,java,indent=0]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=disable]
+----
 
-  public SortedSet<OrderLine> getLineItems() { ...}
-}
+** validate
++
+[source,java,indent=0]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=validate]
 ----
 
-This subclass must provide a no-arg constructor; the fields are set 
reflectively. It must also use `Object` as its generic type. This is to allow 
mixins to also emit the same event.
+** executing
++
+[source,java,indent=0]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=executing]
+----
 
+** executed
++
+[source,java,indent=0]
+----
+include::DomainObjectXxxDomainEventControlStrategy.java[tags=executed]
+----
 
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
index d2884b23ba..c3e0ca9487 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
@@ -19,29 +19,84 @@
 package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import 
demoapp.dom.domain.objects.DomainObject.xxxDomainEvent.child.DomainObjectXxxDomainEventChildVm;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.inject.Named;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.*;
 
-import org.apache.causeway.applib.annotation.DomainObject;
-import org.apache.causeway.applib.annotation.Nature;
-import org.apache.causeway.applib.annotation.ObjectSupport;
+import org.apache.causeway.applib.annotation.*;
+import org.apache.causeway.applib.events.domain.ActionDomainEvent;
+import org.apache.causeway.applib.events.domain.CollectionDomainEvent;
+import org.apache.causeway.applib.events.domain.PropertyDomainEvent;
 
-//tag::class[]
-@XmlRootElement(name = "root")
+@XmlRootElement(name = "demo.DomainObjectxxxDomainEventPage")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
-@Named("demo.DomainObjectXxxDomainEventPage")
+@Named("demo.DomainObjectxxxDomainEventPage")
+@NoArgsConstructor
+//tag::class[]
+// ...
 @DomainObject(
-        nature = Nature.VIEW_MODEL)
+    actionDomainEvent = DomainObjectXxxDomainEventPage.ActionEvent.class,      
     //  <.>
+    propertyDomainEvent = DomainObjectXxxDomainEventPage.PropertyEvent.class,  
     //  <.>
+    collectionDomainEvent = 
DomainObjectXxxDomainEventPage.CollectionEvent.class,   //  <.>
+    nature=Nature.VIEW_MODEL
+)
 public class DomainObjectXxxDomainEventPage implements HasAsciiDocDescription {
 
+    public interface DomainEventMarker {}                                      
     //  <.>
+
+    public static class ActionEvent                                            
     //  <1>
+            extends ActionDomainEvent<DomainObjectXxxDomainEventPage>
+            implements DomainEventMarker {}
+
+    public static class PropertyEvent                                          
     //  <2>
+            extends PropertyDomainEvent<DomainObjectXxxDomainEventPage, Object>
+            implements DomainEventMarker {}
+
+    public static class CollectionEvent                                        
     //  <3>
+            extends CollectionDomainEvent<DomainObjectXxxDomainEventPage, 
Object>
+            implements DomainEventMarker {}
+    // ...
+
+//end::class[]
+    public DomainObjectXxxDomainEventPage(final String text) {
+        this.text = text;
+    }
+
     @ObjectSupport public String title() {
         return "@DomainObject#xxxDomainEvent";
     }
 
+    public void addChild(String value) {
+        this.getChildren().add(new DomainObjectXxxDomainEventChildVm(value));
+    }
+
+//tag::class[]
+    @Property(editing = Editing.ENABLED)                                       
     // <.>
+    @XmlElement(required = true)
+    @Getter @Setter
+    private String text;
+
+    public DomainObjectXxxDomainEventPage updateTextDirectly(String text) {
+        setText(text);
+        return this;
+    }
+    public String default0UpdateTextDirectly() {
+        return getText();
+    }
+
+
+    @Collection
+    @XmlElementWrapper(name = "children")
+    @XmlElement(name = "child")
+    @Getter @Setter
+    private List<DomainObjectXxxDomainEventChildVm> children = new 
ArrayList<>();
 }
 //end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
index 2ca31ba597..ad7315e077 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
@@ -18,7 +18,6 @@
        <bs3:row>
                <bs3:col span="10" unreferencedActions="true">
                        <cpt:domainObject />
-                       <cpt:action id="toggleEvents"/>
                </bs3:col>
                <bs3:col span="2">
                        <cpt:fieldSet name="" id="sources" />
@@ -27,10 +26,34 @@
 
        <bs3:row>
                <bs3:col span="6">
-                       <cpt:fieldSet name="Other" id="other" 
unreferencedProperties="true"/>
-                       <cpt:collection id="objects">
-                               <cpt:action id="updateName"/>
-                       </cpt:collection>
+                       <bs3:row>
+                               <bs3:col span="12">
+                                       <cpt:fieldSet name="Object" id="object">
+                                               <cpt:property id="text">
+                                                       <cpt:action 
id="updateText">
+                                                               
<cpt:named>update</cpt:named>
+                                                       </cpt:action>
+                                               </cpt:property>
+                                       </cpt:fieldSet>
+                               </bs3:col>
+                       </bs3:row>
+                       <bs3:row>
+                               <bs3:col span="12">
+                                       <cpt:collection id="children"/>
+                               </bs3:col>
+                       </bs3:row>
+                       <bs3:row>
+                               <bs3:col span="12">
+                                       <cpt:fieldSet name="Control" 
id="contributed">
+                                               <cpt:property 
id="controlStrategy">
+                                                       <cpt:action 
id="changeControlStrategy">
+                                                               
<cpt:named>Change</cpt:named>
+                                                       </cpt:action>
+                                               </cpt:property>
+                                       </cpt:fieldSet>
+                                       <cpt:fieldSet name="Other" id="other" 
unreferencedProperties="true"/>
+                               </bs3:col>
+                       </bs3:row>
                </bs3:col>
                <bs3:col span="6">
                        <cpt:fieldSet name="Description" id="description" >
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_changeControlStrategy.java
similarity index 55%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_changeControlStrategy.java
index a74663ce36..f4aaf5d27b 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateText.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_changeControlStrategy.java
@@ -16,35 +16,40 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.actions.Action.domainEvent;
+package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
+
+import lombok.RequiredArgsConstructor;
+
+import javax.inject.Inject;
 
 import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
 import org.apache.causeway.applib.annotation.MemberSupport;
+import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.applib.events.domain.ActionDomainEvent;
 
-import lombok.RequiredArgsConstructor;
-
 
 //tag::class[]
-@Action(domainEvent = ActionDomainEventPage_updateText.DomainEvent.class)   // 
<.>
+@Action(
+        domainEvent = 
DomainObjectXxxDomainEventPage_changeControlStrategy.DomainEvent.class,   // <.>
+        semantics = SemanticsOf.IDEMPOTENT
+)
 @RequiredArgsConstructor
-public class ActionDomainEventPage_updateText {
+public class DomainObjectXxxDomainEventPage_changeControlStrategy {
 
-    public static class DomainEvent                                         // 
<.>
-            extends ActionDomainEvent<ActionDomainEventPage> {}
-    // ...
-//end::class[]
+    public static class DomainEvent                                            
                 // <1>
+            extends ActionDomainEvent<DomainObjectXxxDomainEventPage> {}
 
-    private final ActionDomainEventPage actionDomainEventVm;
+    private final DomainObjectXxxDomainEventPage page;
 
-    @MemberSupport public ActionDomainEventPage act(final String text) {
-        actionDomainEventVm.setText(text);
-        return actionDomainEventVm;
+    @MemberSupport public DomainObjectXxxDomainEventPage act(
+            DomainObjectXxxDomainEventControlStrategy controlStrategy) {
+        subscriber.controlStrategy = controlStrategy;
+        return page;
     }
-    @MemberSupport public String default0Act() {
-        return actionDomainEventVm.getText();
+    @MemberSupport public DomainObjectXxxDomainEventControlStrategy 
default0Act() {
+        return subscriber.controlStrategy;
     }
-//tag::class[]
+
+    @Inject DomainObjectXxxDomainEventControlSubscriber subscriber;
 }
 //end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_controlStrategy.java
similarity index 78%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_controlStrategy.java
index b7825b38fe..c1c5cb1e36 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_controlStrategy.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_controlStrategy.java
@@ -16,28 +16,29 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.actions.Action.domainEvent;
+package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
+
+import lombok.RequiredArgsConstructor;
 
 import javax.inject.Inject;
 
 import org.apache.causeway.applib.annotation.Property;
 import org.apache.causeway.applib.annotation.PropertyLayout;
 
-import lombok.RequiredArgsConstructor;
-
 
 //tag::class[]
 @Property()
 @PropertyLayout(fieldSetId = "contributed", sequence = "1")
 @RequiredArgsConstructor
-public class ActionDomainEventPage_controlStrategy {
+public class DomainObjectXxxDomainEventPage_controlStrategy {
 
-    private final ActionDomainEventPage page;
+    private final DomainObjectXxxDomainEventPage page;
 
-    public ActionDomainEventControlStrategy prop() {
+    public DomainObjectXxxDomainEventControlStrategy prop() {
         return eventActionDomainEventControlService.controlStrategy;
     }
 
-    @Inject ActionDomainEventControlSubscriber 
eventActionDomainEventControlService;
+    @Inject
+    DomainObjectXxxDomainEventControlSubscriber 
eventActionDomainEventControlService;
 }
 //end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_updateTextMixin.java
similarity index 64%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_updateTextMixin.java
index 03c15987ae..637b77236c 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/actions/Action/domainEvent/ActionDomainEventPage_updateTextNotAnnotated.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage_updateTextMixin.java
@@ -16,32 +16,27 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.actions.Action.domainEvent;
+package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
 
 import lombok.RequiredArgsConstructor;
 
 import org.apache.causeway.applib.annotation.Action;
-import org.apache.causeway.applib.annotation.ActionLayout;
 import org.apache.causeway.applib.annotation.MemberSupport;
-import org.apache.causeway.applib.events.domain.ActionDomainEvent;
 
 
 //tag::class[]
-@Action()                                                       // <.>
+@Action()
 @RequiredArgsConstructor
-public class ActionDomainEventPage_updateTextNotAnnotated {
-    // ...
-//end::class[]
+public class DomainObjectXxxDomainEventPage_updateTextMixin {
 
-    private final ActionDomainEventPage actionDomainEventVm;
+    private final DomainObjectXxxDomainEventPage page;
 
-    @MemberSupport public ActionDomainEventPage act(final String text) {
-        actionDomainEventVm.setText(text);
-        return actionDomainEventVm;
+    @MemberSupport public DomainObjectXxxDomainEventPage act(final String 
text) {
+        page.setText(text);
+        return page;
     }
     @MemberSupport public String default0Act() {
-        return actionDomainEventVm.getText();
+        return page.getText();
     }
-//tag::class[]
 }
 //end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm-description.adoc
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm-description.adoc
new file mode 100644
index 0000000000..3bae8376bb
--- /dev/null
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm-description.adoc
@@ -0,0 +1,4 @@
+:Notice: 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 ag [...]
+
+This is a child object used in the demonstration of 
`DomainObject#domainEvent()`.
+
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.java
similarity index 58%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.java
index d2884b23ba..0392275c19 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.java
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.java
@@ -16,32 +16,38 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent;
+package demoapp.dom.domain.objects.DomainObject.xxxDomainEvent.child;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
 
 import javax.inject.Named;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.*;
 
-import org.apache.causeway.applib.annotation.DomainObject;
-import org.apache.causeway.applib.annotation.Nature;
-import org.apache.causeway.applib.annotation.ObjectSupport;
+import org.apache.causeway.applib.annotation.*;
 
 //tag::class[]
-@XmlRootElement(name = "root")
+@XmlRootElement(name = "demo.DomainObjectXxxDomainEventChildVm")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
-@Named("demo.DomainObjectXxxDomainEventPage")
-@DomainObject(
-        nature = Nature.VIEW_MODEL)
-public class DomainObjectXxxDomainEventPage implements HasAsciiDocDescription {
+@Named("demo.DomainObjectXxxDomainEventChildVm")
+@DomainObject(nature=Nature.VIEW_MODEL)
+@NoArgsConstructor
+public class DomainObjectXxxDomainEventChildVm implements 
HasAsciiDocDescription {
 
-    @ObjectSupport public String title() {
-        return "@DomainObject#xxxDomainEvent";
+//end::class[]
+    public DomainObjectXxxDomainEventChildVm(final String value) {
+        this.value = value;
     }
 
+//tag::class[]
+    @Title
+    @Property()
+    @XmlElement(required = true)
+    @Getter @Setter
+    private String value;
+
 }
 //end::class[]
diff --git 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.layout.xml
similarity index 91%
copy from 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
copy to 
examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.layout.xml
index 2ca31ba597..a5d295bce2 100644
--- 
a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/DomainObjectXxxDomainEventPage.layout.xml
+++ 
b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/xxxDomainEvent/child/DomainObjectXxxDomainEventChildVm.layout.xml
@@ -18,7 +18,6 @@
        <bs3:row>
                <bs3:col span="10" unreferencedActions="true">
                        <cpt:domainObject />
-                       <cpt:action id="toggleEvents"/>
                </bs3:col>
                <bs3:col span="2">
                        <cpt:fieldSet name="" id="sources" />
@@ -27,10 +26,14 @@
 
        <bs3:row>
                <bs3:col span="6">
-                       <cpt:fieldSet name="Other" id="other" 
unreferencedProperties="true"/>
-                       <cpt:collection id="objects">
-                               <cpt:action id="updateName"/>
-                       </cpt:collection>
+                       <bs3:row>
+                               <bs3:col span="12">
+                                       <cpt:fieldSet name="Properties" 
id="properties">
+                                               <cpt:property id="value"/>
+                                       </cpt:fieldSet>
+                                       <cpt:fieldSet name="Other" id="other" 
unreferencedProperties="true"/>
+                               </bs3:col>
+                       </bs3:row>
                </bs3:col>
                <bs3:col span="6">
                        <cpt:fieldSet name="Description" id="description" >

Reply via email to