=== Domain Event Defaults

: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:

Whenever an member of a domain object is interacted with then a domain event will be fired, for each of the various phases (hidden, disabled, validated, executing, executed).

For each of the three types of members (action, property and collection), the xref:refguide:applib:index/annotation/DomainObject.adoc[DomainObject] provides an element that defines a common event domain class to be fired whenever interacting with members of that type.
This default event type can be overridden with a more specific event type if necessary.

[cols="3a,6a,7a"]
|===
| Type
| @DomainObject default
| Overridden with

|Actions
|xref:refguide:applib:index/annotation/DomainObject.adoc#actionDomainEvent[actionDomainEvent()]

|xref:refguide:applib:index/annotation/Action.adoc#domainEvent[@Action#domainEvent].

|Properties
|xref:refguide:applib:index/annotation/DomainObject.adoc#propertyDomainEvent[propertyDomainEvent()]


|xref:refguide:applib:index/annotation/Property.adoc#domainEvent[@Property#domainEvent()].

|Collections

|xref:refguide:applib:index/annotation/DomainObject.adoc#collectionDomainEvent[collectionDomainEvent()]

|xref:refguide:applib:index/annotation/Collection.adoc#domainEvent[@Collection#domainEvent()].

|===

==== Action example

For an action:

[source,java]
----
@DomainObject(
    actionDomainEvent=ToDoItem.ActionDomainEventDefault.class
)
public class ToDoItem {

    public static class ActionDomainEventDefault extends
        org.apache.isis.applib.events.domain.ActionDomainEvent<Object> { }
    // ...

    public void updateDescription(final String description) {
        this.description = description;
    }

}
----

The specified class will also be used as the event for any mixin action contributed to the class.

Note though one small difference between the events emitted by a "regular" action and a contributed action is that the source of the event (as in `event#getSource()` will be different.
In the former case it will be the domain object instance, in the latter it will be the mixin object instantiated automatically by the framework.

However, the domain object is available using `event#getMixedIn()`.
Even easier, `event#getSubject()` will always return the domain object (it returns the `#getMixedIn()` if present, otherwise the `#getSource()`.

[NOTE]
====
Action domain events have generic types, with the (first and only) generic type indicating the event's source's type.

Because an event specified at the class level might have either the domain object or a mixin for the domain object as its source, they should therefore use simply `Object` as their generic type.
====

==== Property example

For example:

[source,java]
----
@DomainObject(
    propertyDomainEvent=ToDoItem.PropertyDomainEventDefault.class
)
public class ToDoItem {
    public static class PropertyDomainEventDefault
        extends org.apache.isis.applib.events.domain.PropertyDomainEvent<Object> { }
    ...

    @Getter @Setter
    private String description;
}
----

If there is a mixin for the domain object, then this will also honour the domain event.
For example:

[source,java]
----
@Property(
	propertyDomainEvent=ToDoItem_priority.PropertyDomainEventDefault.class
)
public class ToDoItem_priority {
    private final ToDoItem todoItem;
    // constructor omitted

    public static class PropertyDomainEventDefault
        extends org.apache.isis.applib.events.domain.PropertyDomainEvent<Object> { }

    public Integer prop() { /* ... */ }
}
----

Interactions with the property contributed by this mixin will emit the domain event of the subject (`ToDoItem`).

One small difference between the events emitted by a "regular" property and a contributed property is that the source of the event (as in `event#getSource()` will be different.
In the former case it will be the domain object instance, in the latter it will be the mixin object instantiated automatically by the framework.

However, the domain object is available using `event#getMixedIn()`.
Even easier, `event#getSubject()` will always return the domain object (it returns the `#getMixedIn()` if present, otherwise the `#getSource()`.

[NOTE]
====
Property domain events have generic types, with the first generic type indicating the event's source's type, and the second generic type indicating the property return type.

Because an event specified at the class level might have either the domain object or a mixin for the domain object as its source, they should therefore use simply `Object` as their first generic type.

They should _also_ have `Object` for their second generic type, because the return type of the various properties of the domain object will or could be different.
====

==== Collection example

For example:

[source,java]
----
import lombok.Getter;
import lombok.Setter;

@DomainObject(
    collectionDomainEvent=ToDoItem.CollectionDomainEventDefault.class
)
public class ToDoItem {
    public static class CollectionDomainEventDefault extends
            org.apache.isis.applib.events.domain.CollectionDomainEvent<Object> { }
    ...

    @Getter @Setter
    private Set<Category> categories = new TreeSet<>();
}
----

If there is a mixin for the domain object, then this will also honour the domain event.
For example:

[source,java]
----
public class ToDoItem {

    @Collection
    @CollectionLayout(defaultView = "table")
    public class related {

        public List<ToDoItem> coll() {
            // ...
        }
    }

}
----

Interactions with the collection contributed by this mixin will emit the domain event of the subject (`ToDoItem`).

One small difference between the events emitted by a "regular" collection and a contributed action is that the source of the event (as in `event#getSource()` will be different.
In the former case it will be the domain object instance, in the latter it will be the mixin object instantiated automatically by the framework.

However, the domain object is available using `event#getMixedIn()`.
Even easier, `event#getSubject()` will always return the domain object (it returns the `#getMixedIn()` if present, otherwise the `#getSource()`.

[NOTE]
====
Collection domain events have generic types, with the first generic type indicating the event's source's type, and the second generic type indicating the element type.

Because an event specified at the class level might have either the domain object or a mixin for the domain object as its source, they should therefore use simply `Object` as their first generic type.

They should _also_ have `Object` for their second generic type, because the element type of the various collections of the domain object will or could be different.
====


