Made all the model classes extend off the schema xml classes for race, and made xml builder, validator and reader utility class.

#story[1092]
This commit is contained in:
Fan-Wu Yang
2017-08-14 03:47:42 +12:00
parent 70d5447e88
commit b5e414f97a
33 changed files with 477 additions and 5071 deletions
@@ -3,7 +3,6 @@ package mock.app;
import mock.dataInput.PolarParser;
import mock.model.MockRace;
import mock.model.Polars;
import mock.xml.Race;
import mock.xml.RaceXMLCreator;
import network.Messages.LatestMessages;
import org.xml.sax.SAXException;
@@ -14,6 +13,7 @@ import shared.exceptions.InvalidRaceDataException;
import shared.exceptions.InvalidRegattaDataException;
import shared.exceptions.XMLReaderException;
import shared.model.Constants;
import shared.xml.Race.XMLRace;
import shared.xml.XMLUtilities;
import javax.xml.bind.JAXBException;
@@ -22,8 +22,6 @@ import javax.xml.transform.TransformerException;
import java.io.*;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
/**
@@ -49,7 +47,7 @@ public class Event {
private Event() {
try {
try {
this.raceXML = getRaceXMLAtCurrentTime(RaceXMLCreator.alterRaceToWind("mock/mockXML/raceSchemaTest.xml", 90));
this.raceXML = RaceXMLCreator.alterRaceToWind("mock/mockXML/raceSchemaTest.xml", 90);
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
@@ -102,15 +100,16 @@ public class Event {
sendXMLs();
//Parse the XML files into data sources.
// RaceDataSource raceDataSource = new RaceXMLReader(this.raceXML, this.xmlFileType);
Race race = (Race) XMLUtilities.xmlToClass(raceXML,
RaceDataSource raceDataSource = new RaceXMLReader(this.raceXML, this.xmlFileType);
//more work here
XMLRace race = (XMLRace) XMLUtilities.xmlToClass(raceXML,
RaceXMLCreator.class.getClassLoader().getResource("mock/mockXML/schema/raceSchema.xsd"),
Race.class);
XMLRace.class);
BoatDataSource boatDataSource = new BoatXMLReader(this.boatXML, this.xmlFileType);
RegattaDataSource regattaDataSource = new RegattaXMLReader(this.regattaXML, this.xmlFileType);
//Create and start race.
MockRace newRace = new MockRace(boatDataSource, race, regattaDataSource, this.latestMessages, this.boatPolars, Constants.RaceTimeScale);
MockRace newRace = new MockRace(boatDataSource, raceDataSource, regattaDataSource, this.latestMessages, this.boatPolars, Constants.RaceTimeScale);
new Thread(newRace).start();
}
@@ -127,28 +126,5 @@ public class Event {
mockOutput.setBoatsXml(boatXML);
}
/**
* Sets the xml description of the race to show the race was created now, and starts in 4 minutes
* @param raceXML The race.xml contents.
* @return String containing edited xml
*/
private String getRaceXMLAtCurrentTime(String raceXML) {
//The start time is current time + 4 minutes. prestart is 3 minutes, and we add another minute.
long millisecondsToAdd = Constants.RacePreStartTime + (1 * 60 * 1000);
long secondsToAdd = millisecondsToAdd / 1000;
//Scale the time using our time scalar.
secondsToAdd = secondsToAdd / Constants.RaceTimeScale;
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
ZonedDateTime creationTime = ZonedDateTime.now();
raceXML = raceXML.replace("CREATION_TIME", dateFormat.format(creationTime));
raceXML = raceXML.replace("START_TIME", dateFormat.format(creationTime.plusSeconds(secondsToAdd)));
return raceXML;
}
}
@@ -90,7 +90,7 @@ public class MockRace extends Race {
* @param polars The polars table to be used for boat simulation.
* @param timeScale The timeScale for the race. See {@link Constants#RaceTimeScale}.
*/
public MockRace(BoatDataSource boatDataSource, mock.xml.Race raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages, Polars polars, int timeScale) {
public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages, Polars polars, int timeScale) {
super(boatDataSource, raceDataSource, regattaDataSource, latestMessages);
File diff suppressed because it is too large Load Diff
@@ -1,127 +0,0 @@
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2017.08.13 at 10:39:29 PM NZST
//
package mock.xml;
import javax.xml.bind.annotation.XmlRegistry;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the scd package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class RaceFactory {
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: scd
*
*/
public RaceFactory() {
}
/**
* Create an instance of {@link Race }
*
*/
public Race createRace() {
return new Race();
}
/**
* Create an instance of {@link Race.CourseLimit }
*
*/
public Race.CourseLimit createRaceCourseLimit() {
return new Race.CourseLimit();
}
/**
* Create an instance of {@link Race.Course }
*
*/
public Race.Course createRaceCourse() {
return new Race.Course();
}
/**
* Create an instance of {@link Race.Course.CompoundMark }
*
*/
public Race.Course.CompoundMark createRaceCourseCompoundMark() {
return new Race.Course.CompoundMark();
}
/**
* Create an instance of {@link Race.CompoundMarkSequence }
*
*/
public Race.CompoundMarkSequence createRaceCompoundMarkSequence() {
return new Race.CompoundMarkSequence();
}
/**
* Create an instance of {@link Race.Participants }
*
*/
public Race.Participants createRaceParticipants() {
return new Race.Participants();
}
/**
* Create an instance of {@link Race.RaceStartTime }
*
*/
public Race.RaceStartTime createRaceRaceStartTime() {
return new Race.RaceStartTime();
}
/**
* Create an instance of {@link Race.CourseLimit.Limit }
*
*/
public Race.CourseLimit.Limit createRaceCourseLimitLimit() {
return new Race.CourseLimit.Limit();
}
/**
* Create an instance of {@link Race.Course.CompoundMark.Mark }
*
*/
public Race.Course.CompoundMark.Mark createRaceCourseCompoundMarkMark() {
return new Race.Course.CompoundMark.Mark();
}
/**
* Create an instance of {@link Race.CompoundMarkSequence.Corner }
*
*/
public Race.CompoundMarkSequence.Corner createRaceCompoundMarkSequenceCorner() {
return new Race.CompoundMarkSequence.Corner();
}
/**
* Create an instance of {@link Race.Participants.Yacht }
*
*/
public Race.Participants.Yacht createRaceParticipantsYacht() {
return new Race.Participants.Yacht();
}
}
@@ -6,10 +6,8 @@ import shared.dataInput.RaceXMLReader;
import shared.enums.XMLFileType;
import shared.exceptions.InvalidRaceDataException;
import shared.exceptions.XMLReaderException;
import shared.model.CompoundMark;
import shared.model.Corner;
import shared.model.GPSCoordinate;
import shared.model.Mark;
import shared.model.*;
import shared.xml.Race.*;
import shared.xml.XMLUtilities;
import javax.xml.XMLConstants;
@@ -29,98 +27,16 @@ import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.net.URL;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
/**
* Helper Class for creating a Race XML
*/
public class RaceXMLCreator {
/**
* Copy the race to a mock.xml.Race class from a RaceXMlReader
* @param reader RaceXMlReader
* @return string of the new mock.xml.Race
* @throws InvalidRaceDataException If the reader is unable to be read
* @throws XMLReaderException If the reader is unable to be read
*/
public static Race copyRace(RaceXMLReader reader) throws InvalidRaceDataException, XMLReaderException {
RaceFactory raceFactory = new RaceFactory();
Race race = raceFactory.createRace();
race.setRaceID(String.valueOf(reader.getRaceId()));
race.setRaceType(String.valueOf(reader.getRaceType()));
race.setCreationTimeDate("CREATION_TIME");//this needs to be changed later
//Race Start Time
Race.RaceStartTime raceStartTime = raceFactory.createRaceRaceStartTime();
raceStartTime.setPostpone("false");
raceStartTime.setTime("START_TIME");//this needs to be changed later
race.setRaceStartTime(raceStartTime);
//Participants
Race.Participants participants = raceFactory.createRaceParticipants();
for (int i :reader.getParticipants()) {
Race.Participants.Yacht yacht = raceFactory.createRaceParticipantsYacht();
yacht.setSourceID(String.valueOf(i));
participants.getYacht().add(yacht); //java schema does not clone the array so this is "safe".
}
race.setParticipants(participants);
//compound marks sequence
Race.CompoundMarkSequence cms = raceFactory.createRaceCompoundMarkSequence();
for (Corner mark: reader.getCornersList()){
Race.CompoundMarkSequence.Corner corner = raceFactory.createRaceCompoundMarkSequenceCorner();
corner.setCompoundMarkID(String.valueOf(mark.getId()));
corner.setSeqID(String.valueOf(mark.getSeqID()));
cms.getCorner().add(corner);
}
race.setCompoundMarkSequence(cms);
//Course
Race.Course course = raceFactory.createRaceCourse();
for (CompoundMark mark: reader.getCompoundMarks()){
Race.Course.CompoundMark cm = raceFactory.createRaceCourseCompoundMark();
cm.setName(mark.getName());
cm.setCompoundMarkID(String.valueOf(mark.getId()));
cm.getMark().add(setMarkFromMark(raceFactory, mark.getMark1()));
Race.Course.CompoundMark.Mark m2 = setMarkFromMark(raceFactory, mark.getMark2());
if (m2 != null) {
cm.getMark().add(m2);
}
course.getCompoundMark().add(cm);
}
race.setCourse(course);
//Course Limit
Race.CourseLimit courseLimit = raceFactory.createRaceCourseLimit();
for (int i = 0; i < reader.getBoundary().size(); i++){
Race.CourseLimit.Limit limit = raceFactory.createRaceCourseLimitLimit();
limit.setSeqID(String.valueOf(i+1));
limit.setLat(String.valueOf(reader.getBoundary().get(i).getLatitude()));
limit.setLon(String.valueOf(reader.getBoundary().get(i).getLongitude()));
courseLimit.getLimit().add(limit);
}
race.setCourseLimit(courseLimit);
return race;
}
/**
* Sets a mock.xml.Mark from a shared.model.Mark
* @param raceFactory race Factory for creating mock.xml.Race classes and subclasses
* @param mark Mark to be converted.
* @return converted mock.xml.Mark.
*/
public static Race.Course.CompoundMark.Mark setMarkFromMark(RaceFactory raceFactory, Mark mark){
if (mark != null) {
Race.Course.CompoundMark.Mark m = raceFactory.createRaceCourseCompoundMarkMark();
m.setName(mark.getName());
m.setTargetLat(String.valueOf(mark.getPosition().getLatitude()));
m.setTargetLng(String.valueOf(mark.getPosition().getLongitude()));
m.setSourceID(String.valueOf(mark.getSourceID()));
return m;
}
return null;
}
/**
* get the windward gate in a race
@@ -158,9 +74,11 @@ public class RaceXMLCreator {
public static String alterRaceToWind(String s, double degrees) throws XMLReaderException, InvalidRaceDataException, JAXBException, IOException, SAXException, ParserConfigurationException {
RaceXMLReader reader = new RaceXMLReader(s, XMLFileType.ResourcePath);
Race race = (Race) XMLUtilities.xmlToClass(new File(RaceXMLCreator.class.getClassLoader().getResource(s).getFile()),
XMLRace race = (XMLRace) XMLUtilities.xmlToClass(new File(RaceXMLCreator.class.getClassLoader().getResource(s).getFile()),
RaceXMLCreator.class.getClassLoader().getResource("mock/mockXML/schema/raceSchema.xsd"),
Race.class);
XMLRace.class);
setRaceXMLAtCurrentTimeToNow(race);
double raceOriginalBearing = getLineAngle(getLeewardGate(reader).getMark1Position(), getWindwardGate(reader).getMark1Position());
@@ -168,7 +86,7 @@ public class RaceXMLCreator {
alterRaceRotation(race, degreesToRotate);
JAXBContext context = JAXBContext.newInstance(Race.class);
JAXBContext context = JAXBContext.newInstance(XMLRace.class);
Marshaller jaxbMarshaller = context.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
@@ -183,20 +101,20 @@ public class RaceXMLCreator {
* @param race the race to alter
* @param degrees the degrees to rotate by.
*/
public static void alterRaceRotation(Race race, double degrees){
public static void alterRaceRotation(XMLRace race, double degrees){
GPSCoordinate center = getCenter(race);
for(Race.CourseLimit.Limit limit: race.getCourseLimit().getLimit()){
for(XMLLimit limit: race.getCourseLimit().getLimit()){
GPSCoordinate rotatedLim = rotate(center, limitToGPSCoordinate(limit), degrees);
limit.setLat(String.valueOf(rotatedLim.getLatitude()));
limit.setLon(String.valueOf(rotatedLim.getLongitude()));
limit.setLat(rotatedLim.getLatitude());
limit.setLon(rotatedLim.getLongitude());
}
for(Race.Course.CompoundMark compoundMark: race.getCourse().getCompoundMark()){
for (Race.Course.CompoundMark.Mark mark: compoundMark.getMark()){
for(XMLCompoundMark compoundMark: race.getCourse().getCompoundMark()){
for (XMLMark mark: compoundMark.getMark()){
System.out.println(mark);
GPSCoordinate rotatedMark = rotate(center, markToGPSCoordinate(mark), degrees);
mark.setTargetLat(String.valueOf(rotatedMark.getLatitude()));
mark.setTargetLng(String.valueOf(rotatedMark.getLongitude()));
mark.setTargetLat(rotatedMark.getLatitude());
mark.setTargetLng(rotatedMark.getLongitude());
}
}
}
@@ -206,8 +124,8 @@ public class RaceXMLCreator {
* @param limit limit to convert
* @return gps coordinate corresponding to the limit
*/
public static GPSCoordinate limitToGPSCoordinate(Race.CourseLimit.Limit limit){
return new GPSCoordinate(Double.parseDouble(limit.getLat()), Double.parseDouble(limit.getLon()));
public static GPSCoordinate limitToGPSCoordinate(XMLLimit limit){
return new GPSCoordinate(limit.getLat(), limit.getLon());
}
/**
@@ -232,8 +150,8 @@ public class RaceXMLCreator {
* @param mark mark to obtain the GPSCoordinates of
* @return the GPSCOordinatess of a mark
*/
public static GPSCoordinate markToGPSCoordinate(Race.Course.CompoundMark.Mark mark){
return new GPSCoordinate(Double.parseDouble(mark.getTargetLat()), Double.parseDouble(mark.getTargetLng()));
public static GPSCoordinate markToGPSCoordinate(XMLMark mark){
return new GPSCoordinate(mark.getTargetLat(), mark.getTargetLng());
}
/**
@@ -241,12 +159,12 @@ public class RaceXMLCreator {
* @param race race to get the center of
* @return GPSCoordinates of the center
*/
public static GPSCoordinate getCenter(Race race){
public static GPSCoordinate getCenter(XMLRace race){
double avgLat = 0;
double avgLng = 0;
for (Race.CourseLimit.Limit limit: race.getCourseLimit().getLimit()){
avgLat += Double.parseDouble(limit.getLat());
avgLng += Double.parseDouble(limit.getLon());
for (XMLLimit limit: race.getCourseLimit().getLimit()){
avgLat += limit.getLat();
avgLng += limit.getLon();
}
avgLat = avgLat/race.getCourseLimit().getLimit().size();
avgLng = avgLng/race.getCourseLimit().getLimit().size();
@@ -265,4 +183,24 @@ public class RaceXMLCreator {
return Math.atan2(dy, dx)/Math.PI * 180;
}
/**
* Sets the xml description of the race to show the race was created now, and starts in 4 minutes
* @param raceXML The race.xml contents.
* @return String containing edited xml
*/
public static void setRaceXMLAtCurrentTimeToNow(XMLRace raceXML) {
//The start time is current time + 4 minutes. prestart is 3 minutes, and we add another minute.
long millisecondsToAdd = Constants.RacePreStartTime + (1 * 60 * 1000);
long secondsToAdd = millisecondsToAdd / 1000;
//Scale the time using our time scalar.
secondsToAdd = secondsToAdd / Constants.RaceTimeScale;
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
ZonedDateTime creationTime = ZonedDateTime.now();
raceXML.setCreationTimeDate(dateFormat.format(creationTime));
raceXML.getRaceStartTime().setTime(dateFormat.format(creationTime.plusSeconds(secondsToAdd)));
}
}