![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Developing exteNd Director Applications
CHAPTER 13
This chapter describes the exteNd Director event model and event-handling concepts. It has these sections:
The exteNd Director event model is an extension of the event listener/producer model in Java. An event is a lightweight notification object that contains information relevant to one or more event listeners. The listener responds to the event in an appropriate way. The primary user of events in exteNd Director is the Content Management (CM) subsystem, which defines event objects for various CM operations. For example, you can register a listener for the "document added" operation that generates an event carrying information about the document's author, title, and other data. You can handle this event in any way you choose, like making a log entry, writing to a print stream, or e-mailing interested parties. exteNd Director provides an extensible event framework with a full set of predefined events for CM, WebDav, and CM task management operations.
This chapter describes basic event concepts in exteNd Director. For information about event support for specific subsystems, see the following:
Subsystem or function |
Information about events |
---|---|
CM subsystem |
|
CM tasks |
|
WebDAV |
The exteNd Director event model consists of these types of objects:
Event handling is the processing of a specific event by a listener after the listener's event handler method is called by the event producer. In this context, the event listener functions as the event handler object. Here is a flow diagram of the event handling process. The flow assumes an event associated with a database transaction, like a CM repository update:
In this scenario, several regular listeners have been registered with an event producer. An action in the event domain of the producer has occurred—such as a user adding a document to the CM repository. Here is the event-handling sequence:
After verifying that there are no vetoable listeners registered for this event, the event producer performs the action requested.
If the action fails for some reason, the producer handles the exception.
If the action succeeds, the event producer instantiates an event object and populates it with relevant information.
The event producer calls the stateChanged() event handler for each listener, passing in the event object.
NOTE: The event producer notifies the listeners in the order in which they were registered.
As the method is called, each listener performs any specified notification, such as e-mailing an interested party.
In this scenario, several vetoable and regular listeners are registered for the event, and the action is vetoed. Here is the event-handling sequence:
The event producer instantiates an event object and populates it with relevant information.
The event producer calls the vetoableStateChanged() event handler for each vetoable listener.
Since the event is vetoed, no action is performed by the producer and no regular listeners are notified.
In the final scenario, several vetoable and regular listeners are registered for the event, and the action is not vetoed. Here is the event-handling sequence:
The event producer calls the vetoable stateChanged() event on each vetoable listener.
Since no listener vetoes the action, the event producer performs it.
Assuming the action does not fail, the producer iterates over the regular listeners by calling their stateChanged() methods.
This section is an overview of the exteNd Director Event API.
This diagram shows the class hierarchy for the event objects:
Also (not shown in the diagram), the Event API includes class constants related to event monitoring:
This diagram shows the class hierarchy for the event producer interfaces:
This diagram shows the class hierarchy for the event listener interfaces:
To implement events in your application, you first need to determine what events you are interested in and how you want to handle them:
Decide what types of operations you want to monitor. In the case of content management elements, decide what element (directories, documents, document types etc.) in the repository you are interested in.
Figure out the logic you need to handle the event. Typically you'll want to notify an interested party, record the event in a log, or respond in some other manner.
Determine whether there are conditions under which you want to veto an operation represented by an event. In these cases use a vetoable listener.
Implementing your event scheme involves these steps:
Instantiate a listener to handle the event.
TIP: For reusability you can create a separate listener class that implements one or more of the event listeners.
Register the listener and events using one of the add listener methods on the event producer.
Event handling usually involves some kind of notification, like making a log entry or e-mailing an interested party. exteNd Director provides the following support for event notification:
Notification listener |
What it does |
---|---|
Sends an e-mail to specified parties |
|
Writes to a specified log |
|
Writes to a specified print stream. |
You can get a notification listener using the appropriate factory method. For example:
EbiMailStateChangeListener listener = com.sssw.fw.event.factory.EboFactort.getMailStateChangeListener();
This example shows how to create a class that implements an EbiMailStateChangeListener by delegating to the default listener:
public class MyClass implements com.sssw.fw.event.api.EbiStateChangeListener { protected EbiMailStateChangeListener m_scl; public void stateChanged(EboStateChangeEvent event) { try { EbiMailStateChangeListener scl = getScl(); scl.setMsgText(...); // provide other settings ... scl.stateChanged(event); } catch (Exception ex) { // handle exceptions here } } protected EbiMailStateChangeListener getScl() throws EboFactoryException { if (m_scl == null) m_scl = com.sssw.fw.event.factory.EboFactory.getMailStateChangeListener(); return m_scl; } }
To veto an operation, you define the veto condition in the vetoable listener's vetoableStateChanged() event and return false. The event producer responds by vetoing the operation and throwing com.sssw.fw.exception.EboOperationVetoedException.
Because EboOperationVetoedException is a runtime exception, it is not included in the throws clause of the operation methods. However, you must handle the exception somewhere in your code. 1For example: if you added a vetoable listener that included the content management add document event, you would need to handle the exception for the addDocument() method, as shown here:
try { EbiContentMgmtDelegate cmgr = ... EbiAddDocumentParams params = ... EbiDocument doc = cmgr.addDocument(context, params); ..... } catch (EboUnrecoverableSystemException ue) { // handle unrecoverable system exception } catch (EboSecurityException se) { // handle security exception } catch (EboItemExistenceException iee) { // handle item existence exception } catch (EboOperationVetoedException ove) { // handle operation vetoed exception } catch (Exception e) { // handle any other exception }
To create a listener you need to implement one or more of the listener interface(s) in your application code.To create a regular (non-vetoable) listener, provide an implementation for the stateChanged() method, as shown here:
public class MyClass implements com.sssw.fw.event.api.EbiStateChangeListener { public void stateChanged(EboStateChangeEvent event) { // perform action, inspect event, and notify... } }
IMPORTANT: You must provide implementations for the four methods on the super class EbiEventListener (extended by EbiStateChangeListener). This applies to creating a vetoable listener as well.
Creating a vetoable listener To create a vetoable listener, provide an implementation for the vetoableStateChanged() method, as shown here:
public MyClass implements EbiVetoableStateChangeListener { public boolean vetoableStateChanged(EboStateChangeEvent event) { // Inspect event: // If vetoed, return false // If not vetoed return true and perform action } }
IMPORTANT: If an action or operation is vetoed, the event producer throws a runtime exception called EboOperationVetoedException. See Using a vetoable listener.
You register for events using one of the add listener methods on EbiStateChangeProducer or one of its subclasses.
When you add an event listener you can specify a range of events for which you want to register in a Java BitSet, using the addStateChangeListener() or addVetoableStateChangeListener() method. For example:
EbiStateChangeProducer producer = new EbiStateChangeProducer() BitSet events = new BitSet(); events.set(MyEvent.getEventID());//interested in MyEvent events.set(MyEvent2.getEventID());//interested in MyEvent2 producer.addStateChangeListener(events, MyListenerClass);
The event IDs for content management, WebDAV, and task management are defined as constants in the respective subsystem API packages. The com.sssw.cm.api also provides some helper methods for populating the BitSet.
For more information, see the section on using the event helper class in the Content Management Guide.
You can extend the Event API to write your own state change event and event producers.
You can write your own event producer that uses custom versions of the addStateChangeListener() method. To create a state change producer, you must implement the com.sssw.fw.event.api.EbiStateChangeProducer interface.
The example that follows shows how to delegate to the default event producer. It uses a factory method to get the default state change producer, adds a description and log, and provides an implementation of addStateChangeListener():
public class MySCP implements com.sssw.fw.event.api.EbiStateChangeProducer { protected EbiStateChangeProducer m_scp; public MySCP() {} public boolean addStateChangeListener(BitSet events, EbiStateChangeListener listener) { getScp().addStateChangeListener(events, listener); } // .... // other EbiStateChangeProducer methods, implemented with addStateChangeListener()... // .... protected EbiStateChangeProducer getScp() { if (m_scp == null) { m_scp = com.sssw.fw.event.factory.EboFactory.getStateChangeProducer(); m_scp.setScpDescription("My state change event producer"); m_scp.setScpLog(EboLogFactory.getLog(MYLOG)); } return m_scp; } }
A custom state change event must extend com.sssw.fw.event.api.EboStateChangeEvent. You need to implement the following two methods that are marked abstract in the superclass:
public abstract int getEventID(); public abstract String getVerboseDescr();
NOTE: The exteNd Director Framework API reserves the value range 1 through 8000, so you must use another value for your event ID.
Copyright © 2003 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved. more ...