2 * Copyright (c) 2010-2023 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.tr064.internal.util;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Optional;
20 import java.util.stream.Collectors;
21 import java.util.stream.Stream;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jetty.client.HttpClient;
25 import org.openhab.binding.tr064.internal.SCPDException;
26 import org.openhab.binding.tr064.internal.dto.scpd.root.SCPDDeviceType;
27 import org.openhab.binding.tr064.internal.dto.scpd.root.SCPDRootType;
28 import org.openhab.binding.tr064.internal.dto.scpd.root.SCPDServiceType;
29 import org.openhab.binding.tr064.internal.dto.scpd.service.SCPDScpdType;
32 * The {@link SCPDUtil} is responsible for handling commands, which are
33 * sent to one of the channels.
35 * @author Jan N. Klug - Initial contribution
38 public class SCPDUtil {
39 private SCPDRootType scpdRoot;
40 private final List<SCPDDeviceType> scpdDevicesList = new ArrayList<>();
41 private final Map<String, SCPDScpdType> serviceMap = new HashMap<>();
43 public SCPDUtil(HttpClient httpClient, String endpoint) throws SCPDException {
44 SCPDRootType scpdRoot = Util.getAndUnmarshalXML(httpClient, endpoint + "/tr64desc.xml", SCPDRootType.class);
45 if (scpdRoot == null) {
46 throw new SCPDException("could not get SCPD root");
48 this.scpdRoot = scpdRoot;
50 scpdDevicesList.addAll(flatDeviceList(scpdRoot.getDevice()).collect(Collectors.toList()));
51 for (SCPDDeviceType device : scpdDevicesList) {
52 for (SCPDServiceType service : device.getServiceList()) {
53 SCPDScpdType scpd = serviceMap.computeIfAbsent(service.getServiceId(), serviceId -> Util
54 .getAndUnmarshalXML(httpClient, endpoint + service.getSCPDURL(), SCPDScpdType.class));
56 throw new SCPDException("could not get SCPD service");
63 * recursively flatten the device tree to a stream
65 * @param device a device
66 * @return stream of sub-devices
68 private Stream<SCPDDeviceType> flatDeviceList(SCPDDeviceType device) {
69 return Stream.concat(Stream.of(device), device.getDeviceList().stream().flatMap(this::flatDeviceList));
73 * get a list of all sub-devices (root device not included)
75 * @return the device list
77 public List<SCPDDeviceType> getAllSubDevices() {
78 return scpdDevicesList.stream().filter(device -> !device.getUDN().equals(scpdRoot.getDevice().getUDN()))
79 .collect(Collectors.toList());
83 * get a single device by it's UDN
85 * @param udn the device UDN
88 public Optional<SCPDDeviceType> getDevice(String udn) {
90 return Optional.of(scpdRoot.getDevice());
92 return getAllSubDevices().stream().filter(device -> udn.equals(device.getUDN())).findFirst();
97 * get a single service by it's serviceId
99 * @param serviceId the service id
100 * @return the service
102 public Optional<SCPDScpdType> getService(String serviceId) {
103 return Optional.ofNullable(serviceMap.get(serviceId));