]> git.basschouten.com Git - openhab-addons.git/blob
58e5fa2de0aa886a2e550c1c24a7ccc66eca118d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.satel.internal.event;
14
15 import java.lang.reflect.Method;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.concurrent.CopyOnWriteArraySet;
19 import java.util.stream.Collectors;
20 import java.util.stream.Stream;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Allows distributing incoming event to all registered listeners. Listeners
29  * must implement {@link SatelEventListener} interface.
30  *
31  * @author Krzysztof Goworek - Initial contribution
32  */
33 @NonNullByDefault
34 public class EventDispatcher {
35
36     private final Logger logger = LoggerFactory.getLogger(EventDispatcher.class);
37
38     private final Set<SatelEventListener> eventListeners = new CopyOnWriteArraySet<>();
39
40     @SuppressWarnings("unchecked")
41     private final Map<Class<? extends SatelEvent>, @Nullable Method> eventHandlers = Stream
42             .of(SatelEventListener.class.getDeclaredMethods())
43             .filter(m -> m.getParameterCount() == 1 && SatelEvent.class.isAssignableFrom(m.getParameterTypes()[0]))
44             .collect(Collectors.toMap(m -> (Class<SatelEvent>) m.getParameterTypes()[0], m -> m));
45
46     /**
47      * Add a listener for Satel events.
48      *
49      * @param eventListener the event listener to add.
50      */
51     public void addEventListener(SatelEventListener eventListener) {
52         this.eventListeners.add(eventListener);
53     }
54
55     /**
56      * Remove a listener for Satel events.
57      *
58      * @param eventListener the event listener to remove.
59      */
60     public void removeEventListener(SatelEventListener eventListener) {
61         this.eventListeners.remove(eventListener);
62     }
63
64     /**
65      * Dispatch incoming event to all listeners.
66      *
67      * @param event the event to distribute.
68      */
69     public void dispatchEvent(SatelEvent event) {
70         final Method m = eventHandlers.get(event.getClass());
71         if (m == null) {
72             logger.warn("Missing event handler for event {}. Event discarded.", event.getClass().getName());
73         } else {
74             logger.debug("Distributing event: {}", event);
75             eventListeners.forEach(listener -> {
76                 logger.trace("Distributing to {}", listener);
77                 try {
78                     m.invoke(listener, event);
79                 } catch (ReflectiveOperationException e) {
80                     logger.warn("Unable to distribute {} to {}", event.getClass().getName(), listener, e);
81                 }
82             });
83         }
84     }
85 }