Class designation: Interface org.apache.wiki.event.WikiEventManager extends java.lang.Object

WikiEventManager is a singleton class, the part of the JSPWiki WikiEvent API/implementation that manages the addition and removal of WikiEventListeners to a event source, as well as the firing of events to those listeners. An event source is the object delegating its event handling to an inner delegating class supplied by this manager. The class being serviced is considered a client of the delegate. The WikiEventManager operates across any number of simultaneously-existing WikiEngines since it manages all delegation on a per-object basis. Anything that might fire a WikiEvent (or any of its subclasses) can be a client.

Using a Delegate for Event Listener Management#

Basically, rather than have all manner of client classes maintain their own listener lists, add and remove listener methods, any class wanting to attach listeners can simply request a delegate object to provide that service. The delegate handles the listener list, the add and remove listener methods. Firing events is then a matter of calling the WikiEventManager's fireEvent(Object,WikiEvent) method, where the Object is the client. Prior to instantiating the event object, the client can call isListening(Object) to see there are any listeners attached to its delegate.

Adding Listeners#

Adding a WikiEventListener to an object is very simple:

  WikiEventManager.addWikiEventListener(object,listener);

Removing Listeners#

Removing a WikiEventListener from an object is very simple:

  WikiEventManager.removeWikiEventListener(object,listener);

If you only have a reference to the listener, the following method will remove it from any clients managed by the WikiEventManager:

  WikiEventManager.removeWikiEventListener(listener);

Firing Events#

Even with listeners in place, nothing happens with the events API unless events are actually fired. Since the WikiEvent class is abstract and only provides for an UNDEFINED and ERROR event types, it is meant to be extended for each category of event types. To this effect, the initial implementation of the API included two subclasses:

  • WikiEngineEvents mark state changes within the WikiEngine
  • WikiPageEvent mark different stages during page processing

Subsequently, WikiSecurityEvent and WorkflowEvent have been added.

It may be helpful to look within the JSPWiki WikiEngine and PageManager code to see how each interacts with the WikiEventManager. There's also a brief explanation on how this works within the description of the WikiEngineEvent documentation.

Backward Compatibility: Replacing Existing fireEvent() Methods#

Using one manager for all events processing permits consolidation of all event listeners and their associated methods in one place rather than having them attached to specific subcomponents of an application, and avoids a great deal of event-related cut-and-paste code. Convenience methods that call the WikiEventManager for event delegation can be written to maintain existing APIs.

For example, an existing fireEvent() method might look something like this:

  protected final void fireEvent( WikiEvent event )
  {
      for ( Iterator it = m_listeners.iterator(); it.hasNext(); )
      {
          WikiEventListener listener = (WikiEventListener)it.next();
          listener.actionPerformed(event);
      }
  }

One disadvantage is that the above method is supplied with event objects, which are created even when no listener exists for them. In a busy wiki with many users unused/unnecessary event creation could be considerable. Another advantage is that in addition to the iterator, there must be code to support the addition and remove of listeners. The above could be replaced with the below code (and with no necessary local support for adding and removing listeners):

  protected final void fireEvent( int type )
  {
      if ( WikiEventManager.isListening(this) )
      {
          WikiEngineEvent event = new WikiEngineEvent(this,type);
          WikiEventManager.fireEvent(this,event);
      }
  }

This only needs to be customized to supply the specific parameters for whatever WikiEvent you want to create.

You could of course write the fireEvent() method to take a WikiEvent parameter (as is relatively common in Java event code), but if as above you instead provide only the arguments needed to create the event, the event object is only created if the manager is actually listening.

Preloading Listeners#

This may be used to create listeners for objects that don't yet exist, particularly designed for embedded applications that need to be able to listen for the instantiation of an Object, by maintaining a cache of client-less WikiEvent sources that set their client upon being popped from the cache. Each time any of the methods expecting a client parameter is called with a null parameter it will preload an internal cache with a client-less delegate object that will be popped and returned in preference to creating a new object. This can have unwanted side effects if there are multiple clients populating the cache with listeners. The only check is for a Class match, so be aware if others might be populating the client-less cache with listeners.


See: WikiEvent, WikiEngineEvent, WikiPageEvent, WikiSecurityEvent, WikiEventListener, WikiEventUtils


Category.D