__WikiEventManager__ is a singleton class that manages the addition and removal of WikiEvent listeners 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);
}}}


!! 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 <tt>fireEvent()</tt> 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) )
      {
          WikiEventManager.fireEvent(this,new WikiEngineEvent(this,type));
      }
  }
}}}
This only needs to be customized to supply the specific parameters for
whatever WikiEvent you want to create.


!! 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.


!! Listener lifecycle

Note that in most cases it is not necessary to remove a listener.
As of 2.4.97, the listeners are stored as WeakReferences, and will be
automatically cleaned at the next garbage collection, if you no longer
hold a reference to them.  Of course, until the garbage is collected,
your object might still be getting events, so if you wish to avoid that,
please remove it explicitly as described above.

----
 
! Notes: Preloading Listeners

The design includes the ability to __preload__ listeners to the ~WikiEngine prior to instantiation, such that when WikiEngine's {{initialize()}} method is called, the listener fires a {{~WikiEvent.INITIALIZING}} event right after the m_properties member variable has been set. This enables foreign code to alter anything in jspwiki.properties prior to the event API sending {{~WikiEvent.INITIALIZED}}, signaling a finished initialization. See the ''Preloading Listeners'' section on the WikiEventManager page.

The WikiEventManager also manages the addition of event listeners to the WikiEngine prior to its instantiation. This is a "singleton-per-WikiEngine" object which works for either server or embedded applications. You can also ignore it and add listeners directly to the engine if you like. But if you use it for event management and you have an existing hook to the engine (or a WikiContext, which gets you the engine), you can then obtain all of the listeners attached to the engine and not have to deal with where the events are being fired from. This simplifies your life.

I've found a way around preloading WikiEventListeners in the
WikiEventManager, which was a hook to intercept the initialization
process of a WikiEngine by catching WikiEngineEvent.INITIALIZING
and pre-set properties. This was necessary for embedded applications
if one wanted to set something like installed paths or other settings
from the user application.

If you think about it, when a Java application containing an
embedded JSPWiki starts up, neither the WikiEngine nor the
WikiEventManager exist. We need a way to alter the properties
of the WikiEngine either before or during the initialization
process based on settings coming from the parent application.
To intercept the initialization, we 'preload' a listener to
a singleton cache in the WikiEventManager, which given that
the cache is static, doesn't even have to exist at that point.
Since in the WikiEventManager listeners are normally attached
to 'delegates' rather than directly to objects, we create a
delegate based not on the object (the WikiEngine that does not
yet exist) but on its *class*.

So, to preload a listener to the singleton WikiEventManager,
i.e., attach a listener to a non-existent WikiEngine by class
rather than by object, one could create a listener and call:
{{{
  WikiEventListener listener = getWikiEventListener();
  WikiEventManager.addWikiEventListener(
          WikiEngine.class,listener);
}}}
This adds the listener to the preload cache so that the when
the engine fires its first events or asks if anybody is
listening, we first check to see if there are any delegates
in the preload cache whose class matches the incoming object
(the WikiEngine), and rather than create a new delegate we
remove the cached delegate and attach it to the WikiEngine.
In this way we can attach listeners to a WikiEngine before it
even exists.

Is anyone using the preload feature? It's been around since the
beginning of the WikiEventManager and it may still prove useful.
But if nobody is using it we could either deprecate it or
outright remove it. If nobody is I'm sure it doesn't need to
survive into JSPWiki 2.6. The one advantage it does have is that
the alternative (using cascading properties in PropertyReader)
requires writing a property file to the file system that gets
picked up during initialization, whereas the preload feature is
entirely based on listeners and requires no files.