eXo Platform 3.5

## Chapter 59. Understanding the ListenerService

Related documents

- Service Configuration for Beginners

- Service Configuration in Detail

- Container Configuration

## Objectives

This article will first describe how the ListenerService works and then it will show you how to configure the ListenerService.

## What is the ListenerService ?

Inside eXo, an event mechanism allows to trigger and listen to events under specific conditions. This mechanism is used in several places in eXo such as login/logout time.

## How does it work?

Listeners must be subclasses of org.exoplatform.services.listener.Listener registered by the ListenerService.

### Registering a listener

To register a listener, you need to call the addListener() method.

    /**

     * This method is used to register a listener with the service. The method

     * should: 1. Check to see if there is a list of listener with the listener

     * name, create one if the listener list doesn't exit 2. Add the new listener

     * to the listener list

     *

     * @param listener

    */

    public void addListener(Listener listener) {

       ...

    }

By convention, we use the listener name as the name of the event to listen to.

### Triggering an event

To trigger an event, an application can call one of the broadcast() methods of ListenerService.

    /**

     * This method is used to broadcast an event. This method should: 1. Check if

     * there is a list of listener that listen to the event name. 2. If there is a

     * list of listener, create the event object with the given name , source and

     * data 3. For each listener in the listener list, invoke the method

     * onEvent(Event)

     *

     * @param <S> The type of the source that broadcast the event

     * @param <D> The type of the data that the source object is working on

     * @param name The name of the event

     * @param source The source object instance

     * @param data The data object instance

     * @throws Exception

     */

    public <S, D> void broadcast(String name, S source, D data) throws Exception {

       ...

    }

    /**

     * This method is used when a developer want to implement his own event object

     * and broadcast the event. The method should: 1. Check if there is a list of

     * listener that listen to the event name. 2. If there is a list of the

     * listener, For each listener in the listener list, invoke the method

     * onEvent(Event)

     *

     * @param <T> The type of the event object, the type of the event object has

     *          to be extended from the Event type

     * @param event The event instance

     * @throws Exception

     */

    public <T extends Event> void broadcast(T event) throws Exception {

       ...

    }

The boadcast() methods retrieve the name of the event and find the registered listeners with the same name and call the method onEvent() on each listener found.

Each listener is a class that extends org.exoplatform.services.listener.Listener, as you can see below:

    public abstract class Listener<S, D> extends BaseComponentPlugin {

       /**

        * This method should be invoked when an event with the same name is

        * broadcasted

        */

       public abstract void onEvent(Event<S, D> event) throws Exception;

    }

### Warning

As you can see we use generics to limit the source of the event to the type 'S' and the data of the event to the type 'D', so we expect that listeners implement the method onEvent() with the corresponding types

Each listener is also a ComponentPlugin with a name and a description, in other words, the name of the listener will be the name given in the configuration file, for more details see the next section.

    public interface ComponentPlugin {

       public String getName();

       public void setName(String name);

       public String getDescription();

       public void setDescription(String description);

    }

## How to configure a listener?

All listeners are in fact a ComponentPlugin so it must be configured as below:

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <configuration>

    ...

      <external-component-plugins>

        <!-- The full qualified name of the ListenerService -->

        <target-component>org.exoplatform.services.listener.ListenerService</target-component>

        <component-plugin>

        <!-- The name of the listener that is also the name of the target event -->

          <name>${name-of-the-target-event}</name>

          <!-- The name of the method to call on the ListenerService in order to register the Listener -->

          <set-method>addListener</set-method>

          <!-- The full qualified name of the Listener -->

          <type>${the-FQN-of-the-listener}</type>

        </component-plugin>

      </external-component-plugins>

    </configuration>

## Concrete Example

The org.exoplatform.services.security.ConversationRegistry uses the ListenerService to notify that a user has just signed in or just left the application. For example, when a new user signs in, the following code is called:

    listenerService.broadcast("exo.core.security.ConversationRegistry.register", this, state);

This code will in fact create a new Event which name is "exo.core.security.ConversationRegistry.register", which source is the current instance of ConversationRegistry and which data is the given state. The ListenerService will call the method onEvent(Event<ConversationRegistry, ConversationState> event) on all the listeners which name is "exo.core.security.ConversationRegistry.register".

In the example below, we define a Listener that will listen the event "exo.core.security.ConversationRegistry.register".

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <configuration>

    ...

      <external-component-plugins>

        <!-- The full qualified name of the ListenerService -->

        <target-component>org.exoplatform.services.listener.ListenerService</target-component>

        <component-plugin>

          <!-- The name of the listener that is also the name of the target event -->

          <name>exo.core.security.ConversationRegistry.register</name>

          <!-- The name of the method to call on the ListenerService in order to register the Listener -->

          <set-method>addListener</set-method>

          <!-- The full qualified name of the Listener -->

          <type>org.exoplatform.forum.service.AuthenticationLoginListener</type>

        </component-plugin>

      </external-component-plugins>

    </configuration>

    ...