]> git.basschouten.com Git - openhab-addons.git/blob
f57638c82281e39e81b9c2ab29e172755169d229
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.lutron.internal.xml;
14
15 import java.io.File;
16 import java.io.Reader;
17 import java.net.URL;
18
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;
29
30 import com.thoughtworks.xstream.XStream;
31 import com.thoughtworks.xstream.converters.ConversionException;
32 import com.thoughtworks.xstream.io.xml.StaxDriver;
33
34 /**
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.
37  *
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.
41  */
42 @NonNullByDefault
43 public class DbXmlInfoReader {
44
45     private final XStream xstream;
46
47     public DbXmlInfoReader() {
48         StaxDriver driver = new StaxDriver();
49
50         xstream = new XStream(driver);
51
52         configureSecurity(xstream);
53         ClassLoader classLoader = Project.class.getClassLoader();
54         if (classLoader == null) {
55             throw new UnknownError("Cannot find classloader");
56         }
57         setClassLoader(classLoader);
58         registerAliases(xstream);
59     }
60
61     private void configureSecurity(XStream xstream) {
62         XStream.setupDefaultSecurity(xstream);
63         xstream.allowTypesByWildcard(new String[] { Project.class.getPackageName() + ".**" });
64     }
65
66     private void setClassLoader(ClassLoader classLoader) {
67         xstream.setClassLoader(classLoader);
68     }
69
70     private void registerAliases(XStream xstream) {
71         xstream.alias("Project", Project.class);
72         xstream.aliasField("AppVer", Project.class, "appVersion");
73         xstream.aliasField("XMLVer", Project.class, "xmlVersion");
74         xstream.aliasField("Areas", Project.class, "areas");
75         xstream.aliasField("Timeclocks", Project.class, "timeclocks");
76         xstream.aliasField("GreenModes", Project.class, "greenmodes");
77
78         xstream.alias("Area", Area.class);
79         xstream.aliasField("Name", Area.class, "name");
80         xstream.useAttributeFor(Area.class, "name");
81         xstream.aliasField("IntegrationID", Area.class, "integrationId");
82         xstream.useAttributeFor(Area.class, "integrationId");
83         xstream.aliasField("DeviceGroups", Area.class, "deviceNodes");
84         xstream.aliasField("Outputs", Area.class, "outputs");
85         xstream.aliasField("Areas", Area.class, "areas");
86
87         xstream.alias("DeviceGroup", DeviceGroup.class);
88         xstream.aliasField("Name", DeviceGroup.class, "name");
89         xstream.useAttributeFor(DeviceGroup.class, "name");
90         xstream.aliasField("Devices", DeviceGroup.class, "devices");
91
92         xstream.alias("Device", Device.class);
93         xstream.aliasField("Name", Device.class, "name");
94         xstream.useAttributeFor(Device.class, "name");
95         xstream.aliasField("IntegrationID", Device.class, "integrationId");
96         xstream.useAttributeFor(Device.class, "integrationId");
97         xstream.aliasField("DeviceType", Device.class, "type");
98         xstream.useAttributeFor(Device.class, "type");
99         xstream.aliasField("Components", Device.class, "components");
100
101         xstream.alias("Component", Component.class);
102         xstream.aliasField("ComponentNumber", Component.class, "componentNumber");
103         xstream.useAttributeFor(Component.class, "componentNumber");
104         xstream.aliasField("ComponentType", Component.class, "type");
105         xstream.useAttributeFor(Component.class, "type");
106
107         xstream.alias("Output", Output.class);
108         xstream.aliasField("Name", Output.class, "name");
109         xstream.useAttributeFor(Output.class, "name");
110         xstream.aliasField("IntegrationID", Output.class, "integrationId");
111         xstream.useAttributeFor(Output.class, "integrationId");
112         xstream.aliasField("OutputType", Output.class, "type");
113         xstream.useAttributeFor(Output.class, "type");
114
115         xstream.alias("Timeclock", Timeclock.class);
116         xstream.aliasField("Name", Timeclock.class, "name");
117         xstream.useAttributeFor(Timeclock.class, "name");
118         xstream.aliasField("IntegrationID", Timeclock.class, "integrationId");
119         xstream.useAttributeFor(Timeclock.class, "integrationId");
120
121         xstream.alias("GreenMode", GreenMode.class);
122         xstream.aliasField("Name", GreenMode.class, "name");
123         xstream.useAttributeFor(GreenMode.class, "name");
124         xstream.aliasField("IntegrationID", GreenMode.class, "integrationId");
125         xstream.useAttributeFor(GreenMode.class, "integrationId");
126
127         // This reader is only interested in device thing information and does not read
128         // everything contained in DbXmlInfo. Ignoring unknown elements also makes the
129         // binding more tolerant of potential future changes to the XML schema.
130         xstream.ignoreUnknownElements();
131     }
132
133     public @Nullable Project readFromXML(@Nullable URL xmlURL) throws ConversionException {
134         if (xmlURL != null) {
135             return (Project) xstream.fromXML(xmlURL);
136         }
137
138         return null;
139     }
140
141     public @Nullable Project readFromXML(@Nullable File xmlFile) throws ConversionException {
142         if (xmlFile != null) {
143             return (Project) xstream.fromXML(xmlFile);
144         }
145
146         return null;
147     }
148
149     public @Nullable Project readFromXML(@Nullable Reader xmlReader) throws ConversionException {
150         if (xmlReader != null) {
151             return (Project) xstream.fromXML(xmlReader);
152         }
153
154         return null;
155     }
156
157     public @Nullable Project readFromXML(@Nullable String xmlString) throws ConversionException {
158         if (xmlString != null) {
159             return (Project) xstream.fromXML(xmlString);
160         }
161
162         return null;
163     }
164 }