2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.satel.internal.event;
15 import java.lang.reflect.Method;
18 import java.util.concurrent.CopyOnWriteArraySet;
19 import java.util.stream.Collectors;
20 import java.util.stream.Stream;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Allows distributing incoming event to all registered listeners. Listeners
29 * must implement {@link SatelEventListener} interface.
31 * @author Krzysztof Goworek - Initial contribution
34 public class EventDispatcher {
36 private final Logger logger = LoggerFactory.getLogger(EventDispatcher.class);
38 private final Set<SatelEventListener> eventListeners = new CopyOnWriteArraySet<>();
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));
47 * Add a listener for Satel events.
49 * @param eventListener the event listener to add.
51 public void addEventListener(SatelEventListener eventListener) {
52 this.eventListeners.add(eventListener);
56 * Remove a listener for Satel events.
58 * @param eventListener the event listener to remove.
60 public void removeEventListener(SatelEventListener eventListener) {
61 this.eventListeners.remove(eventListener);
65 * Dispatch incoming event to all listeners.
67 * @param event the event to distribute.
69 public void dispatchEvent(SatelEvent event) {
70 final Method m = eventHandlers.get(event.getClass());
72 logger.warn("Missing event handler for event {}. Event discarded.", event.getClass().getName());
74 logger.debug("Distributing event: {}", event);
75 eventListeners.forEach(listener -> {
76 logger.trace("Distributing to {}", listener);
78 m.invoke(listener, event);
79 } catch (ReflectiveOperationException e) {
80 logger.warn("Unable to distribute {} to {}", event.getClass().getName(), listener, e);