Custom Event Handlers

User activity in rap-X is recorded as Events. A background task processes these events, and calls event handlers to deal with them. These event handlers are defined in a configuration file found in WEB-INF/notif.xml. By default, rap-X is configured to use event handlers which send emails notifications to users. Custom events handlers can be written to perform whatever functionality is required in response to events. These event handlers must implement the following Java interface:

//*
 * Processor.java
 *
 * Created on September 7, 2002, 1:27 AM
 */

package com.rap_x.notify;

import java.util.Collection;

/**
 * Processor interface.
 * Processors are used to react to events published by rap-X.
 * They are typical used to perform actions such as
 * selecting users, sending emails, 
 * altering user settings, etc.
 *
 * @author  oleg
 */
public interface Processor {
    
    /**
     * Process the notification event.
     * Do whatever you wish here: send emails, alter user settings, etc.
     * @param users - the Users who are watching this event
     * @param evt The Notification Event to process
     * @throws ProcessingException
     */

    public void handleEvent(Collection users, NotificationEvent evt)
    throws ProcessingException;
    
    /**
     * Configures this processor using information provided in
     * elem object. 
* This method is called before any call to * {@link #handleEvent(Collection, NotificationEvent)} * @param elem XML element containing attributes required for * configuration of the implementing class * @throws ConfigurationException */ public void configure(org.dom4j.Element elem) throws ConfigurationException; /** * Called by the framework when the class is about * to be unferenced so that any allocated resources * may be freed.
* * {@link #handleEvent(Collection, NotificationEvent)} * will not be called after this method executes. */ public void cleanup(); }

Registering a Custom Processor

To register your class for use by rap-X it is necessary to edit notif.xml file. This file is organized as follows. Under root tag <config> there are definitions of aliases and slots. Aliases are used to provide a short name to your class, this is particularly useful if you need to specify it more than once. A side effect of this is that you can change the implementation class name in one place instead of changing it in many places scattered across the file.


You can define an alias for your Processor as follows:

<alias name="ALIAS_NAME"
class="FULLY_QUALIFIED_CLASSNAME">
Documentation goes here (optional)
</alias>

For example email sender processor is aliased as below:

<alias name="email"
class="com.rap_x.notify.processor.SendEmailProcessor">
Send email
</alias>

Slots correspond to events in rap-x. Every rap-x event type which is identified by a string has a corresponding slot. Below is a DTD for slot tag and its children.


<!ELEMENT slot
description?, (task | condition | selector | processor) *>
<!ATTLIST slot
event CDATA #REQUIRED
class CDATA #IMPLIED >
<!-- class attribute in slot tag is used by the XSL stylesheet which
presents a convenient table of events.
Should be one of "req", "prop", "news" or none -->

<!ELEMENT task
(task | condition | selector | processor) * >

<!ELEMENT condition
(condition | selector | processor) * >
<!ATTLIST condition
name CDATA #REQUIRED >


<!ELEMENT selector
ANY >
<!ATTLIST selector
name CDATA #REQUIRED >

<!ELEMENT processor
ANY>
<!ATTLIST processor
name CDATA #REQUIRED >

Typical event handlers work as follows:

  • <selector> collect relevant users into a collection (consequent selectors append to the collection)
  • <processor> either sends emails or modifies users' watch modes
  • <condition> tags allow conditionally include groups of users. As seen from DTD, it can contain other conditions, selectors or processors.
  • <task> tags are used to define separate tasks. Collection of users does not survive between task tags. I.e. in this particular example:

<slot event="RENT" class="req">

 <description>New Request Entered</description>

 <task>
 <selector name="Cat-ReqAuthorOrg" mode="new"/>
 <processor name="email" xsltext="request_entered.xsl">
  <subject>
    <value-of select="/event/supplier/requestLabel" hint="request"/>
    <value-of select="/event/request/no" hint="request#"/>NEW
    <value-of select="/event/supplier/requestLabel"/>from
    <value-of hint="requestor organisation" select="/event/request/author/org/name"/>/
    <value-of hint="requestor name" select="/event/request/author/login"/>
    &quot;<value-of select="/event/request/title" hint="request title"/>&quot;
  </subject>
 </processor>
 </task>

 <task>
  <selector name="Cat-ReqAuthorOrg" mode="key"/>
   <processor name="Req-AddWatch"/>
 </task>

</slot>

there are 2 tasks. The Selector in the second task starts with an empty list of users.