HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Event Management & Enterprise JavaBeans"
Volume: 4 Issue: 1, p. 8

	

Listing 1:
  
package event; 

import java.util.EventListener; 
import java.io.Serializable; 

/** 
 *  Interface for anything that will consume events. 
 */ 

public interface EventConsumer 
    extends EventListener 
  { 

  /** 
   * Consume method processes events of interest. 
   * @param Event the event. 
   */ 
  public void consume(Event event); 
} 
  

Listing 2:
  
package event; 

/** 
 * The interface used by any component that 
 * distributes events to other consumers. 
 */ 
public interface EventDistributor { 
  /** 
   * Add an Event Consumer to the existing set of 
   * event consumers that will be called when an 
   * event of the proper type is recieved. 
   * @param EventConsumer the consumer to be 
   * added. 
   * @param String the context in which the event 
   * consumer wants to be called. 
   */ 
  public void addEventConsumer(EventConsumer cons, 
    String context); 

  /** 
   * Remove an Event Consumer from the existing 
   * set of event consumers that will be called 
   * when an event is processed. 
   * @param EventConsumer the consumer to be 
   * removed. 
   */ 
  public void removeEventConsumer(EventConsumer c); 
} 
  

Listing 3:
  
package event; 

import com.sun.java.swing.event.EventListenerList; 
import java.io.Serializable; 

/** 
 * Abstract class that both consumes events and 
 * forwards event to other consumers. 
 * Generally used to filter the events by their 
 * context and possibly some other data, so that 
 * the other consumers get only the events they 
 * are interested in. 
 * The consume method needs to be implemented. 
 */ 

public abstract class EventFilter implements 
    EventConsumer, EventDistributor, Serializable 
{ 
  private EventListenerList myEventConsumer = null; 

  /** 
   * Constructor. 
   */ 
  public EventFilter () { 
    myEventConsumer = new EventListenerList(); 
  } 

  /** 
   * Abstract method that processes Events. 
   * This method needs to be implmented to 
   * process each event when they are received. 
   * @param Event the event to be processed. 
   * @see EventConsumer. 
   */ 
  public abstract void consume(Event event); 

  /** 
   * Add an event consumer. 
   * @see EventDistributor. 
   */ 
  public void addEventConsumer( 
      EventConsumer consumer, String context) 
  { 
    myEventConsumer.add(EventConsumer.class, 
      consumer); 
  } 

  /** 
   * Remove an event consumer. 
   * @see EventDistributor. 
   */ 
  public void removeEventConsumer( 
      EventConsumer consumer) 
  { 
    myEventConsumer.remove(EventConsumer.class, 
      consumer); 
  } 

  /** 
   * Call all consumers that have registered. 
   * Helper method to walk the list of consumers 
   * calling all of their consume methods. 
   * @param Event the event to be processed. 
   * @see EventListenerList 
   */ 
  protected void fireEventConsumer(Event newEvent) 
  { 
    Object[] listeners = 
      myEventConsumer.getListenerList(); 

    for (int i = listeners.length-2; 
        i >= 0; 
        i -= 2) 
    { 
      if (listeners[i] == EventConsumer.class) { 
        ((EventConsumer) 
          listeners[i+1]).consume(newEvent); 
      } 
    } 
  } 
} 

Listing 4:
  
package event; 

import java.util.Hashtable; 
import java.io.Serializable; 

/** 
 * The Basic event object that is passed around by 
 * the * Event Distribution system. This object can 
 * contain any and all information that is needed 
 * for any event. 
 */ 

public class Event implements Serializable { 
  private EventContext context = null; 
  private Hashtable data = null; 

  /** 
   * Event constructor. Builds an event with the 
   * context set to the value of it's argument. 
   * @param String type The context in a URL 
   * notation. 
   */ 
  public Event(String type) { 
    context = new EventContext(type); 
    data = new Hashtable(); 
  } 

  /** 
   * Get an attribute from the attributes in the 
   * event. 
   * @param String name of the attribute that will 
   * be returned. 
   * @return Object the value of the attribute 
   * that was asked for. Null if attribute is 
   * not found. 
   */ 
  public Object getAttributeByName(String name) { 
    return data.get(name); 
  } 

  /** 
   * Add an attribute by name. Override existing 
   * one if their is a name collision. 
   * @param String name of the new attribute. 
   * @param Object value of the new attribute. 
   */ 
  public void setAttributeByName 
    (String name, Object value) { 
      data.put(name, value); 
  } 

  /** 
   * Checks to determine if this event's context 
   * matches the context of the argument. 
   * Advances the context to the next component 
   * if the context does match. 
   * @param String context we are checking 
   * against. 
   * @return boolean true if this object has the 
   * same context as the one passed in. 
   * @see EventContext 
   */ 
  public boolean isA(String type) { 
    String c = context.getComponent(); 
    if (c != null && (c.equals(type))) { 
      context.nextComponent(); 
      return true; 
    } 
    return false; 
  } 

  /** 
   * Publishes this event to the Event 
   * Distribution system. 
   */ 
  public void publish() { 
    // TODO: Call the helper... 
  } 

  /** 
   * Returns a string of this Event's context. 
   * @return String the context of this event. 
   */ 
  public String toString() { 
    return context.toString(); 
  } 
} 

Listing 5:
  
package event; 

import java.io.Serializable; 
import java.util.Vector; 

/** 
 * EventContext handles URL encoding of the type 
 * of event or event consumer that is required. 
 */ 
public class EventContext 
    implements Serializable 
{ 
  String originalContext = null; 
  String context = null; 

  /** 
   * EventContext constructor. Constructs an 
   * event context from the argument. 
   * @param String the context. 
   */ 
  public EventContext(String context) { 
    if (!context.startsWith("events://")) { 
      System.err.println( 
        "Invalid context string: " + context); 
    } 
    originalContext = context; 
    this.context = context.substring(9); 
  } 

  /** 
   * Get the current component of the event 
   * context. If the event context was 
   * "events://Security/Breach/FailedLogin 
   * the first call would return "Security", 
   * the second call would return "Breach", 
   * etc. Calls to getComponent do NOT move 
   * the context forward 
   * @return String the current component of 
   * the events context. 
   * @see nextComponent. 
   */ 
  public String getComponent() { 
    if (context == null) { 
      return null; 
    } 

    String component = null; 
    int end; 
    end = context.indexOf('/'); 

    if (end != -1) { 
      component = context.substring(0, end); 
    } else { 
      end = context.indexOf('?'); 
      if (end != -1) { 
        component = context.substring(0, end); 
      } else { 
        component = context; 
      } 
    } 
    return component; 
  } 

  /** 
   * Move from the current component to the next 
   * component. If the event context was 
   * "events://Security/Breach/FailedLogin 
   * before calling nextComponent() getComponent 
   * would return "Security", after calling it 
   * once nextComponent() would return "Breach", 
   * etc. 
   * @see nextComponent. 
   */ 
  public void nextComponent() { 
    if (context == null) { 
      return; 
    } 

    int end; 
    end = context.indexOf('/'); 

    if (end != -1) { 
      context = context.substring(end+1); 
    } else { 
      end = context.indexOf('?'); 
      if (end != -1) { 
        context = context.substring(end+1); 
      } else { 
        context = null; 
      } 
    } 
  } 

  /** 
   * Get the string representation of the event 
   * context. 
   * @return String the string representation of 
   * the context. 
   */ 
  public String toString() { 
    return originalContext; 
  } 
} 

Listing 6:
  
package event; 

/** 
 * A sample distributor for the Events distribution 
 * example code.  Used strictly for testing and 
 * demoing of the Event Distributor package. 
 * @see EventFilter 
 */ 

public class BasicDistributor extends EventFilter { 
  public BasicDistributor() { 
    super(); 
    System.out.println("BasicDistributor constructor"); 
  } 

  public void publish(Event event) { 
    System.out.println("BasicDistributor.publish " + 
      event.toString()); 
    fireEventConsumer(event); 
  } 

  public void consume(Event event) { 
    System.out.println("BasicDistributor.consume " + 
      event.toString()); 
  } 
} 

Listing 7:
  
package event; 

/** 
 * Sample Event consumer for demoing of the Event 
 * distribution package. 
 * @see EventFilter 
 */ 

public class ChartUpdateConsumer extends EventFilter { 
  public ChartUpdateConsumer() { 
    super(); 
    System.out.println("ChartUpdateConsumer constructor"); 
  } 

  public void consume(Event event) { 
    if (event == null) { 
      System.out.println( 
        "ChartUpdateConsumer.consume event is null"); 
      return; 
    } 

    if (event.isA("Chart Update")) { 
      System.out.println("ChartUpdateConsumer.consume: " + 
        event.toString()); 
      fireEventConsumer(event); 
    } 
  } 
} 

Listing 8:
  
package event; 

/** 
 * Another test consumer. 
 * @see FailedLoginConsumer. 
 */ 
public class SecurityConsumer 
    extends EventFilter 
{ 

  public SecurityConsumer() { 
    super(); 
    System.out.println( 
      "SecurityConsumer constructor"); 
  } 

  public void consume(Event event) { 
    if (event == null) { 
      System.out.println( 
        "SecurityConsumer.consume event is null"); 
      return; 
    } 

    if (event.isA("Security")) { 
      System.out.println( 
        "SecurityConsumer.consume: " + 
        event.toString()); 
      fireEventConsumer(event); 
    } 
  } 
} 

Listing 9:
  
package event; 

/** 
 * Test consumer to verify the event distribution system 
 * works correctly. 
 * @see EventFilter 
 */ 
public class FailedLoginConsumer 
    extends EventFilter 
{ 

  static final long OFFSET = 30000; 
  long firstTime = 0; 
  long secondTime = 0; 
  long thirdTime = 0; 

  /** 
   * Constructor. 
   */ 
  public FailedLoginConsumer() { 
    super(); 
    System.out.println( 
      "FailedLoginConsumer constructor"); 
  } 

  /** 
   * consume each event. 
   * @param Event the event. 
   * @see EventFilter. 
   */ 
  public void consume(Event event) { 
    if (event.isA("FailedLogin")) { 
      System.out.println( 
        "FailedLoginConsumer.consume: " + 
        event.toString()); 
      if (attack()) { 
        System.out.println( 
          "FailedLoginConsumer.AttackDetected: " + 
          event.toString()); 
        fireEventConsumer(event); 
      } 
    } 
  } 

  /** 
   * Some business logic to determine if a 
   * login attack is occuring. Demonstrates 
   * how to process events. 
   */ 
  private boolean attack() { 
    firstTime = secondTime; 
    secondTime = thirdTime; 
    thirdTime = System.currentTimeMillis(); 

    if((thirdTime - firstTime) < OFFSET) { 
      return true; 
    } else { 
      return false; 
    } 
  } 
} 

Listing 10:
  
package event; 

/** 
 * A test driver for the Event distribution 
 * system. Builds a distributor, adds a few 
 * consumers in a chain, and fires some events 
 * off to the distributor.  Should cause the 
 * consumers to process the events as desired. 
 */ 
public class main { 

  private BasicDistributor distro = null; 

  /** 
   * Main method. Just creates an object so 
   * the object can test the rest of the system. 
   */ 
  public static void main (String[] args) { 
    System.out.println("Testing Events."); 
    main m = new main(); 
  } 

  /** 
   * Constructor. Actually performs the test. 
   */ 
  public main () { 
    System.out.println("Starting Distributor."); 
    distro = new BasicDistributor(); 

    System.out.println( 
      "Registering consumer callback."); 
    SecurityConsumer s = new SecurityConsumer(); 
    distro.addEventConsumer( 
      s, "events://Security"); 

    ChartUpdateConsumer c = 
      new ChartUpdateConsumer(); 
    distro.addEventConsumer(c, 
      "events://Chart Update"); 

    FailedLoginConsumer f = 
      new FailedLoginConsumer(); 
    s.addEventConsumer(f, 
      "events://Security/FailedLogin"); 

    System.out.println("Publishing events."); 
    Event e = new Event( 
      "events://Security/FailedLogin"); 
    distro.publish(e); 

    e = new Event( 
      "events://Security/FailedLogin"); 
    distro.publish(e); 

    // Use this sleep to verify the login in 
    // the FailedLoginConsumer acts correctly. 

    /* 
    try { 
      Thread.currentThread().sleep(30000); 
    } catch (InterruptedException ex) { 
    } 
    */ 

    e = new Event( 
      "events://Security/FailedLogin"); 
    distro.publish(e); 

    e = new Event( 
      "events://Chart Update?Joe Smith"); 
    distro.publish(e); 

    e = new Event( 
      "events://Security/Breach/Invalid Cridentials"); 
    distro.publish(e); 

    System.out.println("Done."); 
  } 
} 

Listing 11:
  
Testing Events. 

Starting Distributor. 

BasicDistributor constructor 

Registering consumer callback. 

SecurityConsumer constructor 

ChartUpdateConsumer constructor 

FailedLoginConsumer constructor 

Publishing events. 

BasicDistributor.publish events://Security.FailedLogin 

SecurityConsumer.consume: events://Security.FailedLogin 

FailedLoginConsumer.consume: events://Security.FailedLogin 

BasicDistributor.publish events://Security.FailedLogin 

SecurityConsumer.consume: events://Security.FailedLogin 

FailedLoginConsumer.consume: events://Security.FailedLogin 

BasicDistributor.publish events://Security.FailedLogin 

SecurityConsumer.consume: events://Security.FailedLogin 

FailedLoginConsumer.consume: events://Security.FailedLogin 

FailedLoginConsumer.AttackDetected: events://Security.FailedLogin 

BasicDistributor.publish events://Chart Update/Joe Smith 

ChartUpdateConsumer.consume: events://Chart Update/Joe Smith 

BasicDistributor.publish events://Security.Breach.Invalid Cridentials 

SecurityConsumer.consume: events://Security.Breach.Invalid Cridentials 

Done. 

  
      
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.