/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.frontiersiliconradio.internal; import java.io.IOException; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * This class hold the result of a request read from the radio. Upon a request the radio returns a XML document like * this: * * <pre> * <xmp> * <fsapiResponse> <status>FS_OK</status> <value><u8>1</u8></value> </fsapiResponse> * </xmp> * </pre> * * This class parses this XML data and provides functions for reading and casting typical fields. * * @author Rainer Ostendorf * @author paphko * @since 1.7.0 * */ public class FrontierSiliconRadioApiResult { /** * XML structure holding the parsed response */ final Document xmlDoc; private static final Logger logger = LoggerFactory.getLogger(FrontierSiliconRadioConnection.class); /** * Create result object from XML that was received from the radio. * * @param requestResultString * The XML string received from the radio. */ public FrontierSiliconRadioApiResult(String requestResultString) { Document xml = null; try { xml = getXmlDocFromString(requestResultString); } catch (Exception e) { logger.error("converting to XML failed: '" + requestResultString + "' with " + e.getClass().getName() + ": " + e.getMessage()); } xmlDoc = xml; } /** * Extract the field "status" from the result and return it * * @return result field as string. */ private String getStatus() { final Element fsApiResult = (Element) xmlDoc.getElementsByTagName("fsapiResponse").item(0); final Element statusNode = (Element) fsApiResult.getElementsByTagName("status").item(0); final String status = getCharacterDataFromElement(statusNode); logger.trace("status is: " + status); return status; } /** * checks if the responses status code was "FS_OK" * * @return true if status is "FS_OK", false else */ public boolean isStatusOk() { return ("FS_OK").equals(getStatus()); } /** * read the <value><u8> field as boolean * * @return value.u8 field as bool */ public boolean getValueU8AsBoolean() { try { final Element fsApiResult = (Element) xmlDoc.getElementsByTagName("fsapiResponse").item(0); final Element valueNode = (Element) fsApiResult.getElementsByTagName("value").item(0); final Element u8Node = (Element) valueNode.getElementsByTagName("u8").item(0); final String value = getCharacterDataFromElement(u8Node); logger.trace("value is: " + value); return "1".equals(value); } catch (Exception e) { logger.error("getting Value.U8 failed with " + e.getClass().getName() + ": " + e.getMessage()); return false; } } /** * read the <value><u8> field as int * * @return value.u8 field as int */ public int getValueU8AsInt() { try { final Element fsApiResult = (Element) xmlDoc.getElementsByTagName("fsapiResponse").item(0); final Element valueNode = (Element) fsApiResult.getElementsByTagName("value").item(0); final Element u8Node = (Element) valueNode.getElementsByTagName("u8").item(0); final String value = getCharacterDataFromElement(u8Node); logger.trace("value is: " + value); return Integer.parseInt(value); } catch (Exception e) { logger.error("getting Value.U8 failed with " + e.getClass().getName() + ": " + e.getMessage()); return 0; } } /** * read the <value><u32> field as int * * @return value.u32 field as int */ public int getValueU32AsInt() { try { final Element fsApiResult = (Element) xmlDoc.getElementsByTagName("fsapiResponse").item(0); final Element valueNode = (Element) fsApiResult.getElementsByTagName("value").item(0); final Element u32Node = (Element) valueNode.getElementsByTagName("u32").item(0); final String value = getCharacterDataFromElement(u32Node); logger.trace("value is: " + value); return Integer.parseInt(value); } catch (Exception e) { logger.error("getting Value.U32 failed with " + e.getClass().getName() + ": " + e.getMessage()); return 0; } } /** * read the <value><c8_array> field as String * * @return value.c8_array field as String */ public String getValueC8ArrayAsString() { try { final Element fsApiResult = (Element) xmlDoc.getElementsByTagName("fsapiResponse").item(0); final Element valueNode = (Element) fsApiResult.getElementsByTagName("value").item(0); final Element c8Array = (Element) valueNode.getElementsByTagName("c8_array").item(0); final String value = getCharacterDataFromElement(c8Array); logger.trace("value is: " + value); return value; } catch (Exception e) { logger.error("getting Value.c8array failed with " + e.getClass().getName() + ": " + e.getMessage()); return ""; } } /** * read the <sessionId> field as String * * @return value of sessionId field */ public String getSessionId() { final NodeList sessionIdTagList = xmlDoc.getElementsByTagName("sessionId"); final String givenSessId = getCharacterDataFromElement((Element) sessionIdTagList.item(0)); return givenSessId; } /** * converts the string we got from the radio to a parsable XML document * * @param xmlString * the XML string read from the radio * @return the parsed XML document * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ private Document getXmlDocFromString(String xmlString) throws ParserConfigurationException, SAXException, IOException { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); final DocumentBuilder builder = factory.newDocumentBuilder(); final Document xmlDocument = builder.parse(new InputSource(new StringReader(xmlString))); return xmlDocument; } /** * convert the value of a given XML element to a string for further processing * * @param e * XML Element * @return the elements value converted to string */ private static String getCharacterDataFromElement(Element e) { final Node child = e.getFirstChild(); if (child instanceof CharacterData) { final CharacterData cd = (CharacterData) child; return cd.getData(); } return ""; } }