[#events]
= Events

: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 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.
:page-partial:


When the framework renders a domain object, and as the end-user interacts with the domain object, the framework it emits multiple events using the intra-process xref:refguide:applib:index/services/eventbus/EventBusService.adoc[event bus].
These events enable other domain services (possibly in other modules) to influence how the domain object is rendered, or to perform side-effects or even veto an action invocation.

To receive the events, the domain service should subscribe to the xref:refguide:applib:index/services/eventbus/EventBusService.adoc[EventBusService], and implement an appropriately annotated method to receive the events.

The framework has several categories of events: domain events, UI events and lifecycle events.
These are explored in the sections below.

[#domain-events]
== Domain Events

Domain events are fired -- through the internal xref:refguide:applib:index/services/eventbus/EventBusService.adoc[event bus] -- for every user interaction with each object member (property, collection or action).

By default, rendering a property causes a `PropertyDomainEvent` to be fired, though the xref:refguide:applib:index/annotation/Property.adoc#domainEvent[@Property#domainEvent()] attribute allows a custom subclass to be specified if necessary.
Similarly, rendering a collection causes a `DomainEvent` to be fired, and rendering an action causes an `ActionDomainEvent` to be fired.

In fact, each event can be fired up to five times, with the event's `getEventPhase()` method indicating to the subscriber the phase:

* *hide* phase allows the subscriber to hide the member

* *disable* phase allows the subscriber to disable the member.
+
For a property this makes it read-only; for an action this makes it "greyed out".
(Collections are implicitly read-only).

* *validate* phase allows the subscriber to validate the proposed change.
+
For a property this means validating the proposed new value of the property; for an action this means validating the action parameter arguments.
For example, a referential integrity restrict could be implemented here.

* *executing* phase is prior to the actual property edit/action invocation, allowing the subscriber to perform side-effects.
+
For example, a cascade delete could be implemented here.

* *executed* phase is after the actual property edit/action invocation.
+
For example, a business audit event could be implemented here.

For more details on the actual domain event classes, see the xref:refguide:applib-classes:events.adoc#domain-event-classes[domain event] section of the relevant reference guide.

== UI Events

As explained xref:userguide:fun:overview.adoc#title-and-icon-and-css-class[earlier], to allow the end-user to distinguish one domain object from another, it is rendered with a title and an icon.

xref:userguide:fun:ui.adoc#object-titles-and-icons[Normally] the code to return title and icon of an object is part of the domain object's implementation.
However, UI events allow this title and icon to be provided instead by a subscriber.
UI events have higher precedence than the other mechanisms of supplying a title.

If annotated with xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#titleUiEvent[@DomainObjectLayout#titleUiEvent()], the appropriate (subclass of) `TitleUiEvent` will be emitted.
Similarly for xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#iconUiEvent[#iconUiEvent()].
In addition, it is possible to use events to obtain a CSS class to render with the domain object, using xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#cssClassUiEvent[#cssClassUiEvent()], and to select an alternate xref:userguide:fun:ui/object-layout.adoc[layout file] using xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#layoutUiEvent[#layoutUiEvent()].

There are two use cases where this feature is useful:

* the first is to override the title/icon/CSS class/layout of 3rd party library code, for example as provided by the xref:security:secman:about.adoc[SecMan] extension.

* the second is for xref:userguide:fun:view-models.adoc#jaxb[JAXB-style view models] which are code generated from XSDs and so cannot have any dependencies on the rest of the Apache Isis framework.

In this second case a subscriber on the default events can provide a title and icon for such an object, with the behaviour provided using xref:userguide:fun:overview.adoc#mixins[mixins].

[#lifecycle-events]
== Lifecycle Events

Lifecycle events allow domain object subscribers to listen for changes to the persistence state of domain entities, and act accordingly.

[WARNING]
====
Lifecycle events are _not_ fired for view models.
====

The lifecycle events supported are:

* *created*
+
Entity has just been instantiated.
Note that this requires that the object is instantiated using the framework, see xref:userguide:fun:domain-entities-and-services.adoc#instantiating[here] for further discussion.

* *loaded*
+
Entity has just retrieved/rehydrated from the database

* *persisting*
+
Entity is about to be inserted/saved (ie for the first time) into the database

* *persisted*
+
Entity has just been inserted/saved (ie for the first time) into the database

* *updating*
+
The (already persistent) entity about to be flushed in the database

* *updated*
+
The (already persistent) entity has just been flushed to the database

* *removing*
+
The (already persistent) entity is about to be deleted from the database

For example, if annotated with xref:refguide:applib:index/annotation/DomainObject.adoc#updatingLifecycleEvent[@DomainObjectLayout#updatingLifecycleEvent], the appropriate (subclass of) `ObjectUpdatingEvent` will be emitted.

There is no lifecycle event for "entity creating" because (obviously) the framework doesn't know about newly created objects until they have been created.
Similarly, there is no lifecycle event for entities that have been removed because it is not valid to "touch" a domain entity once deleted.



