Implemented Leg generation from Race.xml format

- StreamedCourse now utilises StreamedCourseXMLReader as data source

#story[758]
main
cbt24 9 years ago
parent e89a269565
commit 1653003cf0

@ -14,44 +14,23 @@ import java.util.List;
* Created by jjg64 on 21/04/17. * Created by jjg64 on 21/04/17.
*/ */
public class StreamedCourse implements RaceDataSource { public class StreamedCourse implements RaceDataSource {
StreamedCourseXMLReader streamedCourseXMLReader = null; StreamedCourseXMLReader streamedCourseXMLReader;
BoatXMLReader boatXMLReader = null;
List<GPSCoordinate> boundary = new ArrayList<>(); List<GPSCoordinate> boundary = new ArrayList<>();
public StreamedCourse(StreamedCourseXMLReader streamedCourseXMLReader) { public StreamedCourse(StreamedCourseXMLReader streamedCourseXMLReader) {
this.streamedCourseXMLReader = streamedCourseXMLReader; this.streamedCourseXMLReader = streamedCourseXMLReader;
} }
public StreamedCourse(BoatXMLReader boatXMLReader) {
this.boatXMLReader = boatXMLReader;
}
public void setBoatXMLReader(BoatXMLReader boatXMLReader) {
this.boatXMLReader = boatXMLReader;
if (streamedCourseXMLReader != null) {
boatXMLReader.setParticipants(streamedCourseXMLReader.getParticipants());
boatXMLReader.read();
}
}
public void setStreamedCourseXMLReader(StreamedCourseXMLReader streamedCourseXMLReader) {
this.streamedCourseXMLReader = streamedCourseXMLReader;
if (streamedCourseXMLReader != null) {
boatXMLReader.setParticipants(streamedCourseXMLReader.getParticipants());
boatXMLReader.read();
}
}
public List<BoatInRace> getBoats() { public List<BoatInRace> getBoats() {
return null; return null;
} }
public List<Leg> getLegs() { public List<Leg> getLegs() {
return null; return streamedCourseXMLReader.getLegs();
} }
public List<GPSCoordinate> getBoundary() { public List<GPSCoordinate> getBoundary() {
return null; return streamedCourseXMLReader.getBoundary();
} }
public ZonedDateTime getZonedDateTime() { public ZonedDateTime getZonedDateTime() {
@ -59,10 +38,13 @@ public class StreamedCourse implements RaceDataSource {
} }
public GPSCoordinate getMapTopLeft() { public GPSCoordinate getMapTopLeft() {
return null; return streamedCourseXMLReader.getMapTopLeft();
} }
public GPSCoordinate getMapBottomRight() { public GPSCoordinate getMapBottomRight() {
return null; return streamedCourseXMLReader.getMapBottomRight();
} }
} }

@ -0,0 +1,7 @@
package seng302.Mock;
/**
* Created by cbt24 on 25/04/17.
*/
public class StreamedCourseXMLException extends Throwable {
}

@ -3,8 +3,11 @@ package seng302.Mock;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import seng302.GPSCoordinate; import seng302.GPSCoordinate;
import seng302.Model.Leg;
import seng302.Model.Marker;
import seng302.XMLReader; import seng302.XMLReader;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
@ -21,7 +24,8 @@ public class StreamedCourseXMLReader extends XMLReader {
private static double COORDINATEPADDING = 0.0005; private static double COORDINATEPADDING = 0.0005;
private GPSCoordinate mapTopLeft, mapBottomRight; private GPSCoordinate mapTopLeft, mapBottomRight;
private List<GPSCoordinate> boundary = new ArrayList<>(); private List<GPSCoordinate> boundary = new ArrayList<>();
private Map<Integer, StreamedBoat> participants = new HashMap<>(); private Map<Integer,Element> marks = new HashMap<>();
private List<Leg> legs = new ArrayList<>();
Date creationTimeDate; Date creationTimeDate;
Date raceStartTime; Date raceStartTime;
int raceID; int raceID;
@ -35,7 +39,7 @@ public class StreamedCourseXMLReader extends XMLReader {
* @throws SAXException error * @throws SAXException error
* @throws ParserConfigurationException error * @throws ParserConfigurationException error
*/ */
public StreamedCourseXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException, ParseException { public StreamedCourseXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException, ParseException, StreamedCourseXMLException {
this(filePath, true); this(filePath, true);
} }
@ -47,14 +51,14 @@ public class StreamedCourseXMLReader extends XMLReader {
* @throws SAXException error * @throws SAXException error
* @throws ParserConfigurationException error * @throws ParserConfigurationException error
*/ */
public StreamedCourseXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException, ParseException { public StreamedCourseXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException, ParseException, StreamedCourseXMLException {
super(filePath); super(filePath);
if (read) { if (read) {
read(); read();
} }
} }
private void read() throws ParseException { private void read() throws ParseException, StreamedCourseXMLException {
readRace(); readRace();
readParticipants(); readParticipants();
readCourse(); readCourse();
@ -73,32 +77,90 @@ public class StreamedCourseXMLReader extends XMLReader {
} }
private void readParticipants() { private void readParticipants() {
Element nParticipants = (Element) doc.getElementsByTagName("Participants").item(0); //TODO Modify BoatInRace to take in a sourceID
for (int i = 0; i < nParticipants.getChildNodes().getLength(); i++) { //TODO Produce list of BoatInRace
int sourceID;
Node yacht = nParticipants.getChildNodes().item(i);
if (yacht.getNodeName().equals("Yacht")) {
if (exists(yacht, "SourceID")) {
sourceID = Integer.parseInt(yacht.getAttributes().getNamedItem("SourceID").getTextContent());
participants.put(sourceID, new StreamedBoat(sourceID));
}
}
}
} }
private void readCourse() { private void readCourse() throws StreamedCourseXMLException {
readCompoundMarks(); readCompoundMarks();
readCompoundMarkSequence(); readCompoundMarkSequence();
readCourseLimit(); readCourseLimit();
} }
/**
* Indexes CompoundMark elements by their ID for use in generating the course.
*/
private void readCompoundMarks() { private void readCompoundMarks() {
// TODO Produce map of sequence id to compound mark nodes (in xml) Element nCourse = (Element) doc.getElementsByTagName("Course").item(0);
// TODO Populate list of markers for(int i = 0; i < nCourse.getChildNodes().getLength(); i++) {
Node compoundMark = nCourse.getChildNodes().item(i);
if(compoundMark.getNodeName().equals("CompoundMark")) {
marks.put(getCompoundMarkID((Element)compoundMark),(Element)compoundMark);
}
}
} }
private void readCompoundMarkSequence() { /**
// TODO Produce list of legs according to mark sequence ids * Generates a Marker from the CompoundMark element with given ID.
* @param compoundMarkID index of required CompoundMark element
* @return generated Marker
* @throws StreamedCourseXMLException if CompoundMark element contains unhandled number of marks
* @see seng302.Model.Marker
*/
private Marker getMarker(int compoundMarkID) throws StreamedCourseXMLException {
Element compoundMark = marks.get(compoundMarkID);
NodeList nMarks = compoundMark.getElementsByTagName("Mark");
Marker marker;
switch(nMarks.getLength()) {
case 1: marker = new Marker(getCoordinate((Element)nMarks.item(0))); break;
case 2: marker = new Marker(getCoordinate((Element)nMarks.item(0)), getCoordinate((Element)nMarks.item(1))); break;
default: throw new StreamedCourseXMLException();
}
return marker;
}
private GPSCoordinate getCoordinate(Element mark) {
double lat = Double.parseDouble(mark.getAttribute("TargetLat"));
double lon = Double.parseDouble(mark.getAttribute("TargetLng"));
return new GPSCoordinate(lat,lon);
}
/**
* Reads "compoundMarkID" attribute of CompoundMark or Corner element
* @param element with "compoundMarkID" attribute
* @return value of "compoundMarkID" attribute
*/
private int getCompoundMarkID(Element element) {
return Integer.parseInt(element.getAttribute("CompoundMarkID"));
}
/**
* Reads "name" attribute of CompoundMark element with corresponding CompoundMarkID
* @param compoundMarkID unique ID for CompoundMark element
* @return value of "name" attribute
*/
private String getCompoundMarkName(int compoundMarkID) {
return marks.get(compoundMarkID).getAttribute("Name");
}
/**
* Populates list of legs given CompoundMarkSequence element and referenced CompoundMark elements.
* @throws StreamedCourseXMLException if markers cannot be resolved from CompoundMark
*/
private void readCompoundMarkSequence() throws StreamedCourseXMLException {
Element nCompoundMarkSequence = (Element) doc.getElementsByTagName("CompoundMarkSequence").item(0);
NodeList nCorners = nCompoundMarkSequence.getElementsByTagName("Corner");
Marker lastMarker = getMarker(getCompoundMarkID((Element)nCorners.item(0)));
String legName = getCompoundMarkName(getCompoundMarkID((Element)nCorners.item(0)));
for(int i = 1; i < nCorners.getLength(); i++) {
Element markXML = (Element)nCorners.item(i);
Marker currentMarker = getMarker(getCompoundMarkID(markXML));
legs.add(new Leg(legName, lastMarker, currentMarker, i-1));
lastMarker = currentMarker;
legName = getCompoundMarkName(getCompoundMarkID(markXML));
}
} }
private void readCourseLimit() { private void readCourseLimit() {
@ -133,6 +195,10 @@ public class StreamedCourseXMLReader extends XMLReader {
return mapBottomRight; return mapBottomRight;
} }
public List<Leg> getLegs() {
return legs;
}
public Double getPadding() { public Double getPadding() {
return COORDINATEPADDING; return COORDINATEPADDING;
} }
@ -156,8 +222,4 @@ public class StreamedCourseXMLReader extends XMLReader {
public boolean isPostpone() { public boolean isPostpone() {
return postpone; return postpone;
} }
public Map<Integer, StreamedBoat> getParticipants() {
return participants;
}
} }

@ -3,12 +3,11 @@ package seng302.Mock;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import seng302.GPSCoordinate; import seng302.GPSCoordinate;
import seng302.Model.Leg;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
/** /**
@ -26,6 +25,8 @@ public class StreamedRaceTest {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
//fail("Cannot find mockXML/raceXML/raceTest.xml in the resources folder"); //fail("Cannot find mockXML/raceXML/raceTest.xml in the resources folder");
} catch (StreamedCourseXMLException e) {
e.printStackTrace();
} }
} }
@ -59,9 +60,19 @@ public class StreamedRaceTest {
} }
@Test @Test
public void testParticipants() { public void testRaceSettings() {
Map<Integer, StreamedBoat> participants = streamedCourseXMLReader.getParticipants();
assertTrue(participants.containsKey(107)); }
assertTrue(participants.containsKey(108));
@Test
public void correctLegSequence() {
List<Leg> legs = streamedCourseXMLReader.getLegs();
String[] expectedNames = {
"StartLine",
"M1",
"M2",
"Gate"
};
for(int i = 0; i < legs.size(); i++) assertEquals(expectedNames[i], legs.get(i).getName());
} }
} }

Loading…
Cancel
Save