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