]> git.basschouten.com Git - openhab-addons.git/blob
f8f31e61dc59913c798fc0b1149eb506f50df52d
[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.bosesoundtouch.internal;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.Objects;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.core.types.StateOption;
22
23 import com.google.gson.annotations.Expose;
24
25 /**
26  * The {@link ContentItem} class manages a ContentItem
27  *
28  * @author Christian Niessner - Initial contribution
29  * @author Thomas Traunbauer - Initial contribution
30  */
31 @NonNullByDefault
32 public class ContentItem {
33
34     private String source = "";
35     private @Nullable String sourceAccount;
36     private @Nullable String location;
37     private boolean presetable = false;
38     private @Nullable String itemName;
39     private int presetID = 0;
40     private @Nullable String containerArt;
41     @Expose
42     private final Map<String, String> additionalAttributes = new HashMap<>();
43
44     /**
45      * Returns true if this ContentItem is defined as Preset
46      *
47      * @return true if this ContentItem is defined as Preset
48      */
49     public boolean isPreset() {
50         if (presetable) {
51             return presetID > 0;
52         } else {
53             return false;
54         }
55     }
56
57     /**
58      * Returns true if all necessary stats are set
59      *
60      * @return true if all necessary stats are set
61      */
62     public boolean isValid() {
63         if (getOperationMode() == OperationModeType.STANDBY) {
64             return true;
65         } else {
66             String localItemName = itemName;
67             if (localItemName != null) {
68                 return !(localItemName.isEmpty() || source.isEmpty());
69             } else {
70                 return false;
71             }
72         }
73     }
74
75     /**
76      * Returns true if source, sourceAccount, location, itemName, and presetable are equal
77      *
78      * @return true if source, sourceAccount, location, itemName, and presetable are equal
79      */
80     @Override
81     public boolean equals(@Nullable Object obj) {
82         if (obj instanceof ContentItem other) {
83             return Objects.equals(other.source, this.source) || Objects.equals(other.sourceAccount, this.sourceAccount)
84                     || other.presetable == this.presetable || Objects.equals(other.location, this.location)
85                     || Objects.equals(other.itemName, this.itemName);
86         }
87         return super.equals(obj);
88     }
89
90     /**
91      * Returns the operation Mode, depending on the stats that are set
92      *
93      * @return the operation Mode, depending on the stats that are set
94      */
95     public OperationModeType getOperationMode() {
96         OperationModeType operationMode = OperationModeType.OTHER;
97         if ("".equals(source)) {
98             return OperationModeType.OTHER;
99         }
100         if (source.contains("PRODUCT")) {
101             String localSourceAccount = sourceAccount;
102             if (localSourceAccount != null) {
103                 if (localSourceAccount.contains("TV")) {
104                     operationMode = OperationModeType.TV;
105                 }
106                 if (localSourceAccount.contains("HDMI")) {
107                     operationMode = OperationModeType.HDMI1;
108                 }
109             }
110             return operationMode;
111         }
112         try {
113             operationMode = OperationModeType.valueOf(source);
114             return operationMode;
115         } catch (IllegalArgumentException iae) {
116             return OperationModeType.OTHER;
117         }
118     }
119
120     public void setSource(String source) {
121         this.source = source;
122     }
123
124     public void setSourceAccount(String sourceAccount) {
125         this.sourceAccount = sourceAccount;
126     }
127
128     public void setLocation(String location) {
129         this.location = location;
130     }
131
132     public void setItemName(String itemName) {
133         this.itemName = itemName;
134     }
135
136     public void setAdditionalAttribute(String name, String value) {
137         this.additionalAttributes.put(name, value);
138     }
139
140     public void setPresetable(boolean presetable) {
141         this.presetable = presetable;
142     }
143
144     public void setPresetID(int presetID) {
145         this.presetID = presetID;
146     }
147
148     public void setContainerArt(String containerArt) {
149         this.containerArt = containerArt;
150     }
151
152     public String getSource() {
153         return source;
154     }
155
156     public @Nullable String getSourceAccount() {
157         return sourceAccount;
158     }
159
160     public @Nullable String getLocation() {
161         return location;
162     }
163
164     public @Nullable String getItemName() {
165         return itemName;
166     }
167
168     public boolean isPresetable() {
169         return presetable;
170     }
171
172     public int getPresetID() {
173         return presetID;
174     }
175
176     public @Nullable String getContainerArt() {
177         return containerArt;
178     }
179
180     /**
181      * Simple method to escape XML special characters in String.
182      * There are five XML Special characters which needs to be escaped :
183      * & - &amp;
184      * < - &lt;
185      * > - &gt;
186      * " - &quot;
187      * ' - &apos;
188      */
189     private String escapeXml(String xml) {
190         xml = xml.replace("&", "&amp;");
191         xml = xml.replace("<", "&lt;");
192         xml = xml.replace(">", "&gt;");
193         xml = xml.replace("\"", "&quot;");
194         xml = xml.replace("'", "&apos;");
195         return xml;
196     }
197
198     /**
199      * Returns the XML Code that is needed to switch to this ContentItem
200      *
201      * @return the XML Code that is needed to switch to this ContentItem
202      */
203     public String generateXML() {
204         String xml;
205         switch (getOperationMode()) {
206             case BLUETOOTH:
207                 xml = "<ContentItem source=\"BLUETOOTH\"></ContentItem>";
208                 break;
209             case AUX:
210             case AUX1:
211             case AUX2:
212             case AUX3:
213                 xml = "<ContentItem source=\"AUX\" sourceAccount=\"" + sourceAccount + "\"></ContentItem>";
214                 break;
215             case TV:
216                 xml = "<ContentItem source=\"PRODUCT\" sourceAccount=\"TV\" isPresetable=\"false\" />";
217                 break;
218             case HDMI1:
219                 xml = "<ContentItem source=\"PRODUCT\" sourceAccount=\"HDMI_1\" isPresetable=\"false\" />";
220                 break;
221             default:
222                 StringBuilder sbXml = new StringBuilder("<ContentItem");
223
224                 sbXml.append(" source=\"").append(escapeXml(source)).append("\"");
225
226                 String localLocation = location;
227                 if (localLocation != null) {
228                     sbXml.append(" location=\"").append(escapeXml(localLocation)).append("\"");
229                 }
230                 String localSourceAccount = sourceAccount;
231                 if (localSourceAccount != null) {
232                     sbXml.append(" sourceAccount=\"").append(escapeXml(localSourceAccount)).append("\"");
233                 }
234                 sbXml.append(" isPresetable=\"").append(presetable).append("\"");
235                 for (Map.Entry<String, String> aae : additionalAttributes.entrySet()) {
236                     sbXml.append(" ").append(aae.getKey()).append("=\"").append(escapeXml(aae.getValue())).append("\"");
237                 }
238                 sbXml.append(">");
239                 if (itemName != null) {
240                     sbXml.append("<itemName>").append(itemName).append("</itemName>");
241                 }
242                 if (containerArt != null) {
243                     sbXml.append("<containerArt>").append(containerArt).append("</containerArt>");
244                 }
245                 sbXml.append("</ContentItem>");
246                 xml = sbXml.toString();
247                 break;
248         }
249         return xml;
250     }
251
252     public StateOption toStateOption() {
253         String stateOptionLabel = presetID + ": " + itemName;
254         return new StateOption(String.valueOf(presetID), stateOptionLabel);
255     }
256
257     @Override
258     public String toString() {
259         // if (presetID >= 1 && presetID <= 6) {
260         // StringBuilder buffer = new StringBuilder();
261         // buffer.append("PRESET_");
262         // buffer.append(presetID);
263         // return buffer.toString();
264         // }
265         String localString = itemName;
266         return (localString != null) ? localString : "";
267     }
268 }