Class designation: Class org.apache.wiki.event.WikiEngineEvent extends org.apache.wiki.event.WikiEvent

WikiEngineEvent extends the abstract class WikiEvent to provide notification of changes in the state of the WikiEngine. There are four types of WikiEngineEvents:

WikiEngineEvent.INITIALIZING
indicates a WikiEngine initialization event, fired as the wiki service is being initialized (in progress)
WikiEngineEvent.INITIALIZED
indicates a WikiEngine initialized event, fired after the wiki service is fully available
WikiEngineEvent.SHUTDOWN
indicates a WikiEngine closing event, fired as a signal that the wiki service is shutting down
WikiEngineEvent.STOPPED
indicates a WikiEngine stopped event, fired after halting the wiki service. A WikiEngine in this state is not expected to provide further services

An Example#

The following example is code taken directly from the WikiEngine class.

If you are creating your own class that used event handling it might look similar to this. You'd likely want to create your own subclass of WikiEvent (if none of the existing subclasses suited your particular purpose) and follow the steps below:

1. Create a WikiEventListener#

Create an inner class implementing WikiEventListener, which has one actionPerformed(WikiEvent) method that is called when it receives a WikiEvent. This method that contains code that reacts to the event (i.e., whatever it is you want to happen upon receiving an event of a certain type)

    WikiEventListener listener = new WikiEventListener() {
            public void actionPerformed( WikiEvent e ) {
                Object o = e.getSource();
                if ( o instanceof WikiEngine ) { // it's an event for us
                    wikiStateChanged((WikiEngine)o,e);
                }
            }
        };

2. Add the listener to the WikiEventManager#

Add the WikiEventListener for this object to the WikiEventManager using:

    WikiEventManager.addWikiEventListener(this,listener);

3. Create your own fireEvent() method#

Create a fireEvent() method containing an isListening(this) filter so that events are created and forwarded on to the WikiEventManager only if there's somebody actually listening for them (note that a listener for an object can be added to the WikiEventManager from anywhere that has access to the object, not simply from the object itself). You may wish to filter in other ways, based on type or other context available to your class.

Your method's parameter will contain either an already-created event object or the parameters necessary to create an event object of your particular subclass of WikiEvent.

    protected final void fireEvent( int type )
    {
        // is the manager listening for events from this object?
        if ( WikiEventManager.isListening(this) )
        {
            // create an event from the parameters
            WikiEngineEvent event = new WikiEngineEvent(this,type);
            // send the event on to the WikiEventManager, which will
            // forward it on to the delegate to send to its listeners 
            WikiEventManager.fireEvent(this,event);
        }
    }

Part of the impetus in performing checks before firing is the scenario of a large and busy wiki, where the volume of events is enormous — we don't want to create and fire events off to a central manager unless they are actually being listened for. In a lot of Java programs one just fires events off regardless of their value or use, but given that a single wiki page display could generate dozens of events, a single call to RecentChanges multiplies that times the number of pages on the wiki, multiplied by the number of users. There could be a lot of events so we're trying to limit those fired to only the ones where there's somebody listening.

4. Fire your events!#

Fire the event(s) upon appropriate circumstances. In WikiEngine there are events fired at the beginning and end of the initialization process, and upon engine shutdown:

    private void initialize( Properties props )
        throws WikiException 
    {

        fireEvent( WikiEngineEvent.INITIALIZING ); // begin initialization

        // the WikiEngine is initialized...

        fireEvent( WikiEngineEvent.INITIALIZED ); // initialization complete

    }

    protected void shutdown()
    {
        fireEvent( WikiEngineEvent.SHUTDOWN );
    }

5. Process the incoming events#

The previously-created WikiEventListener receives the events from the WikiEventManager's delegate for the WikiEngine object (in an extremely mysterious and almost mystical process you needn't worry about), calling the listener's actionPerformed() method. If you recall above, the listener contained a call to wikiStateChanged((WikiEngine)o,e).

Since there is nothing within JSPWiki that actually exercises this code, the below example is taken from Ceryle's WikiUtils class, which provides event notification of changes in the WikiEngine state.

    public void wikiStateChanged( WikiEngine engine, WikiEvent event )
    {
        switch ( event.getType() ) {

            case WikiEngineEvent.INITIALIZING:
                // the WikiEngine is just starting up
                break;

            case WikiEngineEvent.INITIALIZED:
                // the WikiEngine is finished initializing
                break;

            case WikiEngineEvent.SHUTDOWN:
                // the WikiEngine is starting to shut down
                break;

            case WikiEngineEvent.STOPPED:
                // the WikiEngine is dead, long live the WikiEngine
                break;

            default:
                // you may want to handle ERROR and UNDEFINED, or any
                // other WikiEvent subclass types that might arrive
        }
    }

6. Ending it all#

When you no longer need notification, or when your class is being destroyed, it's probably a good idea to remove the existing listeners,

    WikiEventManager.removeWikiEventListener( this, listener );
otherwise they just hang around and get older and take up space and smoke cigarettes.

Using a fireEvent() method#

Sections 3 and 4 above describe a single fireEvent() method that gets called with the necessary event parameters from elsewhere within the class, what one might call a "consolidated" approach.

The alternative to this (a "distributed" approach) would be to create and fire your events without using a single fireEvent() method, effectively copying the internals of the fireEvent() method to each place you plan to fire an event. The advantage of the approach shown here is that you only need one version of the checks (which in the example is only isListening() but could be much more complicated), and it's also easier to debug and/or disable if events actually get fired from one place.

But if your class only has only one place where it fires events, or if the checks vary depending on context, you could avoid creating the consolidated fireEvent() method and just fire the events directly, using something akin to the following:

    public void myMethod()
    {
        // ...

        boolean okToFire = true; // your checks on firing context here

        if ( okToFire && WikiEventManager.isListening(this) )
        {
            WikiEventManager.fireEvent(this,
                    new WikiEngineEvent(this,type));
        }

        // ...
    }

See: WikiEvent


Category.D