001: /*
002: * Copyright (c) 2001 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.internal;
026:
027: import seda.sandStorm.api.*;
028: import java.io.*;
029: import java.util.*;
030:
031: /**
032: * The SignalMgr is an implementation of SignalMgrIF. It allows stages
033: * to register to receive certain signals and delivers those signals once
034: * they are triggered.
035: *
036: * @author Matt Welsh
037: * @see SignalMgrIF
038: * @see SignalIF
039: */
040: class SignalMgr implements SignalMgrIF {
041:
042: private Hashtable signalTbl; // Map signal type to Vector of sinks
043:
044: SignalMgr() {
045: signalTbl = new Hashtable();
046: }
047:
048: /**
049: * Register for the given signal type. When the signal is triggered,
050: * an object of the given type (although not necessarily the same
051: * object instance) will be delivered to the given SinkIF.
052: */
053: public void register(SignalIF signalType, SinkIF sink) {
054: Class type = signalType.getClass();
055: Vector vec = (Vector) signalTbl.get(type);
056: if (vec == null) {
057: vec = new Vector();
058: vec.addElement(sink);
059: signalTbl.put(type, vec);
060: } else {
061: for (int i = 0; i < vec.size(); i++) {
062: SinkIF s = (SinkIF) vec.elementAt(i);
063: if (s.equals(sink))
064: throw new IllegalArgumentException("Sink " + sink
065: + " already registered for signal type "
066: + type);
067: }
068: vec.addElement(sink);
069: }
070: }
071:
072: /**
073: * Deregister for the given signal type.
074: */
075: public void deregister(SignalIF signalType, SinkIF sink) {
076: Class type = signalType.getClass();
077: Vector vec = (Vector) signalTbl.get(type);
078: if (vec == null) {
079: throw new IllegalArgumentException("Sink " + sink
080: + " not registered for signal type " + type);
081: } else {
082:
083: for (int i = 0; i < vec.size(); i++) {
084: SinkIF s = (SinkIF) vec.elementAt(i);
085: if (s.equals(sink)) {
086: vec.removeElementAt(i);
087: return;
088: }
089: }
090: throw new IllegalArgumentException("Sink " + sink
091: + " not registered for signal type " + type);
092: }
093: }
094:
095: /**
096: * Send the given signal to all registered sinks. Uses enqueue_lossy
097: * on each sink, so if a sink rejects the signal this method will
098: * continue regardless. Package access only.
099: *
100: * XXX MDW: Really should register sinks with the chain of superclasses
101: * for each signal as well, so that triggering a superclass of a given
102: * signal will also reach those sinks registered for the subclass.
103: */
104: public void trigger(SignalIF signal) {
105: Class type = signal.getClass();
106: Vector vec = (Vector) signalTbl.get(type);
107: if (vec == null)
108: return;
109: for (int i = 0; i < vec.size(); i++) {
110: SinkIF s = (SinkIF) vec.elementAt(i);
111: s.enqueue_lossy(signal);
112: }
113: }
114:
115: }
|