Source code: com/voytechs/html/event/Dispatcher.java
1 /*
2 * File: Dispatcher.java
3 * Auth: Mark Bednarczyk
4 * Date: DATE
5 * Id: $Id: Dispatcher.java,v 1.1.1.1 2002/01/23 23:52:47 voytechs Exp $
6 ********************************************
7 * $Log: Dispatcher.java,v $
8 * Revision 1.1.1.1 2002/01/23 23:52:47 voytechs
9 * Initial public release, BETA 1.0 - voytechs
10 *
11 */
12 package com.voytechs.html.event;
13
14 import com.voytechs.html.util.LogFacility;
15
16 import java.lang.*;
17 import java.util.*;
18
19 /**
20 * An event dispatcher object. A user action triggers an event
21 * to be generated. Events are dispatched to event listeners.
22 * This is an abstract class and an appropriate implementation of it
23 * should be created, such as ServletDispatcher or CGI Dispatcher with
24 * appropriate hooks for processing the event conditions in whatever form
25 * they may be (ie. http forms).
26 */
27 public abstract class Dispatcher {
28 /* Internal attributes */
29
30 private int eventMask = 0x0000;
31 private int registeredEventTypes = 0x0000;
32 private Hashtable eventTypes = new Hashtable();
33
34 private Hashtable listenerHash = new Hashtable();
35
36 private int nextId = 1000;
37
38 /**
39 *
40 * @param
41 * @exception
42 */
43 public Dispatcher() {
44 }
45
46 /**
47 * Find if there is a listener for this event.
48 * If yes, find the listener and its custom assigned data,
49 * then allow subclassed dispatcher to do the dispatching.
50 */
51 protected void handleEvent(Event event)
52 throws EventException {
53
54 LogFacility.log.println("Dispatcher::handleEvent() event=" + event);
55
56 // Check to see if we need to handle this event type
57 if(isEventEnabled(event.getType()) == false)
58 return;
59
60 Vector lv = (Vector)listenerHash.get(new Integer(event.getId()));
61
62 if(lv == null)
63 return;
64
65
66 /*
67 * Allow dispatcher subclassed disptacher to disptach event and its cutom data.
68 */
69 for(int i = 0; i < lv.size(); i ++) {
70 ListenerRequest ld = (ListenerRequest)lv.elementAt(i);
71 event.setEventSource(ld.getSource());
72 dispatchEvent(ld.getListener(), event, ld.getData());
73 }
74
75 }
76
77 /**
78 * Register a new Event Type with dispatcher.
79 * After registration, dispatcher will be able to handle these event types
80 * and dispatch them as they occure.
81 * @param eventType The ID of the new Event Type.
82 */
83 protected void registerEventType(int eventType) {
84 registeredEventTypes |= eventType;
85 }
86
87 /**
88 *
89 */
90 public void removeSource(int eventType,
91 int source) throws EventException {
92
93 if(isEventEnabled(eventType) == false)
94 return; // Nothing to do.
95
96 listenerHash.remove(new Integer(source));
97 }
98
99 /**
100 * Add a new listener onto the Vector list of a particular Observed target.
101 * Basically a Hash table of Vectors. This is a convenience function.
102 * @param eventType ID of the type of event for which a listener is being
103 * added.
104 * @param target The observed target to which to attache the listener.
105 * @param listener The listener to notify when a specified event occures.
106 */
107 public void addListener(int eventType,
108 int target,
109 ListenerRequest request) throws EventException {
110
111 addListener(eventType, target, request.getListener(),
112 request.getData(), request.getSource());
113 }
114
115 /**
116 * Add a new listener onto the Vector list of a particular Observed target.
117 * Basically a Hash table of Vectors. This is a convenience function.
118 * @param eventType ID of the type of event for which a listener is being
119 * added.
120 * @param target The observed target to which to attache the listener.
121 * @param listener The listener to notify when a specified event occures.
122 */
123 public void addListener(int eventType,
124 int target,
125 ListenerIf listener,
126 Object listenerData,
127 Object eventSource) throws EventException {
128
129 if(isEventEnabled(eventType) == false)
130 throw new EventException("Event not enabled; type=" + eventType);
131
132 Vector listenerVector = null;
133 Integer t = new Integer(target);
134 if( (listenerVector = (Vector)listenerHash.get(t)) == null) {
135 listenerVector = new Vector();
136
137 listenerHash.put(t, listenerVector);
138 }
139
140 listenerVector.addElement(new ListenerRequest(listener,
141 listenerData,
142 eventSource));
143
144 }
145
146 /**
147 * Remove a listener of a particual event.
148 */
149 public void removeListener(int target, ListenerIf listener)
150 throws EventException {
151
152 Vector listenerVector = null;
153 Integer t = new Integer(target);
154 if( (listenerVector = (Vector)listenerHash.get(t)) == null)
155 throw new EventException("Can not remove listener; event is not " +
156 "registered; event=" + target);
157
158 ListenerRequest ld = new ListenerRequest(listener, null, null);
159 int i = listenerVector.indexOf(ld);
160 if(i < 0)
161 throw new EventException("Can not remove listener; listener is not " +
162 "registered for event=" + target);
163 else
164 listenerVector.removeElementAt(i);
165 }
166
167 /**
168 * Define which events to handle.
169 */
170 public void enableEvents(int mask) throws EventException {
171 if( (registeredEventTypes & mask) == 0)
172 throw new EventException("Can not enable event(s); One or more events " +
173 "not registered; eventMask=" + mask);
174
175 eventMask |= mask;
176 }
177
178 /**
179 * Check to see if event of this type has been enabled
180 * If yes, return true
181 * @param eventTypeId The ID of this Event Type. Not ID of the event.
182 */
183 protected boolean isEventEnabled(int eventTypeId) {
184 return( (eventMask & eventTypeId) != 0);
185 }
186
187 /**
188 * Let the dispatcher generated uniq Id. This ID is uniq in the dispatcher
189 * scope. If multiple dispatchers are running the IDs of each of the
190 * dispatchers will overlap, but uniq in their own contexes.
191 * @return A uniq ID generated by the dispatcher.
192 */
193 public int generateUniqId() {
194 return(nextId++);
195 }
196
197 /**
198 * Abstract method that is implementation dependent. It scans for conditions
199 * which would need to generate an event. All events are mapped and registered
200 * with the dispatcher via event type IDs.
201 */
202 protected abstract void scanEvent(Object source) throws EventException;
203
204 /**
205 * Abstract method that is implementation depenedent. It dispatches events to
206 * listners
207 * using their listener subclassed specific processEvent methods.
208 */
209 protected abstract void dispatchEvent(ListenerIf listener,
210 Event event,
211 Object data)
212 throws EventException;
213
214 } /* END OF: Dispatcher */