From 0b2ef3de0012724a35b7610e2bdc61919be4a877 Mon Sep 17 00:00:00 2001 From: alistairjmcintyre Date: Sun, 30 Apr 2017 00:52:18 +1200 Subject: [PATCH] XML data types are done. Easily navigated for future use. Some documentation has been done, tests aren't yet completed just yet. #story[820] --- .../seng302/models/parsers/StreamParser.java | 22 ++- .../seng302/models/parsers/XMLParser.java | 138 ++++++++++++++++-- 2 files changed, 131 insertions(+), 29 deletions(-) diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index d3520cf6..2971e6fd 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -2,9 +2,6 @@ package seng302.models.parsers; 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; @@ -14,7 +11,8 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; /** * Created by kre39 on 23/04/17. @@ -110,9 +108,9 @@ public class StreamParser { } static void extractXmlMessage(StreamPacket packet){ - - byte[] payload = packet.getPayload(); - String xmlMessage = ""; + + byte[] payload = packet.getPayload(); //Raw Binary XML Message + String xmlMessage = ""; //Empty xmlMessage String to store XML in ByteArrayInputStream payloadStream = new ByteArrayInputStream(payload); @@ -129,21 +127,19 @@ public class StreamParser { while (payloadStream.available() > 0 && (currentChar = payloadStream.read()) != 0) { xmlMessage += (char)currentChar; } - if (xmlMessageSubType == 7) System.out.println(xmlMessage); //Create XML document Object DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); DocumentBuilder db = null; + Document doc = null; try { db = dbf.newDocumentBuilder(); - Document doc = db.parse(new InputSource(new StringReader(xmlMessage))); - if (xmlMessageSubType == 7) { - XMLParser x = new XMLParser(); - XMLParser.BoatXMLObject xr = x.createBoatXML(doc); - } + doc = db.parse(new InputSource(new StringReader(xmlMessage))); } catch (ParserConfigurationException|SAXException|IOException e) { e.printStackTrace(); } + // TODO: 30/04/2017 (ajm412) Figure out how this will tie into the backend of the visualiser now that the parsing is done. } private static void extractRaceStartStatus(StreamPacket packet){ diff --git a/src/main/java/seng302/models/parsers/XMLParser.java b/src/main/java/seng302/models/parsers/XMLParser.java index 03e1c3e2..aa9e3a46 100644 --- a/src/main/java/seng302/models/parsers/XMLParser.java +++ b/src/main/java/seng302/models/parsers/XMLParser.java @@ -1,57 +1,135 @@ package seng302.models.parsers; -import com.sun.org.apache.xpath.internal.SourceTree; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +/** + * Class to create an XML object from the XML Packet Messages. + */ class XMLParser { + /** + * Creates a Regatta XML Object from the data in a Regatta XML Message + * @param doc XML Document Object + * @return A new RegattaXMLObject from the input Document. + */ RegattaXMLObject createRegattaXML(Document doc) { return new RegattaXMLObject(doc); } + /** + * Creates a Race XML Object from the data in a Regatta XML Message + * @param doc XML Document Object + * @return A new RaceXMLObject from the input Document. + */ RaceXMLObject createRaceXML(Document doc) { return new RaceXMLObject(doc); } + /** + * Creates a Boat XML Object from the data in a Regatta XML Message + * @param doc XML Document Object + * @return A new BoatXMLObject from the input Document. + */ BoatXMLObject createBoatXML(Document doc) { return new BoatXMLObject(doc); } - // TODO: 29/04/17 ajm412: Data Validation here to return null if a tag somehow doesn't actually exist. + /** + * Returns the text content of a given child element tag, assuming it exists, as an Integer. + * @param ele Document Element with child elements. + * @param tag Tag to find in document elements child elements. + * @return Text content from tag if found, null otherwise. + */ private static Integer getElementInt(Element ele, String tag) { - return Integer.parseInt(ele.getElementsByTagName(tag).item(0).getTextContent()); + NodeList tagList = ele.getElementsByTagName(tag); + if (tagList.getLength() > 0) { + return Integer.parseInt(tagList.item(0).getTextContent()); + } else { + return null; + } } + /** + * Returns the text content of a given child element tag, assuming it exists, as an String. + * @param ele Document Element with child elements. + * @param tag Tag to find in document elements child elements. + * @return Text content from tag if found, null otherwise. + */ private static String getElementString(Element ele, String tag) { - return ele.getElementsByTagName(tag).item(0).getTextContent(); + NodeList tagList = ele.getElementsByTagName(tag); + if (tagList.getLength() > 0) { + return tagList.item(0).getTextContent(); + } else { + return null; + } } + /** + * Returns the text content of a given child element tag, assuming it exists, as a Double. + * @param ele Document Element with child elements. + * @param tag Tag to find in document elements child elements. + * @return Text content from tag if found, null otherwise. + */ private static Double getElementDouble(Element ele, String tag) { - return Double.parseDouble(ele.getElementsByTagName(tag).item(0).getTextContent()); + NodeList tagList = ele.getElementsByTagName(tag); + if (tagList.getLength() > 0) { + return Double.parseDouble(tagList.item(0).getTextContent()); + } else { + return null; + } } + /** + * Returns the text content of an attribute of a given Node, assuming it exists, as a String. + * @param n A node object that should have some attributes + * @param attr The attribute you want to get from the given node. + * @return The String representation of the text content of an attribute in the given node, else returns null. + */ private static String getNodeAttributeString(Node n, String attr) { - return n.getAttributes().getNamedItem(attr).getTextContent(); + Node attrItem = n.getAttributes().getNamedItem(attr); + if (attrItem != null) { + return attrItem.getTextContent(); + } else { + return null; + } } + /** + * Returns the text content of an attribute of a given Node, assuming it exists, as an Integer. + * @param n A node object that should have some attributes + * @param attr The attribute you want to get from the given node. + * @return The Integer representation of the text content of an attribute in the given node, else returns null. + */ private static Integer getNodeAttributeInt(Node n, String attr) { - return Integer.parseInt(n.getAttributes().getNamedItem(attr).getTextContent()); + Node attrItem = n.getAttributes().getNamedItem(attr); + if (attrItem != null) { + return Integer.parseInt(attrItem.getTextContent()); + } else { + return null; + } } + /** + * Returns the text content of an attribute of a given Node, assuming it exists, as a Double. + * @param n A node object that should have some attributes + * @param attr The attribute you want to get from the given node. + * @return The Double representation of the text content of an attribute in the given node, else returns null. + */ private static Double getNodeAttributeDouble(Node n, String attr) { - return Double.parseDouble(n.getAttributes().getNamedItem(attr).getTextContent()); + Node attrItem = n.getAttributes().getNamedItem(attr); + if (attrItem != null) { + return Double.parseDouble(attrItem.getTextContent()); + } else { + return null; + } } class RegattaXMLObject { - //Regatta Info private Integer regattaID; private String regattaName; @@ -60,6 +138,11 @@ class XMLParser { private Double centralLng; private Integer utcOffset; + /** + * Constructor for a RegattaXMLObject. + * Takes the information from a Document object and creates a more usable format. + * @param doc XML Document Object + */ RegattaXMLObject(Document doc) { Element docEle = doc.getDocumentElement(); @@ -97,6 +180,11 @@ class XMLParser { ArrayList compoundMarkSequence; ArrayList courseLimit; + /** + * Constructor for a RaceXMLObject. + * Takes the information from a Document object and creates a more usable format. + * @param doc XML Document Object + */ RaceXMLObject(Document doc) { Element docEle = doc.getDocumentElement(); participants = new ArrayList<>(); @@ -230,7 +318,6 @@ class XMLParser { this.compoundMarkID = getNodeAttributeInt(cornerNode, "CompoundMarkID"); this.rounding = getNodeAttributeString(cornerNode, "Rounding"); this.zoneSize = getNodeAttributeInt(cornerNode, "ZoneSize"); - } public Integer getSeqID() { return seqID; } @@ -273,6 +360,11 @@ class XMLParser { //Boats ArrayList boats; + /** + * Constructor for a BoatXMLObject. + * Takes the information from a Document object and creates a more usable format. + * @param doc XML Document Object + */ BoatXMLObject(Document doc) { Element docEle = doc.getDocumentElement(); @@ -294,6 +386,17 @@ class XMLParser { this.zoneLimits.add(getNodeAttributeDouble(zoneLimitsList, tag)); } + this.boats = new ArrayList<>(); + NodeList boatsList = docEle.getElementsByTagName("Boats").item(0).getChildNodes(); + for (int i = 0; i < boatsList.getLength(); i++) { + Node currentBoat = boatsList.item(i); + if (currentBoat.getNodeName().equals("Boat")) { + Boat boat = new Boat(currentBoat); + this.boats.add(boat); + } + //System.out.println(this.getBoats()); + } + } public String getLastModified() { return lastModified; } @@ -314,10 +417,14 @@ class XMLParser { private String shortName; private String boatName; private String country; - private String skipper; Boat(Node boatNode) { - // TODO: 29/04/17 Actually build the boats. + this.boatType = getNodeAttributeString(boatNode, "Type"); + this.sourceID = getNodeAttributeInt(boatNode, "SourceID"); + this.hullID = getNodeAttributeString(boatNode, "HullNum"); + this.shortName = getNodeAttributeString(boatNode, "ShortName"); + this.boatName = getNodeAttributeString(boatNode, "BoatName"); + this.country = getNodeAttributeString(boatNode, "Country"); } public String getBoatType() { return boatType; } @@ -326,7 +433,6 @@ class XMLParser { public String getShortName() { return shortName; } public String getBoatName() { return boatName; } public String getCountry() { return country; } - public String getSkipper() { return skipper; } }