]> git.basschouten.com Git - openhab-addons.git/blob
44ebb77340260ad74831afa4f5342eeb4500a99e
[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.nest.internal.update;
14
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.function.Supplier;
21 import java.util.stream.Collectors;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.nest.internal.data.NestIdentifiable;
26 import org.openhab.binding.nest.internal.data.TopLevelData;
27 import org.openhab.binding.nest.internal.listener.NestThingDataListener;
28
29 /**
30  * Handles all Nest data updates through delegation to the {@link NestUpdateHandler} for the respective data type.
31  *
32  * @author Wouter Born - Initial contribution
33  */
34 @NonNullByDefault
35 public class NestCompositeUpdateHandler {
36
37     private final Supplier<Set<String>> presentNestIdsSupplier;
38     private final Map<Class<?>, NestUpdateHandler<?>> updateHandlersMap = new ConcurrentHashMap<>();
39
40     public NestCompositeUpdateHandler(Supplier<Set<String>> presentNestIdsSupplier) {
41         this.presentNestIdsSupplier = presentNestIdsSupplier;
42     }
43
44     public <T> boolean addListener(Class<T> dataClass, NestThingDataListener<T> listener) {
45         return getOrCreateUpdateHandler(dataClass).addListener(listener);
46     }
47
48     public <T> boolean addListener(Class<T> dataClass, String nestId, NestThingDataListener<T> listener) {
49         return getOrCreateUpdateHandler(dataClass).addListener(nestId, listener);
50     }
51
52     private Set<String> findMissingNestIds(Set<NestIdentifiable> updates) {
53         Set<String> nestIds = updates.stream().map(u -> u.getId()).collect(Collectors.toSet());
54         Set<String> missingNestIds = presentNestIdsSupplier.get();
55         missingNestIds.removeAll(nestIds);
56         return missingNestIds;
57     }
58
59     public @Nullable <T> T getLastUpdate(Class<T> dataClass, String nestId) {
60         return getOrCreateUpdateHandler(dataClass).getLastUpdate(nestId);
61     }
62
63     public <T> List<T> getLastUpdates(Class<T> dataClass) {
64         return getOrCreateUpdateHandler(dataClass).getLastUpdates();
65     }
66
67     private Set<NestIdentifiable> getNestUpdates(TopLevelData data) {
68         Set<NestIdentifiable> updates = new HashSet<>();
69         if (data.getDevices() != null) {
70             if (data.getDevices().getCameras() != null) {
71                 updates.addAll(data.getDevices().getCameras().values());
72             }
73             if (data.getDevices().getSmokeCoAlarms() != null) {
74                 updates.addAll(data.getDevices().getSmokeCoAlarms().values());
75             }
76             if (data.getDevices().getThermostats() != null) {
77                 updates.addAll(data.getDevices().getThermostats().values());
78             }
79         }
80         if (data.getStructures() != null) {
81             updates.addAll(data.getStructures().values());
82         }
83         return updates;
84     }
85
86     @SuppressWarnings("unchecked")
87     private <T> NestUpdateHandler<T> getOrCreateUpdateHandler(Class<T> dataClass) {
88         NestUpdateHandler<T> handler = (NestUpdateHandler<T>) updateHandlersMap.get(dataClass);
89         if (handler == null) {
90             handler = new NestUpdateHandler<>();
91             updateHandlersMap.put(dataClass, handler);
92         }
93         return handler;
94     }
95
96     @SuppressWarnings("unchecked")
97     public void handleUpdate(TopLevelData data) {
98         Set<NestIdentifiable> updates = getNestUpdates(data);
99         updates.forEach(update -> {
100             Class<NestIdentifiable> updateClass = (Class<NestIdentifiable>) update.getClass();
101             getOrCreateUpdateHandler(updateClass).handleUpdate(updateClass, update.getId(), update);
102         });
103
104         Set<String> missingNestIds = findMissingNestIds(updates);
105         if (!missingNestIds.isEmpty()) {
106             updateHandlersMap.values().forEach(handler -> {
107                 handler.handleMissingNestIds(missingNestIds);
108             });
109         }
110     }
111
112     public <T> boolean removeListener(Class<T> dataClass, NestThingDataListener<T> listener) {
113         return getOrCreateUpdateHandler(dataClass).removeListener(listener);
114     }
115
116     public <T> boolean removeListener(Class<T> dataClass, String nestId, NestThingDataListener<T> listener) {
117         return getOrCreateUpdateHandler(dataClass).removeListener(nestId, listener);
118     }
119
120     public void resendLastUpdates() {
121         updateHandlersMap.values().forEach(handler -> {
122             handler.resendLastUpdates();
123         });
124     }
125 }