View Javadoc
1   package org.djutils.event;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertFalse;
5   import static org.junit.Assert.assertNotEquals;
6   import static org.junit.Assert.assertTrue;
7   import static org.junit.Assert.fail;
8   
9   import java.io.Serializable;
10  import java.lang.reflect.Field;
11  import java.rmi.RemoteException;
12  import java.util.Arrays;
13  import java.util.LinkedHashSet;
14  import java.util.List;
15  
16  import org.djutils.event.ref.Reference;
17  import org.djutils.event.ref.ReferenceType;
18  import org.djutils.exceptions.Try;
19  import org.djutils.metadata.MetaData;
20  import org.djutils.metadata.ObjectDescriptor;
21  import org.junit.Test;
22  
23  /**
24   * Test the EventProducer and EventListener.
25   * <p>
26   * Copyright (c) 2002-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
27   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
28   * distributed under a three-clause BSD-style license, which can be found at
29   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>. This class was
30   * originally part of the DSOL project, see <a href="https://simulation.tudelft.nl/dsol/manual" target="_blank">
31   * https://simulation.tudelft.nl/dsol/manual</a>.
32   * </p>
33   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
34   */
35  public class EventPubSubTest
36  {
37      /**
38       * Test the EventProducer and EventListener.
39       */
40      @Test
41      public void testEventPubSub()
42      {
43          TestEventProducer producer = new TestEventProducer();
44          TestEventListener listener = new TestEventListener();
45          EventType eventType = new EventType("TEST_TYPE", MetaData.NO_META_DATA);
46          TimedEventType timedEventType = new TimedEventType("TIMED_TEST_TYPE", MetaData.NO_META_DATA);
47  
48          assertFalse(producer.hasListeners());
49          assertEquals(0, producer.numberOfListeners(eventType));
50          assertEquals(0, producer.getEventTypesWithListeners().size());
51          assertEquals(0, producer.getListenerReferences(eventType).size());
52          boolean addListenerOK = producer.addListener(listener, eventType);
53          assertTrue(addListenerOK);
54          assertTrue(producer.hasListeners());
55          assertEquals(1, producer.numberOfListeners(eventType));
56          assertEquals(1, producer.getEventTypesWithListeners().size());
57          assertEquals(1, producer.getListenerReferences(eventType).size());
58          assertEquals(listener, producer.getListenerReferences(eventType).get(0).get());
59  
60          String string = "abc123";
61          listener.setExpectedObject(string);
62          producer.fireEvent(new Event(eventType, producer, string));
63          assertEquals(string, listener.getReceivedEvent().getContent());
64          assertEquals(eventType, listener.getReceivedEvent().getType());
65          assertEquals(producer, listener.getReceivedEvent().getSourceId());
66  
67          listener.setExpectedObject(Boolean.valueOf(true));
68          producer.fireEvent(eventType, true);
69          listener.setExpectedObject(Boolean.valueOf(false));
70          producer.fireEvent(eventType, false);
71  
72          listener.setExpectedObject(Byte.valueOf((byte) 87));
73          producer.fireEvent(eventType, (byte) 87);
74  
75          listener.setExpectedObject(Character.valueOf('a'));
76          producer.fireEvent(eventType, 'a');
77  
78          listener.setExpectedObject(Short.valueOf((short) -234));
79          producer.fireEvent(eventType, (short) -234);
80  
81          listener.setExpectedObject(Float.valueOf(458.9f));
82          producer.fireEvent(eventType, 458.9f);
83  
84          listener.setExpectedObject(Double.valueOf(123.456d));
85          producer.fireEvent(eventType, 123.456d);
86  
87          listener.setExpectedObject(Integer.valueOf(12345));
88          producer.fireEvent(eventType, 12345);
89  
90          listener.setExpectedObject(Long.valueOf(123456L));
91          producer.fireEvent(eventType, 123456L);
92  
93          listener.setExpectedObject("abcde");
94          producer.fireEvent(eventType, "abcde");
95  
96          listener.setExpectedObject(null);
97          producer.fireEvent(eventType);
98  
99          // remove listener tests
100         producer.removeListener(listener, TestEventProducer.PRODUCER_EVENT_1);
101         listener.setExpectedObject(Byte.valueOf((byte) 87));
102         producer.fireEvent(eventType, (byte) 87);
103 
104         producer.removeListener(listener, eventType);
105         listener.setExpectingNotification(false);
106         producer.fireEvent(eventType, 12345);
107 
108         addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1);
109         assertTrue(addListenerOK);
110         addListenerOK = producer.addListener(listener, eventType);
111         assertTrue(addListenerOK);
112         listener.setExpectingNotification(true);
113         listener.setExpectedObject(Double.valueOf(123.456d));
114         producer.fireEvent(eventType, 123.456d);
115         assertEquals(eventType, listener.getReceivedEvent().getType());
116         listener.setExpectedObject(Double.valueOf(234.567d));
117         producer.fireEvent(TestEventProducer.PRODUCER_EVENT_1, 234.567d);
118         assertEquals(TestEventProducer.PRODUCER_EVENT_1, listener.getReceivedEvent().getType());
119 
120         int nrRemovedListeners = producer.removeAllListeners();
121         assertEquals(2, nrRemovedListeners);
122         listener.setExpectingNotification(false);
123         listener.setExpectedObject(Byte.valueOf((byte) 87));
124         producer.fireEvent(eventType, (byte) 87);
125         producer.fireEvent(TestEventProducer.PRODUCER_EVENT_1, 12345);
126 
127         addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1);
128         assertTrue(addListenerOK);
129         addListenerOK = producer.addListener(listener, eventType);
130         assertTrue(addListenerOK);
131         listener.setExpectingNotification(true);
132         listener.setExpectedObject(Double.valueOf(123.456d));
133         producer.fireEvent(eventType, 123.456d);
134         assertEquals(eventType, listener.getReceivedEvent().getType());
135         listener.setExpectedObject(Double.valueOf(234.567d));
136         producer.fireEvent(TestEventProducer.PRODUCER_EVENT_1, 234.567d);
137         assertEquals(TestEventProducer.PRODUCER_EVENT_1, listener.getReceivedEvent().getType());
138         TestTimedEventListener<Double> timedListener = new TestTimedEventListener<>();
139         addListenerOK = producer.addListener(timedListener, timedEventType);
140         assertTrue(addListenerOK);
141         timedListener.setExpectingNotification(true);
142         timedListener.setExpectedObject(Double.valueOf(12.34d));
143         listener.setExpectedObject(Double.valueOf(12.34d));
144         producer.fireTimedEvent(new TimedEvent<Double>(timedEventType, producer, Double.valueOf(12.34d), 12.01d));
145         assertEquals(12.01, timedListener.getReceivedEvent().getTimeStamp(), 0.001);
146 
147         nrRemovedListeners = producer.removeAllListeners(TestEventListener.class);
148         assertEquals(2, nrRemovedListeners);
149         listener.setExpectingNotification(false);
150         timedListener.setExpectingNotification(true);
151         timedListener.setExpectedObject(Byte.valueOf((byte) 87));
152         producer.fireTimedEvent(timedEventType, (byte) 87, Double.valueOf(13.02d));
153         assertEquals(13.02, timedListener.getReceivedEvent().getTimeStamp(), 0.001);
154 
155         nrRemovedListeners = producer.removeAllListeners();
156         assertEquals(1, nrRemovedListeners);
157     }
158 
159     /**
160      * Test the EventProducer and EventListener for verified / unverified events.
161      */
162     @Test
163     public void testEventVerificationPubSub()
164     {
165         TestEventProducer producer = new TestEventProducer();
166         TestEventListener listener = new TestEventListener();
167         EventType eventType = new EventType("STRING_TYPE",
168                 new MetaData("STRING", "string", new ObjectDescriptor("String", "string", String.class)));
169 
170         boolean addListenerOK = producer.addListener(listener, eventType);
171         assertTrue(addListenerOK);
172 
173         Try.testFail(new Try.Execution()
174         {
175             @Override
176             public void execute() throws Throwable
177             {
178                 listener.setExpectedObject(Boolean.valueOf(true));
179                 producer.fireEvent(eventType, true);
180             }
181         }, "expected ClassCastException", ClassCastException.class);
182 
183         Try.testFail(new Try.Execution()
184         {
185             @Override
186             public void execute() throws Throwable
187             {
188                 listener.setExpectedObject(Byte.valueOf((byte) 87));
189                 producer.fireEvent(eventType, (byte) 87);
190             }
191         }, "expected ClassCastException", ClassCastException.class);
192 
193         Try.testFail(new Try.Execution()
194         {
195             @Override
196             public void execute() throws Throwable
197             {
198                 listener.setExpectedObject(Character.valueOf('a'));
199                 producer.fireEvent(eventType, 'a');
200             }
201         }, "expected ClassCastException", ClassCastException.class);
202 
203         Try.testFail(new Try.Execution()
204         {
205             @Override
206             public void execute() throws Throwable
207             {
208                 listener.setExpectedObject(Short.valueOf((short) -234));
209                 producer.fireEvent(eventType, (short) -234);
210             }
211         }, "expected ClassCastException", ClassCastException.class);
212 
213         Try.testFail(new Try.Execution()
214         {
215             @Override
216             public void execute() throws Throwable
217             {
218                 listener.setExpectedObject(Float.valueOf(458.9f));
219                 producer.fireEvent(eventType, 458.9f);
220             }
221         }, "expected ClassCastException", ClassCastException.class);
222 
223         Try.testFail(new Try.Execution()
224         {
225             @Override
226             public void execute() throws Throwable
227             {
228                 listener.setExpectedObject(Double.valueOf(123.456d));
229                 producer.fireEvent(eventType, 123.456d);
230             }
231         }, "expected ClassCastException", ClassCastException.class);
232 
233         Try.testFail(new Try.Execution()
234         {
235             @Override
236             public void execute() throws Throwable
237             {
238                 listener.setExpectedObject(Integer.valueOf(12345));
239                 producer.fireEvent(eventType, 12345);
240             }
241         }, "expected ClassCastException", ClassCastException.class);
242 
243         Try.testFail(new Try.Execution()
244         {
245             @Override
246             public void execute() throws Throwable
247             {
248                 listener.setExpectedObject(Long.valueOf(123456L));
249                 producer.fireEvent(eventType, 123456L);
250             }
251         }, "expected ClassCastException", ClassCastException.class);
252 
253         Try.testFail(new Try.Execution()
254         {
255             @Override
256             public void execute() throws Throwable
257             {
258                 listener.setExpectedObject(new String[] {"a", "b"});
259                 producer.fireEvent(eventType, new String[] {"a", "b"});
260             }
261         }, "expected IndexOutOfBoundsException", IndexOutOfBoundsException.class);
262 
263         Try.testFail(new Try.Execution()
264         {
265             @Override
266             public void execute() throws Throwable
267             {
268                 listener.setExpectedObject(Double.valueOf(1.2));
269                 producer.fireEvent(eventType, Double.valueOf(1.2));
270             }
271         }, "expected ClassCastException", ClassCastException.class);
272 
273         listener.setExpectedObject("abc");
274         producer.fireUnverifiedEvent(new Event(eventType, producer, "abc"));
275 
276         listener.setExpectedObject(Boolean.valueOf(true));
277         producer.fireUnverifiedEvent(eventType, true);
278 
279         listener.setExpectedObject(Byte.valueOf((byte) 87));
280         producer.fireUnverifiedEvent(eventType, (byte) 87);
281 
282         listener.setExpectedObject(Character.valueOf('a'));
283         producer.fireUnverifiedEvent(eventType, 'a');
284 
285         listener.setExpectedObject(Short.valueOf((short) -234));
286         producer.fireUnverifiedEvent(eventType, (short) -234);
287 
288         listener.setExpectedObject(Float.valueOf(458.9f));
289         producer.fireUnverifiedEvent(eventType, 458.9f);
290 
291         listener.setExpectedObject(Double.valueOf(123.456d));
292         producer.fireUnverifiedEvent(eventType, 123.456d);
293 
294         listener.setExpectedObject(Integer.valueOf(12345));
295         producer.fireUnverifiedEvent(eventType, 12345);
296 
297         listener.setExpectedObject(Long.valueOf(123456L));
298         producer.fireUnverifiedEvent(eventType, 123456L);
299 
300         listener.setExpectedObject(new String[] {"a", "b"});
301         producer.fireUnverifiedEvent(eventType, new String[] {"a", "b"});
302 
303         listener.setExpectedObject(Double.valueOf(1.2));
304         producer.fireUnverifiedEvent(eventType, Double.valueOf(1.2));
305 
306         listener.setExpectedObject(null);
307         producer.fireUnverifiedEvent(eventType);
308 
309         producer.removeAllListeners();
310     }
311 
312     /**
313      * Test the EventProducer and EventListener for TimedEvents.
314      */
315     @Test
316     public void testTimedEventPubSub()
317     {
318         TestEventProducer producer = new TestEventProducer();
319         TestTimedEventListener<Double> listener = new TestTimedEventListener<>();
320         TimedEventType timedEventType = new TimedEventType("TIMED_TEST_TYPE", MetaData.NO_META_DATA);
321 
322         boolean addListenerOK = producer.addListener(listener, timedEventType);
323         assertTrue(addListenerOK);
324 
325         String string = "abc123";
326         listener.setExpectedObject(string);
327         producer.fireTimedEvent(new TimedEvent<Double>(timedEventType, producer, string, 12.01d));
328         assertEquals(string, listener.getReceivedEvent().getContent());
329         assertEquals(timedEventType, listener.getReceivedEvent().getType());
330         assertEquals(producer, listener.getReceivedEvent().getSourceId());
331         assertEquals(12.01d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
332 
333         listener.setExpectedObject(Boolean.valueOf(true));
334         producer.fireTimedEvent(timedEventType, true, Double.valueOf(12.02d));
335         assertEquals(12.02d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
336         listener.setExpectedObject(Boolean.valueOf(false));
337         producer.fireTimedEvent(timedEventType, false, Double.valueOf(12.03d));
338         assertEquals(12.03d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
339 
340         listener.setExpectedObject(Byte.valueOf((byte) 87));
341         producer.fireTimedEvent(timedEventType, (byte) 87, Double.valueOf(12.04d));
342         assertEquals(12.04d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
343 
344         listener.setExpectedObject(Character.valueOf('X'));
345         producer.fireTimedEvent(timedEventType, 'X', Double.valueOf(12.14d));
346         assertEquals(12.14d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
347 
348         listener.setExpectedObject(Short.valueOf((short) -234));
349         producer.fireTimedEvent(timedEventType, (short) -234, Double.valueOf(12.05d));
350         assertEquals(12.05d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
351 
352         listener.setExpectedObject(Float.valueOf(246.8f));
353         producer.fireTimedEvent(timedEventType, 246.8f, Double.valueOf(12.15d));
354         assertEquals(12.15d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
355 
356         listener.setExpectedObject(Double.valueOf(123.456d));
357         producer.fireTimedEvent(timedEventType, 123.456d, Double.valueOf(12.06d));
358         assertEquals(12.06d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
359 
360         listener.setExpectedObject(Integer.valueOf(12345));
361         producer.fireTimedEvent(timedEventType, 12345, Double.valueOf(12.07d));
362         assertEquals(12.07d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
363 
364         listener.setExpectedObject(Long.valueOf(123456L));
365         producer.fireTimedEvent(timedEventType, 123456L, Double.valueOf(12.08d));
366         assertEquals(12.08d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
367 
368         listener.setExpectedObject(null);
369         producer.fireTimedEvent(timedEventType, null, Double.valueOf(12.09d));
370         assertEquals(12.09d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
371 
372         listener.setExpectedObject("abc");
373         producer.fireUnverifiedTimedEvent(new TimedEvent<Double>(timedEventType, producer, "abc", Double.valueOf(12.10d)));
374         assertEquals(12.10d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
375 
376         listener.setExpectedObject(null);
377         producer.fireUnverifiedTimedEvent(timedEventType, Double.valueOf(12.11d));
378         assertEquals(12.11d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
379 
380         producer.removeAllListeners();
381     }
382 
383     /**
384      * Test the EventProducer and EventListener for verified / unverified timed events.
385      */
386     @Test
387     @SuppressWarnings("checkstyle:methodlength")
388     public void testTimedEventVerificationPubSub()
389     {
390         TestEventProducer producer = new TestEventProducer();
391         TestTimedEventListener<Double> listener = new TestTimedEventListener<>();
392         TimedEventType timedEventType = new TimedEventType("TIMED_STRING_TYPE",
393                 new MetaData("STRING", "string", new ObjectDescriptor("String", "string", String.class)));
394 
395         boolean addListenerOK = producer.addListener(listener, timedEventType);
396         assertTrue(addListenerOK);
397 
398         Try.testFail(new Try.Execution()
399         {
400             @Override
401             public void execute() throws Throwable
402             {
403                 listener.setExpectedObject(Boolean.valueOf(true));
404                 producer.fireTimedEvent(timedEventType, true, Double.valueOf(12.01d));
405             }
406         }, "expected ClassCastException", ClassCastException.class);
407 
408         Try.testFail(new Try.Execution()
409         {
410             @Override
411             public void execute() throws Throwable
412             {
413                 listener.setExpectedObject(Byte.valueOf((byte) 87));
414                 producer.fireTimedEvent(timedEventType, (byte) 87, Double.valueOf(12.02d));
415             }
416         }, "expected ClassCastException", ClassCastException.class);
417 
418         Try.testFail(new Try.Execution()
419         {
420             @Override
421             public void execute() throws Throwable
422             {
423                 listener.setExpectedObject(Character.valueOf('a'));
424                 producer.fireTimedEvent(timedEventType, 'a', Double.valueOf(12.03d));
425             }
426         }, "expected ClassCastException", ClassCastException.class);
427 
428         Try.testFail(new Try.Execution()
429         {
430             @Override
431             public void execute() throws Throwable
432             {
433                 listener.setExpectedObject(Short.valueOf((short) -234));
434                 producer.fireTimedEvent(timedEventType, (short) -234, Double.valueOf(12.04d));
435             }
436         }, "expected ClassCastException", ClassCastException.class);
437 
438         Try.testFail(new Try.Execution()
439         {
440             @Override
441             public void execute() throws Throwable
442             {
443                 listener.setExpectedObject(Float.valueOf(458.9f));
444                 producer.fireTimedEvent(timedEventType, 458.9f, Double.valueOf(12.05d));
445             }
446         }, "expected ClassCastException", ClassCastException.class);
447 
448         Try.testFail(new Try.Execution()
449         {
450             @Override
451             public void execute() throws Throwable
452             {
453                 listener.setExpectedObject(Double.valueOf(123.456d));
454                 producer.fireTimedEvent(timedEventType, 123.456d, Double.valueOf(12.06d));
455             }
456         }, "expected ClassCastException", ClassCastException.class);
457 
458         Try.testFail(new Try.Execution()
459         {
460             @Override
461             public void execute() throws Throwable
462             {
463                 listener.setExpectedObject(Integer.valueOf(12345));
464                 producer.fireTimedEvent(timedEventType, 12345, Double.valueOf(12.07d));
465             }
466         }, "expected ClassCastException", ClassCastException.class);
467 
468         Try.testFail(new Try.Execution()
469         {
470             @Override
471             public void execute() throws Throwable
472             {
473                 listener.setExpectedObject(Long.valueOf(123456L));
474                 producer.fireTimedEvent(timedEventType, 123456L, Double.valueOf(12.08d));
475             }
476         }, "expected ClassCastException", ClassCastException.class);
477 
478         Try.testFail(new Try.Execution()
479         {
480             @Override
481             public void execute() throws Throwable
482             {
483                 listener.setExpectedObject(new String[] {"a", "b"});
484                 producer.fireTimedEvent(timedEventType, new String[] {"a", "b"}, Double.valueOf(12.09d));
485             }
486         }, "expected IndexOutOfBoundsException", IndexOutOfBoundsException.class);
487 
488         Try.testFail(new Try.Execution()
489         {
490             @Override
491             public void execute() throws Throwable
492             {
493                 listener.setExpectedObject(Double.valueOf(1.2));
494                 producer.fireTimedEvent(timedEventType, Double.valueOf(1.2), Double.valueOf(12.10d));
495             }
496         }, "expected ClassCastException", ClassCastException.class);
497 
498         listener.setExpectedObject(Boolean.valueOf(true));
499         producer.fireUnverifiedTimedEvent(timedEventType, true, Double.valueOf(12.01d));
500         assertEquals(12.01d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
501 
502         listener.setExpectedObject(Byte.valueOf((byte) 87));
503         producer.fireUnverifiedTimedEvent(timedEventType, (byte) 87, Double.valueOf(12.02d));
504         assertEquals(12.02d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
505 
506         listener.setExpectedObject(Character.valueOf('a'));
507         producer.fireUnverifiedTimedEvent(timedEventType, 'a', Double.valueOf(12.03d));
508         assertEquals(12.03d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
509 
510         listener.setExpectedObject(Short.valueOf((short) -234));
511         producer.fireUnverifiedTimedEvent(timedEventType, (short) -234, Double.valueOf(12.04d));
512         assertEquals(12.04d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
513 
514         listener.setExpectedObject(Float.valueOf(458.9f));
515         producer.fireUnverifiedTimedEvent(timedEventType, 458.9f, Double.valueOf(12.05d));
516         assertEquals(12.05d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
517 
518         listener.setExpectedObject(Double.valueOf(123.456d));
519         producer.fireUnverifiedTimedEvent(timedEventType, 123.456d, Double.valueOf(12.06d));
520         assertEquals(12.06d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
521 
522         listener.setExpectedObject(Integer.valueOf(12345));
523         producer.fireUnverifiedTimedEvent(timedEventType, 12345, Double.valueOf(12.07d));
524         assertEquals(12.07d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
525 
526         listener.setExpectedObject(Long.valueOf(123456L));
527         producer.fireUnverifiedTimedEvent(timedEventType, 123456L, Double.valueOf(12.08d));
528         assertEquals(12.08d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
529 
530         listener.setExpectedObject(new String[] {"a", "b"});
531         producer.fireUnverifiedTimedEvent(timedEventType, new String[] {"a", "b"}, Double.valueOf(12.09d));
532         assertEquals(12.09d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
533 
534         listener.setExpectedObject(Double.valueOf(1.2));
535         producer.fireUnverifiedTimedEvent(timedEventType, Double.valueOf(1.2), Double.valueOf(12.10d));
536         assertEquals(12.10d, listener.getReceivedEvent().getTimeStamp().doubleValue(), 0.001);
537 
538         producer.removeAllListeners();
539     }
540 
541     /**
542      * Test the EventProducer and EventListener for two events with the same name being equal...
543      */
544     @Test
545     public void testIllegalEventProducer()
546     {
547         assertEquals(TestIllegalEventProducer.PRODUCER_EVENT_1, TestIllegalEventProducer.PRODUCER_EVENT_2);
548         assertNotEquals(TestIllegalEventProducer.PRODUCER_EVENT_1, TestEventProducer.PRODUCER_EVENT_1);
549         assertNotEquals(TestEventProducer.PRODUCER_EVENT_2, TestEventProducer.PRODUCER_EVENT_1);
550     }
551 
552     /**
553      * Test the EventProducer for strong and weak references, and for position information.
554      * @throws SecurityException on error retrieving listener map
555      * @throws NoSuchFieldException on error retrieving listener map
556      * @throws IllegalAccessException on error retrieving listener map
557      * @throws IllegalArgumentException on error retrieving listener map
558      */
559     @Test
560     public void testEventStrongWeakPos()
561             throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException
562     {
563         TestEventProducer producer = new TestEventProducer();
564         TestEventListener listener = new TestEventListener();
565 
566         // test illegal parameters and null pointer exceptions in adding a listener
567         try
568         {
569             producer.addListener(null, TestEventProducer.PRODUCER_EVENT_1);
570             fail("null listener should have thrown an exception");
571         }
572         catch (NullPointerException npe)
573         {
574             // Ignore expected exception
575         }
576         boolean addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1, -10, ReferenceType.STRONG);
577         assertFalse(addListenerOK);
578         Try.testFail(new Try.Execution()
579         {
580             @Override
581             public void execute() throws Throwable
582             {
583                 producer.addListener(listener, null);
584             }
585         }, "expected NullPointerException", NullPointerException.class);
586         Try.testFail(new Try.Execution()
587         {
588             @Override
589             public void execute() throws Throwable
590             {
591                 producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1, null);
592             }
593         }, "expected NullPointerException", NullPointerException.class);
594         Try.testFail(new Try.Execution()
595         {
596             @Override
597             public void execute() throws Throwable
598             {
599                 producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1, 0, null);
600             }
601         }, "expected NullPointerException", NullPointerException.class);
602 
603         // test whether weak and strong calls to addListener work, and whether positions can be provided
604         assertFalse(producer.hasListeners());
605         assertEquals(0, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
606         assertEquals(new LinkedHashSet<EventType>(), producer.getEventTypesWithListeners());
607 
608         addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1);
609         assertTrue(addListenerOK);
610         assertTrue(producer.hasListeners());
611         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
612         assertEquals(new LinkedHashSet<EventType>(Arrays.asList(TestEventProducer.PRODUCER_EVENT_1)),
613                 producer.getEventTypesWithListeners());
614 
615         addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_2, ReferenceType.WEAK);
616         assertTrue(addListenerOK);
617         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
618         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_2));
619         assertEquals(
620                 new LinkedHashSet<EventType>(
621                         Arrays.asList(TestEventProducer.PRODUCER_EVENT_1, TestEventProducer.PRODUCER_EVENT_2)),
622                 producer.getEventTypesWithListeners());
623 
624         // check false for adding same listener second time
625         addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_2, ReferenceType.WEAK);
626         assertFalse(addListenerOK);
627         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
628         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_2));
629         assertEquals(
630                 new LinkedHashSet<EventType>(
631                         Arrays.asList(TestEventProducer.PRODUCER_EVENT_1, TestEventProducer.PRODUCER_EVENT_2)),
632                 producer.getEventTypesWithListeners());
633 
634         // check LAST_POSITION and FIRST_POSITION
635         TestEventListener listener2 = new TestEventListener();
636         TestEventListener listener3 = new TestEventListener();
637         addListenerOK =
638                 producer.addListener(listener2, TestEventProducer.PRODUCER_EVENT_2, EventProducerInterface.LAST_POSITION);
639         addListenerOK =
640                 producer.addListener(listener3, TestEventProducer.PRODUCER_EVENT_2, EventProducerInterface.FIRST_POSITION);
641         assertEquals(3, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_2));
642 
643         // check whether positions have been inserted okay: listener3 - listener - listener2
644         List<Reference<EventListenerInterface>> listenerList =
645                 producer.getListenerReferences(TestEventProducer.PRODUCER_EVENT_2);
646         assertEquals(3, listenerList.size());
647         assertEquals(listener3, listenerList.get(0).get());
648         assertEquals(listener, listenerList.get(1).get());
649         assertEquals(listener2, listenerList.get(2).get());
650     }
651 
652     /**
653      * Test the EventProducer for a weak reference that is removed by the garbage collector.
654      * @throws SecurityException on error retrieving listener map
655      * @throws NoSuchFieldException on error retrieving listener map
656      * @throws IllegalAccessException on error retrieving listener map
657      * @throws IllegalArgumentException on error retrieving listener map
658      */
659     @Test
660     public void testEventProducerWeakRemoval()
661             throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException
662     {
663         TestEventProducer producer = new TestEventProducer();
664         TestEventListener listener = new TestEventListener();
665         boolean addListenerOK = producer.addListener(listener, TestEventProducer.PRODUCER_EVENT_1, ReferenceType.WEAK);
666         assertTrue(addListenerOK);
667         assertTrue(producer.hasListeners());
668         assertEquals(1, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
669 
670         // fire an event -- should arrive
671         listener.setExpectingNotification(true);
672         listener.setExpectedObject(Integer.valueOf(12));
673         producer.fireEvent(TestEventProducer.PRODUCER_EVENT_1, 12);
674 
675         // check the registered listeners in the map
676         List<Reference<EventListenerInterface>> listenerList =
677                 producer.getListenerReferences(TestEventProducer.PRODUCER_EVENT_1);
678         assertEquals(1, listenerList.size());
679         Reference<EventListenerInterface> ref = listenerList.get(0);
680         // simulate clearing by GC (the list is a safe copy, but the reference is original)
681         Field referent = ref.getClass().getDeclaredField("referent");
682         referent.setAccessible(true);
683         referent.set(ref, new java.lang.ref.WeakReference<EventListenerInterface>(null));
684         referent.setAccessible(false);
685 
686         // fire an event -- should not arrive
687         listener.setExpectingNotification(false);
688         producer.fireEvent(TestEventProducer.PRODUCER_EVENT_1, 34);
689         assertFalse(producer.hasListeners());
690         assertEquals(0, producer.numberOfListeners(TestEventProducer.PRODUCER_EVENT_1));
691 
692         producer.removeAllListeners();
693     }
694 
695     /** */
696     protected static class TestEventProducer extends EventProducer
697     {
698         /** */
699         private static final long serialVersionUID = 20191230L;
700 
701         /** */
702         public static final EventType PRODUCER_EVENT_1 = new EventType("PRODUCER_EVENT_1", MetaData.NO_META_DATA);
703 
704         /** */
705         public static final EventType PRODUCER_EVENT_2 = new EventType("PRODUCER_EVENT_2", MetaData.NO_META_DATA);
706 
707         /** this should be okay. */
708         @SuppressWarnings("unused")
709         private static final EventType PRODUCER_EVENT_3 = new EventType("PRODUCER_EVENT_1", MetaData.NO_META_DATA);
710 
711         /** this should be okay. */
712         @SuppressWarnings("unused")
713         private static final EventType PRODUCER_EVENT_4 = new EventType("PRODUCER_EVENT_1", MetaData.NO_META_DATA);
714 
715         /** {@inheritDoc} */
716         @Override
717         public Serializable getSourceId()
718         {
719             return "producer_source_id";
720         }
721     }
722 
723     /** */
724     protected static class TestIllegalEventProducer extends EventProducer
725     {
726         /** */
727         private static final long serialVersionUID = 20191230L;
728 
729         /** */
730         public static final EventType PRODUCER_EVENT_1 = new EventType("PRODUCER_EVENT_1", MetaData.NO_META_DATA);
731 
732         /** duplicate static non-private EventType should give error on class construction. */
733         public static final EventType PRODUCER_EVENT_2 = new EventType("PRODUCER_EVENT_1", MetaData.NO_META_DATA);
734 
735         /** {@inheritDoc} */
736         @Override
737         public Serializable getSourceId()
738         {
739             return "illegal_producer_source_id";
740         }
741     }
742 
743     /** */
744     protected static class TestEventListener implements EventListenerInterface
745     {
746         /** */
747         private static final long serialVersionUID = 20191230L;
748 
749         /** expect notification or not. */
750         private boolean expectingNotification = true;
751 
752         /** expected object in notify. */
753         private Object expectedObject;
754 
755         /** received event. */
756         private EventInterface receivedEvent;
757 
758         /**
759          * @param expectingNotification set expectingNotification
760          */
761         public void setExpectingNotification(final boolean expectingNotification)
762         {
763             this.expectingNotification = expectingNotification;
764         }
765 
766         /**
767          * @param expectedObject set expectedObject
768          */
769         public void setExpectedObject(final Object expectedObject)
770         {
771             this.expectedObject = expectedObject;
772         }
773 
774         /**
775          * @return receivedEvent
776          */
777         public EventInterface getReceivedEvent()
778         {
779             return this.receivedEvent;
780         }
781 
782         /** {@inheritDoc} */
783         @Override
784         public void notify(final EventInterface event) throws RemoteException
785         {
786             if (!this.expectingNotification)
787             {
788                 fail("Received event " + event + " unexpectedly");
789             }
790             this.receivedEvent = event;
791             if (this.expectedObject != null && event.getContent() != null && this.expectedObject.getClass().isArray()
792                     && event.getContent().getClass().isArray())
793             {
794                 Object[] e = (Object[]) this.expectedObject;
795                 Object[] r = (Object[]) event.getContent();
796                 assertEquals(e.length, r.length);
797                 for (int i = 0; i < e.length; i++)
798                 {
799                     assertEquals(e[i], r[i]);
800                 }
801             }
802             else
803             {
804                 assertEquals(this.expectedObject, event.getContent());
805             }
806         }
807 
808     }
809 
810     /**
811      * TimedEventListener.
812      * @param <C> the comparable time type
813      */
814     protected static class TestTimedEventListener<C extends Comparable<C> & Serializable> implements EventListenerInterface
815     {
816         /** */
817         private static final long serialVersionUID = 20191230L;
818 
819         /** expect notification or not. */
820         private boolean expectingNotification = true;
821 
822         /** expected object in notify. */
823         private Object expectedObject;
824 
825         /** received event. */
826         private TimedEvent<C> receivedEvent;
827 
828         /**
829          * @param expectingNotification set expectingNotification
830          */
831         public void setExpectingNotification(final boolean expectingNotification)
832         {
833             this.expectingNotification = expectingNotification;
834         }
835 
836         /**
837          * @param expectedObject set expectedObject
838          */
839         public void setExpectedObject(final Object expectedObject)
840         {
841             this.expectedObject = expectedObject;
842         }
843 
844         /**
845          * @return receivedEvent
846          */
847         public TimedEvent<C> getReceivedEvent()
848         {
849             return this.receivedEvent;
850         }
851 
852         /** {@inheritDoc} */
853         @SuppressWarnings("unchecked")
854         @Override
855         public void notify(final EventInterface event) throws RemoteException
856         {
857             if (!this.expectingNotification)
858             {
859                 fail("Received event " + event + " unexpectedly");
860             }
861             if (!(event instanceof TimedEvent))
862             {
863                 fail("Received event " + event + " is not a TimedEvent");
864             }
865             this.receivedEvent = (TimedEvent<C>) event;
866             if (this.expectedObject != null && event.getContent() != null && this.expectedObject.getClass().isArray()
867                     && event.getContent().getClass().isArray())
868             {
869                 Object[] e = (Object[]) this.expectedObject;
870                 Object[] r = (Object[]) event.getContent();
871                 assertEquals(e.length, r.length);
872                 for (int i = 0; i < e.length; i++)
873                 {
874                     assertEquals(e[i], r[i]);
875                 }
876             }
877             else
878             {
879                 assertEquals(this.expectedObject, event.getContent());
880             }
881         }
882 
883     }
884 
885 }