Here's my latest proposal:

/**
  * Components wanting to receive Observation {...@link Event events}  
must implement this interface.
  *
  * @version $Id: EventListener.java 10164 2008-06-09 12:44:53Z  
sdumitriu $
  */
public interface EventListener
{
     /**
      * @return the listener's name. It's a free form text identifying  
this listener instance in a unique manner.
      *         This name is used for some operations in {...@link  
ObservationManager}.
      */
     String getName();

     /**
      * @return the list of events this listener is configured to  
receive. This listener will be automatically
      *         registered with this list of events against the {...@link  
ObservationManager}. For each matching event
      *         the {...@link #onEvent(Event, Object, Object)} method  
will be called.
      */
     List<Event> getEvents();

     /**
      * The {...@link org.xwiki.observation.ObservationManager} calls  
this methods when an event matches the events for
      * which this listener is registered (see {...@link #getEvents()}.
      *
      * @param event the event triggered. Can be used to differentiate  
different events if your Object supports several
      *            events for example.
      * @param source the event source i.e. the object for which the  
event was triggered. For example this would be the
      *            document Object if the event is a document update  
event.
      * @param data some additional and optional data passed that can  
be acted on.
      */
     void onEvent(Event event, Object source, Object data);
}

And:

/**
  * The main orchestrator for event notification. To receive events  
create a component implementing the
  * {...@link EventListener} interface. Your component will be  
automatically registered when this Observation
  * Manager component is loaded. To send events to all registered  
listeners, call one of the
  * {...@link #notify} methods.
  *
  * @version $Id: ObservationManager.java 20537 2009-05-26 20:41:25Z  
vmassol $
  */
@ComponentRole
public interface ObservationManager
{
     /**
      * Manually add a listener. Components implementing the {...@link  
EventListener} interfaces are only loaded
      * when the Observation Manager component is created. Thus if you  
need to add a new listener while the
      * system is running you'll need to call this method.
      *
      * @param event the event to register the listener against; acts  
as a template that filters out only specific events
      *            the listener is interested in
      * @param eventListener the listener to register
      */
     void addListener(EventListener eventListener);

     /**
      * Remove a listener from the list of registered listeners. The  
removed listener will no longer receive events.
      *
      * @param listenerName the name of the listener to remove (must  
match {...@link EventListener#getName()}
      */
     void removeListener(String listenerName);

     /**
      * Adds an Event to an already registered listener.
      *
      * @param listenerName the name of the listener to which the  
event must be added
      *        (must match {...@link EventListener#getName()}
      * @param event the event to add to the matching listener
      */
     void addEvent(String listenerName, Event event);

     /**
      * Removes an Event to an already registered listener.
      *
      * @param listenerName the name of the listener to which the  
event must be removed
      *        (must match {...@link EventListener#getName()}
      * @param event the event to remove to the matching listener
      */
     void removeEvent(String listenerName, Event event);

     /**
      * Remove a listener from a specific event.
      *
      * @param event the event to remove the listener from.
      * @param eventListener the listener to remove.
      */
     void removeListener(Event event, EventListener eventListener);

     /**
      * Call the registered listeners matching the passed Event.
      * The definition of <em>source</em> and <em>data</em> is purely  
up to the communicating classes.
      *
      * @param event the event to pass to the registered listeners
      * @param source the source of the event (or <code>null</code>)
      * @param data the additional data related to the event (or  
<code>null</code>)
      */
     void notify(Event event, Object source, Object data);

     /**
      * Convenience front-end where the additional data parameter is  
<code>null</code>.
      *
      * @param event the event to pass to the registered listeners
      * @param source the source of the event (or <code>null</code>)
      * @see #notify(org.xwiki.observation.event.Event, Object, Object)
      */
     void notify(Event event, Object source);
}

This allows adding events after the listener is registered thus  
allowing Sergiu's use case in the Localization module.

WDYT?

Thanks
-Vincent

On May 28, 2009, at 1:59 PM, Sergiu Dumitriu wrote:

> Sergiu Dumitriu wrote:
>> Vincent Massol wrote:
>>> Hi,
>>>
>>> There's a pb with the current implementation:
>>> When we get the Observation manager implementation and list the
>>> registered listeners we only get the components that have been
>>> initialized *before* we get the Observation manager component.   
>>> Thus if
>>> we want to be sure all listeners will receive events we need to
>>> ensure  they're loaded first. This is hard to do.
>>>
>>> I'm proposing instead to modify the observation module:
>>>
>>> * Modify EventListener to be a @ComponentRole
>>
>> +1
>>
>>> * Add List<Event> EventListener.getEvents() (the events that the
>>> listener handles)
>>
>> Hm, I'm not sure about this. A document watcher will dynamically  
>> add and
>> remove events to the list of monitored resources. We could have this
>> method to be called for the initial registration, as otherwise it's  
>> hard
>> to do the initialization.
>>
>> +0
>
> Also, this requires that the ComponentManager is Initializable,
> otherwise it won't actually register anything.
>
>>> * Inject List<EventListener> in DefaultObservationManager. Thus when
>>> the Observation Manager is looked up, all listener components are
>>> created and injected.
>>
>> +1
>>
>>> * Keep add/removeListener in ObservationManager so that listeners  
>>> can
>>> be manually added/removed (for ex if a new listener component is
>>> added  dynamically in the system) but with following signatures:
>>> - addListener(EventListener);
>>> - removeListener(EventListener);
>>
>> -1. See above, a component with a dynamic list of events will need to
>> register/unregister just one in a long list. So we do need the  
>> existing
>> signatures. Maybe add these signatures, but also keep the existing  
>> ones.
>>
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to