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) {}
}
} |