2 * Copyright (c) 2010-2022 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.bosesoundtouch.internal;
15 import java.io.IOException;
16 import java.io.StringReader;
17 import java.util.HashMap;
20 import org.openhab.binding.bosesoundtouch.internal.handler.BoseSoundTouchHandler;
21 import org.xml.sax.InputSource;
22 import org.xml.sax.SAXException;
23 import org.xml.sax.XMLReader;
24 import org.xml.sax.helpers.XMLReaderFactory;
27 * The {@link XMLResponseProcessor} class handles the XML mapping
29 * @author Christian Niessner - Initial contribution
30 * @author Thomas Traunbauer - Initial contribution
32 public class XMLResponseProcessor {
33 private BoseSoundTouchHandler handler;
35 private Map<XMLHandlerState, Map<String, XMLHandlerState>> stateSwitchingMap;
37 public XMLResponseProcessor(BoseSoundTouchHandler handler) {
38 this.handler = handler;
42 public void handleMessage(String msg) throws SAXException, IOException {
43 XMLReader reader = XMLReaderFactory.createXMLReader();
44 reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
45 reader.setContentHandler(new XMLResponseHandler(handler, stateSwitchingMap));
46 reader.parse(new InputSource(new StringReader(msg)));
49 // initializes our XML parsing state machine
51 stateSwitchingMap = new HashMap<>();
53 Map<String, XMLHandlerState> msgInitMap = new HashMap<>();
54 stateSwitchingMap.put(XMLHandlerState.INIT, msgInitMap);
55 msgInitMap.put("msg", XMLHandlerState.Msg);
56 msgInitMap.put("SoundTouchSdkInfo", XMLHandlerState.Unprocessed);
57 msgInitMap.put("userActivityUpdate", XMLHandlerState.Unprocessed); // ignored..
59 Map<String, XMLHandlerState> msgBodyMap = new HashMap<>();
60 stateSwitchingMap.put(XMLHandlerState.MsgBody, msgBodyMap);
61 msgBodyMap.put("info", XMLHandlerState.Info);
62 msgBodyMap.put("volume", XMLHandlerState.Volume);
63 msgBodyMap.put("presets", XMLHandlerState.Presets);
64 msgBodyMap.put("key", XMLHandlerState.Unprocessed); // only confirmation of our key presses...
65 msgBodyMap.put("status", XMLHandlerState.Unprocessed); // only confirmation of commands sent to device...
66 msgBodyMap.put("zone", XMLHandlerState.Zone); // only confirmation of our key presses...
67 msgBodyMap.put("bass", XMLHandlerState.Bass);
68 msgBodyMap.put("sources", XMLHandlerState.Sources);
69 msgBodyMap.put("bassCapabilities", XMLHandlerState.BassCapabilities);
70 msgBodyMap.put("group", XMLHandlerState.Group);
72 // info message states
73 Map<String, XMLHandlerState> infoMap = new HashMap<>();
74 stateSwitchingMap.put(XMLHandlerState.Info, infoMap);
75 infoMap.put("components", XMLHandlerState.Info);
76 infoMap.put("component", XMLHandlerState.Info);
77 infoMap.put("name", XMLHandlerState.InfoName);
78 infoMap.put("type", XMLHandlerState.InfoType);
79 infoMap.put("componentCategory", XMLHandlerState.Unprocessed);
80 infoMap.put("softwareVersion", XMLHandlerState.InfoFirmwareVersion);
81 infoMap.put("serialNumber", XMLHandlerState.Unprocessed);
82 infoMap.put("networkInfo", XMLHandlerState.Unprocessed);
83 infoMap.put("margeAccountUUID", XMLHandlerState.Unprocessed);
84 infoMap.put("margeURL", XMLHandlerState.Unprocessed);
85 infoMap.put("moduleType", XMLHandlerState.InfoModuleType);
86 infoMap.put("variant", XMLHandlerState.Unprocessed);
87 infoMap.put("variantMode", XMLHandlerState.Unprocessed);
88 infoMap.put("countryCode", XMLHandlerState.Unprocessed);
89 infoMap.put("regionCode", XMLHandlerState.Unprocessed);
91 Map<String, XMLHandlerState> updatesMap = new HashMap<>();
92 stateSwitchingMap.put(XMLHandlerState.Updates, updatesMap);
93 updatesMap.put("clockDisplayUpdated", XMLHandlerState.Unprocessed); // can we get anything useful of that?
94 updatesMap.put("connectionStateUpdated", XMLHandlerState.UnprocessedNoTextExpected);
95 updatesMap.put("infoUpdated", XMLHandlerState.Unprocessed);
96 updatesMap.put("nowPlayingUpdated", XMLHandlerState.MsgBody);
97 updatesMap.put("nowSelectionUpdated", XMLHandlerState.Unprocessed); // TODO this seems to be quite a useful info
98 // what is currently played..
99 updatesMap.put("recentsUpdated", XMLHandlerState.Unprocessed);
100 updatesMap.put("volumeUpdated", XMLHandlerState.MsgBody);
101 updatesMap.put("zoneUpdated", XMLHandlerState.ZoneUpdated); // just notifies but dosn't provide details
102 updatesMap.put("bassUpdated", XMLHandlerState.BassUpdated);
103 updatesMap.put("presetsUpdated", XMLHandlerState.MsgBody);
104 updatesMap.put("groupUpdated", XMLHandlerState.MsgBody);
106 Map<String, XMLHandlerState> volume = new HashMap<>();
107 stateSwitchingMap.put(XMLHandlerState.Volume, volume);
108 volume.put("targetvolume", XMLHandlerState.VolumeTarget);
109 volume.put("actualvolume", XMLHandlerState.VolumeActual);
110 volume.put("muteenabled", XMLHandlerState.VolumeMuteEnabled);
112 Map<String, XMLHandlerState> nowPlayingMap = new HashMap<>();
113 stateSwitchingMap.put(XMLHandlerState.NowPlaying, nowPlayingMap);
114 nowPlayingMap.put("album", XMLHandlerState.NowPlayingAlbum);
115 nowPlayingMap.put("art", XMLHandlerState.NowPlayingArt);
116 nowPlayingMap.put("artist", XMLHandlerState.NowPlayingArtist);
117 nowPlayingMap.put("ContentItem", XMLHandlerState.ContentItem);
118 nowPlayingMap.put("description", XMLHandlerState.NowPlayingDescription);
119 nowPlayingMap.put("playStatus", XMLHandlerState.NowPlayingPlayStatus);
120 nowPlayingMap.put("rateEnabled", XMLHandlerState.NowPlayingRateEnabled);
121 nowPlayingMap.put("skipEnabled", XMLHandlerState.NowPlayingSkipEnabled);
122 nowPlayingMap.put("skipPreviousEnabled", XMLHandlerState.NowPlayingSkipPreviousEnabled);
123 nowPlayingMap.put("stationLocation", XMLHandlerState.NowPlayingStationLocation);
124 nowPlayingMap.put("stationName", XMLHandlerState.NowPlayingStationName);
125 nowPlayingMap.put("track", XMLHandlerState.NowPlayingTrack);
126 nowPlayingMap.put("connectionStatusInfo", XMLHandlerState.Unprocessed); // TODO active when Source==Bluetooth
127 // TODO active when Source==Pandora and maybe also other sources - seems to be rating related
128 nowPlayingMap.put("time", XMLHandlerState.Unprocessed);
129 nowPlayingMap.put("rating", XMLHandlerState.Unprocessed);
130 nowPlayingMap.put("rateEnabled", XMLHandlerState.Unprocessed);
132 // ContentItem specifies a resource (that also could be bookmarked in a preset)
133 Map<String, XMLHandlerState> contentItemMap = new HashMap<>();
134 stateSwitchingMap.put(XMLHandlerState.ContentItem, contentItemMap);
135 contentItemMap.put("itemName", XMLHandlerState.ContentItemItemName);
136 contentItemMap.put("containerArt", XMLHandlerState.ContentItemContainerArt);
138 Map<String, XMLHandlerState> presetMap = new HashMap<>();
139 stateSwitchingMap.put(XMLHandlerState.Preset, presetMap);
140 presetMap.put("ContentItem", XMLHandlerState.ContentItem);
142 Map<String, XMLHandlerState> zoneMap = new HashMap<>();
143 stateSwitchingMap.put(XMLHandlerState.Zone, zoneMap);
144 zoneMap.put("member", XMLHandlerState.ZoneMember);
146 Map<String, XMLHandlerState> bassMap = new HashMap<>();
147 stateSwitchingMap.put(XMLHandlerState.Bass, bassMap);
148 bassMap.put("targetbass", XMLHandlerState.BassTarget);
149 bassMap.put("actualbass", XMLHandlerState.BassActual);
151 Map<String, XMLHandlerState> sourceMap = new HashMap<>();
152 stateSwitchingMap.put(XMLHandlerState.Sources, sourceMap);
154 Map<String, XMLHandlerState> bassCapabilitiesMap = new HashMap<>();
155 stateSwitchingMap.put(XMLHandlerState.BassCapabilities, bassCapabilitiesMap);
156 bassCapabilitiesMap.put("bassAvailable", XMLHandlerState.BassAvailable);
157 bassCapabilitiesMap.put("bassMin", XMLHandlerState.BassMin);
158 bassCapabilitiesMap.put("bassMax", XMLHandlerState.BassMax);
159 bassCapabilitiesMap.put("bassDefault", XMLHandlerState.BassDefault);
161 Map<String, XMLHandlerState> groupsMap = new HashMap<>();
162 stateSwitchingMap.put(XMLHandlerState.Group, groupsMap);
163 groupsMap.put("name", XMLHandlerState.GroupName);
164 groupsMap.put("masterDeviceId", XMLHandlerState.MasterDeviceId);
165 groupsMap.put("roles", XMLHandlerState.Unprocessed);
166 groupsMap.put("senderIPAddress", XMLHandlerState.Unprocessed);
167 groupsMap.put("status", XMLHandlerState.Unprocessed);
168 groupsMap.put("roles", XMLHandlerState.Unprocessed);
169 groupsMap.put("groupRole", XMLHandlerState.Unprocessed);
170 groupsMap.put("deviceId", XMLHandlerState.DeviceId);
171 groupsMap.put("role", XMLHandlerState.Unprocessed);
172 groupsMap.put("ipAddress", XMLHandlerState.DeviceIp);