1 package org.djutils.event;
2
3 import java.io.Serializable;
4 import java.rmi.RemoteException;
5 import java.util.ArrayList;
6 import java.util.Iterator;
7 import java.util.LinkedHashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
12 import org.djutils.event.ref.Reference;
13 import org.djutils.event.ref.ReferenceType;
14 import org.djutils.event.ref.StrongReference;
15 import org.djutils.event.ref.WeakReference;
16 import org.djutils.exceptions.Throw;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class EventProducerImpl implements EventProducerInterface, Serializable
33 {
34
35 private static final long serialVersionUID = 20200207;
36
37
38 private EventListenerMap listeners = new EventListenerMap();
39
40
41 private final EventProducerInterface embeddingEventProducer;
42
43
44
45
46
47 public EventProducerImpl(final EventProducerInterface embeddingEventProducer)
48 {
49 this.embeddingEventProducer = embeddingEventProducer;
50 }
51
52
53 @Override
54 public Serializable getSourceId()
55 {
56 try
57 {
58 return this.embeddingEventProducer.getSourceId();
59 }
60 catch (RemoteException rme)
61 {
62 throw new RuntimeException(rme);
63 }
64 }
65
66
67 @Override
68 public final synchronized boolean addListener(final EventListenerInterface listener, final EventTypeInterface eventType)
69 {
70 return this.addListener(listener, eventType, EventProducerInterface.FIRST_POSITION);
71 }
72
73
74 @Override
75 public final synchronized boolean addListener(final EventListenerInterface listener, final EventTypeInterface eventType,
76 final ReferenceType referenceType)
77 {
78 return this.addListener(listener, eventType, EventProducerInterface.FIRST_POSITION, referenceType);
79 }
80
81
82 @Override
83 public final synchronized boolean addListener(final EventListenerInterface listener, final EventTypeInterface eventType,
84 final int position)
85 {
86 return this.addListener(listener, eventType, position, ReferenceType.STRONG);
87 }
88
89
90 @Override
91 public final synchronized boolean addListener(final EventListenerInterface listener, final EventTypeInterface eventType,
92 final int position, final ReferenceType referenceType)
93 {
94 Throw.whenNull(listener, "listener cannot be null");
95 Throw.whenNull(eventType, "eventType cannot be null");
96 Throw.whenNull(referenceType, "referenceType cannot be null");
97 if (position < EventProducerInterface.LAST_POSITION)
98 {
99 return false;
100 }
101 Reference<EventListenerInterface> reference = null;
102 if (referenceType.isStrong())
103 {
104 reference = new StrongReference<EventListenerInterface>(listener);
105 }
106 else
107 {
108 reference = new WeakReference<EventListenerInterface>(listener);
109 }
110 if (this.listeners.containsKey(eventType))
111 {
112 for (Reference<EventListenerInterface> entry : this.listeners.get(eventType))
113 {
114 if (listener.equals(entry.get()))
115 {
116 return false;
117 }
118 }
119 List<Reference<EventListenerInterface>> entries = this.listeners.get(eventType);
120 if (position == EventProducerInterface.LAST_POSITION)
121 {
122 entries.add(reference);
123 }
124 else
125 {
126 entries.add(position, reference);
127 }
128 }
129 else
130 {
131 List<Reference<EventListenerInterface>> entries = new ArrayList<>();
132 entries.add(reference);
133 this.listeners.put(eventType, entries);
134 }
135 return true;
136 }
137
138
139
140
141
142
143
144
145 public void fireEvent(final EventListenerInterface listener, final EventInterface event) throws RemoteException
146 {
147 listener.notify(event);
148 }
149
150
151
152
153
154 public synchronized void fireEvent(final EventInterface event)
155 {
156 Throw.whenNull(event, "event may not be null");
157 Throw.whenNull(event.getType(), "event type may not be null");
158 if (this.listeners.containsKey(event.getType()))
159 {
160
161 List<Reference<EventListenerInterface>> listenerList = new ArrayList<>(this.listeners.get(event.getType()));
162 for (Reference<EventListenerInterface> reference : listenerList)
163 {
164 EventListenerInterface listener = reference.get();
165 try
166 {
167 if (listener != null)
168 {
169
170 this.fireEvent(listener, event);
171 }
172 else
173 {
174
175
176 this.removeListener(reference, event.getType());
177 }
178 }
179 catch (RemoteException remoteException)
180 {
181
182
183 this.removeListener(reference, event.getType());
184 }
185 }
186 }
187 }
188
189
190
191
192
193
194 public void fireEvent(final EventInterface event, final boolean verifyMetaData)
195 {
196 fireEvent(event);
197 }
198
199
200
201
202
203
204
205 public <C extends Comparable<C> & Serializable> void fireTimedEvent(final TimedEventInterface<C> event,
206 final boolean verifyMetaData)
207 {
208 fireEvent(event);
209 }
210
211
212
213
214
215
216 public void fireEvent(final EventTypeInterface eventType, final boolean verifyMetaData)
217 {
218 this.fireEvent(new Event(eventType, getSourceId(), null, verifyMetaData));
219 }
220
221
222
223
224
225
226
227
228 public <C extends Comparable<C> & Serializable> void fireTimedEvent(final TimedEventTypeInterface eventType, final C time,
229 final boolean verifyMetaData)
230 {
231 Throw.whenNull(time, "time may not be null");
232 this.fireEvent(new TimedEvent<C>(eventType, getSourceId(), null, time, verifyMetaData));
233 }
234
235
236
237
238
239
240
241
242 public Serializable fireEvent(final EventTypeInterface eventType, final Serializable value, final boolean verifyMetaData)
243 {
244 this.fireEvent(new Event(eventType, getSourceId(), value, verifyMetaData));
245 return value;
246 }
247
248
249
250
251
252
253
254
255
256
257 public <C extends Comparable<C> & Serializable> Serializable fireTimedEvent(final TimedEventTypeInterface eventType,
258 final Serializable value, final C time, final boolean verifyMetaData)
259 {
260 Throw.whenNull(time, "time may not be null");
261 this.fireEvent(new TimedEvent<C>(eventType, getSourceId(), value, time, verifyMetaData));
262 return value;
263 }
264
265
266
267
268
269
270
271
272 public byte fireEvent(final EventTypeInterface eventType, final byte value, final boolean verifyMetaData)
273 {
274 this.fireEvent(eventType, Byte.valueOf(value), verifyMetaData);
275 return value;
276 }
277
278
279
280
281
282
283
284
285
286
287 public <C extends Comparable<C> & Serializable> byte fireTimedEvent(final TimedEventTypeInterface eventType,
288 final byte value, final C time, final boolean verifyMetaData)
289 {
290 this.fireTimedEvent(eventType, Byte.valueOf(value), time, verifyMetaData);
291 return value;
292 }
293
294
295
296
297
298
299
300
301 public char fireEvent(final EventTypeInterface eventType, final char value, final boolean verifyMetaData)
302 {
303 this.fireEvent(eventType, Character.valueOf(value), verifyMetaData);
304 return value;
305 }
306
307
308
309
310
311
312
313
314
315
316 public <C extends Comparable<C> & Serializable> char fireTimedEvent(final TimedEventTypeInterface eventType,
317 final char value, final C time, final boolean verifyMetaData)
318 {
319 this.fireTimedEvent(eventType, Character.valueOf(value), time, verifyMetaData);
320 return value;
321 }
322
323
324
325
326
327
328
329
330 public boolean fireEvent(final EventTypeInterface eventType, final boolean value, final boolean verifyMetaData)
331 {
332 this.fireEvent(eventType, Boolean.valueOf(value), verifyMetaData);
333 return value;
334 }
335
336
337
338
339
340
341
342
343
344
345 public <C extends Comparable<C> & Serializable> boolean fireTimedEvent(final TimedEventTypeInterface eventType,
346 final boolean value, final C time, final boolean verifyMetaData)
347 {
348 fireTimedEvent(eventType, Boolean.valueOf(value), time, verifyMetaData);
349 return value;
350 }
351
352
353
354
355
356
357
358
359 public double fireEvent(final EventTypeInterface eventType, final double value, final boolean verifyMetaData)
360 {
361 this.fireEvent(eventType, Double.valueOf(value), verifyMetaData);
362 return value;
363 }
364
365
366
367
368
369
370
371
372
373
374 public <C extends Comparable<C> & Serializable> double fireTimedEvent(final TimedEventTypeInterface eventType,
375 final double value, final C time, final boolean verifyMetaData)
376 {
377 this.fireTimedEvent(eventType, Double.valueOf(value), time, verifyMetaData);
378 return value;
379 }
380
381
382
383
384
385
386
387
388 public int fireEvent(final EventTypeInterface eventType, final int value, final boolean verifyMetaData)
389 {
390 this.fireEvent(eventType, Integer.valueOf(value), verifyMetaData);
391 return value;
392 }
393
394
395
396
397
398
399
400
401
402
403 public <C extends Comparable<C> & Serializable> int fireTimedEvent(final TimedEventTypeInterface eventType, final int value,
404 final C time, final boolean verifyMetaData)
405 {
406 this.fireTimedEvent(eventType, Integer.valueOf(value), time, verifyMetaData);
407 return value;
408 }
409
410
411
412
413
414
415
416
417 public long fireEvent(final EventTypeInterface eventType, final long value, final boolean verifyMetaData)
418 {
419 this.fireEvent(eventType, Long.valueOf(value), verifyMetaData);
420 return value;
421 }
422
423
424
425
426
427
428
429
430
431
432 public <C extends Comparable<C> & Serializable> long fireTimedEvent(final TimedEventTypeInterface eventType,
433 final long value, final C time, final boolean verifyMetaData)
434 {
435 this.fireTimedEvent(eventType, Long.valueOf(value), time, verifyMetaData);
436 return value;
437 }
438
439
440
441
442
443
444
445
446 public short fireEvent(final EventTypeInterface eventType, final short value, final boolean verifyMetaData)
447 {
448 this.fireEvent(eventType, Short.valueOf(value), verifyMetaData);
449 return value;
450 }
451
452
453
454
455
456
457
458
459
460
461 public <C extends Comparable<C> & Serializable> short fireTimedEvent(final TimedEventTypeInterface eventType,
462 final short value, final C time, final boolean verifyMetaData)
463 {
464 this.fireTimedEvent(eventType, Short.valueOf(value), time, verifyMetaData);
465 return value;
466 }
467
468
469
470
471
472
473
474
475 public float fireEvent(final EventTypeInterface eventType, final float value, final boolean verifyMetaData)
476 {
477 this.fireEvent(eventType, Float.valueOf(value), verifyMetaData);
478 return value;
479 }
480
481
482
483
484
485
486
487
488
489
490 public <C extends Comparable<C> & Serializable> float fireTimedEvent(final TimedEventTypeInterface eventType,
491 final float value, final C time, final boolean verifyMetaData)
492 {
493 this.fireTimedEvent(eventType, Float.valueOf(value), time, verifyMetaData);
494 return value;
495 }
496
497
498
499
500
501 public synchronized int removeAllListeners()
502 {
503 int result = this.listeners.size();
504 this.listeners = null;
505 this.listeners = new EventListenerMap();
506 return result;
507 }
508
509
510
511
512
513
514 public synchronized int removeAllListeners(final Class<?> ofClass)
515 {
516 Throw.whenNull(ofClass, "ofClass may not be null");
517 int result = 0;
518 Map<EventTypeInterface, Reference<EventListenerInterface>> removeMap = new LinkedHashMap<>();
519 for (EventTypeInterface type : this.listeners.keySet())
520 {
521 for (Iterator<Reference<EventListenerInterface>> ii = this.listeners.get(type).iterator(); ii.hasNext();)
522 {
523 Reference<EventListenerInterface> listener = ii.next();
524 if (listener.get().getClass().isAssignableFrom(ofClass))
525 {
526 removeMap.put(type, listener);
527 result++;
528 }
529 }
530 }
531 for (EventTypeInterface type : removeMap.keySet())
532 {
533 removeListener(removeMap.get(type).get(), type);
534 }
535 return result;
536 }
537
538
539 @Override
540 public final synchronized boolean removeListener(final EventListenerInterface listener, final EventTypeInterface eventType)
541 {
542 Throw.whenNull(listener, "listener may not be null");
543 Throw.whenNull(eventType, "eventType may not be null");
544 if (!this.listeners.containsKey(eventType))
545 {
546 return false;
547 }
548 boolean result = false;
549 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
550 {
551 Reference<EventListenerInterface> reference = i.next();
552 EventListenerInterface entry = reference.get();
553 if (entry == null)
554 {
555 i.remove();
556 }
557 else
558 {
559 if (listener.equals(entry))
560 {
561 i.remove();
562 result = true;
563 }
564 }
565 if (this.listeners.get(eventType).size() == 0)
566 {
567 this.listeners.remove(eventType);
568 }
569 }
570 return result;
571 }
572
573
574
575
576
577
578
579 private synchronized boolean removeListener(final Reference<EventListenerInterface> reference,
580 final EventTypeInterface eventType)
581 {
582 Throw.whenNull(reference, "reference may not be null");
583 Throw.whenNull(eventType, "eventType may not be null");
584 boolean success = false;
585 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
586 {
587 if (i.next().equals(reference))
588 {
589 i.remove();
590 success = true;
591 }
592 }
593 if (this.listeners.get(eventType).size() == 0)
594 {
595 this.listeners.remove(eventType);
596 }
597 return success;
598 }
599
600
601 @Override
602 public boolean hasListeners()
603 {
604 return !this.listeners.isEmpty();
605 }
606
607
608 @Override
609 public synchronized int numberOfListeners(final EventTypeInterface eventType)
610 {
611 if (this.listeners.containsKey(eventType))
612 {
613 return this.listeners.get(eventType).size();
614 }
615 return 0;
616 }
617
618
619
620
621
622
623
624
625
626 public List<Reference<EventListenerInterface>> getListenerReferences(final EventTypeInterface eventType)
627 {
628 List<Reference<EventListenerInterface>> result = new ArrayList<>();
629 if (this.listeners.get(eventType) != null)
630 {
631 result.addAll(this.listeners.get(eventType));
632 }
633 return result;
634 }
635
636
637 @Override
638 public synchronized Set<EventTypeInterface> getEventTypesWithListeners()
639 {
640 return this.listeners.keySet();
641 }
642
643 }