mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[sonos] Fix warnings (#15708)
* Fix warnings * Fix discovery error logging for offline devices Fixes #6793 Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
792836d787
commit
0838b6555f
@ -22,7 +22,6 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.sonos.internal.handler.ZonePlayerHandler;
|
||||
import org.openhab.core.audio.AudioFormat;
|
||||
import org.openhab.core.audio.AudioHTTPServer;
|
||||
import org.openhab.core.audio.AudioSink;
|
||||
import org.openhab.core.audio.AudioSinkSync;
|
||||
import org.openhab.core.audio.AudioStream;
|
||||
import org.openhab.core.audio.FileAudioStream;
|
||||
@ -39,7 +38,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This makes a Sonos speaker to serve as an {@link AudioSink}-
|
||||
* This makes a Sonos speaker to serve as an {@link org.openhab.core.audio.AudioSink}-
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution and API
|
||||
* @author Christoph Weitkamp - Added getSupportedStreams() and UnsupportedAudioStreamException
|
||||
|
@ -25,6 +25,10 @@ import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.util.StringUtils;
|
||||
@ -33,9 +37,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* The {@link SonosXMLParser} is a class of helper functions
|
||||
@ -48,15 +50,18 @@ public class SonosXMLParser {
|
||||
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(SonosXMLParser.class);
|
||||
|
||||
private static final MessageFormat METADATA_FORMAT = new MessageFormat(
|
||||
"<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\" "
|
||||
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" "
|
||||
+ "xmlns:r=\"urn:schemas-rinconnetworks-com:metadata-1-0/\" "
|
||||
+ "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">"
|
||||
+ "<item id=\"{0}\" parentID=\"{1}\" restricted=\"true\">" + "<dc:title>{2}</dc:title>"
|
||||
+ "<upnp:class>{3}</upnp:class>"
|
||||
+ "<desc id=\"cdudn\" nameSpace=\"urn:schemas-rinconnetworks-com:metadata-1-0/\">" + "{4}</desc>"
|
||||
+ "</item></DIDL-Lite>");
|
||||
private static final String METADATA_FORMAT_PATTERN = """
|
||||
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" \
|
||||
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" \
|
||||
xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" \
|
||||
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">\
|
||||
<item id="{0}" parentID="{1}" restricted="true">\
|
||||
<dc:title>{2}</dc:title>\
|
||||
<upnp:class>{3}</upnp:class>\
|
||||
<desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">{4}</desc>\
|
||||
</item>\
|
||||
</DIDL-Lite>\
|
||||
""";
|
||||
|
||||
private enum Element {
|
||||
TITLE,
|
||||
@ -90,13 +95,11 @@ public class SonosXMLParser {
|
||||
public static List<SonosAlarm> getAlarmsFromStringResult(String xml) {
|
||||
AlarmHandler handler = new AlarmHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Could not parse Alarms from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse Alarms from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse Alarms from string '{}'", xml);
|
||||
}
|
||||
return handler.getAlarms();
|
||||
}
|
||||
@ -108,13 +111,11 @@ public class SonosXMLParser {
|
||||
public static List<SonosEntry> getEntriesFromString(String xml) {
|
||||
EntryHandler handler = new EntryHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Could not parse Entries from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse Entries from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse Entries from string '{}'", xml);
|
||||
}
|
||||
|
||||
return handler.getArtists();
|
||||
@ -127,18 +128,18 @@ public class SonosXMLParser {
|
||||
* @param xml
|
||||
* @return The value of the desc xml tag
|
||||
* @throws SAXException
|
||||
* @throws ParserConfigurationException
|
||||
*/
|
||||
public static @Nullable SonosResourceMetaData getResourceMetaData(String xml) throws SAXException {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
public static @Nullable SonosResourceMetaData getResourceMetaData(String xml)
|
||||
throws SAXException, ParserConfigurationException {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
ResourceMetaDataHandler handler = new ResourceMetaDataHandler();
|
||||
reader.setContentHandler(handler);
|
||||
try {
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Could not parse Resource MetaData from String '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse Resource MetaData from string '{}'", xml);
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException e) {
|
||||
LOGGER.warn("Could not parse Resource MetaData from string '{}'", xml);
|
||||
}
|
||||
return handler.getMetaData();
|
||||
}
|
||||
@ -150,14 +151,11 @@ public class SonosXMLParser {
|
||||
public static List<SonosZoneGroup> getZoneGroupFromXML(String xml) {
|
||||
ZoneGroupHandler handler = new ZoneGroupHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse ZoneGroup from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse ZoneGroup from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse ZoneGroup from string '{}'", xml);
|
||||
}
|
||||
|
||||
return handler.getGroups();
|
||||
@ -166,14 +164,11 @@ public class SonosXMLParser {
|
||||
public static List<String> getRadioTimeFromXML(String xml) {
|
||||
OpmlHandler handler = new OpmlHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse RadioTime from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse RadioTime from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse RadioTime from string '{}'", xml);
|
||||
}
|
||||
|
||||
return handler.getTextFields();
|
||||
@ -182,14 +177,11 @@ public class SonosXMLParser {
|
||||
public static Map<String, String> getRenderingControlFromXML(String xml) {
|
||||
RenderingControlEventHandler handler = new RenderingControlEventHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse Rendering Control from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse Rendering Control from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse Rendering Control from string '{}'", xml);
|
||||
}
|
||||
return handler.getChanges();
|
||||
}
|
||||
@ -197,14 +189,11 @@ public class SonosXMLParser {
|
||||
public static Map<String, String> getAVTransportFromXML(String xml) {
|
||||
AVTransportEventHandler handler = new AVTransportEventHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse AV Transport from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse AV Transport from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse AV Transport from string '{}'", xml);
|
||||
}
|
||||
return handler.getChanges();
|
||||
}
|
||||
@ -212,14 +201,11 @@ public class SonosXMLParser {
|
||||
public static SonosMetaData getMetaDataFromXML(String xml) {
|
||||
MetaDataHandler handler = new MetaDataHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse MetaData from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse MetaData from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse MetaData from string '{}'", xml);
|
||||
}
|
||||
|
||||
return handler.getMetaData();
|
||||
@ -228,14 +214,11 @@ public class SonosXMLParser {
|
||||
public static List<SonosMusicService> getMusicServicesFromXML(String xml) {
|
||||
MusicServiceHandler handler = new MusicServiceHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(handler);
|
||||
reader.parse(new InputSource(new StringReader(xml)));
|
||||
} catch (IOException e) {
|
||||
// This should never happen - we're not performing I/O!
|
||||
LOGGER.error("Could not parse music services from string '{}'", xml);
|
||||
} catch (SAXException s) {
|
||||
LOGGER.error("Could not parse music services from string '{}'", xml);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(new StringReader(xml)), handler);
|
||||
} catch (IOException | SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse music services from string '{}'", xml);
|
||||
}
|
||||
return handler.getServices();
|
||||
}
|
||||
@ -305,14 +288,14 @@ public class SonosXMLParser {
|
||||
if (curIgnore == null) {
|
||||
curIgnore = new ArrayList<>();
|
||||
curIgnore.add("DIDL-Lite");
|
||||
curIgnore.add("type");
|
||||
curIgnore.add("ordinal");
|
||||
curIgnore.add("description");
|
||||
curIgnore.add("r:type");
|
||||
curIgnore.add("r:ordinal");
|
||||
curIgnore.add("r:description");
|
||||
ignore = curIgnore;
|
||||
}
|
||||
|
||||
if (!curIgnore.contains(localName)) {
|
||||
LOGGER.debug("Did not recognise element named {}", localName);
|
||||
if (!curIgnore.contains(qName)) {
|
||||
LOGGER.debug("Did not recognise element named {}", qName);
|
||||
}
|
||||
element = null;
|
||||
break;
|
||||
@ -373,7 +356,7 @@ public class SonosXMLParser {
|
||||
if (!desc.toString().isEmpty()) {
|
||||
try {
|
||||
md = getResourceMetaData(desc.toString());
|
||||
} catch (SAXException ignore) {
|
||||
} catch (SAXException | ParserConfigurationException ignore) {
|
||||
LOGGER.debug("Failed to parse embeded", ignore);
|
||||
}
|
||||
}
|
||||
@ -715,13 +698,14 @@ public class SonosXMLParser {
|
||||
* The events are all of the form <qName val="value"/> so we can get all
|
||||
* the info we need from here.
|
||||
*/
|
||||
if (localName == null) {
|
||||
// this means that localName isn't defined in EventType, which is expected for some elements
|
||||
LOGGER.info("{} is not defined in EventType. ", localName);
|
||||
if (qName == null) {
|
||||
// this means that qName isn't defined in EventType, which is expected for some elements
|
||||
LOGGER.info("{} is not defined in EventType. ", qName);
|
||||
} else {
|
||||
String val = attributes == null ? null : attributes.getValue("val");
|
||||
if (val != null) {
|
||||
changes.put(localName, val);
|
||||
String key = qName.contains(":") ? qName.split(":")[1] : qName;
|
||||
changes.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -749,7 +733,7 @@ public class SonosXMLParser {
|
||||
@Override
|
||||
public void startElement(@Nullable String uri, @Nullable String localName, @Nullable String qName,
|
||||
@Nullable Attributes attributes) throws SAXException {
|
||||
String name = localName == null ? "" : localName;
|
||||
String name = qName == null ? "" : qName;
|
||||
switch (name) {
|
||||
case "item":
|
||||
currentElement = CurrentElement.item;
|
||||
@ -761,25 +745,25 @@ public class SonosXMLParser {
|
||||
case "res":
|
||||
currentElement = CurrentElement.res;
|
||||
break;
|
||||
case "streamContent":
|
||||
case "r:streamContent":
|
||||
currentElement = CurrentElement.streamContent;
|
||||
break;
|
||||
case "albumArtURI":
|
||||
case "upnp:albumArtURI":
|
||||
currentElement = CurrentElement.albumArtURI;
|
||||
break;
|
||||
case "title":
|
||||
case "dc:title":
|
||||
currentElement = CurrentElement.title;
|
||||
break;
|
||||
case "class":
|
||||
case "upnp:class":
|
||||
currentElement = CurrentElement.upnpClass;
|
||||
break;
|
||||
case "creator":
|
||||
case "dc:creator":
|
||||
currentElement = CurrentElement.creator;
|
||||
break;
|
||||
case "album":
|
||||
case "upnp:album":
|
||||
currentElement = CurrentElement.album;
|
||||
break;
|
||||
case "albumArtist":
|
||||
case "r:albumArtist":
|
||||
currentElement = CurrentElement.albumArtist;
|
||||
break;
|
||||
default:
|
||||
@ -928,15 +912,16 @@ public class SonosXMLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable String getRoomName(String descriptorXML) {
|
||||
public static @Nullable String getRoomName(URL descriptorURL) {
|
||||
RoomNameHandler roomNameHandler = new RoomNameHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(roomNameHandler);
|
||||
URL url = new URL(descriptorXML);
|
||||
reader.parse(new InputSource(url.openStream()));
|
||||
} catch (IOException | SAXException e) {
|
||||
LOGGER.error("Could not parse Sonos room name from string '{}'", descriptorXML);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(descriptorURL.openStream()), roomNameHandler);
|
||||
} catch (SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse Sonos room name from URL '{}'", descriptorURL);
|
||||
} catch (IOException e) {
|
||||
LOGGER.debug("Could not fetch descriptor XML from URL '{}': {}", descriptorURL, e.getMessage());
|
||||
}
|
||||
return roomNameHandler.getRoomName();
|
||||
}
|
||||
@ -949,7 +934,7 @@ public class SonosXMLParser {
|
||||
@Override
|
||||
public void startElement(@Nullable String uri, @Nullable String localName, @Nullable String qName,
|
||||
@Nullable Attributes attributes) throws SAXException {
|
||||
if ("roomName".equalsIgnoreCase(localName)) {
|
||||
if ("roomName".equalsIgnoreCase(qName)) {
|
||||
roomNameTag = true;
|
||||
}
|
||||
}
|
||||
@ -970,12 +955,13 @@ public class SonosXMLParser {
|
||||
public static @Nullable String parseModelDescription(URL descriptorURL) {
|
||||
ModelNameHandler modelNameHandler = new ModelNameHandler();
|
||||
try {
|
||||
XMLReader reader = XMLReaderFactory.createXMLReader();
|
||||
reader.setContentHandler(modelNameHandler);
|
||||
URL url = new URL(descriptorURL.toString());
|
||||
reader.parse(new InputSource(url.openStream()));
|
||||
} catch (IOException | SAXException e) {
|
||||
LOGGER.error("Could not parse Sonos model name from string '{}'", descriptorURL.toString());
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
saxParser.parse(new InputSource(descriptorURL.openStream()), modelNameHandler);
|
||||
} catch (SAXException | ParserConfigurationException e) {
|
||||
LOGGER.warn("Could not parse Sonos model name from URL '{}'", descriptorURL);
|
||||
} catch (IOException e) {
|
||||
LOGGER.debug("Could not fetch descriptor XML from URL '{}': {}", descriptorURL, e.getMessage());
|
||||
}
|
||||
return modelNameHandler.getModelName();
|
||||
}
|
||||
@ -988,7 +974,7 @@ public class SonosXMLParser {
|
||||
@Override
|
||||
public void startElement(@Nullable String uri, @Nullable String localName, @Nullable String qName,
|
||||
@Nullable Attributes attributes) throws SAXException {
|
||||
if ("modelName".equalsIgnoreCase(localName)) {
|
||||
if ("modelName".equalsIgnoreCase(qName)) {
|
||||
modelNameTag = true;
|
||||
}
|
||||
}
|
||||
@ -1079,8 +1065,6 @@ public class SonosXMLParser {
|
||||
|
||||
title = StringUtils.escapeXml(title);
|
||||
|
||||
String metadata = METADATA_FORMAT.format(new Object[] { id, parentId, title, upnpClass, desc });
|
||||
|
||||
return metadata;
|
||||
return new MessageFormat(METADATA_FORMAT_PATTERN).format(new Object[] { id, parentId, title, upnpClass, desc });
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,6 @@ public class ZonePlayerDiscoveryParticipant implements UpnpDiscoveryParticipant
|
||||
}
|
||||
|
||||
private @Nullable String getSonosRoomName(RemoteDevice device) {
|
||||
return SonosXMLParser.getRoomName(device.getIdentity().getDescriptorURL().toString());
|
||||
return SonosXMLParser.getRoomName(device.getIdentity().getDescriptorURL());
|
||||
}
|
||||
}
|
||||
|
@ -1689,11 +1689,12 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
||||
*/
|
||||
protected void saveState() {
|
||||
synchronized (stateLock) {
|
||||
savedState = new SonosZonePlayerState();
|
||||
String currentURI = getCurrentURI();
|
||||
|
||||
SonosZonePlayerState savedState = new SonosZonePlayerState();
|
||||
savedState.transportState = getTransportState();
|
||||
savedState.volume = getVolume();
|
||||
this.savedState = savedState;
|
||||
|
||||
String currentURI = getCurrentURI();
|
||||
|
||||
if (currentURI != null) {
|
||||
if (isPlayingStreamOrRadio(currentURI)) {
|
||||
@ -2523,7 +2524,6 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.CompareObjectsWithEquals")
|
||||
public boolean publicAddress(LineInType lineInType) {
|
||||
// check if sourcePlayer has a line-in connected
|
||||
if ((lineInType != LineInType.DIGITAL && isAnalogLineInConnected())
|
||||
@ -2536,7 +2536,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
||||
for (String player : group.getMembers()) {
|
||||
try {
|
||||
ZonePlayerHandler somePlayer = getHandlerByName(player);
|
||||
if (somePlayer != this) {
|
||||
if (!somePlayer.equals(this)) {
|
||||
somePlayer.becomeStandAlonePlayer();
|
||||
somePlayer.stop();
|
||||
addMember(StringType.valueOf(somePlayer.getUDN()));
|
||||
|
@ -79,4 +79,43 @@ public class SonosXMLParserTest {
|
||||
assertEquals("Paris, France", result.get(2));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetaDataFromXML() throws IOException {
|
||||
InputStream resourceStream = getClass().getResourceAsStream("/MetaData.xml");
|
||||
assertNotNull(resourceStream);
|
||||
final String xml = new String(resourceStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
SonosMetaData sonosMetaData = SonosXMLParser.getMetaDataFromXML(xml);
|
||||
assertEquals("-1", sonosMetaData.getId());
|
||||
assertEquals("-1", sonosMetaData.getParentId());
|
||||
assertEquals("Turn Down for What - Single", sonosMetaData.getAlbum());
|
||||
assertEquals("DJ Snake & Lil Jon", sonosMetaData.getCreator());
|
||||
assertEquals("Turn Down for What", sonosMetaData.getTitle());
|
||||
assertEquals("object.item.audioItem.musicTrack", sonosMetaData.getUpnpClass());
|
||||
assertEquals("x-sonosapi-hls-static:librarytrack%3ai.eoD8VQ5SZOB8QX7?sid=204&flags=8232&sn=9",
|
||||
sonosMetaData.getResource());
|
||||
assertEquals(
|
||||
"/getaa?s=1&u=x-sonosapi-hls-static%3alibrarytrack%253ai.eoD8VQ5SZOB8QX7%3fsid%3d204%26flags%3d8232%26sn%3d9",
|
||||
sonosMetaData.getAlbumArtUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compileMetadataString() {
|
||||
SonosEntry sonosEntry = new SonosEntry("1", "Can't Buy Me Love", "0", "A Hard Day's Night", "", "",
|
||||
"object.item.audioItem.musicTrack", "");
|
||||
String expected = """
|
||||
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" \
|
||||
xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" \
|
||||
xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" \
|
||||
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">\
|
||||
<item id="1" parentID="0" restricted="true">\
|
||||
<dc:title>Can't Buy Me Love</dc:title>\
|
||||
<upnp:class>object.item.audioItem.musicTrack</upnp:class>\
|
||||
<desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">RINCON_AssociatedZPUDN</desc>\
|
||||
</item>\
|
||||
</DIDL-Lite>\
|
||||
""";
|
||||
String actual = SonosXMLParser.compileMetadataString(sonosEntry);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="-1" parentID="-1" restricted="true"><res protocolInfo="sonos.com-http:*:application/x-mpegURL:*" duration="0:03:33">x-sonosapi-hls-static:librarytrack%3ai.eoD8VQ5SZOB8QX7?sid=204&flags=8232&sn=9</res><r:streamContent></r:streamContent><r:radioShowMd></r:radioShowMd><r:streamInfo>bd:16,sr:22050,c:3,l:0,d:0</r:streamInfo><upnp:albumArtURI>/getaa?s=1&u=x-sonosapi-hls-static%3alibrarytrack%253ai.eoD8VQ5SZOB8QX7%3fsid%3d204%26flags%3d8232%26sn%3d9</upnp:albumArtURI><dc:title>Turn Down for What</dc:title><upnp:class>object.item.audioItem.musicTrack</upnp:class><dc:creator>DJ Snake & Lil Jon</dc:creator><upnp:album>Turn Down for What - Single</upnp:album></item></DIDL-Lite>
|
Loading…
Reference in New Issue
Block a user