improved XML_Handler with documentation and style improvements

This commit is contained in:
paul-loedige 2020-12-26 12:41:49 +01:00
parent 180980f1f3
commit 10d406f714

View File

@ -10,7 +10,6 @@ import org.xml.sax.SAXException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Documented;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Dictionary; import java.util.Dictionary;
import java.util.Hashtable; import java.util.Hashtable;
@ -26,30 +25,28 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import kotlin.NotImplementedError; import kotlin.NotImplementedError;
public class XMLHandler implements IXML{ public class XMLHandler implements IXML {
/** the root of the XMl file **/ /** the root of the XMl file. **/
private Document root; private Document root;
/** /**
* constructor for the XMLHandler * constructor for the XMLHandler.
* @param xmlPath the path to the XML file * @param xmlPath the path to the XML file
* @param xsdPath the path to the XSD file * @param xsdPath the path to the XSD file
* @throws ParserConfigurationException the XML parser configuration failed * @throws ParserConfigurationException the XML parser configuration failed
* @throws IOException the XML file could not be accessed * @throws IOException the XML file could not be accessed
* @throws SAXException the XML parse failed * @throws SAXException the XML parse failed
*/ */
public XMLHandler(String xmlPath, String xsdPath) public XMLHandler(final String xmlPath, final String xsdPath)
throws ParserConfigurationException, IOException, SAXException throws ParserConfigurationException, IOException, SAXException {
{ if (!validate(xmlPath, xsdPath)) {
if(!validate(xmlPath,xsdPath)){
throw new VerifyError("the XML file is invalid"); throw new VerifyError("the XML file is invalid");
} }
//parse the root document fromt the XML file //parse the root document fromt the XML file
@ -59,12 +56,12 @@ public class XMLHandler implements IXML{
} }
/** /**
* validates a XML file against a XSD file * validates a XML file against a XSD file.
* @param xmlPath the path to the XML file * @param xmlPath the path to the XML file
* @param xsdPath the path to the XSD file * @param xsdPath the path to the XSD file
* @return true if XML is valid * @return true if XML is valid
*/ */
private boolean validate(String xmlPath, String xsdPath){ private boolean validate(final String xmlPath, final String xsdPath) {
try { try {
SchemaFactory factory = SchemaFactory.newInstance( SchemaFactory factory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI XMLConstants.W3C_XML_SCHEMA_NS_URI
@ -72,10 +69,10 @@ public class XMLHandler implements IXML{
Schema schema = factory.newSchema(new File(xsdPath)); Schema schema = factory.newSchema(new File(xsdPath));
Validator validator = schema.newValidator(); Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(xmlPath))); validator.validate(new StreamSource(new File(xmlPath)));
}catch (IOException | SAXException e){ } catch (IOException | SAXException e) {
Log.e("XMLHandler", Log.e("XMLHandler",
"Error while validating the XML file" + "Error while validating the XML file"
e.getMessage()); + e.getMessage());
return false; return false;
} }
return true; return true;
@ -91,69 +88,97 @@ public class XMLHandler implements IXML{
throw new NotImplementedError(); throw new NotImplementedError();
} }
/**
* reads the device names from the XML file.
* @return the device names as a list of strings
*/
@Override @Override
public List<String> getDeviceNames() { public List<String> getDeviceNames() {
List<String> returnList = new ArrayList<>(); List<String> returnList = new ArrayList<>();
NodeList devices = root.getElementsByTagName("Device"); NodeList devices = root.getElementsByTagName("Device");
for(int i = 0; i < devices.getLength();i++){ for (int i = 0; i < devices.getLength(); i++) {
returnList.add(((Element) devices.item(i)).getAttribute("name")); returnList.add(((Element) devices.item(i)).getAttribute("name"));
} }
return returnList; return returnList;
} }
/**
* reads the value info from the XML file.
* @param deviceName the name of the relevant device
* @return the value info as a dictionary {'unit','type','Offset','Factor'}
*/
@Override @Override
public Dictionary<String, Object> getValueInfo(String deviceName) { public Dictionary<String, Object> getValueInfo(final String deviceName) {
Dictionary<String, Object> returnDictionary = new Hashtable<>(); Dictionary<String, Object> returnDictionary = new Hashtable<>();
XPathFactory xPathFactory = XPathFactory.newInstance(); XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath(); XPath xPath = xPathFactory.newXPath();
try{ try {
XPathExpression xPathExpression = xPath.compile("//Device[@name='" + deviceName + "']/ValueInfo"); XPathExpression xPathExpression = xPath.compile(
Element result = (Element) xPathExpression.evaluate(root, XPathConstants.NODE); "//Device[@name='" + deviceName + "']/ValueInfo");
returnDictionary.put("type",result.getAttribute("type")); Element result = (Element) xPathExpression.evaluate(
returnDictionary.put("unit",result.getAttribute("unit")); root, XPathConstants.NODE);
returnDictionary.put("type", result.getAttribute("type"));
returnDictionary.put("unit", result.getAttribute("unit"));
NodeList childNodes = result.getChildNodes(); NodeList childNodes = result.getChildNodes();
float offset = 0.0f; float offset = 0.0f;
float factor = 1.0f; float factor = 1.0f;
for(int i = 0; i < childNodes.getLength(); i++){ for (int i = 0; i < childNodes.getLength(); i++) {
switch (childNodes.item(i).getNodeName()){ switch (childNodes.item(i).getNodeName()) {
case "Offset": case "Offset":
offset = Float.parseFloat(childNodes.item(i).getTextContent()); offset = Float.parseFloat(childNodes.item(i)
.getTextContent());
break; break;
case "Factor": case "Factor":
factor = Float.parseFloat(childNodes.item(i).getTextContent()); factor = Float.parseFloat(childNodes.item(i)
.getTextContent());
break; break;
default: default:
break; break;
} }
} }
returnDictionary.put("offset",offset); returnDictionary.put("offset", offset);
returnDictionary.put("factor",factor); returnDictionary.put("factor", factor);
}catch (XPathExpressionException e){ } catch (XPathExpressionException e) {
Log.e("XMLHandler","the XPath for getting the value info has errors:" + e.getMessage()); Log.e(
"XMLHandler",
"the XPath for getting the value info has errors:"
+ e.getMessage()
);
} }
return returnDictionary; return returnDictionary;
} }
/**
* reads the port information from the XML file.
* @param deviceName the name of the relevant device
* @return the port information as a dictionary {'protocol','pins'}
*/
@Override @Override
public Dictionary<String, Object> getPort(String deviceName) { public Dictionary<String, Object> getPort(final String deviceName) {
Dictionary<String, Object> returnDictionary = new Hashtable<>(); Dictionary<String, Object> returnDictionary = new Hashtable<>();
XPathFactory xPathFactory = XPathFactory.newInstance(); XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath(); XPath xPath = xPathFactory.newXPath();
try{ try {
XPathExpression xPathExpression = xPath.compile("//Device[@name='" + deviceName + "']/Port"); XPathExpression xPathExpression = xPath.compile(
Element result = (Element) xPathExpression.evaluate(root, XPathConstants.NODE); "//Device[@name='" + deviceName + "']/Port");
returnDictionary.put("protocol",result.getAttribute("protocol")); Element result = (Element) xPathExpression.evaluate(
root, XPathConstants.NODE);
returnDictionary.put("protocol", result.getAttribute("protocol"));
NodeList childNodes = result.getChildNodes(); NodeList childNodes = result.getChildNodes();
List<String> pins = new ArrayList<>(); List<String> pins = new ArrayList<>();
for(int i = 0; i < childNodes.getLength(); i++){ for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i); Node childNode = childNodes.item(i);
if(childNode.getNodeName().equals("Pin")){ if (childNode.getNodeName().equals("Pin")) {
pins.add(childNode.getTextContent()); pins.add(childNode.getTextContent());
} }
} }
returnDictionary.put("pins",pins); returnDictionary.put("pins", pins);
}catch (XPathExpressionException e){ } catch (XPathExpressionException e) {
Log.e("XMLHandler","the XPath for getting the value info has errors:" + e.getMessage()); Log.e(
"XMLHandler",
"the XPath for getting the value info has errors:"
+ e.getMessage()
);
} }
return returnDictionary; return returnDictionary;
} }