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 EventListenerMaptListenerMap">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 Event 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 TimedEvent<C> event, final boolean verifyMetaData)
206 {
207 fireEvent(event);
208 }
209
210
211
212
213
214
215 public void fireEvent(final EventType eventType, final boolean verifyMetaData)
216 {
217 this.fireEvent(new Event(eventType, getSourceId(), null, verifyMetaData));
218 }
219
220
221
222
223
224
225
226
227 public <C extends Comparable<C> & Serializable> void fireTimedEvent(final TimedEventType eventType, final C time,
228 final boolean verifyMetaData)
229 {
230 Throw.whenNull(time, "time may not be null");
231 this.fireEvent(new TimedEvent<C>(eventType, getSourceId(), null, time, verifyMetaData));
232 }
233
234
235
236
237
238
239
240
241 public Serializable fireEvent(final EventType eventType, final Serializable value, final boolean verifyMetaData)
242 {
243 this.fireEvent(new Event(eventType, getSourceId(), value, verifyMetaData));
244 return value;
245 }
246
247
248
249
250
251
252
253
254
255
256 public <C extends Comparable<C> & Serializable> Serializable fireTimedEvent(final TimedEventType eventType,
257 final Serializable value, final C time, final boolean verifyMetaData)
258 {
259 Throw.whenNull(time, "time may not be null");
260 this.fireEvent(new TimedEvent<C>(eventType, getSourceId(), value, time, verifyMetaData));
261 return value;
262 }
263
264
265
266
267
268
269
270
271 public byte fireEvent(final EventType eventType, final byte value, final boolean verifyMetaData)
272 {
273 this.fireEvent(eventType, Byte.valueOf(value), verifyMetaData);
274 return value;
275 }
276
277
278
279
280
281
282
283
284
285
286 public <C extends Comparable<C> & Serializable> byte fireTimedEvent(final TimedEventType eventType, final byte value,
287 final C time, final boolean verifyMetaData)
288 {
289 this.fireTimedEvent(eventType, Byte.valueOf(value), time, verifyMetaData);
290 return value;
291 }
292
293
294
295
296
297
298
299
300 public char fireEvent(final EventType eventType, final char value, final boolean verifyMetaData)
301 {
302 this.fireEvent(eventType, Character.valueOf(value), verifyMetaData);
303 return value;
304 }
305
306
307
308
309
310
311
312
313
314
315 public <C extends Comparable<C> & Serializable> char fireTimedEvent(final TimedEventType eventType, final char value,
316 final C time, final boolean verifyMetaData)
317 {
318 this.fireTimedEvent(eventType, Character.valueOf(value), time, verifyMetaData);
319 return value;
320 }
321
322
323
324
325
326
327
328
329 public boolean fireEvent(final EventType eventType, final boolean value, final boolean verifyMetaData)
330 {
331 this.fireEvent(eventType, Boolean.valueOf(value), verifyMetaData);
332 return value;
333 }
334
335
336
337
338
339
340
341
342
343
344 public <C extends Comparable<C> & Serializable> boolean fireTimedEvent(final TimedEventType eventType, final boolean value,
345 final C time, final boolean verifyMetaData)
346 {
347 fireTimedEvent(eventType, Boolean.valueOf(value), time, verifyMetaData);
348 return value;
349 }
350
351
352
353
354
355
356
357
358 public double fireEvent(final EventType eventType, final double value, final boolean verifyMetaData)
359 {
360 this.fireEvent(eventType, Double.valueOf(value), verifyMetaData);
361 return value;
362 }
363
364
365
366
367
368
369
370
371
372
373 public <C extends Comparable<C> & Serializable> double fireTimedEvent(final TimedEventType eventType, final double value,
374 final C time, final boolean verifyMetaData)
375 {
376 this.fireTimedEvent(eventType, Double.valueOf(value), time, verifyMetaData);
377 return value;
378 }
379
380
381
382
383
384
385
386
387 public int fireEvent(final EventType eventType, final int value, final boolean verifyMetaData)
388 {
389 this.fireEvent(eventType, Integer.valueOf(value), verifyMetaData);
390 return value;
391 }
392
393
394
395
396
397
398
399
400
401
402 public <C extends Comparable<C> & Serializable> int fireTimedEvent(final TimedEventType eventType, final int value,
403 final C time, final boolean verifyMetaData)
404 {
405 this.fireTimedEvent(eventType, Integer.valueOf(value), time, verifyMetaData);
406 return value;
407 }
408
409
410
411
412
413
414
415
416 public long fireEvent(final EventType eventType, final long value, final boolean verifyMetaData)
417 {
418 this.fireEvent(eventType, Long.valueOf(value), verifyMetaData);
419 return value;
420 }
421
422
423
424
425
426
427
428
429
430
431 public <C extends Comparable<C> & Serializable> long fireTimedEvent(final TimedEventType eventType, final long value,
432 final C time, final boolean verifyMetaData)
433 {
434 this.fireTimedEvent(eventType, Long.valueOf(value), time, verifyMetaData);
435 return value;
436 }
437
438
439
440
441
442
443
444
445 public short fireEvent(final EventType eventType, final short value, final boolean verifyMetaData)
446 {
447 this.fireEvent(eventType, Short.valueOf(value), verifyMetaData);
448 return value;
449 }
450
451
452
453
454
455
456
457
458
459
460 public <C extends Comparable<C> & Serializable> short fireTimedEvent(final TimedEventType eventType, final short value,
461 final C time, final boolean verifyMetaData)
462 {
463 this.fireTimedEvent(eventType, Short.valueOf(value), time, verifyMetaData);
464 return value;
465 }
466
467
468
469
470
471
472
473
474 public float fireEvent(final EventType eventType, final float value, final boolean verifyMetaData)
475 {
476 this.fireEvent(eventType, Float.valueOf(value), verifyMetaData);
477 return value;
478 }
479
480
481
482
483
484
485
486
487
488
489 public <C extends Comparable<C> & Serializable> float fireTimedEvent(final TimedEventType eventType, final float value,
490 final C time, final boolean verifyMetaData)
491 {
492 this.fireTimedEvent(eventType, Float.valueOf(value), time, verifyMetaData);
493 return value;
494 }
495
496
497
498
499
500 public synchronized int removeAllListeners()
501 {
502 int result = this.listeners.size();
503 this.listeners = null;
504 this.listeners = new EventListenerMap();
505 return result;
506 }
507
508
509
510
511
512
513 public synchronized int removeAllListeners(final Class<?> ofClass)
514 {
515 Throw.whenNull(ofClass, "ofClass may not be null");
516 int result = 0;
517 Map<EventTypeInterface, Reference<EventListenerInterface>> removeMap = new LinkedHashMap<>();
518 for (EventTypeInterface type : this.listeners.keySet())
519 {
520 for (Iterator<Reference<EventListenerInterface>> ii = this.listeners.get(type).iterator(); ii.hasNext();)
521 {
522 Reference<EventListenerInterface> listener = ii.next();
523 if (listener.get().getClass().isAssignableFrom(ofClass))
524 {
525 removeMap.put(type, listener);
526 result++;
527 }
528 }
529 }
530 for (EventTypeInterface type : removeMap.keySet())
531 {
532 removeListener(removeMap.get(type).get(), type);
533 }
534 return result;
535 }
536
537
538 @Override
539 public final synchronized boolean removeListener(final EventListenerInterface listener, final EventTypeInterface eventType)
540 {
541 Throw.whenNull(listener, "listener may not be null");
542 Throw.whenNull(eventType, "eventType may not be null");
543 if (!this.listeners.containsKey(eventType))
544 {
545 return false;
546 }
547 boolean result = false;
548 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
549 {
550 Reference<EventListenerInterface> reference = i.next();
551 EventListenerInterface entry = reference.get();
552 if (entry == null)
553 {
554 i.remove();
555 }
556 else
557 {
558 if (listener.equals(entry))
559 {
560 i.remove();
561 result = true;
562 }
563 }
564 if (this.listeners.get(eventType).size() == 0)
565 {
566 this.listeners.remove(eventType);
567 }
568 }
569 return result;
570 }
571
572
573
574
575
576
577
578 private synchronized boolean removeListener(final Reference<EventListenerInterface> reference,
579 final EventTypeInterface eventType)
580 {
581 Throw.whenNull(reference, "reference may not be null");
582 Throw.whenNull(eventType, "eventType may not be null");
583 boolean success = false;
584 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
585 {
586 if (i.next().equals(reference))
587 {
588 i.remove();
589 success = true;
590 }
591 }
592 if (this.listeners.get(eventType).size() == 0)
593 {
594 this.listeners.remove(eventType);
595 }
596 return success;
597 }
598
599
600 @Override
601 public boolean hasListeners()
602 {
603 return !this.listeners.isEmpty();
604 }
605
606
607 @Override
608 public synchronized int numberOfListeners(final EventTypeInterface eventType)
609 {
610 if (this.listeners.containsKey(eventType))
611 {
612 return this.listeners.get(eventType).size();
613 }
614 return 0;
615 }
616
617
618
619
620
621
622
623
624
625 public List<Reference<EventListenerInterface>> getListenerReferences(final EventTypeInterface eventType)
626 {
627 List<Reference<EventListenerInterface>> result = new ArrayList<>();
628 if (this.listeners.get(eventType) != null)
629 {
630 result.addAll(this.listeners.get(eventType));
631 }
632 return result;
633 }
634
635
636 @Override
637 public synchronized Set<EventTypeInterface> getEventTypesWithListeners()
638 {
639 return this.listeners.keySet();
640 }
641
642 }