1 package org.djutils.event;
2
3 import java.io.Serializable;
4 import java.rmi.Remote;
5 import java.rmi.RemoteException;
6 import java.util.ArrayList;
7 import java.util.Iterator;
8 import java.util.LinkedHashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12
13 import org.djutils.event.reference.Reference;
14 import org.djutils.event.reference.ReferenceType;
15 import org.djutils.event.reference.StrongReference;
16 import org.djutils.event.reference.WeakReference;
17 import org.djutils.exceptions.Throw;
18
19
20
21
22
23
24
25
26
27
28
29
30 public interface EventProducer extends Serializable, Remote
31 {
32
33 int FIRST_POSITION = 0;
34
35
36 int LAST_POSITION = -1;
37
38
39
40
41
42
43
44
45
46
47
48
49 default boolean addListener(final EventListener listener, final EventType eventType, final int position,
50 final ReferenceType referenceType) throws RemoteException
51 {
52 Throw.whenNull(listener, "listener cannot be null");
53 Throw.whenNull(eventType, "eventType cannot be null");
54 Throw.whenNull(referenceType, "referenceType cannot be null");
55 if (position < LAST_POSITION)
56 {
57 return false;
58 }
59 Reference<EventListener> reference = null;
60 if (referenceType.isStrong())
61 {
62 reference = new StrongReference<EventListener>(listener);
63 }
64 else
65 {
66 reference = new WeakReference<EventListener>(listener);
67 }
68 EventListenerMap eventListenerMap = getEventListenerMap();
69 if (eventListenerMap.containsKey(eventType))
70 {
71 for (Reference<EventListener> entry : eventListenerMap.get(eventType))
72 {
73 if (listener.equals(entry.get()))
74 {
75 return false;
76 }
77 }
78 List<Reference<EventListener>> entries = eventListenerMap.get(eventType);
79 if (position == LAST_POSITION)
80 {
81 entries.add(reference);
82 }
83 else
84 {
85 entries.add(position, reference);
86 }
87 }
88 else
89 {
90 List<Reference<EventListener>> entries = new ArrayList<>();
91 entries.add(reference);
92 eventListenerMap.put(eventType, entries);
93 }
94 return true;
95 }
96
97
98
99
100
101
102
103
104 default boolean addListener(final EventListener listener, final EventType eventType) throws RemoteException
105 {
106 return addListener(listener, eventType, FIRST_POSITION);
107 }
108
109
110
111
112
113
114
115
116
117
118 default boolean addListener(final EventListener listener, final EventType eventType, final ReferenceType referenceType)
119 throws RemoteException
120 {
121 return addListener(listener, eventType, FIRST_POSITION, referenceType);
122 }
123
124
125
126
127
128
129
130
131
132
133 default boolean addListener(final EventListener listener, final EventType eventType, final int position)
134 throws RemoteException
135 {
136 return addListener(listener, eventType, position, ReferenceType.STRONG);
137 }
138
139
140
141
142
143
144 EventListenerMap getEventListenerMap() throws RemoteException;
145
146
147
148
149
150
151 default int removeAllListeners() throws RemoteException
152 {
153 int result = getEventListenerMap().size();
154 getEventListenerMap().clear();
155 return result;
156 }
157
158
159
160
161
162
163
164 default int removeAllListeners(final Class<?> ofClass) throws RemoteException
165 {
166 Throw.whenNull(ofClass, "ofClass may not be null");
167 int result = 0;
168 Map<EventType, Reference<EventListener>> removeMap = new LinkedHashMap<>();
169 for (EventType type : getEventListenerMap().keySet())
170 {
171 for (Iterator<Reference<EventListener>> ii = getEventListenerMap().get(type).iterator(); ii.hasNext();)
172 {
173 Reference<EventListener> listener = ii.next();
174 if (listener.get().getClass().isAssignableFrom(ofClass))
175 {
176 removeMap.put(type, listener);
177 result++;
178 }
179 }
180 }
181 for (EventType type : removeMap.keySet())
182 {
183 removeListener(removeMap.get(type).get(), type);
184 }
185 return result;
186 }
187
188
189
190
191
192
193
194
195 default boolean removeListener(final EventListener listener, final EventType eventType) throws RemoteException
196 {
197 Throw.whenNull(listener, "listener may not be null");
198 Throw.whenNull(eventType, "eventType may not be null");
199 EventListenerMap eventListenerMap = getEventListenerMap();
200 if (!eventListenerMap.containsKey(eventType))
201 {
202 return false;
203 }
204 boolean result = false;
205 for (Iterator<Reference<EventListener>> i = eventListenerMap.get(eventType).iterator(); i.hasNext();)
206 {
207 Reference<EventListener> reference = i.next();
208 EventListener entry = reference.get();
209 if (entry == null)
210 {
211 i.remove();
212 }
213 else
214 {
215 if (listener.equals(entry))
216 {
217 i.remove();
218 result = true;
219 }
220 }
221 if (eventListenerMap.get(eventType).size() == 0)
222 {
223 eventListenerMap.remove(eventType);
224 }
225 }
226 return result;
227 }
228
229
230
231
232
233
234 default boolean hasListeners() throws RemoteException
235 {
236 return !getEventListenerMap().isEmpty();
237 }
238
239
240
241
242
243
244
245 default int numberOfListeners(final EventType eventType) throws RemoteException
246 {
247 if (getEventListenerMap().containsKey(eventType))
248 {
249 return getEventListenerMap().get(eventType).size();
250 }
251 return 0;
252 }
253
254
255
256
257
258
259
260
261
262
263 default List<Reference<EventListener>> getListenerReferences(final EventType eventType) throws RemoteException
264 {
265 List<Reference<EventListener>> result = new ArrayList<>();
266 if (getEventListenerMap().get(eventType) != null)
267 {
268 result.addAll(getEventListenerMap().get(eventType));
269 }
270 return result;
271 }
272
273
274
275
276
277
278 default Set<EventType> getEventTypesWithListeners() throws RemoteException
279 {
280 return getEventListenerMap().keySet();
281 }
282
283
284
285
286
287
288
289
290 private boolean removeListener(final Reference<EventListener> reference, final EventType eventType) throws RemoteException
291 {
292 Throw.whenNull(reference, "reference may not be null");
293 Throw.whenNull(eventType, "eventType may not be null");
294 EventListenerMap eventListenerMap = getEventListenerMap();
295 boolean success = false;
296 for (Iterator<Reference<EventListener>> i = eventListenerMap.get(eventType).iterator(); i.hasNext();)
297 {
298 if (i.next().equals(reference))
299 {
300 i.remove();
301 success = true;
302 }
303 }
304 if (eventListenerMap.get(eventType).size() == 0)
305 {
306 eventListenerMap.remove(eventType);
307 }
308 return success;
309 }
310
311
312
313
314
315
316 default void fireEvent(final Event event) throws RemoteException
317 {
318 Throw.whenNull(event, "event may not be null");
319 EventListenerMap eventListenerMap = getEventListenerMap();
320 if (eventListenerMap.containsKey(event.getType()))
321 {
322
323 List<Reference<EventListener>> listenerList = new ArrayList<>(eventListenerMap.get(event.getType()));
324 for (Reference<EventListener> reference : listenerList)
325 {
326 EventListener listener = reference.get();
327 try
328 {
329 if (listener != null)
330 {
331
332 fireEvent(listener, event);
333 }
334 else
335 {
336
337
338 removeListener(reference, event.getType());
339 }
340 }
341 catch (RemoteException remoteException)
342 {
343
344
345 removeListener(reference, event.getType());
346 }
347 }
348 }
349 }
350
351
352
353
354
355
356
357
358 private void fireEvent(final EventListener listener, final Event event) throws RemoteException
359 {
360 listener.notify(event);
361 }
362
363
364
365
366
367
368
369 default <C extends Comparable<C> & Serializable> void fireTimedEvent(final TimedEvent<C> event) throws RemoteException
370 {
371 fireEvent(event);
372 }
373
374
375
376
377
378
379 default void fireEvent(final EventType eventType) throws RemoteException
380 {
381 fireEvent(new Event(eventType, null, true));
382 }
383
384
385
386
387
388
389
390
391 default <C extends Comparable<C> & Serializable> void fireTimedEvent(final EventType eventType, final C time)
392 throws RemoteException
393
394 {
395 fireEvent(new TimedEvent<C>(eventType, null, time, true));
396 }
397
398
399
400
401
402
403
404 default void fireEvent(final EventType eventType, final Serializable value) throws RemoteException
405 {
406 fireEvent(new Event(eventType, value, true));
407 }
408
409
410
411
412
413
414
415
416
417 default <C extends Comparable<C> & Serializable> void fireTimedEvent(final EventType eventType, final Serializable value,
418 final C time) throws RemoteException
419 {
420 fireEvent(new TimedEvent<C>(eventType, value, time, true));
421 }
422
423
424
425
426
427
428 default void fireUnverifiedEvent(final EventType eventType) throws RemoteException
429 {
430 fireEvent(new Event(eventType, null, false));
431 }
432
433
434
435
436
437
438
439
440 default <C extends Comparable<C> & Serializable> void fireUnverifiedTimedEvent(final EventType eventType, final C time)
441 throws RemoteException
442 {
443 fireEvent(new TimedEvent<C>(eventType, null, time, false));
444 }
445
446
447
448
449
450
451
452 default void fireUnverifiedEvent(final EventType eventType, final Serializable value) throws RemoteException
453 {
454 fireEvent(new Event(eventType, value, false));
455 }
456
457
458
459
460
461
462
463
464
465 default <C extends Comparable<C> & Serializable> void fireUnverifiedTimedEvent(final EventType eventType,
466 final Serializable value, final C time) throws RemoteException
467 {
468 fireEvent(new TimedEvent<C>(eventType, value, time, false));
469 }
470
471 }