This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-2485 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit d3d19b91a27dd678777a2aec889ed01f1c06100b Author: danhaywood <[email protected]> AuthorDate: Fri May 19 07:27:47 2023 +0100 CAUSEWAY-2485: updates the EventBusService example --- .../dom/domain/objects/progmodel/bean/readme.txt | 41 ++++++++++++++++++ .../src/main/java/demoapp/dom/menubars.layout.xml | 7 +++- .../demoapp/dom/services/core/ServicesMenu.java | 7 ++-- .../EventBusServiceDemoPage-description.adoc | 49 ++++++++++++++++++++++ ...iceDemoVm.java => EventBusServiceDemoPage.java} | 47 +++++++++++---------- ...yout.xml => EventBusServiceDemoPage.layout.xml} | 0 .../EventBusServiceDemoVm-description.adoc | 13 ------ ...eDemoVm.layout.xml => EventLogEntry.layout.xml} | 5 --- .../core/eventbusservice/EventLogEntryJdo.java | 4 +- .../EventLogEntryJdoRepository.java | 2 +- .../core/eventbusservice/EventLogEntryJpa.java | 2 +- .../EventLogEntryJpaRepository.java | 2 +- .../eventbusservice/EventLogEntryRepository.java | 9 ++-- ...ementation.java => EventSubscriberForDemo.java} | 37 ++++------------ 14 files changed, 141 insertions(+), 84 deletions(-) diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/bean/readme.txt b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/bean/readme.txt new file mode 100644 index 0000000000..c74126b0e1 --- /dev/null +++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/progmodel/bean/readme.txt @@ -0,0 +1,41 @@ + +TODO: create a new demo to show the BEAN nature. +TODO: this also demonstrates async call of WrapperFactory + +This is the original version of EventSubscriberForDemo (since simplified): + +@Service +@Named("demo.eventSubscriber") +@Qualifier("demo") +@Log4j2 +@RequiredArgsConstructor(onConstructor_ = { @Inject }) +public class EventSubscriberForDemo { + + final FactoryService factoryService; + final WrapperFactory wrapper; + + @EventListener(UiButtonEvent.class) // <.> <.> listen on the event, triggered by button in the UI + public void on(final UiButtonEvent event) { + + log.info(emphasize("UiButtonEvent")); + + val eventLogWriter = factoryService.get(EventLogWriter.class); // <.> <.> get a new writer from Spring + + wrapper.asyncWrap(eventLogWriter, AsyncControl.returningVoid()).storeEvent(event); + } + + @Named("demo.eventLogWriter") + @DomainObject(nature = Nature.BEAN) // <.> <.> have this Object's lifecycle managed by Spring + @Scope("prototype") + public static class EventLogWriter { + + @Inject private EventLogEntryRepository<? extends EventLogEntry> eventLogEntryRepository; + + @Action // called asynchronously by above invocation + public void storeEvent(final UiButtonEvent event) { + eventLogEntryRepository.storeEvent(event); + } + } +} + + diff --git a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml index e03c23a087..321aeffd60 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/menubars.layout.xml @@ -164,12 +164,15 @@ For latest we use: https://raw.githubusercontent.com/apache/causeway/master/anto <mb3:menu> <mb3:named>Selected Services</mb3:named> <mb3:section> - <mb3:named>Core</mb3:named> - <mb3:serviceAction objectType="demo.ServicesMenu" id="errorReportingService" /> + <mb3:named>Core APIs</mb3:named> <mb3:serviceAction objectType="demo.ServicesMenu" id="eventBusService" /> <mb3:serviceAction objectType="demo.ServicesMenu" id="messageService" /> <mb3:serviceAction objectType="demo.ServicesMenu" id="wrapperFactory"/> </mb3:section> + <mb3:section> + <mb3:named>Core SPIs</mb3:named> + <mb3:serviceAction objectType="demo.ServicesMenu" id="errorReportingService" /> + </mb3:section> </mb3:menu> <mb3:menu> diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/ServicesMenu.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/ServicesMenu.java index 4e3b39ba14..78c6ef3fdb 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/ServicesMenu.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/ServicesMenu.java @@ -30,11 +30,10 @@ import org.apache.causeway.applib.annotation.SemanticsOf; import org.apache.causeway.applib.services.factory.FactoryService; import lombok.RequiredArgsConstructor; -import lombok.val; import demoapp.dom._infra.values.ValueHolderRepository; import demoapp.dom.services.core.errorreportingservice.ErrorReportingServiceDemoVm; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage; import demoapp.dom.services.core.messageservice.MessageServiceDemoVm; import demoapp.dom.services.core.wrapperFactory.WrapperFactoryEntity; @@ -52,8 +51,8 @@ public class ServicesMenu { @Action @ActionLayout(cssClassFa="fa-bolt") - public EventBusServiceDemoVm eventBusService(){ - return factoryService.viewModel(new EventBusServiceDemoVm()); + public EventBusServiceDemoPage eventBusService(){ + return factoryService.viewModel(new EventBusServiceDemoPage()); } @Action diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage-description.adoc new file mode 100644 index 0000000000..871ed24777 --- /dev/null +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage-description.adoc @@ -0,0 +1,49 @@ +: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 [...] + +The framework's programming model automatically emits events for each member of each object as it is rendered, allowing subscribers to determine what is visible/hidden, enabled/disabled, or valid (when invoking an action). +And if an action is invoked, then additional events are emitted before and after execution. +The same is true for property edits. + +Moreover, there are also events emitted for the persistence lifecycle of domain objects, and UI events that allow subscribers to influence the title, icon, CSS and layout of objects. + +In most cases you should find that this rich in-built event model will suffice for your needs. +However, you can also post your own custom events, by accessing the API of the link:https://causeway.apache.org/refguide/2.0.0-RC1/applib/index/services/eventbus/EventBusService.html[EventBusService] service. + +== How this demo works + +On the left hand side is an (initially empty) collection, and an action to trigger an event. +When invoked, the action programmatically raises an event. +A subscriber listening on this event then causes an entity representing that event to be raised. +The list of all created events is shown in the table. + +In terms of code: + +* this page provides the action to trigger an event: ++ +[source,java,indent=0] +.EventBusServiceDemoPage.java +---- +include::EventBusServiceDemoPage.java[tags=triggerEvent] +---- +<.> instantiates an event and posts to ... +<.> \... the injected `EventBusService` + +* where the event class is: ++ +[source,java,indent=0] +.EventBusServiceDemoPage.java +---- +include::EventBusServiceDemoPage.java[tags=eventClass] +---- +<.> it's idiomatic (but not necessary) to inherit from `EventObject` + +* Meanwhile the subscriber is a singleton service (entities and view models cannot be subscribers) ++ +[source,java] +.EventSubscriberForDemo.java +---- +include::EventSubscriberForDemo.java[tags=class] +---- +<.> listen on the event, triggered by button in the UI +<.> delegate to repository to store the event + diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage.java similarity index 69% rename from examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.java rename to examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage.java index 1441fae4d2..9d53cbc2b8 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage.java @@ -18,6 +18,7 @@ */ package demoapp.dom.services.core.eventbusservice; +import java.util.EventObject; import java.util.List; import javax.inject.Inject; @@ -35,39 +36,41 @@ import org.apache.causeway.applib.services.eventbus.EventBusService; import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription; -@Named("demo.EventBusServiceDemoVm") +//tag::class[] +@Named("demo.EventBusServiceDemoPage") @DomainObject(nature=Nature.VIEW_MODEL) -public class EventBusServiceDemoVm implements HasAsciiDocDescription { - - @Inject private EventLogEntryRepository<? extends EventLogEntry> eventLogEntryRepository; - @Inject private EventBusService eventBusService; +public class EventBusServiceDemoPage implements HasAsciiDocDescription { + // ... +//end::class[] @ObjectSupport public String title() { return "Event Demo"; } - @Collection - public List<? extends EventLogEntry> getAllEvents(){ - return eventLogEntryRepository.listAll(); - } - - @Named("demo.EventBusServiceDemoVm.UiButtonEvent") - @DomainObject(nature = Nature.VIEW_MODEL) - public static class UiButtonEvent implements ViewModel { - // -- VIEWMODEL CONTRACT - public UiButtonEvent(final String memento) { } - @Override public String viewModelMemento() { return ""; } +//tag::eventClass[] + public static class UiButtonEvent extends EventObject { // <.> + public UiButtonEvent(Object source) { + super(source); + } } +//end::eventClass[] - @ActionLayout( - describedAs = "Writes a new EventLog entry to the persistent eventlog.", - cssClassFa="fa-bolt", - position = Position.PANEL) +//tag::triggerEvent[] @Action - public EventBusServiceDemoVm triggerEvent(){ - eventBusService.post(new UiButtonEvent(null)); + public EventBusServiceDemoPage triggerEvent(){ + eventBusService.post(new UiButtonEvent(this)); // <.> return this; } + @Inject private EventBusService eventBusService; // <.> +//end::triggerEvent[] + + @Collection public List<? extends EventLogEntry> getAllEvents(){ + return eventLogEntryRepository.listAll(); + } + + @Inject private EventLogEntryRepository<? extends EventLogEntry> eventLogEntryRepository; +//tag::class[] } +//end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage.layout.xml similarity index 100% copy from examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.layout.xml copy to examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoPage.layout.xml diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm-description.adoc deleted file mode 100644 index 5ef251118a..0000000000 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm-description.adoc +++ /dev/null @@ -1,13 +0,0 @@ -: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 [...] - -(since 2.0) - -Note: events are written to the list in the background, so a page refresh might be required to see all events - -[source,java] ----- -// TODO ----- - -See the tree demo link:${SOURCES_DEMO}/demoapp/dom/events[sources]. - diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntry.layout.xml similarity index 92% rename from examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.layout.xml rename to examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntry.layout.xml index cd5f451265..207cc516f1 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventBusServiceDemoVm.layout.xml +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntry.layout.xml @@ -23,11 +23,6 @@ <bs3:row> <bs3:col span="6"> <bs3:row> - <bs3:col span="12"> - <cpt:collection defaultView="table" id="allEvents"> - <cpt:action id="triggerEvent"/> - </cpt:collection> - </bs3:col> </bs3:row> <bs3:row> <bs3:col span="12"> diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdo.java index 883c8e60d3..1c4f0236f6 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdo.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdo.java @@ -39,7 +39,7 @@ import lombok.Getter; import lombok.Setter; import lombok.val; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; @Profile("demo-jdo") @PersistenceCapable(identityType = IdentityType.DATASTORE, schema = "demo" ) @@ -51,7 +51,7 @@ extends EventLogEntry { // -- FACTORY - public static EventLogEntryJdo of(final UiButtonEvent even) { + public static EventLogEntryJdo of(final UiButtonEvent event) { val x = new EventLogEntryJdo(); x.setEvent("Button clicked " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME)); return x; diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdoRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdoRepository.java index 25bd789459..866b398e9f 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdoRepository.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJdoRepository.java @@ -30,7 +30,7 @@ import org.apache.causeway.applib.services.repository.RepositoryService; import lombok.RequiredArgsConstructor; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; @Profile("demo-jdo") @Repository diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpa.java index a42b4dcbd9..f79acfbb7b 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpa.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpa.java @@ -39,7 +39,7 @@ import lombok.Getter; import lombok.Setter; import lombok.val; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; @Profile("demo-jpa") @Entity diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpaRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpaRepository.java index 4674fcc7e2..a0d71dba03 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpaRepository.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryJpaRepository.java @@ -30,7 +30,7 @@ import org.apache.causeway.applib.services.repository.RepositoryService; import lombok.RequiredArgsConstructor; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; @Profile("demo-jpa") @Repository diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryRepository.java index 7e65297fe6..d97cf06ed1 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryRepository.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventLogEntryRepository.java @@ -22,19 +22,22 @@ import java.util.List; import lombok.val; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; +//tag::class[] public interface EventLogEntryRepository<T extends EventLogEntry> { - + // ... +//end::class[] List<T> listAll(); void add(T entry); T newEntityFor(UiButtonEvent event); +//tag::class[] default void storeEvent(final UiButtonEvent event) { val entry = newEntityFor(event); add(entry); } - } +//end::class[] diff --git a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberDemoImplementation.java b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberForDemo.java similarity index 65% rename from examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberDemoImplementation.java rename to examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberForDemo.java index 186fb0e1dd..c48d76b21b 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberDemoImplementation.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/services/core/eventbusservice/EventSubscriberForDemo.java @@ -37,46 +37,23 @@ import lombok.RequiredArgsConstructor; import lombok.val; import lombok.extern.log4j.Log4j2; -import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoVm.UiButtonEvent; +import demoapp.dom.services.core.eventbusservice.EventBusServiceDemoPage.UiButtonEvent; import static demoapp.dom._infra.utils.LogUtils.emphasize; +//tag::class[] @Service @Named("demo.eventSubscriber") @Qualifier("demo") @Log4j2 @RequiredArgsConstructor(onConstructor_ = { @Inject }) -public class EventSubscriberDemoImplementation { +public class EventSubscriberForDemo { - final WrapperFactory wrapper; - final FactoryService factoryService; + final EventLogEntryRepository<? extends EventLogEntry> eventLogEntryRepository; - @EventListener(UiButtonEvent.class) // <-- listen on the event, triggered by button in the UI + @EventListener(UiButtonEvent.class) // <.> public void on(final UiButtonEvent event) { - - log.info(emphasize("UiButtonEvent")); // <-- log to the console - - val eventLogWriter = factoryService.get(EventLogWriter.class); // <-- get a new writer - - wrapper.asyncWrap(eventLogWriter, AsyncControl.returningVoid()).storeEvent(event); - + eventLogEntryRepository.storeEvent(event); // <.> } - - @Named("demo.eventLogWriter") - @DomainObject( - nature = Nature.BEAN) @Scope("prototype") // <-- have this Object's lifecycle managed by Spring - public static class EventLogWriter { - - @Inject private EventLogEntryRepository<? extends EventLogEntry> eventLogEntryRepository; - - @Action // called asynchronously by above invocation - public void storeEvent(final UiButtonEvent event) { - - eventLogEntryRepository.storeEvent(event); - } - - } - - - } +//end::class[]
