FileDocCategorySizeDatePackage
EventTransceiver.javaAPI DocExample4525Tue Jan 20 21:43:38 GMT 1998dcj.util.message

EventTransceiver.java

package dcj.util.message;

import java.util.*;
import java.net.*;
import java.io.*;

/**
 * Source code from "Java Distributed Computing", by Jim Farley.
 *
 * Class: EventTransceiver
 * Example: 6-13
 * Description: One end of an event-based network communication scheme.
 */

public class EventTransceiver extends Thread implements EventHandler {
  // A hashtable of handlers for specific events
  private Hashtable handlers = new Hashtable();
  // A list of handlers that want all events
  private Vector globalHandlers = new Vector();

  // Our connection to a remote agent
  InputStream evIn = null;
  OutputStream evOut = null;

  public EventTransceiver(String host, int port) {
    try {
      InetAddress a = InetAddress.getByName(host);
      connect(a, port);
    }
    catch (Exception e) {}
  }

  public EventTransceiver(InetAddress a, int port) {
    connect(a, port);
  }

  void connect(InetAddress a, int port) {
    try {
      Socket s = new Socket(a, port);
      evIn = s.getInputStream();
      evOut = s.getOutputStream();
    }
    catch (Exception e) {
      evIn = null;
      evOut = null;
    }
  }

  public EventTransceiver(InputStream in, OutputStream out) {
    setStreams(in, out);
  }

  void setStreams(InputStream in, OutputStream out) {
    evIn = in;
    evOut = out;
  }

  public void sendEvent(EventObject ev) throws IOException {
    ObjectOutputStream oout = new ObjectOutputStream(evOut);
    oout.writeObject(ev);
  }

  EventObject receiveEvent() throws IOException {
    ObjectInputStream oin = new ObjectInputStream(evIn);
    EventObject ev = null;
    try {
      ev = (EventObject)oin.readObject();
    }
    catch (ClassCastException e) {
      System.out.println("Non-event object sent to EventTransceiver");
    }
    catch (ClassNotFoundException e2) {
      System.out.println("Unresolvable object type sent to EventTransceiver");
    }

    return ev;
  }

  void distributeEvent(EventObject ev) {
    // Send event to all "global" handlers
    Enumeration e = globalHandlers.elements();
    while (e.hasMoreElements()){
      EventHandler h = (EventHandler)e.nextElement();
      h.handleEvent(ev);
    }

    // Send event to handlers targetting the event's class
    Class evClass = ev.getClass();
    Vector evHandlers = (Vector)handlers.get(evClass);
    e = evHandlers.elements();
    while (e.hasMoreElements()) {
      EventHandler h = (EventHandler)e.nextElement();
      h.handleEvent(ev);
    }
  }

  // No default behavior for handling events...
  public void handleEvent(EventObject e) {}

  // Register a handler that wants all events.
  public void addHandler(EventHandler eh) {
    if (!globalHandlers.contains(eh)) {
      globalHandlers.addElement(eh);
    }
  }

  // Register a handler for a specific type of event
  public void addHandler(EventHandler eh, EventObject e) {
    Class eClass = e.getClass();
    addHandler(eh, eClass);
  }

  public void addHandler(EventHandler eh, Class ec) {
    Vector evHandlers = (Vector)handlers.get(ec);
    if (evHandlers == null) {
      evHandlers = new Vector();
      handlers.put(ec, evHandlers);
    }
    if (!evHandlers.contains(eh)) {
      evHandlers.addElement(eh);
    }
  }

  // Remove a handler from all lists
  public void removeHandler(EventHandler eh) {
    globalHandlers.removeElement(eh);
    Enumeration ecList = handlers.keys();
    while (ecList.hasMoreElements()) {
      Vector evHandlers =
        (Vector)handlers.get(ecList.nextElement());
      if (evHandlers != null) {
        evHandlers.removeElement(eh);
      }
    }
  }

  // Remove a handler for a specific event type
  public void removeHandler(EventHandler eh, EventObject e) {
    removeHandler(eh, e.getClass());
  }

  public void removeHandler(EventHandler eh, Class ec) {
    Vector evHandlers = (Vector)handlers.get(ec);
    if (evHandlers != null) {
      evHandlers.removeElement(eh);
    }
  }

  // If run as an independent thread, just loop listening
  // for events from the remote agent, and distribute them
  // to registered handlers
  public void run() {
    try {
      while (true) {
        EventObject e = receiveEvent();
        if (e != null)
          distributeEvent(e);
      }
    }
    // Treat an IOException as termination of the event
    // input stream, and let this handler thread die
    catch (IOException e) {}
  }
}