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.lutron.internal.xml;
16 import java.io.Reader;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.lutron.internal.discovery.project.Area;
22 import org.openhab.binding.lutron.internal.discovery.project.Component;
23 import org.openhab.binding.lutron.internal.discovery.project.Device;
24 import org.openhab.binding.lutron.internal.discovery.project.DeviceGroup;
25 import org.openhab.binding.lutron.internal.discovery.project.GreenMode;
26 import org.openhab.binding.lutron.internal.discovery.project.Output;
27 import org.openhab.binding.lutron.internal.discovery.project.Project;
28 import org.openhab.binding.lutron.internal.discovery.project.Timeclock;
30 import com.thoughtworks.xstream.XStream;
31 import com.thoughtworks.xstream.converters.ConversionException;
32 import com.thoughtworks.xstream.io.xml.StaxDriver;
35 * The {@link DbXmlInfoReader} reads Lutron XML project files and converts them to {@link Project}
36 * objects describing the device things contained within the Lutron system.
38 * @author Allan Tong - Initial contribution
39 * @author Bob Adair - Added support for reading XML from a file. Requires using XStream directly
40 * instead of XmlDocumentReader.
43 public class DbXmlInfoReader {
45 private final XStream xstream;
47 public DbXmlInfoReader() {
48 StaxDriver driver = new StaxDriver();
50 xstream = new XStream(driver);
52 configureSecurity(xstream);
53 ClassLoader classLoader = Project.class.getClassLoader();
54 if (classLoader == null) {
55 throw new UnknownError("Cannot find classloader");
57 setClassLoader(classLoader);
58 registerAliases(xstream);
61 private void configureSecurity(XStream xstream) {
62 xstream.allowTypesByWildcard(new String[] { Project.class.getPackageName() + ".**" });
65 private void setClassLoader(ClassLoader classLoader) {
66 xstream.setClassLoader(classLoader);
69 private void registerAliases(XStream xstream) {
70 xstream.alias("Project", Project.class);
71 xstream.aliasField("AppVer", Project.class, "appVersion");
72 xstream.aliasField("XMLVer", Project.class, "xmlVersion");
73 xstream.aliasField("Areas", Project.class, "areas");
74 xstream.aliasField("Timeclocks", Project.class, "timeclocks");
75 xstream.aliasField("GreenModes", Project.class, "greenmodes");
77 xstream.alias("Area", Area.class);
78 xstream.aliasField("Name", Area.class, "name");
79 xstream.useAttributeFor(Area.class, "name");
80 xstream.aliasField("IntegrationID", Area.class, "integrationId");
81 xstream.useAttributeFor(Area.class, "integrationId");
82 xstream.aliasField("DeviceGroups", Area.class, "deviceNodes");
83 xstream.aliasField("Outputs", Area.class, "outputs");
84 xstream.aliasField("Areas", Area.class, "areas");
86 xstream.alias("DeviceGroup", DeviceGroup.class);
87 xstream.aliasField("Name", DeviceGroup.class, "name");
88 xstream.useAttributeFor(DeviceGroup.class, "name");
89 xstream.aliasField("Devices", DeviceGroup.class, "devices");
91 xstream.alias("Device", Device.class);
92 xstream.aliasField("Name", Device.class, "name");
93 xstream.useAttributeFor(Device.class, "name");
94 xstream.aliasField("IntegrationID", Device.class, "integrationId");
95 xstream.useAttributeFor(Device.class, "integrationId");
96 xstream.aliasField("DeviceType", Device.class, "type");
97 xstream.useAttributeFor(Device.class, "type");
98 xstream.aliasField("Components", Device.class, "components");
100 xstream.alias("Component", Component.class);
101 xstream.aliasField("ComponentNumber", Component.class, "componentNumber");
102 xstream.useAttributeFor(Component.class, "componentNumber");
103 xstream.aliasField("ComponentType", Component.class, "type");
104 xstream.useAttributeFor(Component.class, "type");
106 xstream.alias("Output", Output.class);
107 xstream.aliasField("Name", Output.class, "name");
108 xstream.useAttributeFor(Output.class, "name");
109 xstream.aliasField("IntegrationID", Output.class, "integrationId");
110 xstream.useAttributeFor(Output.class, "integrationId");
111 xstream.aliasField("OutputType", Output.class, "type");
112 xstream.useAttributeFor(Output.class, "type");
114 xstream.alias("Timeclock", Timeclock.class);
115 xstream.aliasField("Name", Timeclock.class, "name");
116 xstream.useAttributeFor(Timeclock.class, "name");
117 xstream.aliasField("IntegrationID", Timeclock.class, "integrationId");
118 xstream.useAttributeFor(Timeclock.class, "integrationId");
120 xstream.alias("GreenMode", GreenMode.class);
121 xstream.aliasField("Name", GreenMode.class, "name");
122 xstream.useAttributeFor(GreenMode.class, "name");
123 xstream.aliasField("IntegrationID", GreenMode.class, "integrationId");
124 xstream.useAttributeFor(GreenMode.class, "integrationId");
126 // This reader is only interested in device thing information and does not read
127 // everything contained in DbXmlInfo. Ignoring unknown elements also makes the
128 // binding more tolerant of potential future changes to the XML schema.
129 xstream.ignoreUnknownElements();
132 public @Nullable Project readFromXML(@Nullable URL xmlURL) throws ConversionException {
133 if (xmlURL != null) {
134 return (Project) xstream.fromXML(xmlURL);
140 public @Nullable Project readFromXML(@Nullable File xmlFile) throws ConversionException {
141 if (xmlFile != null) {
142 return (Project) xstream.fromXML(xmlFile);
148 public @Nullable Project readFromXML(@Nullable Reader xmlReader) throws ConversionException {
149 if (xmlReader != null) {
150 return (Project) xstream.fromXML(xmlReader);
156 public @Nullable Project readFromXML(@Nullable String xmlString) throws ConversionException {
157 if (xmlString != null) {
158 return (Project) xstream.fromXML(xmlString);