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
33 public class EventProducerImpl implements EventProducerInterface, Serializable
34 {
35
36 private static final long serialVersionUID = 20200207;
37
38
39 private EventListenerMaptListenerMap">EventListenerMap listeners = new EventListenerMap();
40
41
42 private final EventProducerInterface embeddingEventProducer;
43
44
45
46
47
48 public EventProducerImpl(final EventProducerInterface embeddingEventProducer)
49 {
50 super();
51 this.embeddingEventProducer = embeddingEventProducer;
52 }
53
54
55 @Override
56 public Serializable getSourceId()
57 {
58 try
59 {
60 return this.embeddingEventProducer.getSourceId();
61 }
62 catch (RemoteException rme)
63 {
64 throw new RuntimeException(rme);
65 }
66 }
67
68
69 @Override
70 public final synchronized boolean addListener(final EventListenerInterface listener, final EventType eventType)
71 {
72 return this.addListener(listener, eventType, EventProducerInterface.FIRST_POSITION);
73 }
74
75
76 @Override
77 public final synchronized boolean addListener(final EventListenerInterface listener, final EventType eventType,
78 final ReferenceType referenceType)
79 {
80 return this.addListener(listener, eventType, EventProducerInterface.FIRST_POSITION, referenceType);
81 }
82
83
84 @Override
85 public final synchronized boolean addListener(final EventListenerInterface listener, final EventType eventType,
86 final int position)
87 {
88 return this.addListener(listener, eventType, position, ReferenceType.STRONG);
89 }
90
91
92 @Override
93 public final synchronized boolean addListener(final EventListenerInterface listener, final EventType eventType,
94 final int position, final ReferenceType referenceType)
95 {
96 Throw.whenNull(listener, "listener cannot be null");
97 Throw.whenNull(eventType, "eventType cannot be null");
98 Throw.whenNull(referenceType, "referenceType cannot be null");
99 if (position < EventProducerInterface.LAST_POSITION)
100 {
101 return false;
102 }
103 Reference<EventListenerInterface> reference = null;
104 if (referenceType.isStrong())
105 {
106 reference = new StrongReference<EventListenerInterface>(listener);
107 }
108 else
109 {
110 reference = new WeakReference<EventListenerInterface>(listener);
111 }
112 if (this.listeners.containsKey(eventType))
113 {
114 for (Reference<EventListenerInterface> entry : this.listeners.get(eventType))
115 {
116 if (listener.equals(entry.get()))
117 {
118 return false;
119 }
120 }
121 List<Reference<EventListenerInterface>> entries = this.listeners.get(eventType);
122 if (position == EventProducerInterface.LAST_POSITION)
123 {
124 entries.add(reference);
125 }
126 else
127 {
128 entries.add(position, reference);
129 }
130 }
131 else
132 {
133 List<Reference<EventListenerInterface>> entries = new ArrayList<>();
134 entries.add(reference);
135 this.listeners.put(eventType, entries);
136 }
137 return true;
138 }
139
140
141
142
143
144
145
146
147
148 public EventInterface fireEvent(EventInterfacestrong> EventListenerInterface listener, final EventInterface event) throws RemoteException
149 {
150 listener.notify(event);
151 return event;
152 }
153
154
155
156
157
158
159 public synchronized EventInterfacetInterface">EventInterface fireEvent(final EventInterface event)
160 {
161 Throw.whenNull(event, "event may not be null");
162 Throw.whenNull(event.getType(), "event type may not be null");
163 if (this.listeners.containsKey(event.getType()))
164 {
165
166 List<Reference<EventListenerInterface>> listenerList = new ArrayList<>(this.listeners.get(event.getType()));
167 for (Reference<EventListenerInterface> reference : listenerList)
168 {
169 EventListenerInterface listener = reference.get();
170 try
171 {
172 if (listener != null)
173 {
174
175 this.fireEvent(listener, event);
176 }
177 else
178 {
179
180
181 this.removeListener(reference, event.getType());
182 }
183 }
184 catch (RemoteException remoteException)
185 {
186
187
188 this.removeListener(reference, event.getType());
189 }
190 }
191 }
192 return event;
193 }
194
195
196
197
198
199
200
201 public Serializable fireEvent(final EventType eventType, final Serializable value)
202 {
203 this.fireEvent(new Event(eventType, getSourceId(), value));
204 return value;
205 }
206
207
208
209
210
211 public void fireEvent(final EventType eventType)
212 {
213 this.fireEvent(new Event(eventType, getSourceId(), null));
214 }
215
216
217
218
219
220
221
222
223
224 public <C extends Comparable<C> & Serializable> Serializable fireTimedEvent(final EventType eventType,
225 final Serializable value, final C time)
226 {
227 Throw.whenNull(time, "time may not be null");
228 this.fireEvent(new TimedEvent<C>(eventType, getSourceId(), value, time));
229 return value;
230 }
231
232
233
234
235
236
237
238 public byte fireEvent(final EventType eventType, final byte value)
239 {
240 this.fireEvent(eventType, Byte.valueOf(value));
241 return value;
242 }
243
244
245
246
247
248
249
250
251
252 public <C extends Comparable<C> & Serializable> byte fireTimedEvent(final EventType eventType, final byte value,
253 final C time)
254 {
255 this.fireTimedEvent(eventType, Byte.valueOf(value), time);
256 return value;
257 }
258
259
260
261
262
263
264
265 public boolean fireEvent(final EventType eventType, final boolean value)
266 {
267 this.fireEvent(eventType, Boolean.valueOf(value));
268 return value;
269 }
270
271
272
273
274
275
276
277
278
279 public <C extends Comparable<C> & Serializable> boolean fireTimedEvent(final EventType eventType, final boolean value,
280 final C time)
281 {
282 fireTimedEvent(eventType, Boolean.valueOf(value), time);
283 return value;
284 }
285
286
287
288
289
290
291
292 public double fireEvent(final EventType eventType, final double value)
293 {
294 this.fireEvent(eventType, Double.valueOf(value));
295 return value;
296 }
297
298
299
300
301
302
303
304
305
306 public <C extends Comparable<C> & Serializable> double fireTimedEvent(final EventType eventType, final double value,
307 final C time)
308 {
309 this.fireTimedEvent(eventType, Double.valueOf(value), time);
310 return value;
311 }
312
313
314
315
316
317
318
319 public int fireEvent(final EventType eventType, final int value)
320 {
321 this.fireEvent(eventType, Integer.valueOf(value));
322 return value;
323 }
324
325
326
327
328
329
330
331
332
333 public <C extends Comparable<C> & Serializable> int fireTimedEvent(final EventType eventType, final int value, final C time)
334 {
335 this.fireTimedEvent(eventType, Integer.valueOf(value), time);
336 return value;
337 }
338
339
340
341
342
343
344
345 public long fireEvent(final EventType eventType, final long value)
346 {
347 this.fireEvent(eventType, Long.valueOf(value));
348 return value;
349 }
350
351
352
353
354
355
356
357
358
359 public <C extends Comparable<C> & Serializable> long fireTimedEvent(final EventType eventType, final long value,
360 final C time)
361 {
362 this.fireTimedEvent(eventType, Long.valueOf(value), time);
363 return value;
364 }
365
366
367
368
369
370
371
372 public short fireEvent(final EventType eventType, final short value)
373 {
374 this.fireEvent(eventType, Short.valueOf(value));
375 return value;
376 }
377
378
379
380
381
382
383
384
385
386 public <C extends Comparable<C> & Serializable> short fireTimedEvent(final EventType eventType, final short value,
387 final C time)
388 {
389 this.fireTimedEvent(eventType, Short.valueOf(value), time);
390 return value;
391 }
392
393
394
395
396
397 public synchronized int removeAllListeners()
398 {
399 int result = this.listeners.size();
400 this.listeners = null;
401 this.listeners = new EventListenerMap();
402 return result;
403 }
404
405
406
407
408
409
410 public synchronized int removeAllListeners(final Class<?> ofClass)
411 {
412 Throw.whenNull(ofClass, "ofClass may not be null");
413 int result = 0;
414 Map<EventType, Reference<EventListenerInterface>> removeMap = new LinkedHashMap<>();
415 for (EventType type : this.listeners.keySet())
416 {
417 for (Iterator<Reference<EventListenerInterface>> ii = this.listeners.get(type).iterator(); ii.hasNext();)
418 {
419 Reference<EventListenerInterface> listener = ii.next();
420 if (listener.get().getClass().isAssignableFrom(ofClass))
421 {
422 removeMap.put(type, listener);
423 result++;
424 }
425 }
426 }
427 for (EventType type : removeMap.keySet())
428 {
429 removeListener(removeMap.get(type).get(), type);
430 }
431 return result;
432 }
433
434
435 @Override
436 public final synchronized boolean removeListener(final EventListenerInterface listener, final EventType eventType)
437 {
438 Throw.whenNull(listener, "listener may not be null");
439 Throw.whenNull(eventType, "eventType may not be null");
440 if (!this.listeners.containsKey(eventType))
441 {
442 return false;
443 }
444 boolean result = false;
445 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
446 {
447 Reference<EventListenerInterface> reference = i.next();
448 EventListenerInterface entry = reference.get();
449 if (entry == null)
450 {
451 i.remove();
452 }
453 else
454 {
455 if (listener.equals(entry))
456 {
457 i.remove();
458 result = true;
459 }
460 }
461 if (this.listeners.get(eventType).size() == 0)
462 {
463 this.listeners.remove(eventType);
464 }
465 }
466 return result;
467 }
468
469
470
471
472
473
474
475 private synchronized boolean removeListener(final Reference<EventListenerInterface> reference, final EventType eventType)
476 {
477 Throw.whenNull(reference, "reference may not be null");
478 Throw.whenNull(eventType, "eventType may not be null");
479 boolean success = false;
480 for (Iterator<Reference<EventListenerInterface>> i = this.listeners.get(eventType).iterator(); i.hasNext();)
481 {
482 if (i.next().equals(reference))
483 {
484 i.remove();
485 success = true;
486 }
487 }
488 if (this.listeners.get(eventType).size() == 0)
489 {
490 this.listeners.remove(eventType);
491 }
492 return success;
493 }
494
495
496 @Override
497 public boolean hasListeners()
498 {
499 return !this.listeners.isEmpty();
500 }
501
502
503 @Override
504 public synchronized int numberOfListeners(final EventType eventType)
505 {
506 if (this.listeners.containsKey(eventType))
507 {
508 return this.listeners.get(eventType).size();
509 }
510 return 0;
511 }
512
513
514
515
516
517
518
519
520
521 public List<Reference<EventListenerInterface>> getListenerReferences(final EventType eventType)
522 {
523 List<Reference<EventListenerInterface>> result = new ArrayList<>();
524 if (this.listeners.get(eventType) != null)
525 {
526 result.addAll(this.listeners.get(eventType));
527 }
528 return result;
529 }
530
531
532 @Override
533 public synchronized Set<EventType> getEventTypesWithListeners()
534 {
535 return this.listeners.keySet();
536 }
537
538 }