From 879de9869b563ff883879738b28326573d7fe921 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 27 Mar 2017 02:09:59 +1300 Subject: [PATCH] Implemented XML Reader -XMLReader class for generic XML Reading Created - RaceXML Reader class made specifically for reading races - RaceController COnstants now replced with XML file #implement --- .idea/copyright/profiles_settings.xml | 3 + .../seng302/Controllers/RaceController.java | 22 ++- src/main/java/seng302/RaceXMLReader.java | 165 ++++++++++++++++++ src/main/java/seng302/XMLReader.java | 36 ++++ src/test/java/seng302/Model/RaceXMLTest.java | 66 +++++++ 5 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 src/main/java/seng302/RaceXMLReader.java create mode 100644 src/main/java/seng302/XMLReader.java create mode 100644 src/test/java/seng302/Model/RaceXMLTest.java diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..e7bedf33 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/main/java/seng302/Controllers/RaceController.java b/src/main/java/seng302/Controllers/RaceController.java index 066a4e44..2405a105 100644 --- a/src/main/java/seng302/Controllers/RaceController.java +++ b/src/main/java/seng302/Controllers/RaceController.java @@ -15,9 +15,13 @@ import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.layout.GridPane; import javafx.util.Callback; +import org.xml.sax.SAXException; import seng302.Constants; import seng302.Model.*; +import seng302.RaceXMLReader; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.ResourceBundle; @@ -126,7 +130,20 @@ public class RaceController extends Controller{ * @param scaleFactor */ private void startRace(int scaleFactor) { - BoatInRace[] boats = generateAC35Competitors(); + RaceXMLReader raceXMLReader = null; + try { + raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml"); + } catch (IOException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + BoatInRace[] boats = new BoatInRace[raceXMLReader.getBoats().size()]; + boats = raceXMLReader.getBoats().toArray(boats); + //BoatInRace[] boats = generateAC35Competitors(); + raceMap = new ResizableRaceCanvas(); raceMap.setMouseTransparent(true); raceMap.widthProperty().bind(canvasBase.widthProperty()); @@ -139,7 +156,8 @@ public class RaceController extends Controller{ startScreen.setVisible(false); ongoingRacePane.setVisible(true); - ArrayList legs = generateBermudaCourseLegs(); + //ArrayList legs = generateBermudaCourseLegs(); + ArrayList legs = raceXMLReader.getLegs(); ConstantVelocityRace race = new ConstantVelocityRace(boats, legs, this, scaleFactor); showFPS.setVisible(true); diff --git a/src/main/java/seng302/RaceXMLReader.java b/src/main/java/seng302/RaceXMLReader.java new file mode 100644 index 00000000..746e48f5 --- /dev/null +++ b/src/main/java/seng302/RaceXMLReader.java @@ -0,0 +1,165 @@ +package seng302; + +import javafx.scene.paint.Color; +import org.w3c.dom.*; +import org.xml.sax.SAXException; +import seng302.Model.Boat; +import seng302.Model.BoatInRace; +import seng302.Model.Leg; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.util.ArrayList; + +/** + * Created by fwy13 on 26/03/2017. + */ +public class RaceXMLReader extends XMLReader{ + private ArrayList boats = new ArrayList<>(); + private Color[] colors = {Color.BLUEVIOLET, Color.BLACK, Color.RED, Color.ORANGE, Color.DARKOLIVEGREEN, Color.LIMEGREEN};//TODO make this established in xml or come up with a better system. + private ArrayList legs = new ArrayList<>(); + private GPSCoordinate mark, startPt1, startPt2, finishPt1, finishPt2, leewardPt1, leewardPt2, windwardPt1, windwardPt2; + private ArrayList boundary = new ArrayList<>(); + + + public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { + this(filePath, true); + } + + public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { + super(filePath); + if (read) { + read(); + } + } + + private void read(){ + readCourse(); + readBoats(); + readLegs(); + } + + public void readBoats(){ + //get all boats + NodeList nBoats = doc.getElementsByTagName("boat"); + + for (int i = 0; i < nBoats.getLength(); i++){ + String name = getTextValueOfNode((Element) nBoats.item(i), "name"); + String abbrev = getTextValueOfNode((Element) nBoats.item(i), "abbr"); + double velo = Double.parseDouble(getTextValueOfNode((Element) nBoats.item(i), "speed")); + //System.out.println(String.format("%s, %s, %s",name, abbrev, velo)); + BoatInRace boat = new BoatInRace(name, velo, colors[i], abbrev); + boat.setCurrentPosition(startPt1); + boats.add(boat); + } + } + + public void readLegs(){ + //get all legs + NodeList nLegs = doc.getElementsByTagName("leg"); + + for (int i = 0; i < nLegs.getLength(); i++){ + String label = getTextValueOfNode((Element) nLegs.item(i), "name"); + NodeList start = ((Element) nLegs.item(i)).getElementsByTagName("start"); + GPSCoordinate startCoord = getCoordinates(start); + NodeList finish = ((Element) nLegs.item(i)).getElementsByTagName("finish"); + GPSCoordinate finishCoord = getCoordinates(finish); + //System.out.println(String.format("%s, %s, %s, %s",label, startCoord, finishCoord, i)); + legs.add(new Leg(label, startCoord, finishCoord, i)); + } + } + + public void readCourse(){ + NodeList nCourse = doc.getElementsByTagName("course"); + + NodeList nBounds = ((Element)nCourse.item(0)).getElementsByTagName("boundaries"); + for (int i = 0; i < nBounds.getLength(); i++){ + boundary.add(getCoordinates(nBounds, i)); + } + + NodeList nMarks = ((Element)nCourse.item(0)).getElementsByTagName("marker"); + startPt1 = getCoordinates(nMarks, 0); + startPt2 = getCoordinates(nMarks, 0, 1); + mark = getCoordinates(nMarks, 1); + windwardPt1 = getCoordinates(nMarks, 2); + windwardPt2 = getCoordinates(nMarks, 2, 1); + leewardPt1 = getCoordinates(nMarks, 3); + leewardPt2 = getCoordinates(nMarks, 3, 1); + finishPt1 = getCoordinates(nMarks, 4); + finishPt2 = getCoordinates(nMarks, 4, 1); + } + + private GPSCoordinate getCoordinates(NodeList start){ + return getCoordinates(start, 0); + } + + private GPSCoordinate getCoordinates(NodeList start, int startIndex){ + return getCoordinates(start, startIndex, 0); + } + + private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex){ + NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("coordinate"); + Element coord = (Element) nodeList.item(nodeIndex); + return getCoordinates(coord); + } + + /** + * Returns the coordinate TODO raise exception that runs when the XML is formatted wrongly. + * @param coordNode + * @return + */ + private GPSCoordinate getCoordinates(Element coordNode){ + + double startLat = Double.parseDouble(getTextValueOfNode(coordNode, "latitude")); + double startLong = Double.parseDouble(getTextValueOfNode(coordNode, "longitude")); + return new GPSCoordinate(startLat, startLong); + } + + public ArrayList getBoats() { + return boats; + } + + public ArrayList getLegs() { + return legs; + } + + public GPSCoordinate getMark() { + return mark; + } + + public GPSCoordinate getStartPt1() { + return startPt1; + } + + public GPSCoordinate getStartPt2() { + return startPt2; + } + + public GPSCoordinate getFinishPt1() { + return finishPt1; + } + + public GPSCoordinate getFinishPt2() { + return finishPt2; + } + + public GPSCoordinate getLeewardPt1() { + return leewardPt1; + } + + public GPSCoordinate getLeewardPt2() { + return leewardPt2; + } + + public GPSCoordinate getWindwardPt1() { + return windwardPt1; + } + + public GPSCoordinate getWindwardPt2() { + return windwardPt2; + } + + public ArrayList getBoundary() { + return boundary; + } +} diff --git a/src/main/java/seng302/XMLReader.java b/src/main/java/seng302/XMLReader.java new file mode 100644 index 00000000..9f858a39 --- /dev/null +++ b/src/main/java/seng302/XMLReader.java @@ -0,0 +1,36 @@ +package seng302; + +import org.w3c.dom.*; +import org.xml.sax.SAXException; + +import javax.xml.parsers.*; +import java.io.*; + +/** + * Created by fwy13 on 26/03/2017. + */ +public abstract class XMLReader { + + protected Document doc; + + public XMLReader(String filePath) throws ParserConfigurationException, IOException, SAXException { + InputStream fXmlFile = getClass().getClassLoader().getResourceAsStream(filePath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(fXmlFile); + doc.getDocumentElement().normalize(); + } + + public Document getDocument(){ + return doc; + } + + public String getTextValueOfNode(Element n, String tagName) { + return n.getElementsByTagName(tagName).item(0).getTextContent(); + } + + public String getAttribute(Element n, String attr){ + return n.getAttribute(attr); + } + +} diff --git a/src/test/java/seng302/Model/RaceXMLTest.java b/src/test/java/seng302/Model/RaceXMLTest.java new file mode 100644 index 00000000..55070ef0 --- /dev/null +++ b/src/test/java/seng302/Model/RaceXMLTest.java @@ -0,0 +1,66 @@ +package seng302.Model;/** + * Created by Gondr on 26/03/2017. + */ + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.xml.sax.SAXException; +import seng302.RaceXMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; + +public class RaceXMLTest { + RaceXMLReader raceXMLReader; + + @Test + public void canFindFile(){ + try { + RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); + } catch (Exception e) { + fail("Cannot find raceXML/bermuda_AC35.xml in the resources folder"); + } + } + + @Test + public void canReadBoats(){ + try { + RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); + raceXMLReader.readBoats(); + } catch (Exception e) { + fail("Boat Unreadable"); + } + } + + @Test + public void canReadLegs(){ + try { + RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); + raceXMLReader.readLegs(); + } catch (Exception e) { + fail("Legs Unreadable"); + } + } + + @Test + public void canReadCourse(){ + try { + RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); + raceXMLReader.readCourse(); + System.out.println(raceXMLReader.getStartPt1()); + System.out.println(raceXMLReader.getStartPt2()); + System.out.println(raceXMLReader.getMark()); + System.out.println(raceXMLReader.getWindwardPt1()); + System.out.println(raceXMLReader.getWindwardPt2()); + System.out.println(raceXMLReader.getLeewardPt1()); + System.out.println(raceXMLReader.getLeewardPt2()); + System.out.println(raceXMLReader.getFinishPt1()); + System.out.println(raceXMLReader.getFinishPt2()); + } catch (Exception e) { + e.printStackTrace(); + fail("Course Unreadable"); + } + } + +} \ No newline at end of file