Events
The Axelor Open Platform implements a subset of the CDI 2.0 event notification model.
Event observer classes need to be bound and have observer methods, ie. methods that take an event as parameter, annotated with @Observes
, optional @Priority
(observer methods are called in ascending order of priority) and other optional qualifiers in order to narrow down which events to observe. Observer methods are called whenever the corresponding event is fired.
Built-in Events
All built-in events are located inside the com.axelor.events
package.
Login Events
These events are fired during user login process.
-
PreLogin(AuthenticationToken token)
– fired before user login -
PostLogin(AuthenticationToken token, User user, Throwable error)
– fired after user login
Field | Description |
---|---|
|
|
|
authenticated user |
|
exception that caused login failure |
PostLogin
observer methods may use a @Named
qualifier with either PostLogin.SUCCESS
or PostLogin.FAILURE
.
import com.axelor.event.Observes;
import com.axelor.events.PostLogin;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
@RequestScoped
public class LoginObserver {
@Inject private HttpServletRequest request;
// Observes successful login.
void onLoginSuccess(@Observes @Named(PostLogin.SUCCESS) PostLogin event) {
final String userCode = event.getUser().getCode();
final String userAgent = request.getHeader("User-Agent");
System.out.printf("User: %s, User-Agent: %s%n", userCode, userAgent);
}
}
If you want to redirect the current request to a new URL, you may use WebUtils.issueRedirect
.
Action Events
These events are fired when actions are called.
-
PreAction(String name, Context context)
– fired before action execution -
PostAction(String name, Context context, Object result)
– fired after action execution
Field | Description |
---|---|
|
name of the action |
|
context of the action |
|
object returned by the action |
Observer methods may use the @Named
qualifier with the name of the action to observe.
import com.axelor.event.Observes;
import com.axelor.events.PostAction;
import javax.inject.Named;
public class SaleOrderObserver {
// Observes built-in post-action event by its name.
void onConfirmed(@Observes @Named("action-sale-order-confirm") PostAction event) {
System.out.println(event.getName());
}
}
Request Events
These events are fired during server requests (REST service).
-
PreRequest(Object source, Request request)
- fired before a request -
PostRequest(Object source, Request request, Response response)
- fired after a request
Field | Description |
---|---|
|
source of the event |
|
request object |
|
response object |
Observer methods may use the @Named
qualifier with the name of the request to observe:
-
RequestEvent.SEARCH
-
RequestEvent.EXPORT
-
RequestEvent.READ
-
RequestEvent.FETCH
-
RequestEvent.SAVE
-
RequestEvent.MASS_UPDATE
-
RequestEvent.REMOVE
-
RequestEvent.COPY
-
RequestEvent.FETCH_NAME
Observer methods may also use the built-in @EntityType
qualifier to select which entity type to observe.
import com.axelor.event.Observes;
import com.axelor.event.Priority;
import com.axelor.events.PostRequest;
import com.axelor.events.RequestEvent;
import com.axelor.events.qualifiers.EntityType;
import javax.inject.Named;
public class ContactObserver {
void onExport(@Observes @Priority(0)
@Named(RequestEvent.EXPORT) @EntityType(Contact.class) PostRequest event) {
System.out.println(event.getSource());
}
}
Workflow Status Tags
Observing fetch events, it is possible to add workflow status as tags in the form view.
public void onFetch(@Observes @Named(RequestEvent.FETCH) PostRequest event) {
@SuppressWarnings("unchecked")
final Map<String, Object> values = (Map<String, Object>) event.getResponse().getItem(0);
if (values != null) {
final List<Map<String, Object>> status = new ArrayList<>();
status.add(ImmutableMap.of("name", "s1", "title", "Status 1", "color", "red"));
values.put("$wkfStatus", status);
}
}
status
should be a list of maps with the following keys:
-
name – name of the node
-
title – display title
-
color – background HTML color
Custom Events
Event Object
You can create your own events. An event object can be any kind of POJO:
public class ContactSaved {
private final Contact contact;
public ContactSaved(Contact contact) {
this.contact = contact;
}
public Contact getContact() {
return contact;
}
}
Event Source
A service firing an event is an event source. To fire an event, a service needs to inject a parameterized Event object and invoke its fire
method with an instance of the event object as parameter:
import com.axelor.event.Event;
import javax.inject.Inject;
public class ContactService {
@Inject private Event<ContactSaved> contactSavedEvent;
// Probably should be called from entity listener. (1)
public void fireContactSavedEvent(Contact contact) {
contactSavedEvent.fire(new ContactSaved(contact));
}
}
1 | See entity listeners. |
Event Observer
You can observe your custom events in an event observer. Remember that the observer class needs to be bound and consists of observer methods.
import com.axelor.event.Observes;
public class ContactObserver {
void onContactChanged(@Observes ContactSaved event) {
Contact contact = event.getContact();
System.out.println(contact);
}
}
Qualifiers
When firing your events, you can also select
your own qualifiers in order to narrow down which observer methods to call:
import com.axelor.event.Event;
import com.axelor.event.NamedLiteral;
import javax.inject.Inject;
public class ContactService {
@Inject private Event<ContactSaved> contactSavedEvent;
public void fireContactSavedEvent(Contact contact) {
contactSavedEvent.fire(new ContactSaved(contact));
}
public void fireContactSavedEventSuccess(Contact contact) {
contactSavedEvent.select(NamedLiteral.of("success")).fire(new ContactSaved(contact));
}
public void fireContactSavedEventFailure(Contact contact) {
contactSavedEvent.select(NamedLiteral.of("failure")).fire(new ContactSaved(contact));
}
}
public class ContactObserver {
void onContactChanged(@Observes ContactSaved event) {
// Called by fireContactSavedEvent,
// fireContactSavedEventSuccess, and fireContactSavedEventFailure.
}
void onContactChangedSuccess(@Observes @Named("success") ContactSaved event) {
// Called by fireContactSavedEventSuccess.
}
void onContactChangedFailure(@Observes @Named("failure") ContactSaved event) {
// Called by fireContactSavedEventFailure.
}
}