diff --git a/mock/pom.xml b/mock/pom.xml index 9dac409c..3ccd5249 100644 --- a/mock/pom.xml +++ b/mock/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 @@ -46,6 +46,18 @@ test + + seng302 + network + 1.0-SNAPSHOT + + + + seng302 + sharedModel + 1.0-SNAPSHOT + + @@ -88,7 +100,8 @@ 2.4.3 - + seng302.App ${maven.compiler.source} diff --git a/mock/src/main/java/seng302/App.java b/mock/src/main/java/seng302/App.java index f550a638..5b8c94f4 100644 --- a/mock/src/main/java/seng302/App.java +++ b/mock/src/main/java/seng302/App.java @@ -4,9 +4,13 @@ package seng302; import javafx.application.Application; import javafx.stage.Stage; import org.xml.sax.SAXException; -import seng302.Mock.RaceDataSource; -import seng302.Mock.RegattaDataSource; +import seng302.DataInput.RaceDataSource; +import seng302.DataInput.RaceXMLReader; +import seng302.DataInput.RegattaDataSource; +import seng302.DataInput.RegattaXMLReader; import seng302.Model.Event; +import java.io.OutputStream; + import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; @@ -25,9 +29,11 @@ public class App extends Application { @Override public void start(Stage primaryStage) { try { + OutputStream outputStream = System.out;//TEMP currently using System.out, but should replace this with tcp socket we are sending over. + RaceDataSource raceData = new RaceXMLReader("raceXML/bermuda_AC35.xml"); RegattaDataSource regattaData = new RegattaXMLReader("mockXML/regattaTest.xml"); - Event raceEvent = new Event(raceData, regattaData); + Event raceEvent = new Event(raceData, regattaData, outputStream); raceEvent.start(); } catch (IOException e) { e.printStackTrace(); diff --git a/mock/src/main/java/seng302/Data/BoatData.java b/mock/src/main/java/seng302/Data/BoatData.java index d8a5594b..27a42503 100644 --- a/mock/src/main/java/seng302/Data/BoatData.java +++ b/mock/src/main/java/seng302/Data/BoatData.java @@ -3,10 +3,8 @@ package seng302.Data; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; - import seng302.Exceptions.InvalidBoatDataException; -import seng302.Model.BoatInRace; - +import SharedModel.BoatInRace; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -24,8 +22,8 @@ import java.util.List; */ public class BoatData { - private List boatData; Document doc; + private List boatData; public BoatData(List boatData) { @@ -34,6 +32,7 @@ public class BoatData { /** * Creates an AC35 officially formatted xml description of boats competing in a race + * * @return String containing xml-formatted boats description */ public String createXML() { @@ -61,7 +60,7 @@ public class BoatData { //Serialize document. StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter); - transformer.transform(source,result); + transformer.transform(source, result); return stringWriter.toString(); @@ -76,11 +75,12 @@ public class BoatData { /** * Runs through competing boats, creating an element for each + * * @param boatsElement boats element to be added to */ private void appendIndividualBoats(Element boatsElement) { - for (int i=0; i < boatData.size(); i++) { + for (int i = 0; i < boatData.size(); i++) { Element boat = doc.createElement("Boat"); appendType(boat); appendSourceID(boat, i); @@ -97,6 +97,7 @@ public class BoatData { /** * Creates and appends type attribute of a boat + * * @param boat element being added to */ private void appendType(Element boat) { @@ -108,8 +109,9 @@ public class BoatData { /** * Creates and appends sourceID attribute of a boat + * * @param boat element being added to - * @param i boat number + * @param i boat number */ private void appendSourceID(Element boat, int i) { //SourceID attribute @@ -120,6 +122,7 @@ public class BoatData { /** * Creates and appends shapeID attribute of a boat + * * @param boat element being added to */ private void appendShapeID(Element boat) { @@ -131,6 +134,7 @@ public class BoatData { /** * Creates and appends hull name attribute of a boat + * * @param boat element being added to */ private void appendHullNum(Element boat) { @@ -142,8 +146,9 @@ public class BoatData { /** * Creates and appends stow name attribute of a boat + * * @param boat element being added to - * @param i boat number + * @param i boat number */ private void appendStoweName(Element boat, int i) { //StoweName attribute @@ -154,8 +159,9 @@ public class BoatData { /** * Creates and appends short name attribute of a boat + * * @param boat element being added to - * @param i boat number + * @param i boat number */ private void appendShortName(Element boat, int i) { //ShortName attribute @@ -166,8 +172,9 @@ public class BoatData { /** * Creates and appends boat name attribute of a boat + * * @param boat element being added to - * @param i boat number + * @param i boat number */ private void appendBoatName(Element boat, int i) { //BoatName attribute @@ -178,8 +185,9 @@ public class BoatData { /** * Creates and appends gps attributes of a boat + * * @param boat element being added to - * @param i boat number + * @param i boat number */ private void appendGPSCoords(Element boat, int i) { //GPSCoord for element diff --git a/mock/src/main/java/seng302/Data/RaceData.java b/mock/src/main/java/seng302/Data/RaceData.java index 096998b5..d4834d32 100644 --- a/mock/src/main/java/seng302/Data/RaceData.java +++ b/mock/src/main/java/seng302/Data/RaceData.java @@ -2,11 +2,11 @@ package seng302.Data; import org.w3c.dom.Document; import org.w3c.dom.Element; +import seng302.DataInput.RaceDataSource; import seng302.Exceptions.InvalidRaceDataException; -import seng302.GPSCoordinate; -import seng302.Model.BoatInRace; -import seng302.Model.Marker; -import seng302.Mock.RaceDataSource; +import SharedModel.BoatInRace; +import SharedModel.GPSCoordinate; +import SharedModel.Marker; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -36,6 +36,7 @@ public class RaceData { /** * Creates an AC35 officially formatted xml description of a race. + * * @return String containing xml-formatted race description */ public String createXML() { @@ -158,6 +159,7 @@ public class RaceData { /** * Creates a mark element for insertion in a coumpound mark element + * * @param marker GPS coordinates of the mark * @return Element mark element */ @@ -170,8 +172,9 @@ public class RaceData { /** * Creates a compound marker holding one or two marks,and a sequence number + * * @param marker marker - * @param i sequence number + * @param i sequence number * @return Element compound mark element */ private Element createCompoundMarker(Marker marker, int i) { @@ -190,6 +193,7 @@ public class RaceData { /** * Creates a corner element + * * @param i sequence number * @return Element corner element */ diff --git a/mock/src/main/java/seng302/Data/RegattaData.java b/mock/src/main/java/seng302/Data/RegattaData.java index 1fa7ed8d..2c7fac56 100644 --- a/mock/src/main/java/seng302/Data/RegattaData.java +++ b/mock/src/main/java/seng302/Data/RegattaData.java @@ -2,8 +2,8 @@ package seng302.Data; import org.w3c.dom.Document; import org.w3c.dom.Element; +import seng302.DataInput.RegattaDataSource; import seng302.Exceptions.InvalidRegattaDataException; -import seng302.Mock.RegattaDataSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -32,6 +32,7 @@ public class RegattaData { /** * Creates an AC35 officially formatted xml description of a regatta + * * @return String containing xml-formatted regatta description */ public String createXML() { @@ -55,7 +56,7 @@ public class RegattaData { //Serialize document. StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter); - transformer.transform(source,result); + transformer.transform(source, result); return stringWriter.toString(); diff --git a/mock/src/main/java/seng302/Mock/RaceDataSource.java b/mock/src/main/java/seng302/DataInput/RaceDataSource.java similarity index 72% rename from mock/src/main/java/seng302/Mock/RaceDataSource.java rename to mock/src/main/java/seng302/DataInput/RaceDataSource.java index f19c6676..f23a009c 100644 --- a/mock/src/main/java/seng302/Mock/RaceDataSource.java +++ b/mock/src/main/java/seng302/DataInput/RaceDataSource.java @@ -1,9 +1,9 @@ -package seng302.Mock; +package seng302.DataInput; -import seng302.GPSCoordinate; -import seng302.Model.BoatInRace; -import seng302.Model.Leg; -import seng302.Model.Marker; +import SharedModel.BoatInRace; +import SharedModel.GPSCoordinate; +import SharedModel.Leg; +import SharedModel.Marker; import java.util.List; @@ -12,14 +12,20 @@ import java.util.List; */ public interface RaceDataSource { List getBoats(); + List getLegs(); + List getBoundary(); + List getMarkers(); String getRaceId(); + String getRaceType(); GPSCoordinate getMark(); + GPSCoordinate getMapTopLeft(); + GPSCoordinate getMapBottomRight(); } diff --git a/mock/src/main/java/seng302/RaceXMLReader.java b/mock/src/main/java/seng302/DataInput/RaceXMLReader.java similarity index 90% rename from mock/src/main/java/seng302/RaceXMLReader.java rename to mock/src/main/java/seng302/DataInput/RaceXMLReader.java index 4076a043..95ac8cac 100644 --- a/mock/src/main/java/seng302/RaceXMLReader.java +++ b/mock/src/main/java/seng302/DataInput/RaceXMLReader.java @@ -1,13 +1,13 @@ -package seng302; +package seng302.DataInput; import javafx.scene.paint.Color; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import seng302.Mock.RaceDataSource; -import seng302.Model.BoatInRace; -import seng302.Model.Leg; -import seng302.Model.Marker; +import SharedModel.BoatInRace; +import SharedModel.GPSCoordinate; +import SharedModel.Leg; +import SharedModel.Marker; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; @@ -18,6 +18,7 @@ import java.util.List; * Created by fwy13 on 26/03/2017. */ public class RaceXMLReader extends XMLReader implements RaceDataSource { + private static double COORDINATEPADDING = 0.0005; private String raceID; private List 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. @@ -25,14 +26,14 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { private GPSCoordinate mark, startPt1, startPt2, finishPt1, finishPt2, leewardPt1, leewardPt2, windwardPt1, windwardPt2; private GPSCoordinate mapTopLeft, mapBottomRight; private List boundary = new ArrayList<>(); - private static double COORDINATEPADDING = 0.0005; private List markers = new ArrayList<>(); /** * Constractor for Race XML + * * @param filePath path of the file - * @throws IOException error - * @throws SAXException error + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { @@ -41,10 +42,11 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * COnstructor for Race XML + * * @param filePath file path to read - * @param read whether or not to read and store the files straight away. - * @throws IOException error - * @throws SAXException error + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { @@ -75,7 +77,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * Read all the boats in the XML file - */ + */ public void readBoats() { //get all boats NodeList nBoats = doc.getElementsByTagName("boat"); @@ -95,7 +97,6 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { } - /** * Read all the boats in the XML file */ @@ -198,6 +199,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file + * * @param start base nodelist this should be the tag that contains * @return */ @@ -207,7 +209,8 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex index in the node that has the coordinate tag * @return */ @@ -217,9 +220,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex index in the node that has the coordinate tag - * @param nodeIndex coordinate index + * @param nodeIndex coordinate index * @return */ private Marker getMarker(NodeList start, int startIndex, int nodeIndex) { @@ -230,6 +234,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a changes a marker to GPS coordinates into a marker + * * @param markerNode marker to turn into coordinates * @return */ @@ -250,6 +255,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a coordinates from the XML file + * * @param start base nodelist this should be the tag that contains * @return */ @@ -257,9 +263,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return getCoordinates(start, 0); } - /** + /** * gets a coordinates from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex the index the tag containing the coordinate should be in * @return */ @@ -267,11 +274,12 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return getCoordinates(start, startIndex, 0); } - /** + /** * gets a coordinates from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex the index the tag containing the coordinate should be in - * @param nodeIndex The coordinate index + * @param nodeIndex The coordinate index * @return */ private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex) { @@ -349,9 +357,13 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return mapBottomRight; } - public String getRaceId() { return raceID; } + public String getRaceId() { + return raceID; + } - public List getMarkers() { return markers; } + public List getMarkers() { + return markers; + } public String getRaceType() { return "FLEET"; diff --git a/mock/src/main/java/seng302/DataInput/RegattaDataSource.java b/mock/src/main/java/seng302/DataInput/RegattaDataSource.java new file mode 100644 index 00000000..98b3900c --- /dev/null +++ b/mock/src/main/java/seng302/DataInput/RegattaDataSource.java @@ -0,0 +1,10 @@ +package seng302.DataInput; + +import SharedModel.Regatta; + +/** + * Created by zwu18 on 25/04/17. + */ +public interface RegattaDataSource { + Regatta getRegatta(); +} diff --git a/mock/src/main/java/seng302/RegattaXMLReader.java b/mock/src/main/java/seng302/DataInput/RegattaXMLReader.java similarity index 86% rename from mock/src/main/java/seng302/RegattaXMLReader.java rename to mock/src/main/java/seng302/DataInput/RegattaXMLReader.java index bcba6818..17238c76 100644 --- a/mock/src/main/java/seng302/RegattaXMLReader.java +++ b/mock/src/main/java/seng302/DataInput/RegattaXMLReader.java @@ -1,11 +1,9 @@ -package seng302; +package seng302.DataInput; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import seng302.Mock.RegattaDataSource; -import seng302.Model.Regatta; -import seng302.XMLReader; +import SharedModel.Regatta; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; @@ -18,9 +16,10 @@ public class RegattaXMLReader extends XMLReader implements RegattaDataSource { /** * Constructor for Regatta XML + * * @param filePath path of the file - * @throws IOException error - * @throws SAXException error + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RegattaXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { @@ -29,10 +28,11 @@ public class RegattaXMLReader extends XMLReader implements RegattaDataSource { /** * Constructor for Regatta XML + * * @param filePath file path to read - * @param read whether or not to read and store the files straight away. - * @throws IOException error - * @throws SAXException error + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RegattaXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { diff --git a/mock/src/main/java/seng302/XMLReader.java b/mock/src/main/java/seng302/DataInput/XMLReader.java similarity index 97% rename from mock/src/main/java/seng302/XMLReader.java rename to mock/src/main/java/seng302/DataInput/XMLReader.java index 810096d3..8a6f3a8c 100644 --- a/mock/src/main/java/seng302/XMLReader.java +++ b/mock/src/main/java/seng302/DataInput/XMLReader.java @@ -1,4 +1,4 @@ -package seng302; +package seng302.DataInput; import org.w3c.dom.Document; import org.w3c.dom.Element; diff --git a/mock/src/main/java/seng302/Exceptions/InvalidBoatDataException.java b/mock/src/main/java/seng302/Exceptions/InvalidBoatDataException.java index 7bf7a360..98250e2a 100644 --- a/mock/src/main/java/seng302/Exceptions/InvalidBoatDataException.java +++ b/mock/src/main/java/seng302/Exceptions/InvalidBoatDataException.java @@ -7,15 +7,12 @@ package seng302.Exceptions; /** * An exception thrown when we cannot generate Boats.xml and send an XML message. */ -public class InvalidBoatDataException extends RuntimeException -{ +public class InvalidBoatDataException extends RuntimeException { - public InvalidBoatDataException() - { + public InvalidBoatDataException() { } - public InvalidBoatDataException(String message) - { + public InvalidBoatDataException(String message) { super(message); } } diff --git a/mock/src/main/java/seng302/Exceptions/InvalidRaceDataException.java b/mock/src/main/java/seng302/Exceptions/InvalidRaceDataException.java index 424fb0d5..11e4fcfc 100644 --- a/mock/src/main/java/seng302/Exceptions/InvalidRaceDataException.java +++ b/mock/src/main/java/seng302/Exceptions/InvalidRaceDataException.java @@ -7,14 +7,11 @@ package seng302.Exceptions; /** * Exception thrown when we cannot generate Race.xml data, and send an XML message. */ -public class InvalidRaceDataException extends RuntimeException -{ - public InvalidRaceDataException() - { +public class InvalidRaceDataException extends RuntimeException { + public InvalidRaceDataException() { } - public InvalidRaceDataException(String message) - { + public InvalidRaceDataException(String message) { super(message); } } diff --git a/mock/src/main/java/seng302/Exceptions/InvalidRegattaDataException.java b/mock/src/main/java/seng302/Exceptions/InvalidRegattaDataException.java index bff8ce03..1249ae96 100644 --- a/mock/src/main/java/seng302/Exceptions/InvalidRegattaDataException.java +++ b/mock/src/main/java/seng302/Exceptions/InvalidRegattaDataException.java @@ -7,14 +7,11 @@ package seng302.Exceptions; /** * An exception thrown when a Regatta.xml message cannot be generated and sent. */ -public class InvalidRegattaDataException extends RuntimeException -{ - public InvalidRegattaDataException() - { +public class InvalidRegattaDataException extends RuntimeException { + public InvalidRegattaDataException() { } - public InvalidRegattaDataException(String message) - { + public InvalidRegattaDataException(String message) { super(message); } } diff --git a/mock/src/main/java/seng302/Mock/RegattaDataSource.java b/mock/src/main/java/seng302/Mock/RegattaDataSource.java deleted file mode 100644 index 5841fda5..00000000 --- a/mock/src/main/java/seng302/Mock/RegattaDataSource.java +++ /dev/null @@ -1,10 +0,0 @@ -package seng302.Mock; - -import seng302.Model.Regatta; - -/** - * Created by zwu18 on 25/04/17. - */ -public interface RegattaDataSource{ - Regatta getRegatta(); -} diff --git a/mock/src/main/java/seng302/Model/Event.java b/mock/src/main/java/seng302/Model/Event.java index b1c6cf3e..3e208500 100644 --- a/mock/src/main/java/seng302/Model/Event.java +++ b/mock/src/main/java/seng302/Model/Event.java @@ -3,12 +3,18 @@ package seng302.Model; import seng302.Data.BoatData; import seng302.Data.RaceData; import seng302.Data.RegattaData; - -import seng302.Mock.RegattaDataSource; +import seng302.DataInput.RaceDataSource; +import seng302.DataInput.RegattaDataSource; import seng302.Exceptions.InvalidBoatDataException; import seng302.Exceptions.InvalidRaceDataException; import seng302.Exceptions.InvalidRegattaDataException; -import seng302.Mock.RaceDataSource; +import seng302.Networking.MessageEncoders.XMLMessageEncoder; +import seng302.Networking.Utils.XMLMessage; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; /** @@ -19,23 +25,33 @@ public class Event { RaceDataSource raceDataSource; RegattaDataSource regattaDataSource; - public Event(RaceDataSource raceData, RegattaDataSource regattaData) { + ///The stream to which we send all data. + private OutputStream outputStream; + + //Sequence numbers for XML messages. + private short regattaXMLSequenceNumber = 0; + private short raceXMLSequenceNumber = 0; + private short boatXMLSequenceNumber = 0; + + + public Event(RaceDataSource raceData, RegattaDataSource regattaData, OutputStream outputStream) { this.raceDataSource = raceData; this.regattaDataSource = regattaData; + this.outputStream = outputStream; + } - public void start() - { - System.out.println("\nREGATTA DATA\n");//TEMP REMOVE debug + public void start() { + //System.out.println("\nREGATTA DATA\n");//TEMP REMOVE debug sendRegattaData(); - System.out.println("\nRACE DATA\n");//TEMP REMOVE debug + //System.out.println("\nRACE DATA\n");//TEMP REMOVE debug sendRaceData(); - System.out.println("\nBOAT DATA\n");//TEMP REMOVE debug + //System.out.println("\nBOAT DATA\n");//TEMP REMOVE debug sendBoatData(); - System.out.println("RACE STARTING!!\n\n");//TEMP REMOVE debug + //System.out.println("RACE STARTING!!\n\n");//TEMP REMOVE debug - Race newRace = new Race(raceDataSource, 15); + Race newRace = new Race(raceDataSource, 15, this.outputStream); new Thread((newRace)).start(); } @@ -45,27 +61,134 @@ public class Event { RegattaData regattaData = new RegattaData(regattaDataSource); String xmlString = regattaData.createXML(); - System.out.println(xmlString); // to be replaced by TCPClient.send(xmlString) type function call + byte[] xmlStringUTF8 = new byte[0]; + try + { + xmlStringUTF8 = xmlString.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new InvalidRegattaDataException(); + } + + //Create XML message object and serialize. + short ackNumber = 1;//TEMP need a more sensible way of getting ack number. Is it per packet type, or per packet? + + XMLMessageEncoder xmlMessageEncoder = new XMLMessageEncoder(ackNumber, System.currentTimeMillis(), XMLMessage.XMLTypeRegatta, getNextRegattaXMLSequenceNumber(), (short) xmlStringUTF8.length, xmlString); + + byte[] serializedMessage = xmlMessageEncoder.encode(); + + //Write it. + try + { + this.outputStream.write(serializedMessage); + } + catch (IOException e) + { + throw new InvalidRegattaDataException(); + } + + } - public void sendRaceData() throws InvalidRaceDataException - { + public void sendRaceData() throws InvalidRaceDataException { RaceData raceData = new RaceData(raceDataSource); //Serialize race data to an XML as a string. String xmlString = raceData.createXML(); - System.out.println(xmlString); // to be replaced by TCPClient.send(xmlString) type function call + byte[] xmlStringUTF8 = new byte[0]; + try + { + xmlStringUTF8 = xmlString.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new InvalidRaceDataException(); + } + + //Create XML message object and serialize. + short ackNumber = 1;//TEMP need a more sensible way of getting ack number. Is it per packet type, or per packet? + + XMLMessageEncoder xmlMessageEncoder = new XMLMessageEncoder(ackNumber, System.currentTimeMillis(), XMLMessage.XMLTypeRace, getNextRaceXMLSequenceNumber(), (short) xmlStringUTF8.length, xmlString); + + byte[] serializedMessage = xmlMessageEncoder.encode(); + + //Write it. + try + { + this.outputStream.write(serializedMessage); + } + catch (IOException e) + { + throw new InvalidRaceDataException(); + } } - public void sendBoatData() throws InvalidBoatDataException - { + public void sendBoatData() throws InvalidBoatDataException { BoatData boatData = new BoatData(raceDataSource.getBoats()); //Serialize race data to an XML as a string. String xmlString = boatData.createXML(); - System.out.println(xmlString); // to be replaced by TCPClient.send(xmlString) type function call + byte[] xmlStringUTF8 = new byte[0]; + try + { + xmlStringUTF8 = xmlString.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new InvalidBoatDataException(); + } + + //Create XML message object and serialize. + short ackNumber = 1;//TEMP need a more sensible way of getting ack number. Is it per packet type, or per packet? + + XMLMessageEncoder xmlMessageEncoder = new XMLMessageEncoder(ackNumber, System.currentTimeMillis(), XMLMessage.XMLTypeBoat, getNextBoatXMLSequenceNumber(), (short) xmlStringUTF8.length, xmlString); + + byte[] serializedMessage = xmlMessageEncoder.encode(); + + //Write it. + try + { + this.outputStream.write(serializedMessage); + } + catch (IOException e) + { + throw new InvalidBoatDataException(); + } } + /** + * Returns the next sequence number to be used for regatta XML messages. + * @return + */ + public short getNextRegattaXMLSequenceNumber() + { + short currentNumber = regattaXMLSequenceNumber; + regattaXMLSequenceNumber += 1; + return currentNumber; + } + + /** + * Returns the next sequence number to be used for race XML messages. + * @return + */ + public short getNextRaceXMLSequenceNumber() + { + short currentNumber = raceXMLSequenceNumber; + raceXMLSequenceNumber += 1; + return currentNumber; + } + + /** + * Returns the next sequence number to be used for boat XML messages. + * @return + */ + public short getNextBoatXMLSequenceNumber() + { + short currentNumber = boatXMLSequenceNumber; + boatXMLSequenceNumber += 1; + return currentNumber; + } } diff --git a/mock/src/main/java/seng302/Model/Race.java b/mock/src/main/java/seng302/Model/Race.java index e23fc230..0049ec82 100644 --- a/mock/src/main/java/seng302/Model/Race.java +++ b/mock/src/main/java/seng302/Model/Race.java @@ -2,18 +2,18 @@ package seng302.Model; import javafx.animation.AnimationTimer; - import javafx.collections.FXCollections; import javafx.collections.ObservableList; - import org.geotools.referencing.GeodeticCalculator; -import seng302.Constants; -import seng302.GPSCoordinate; -import seng302.Mock.RaceDataSource; -import seng302.RaceEventMessages.BoatLocationMessage; +import seng302.DataInput.RaceDataSource; +import SharedModel.*; +import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; +import seng302.Networking.Utils.BoatLocationMessage; import java.awt.geom.Point2D; +import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -29,26 +29,31 @@ public class Race implements Runnable { protected List legs; protected int boatsFinished = 0; protected long totalTimeElapsed; - private int lastFPS = 20; - private int dnfChance = 0; //percentage chance a boat fails at each checkpoint protected int heartbeat = 0; protected int scaleFactor; - protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race + private int lastFPS = 20; + private int dnfChance = 0; //percentage chance a boat fails at each checkpoint + + //Outputstream to write messages to. + private OutputStream outputStream; + /** * Initailiser for Race * - * @param boats Takes in an array of boats that are participating in the race. - * @param legs Number of marks in order that the boats pass in order to complete the race. + * @param boats Takes in an array of boats that are participating in the race. + * @param legs Number of marks in order that the boats pass in order to complete the race. * @param scaleFactor for race */ - public Race(List boats, List legs, int scaleFactor) { + public Race(List boats, List legs, int scaleFactor, OutputStream outputStream) { this.startingBoats = FXCollections.observableArrayList(boats); this.legs = legs; this.legs.add(new Leg("Finish", this.legs.size())); this.scaleFactor = scaleFactor; + this.outputStream = outputStream; + if (startingBoats != null && startingBoats.size() > 0) { initialiseBoats(); @@ -56,8 +61,32 @@ public class Race implements Runnable { } - public Race(RaceDataSource raceData, int scaleFactor) { - this(raceData.getBoats(), raceData.getLegs(), scaleFactor); + public Race(RaceDataSource raceData, int scaleFactor, OutputStream outputStream) { + this(raceData.getBoats(), raceData.getLegs(), scaleFactor, outputStream); + } + + /** + * Calculates the boats next GPS position based on its distance travelled and heading + * + * @param oldCoordinates GPS coordinates of the boat's starting position + * @param distanceTravelled distance in nautical miles + * @param azimuth boat's current direction. Value between -180 and 180 + * @return The boat's new coordinate + */ + public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) { + + //Find new coordinate using current heading and distance + + GeodeticCalculator geodeticCalculator = new GeodeticCalculator(); + //Load start point into calculator + Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude()); + geodeticCalculator.setStartingGeographicPoint(startPoint); + //load direction and distance tranvelled into calculator + geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion); + //get new point + Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint(); + + return new GPSCoordinate(endPoint.getY(), endPoint.getX()); } /** @@ -69,20 +98,38 @@ public class Race implements Runnable { countdownTimer(); } + /** + * Starts the heartbeat timer, which sends a heartbeat message every so often (i.e., 5 seconds). + */ public void outputHeartbeat() { + long heartbeatPeriod = 5000; AnimationTimer heartbeatTimer = new AnimationTimer() { long currentHeartbeatTime = System.currentTimeMillis(); - long endHeartbeatTime = System.currentTimeMillis() + 5000; + long endHeartbeatTime = System.currentTimeMillis() + heartbeatPeriod; + @Override public void handle(long now) { if (currentHeartbeatTime >= endHeartbeatTime) { - System.out.println("-------"); - System.out.println("Heartbeat value: " + heartbeat); - System.out.println("-------"); - endHeartbeatTime = System.currentTimeMillis() + 5000; + endHeartbeatTime = System.currentTimeMillis() + heartbeatPeriod; + + //Update heartbeat value. heartbeat++; - //TODO: Send heartbeat value + + //Serialize heartbeat. + byte[] heartBeatMessage = RaceVisionByteEncoder.heartBeat(heartbeat); + + //Write it to stream. + try + { + outputStream.write(heartBeatMessage); + } + catch (IOException e) + {//TODO should probably handle this in a more sensible manner. + e.printStackTrace(); + } + } + //TODO stop the animation at some point. /*if (raceFinish) { System.out.println("Heartbeat stopping"); stop(); @@ -100,7 +147,7 @@ public class Race implements Runnable { protected void countdownTimer() { AnimationTimer timer = new AnimationTimer() { long currentTime = System.currentTimeMillis(); - long startTime = currentTime + (PRERACE_TIME/scaleFactor); + long startTime = currentTime + (PRERACE_TIME / scaleFactor); long minutes; long currentTimeInSeconds; long remainingSeconds; @@ -114,7 +161,7 @@ public class Race implements Runnable { stop(); simulateRace(); } else { - currentTimeInSeconds = (timeLeft*scaleFactor) / 1000; + currentTimeInSeconds = (timeLeft * scaleFactor) / 1000; minutes = currentTimeInSeconds / 60; remainingSeconds = currentTimeInSeconds % 60; hours = minutes / 60; @@ -190,30 +237,40 @@ public class Race implements Runnable { boatLocationMessage.setAltitude(0);//Junk value. boatLocationMessage.setHeading(BoatLocationMessage.convertHeadingDoubleToInt(boat.getHeading())); - boatLocationMessage.setPitch((short)0);//Junk value. - boatLocationMessage.setRoll((short)0);//Junk value. + boatLocationMessage.setPitch((short) 0);//Junk value. + boatLocationMessage.setRoll((short) 0);//Junk value. boatLocationMessage.setBoatSpeed(BoatLocationMessage.convertBoatSpeedDoubleToInt(boat.getVelocity())); boatLocationMessage.setBoatCOG(0);//Junk value. boatLocationMessage.setBoatSOG(0);//Junk value. boatLocationMessage.setApparentWindSpeed(0);//Junk value. - boatLocationMessage.setApparentWindAngle((short)0);//Junk value. + boatLocationMessage.setApparentWindAngle((short) 0);//Junk value. boatLocationMessage.setTrueWindSpeed(0);//Junk value. - boatLocationMessage.setTrueWindAngle((short)0);//Junk value. + boatLocationMessage.setTrueWindDirection(0);//Junk value. + boatLocationMessage.setTrueWindAngle((short) 0);//Junk value. boatLocationMessage.setCurrentDrift(0);//Junk value. boatLocationMessage.setCurrentSet(0);//Junk value. - boatLocationMessage.setRudderAngle((short)0);//Junk value. + boatLocationMessage.setRudderAngle((short) 0);//Junk value. //We have finished creating the message. - //TODO at this point, we need to send the event to the visualiser. - //System.out.println(boatLocationMessage);//TEMP debug print + + //Serialize. + byte[] boatLocationMessageSerialized = RaceVisionByteEncoder.boatLocation(boatLocationMessage); + //Write to stream. + + try + { + outputStream.write(boatLocationMessageSerialized); + } + catch (IOException e) + {//TODO should probably handle this in a more sensible manner. + e.printStackTrace(); + } } else { - System.out.println("Race is over");//TEMP debug print - //raceFinish = true; stop(); } } @@ -227,15 +284,15 @@ public class Race implements Runnable { */ protected void updatePositions() { FXCollections.sort(startingBoats, (a, b) -> b.getCurrentLeg().getLegNumber() - a.getCurrentLeg().getLegNumber()); - for(BoatInRace boat: startingBoats) { - if(boat != null) { + for (BoatInRace boat : startingBoats) { + if (boat != null) { boat.setPosition(Integer.toString(startingBoats.indexOf(boat) + 1)); - System.out.println(boat.toString() + " " + boat.getPosition()); + //System.out.println(boat.toString() + " " + boat.getPosition());//TEMP debug print if (boat.getCurrentLeg().getName().equals("DNF") || boat.getCurrentLeg().getLegNumber() == 0) boat.setPosition("-"); } } - System.out.println("=====");//TEMP debug print + //System.out.println("=====");//TEMP debug print } public void initialiseBoats() { @@ -294,6 +351,7 @@ public class Race implements Runnable { /** * Sets the chance each boat has of failing at a gate or marker + * * @param chance percentage chance a boat has of failing per checkpoint. */ protected void setDnfChance(int chance) { @@ -310,7 +368,7 @@ public class Race implements Runnable { /** * Calculates the distance a boat has travelled and updates its current position according to this value. * - * @param boat to be updated + * @param boat to be updated * @param millisecondsElapsed since last update */ protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { @@ -360,30 +418,6 @@ public class Race implements Runnable { } } - /** - * Calculates the boats next GPS position based on its distance travelled and heading - * - * @param oldCoordinates GPS coordinates of the boat's starting position - * @param distanceTravelled distance in nautical miles - * @param azimuth boat's current direction. Value between -180 and 180 - * @return The boat's new coordinate - */ - public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) { - - //Find new coordinate using current heading and distance - - GeodeticCalculator geodeticCalculator = new GeodeticCalculator(); - //Load start point into calculator - Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude()); - geodeticCalculator.setStartingGeographicPoint(startPoint); - //load direction and distance tranvelled into calculator - geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion); - //get new point - Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint(); - - return new GPSCoordinate(endPoint.getY(), endPoint.getX()); - } - /** * Returns the boats that have started the race. * diff --git a/mock/src/main/java/seng302/Model/RaceClock.java b/mock/src/main/java/seng302/Model/RaceClock.java index 25bac06a..98ce31bf 100644 --- a/mock/src/main/java/seng302/Model/RaceClock.java +++ b/mock/src/main/java/seng302/Model/RaceClock.java @@ -4,7 +4,7 @@ import com.github.bfsmith.geotimezone.TimeZoneLookup; import com.github.bfsmith.geotimezone.TimeZoneResult; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; -import seng302.GPSCoordinate; +import SharedModel.GPSCoordinate; import java.time.LocalDateTime; import java.time.ZoneId; @@ -20,7 +20,7 @@ public class RaceClock { private String timeZone; private ZoneId zoneId; - public RaceClock(GPSCoordinate gpsCoordinate){ + public RaceClock(GPSCoordinate gpsCoordinate) { TimeZoneLookup timeZoneLookup = new TimeZoneLookup(); TimeZoneResult timeZoneResult = timeZoneLookup.getTimeZone(gpsCoordinate.getLatitude(), gpsCoordinate.getLongitude()); zoneId = ZoneId.of(timeZoneResult.getResult()); @@ -32,7 +32,7 @@ public class RaceClock { timeZone = timeZoneFormatter.format(zonedDateTime); } - public void updateTime(){ + public void updateTime() { LocalDateTime localDateTime = LocalDateTime.now(zoneId); ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); time.setValue(dateTimeFormatter.format(zonedDateTime)); diff --git a/mock/src/main/java/seng302/Networking/BinaryMessageDecoder.java b/mock/src/main/java/seng302/Networking/BinaryMessageDecoder.java deleted file mode 100644 index d99bf0b9..00000000 --- a/mock/src/main/java/seng302/Networking/BinaryMessageDecoder.java +++ /dev/null @@ -1,107 +0,0 @@ -package seng302.Networking; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -/** - * Created by hba56 on 21/04/17. - */ -public class BinaryMessageDecoder { - private byte[] fullMessage; - private byte[] header; - private byte[] message; - private byte[] crc; - - private byte headerSync1; - private byte headerSync2; - private byte headerMessageType; - private byte[] headerTimeStamp; - private byte[] headerSourceID; - private byte[] headerMessageLength; - - - public BinaryMessageDecoder(byte[] fullMessage) { - this.fullMessage = fullMessage; - } - - public void decode() throws IndexOutOfBoundsException{ - //get the header - this.header = Arrays.copyOfRange(this.fullMessage, 0, 15); - - this.headerSync1 = this.header[0]; - this.headerSync2 = this.header[1]; - this.headerMessageType = this.header[2]; - this.headerTimeStamp = Arrays.copyOfRange(this.header, 3, 9); - this.headerSourceID = Arrays.copyOfRange(this.header, 9, 13); - this.headerMessageLength = Arrays.copyOfRange(this.header, 13, 15); - - //get message - this.message = Arrays.copyOfRange(this.fullMessage, 15, this.fullMessage.length - 4); - - //get crc - this.crc = Arrays.copyOfRange(this.fullMessage, this.fullMessage.length - 4, fullMessage.length); - - //run through the checks - if (this.message.length != bytesToShort(this.headerMessageLength)){ - System.err.println("message length in header does not equal the message length"); - System.err.println("message length in header: " + bytesToInt(this.headerMessageLength)); - System.err.println("message length: " + this.message.length); - }else if(this.headerSync1 != 0x47){ - System.err.println("Sync byte 1 is wrong"); - }else if(this.headerSync2 !=(byte) 0x83){ - System.err.println("Sync byte 2 is wrong"); - }else if(false){ - //todo check crc - } - } - - - private short bytesToShort(byte[] bytesShort){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); - short num = wrapped.getShort(); - return num; - } - - private int bytesToInt(byte[] bytesInt){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); - int num = wrapped.getInt(); - return num; - } - - private long bytesToLong(byte[] bytesLong){ - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesLong[0]); - byteBuffer.put(bytesLong[1]); - byteBuffer.put(bytesLong[2]); - byteBuffer.put(bytesLong[3]); - byteBuffer.put(bytesLong[4]); - byteBuffer.put(bytesLong[5]); - long longVal = byteBuffer.getLong(0); - return longVal; - } - - public long getTimeStamp() { - return bytesToLong(this.headerTimeStamp); - } - - public int getSourceID() { - return bytesToInt(this.headerSourceID); - } - - public short getMessageLength() { - return bytesToShort(this.headerMessageLength); - } - - public int getMessageType(){ - return (int) this.headerMessageType; - } - - public byte[] getMessage() { - return message; - } -} - diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java b/mock/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java deleted file mode 100644 index cf026ca0..00000000 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java +++ /dev/null @@ -1,30 +0,0 @@ -package seng302.Networking.MessageDecoders; - -import java.util.Arrays; - -/** - * Created by hba56 on 23/04/17. - */ -public class MarkRoundingDecoder { - byte messageVersionNumber; - byte[] byteTime; - byte[] byteAck; - byte[] byteRaceID; - byte[] byteSourceID; - byte byteBoatStatus; - byte byteRoundingSide; - byte byteMarkType; - byte byteMarkID; - - public MarkRoundingDecoder(byte[] encodedMarkRounding) { - messageVersionNumber = encodedMarkRounding[0]; - byteTime = Arrays.copyOfRange(encodedMarkRounding, 1, 7); - byteAck = Arrays.copyOfRange(encodedMarkRounding, 7, 9); - byteRaceID = Arrays.copyOfRange(encodedMarkRounding, 9, 13); - byteSourceID = Arrays.copyOfRange(encodedMarkRounding, 13, 18); - byteBoatStatus = encodedMarkRounding[18]; - byteRoundingSide = encodedMarkRounding[19]; - byteMarkType = encodedMarkRounding[20]; - byteMarkID = encodedMarkRounding[21]; - } -} diff --git a/mock/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java b/mock/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java deleted file mode 100644 index 9afeb4e0..00000000 --- a/mock/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java +++ /dev/null @@ -1,347 +0,0 @@ -package seng302.Networking.MessageEncoders; - -import seng302.Model.BoatInRace; -import seng302.Networking.Utils.BoatLocationMessage; -import seng302.Networking.Utils.CourseWind; -import seng302.Networking.Utils.RaceMessage; - -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Created by fwy13 on 19/04/17. - */ -public class RaceVisionByteEncoder { - - public byte[] heartBeat(int seq){ - ByteBuffer heartBeat = ByteBuffer.allocate(4); - heartBeat.putInt(seq); - byte [] result = heartBeat.array(); - return result; - } - - public byte[] raceStatus(long time, int race, int raceState, long startTime, short raceWindDir, short raceWindSpeed, int raceType, ArrayList boats){ - ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boats.size()); - //Version Number 1 bytes - byte versionNum = 0b10; //this changes with the pdf. (2) - byte[] timeBytes = convert(time, 6);//time (6 bytes) - byte[] raceID = ByteBuffer.allocate(4).putInt(race).array();//race identifier incase multiple races are going at once. - byte[] raceStatus = convert(raceState, 1);//race status 0 - 10 - byte[] expectedStart = convert(startTime, 6);//number of milliseconds from Jan 1, 1970 for when the data is valid - byte[] raceWind = ByteBuffer.allocate(2).putShort(raceWindDir).array();//North = 0x0000 East = 0x4000 South = 0x8000 - byte[] windSpeed = ByteBuffer.allocate(2).putShort(raceWindSpeed).array();//mm/sec - byte[] numBoats = convert(boats.size(), 1); - byte[] bytesRaceType = convert(raceType, 1);//1 match race, 2 fleet race - - raceStatusMessage.put(versionNum); - raceStatusMessage.put(timeBytes); - raceStatusMessage.put(raceID); - raceStatusMessage.put(raceStatus); - raceStatusMessage.put(expectedStart); - raceStatusMessage.put(raceWind); - raceStatusMessage.put(windSpeed); - raceStatusMessage.put(numBoats); - raceStatusMessage.put(bytesRaceType); - - for (int i = 0; i < boats.size(); i++){ - int sourceID = 0; //TODO use boats source id. - byte[] legNum = convert(boats.get(i).getCurrentLeg().getLegNumber(), 1); - byte[] numPenalties = convert(0, 1); //TODO use boats in race penalties class - byte[] numPenaltiesServed = convert(0, 1);//TODO use boats in race penalites served. - byte[] estNextMarkTime = convert((long)0, 6);//TODO use boats estimated time to next mark. - byte[] estFinishTime = convert((long) 0, 6);//TODO use boats estimated time to the finish. - - raceStatusMessage.putInt(sourceID); - raceStatusMessage.put(legNum); - raceStatusMessage.put(numPenalties); - raceStatusMessage.put(numPenaltiesServed); - raceStatusMessage.put(estNextMarkTime); - raceStatusMessage.put(estFinishTime); - } - - return raceStatusMessage.array(); - } - - public byte[] displayTextMessage(RaceMessage[] message){ - //ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32); - int messageVersionNumber = 0b1;//version number - short ackNum = 0;//no clue what this does just a placeholder for 2 bytes. - byte[] messLines = convert(message.length, 1); - -// result.putInt(messageVersionNumber); -// result.putShort(ackNum); -// result.put(messLines); - - ArrayList messages = new ArrayList(); - int size = 4; - - for (int i = 0; i < message.length; i ++){ - int messageLen = message[i].getMessageText().getBytes().length; - byte[] messageAsBytes = message[i].getMessageText().getBytes(); - if (messageLen < 30){ - messageLen = 30; - } - ByteBuffer mess = ByteBuffer.allocate(2 + messageLen); - mess.put(convert(message[i].getLineNumber(), 1)); - mess.put(convert(messageLen, 1)); - for (int j = 0; j < messageLen; j ++){ - mess.put(messageAsBytes[j]); - } - messages.add(mess.array()); - size += 2 + messageLen; - } - - ByteBuffer result = ByteBuffer.allocate(size); - result.put(convert(messageVersionNumber, 1)); - result.putShort(ackNum); - result.put(messLines); - - for(byte[] mess: messages){ - result.put(mess); - } - - return result.array(); - } - - public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){ - int messageVersion = 0b1; - byte[] timestamp = convert(time, 6); - byte[] ackNumber = convert(ack, 2); - byte[] raceStartTime = convert(startTime, 6); - int raceIdentifier = raceID; - byte[] notificationType = convert(notification, 1); - - ByteBuffer result = ByteBuffer.allocate(20); - result.put(convert(messageVersion, 1)); - result.put(timestamp); - result.put(ackNumber); - result.put(raceStartTime); - result.putInt(raceIdentifier); - result.put(notificationType); - - return result.array(); - } - - public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID, - int eventID){ - int messageVersion = 0b10; - byte[] encodeTime = convert(time, 6); - short ackNum = acknowledgeNumber; - int raceUID = raceID;//TODO chekc if this is an into for a 4 char string. - int destSource = destSourceID; - int incident = incidentID; - byte[] event = convert(eventID, 1); - - ByteBuffer result = ByteBuffer.allocate(22); - result.put(convert(messageVersion, 1)); - result.put(encodeTime); - result.putShort(ackNum); - result.putInt(raceUID); - result.putInt(destSource); - result.putInt(incident); - result.put(event); - return result.array(); - } - - public byte[] chatterText(int messageType, String message){ - int messageVersion = 0b1; - byte[] type = convert(messageType, 1); - byte[] length = convert(message.length(), 1); - byte[] text = convert(message, length[0]); - - ByteBuffer result = ByteBuffer.allocate(3 + text.length); - result.put(convert(messageVersion, 1)); - result.put(type); - result.put(length); - result.put(text); - - return result.array(); - } - - public byte[] boatLocation(BoatLocationMessage boatLocationMessage){ - int messageVersionNumber = 0b1; - byte[] time = convert(boatLocationMessage.getTime(), 6); - byte[] sourceID = convert(boatLocationMessage.getSourceID(), 4); - byte[] seqNum = convert(boatLocationMessage.getSequenceNumber(), 4); - byte deviceType = boatLocationMessage.getDeviceType(); - byte[] latitude = convert(boatLocationMessage.getLatitude(), 4); - byte[] longitude = convert(boatLocationMessage.getLongitude(), 4); - byte[] altitude = convert(boatLocationMessage.getAltitude(), 4); - byte[] heading = convert(boatLocationMessage.getHeading(), 2); - byte[] pitch = convert(boatLocationMessage.getPitch(), 2); - byte[] roll = convert(boatLocationMessage.getRoll(), 2); - byte[] boatSpeed = convert(boatLocationMessage.getBoatSpeed(), 2); - byte[] cog = convert(boatLocationMessage.getBoatCOG(), 2); - byte[] sog = convert(boatLocationMessage.getBoatSOG(), 2); - byte[] apparentWindSpeed = convert(boatLocationMessage.getApparentWindSpeed(), 2); - byte[] apparentWindAngle = convert(boatLocationMessage.getApparentWindAngle(), 2); - byte[] trueWindSpeed = convert(boatLocationMessage.getTrueWindSpeed(), 2); - byte[] trueWindDirection = convert(boatLocationMessage.getTrueWindDirection(), 2); - byte[] trueWindAngle = convert(boatLocationMessage.getTrueWindAngle(), 2); - byte[] currentDrift = convert(boatLocationMessage.getCurrentDrift(), 2); - byte[] currentSet = convert(boatLocationMessage.getCurrentSet(), 2); - byte[] rudderAngle = convert(boatLocationMessage.getRudderAngle(), 2); - - ByteBuffer result = ByteBuffer.allocate(56); - result.put(convert(messageVersionNumber, 1)); - result.put(time); - result.put(sourceID); - result.put(seqNum); - result.put(deviceType); - result.put(latitude); - result.put(longitude); - result.put(altitude); - result.put(heading); - result.put(pitch); - result.put(roll); - result.put(boatSpeed); - result.put(cog); - result.put(sog); - result.put(apparentWindSpeed); - result.put(apparentWindAngle); - result.put(trueWindSpeed); - result.put(trueWindDirection); - result.put(trueWindAngle); - result.put(currentDrift); - result.put(currentSet); - result.put(rudderAngle); - return result.array(); - } - - public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ - int messageVersionNumber = 0b1; - byte[] byteTime = convert(time, 6); - byte[] byteAck = convert(ackNumber, 2); - byte[] byteRaceID = convert(raceID, 4); - byte[] byteSourceID = convert(sourceID, 4); - byte[] byteBoatStatus = convert(boatStatus, 1); - byte[] byteRoundingSide = convert(roundingSide, 1); - byte[] byteMarkType = convert(markType, 1); - byte[] byteMarkID = convert(markID, 1); - - ByteBuffer result = ByteBuffer.allocate(21); - result.put(convert(messageVersionNumber, 1)); - result.put(byteTime); - result.put(byteAck); - result.put(byteRaceID); - result.put(byteSourceID); - result.put(byteBoatStatus); - result.put(byteRoundingSide); - result.put(byteMarkType); - result.put(byteMarkID); - return result.array(); - } - - public byte[] courseWind(byte windID, ArrayList courseWinds){ - int messageVersionNumber = 0b1; - byte byteWindID = windID; - byte[] loopcount = convert(courseWinds.size(), 1); - ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size()); - result.put(convert(messageVersionNumber, 1)); - result.put(byteWindID); - result.put(loopcount); - for (CourseWind wind: courseWinds){ - result.put(convert(wind.getID(), 1)); - result.put(convert(wind.getTime(), 6)); - result.put(convert(wind.getRaceID(), 4)); - result.put(convert(wind.getWindDirection(), 2)); - result.put(convert(wind.getWindSpeed(), 2)); - result.put(convert(wind.getBestUpwindAngle(), 2)); - result.put(convert(wind.getBestDownwindAngle(), 2)); - result.put(convert(wind.getFlags(), 1)); - } - return result.array(); - } - - public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ - int messageVersionNumber = 0b1; - byte[] byteTime = convert(time,6); - byte[] byteRawPeriod = convert(rawPeriod, 2); - byte[] byteRawSpeed = convert(rawSampleSpeed, 2); - byte[] bytePeriod2 = convert(period2, 2); - byte[] byteSpeed2 = convert(speed2, 2); - byte[] bytePeriod3 = convert(period3, 2); - byte[] byteSpeed3 = convert(speed3, 2); - byte[] bytePeriod4 = convert(period4, 2); - byte[] byteSpeed4 = convert(speed4, 2); - - ByteBuffer result = ByteBuffer.allocate(23); - result.put(convert(messageVersionNumber, 1)); - result.put(byteTime); - result.put(byteRawPeriod); - result.put(byteRawSpeed); - result.put(bytePeriod2); - result.put(byteSpeed2); - result.put(bytePeriod3); - result.put(byteSpeed3); - result.put(bytePeriod4); - result.put(byteSpeed4); - return result.array(); - } - - public byte[] convert(String s, int size){ - byte[] m = s.getBytes(Charset.forName("UTF-8")); - int length = m.length; - byte[] result; - if (length > 255){ - length = 255; - } else if (size < 1){ - result = new byte[0]; - return result; - } - result = Arrays.copyOfRange(m, 0, length + 1); - return result; - } - - public byte[] convert(int n, int size){ - byte[] result; - if (size > 4){ - result = new byte[4]; - return result; - } else if (size < 1){ - result = new byte[0]; - return result; - } - ByteBuffer byteBuffer = ByteBuffer.allocate(4); - byteBuffer.putInt(n); - byte[] bytes = byteBuffer.array(); - result = Arrays.copyOfRange(bytes, 4 - size, 4); - return result; - } - - public byte[] convert(long n, int size){ - byte[] result; - if (size > 8){ - result = new byte[8]; - return result; - } else if (size < 1){ - result = new byte[0]; - return result; - } - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.putLong(n); - byte[] bytes = byteBuffer.array(); - result = Arrays.copyOfRange(bytes, 8 - size, 8); - return result; - } - - - public byte[] convert(short n, int size){ - byte[] result; - if (size > 2){ - result = new byte[2]; - return result; - } else if (size < 1){ - result = new byte[0]; - return result; - } - ByteBuffer byteBuffer = ByteBuffer.allocate(2); - byteBuffer.putShort(n); - byte[] bytes = byteBuffer.array(); - result = Arrays.copyOfRange(bytes, 2 - size, 2); - return result; - } - -} diff --git a/mock/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java b/mock/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java deleted file mode 100644 index 570f9a2c..00000000 --- a/mock/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java +++ /dev/null @@ -1,77 +0,0 @@ -package seng302.Networking.MessageEncoders; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; - -/** - * Encodes a XML file into a message of AC35 format - */ -public class XMLMessageEncoder { - private byte messageVersionNumber; - private short ackNumber; - private long timeStamp; - private byte xmlMsgSubType; - private short sequenceNumber; - private short xmlMsgLength; - private String xmlMessage; - - public XMLMessageEncoder(byte messageVersionNumber, short ackNumber, long timeStamp, byte xmlMsgSubType, short sequenceNumber, short xmlMsgLenght, String xmlMessage) { - this.messageVersionNumber = messageVersionNumber; - this.ackNumber = ackNumber; - this.timeStamp = timeStamp; - this.xmlMsgSubType = xmlMsgSubType; - this.sequenceNumber = sequenceNumber; - this.xmlMsgLength = xmlMsgLenght; - this.xmlMessage = xmlMessage; - } - - public byte[] encode() { - byte[] messageBytes = xmlMessage.getBytes(); - if (messageBytes.length > this.xmlMsgLength) { - //System.err.println("Xml message is to big"); - return null; - } - ByteBuffer tempOutputByteBuffer = ByteBuffer.allocate(14 + messageBytes.length); - - //ackNumber converted to bytes - byte[] ackNumberBytes = new byte[2]; - ackNumberBytes[0] = (byte) (ackNumber & 0xff); - ackNumberBytes[1] = (byte) ((ackNumber >> 8) & 0xff); - - //sequenceNumber converted to bytes - byte[] sequenceNumberBytes = new byte[2]; - sequenceNumberBytes[0] = (byte) (sequenceNumber & 0xff); - sequenceNumberBytes[1] = (byte) ((sequenceNumber >> 8) & 0xff); - - //xmlMsgLength converted to bytes - byte[] xmlMsgLengthBytes = new byte[2]; - xmlMsgLengthBytes[0] = (byte) (xmlMsgLength & 0xff); - xmlMsgLengthBytes[1] = (byte) ((xmlMsgLength >> 8) & 0xff); - - - tempOutputByteBuffer.put(messageVersionNumber); - tempOutputByteBuffer.put(ackNumberBytes); - tempOutputByteBuffer.put(longToSixBytes(timeStamp)); - tempOutputByteBuffer.put(xmlMsgSubType); - tempOutputByteBuffer.put(sequenceNumberBytes); - tempOutputByteBuffer.put(xmlMsgLengthBytes); - tempOutputByteBuffer.put(messageBytes); - - return tempOutputByteBuffer.array(); - } - - private byte[] longToSixBytes(long x) { - ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); - buffer.putLong(x); - -// System.out.println("====encode===="); -// for (byte i:buffer.array() -// ) { -// System.out.println(i); -// } -// System.out.println("====encode===="); - - return Arrays.copyOfRange(buffer.array(), 2, 8); - } -} diff --git a/mock/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java b/mock/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java deleted file mode 100644 index 0fd59c79..00000000 --- a/mock/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java +++ /dev/null @@ -1,357 +0,0 @@ -package seng302.Networking.Utils; - -/** - * Created by f123 on 21-Apr-17. - */ - -/** - * Represents the information in a boat location message (AC streaming spec: 4.9). - */ -public class BoatLocationMessage -{ - ///Version number of the message - is always 1. - private byte messageVersionNumber = 1; - - ///Time of the event - milliseconds since jan 1 1970. Proper type is 6 byte int. - private long time; - - ///Source ID of the boat. - private int sourceID; - - ///Sequence number of the message. - private int sequenceNumber; - - ///Device type of the message (physical source of the message). - private byte deviceType; - - ///Latitude of the boat. - private int latitude; - - ///Longitude of the boat. - private int longitude; - - ///Altitude of the boat. - private int altitude; - - ///Heading of the boat. Clockwise, 0 = north. Proper type is unsigned 2 byte int. - private int heading; - - ///Pitch of the boat. - private short pitch; - - ///Roll of the boat. - private short roll; - - ///Speed of the boat. Proper type is unsigned 2 byte int. millimeters per second. - private int boatSpeed; - - ///Course over ground (COG) of the boat. Proper type is unsigned 2 byte int. - private int boatCOG; - - ///Speed over ground (SOG) of the boat. Proper type is unsigned 2 byte int. millimeters per second. - private int boatSOG; - - ///Apparent wind speed at time of event. Proper type is unsigned 2 byte int. millimeters per second. - private int apparentWindSpeed; - - ///Apparent wind angle at time of the event. Wind over starboard = positive. - private short apparentWindAngle; - - ///True wind speed. Proper type is unsigned 2 byte int. millimeters per second. - private int trueWindSpeed; - - private short trueWindDirection; - - ///True wind angle. Clockwise compass direction, 0 = north. - private short trueWindAngle; - - ///Current drift. Proper type is unsigned 2 byte int. millimeters per second. - private int currentDrift; - - ///Current set. Proper type is unsigned 2 byte int. Clockwise compass direction, 0 = north. - private int currentSet; - - ///Rudder angle. Positive is rudder set to turn yacht to port. - private short rudderAngle; - - - /** - * Ctor. - */ - public BoatLocationMessage() - { - } - - /** - * Ctor, with all parameters. - * @param messageVersionNumber - * @param time - * @param sourceID - * @param sequenceNumber - * @param deviceType - * @param latitude - * @param longitude - * @param altitude - * @param heading - * @param pitch - * @param roll - * @param boatSpeed - * @param boatCOG - * @param boatSOG - * @param apparentWindSpeed - * @param apparentWindAngle - * @param trueWindSpeed - * @param trueWindDirection - * @param trueWindAngle - * @param currentDrift - * @param currentSet - * @param rudderAngle - */ - public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, int sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) - { - this.messageVersionNumber = messageVersionNumber; - this.time = time; - this.sourceID = sourceID; - this.sequenceNumber = sequenceNumber; - this.deviceType = deviceType; - this.latitude = latitude; - this.longitude = longitude; - this.altitude = altitude; - this.heading = heading; - this.pitch = pitch; - this.roll = roll; - this.boatSpeed = boatSpeed; - this.boatCOG = boatCOG; - this.boatSOG = boatSOG; - this.apparentWindSpeed = apparentWindSpeed; - this.apparentWindAngle = apparentWindAngle; - this.trueWindSpeed = trueWindSpeed; - this.trueWindDirection = trueWindDirection; - this.trueWindAngle = trueWindAngle; - this.currentDrift = currentDrift; - this.currentSet = currentSet; - this.rudderAngle = rudderAngle; - } - - - //Getters and setters for message properties. - - - public byte getMessageVersionNumber() - { - return messageVersionNumber; - } - - public void setMessageVersionNumber(byte messageVersionNumber) - { - this.messageVersionNumber = messageVersionNumber; - } - - public long getTime() - { - return time; - } - - public void setTime(long time) - { - this.time = time; - } - - public int getSourceID() - { - return sourceID; - } - - public void setSourceID(int sourceID) - { - this.sourceID = sourceID; - } - - public int getSequenceNumber() - { - return sequenceNumber; - } - - public void setSequenceNumber(int sequenceNumber) - { - this.sequenceNumber = sequenceNumber; - } - - public byte getDeviceType() - { - return deviceType; - } - - public void setDeviceType(byte deviceType) - { - this.deviceType = deviceType; - } - - public int getLatitude() - { - return latitude; - } - - public void setLatitude(int latitude) - { - this.latitude = latitude; - } - - public int getLongitude() - { - return longitude; - } - - public void setLongitude(int longitude) - { - this.longitude = longitude; - } - - public int getAltitude() - { - return altitude; - } - - public void setAltitude(int altitude) - { - this.altitude = altitude; - } - - public int getHeading() - { - return heading; - } - - public void setHeading(int heading) - { - this.heading = heading; - } - - public short getPitch() - { - return pitch; - } - - public void setPitch(short pitch) - { - this.pitch = pitch; - } - - public short getRoll() - { - return roll; - } - - public void setRoll(short roll) - { - this.roll = roll; - } - - public int getBoatSpeed() - { - return boatSpeed; - } - - public void setBoatSpeed(int boatSpeed) - { - this.boatSpeed = boatSpeed; - } - - public int getBoatCOG() - { - return boatCOG; - } - - public void setBoatCOG(int boatCOG) - { - this.boatCOG = boatCOG; - } - - public int getBoatSOG() - { - return boatSOG; - } - - public void setBoatSOG(int boatSOG) - { - this.boatSOG = boatSOG; - } - - public int getApparentWindSpeed() - { - return apparentWindSpeed; - } - - public void setApparentWindSpeed(int apparentWindSpeed) - { - this.apparentWindSpeed = apparentWindSpeed; - } - - public short getApparentWindAngle() - { - return apparentWindAngle; - } - - public void setApparentWindAngle(short apparentWindAngle) - { - this.apparentWindAngle = apparentWindAngle; - } - - public int getTrueWindSpeed() - { - return trueWindSpeed; - } - - public void setTrueWindSpeed(int trueWindSpeed) - { - this.trueWindSpeed = trueWindSpeed; - } - - public short getTrueWindDirection() { - return trueWindDirection; - } - - public void setTrueWindDirection(short trueWindDirection) { - this.trueWindDirection = trueWindDirection; - } - - public short getTrueWindAngle() - { - return trueWindAngle; - } - - public void setTrueWindAngle(short trueWindAngle) - { - this.trueWindAngle = trueWindAngle; - } - - public int getCurrentDrift() - { - return currentDrift; - } - - public void setCurrentDrift(int currentDrift) - { - this.currentDrift = currentDrift; - } - - public int getCurrentSet() - { - return currentSet; - } - - public void setCurrentSet(int currentSet) - { - this.currentSet = currentSet; - } - - public short getRudderAngle() - { - return rudderAngle; - } - - public void setRudderAngle(short rudderAngle) - { - this.rudderAngle = rudderAngle; - } -} diff --git a/mock/src/main/java/seng302/Networking/Utils/MessageType.java b/mock/src/main/java/seng302/Networking/Utils/MessageType.java deleted file mode 100644 index fcdff527..00000000 --- a/mock/src/main/java/seng302/Networking/Utils/MessageType.java +++ /dev/null @@ -1,18 +0,0 @@ -package seng302.Networking.Utils; - -/** - * Created by hba56 on 21/04/17. - */ -public enum MessageType { - HEARTBEAT(1), RACESTATUS(12), DISPLAYTEXTMESSAGE(20), - XMLMESSAGE(26), RACESTARTSTATUS(27), YACHTEVENTCODE(29), YACHTACTIONCODE(31), - CHATTERTEXT(36), BOATLOCATION(37), MARKROUNDING(38), COURSEWIND(44), AVGWIND(47); - - private byte value; - - private MessageType(int value) { this.value = (byte)value; } - - public byte getValue() { - return value; - } -} diff --git a/mock/src/test/java/seng302/Data/BoatDataTest.java b/mock/src/test/java/seng302/Data/BoatDataTest.java new file mode 100644 index 00000000..14d3ff5a --- /dev/null +++ b/mock/src/test/java/seng302/Data/BoatDataTest.java @@ -0,0 +1,87 @@ +package seng302.Data; + + +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; +import seng302.DataInput.RaceDataSource; +import seng302.DataInput.RaceXMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; + +import static junit.framework.TestCase.assertTrue; + +/** + * Created by esa46 on 25/04/17. + */ +public class BoatDataTest { + + + private static final String ROOT_TAG = "BoatConfig"; + private static final String[] REQUIRED_TAGS = new String[]{ + "Boats", "GPSposition" + }; + private static final String[] REQUIRED_ATTRIBUTES = new String[]{ + "SourceID", "ShapeID", "HullNum", "StoweName", + "ShortName", "BoatName" + }; + + String result; + RaceDataSource raceDataSource; + + @Before + public void initReader() { + try { + raceDataSource = new RaceXMLReader("raceXML/bermuda_AC35.xml"); + BoatData boatData = new BoatData(raceDataSource.getBoats()); + result = boatData.createXML(); + + + } catch (IOException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + @Test + public void xmlHasAllNecessaryTags() { + + assertTrue(result.contains("<" + ROOT_TAG + ">")); + for (String tag : REQUIRED_TAGS) { + assertTrue(result.contains("<" + tag + ">") || result.contains("<" + tag + " ")); + } + } + + @Test + public void xmlHasAllNecessaryAttributes() { + + for (String attribute : REQUIRED_ATTRIBUTES) { + assertTrue(result.contains(attribute + "=")); + } + } + + @Test + public void allTagsAreTerminated() { + + for (String tag : REQUIRED_TAGS) { + int lastIndex = 0; + String openTag = "<" + tag + ">"; + String closeTag = ""; + while (lastIndex < result.length() && lastIndex > 0) { + lastIndex = result.indexOf(openTag, lastIndex); + if (lastIndex > 0) { + + lastIndex = result.indexOf(closeTag, lastIndex); + assertTrue(lastIndex > 0); + } + } + } + } + + + +} diff --git a/mock/src/test/java/seng302/Data/RaceDataTest.java b/mock/src/test/java/seng302/Data/RaceDataTest.java index 4033ca8e..378e20ed 100644 --- a/mock/src/test/java/seng302/Data/RaceDataTest.java +++ b/mock/src/test/java/seng302/Data/RaceDataTest.java @@ -3,14 +3,13 @@ package seng302.Data; import org.junit.Before; import org.junit.Test; import org.xml.sax.SAXException; -import seng302.Mock.RaceDataSource; -import seng302.RaceXMLReader; +import seng302.DataInput.RaceDataSource; +import seng302.DataInput.RaceXMLReader; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; /** * Created by esa46 on 25/04/17. @@ -18,7 +17,7 @@ import static org.junit.Assert.fail; public class RaceDataTest { private static final String ROOT_TAG = "Race"; - private static final String[] REQUIRED_TAGS = new String[] { + private static final String[] REQUIRED_TAGS = new String[]{ "RaceID", "RaceType", "CreationTimeDate", "RaceStartTime", "Participants", "Yacht", "CompoundMarkSequence", "Course", "CompoundMark", "Mark", "CourseLimit", "Limit" }; @@ -48,7 +47,7 @@ public class RaceDataTest { assertTrue(result.contains("<" + ROOT_TAG + ">")); for (String tag : REQUIRED_TAGS) { System.out.println(tag); - assertTrue(result.contains("<" + tag + ">") || result.contains("<" + tag + " ") ); + assertTrue(result.contains("<" + tag + ">") || result.contains("<" + tag + " ")); } } @@ -73,8 +72,8 @@ public class RaceDataTest { @Test public void idAndTypeAreEquivalent() { - String newId = result.substring(result.indexOf("" ) + 8, result.indexOf("")); - String newRaceType = result.substring(result.indexOf("" ) + 10, result.indexOf("")); + String newId = result.substring(result.indexOf("") + 8, result.indexOf("")); + String newRaceType = result.substring(result.indexOf("") + 10, result.indexOf("")); assertTrue(raceDataSource.getRaceId().equals(newId)); assertTrue(raceDataSource.getRaceType().equals(newRaceType)); diff --git a/mock/src/test/java/seng302/Data/RegattaDataTest.java b/mock/src/test/java/seng302/Data/RegattaDataTest.java new file mode 100644 index 00000000..c3040498 --- /dev/null +++ b/mock/src/test/java/seng302/Data/RegattaDataTest.java @@ -0,0 +1,74 @@ +package seng302.Data; + +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; +import seng302.DataInput.RaceDataSource; +import seng302.DataInput.RaceXMLReader; +import seng302.DataInput.RegattaDataSource; +import seng302.DataInput.RegattaXMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; + +import static junit.framework.TestCase.assertTrue; + +/** + * Created by esa46 on 25/04/17. + */ +public class RegattaDataTest { + + private static final String ROOT_TAG = "RegattaConfig"; + private static final String[] REQUIRED_TAGS = new String[]{ + "RegattaID", "RegattaName", "CourseName", "CentralLatitude", "CentralLongitude", + "CentralAltitude", "UtcOffset", "MagneticVariation" + }; + String result; + RegattaDataSource regattaDataSource; + + @Before + public void initReader() { + try { + regattaDataSource = new RegattaXMLReader("mockXML/regattaTest.xml"); + RegattaData regattaData = new RegattaData(regattaDataSource); + result = regattaData.createXML(); + + + } catch (IOException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + @Test + public void xmlHasAllNecessaryFields() { + + assertTrue(result.contains("<" + ROOT_TAG + ">")); + for (String tag : REQUIRED_TAGS) { + System.out.println(tag); + assertTrue(result.contains("<" + tag + ">") || result.contains("<" + tag + " ")); + } + } + + @Test + public void allTagsAreTerminated() { + + for (String tag : REQUIRED_TAGS) { + int lastIndex = 0; + String openTag = "<" + tag + ">"; + String closeTag = ""; + while (lastIndex < result.length() && lastIndex > 0) { + lastIndex = result.indexOf(openTag, lastIndex); + if (lastIndex > 0) { + + lastIndex = result.indexOf(closeTag, lastIndex); + assertTrue(lastIndex > 0); + } + } + } + } + +} diff --git a/mock/src/test/java/seng302/Mock/RegattaXMLTest.java b/mock/src/test/java/seng302/DataInput/RegattaXMLTest.java similarity index 86% rename from mock/src/test/java/seng302/Mock/RegattaXMLTest.java rename to mock/src/test/java/seng302/DataInput/RegattaXMLTest.java index bfc73b28..dd751e16 100644 --- a/mock/src/test/java/seng302/Mock/RegattaXMLTest.java +++ b/mock/src/test/java/seng302/DataInput/RegattaXMLTest.java @@ -1,13 +1,10 @@ -package seng302.Mock; +package seng302.DataInput; import org.junit.Before; import org.junit.Test; -import seng302.Model.Regatta; -import seng302.RegattaXMLReader; +import SharedModel.Regatta; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; /** * Created by jjg64 on 19/04/17. @@ -16,7 +13,7 @@ public class RegattaXMLTest { RegattaXMLReader regattaXMLReader; @Before - public void findFile(){ + public void findFile() { try { regattaXMLReader = new RegattaXMLReader("mockXML/regattaTest.xml", false); } catch (Exception e) { diff --git a/mock/src/test/java/seng302/Model/BoatInRaceTest.java b/mock/src/test/java/seng302/Model/BoatInRaceTest.java index dfbd4b04..2dd9554f 100644 --- a/mock/src/test/java/seng302/Model/BoatInRaceTest.java +++ b/mock/src/test/java/seng302/Model/BoatInRaceTest.java @@ -1,14 +1,10 @@ package seng302.Model; import javafx.scene.paint.Color; -import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; -import seng302.GPSCoordinate; +import SharedModel.*; -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertFalse; -import static junit.framework.TestCase.assertTrue; +import static junit.framework.TestCase.*; /** * Created by esa46 on 22/03/17. @@ -147,13 +143,13 @@ public class BoatInRaceTest { Marker endMarker = new Marker(new GPSCoordinate(50, 0)); Leg leg0deg = new Leg("Start", startMarker, endMarker, 0); boat.setCurrentLeg(leg0deg); - boat.setCurrentPosition(new GPSCoordinate(0,0)); + boat.setCurrentPosition(new GPSCoordinate(0, 0)); // Get latitude of endpoint of wake at 10 kn (longitude is 0) double endpointAt10Kn = boat.getWake().getLatitude(); // Latitude of endpoint at 20 kn should be twice endpoint at 10 kn boat.setVelocity(20); - assertEquals(2*endpointAt10Kn, boat.getWake().getLatitude(), 1e-8); + assertEquals(2 * endpointAt10Kn, boat.getWake().getLatitude(), 1e-8); } -} \ No newline at end of file +} diff --git a/mock/src/test/java/seng302/Model/LegTest.java b/mock/src/test/java/seng302/Model/LegTest.java index ef739253..d86b439e 100644 --- a/mock/src/test/java/seng302/Model/LegTest.java +++ b/mock/src/test/java/seng302/Model/LegTest.java @@ -2,10 +2,11 @@ package seng302.Model; import org.geotools.referencing.GeodeticCalculator; import org.junit.Test; -import seng302.Constants; -import seng302.GPSCoordinate; +import SharedModel.Constants; +import SharedModel.GPSCoordinate; +import SharedModel.Leg; +import SharedModel.Marker; -import java.awt.*; import java.awt.geom.Point2D; import static junit.framework.TestCase.assertEquals; diff --git a/mock/src/test/java/seng302/Model/MarkerTest.java b/mock/src/test/java/seng302/Model/MarkerTest.java index 2d76dafc..2331ae57 100644 --- a/mock/src/test/java/seng302/Model/MarkerTest.java +++ b/mock/src/test/java/seng302/Model/MarkerTest.java @@ -2,7 +2,8 @@ package seng302.Model; import org.junit.Ignore; import org.junit.Test; -import seng302.GPSCoordinate; +import SharedModel.GPSCoordinate; +import SharedModel.Marker; import static org.junit.Assert.assertTrue; diff --git a/mock/src/test/java/seng302/Model/RaceTest.java b/mock/src/test/java/seng302/Model/RaceTest.java index c65c5d76..a26e21d0 100644 --- a/mock/src/test/java/seng302/Model/RaceTest.java +++ b/mock/src/test/java/seng302/Model/RaceTest.java @@ -3,15 +3,12 @@ package seng302.Model; import javafx.scene.paint.Color; import org.junit.Ignore; import org.junit.Test; -import org.xml.sax.SAXException; -import seng302.GPSCoordinate; -import seng302.Mock.RaceDataSource; -import seng302.RaceXMLReader; +import SharedModel.BoatInRace; +import SharedModel.GPSCoordinate; +import SharedModel.Leg; +import SharedModel.Marker; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertEquals; @@ -27,7 +24,7 @@ public class RaceTest { @Ignore @Test - public void timerCanBeDisabled(){ + public void timerCanBeDisabled() { BoatInRace boat1 = new BoatInRace("Test 1", 10000, Color.ALICEBLUE, "t1", 1); BoatInRace boat2 = new BoatInRace("Test 2", 10000, Color.BURLYWOOD, "t2", 2); //BoatInRace[] boats = new BoatInRace[]{boat1, boat2}; @@ -36,9 +33,10 @@ public class RaceTest { boats.add(boat2); ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); legs.add(FINISH_LEG); + legs.add(START_LEG); + legs.add(FINISH_LEG); - Race race = new Race(boats, legs, 5); + Race race = new Race(boats, legs, 5, System.out); race.setDnfChance(0); long timeStarted = System.currentTimeMillis(); race.run(); @@ -59,7 +57,7 @@ public class RaceTest { ArrayList legs = new ArrayList<>(); legs.add(FINISH_LEG); - Race race = new Race(boats, legs, 1); + Race race = new Race(boats, legs, 1, System.out); race.setDnfChance(0); assertEquals(race.boatsFinished, 0); @@ -83,7 +81,7 @@ public class RaceTest { ArrayList legs = new ArrayList<>(); legs.add(FINISH_LEG); - Race race = new Race(boats, legs, 1); + Race race = new Race(boats, legs, 1, System.out); race.setDnfChance(0); assertEquals(race.boatsFinished, 0); @@ -101,7 +99,7 @@ public class RaceTest { legs.add(START_LEG); legs.add(FINISH_LEG); - Race race = new Race(boats, legs, 1); + Race race = new Race(boats, legs, 1, System.out); race.setDnfChance(0); BoatInRace unFinishedBoat = new BoatInRace("Test", 10, Color.ALICEBLUE, "tt", 1); @@ -145,7 +143,7 @@ public class RaceTest { float vel2 = (float) 1.999; float vel3 = (float) 32.5; float vel4 = 500; - BoatInRace boat1 = new BoatInRace("test", vel1, Color.ALICEBLUE, "tt",1); + BoatInRace boat1 = new BoatInRace("test", vel1, Color.ALICEBLUE, "tt", 1); BoatInRace boat2 = new BoatInRace("test", vel2, Color.ALICEBLUE, "tt", 2); BoatInRace boat3 = new BoatInRace("test", vel3, Color.ALICEBLUE, "tt", 3); BoatInRace boat4 = new BoatInRace("test", vel4, Color.ALICEBLUE, "tt", 4); @@ -158,7 +156,7 @@ public class RaceTest { ArrayList legs = new ArrayList<>(); legs.add(START_LEG); - Race race = new Race(boats, legs, scaleFactor); + Race race = new Race(boats, legs, scaleFactor, System.out); race.setDnfChance(0); assertEquals(race.getStartingBoats().get(0).getScaledVelocity(), vel1 * scaleFactor, 1e-6); @@ -176,7 +174,7 @@ public class RaceTest { ArrayList legs = new ArrayList<>(); legs.add(START_LEG); - Race race = new Race(boats, legs, scaleFactor); + Race race = new Race(boats, legs, scaleFactor, System.out); race.totalTimeElapsed = 6000; //6 seconds assertTrue(race.calcTimer().equals("Race clock: 00:01:00")); } @@ -190,7 +188,7 @@ public class RaceTest { ArrayList legs = new ArrayList<>(); legs.add(START_LEG); - Race race = new Race(boats, legs, scaleFactor); + Race race = new Race(boats, legs, scaleFactor, System.out); race.totalTimeElapsed = 3213000; assertTrue(race.calcTimer().equals("Race clock: 02:40:39")); diff --git a/mock/src/test/java/seng302/Model/RaceXMLTest.java b/mock/src/test/java/seng302/Model/RaceXMLTest.java index 481e7e37..1450860d 100644 --- a/mock/src/test/java/seng302/Model/RaceXMLTest.java +++ b/mock/src/test/java/seng302/Model/RaceXMLTest.java @@ -2,23 +2,20 @@ package seng302.Model;/** * Created by Gondr on 26/03/2017. */ -import static org.junit.Assert.*; - import org.junit.Ignore; import org.junit.Test; -import org.xml.sax.SAXException; -import seng302.RaceXMLReader; +import seng302.DataInput.RaceXMLReader; +import SharedModel.BoatInRace; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.util.ArrayList; import java.util.List; +import static org.junit.Assert.*; + public class RaceXMLTest { RaceXMLReader raceXMLReader; @Test - public void canFindFile(){ + public void canFindFile() { try { RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); } catch (Exception e) { @@ -28,7 +25,7 @@ public class RaceXMLTest { @Ignore @Test - public void canReadBoats(){ + public void canReadBoats() { try { RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); raceXMLReader.readBoats(); @@ -63,7 +60,7 @@ public class RaceXMLTest { } @Test - public void canReadLegs(){ + public void canReadLegs() { try { RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); raceXMLReader.readLegs(); @@ -74,7 +71,7 @@ public class RaceXMLTest { } @Test - public void canReadCourse(){ + public void canReadCourse() { try { RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false); raceXMLReader.readCourse(); @@ -96,4 +93,4 @@ public class RaceXMLTest { } } -} \ No newline at end of file +} diff --git a/mock/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java b/mock/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java deleted file mode 100644 index 86396674..00000000 --- a/mock/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package seng302.Networking.MessageDecoders; - -import javafx.scene.paint.Color; -import org.junit.Assert; -import org.junit.Test; -import seng302.Model.BoatInRace; -import seng302.Model.Leg; -import seng302.Networking.MessageDecoders.RaceStatusDecoder; -import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; - -import java.util.ArrayList; - -/** - * Created by hba56 on 23/04/17. - */ -public class RaceStatusDecoderTest { - @Test - public void getByteArrayTest(){ - long time = System.currentTimeMillis(); - BoatInRace boat1 = new BoatInRace("Test", 1, Color.ALICEBLUE, "tt", 1); - Leg testLeg = new Leg("test leg", 1); - boat1.setCurrentLeg(testLeg); - BoatInRace boat2 = new BoatInRace("Test2", 1, Color.ALICEBLUE, "tt", 1); - boat2.setCurrentLeg(testLeg); - ArrayList boats = new ArrayList(); - boats.add(boat1); - boats.add(boat2); - long time2 = System.currentTimeMillis(); - - RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder(); - - byte[] encodedRaceStatus = raceVisionByteEncoder.raceStatus(time, 1, 2, time2, - (short)2, (short)3,4, boats); - - RaceStatusDecoder decoderTest = new RaceStatusDecoder(encodedRaceStatus); - - Assert.assertEquals(0b10, decoderTest.getVersionNum()); - Assert.assertEquals(time, decoderTest.getTime()); - Assert.assertEquals(1, decoderTest.getRace()); - Assert.assertEquals(2, decoderTest.getRaceState()); - Assert.assertEquals(time2, decoderTest.getStartTime()); - Assert.assertEquals((short)2, decoderTest.getRaceWindDir()); - Assert.assertEquals((short)3, decoderTest.getRaceWindSpeed()); - - Assert.assertEquals(0, decoderTest.getBoats().get(0).getBoatStatus()); - Assert.assertEquals(0, decoderTest.getBoats().get(0).getLegNumber()); - Assert.assertEquals(0, decoderTest.getBoats().get(0).getNumPenaltiesAwarded()); - - } -} diff --git a/mock/src/test/resources/mockXML/boatXML/boatTest.xml b/mock/src/test/resources/mockXML/boatXML/boatTest.xml index 738502a5..51f788b0 100644 --- a/mock/src/test/resources/mockXML/boatXML/boatTest.xml +++ b/mock/src/test/resources/mockXML/boatXML/boatTest.xml @@ -8,13 +8,13 @@ - + - + - + - + @@ -24,13 +24,13 @@ - + - + - + - + @@ -40,13 +40,13 @@ - + - + - + - + @@ -56,13 +56,13 @@ - + - + - + - + @@ -72,13 +72,13 @@ - + - + - + - + @@ -88,83 +88,83 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -174,9 +174,9 @@ BoatName="Regardless"> - + - + @@ -184,9 +184,9 @@ BoatName="Constellation"> - + - + @@ -194,17 +194,17 @@ BoatName="Mischief"> - + - + - + - + @@ -212,9 +212,9 @@ BoatName="Volunteer"> - + - + @@ -222,17 +222,17 @@ BoatName="Defender"> - + - + - + - + @@ -240,9 +240,9 @@ BoatName="TEAM KOREA" Country="KOR"> - + - + diff --git a/mock/src/test/resources/raceXML/Boats.xml b/mock/src/test/resources/raceXML/Boats.xml index ed4b6ded..b94f09fb 100644 --- a/mock/src/test/resources/raceXML/Boats.xml +++ b/mock/src/test/resources/raceXML/Boats.xml @@ -4,116 +4,116 @@ 2017-04-19T15:49:40+1200 1 - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - + > - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/mock/src/test/resources/raceXML/Race.xml b/mock/src/test/resources/raceXML/Race.xml index 29478c60..88a1be01 100644 --- a/mock/src/test/resources/raceXML/Race.xml +++ b/mock/src/test/resources/raceXML/Race.xml @@ -2,43 +2,43 @@ 17041901 Fleet - 2017-04-19T15:30:00+1200 - + 2017-04-19T15:30:00+1200 + - - - - - - + + + + + + - - + + - + - - + + - - + + - - + + - - - - - + + + + + diff --git a/network/pom.xml b/network/pom.xml new file mode 100644 index 00000000..40087f2d --- /dev/null +++ b/network/pom.xml @@ -0,0 +1,146 @@ + + 4.0.0 + + seng302 + team-7 + 1.0-SNAPSHOT + + + jar + network + network + 1.0-SNAPSHOT + + + + + seng302 + sharedModel + 1.0-SNAPSHOT + + + + + junit + junit + 4.12 + test + + + + + + + org.mockito + mockito-all + 1.9.5 + + + + + + org.testng + testng + 6.11 + test + + + + + + + + maven2-repository.dev.java.net + Java.net repository + http://download.java.net/maven/2 + + + + + + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + + + seng302.App + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + package + + shade + + + + + + + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.5 + + + org.apache.maven.plugins + maven-pmd-plugin + 3.6 + + true + ${maven.compiler.target} + + /rulesets/java/basic.xml + /rulesets/java/imports.xml + /rulesets/java/codesize.xml + /rulesets/java/design.xml + /rulesets/java/empty.xml + /rulesets/java/junit.xml + /rulesets/java/unusedcode.xml + + true + utf-8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.19.1 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8.1 + + + + diff --git a/mock/src/main/java/seng302/Networking/BinaryMesageEncoder.java b/network/src/main/java/seng302/Networking/BinaryMesageEncoder.java similarity index 79% rename from mock/src/main/java/seng302/Networking/BinaryMesageEncoder.java rename to network/src/main/java/seng302/Networking/BinaryMesageEncoder.java index a4f94c91..9b0fa70e 100644 --- a/mock/src/main/java/seng302/Networking/BinaryMesageEncoder.java +++ b/network/src/main/java/seng302/Networking/BinaryMesageEncoder.java @@ -7,6 +7,10 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.zip.CRC32; +import static seng302.Networking.Utils.ByteConverter.intToBytes; +import static seng302.Networking.Utils.ByteConverter.longToBytes; +import static seng302.Networking.Utils.ByteConverter.shortToBytes; + /** * Created by hba56 on 21/04/17. */ @@ -34,7 +38,7 @@ public class BinaryMesageEncoder { tempHeaderByteBuffer.put(this.headerSync1); tempHeaderByteBuffer.put(this.headerSync2); tempHeaderByteBuffer.put(this.headerMessageType); - tempHeaderByteBuffer.put(longToSixBytes(this.headerTimeStamp)); + tempHeaderByteBuffer.put(longToBytes(this.headerTimeStamp, 6)); tempHeaderByteBuffer.putInt(this.headerSourceID); tempHeaderByteBuffer.put(shortToBytes(this.headerMessageLength)); @@ -59,26 +63,6 @@ public class BinaryMesageEncoder { tempMessageByteBuffer.put(intToBytes((int) crc.getValue())); this.fullMessage = tempMessageByteBuffer.array(); - - - } - - private byte[] longToSixBytes(long x) { - ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); - buffer.putLong(x); - return Arrays.copyOfRange(buffer.array(), 2, 8); - } - - private byte[] shortToBytes(short x) { - ByteBuffer buffer = ByteBuffer.allocate(Short.BYTES); - buffer.putShort(x); - return buffer.array(); - } - - private byte[] intToBytes(int x) { - ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); - buffer.putInt(x); - return buffer.array(); } public byte[] getFullMessage() { diff --git a/network/src/main/java/seng302/Networking/BinaryMessageDecoder.java b/network/src/main/java/seng302/Networking/BinaryMessageDecoder.java new file mode 100644 index 00000000..735d4d6e --- /dev/null +++ b/network/src/main/java/seng302/Networking/BinaryMessageDecoder.java @@ -0,0 +1,165 @@ +package seng302.Networking; + +import seng302.Networking.MessageDecoders.*; +import seng302.Networking.Utils.*; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.zip.CRC32; + +/** + * Created by hba56 on 21/04/17. + */ +public class BinaryMessageDecoder { + private byte[] fullMessage; + private byte[] header; + private byte[] message; + private byte[] crc; + + private byte headerSync1; + private byte headerSync2; + private byte headerMessageType; + private byte[] headerTimeStamp; + private byte[] headerSourceID; + private byte[] headerMessageLength; + + + public BinaryMessageDecoder(byte[] fullMessage) { + this.fullMessage = fullMessage; + } + + public AC35Data decode() throws IndexOutOfBoundsException{ + //get the header + this.header = Arrays.copyOfRange(this.fullMessage, 0, 15); + + this.headerSync1 = this.header[0]; + this.headerSync2 = this.header[1]; + this.headerMessageType = this.header[2]; + this.headerTimeStamp = Arrays.copyOfRange(this.header, 3, 9); + this.headerSourceID = Arrays.copyOfRange(this.header, 9, 13); + this.headerMessageLength = Arrays.copyOfRange(this.header, 13, 15); + + if (15 > this.fullMessage.length - 4){ + //System.err.println("Message is too short."); + return null; + } + //get message + this.message = Arrays.copyOfRange(this.fullMessage, 15, this.fullMessage.length - 4); + + //get crc + this.crc = Arrays.copyOfRange(this.fullMessage, this.fullMessage.length - 4, fullMessage.length); + + + CRC32 crc = new CRC32(); + crc.reset(); + crc.update(this.fullMessage); + + //run through the checks + if (this.message.length != ByteConverter.bytesToShort(this.headerMessageLength)){//keep like this - hba65 + System.err.println("message length in header does not equal the message length"); + System.err.println("message length in header: " + ByteConverter.bytesToInt(this.headerMessageLength)); + System.err.println("message length: " + this.message.length); + return null; + }else if(this.headerSync1 != 0x47){ + System.err.println("Sync byte 1 is wrong: " + this.headerSync1); + return null; + }else if(this.headerSync2 !=(byte) 0x83){ + System.err.println("Sync byte 2 is wrong: " + this.headerSync2); + return null; + }/*else if(crc.getValue() != 0){ + //todo check crc + System.err.println("CRC is not 0 and is instead:" + crc.getValue()); + return; + }*/ + + MessageType mType = MessageType.valueOf(this.headerMessageType); + AC35Data data = null; + + switch(mType){ + case HEARTBEAT: +// System.out.println("HeartBeat Message!"); + data = new Heartbeat(); + break; + case RACESTATUS: +// System.out.println("Race Status Message"); + RaceStatusDecoder rsdecoder = new RaceStatusDecoder(this.message); + data = new RaceStatus(rsdecoder.getTime(), rsdecoder.getRace(), rsdecoder.getRaceState(), rsdecoder.getStartTime(), rsdecoder.getRaceWindDir(), rsdecoder.getRaceWindSpeed(), rsdecoder.getRaceType(), rsdecoder.getBoats()); + break; + case DISPLAYTEXTMESSAGE: +// System.out.println("Display Text Message"); + //no decoder for this. + break; + case XMLMESSAGE: +// System.out.println("XML Message!"); + XMLMessageDecoder xmdecoder = new XMLMessageDecoder(this.message); + xmdecoder.decode(); + data = new XMLMessage(xmdecoder.getAckNumber(), xmdecoder.getTimeStamp(), xmdecoder.getXmlMsgSubType(), xmdecoder.getSequenceNumber(), xmdecoder.getXmlMsgLength(), xmdecoder.getXmlMessageInputSource()); + break; + case RACESTARTSTATUS: +// System.out.println("Race Start Status Message"); + RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder(this.message); + data = new RaceStartStatus(rssDecoder.getTime(), rssDecoder.getAck(), rssDecoder.getStartTime(), rssDecoder.getRaceID(), rssDecoder. getNotification()); + break; + case YACHTEVENTCODE: +// System.out.println("Yacht Action Code!"); + //no decoder + break; + case YACHTACTIONCODE: +// System.out.println("Yacht Action Code!"); + //no decoder + break; + case CHATTERTEXT: +// System.out.println("Chatter Text Message!"); + //no decoder + break; + case BOATLOCATION: +// System.out.println("Boat Location Message!"); + BoatLocationDecoder blDecoder = new BoatLocationDecoder(this.message); + data = blDecoder.getMessage(); + break; + case MARKROUNDING: +// System.out.println("Mark Rounding Message!"); + MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder(this.message); + data = mrDecoder.getMarkRounding(); + break; + case COURSEWIND: +// System.out.println("Couse Wind Message!"); + CourseWindDecoder cwDecoder = new CourseWindDecoder(this.message); + data =new CourseWinds(cwDecoder.getMessageVersionNumber(), cwDecoder.getByteWindID(), cwDecoder.getLoopMessages()); + break; + case AVGWIND: +// System.out.println("Average Wind Message!"); + AverageWindDecoder awDecoder = new AverageWindDecoder(this.message); + data = awDecoder.getAverageWind(); + break; + default: +// System.out.println("Broken Message!"); + break; + } + + return data; + } + + + public long getTimeStamp() { + return ByteConverter.bytesToLong(this.headerTimeStamp); + } + + public int getSourceID() { + return ByteConverter.bytesToInt(this.headerSourceID, ByteOrder.BIG_ENDIAN); + } + + public short getMessageLength() { + return ByteConverter.bytesToShort(this.headerMessageLength); + } + + public int getMessageType(){ + return (int) this.headerMessageType; + } + + public byte[] getMessage() { + return message; + } +} + diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java similarity index 53% rename from mock/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java index 2411ba04..7497f7b5 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/AverageWindDecoder.java @@ -1,5 +1,8 @@ package seng302.Networking.MessageDecoders; +import seng302.Networking.Utils.AverageWind; +import seng302.Networking.Utils.ByteConverter; + import java.util.Arrays; /** @@ -17,6 +20,8 @@ public class AverageWindDecoder { byte[] bytePeriod4; byte[] byteSpeed4; + AverageWind averageWind; + public AverageWindDecoder(byte[] encodedAverageWind) { messageVersionNumber = encodedAverageWind[0]; byteTime = Arrays.copyOfRange(encodedAverageWind, 1, 7); @@ -28,5 +33,23 @@ public class AverageWindDecoder { byteSpeed3 = Arrays.copyOfRange(encodedAverageWind, 17, 19); bytePeriod4 = Arrays.copyOfRange(encodedAverageWind, 19, 21); byteSpeed4 = Arrays.copyOfRange(encodedAverageWind, 21, 23); + + int msgNum = ByteConverter.bytesToInt(messageVersionNumber); + long lngTime = ByteConverter.bytesToLong(byteTime); + int intRawPeriod = ByteConverter.bytesToInt(byteRawPeriod); + int intRawSpeed = ByteConverter.bytesToInt(byteRawSpeed); + int intPeriod2 = ByteConverter.bytesToInt(bytePeriod2); + int intSpeed2 = ByteConverter.bytesToInt(byteSpeed2); + int intPeriod3 = ByteConverter.bytesToInt(bytePeriod3); + int intSpeed3 = ByteConverter.bytesToInt(byteSpeed3); + int intPeriod4 = ByteConverter.bytesToInt(bytePeriod4); + int intSpeed4 = ByteConverter.bytesToInt(byteSpeed4); + + this.averageWind = new AverageWind(msgNum, lngTime, intRawPeriod, intRawSpeed, intPeriod2, intSpeed2, intPeriod3, intSpeed3, intPeriod4, intSpeed4); + + } + + public AverageWind getAverageWind() { + return averageWind; } } diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java similarity index 62% rename from mock/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java index cb492f51..91c8088c 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java @@ -6,6 +6,8 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; +import static seng302.Networking.Utils.ByteConverter.*; + /** * Created by hba56 on 21/04/17. */ @@ -63,55 +65,16 @@ public class BoatLocationDecoder { bytesToInt(sourceID), bytesToInt(seqNum), deviceType, bytesToInt(latitude), bytesToInt(longitude), bytesToInt(altitude), - twoByteToInt(heading), bytesToShort(pitch), - bytesToShort(roll), twoByteToInt(boatSpeed), - twoByteToInt(cog), twoByteToInt(sog), - twoByteToInt(apparentWindSpeed), bytesToShort(apparentWindAngle), - twoByteToInt(trueWindSpeed), bytesToShort(trueWindDirection), - bytesToShort(trueWindAngle), twoByteToInt(currentDrift), - twoByteToInt(currentSet), bytesToShort(rudderAngle) + bytesToInt(heading), bytesToShort(pitch), + bytesToShort(roll), bytesToInt(boatSpeed), + bytesToInt(cog), bytesToInt(sog), + bytesToInt(apparentWindSpeed), bytesToShort(apparentWindAngle), + bytesToInt(trueWindSpeed), bytesToShort(trueWindDirection), + bytesToShort(trueWindAngle), bytesToInt(currentDrift), + bytesToInt(currentSet), bytesToShort(rudderAngle) ); } - private int twoByteToInt(byte[] bytesInt){ - ByteBuffer byteBuffer = ByteBuffer.allocate(4); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesInt); - int num = byteBuffer.getInt(0); - - return num; - } - - private int bytesToInt(byte[] bytesInt){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); - int num = wrapped.getInt(); - return num; - } - - private short bytesToShort(byte[] bytesShort){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); - short num = wrapped.getShort(); - return num; - } - - - private long bytesToLong(byte[] bytesLong){ - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesLong); -// byteBuffer.put(bytesLong[0]); -// byteBuffer.put(bytesLong[1]); -// byteBuffer.put(bytesLong[2]); -// byteBuffer.put(bytesLong[3]); -// byteBuffer.put(bytesLong[4]); -// byteBuffer.put(bytesLong[5]); - long longVal = byteBuffer.getLong(0); - return longVal; - } public BoatLocationMessage getMessage() { return message; diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java similarity index 59% rename from mock/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java index 3ef7b905..904cb4a5 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java @@ -7,6 +7,8 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; +import static seng302.Networking.Utils.ByteConverter.*; + /** * Created by hba56 on 23/04/17. */ @@ -38,49 +40,24 @@ public class CourseWindDecoder { byte[] flags = Arrays.copyOfRange(messageBytes, 19, 20); CourseWind message = new CourseWind(windId[0], bytesToLong(time), - bytesToInt(raceID), twoByteToInt(windDirection), - twoByteToInt(windSpeed), twoByteToInt(bestUpwindAngle), - twoByteToInt(bestDownwindAngle), flags[0]); + bytesToInt(raceID), bytesToInt(windDirection), + bytesToInt(windSpeed), bytesToInt(bestUpwindAngle), + bytesToInt(bestDownwindAngle), flags[0]); loopMessages.add(message); messageLoopIndex += 20; } } - private int twoByteToInt(byte[] bytesInt){ - ByteBuffer byteBuffer = ByteBuffer.allocate(4); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesInt); - int num = byteBuffer.getInt(0); - - return num; - } - - - private int bytesToInt(byte[] bytesInt){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); - int num = wrapped.getInt(); - return num; + public ArrayList getLoopMessages() { + return loopMessages; } - private long bytesToLong(byte[] bytesLong){ - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesLong[0]); - byteBuffer.put(bytesLong[1]); - byteBuffer.put(bytesLong[2]); - byteBuffer.put(bytesLong[3]); - byteBuffer.put(bytesLong[4]); - byteBuffer.put(bytesLong[5]); - long longVal = byteBuffer.getLong(0); - return longVal; + public byte getMessageVersionNumber() { + return messageVersionNumber; } - public ArrayList getLoopMessages() { - return loopMessages; + public byte getByteWindID() { + return byteWindID; } } diff --git a/network/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java new file mode 100644 index 00000000..1080e73a --- /dev/null +++ b/network/src/main/java/seng302/Networking/MessageDecoders/MarkRoundingDecoder.java @@ -0,0 +1,51 @@ +package seng302.Networking.MessageDecoders; + +import seng302.Networking.Utils.ByteConverter; +import seng302.Networking.Utils.MarkRounding; + +import java.util.Arrays; + +/** + * Created by hba56 on 23/04/17. + */ +public class MarkRoundingDecoder { + byte messageVersionNumber; + byte[] byteTime; + byte[] byteAck; + byte[] byteRaceID; + byte[] byteSourceID; + byte byteBoatStatus; + byte byteRoundingSide; + byte byteMarkType; + byte byteMarkID; + + MarkRounding markRounding; + + public MarkRoundingDecoder(byte[] encodedMarkRounding) { + messageVersionNumber = encodedMarkRounding[0]; + byteTime = Arrays.copyOfRange(encodedMarkRounding, 1, 7); + byteAck = Arrays.copyOfRange(encodedMarkRounding, 7, 9); + byteRaceID = Arrays.copyOfRange(encodedMarkRounding, 9, 13); + byteSourceID = Arrays.copyOfRange(encodedMarkRounding, 13, 17); + byteBoatStatus = encodedMarkRounding[17]; + byteRoundingSide = encodedMarkRounding[18]; + byteMarkType = encodedMarkRounding[19]; + byteMarkID = encodedMarkRounding[20]; + + int intMsgVer = ByteConverter.bytesToInt(messageVersionNumber); + long lngTime = ByteConverter.bytesToLong(byteTime); + int intAck = ByteConverter.bytesToInt(byteAck); + int intRaceID = ByteConverter.bytesToInt(byteRaceID); + int intSourceID = ByteConverter.bytesToInt(byteSourceID); + int intBoatState = ByteConverter.bytesToInt(byteBoatStatus); + int intRoundingSide = ByteConverter.bytesToInt(byteRoundingSide); + int intMarkType = ByteConverter.bytesToInt(byteMarkType); + int intMarkID = ByteConverter.bytesToInt(byteMarkID); + + markRounding = new MarkRounding(intMsgVer, lngTime, intAck, intRaceID, intSourceID, intBoatState, intRoundingSide, intMarkType, intMarkID); + } + + public MarkRounding getMarkRounding() { + return markRounding; + } +} diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java similarity index 56% rename from mock/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java index 76179872..81a924ed 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java @@ -1,12 +1,14 @@ package seng302.Networking.MessageDecoders; -import seng302.Model.BoatInRace; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; +import static seng302.Networking.Utils.ByteConverter.*; + /** * Created by hba56 on 21/04/17. */ @@ -37,44 +39,9 @@ public class RaceStartStatusDecoder { ack = bytesToShort(ackNumber); startTime = bytesToLong(raceStartTime); raceID = bytesToInt(raceIdentifier); - notification = byteToChar(notificationType); + notification = bytesToChar(notificationType); } - private char byteToChar(byte bytesInt){ - ByteBuffer byteBuffer = ByteBuffer.allocate(4); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put(bytesInt); - char num = byteBuffer.getChar(0); - return num; - } - - private short bytesToShort(byte[] bytesShort){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); - short num = wrapped.getShort(); - return num; - } - - private int bytesToInt(byte[] bytesInt){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); - int num = wrapped.getInt(); - return num; - } - - private long bytesToLong(byte[] bytesLong){ - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesLong[0]); - byteBuffer.put(bytesLong[1]); - byteBuffer.put(bytesLong[2]); - byteBuffer.put(bytesLong[3]); - byteBuffer.put(bytesLong[4]); - byteBuffer.put(bytesLong[5]); - long longVal = byteBuffer.getLong(0); - return longVal; - } public byte getMessageVersion() { return messageVersion; diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java similarity index 65% rename from mock/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java index 5199cc44..11e2b57f 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java @@ -7,6 +7,8 @@ import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; +import static seng302.Networking.Utils.ByteConverter.*; + /** * Created by hba56 on 21/04/17. */ @@ -26,7 +28,7 @@ public class RaceStatusDecoder { private int race; private int raceState; private long startTime; - private short raceWindDir; + private int raceWindDir; private short raceWindSpeed; private int numberOfBoats; private int raceType; @@ -47,24 +49,24 @@ public class RaceStatusDecoder { time = bytesToLong(timeBytes); race = bytesToInt(raceID); - raceState = byteToInt(raceStatus); + raceState = bytesToInt(raceStatus); startTime = bytesToLong(expectedStart); - raceWindDir = bytesToShort(raceWind); + raceWindDir = bytesToInt(raceWind); raceWindSpeed = bytesToShort(windSpeed); - numberOfBoats = byteToInt(numBoats); + numberOfBoats = bytesToInt(numBoats); int boatLoopIndex = 0; for (int i=0; i < numberOfBoats; i++) { byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex+20); - byte[] sourceID = Arrays.copyOfRange(boatBytes, 1, 5); - byte boatStatus = boatBytes[5]; - byte legNumber = boatBytes[6]; - byte numPenaltiesAwarded = boatBytes[7]; - byte numPenaltiesServed = boatBytes[8]; - byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 9, 15); - byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 15, 20); + byte[] sourceID = Arrays.copyOfRange(boatBytes, 0, 3); + byte boatStatus = boatBytes[4]; + byte legNumber = boatBytes[5]; + byte numPenaltiesAwarded = boatBytes[6]; + byte numPenaltiesServed = boatBytes[7]; + byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 8, 14); + byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 14, 20); BoatStatus boat = new BoatStatus(bytesToInt(sourceID),boatStatus, legNumber, numPenaltiesAwarded, numPenaltiesServed, @@ -75,39 +77,6 @@ public class RaceStatusDecoder { } } - private int byteToInt(byte bytesInt){ - ByteBuffer byteBuffer = ByteBuffer.allocate(4); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesInt); - int intVal = byteBuffer.getInt(0); - return intVal; - } - - private short bytesToShort(byte[] bytesShort){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); - short num = wrapped.getShort(); - return num; - } - - private int bytesToInt(byte[] bytesInt){ - ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); - int num = wrapped.getInt(); - return num; - } - - private long bytesToLong(byte[] bytesLong) { - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte) 0); - byteBuffer.put((byte) 0); - byteBuffer.put(bytesLong); - long longVal = byteBuffer.getLong(0); - return longVal; - } - public byte getVersionNum() { return versionNum; } @@ -128,7 +97,7 @@ public class RaceStatusDecoder { return startTime; } - public short getRaceWindDir() { + public int getRaceWindDir() { return raceWindDir; } diff --git a/mock/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java b/network/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java similarity index 72% rename from mock/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java rename to network/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java index a361ca50..bdae4db7 100644 --- a/mock/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java +++ b/network/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java @@ -1,9 +1,14 @@ package seng302.Networking.MessageDecoders; +import org.xml.sax.InputSource; + +import java.io.StringReader; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; +import static seng302.Networking.Utils.ByteConverter.bytesToLong; + /** * Created by hba56 on 20/04/17. */ @@ -49,29 +54,6 @@ public class XMLMessageDecoder { return shortVal; } - private long bytesToLong(byte[] bytesLong){ - ByteBuffer byteBuffer = ByteBuffer.allocate(8); - byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put(bytesLong[0]); - byteBuffer.put(bytesLong[1]); - byteBuffer.put(bytesLong[2]); - byteBuffer.put(bytesLong[3]); - byteBuffer.put(bytesLong[4]); - byteBuffer.put(bytesLong[5]); - -// System.out.println("====decode===="); -// for (byte i:byteBuffer.array() -// ) { -// System.out.println(i); -// } -// System.out.println("====decode===="); - - long longVal = byteBuffer.getLong(0); - return longVal; - } - public byte getMessageVersionNumber() { return messageVersionNumber; } @@ -96,7 +78,12 @@ public class XMLMessageDecoder { return xmlMsgLength; } - public String getXmlMessage() { - return xmlMessage; + /** + * this will be used latter for the vis + * @return xml string as inputsource + */ + public InputSource getXmlMessageInputSource() { + InputSource is = new InputSource(new StringReader(xmlMessage)); + return is; } } diff --git a/network/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java b/network/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java new file mode 100644 index 00000000..f8117c90 --- /dev/null +++ b/network/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java @@ -0,0 +1,299 @@ +package seng302.Networking.MessageEncoders; + + +import seng302.Networking.Utils.*; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; + +import static seng302.Networking.Utils.ByteConverter.*; + +/** + * Created by fwy13 on 19/04/17. + */ +public class RaceVisionByteEncoder { + + /** + * Serializes a heartbeat message. + * @param seq Heartbeat value. + * @return Serialized message. + */ + public static byte[] heartBeat(long seq){ + ByteBuffer heartBeat = ByteBuffer.allocate(4); + heartBeat.put(longToBytes(seq, 4)); + byte [] result = heartBeat.array(); + return result; + } + + /** + * Serializes a RaceStatus message. + * @param raceStatus Message to serialize. + * @return Serialized (byte array) message, ready to be written to a socket. + */ + public static byte[] raceStatus(RaceStatus raceStatus){ + + ArrayList boatStatuses = raceStatus.getBoatStatuses(); + + ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boatStatuses.size()); + //Version Number 1 bytes + byte versionNum = 0b10; //this changes with the pdf. (2) + byte[] timeBytes = longToBytes(raceStatus.getCurrentTime(), 6);//time (6 bytes) + byte[] raceID = ByteBuffer.allocate(4).put(intToBytes(raceStatus.getRaceID())).array();//race identifier incase multiple races are going at once. + byte[] raceStatusByte = intToBytes(raceStatus.getRaceStatus(), 1);//race status 0 - 10 + byte[] expectedStart = longToBytes(raceStatus.getExpectedStartTime(), 6);//number of milliseconds from Jan 1, 1970 for when the data is valid + byte[] raceWind = ByteBuffer.allocate(2).put(intToBytes(raceStatus.getWindDirection(), 2)).array();//North = 0x0000 East = 0x4000 South = 0x8000. + byte[] windSpeed = ByteBuffer.allocate(2).put(intToBytes(raceStatus.getWindSpeed(), 2)).array();//mm/sec + byte[] numBoats = intToBytes(boatStatuses.size(), 1); + byte[] bytesRaceType = intToBytes(raceStatus.getRaceType(), 1);//1 match race, 2 fleet race + + raceStatusMessage.put(versionNum); + raceStatusMessage.put(timeBytes); + raceStatusMessage.put(raceID); + raceStatusMessage.put(raceStatusByte); + raceStatusMessage.put(expectedStart); + raceStatusMessage.put(raceWind); + raceStatusMessage.put(windSpeed); + raceStatusMessage.put(numBoats); + raceStatusMessage.put(bytesRaceType); + + for (int i = 0; i < boatStatuses.size(); i++){ + byte[] sourceID = intToBytes(boatStatuses.get(i).getSourceID()); + byte[] boatStatus = intToBytes(boatStatuses.get(i).getBoatStatus(), 1); + byte[] legNum = intToBytes(boatStatuses.get(i).getLegNumber(), 1); + byte[] numPenalties = intToBytes(boatStatuses.get(i).getNumPenaltiesAwarded(), 1); + byte[] numPenaltiesServed = intToBytes(boatStatuses.get(i).getNumPenaltiesServed(), 1); + byte[] estNextMarkTime = longToBytes(boatStatuses.get(i).getEstTimeAtNextMark(), 6); + byte[] estFinishTime = longToBytes( boatStatuses.get(i).getEstTimeAtFinish(), 6); + + raceStatusMessage.put(sourceID); + raceStatusMessage.put(boatStatus); + raceStatusMessage.put(legNum); + raceStatusMessage.put(numPenalties); + raceStatusMessage.put(numPenaltiesServed); + raceStatusMessage.put(estNextMarkTime); + raceStatusMessage.put(estFinishTime); + } + + return raceStatusMessage.array(); + } + + public byte[] displayTextMessage(RaceMessage[] message){ + //ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32); + int messageVersionNumber = 0b1;//version number + short ackNum = 0;//no clue what this does just a placeholder for 2 bytes. + byte[] messLines = intToBytes(message.length, 1); + +// result.putInt(messageVersionNumber); +// result.putShort(ackNum); +// result.put(messLines); + + ArrayList messages = new ArrayList(); + int size = 4; + + for (int i = 0; i < message.length; i ++){ + int messageLen = message[i].getMessageText().getBytes().length; + byte[] messageAsBytes = message[i].getMessageText().getBytes(); + if (messageLen < 30){ + messageLen = 30; + } + ByteBuffer mess = ByteBuffer.allocate(2 + messageLen); + mess.put(intToBytes(message[i].getLineNumber(), 1)); + mess.put(intToBytes(messageLen, 1)); + for (int j = 0; j < messageLen; j ++){ + mess.put(messageAsBytes[j]); + } + messages.add(mess.array()); + size += 2 + messageLen; + } + + ByteBuffer result = ByteBuffer.allocate(size); + result.put(intToBytes(messageVersionNumber, 1)); + result.putShort(ackNum); + result.put(messLines); + + for(byte[] mess: messages){ + result.put(mess); + } + + return result.array(); + } + + public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){ + int messageVersion = 0b1; + byte[] timestamp = longToBytes(time, 6); + byte[] ackNumber = intToBytes(ack, 2); + byte[] raceStartTime = longToBytes(startTime, 6); + int raceIdentifier = raceID; + byte[] notificationType = intToBytes(notification, 1); + + ByteBuffer result = ByteBuffer.allocate(20); + result.put(intToBytes(messageVersion, 1)); + result.put(timestamp); + result.put(ackNumber); + result.put(raceStartTime); + result.put(intToBytes(raceIdentifier)); + result.put(notificationType); + + return result.array(); + } + + public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID, + int eventID){ + int messageVersion = 0b10; + byte[] encodeTime = longToBytes(time, 6); + short ackNum = acknowledgeNumber; + int raceUID = raceID;//TODO chekc if this is an into for a 4 char string. + int destSource = destSourceID; + int incident = incidentID; + byte[] event = intToBytes(eventID, 1); + + ByteBuffer result = ByteBuffer.allocate(22); + result.put(intToBytes(messageVersion, 1)); + result.put(encodeTime); + result.putShort(ackNum); + result.put(intToBytes(raceUID)); + result.put(intToBytes(destSource)); + result.put(intToBytes(incident)); + result.put(event); + return result.array(); + } + + public byte[] chatterText(int messageType, String message){ + int messageVersion = 0b1; + byte[] type = intToBytes(messageType, 1); + byte[] text = message.getBytes(); + byte[] length = intToBytes(text.length, 1); + + ByteBuffer result = ByteBuffer.allocate(3 + text.length); + result.put(intToBytes(messageVersion, 1)); + result.put(type); + result.put(length); + result.put(text); + + return result.array(); + } + + public static byte[] boatLocation(BoatLocationMessage boatLocationMessage){ + int messageVersionNumber = 0b1; + byte[] time = longToBytes(boatLocationMessage.getTime(), 6); + byte[] sourceID = intToBytes(boatLocationMessage.getSourceID(), 4); + byte[] seqNum = longToBytes(boatLocationMessage.getSequenceNumber(), 4); + byte[] deviceType = intToBytes(boatLocationMessage.getDeviceType(), 1); + byte[] latitude = intToBytes(boatLocationMessage.getLatitude(), 4); + byte[] longitude = intToBytes(boatLocationMessage.getLongitude(), 4); + byte[] altitude = intToBytes(boatLocationMessage.getAltitude(), 4); + byte[] heading = intToBytes(boatLocationMessage.getHeading(), 2); + byte[] pitch = intToBytes(boatLocationMessage.getPitch(), 2); + byte[] roll = intToBytes(boatLocationMessage.getRoll(), 2); + byte[] boatSpeed = intToBytes(boatLocationMessage.getBoatSpeed(), 2); + byte[] cog = intToBytes(boatLocationMessage.getBoatCOG(), 2); + byte[] sog = intToBytes(boatLocationMessage.getBoatSOG(), 2); + byte[] apparentWindSpeed = intToBytes(boatLocationMessage.getApparentWindSpeed(), 2); + byte[] apparentWindAngle = intToBytes(boatLocationMessage.getApparentWindAngle(), 2); + byte[] trueWindSpeed = intToBytes(boatLocationMessage.getTrueWindSpeed(), 2); + byte[] trueWindDirection = intToBytes(boatLocationMessage.getTrueWindDirection(), 2); + byte[] trueWindAngle = intToBytes(boatLocationMessage.getTrueWindAngle(), 2); + byte[] currentDrift = intToBytes(boatLocationMessage.getCurrentDrift(), 2); + byte[] currentSet = intToBytes(boatLocationMessage.getCurrentSet(), 2); + byte[] rudderAngle = intToBytes(boatLocationMessage.getRudderAngle(), 2); + + ByteBuffer result = ByteBuffer.allocate(56); + result.put(intToBytes(messageVersionNumber, 1)); + result.put(time); + result.put(sourceID); + result.put(seqNum); + result.put(deviceType); + result.put(latitude); + result.put(longitude); + result.put(altitude); + result.put(heading); + result.put(pitch); + result.put(roll); + result.put(boatSpeed); + result.put(cog); + result.put(sog); + result.put(apparentWindSpeed); + result.put(apparentWindAngle); + result.put(trueWindSpeed); + result.put(trueWindDirection); + result.put(trueWindAngle); + result.put(currentDrift); + result.put(currentSet); + result.put(rudderAngle); + return result.array(); + } + + public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ + int messageVersionNumber = 0b1; + byte[] byteTime = longToBytes(time, 6); + byte[] byteAck = intToBytes(ackNumber, 2); + byte[] byteRaceID = intToBytes(raceID, 4); + byte[] byteSourceID = intToBytes(sourceID, 4); + byte[] byteBoatStatus = intToBytes(boatStatus, 1); + byte[] byteRoundingSide = intToBytes(roundingSide, 1); + byte[] byteMarkType = intToBytes(markType, 1); + byte[] byteMarkID = intToBytes(markID, 1); + + ByteBuffer result = ByteBuffer.allocate(21); + result.put(intToBytes(messageVersionNumber, 1)); + result.put(byteTime); + result.put(byteAck); + result.put(byteRaceID); + result.put(byteSourceID); + result.put(byteBoatStatus); + result.put(byteRoundingSide); + result.put(byteMarkType); + result.put(byteMarkID); + return result.array(); + } + + public byte[] courseWind(byte windID, ArrayList courseWinds){ + int messageVersionNumber = 0b1; + byte byteWindID = windID; + byte[] loopcount = intToBytes(courseWinds.size(), 1); + ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size()); + result.put(intToBytes(messageVersionNumber, 1)); + result.put(byteWindID); + result.put(loopcount); + for (CourseWind wind: courseWinds){ + result.put(intToBytes(wind.getID(), 1)); + result.put(longToBytes(wind.getTime(), 6)); + result.put(intToBytes(wind.getRaceID(), 4)); + result.put(intToBytes(wind.getWindDirection(), 2)); + result.put(intToBytes(wind.getWindSpeed(), 2)); + result.put(intToBytes(wind.getBestUpwindAngle(), 2)); + result.put(intToBytes(wind.getBestDownwindAngle(), 2)); + result.put(intToBytes(wind.getFlags(), 1)); + } + return result.array(); + } + + public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ + int messageVersionNumber = 0b1; + byte[] byteTime = longToBytes(time,6); + byte[] byteRawPeriod = intToBytes(rawPeriod, 2); + byte[] byteRawSpeed = intToBytes(rawSampleSpeed, 2); + byte[] bytePeriod2 = intToBytes(period2, 2); + byte[] byteSpeed2 = intToBytes(speed2, 2); + byte[] bytePeriod3 = intToBytes(period3, 2); + byte[] byteSpeed3 = intToBytes(speed3, 2); + byte[] bytePeriod4 = intToBytes(period4, 2); + byte[] byteSpeed4 = intToBytes(speed4, 2); + + ByteBuffer result = ByteBuffer.allocate(23); + result.put(intToBytes(messageVersionNumber, 1)); + result.put(byteTime); + result.put(byteRawPeriod); + result.put(byteRawSpeed); + result.put(bytePeriod2); + result.put(byteSpeed2); + result.put(bytePeriod3); + result.put(byteSpeed3); + result.put(bytePeriod4); + result.put(byteSpeed4); + return result.array(); + } + +} diff --git a/network/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java b/network/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java new file mode 100644 index 00000000..526ee189 --- /dev/null +++ b/network/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java @@ -0,0 +1,62 @@ +package seng302.Networking.MessageEncoders; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +import static seng302.Networking.Utils.ByteConverter.intToBytes; +import static seng302.Networking.Utils.ByteConverter.longToBytes; +import static seng302.Networking.Utils.ByteConverter.shortToBytes; + +/** + * Encodes a XML file into a message of AC35 format + */ +public class XMLMessageEncoder { + private byte[] messageVersionNumber; + private short ackNumber; + private long timeStamp; + private byte[] xmlMsgSubType; + private short sequenceNumber; + private short xmlMsgLength; + private String xmlMessage; + + public XMLMessageEncoder(short ackNumber, long timeStamp, int xmlMsgSubType, short sequenceNumber, short xmlMsgLength, String xmlMessage) { + this.messageVersionNumber = intToBytes(1, 1); + this.ackNumber = ackNumber; + this.timeStamp = timeStamp; + this.xmlMsgSubType = intToBytes(xmlMsgSubType, 1); + this.sequenceNumber = sequenceNumber; + this.xmlMsgLength = xmlMsgLength; + this.xmlMessage = xmlMessage; + } + + public byte[] encode() { + byte[] messageBytes = xmlMessage.getBytes(); + if (messageBytes.length > this.xmlMsgLength) { + //System.err.println("Xml message is to big"); + return null; + } + ByteBuffer tempOutputByteBuffer = ByteBuffer.allocate(14 + messageBytes.length); + + //ackNumber converted to bytes + byte[] ackNumberBytes = shortToBytes(ackNumber, 2); + + //sequenceNumber converted to bytes + byte[] sequenceNumberBytes = shortToBytes(sequenceNumber, 2); + + //xmlMsgLength converted to bytes + byte[] xmlMsgLengthBytes = shortToBytes(xmlMsgLength, 2); + + + tempOutputByteBuffer.put(messageVersionNumber); + tempOutputByteBuffer.put(ackNumberBytes); + tempOutputByteBuffer.put(longToBytes(timeStamp, 6)); + tempOutputByteBuffer.put(xmlMsgSubType); + tempOutputByteBuffer.put(sequenceNumberBytes); + tempOutputByteBuffer.put(xmlMsgLengthBytes); + tempOutputByteBuffer.put(messageBytes); + + return tempOutputByteBuffer.array(); + } + +} diff --git a/network/src/main/java/seng302/Networking/MockOutput.java b/network/src/main/java/seng302/Networking/MockOutput.java new file mode 100644 index 00000000..2f3d2440 --- /dev/null +++ b/network/src/main/java/seng302/Networking/MockOutput.java @@ -0,0 +1,134 @@ +package seng302.Networking; +import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; +import seng302.Networking.MessageEncoders.XMLMessageEncoder; +import seng302.Networking.Utils.BoatLocationMessage; +import seng302.Networking.Utils.MessageType; + +import java.io.*; +import java.net.*; +import java.util.ArrayList; + +/** + * TCP client to recive information from AC35 data source + */ +public class MockOutput +{ + private long lastHeartbeatTime; + + private RaceVisionByteEncoder messageEncoder = new RaceVisionByteEncoder(); + + //socket port 4942 as 4940 is ac35 live port and 4941 is ac35 test port + private Socket mockSocket; + private DataOutputStream outToVisualiser; + + //a buffer that contains items that are waiting to be sent + private ArrayList messagesToSendBuffer = new ArrayList<>(); + + private short messageNumber = 1; + + private short xmlSequenceNumber = 1; + private int heartbeatSequenceNum = 1; + + + + MockOutput() throws IOException{ + /*******************************Test********************************/ + StringBuilder xmlString; + + BufferedReader br = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream(("/raceXML/Regatta.xml")))); + + String line; + xmlString = new StringBuilder(); + while((line=br.readLine())!= null){ + xmlString.append(line.trim()); + } + + parseXMLString(xmlString.toString(), 5); + + /*******************************Test********************************/ + + /**************sockets*******************/ + //start Time + lastHeartbeatTime = System.currentTimeMillis(); + + + mockSocket = new Socket("localhost", 4942); + outToVisualiser = new DataOutputStream(mockSocket.getOutputStream()); + + + //loop that sends + while(true) + { + //sends a heartbeat every 5 seconds + if (timeSinceHeartbeat() >= 5.00){ + outToVisualiser.write(heartbeat()); + lastHeartbeatTime = System.currentTimeMillis(); + } + + //checks the buffer to see if there is anything to send + if (messagesToSendBuffer.size() > 0) { + for (byte[] binaryMessage : messagesToSendBuffer) { + //sends the message to the visualiser + outToVisualiser.write(binaryMessage); + } + //cleans out buffer + messagesToSendBuffer.clear(); + } + } + /**************sockets*******************/ + } + + /** + * calculates the time since last heartbeat + * @return time since last heartbeat + */ + private double timeSinceHeartbeat() { + long now = System.currentTimeMillis(); + return (now - lastHeartbeatTime) / 1000.0; + } + + //returns the heartbeat message + private byte[] heartbeat(){ + byte[] heartbeatMessage = messageEncoder.heartBeat(heartbeatSequenceNum); + heartbeatSequenceNum++; + BinaryMesageEncoder binaryMesageEncoder = new BinaryMesageEncoder(MessageType.HEARTBEAT, System.currentTimeMillis(), messageNumber, (short)heartbeatMessage.length, heartbeatMessage); + messageNumber++; + return binaryMesageEncoder.getFullMessage(); + } + + /** + * Used to give the mockOutput an xml string to be made into a message and sent + * @param xmlString the xml string to send + * @param messageType the kind of xml string, values given in AC35 spec (5 regatta, 6 race, 7 boat) + */ + public void parseXMLString(String xmlString, int messageType){ + XMLMessageEncoder encoder = new XMLMessageEncoder(messageNumber, System.currentTimeMillis(), messageType, xmlSequenceNumber,(short) xmlString.length(), xmlString); + //iterates the sequence numbers + xmlSequenceNumber++; + byte[] encodedXML = encoder.encode(); + + BinaryMesageEncoder binaryMesageEncoder = new BinaryMesageEncoder(MessageType.XMLMESSAGE, System.currentTimeMillis(), messageNumber, (short)encodedXML.length, encodedXML); + //iterates the message number + messageNumber++; + + addMessageToBufferToSend(binaryMesageEncoder.getFullMessage()); + } + + /** + * Used to give the mocOutput information about boat location to be made into a message and sent + */ + public void parseBoatLocation(){ + /// TODO: 26/04/17 + } + + private void addMessageToBufferToSend(byte[] messagesToSendBuffer) { + this.messagesToSendBuffer.add(messagesToSendBuffer); + } + + public static void main(String argv[]) throws Exception + { + MockOutput client = new MockOutput(); + } + +} \ No newline at end of file diff --git a/network/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java b/network/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java new file mode 100644 index 00000000..6d132836 --- /dev/null +++ b/network/src/main/java/seng302/Networking/PacketDump/AC35DumpReader.java @@ -0,0 +1,67 @@ +package seng302.Networking.PacketDump; + +import seng302.Networking.BinaryMesageEncoder; +import seng302.Networking.BinaryMessageDecoder; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Created by fwy13 on 25/04/17. + */ +public class AC35DumpReader { + + private byte[] dump; + private ArrayList packets; + + public AC35DumpReader(String url) throws IOException, URISyntaxException { + + URL uri = getClass().getClassLoader().getResource(url); + Path path = Paths.get(uri.toURI()); + dump = Files.readAllBytes(path); + + packets = new ArrayList<>(); + + System.out.println(dump.length); + readAllPackets(); + } + + private void readAllPackets(){ + int pointer = 0; + while(pointer < dump.length){ + byte[] messLen = new byte[2]; + messLen[1] = dump[pointer + 13]; + messLen[0] = dump[pointer + 14]; + int messageLength = ByteBuffer.wrap(messLen).getShort(); + //System.out.println(messageLength); + + packets.add(new AC35Packet(Arrays.copyOfRange(dump, pointer, pointer + messageLength + 19))); + + pointer += 19 + messageLength; + } + for (AC35Packet pack: packets){ + BinaryMessageDecoder decoder = new BinaryMessageDecoder(pack.getData()); + decoder.decode(); + } + + } + + public static void main(String[] args){ + try { + AC35DumpReader ac35DumpReader = new AC35DumpReader("dataDumps/ac35.bin"); + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } +} diff --git a/network/src/main/java/seng302/Networking/PacketDump/AC35Packet.java b/network/src/main/java/seng302/Networking/PacketDump/AC35Packet.java new file mode 100644 index 00000000..ea6e1a2c --- /dev/null +++ b/network/src/main/java/seng302/Networking/PacketDump/AC35Packet.java @@ -0,0 +1,17 @@ +package seng302.Networking.PacketDump; + +/** + * Created by fwy13 on 25/04/17. + */ +public class AC35Packet { + + byte[] data; + + public AC35Packet(byte[] data){ + this.data = data; + } + + public byte[] getData() { + return data; + } +} diff --git a/network/src/main/java/seng302/Networking/Utils/AC35Data.java b/network/src/main/java/seng302/Networking/Utils/AC35Data.java new file mode 100644 index 00000000..89867839 --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/AC35Data.java @@ -0,0 +1,15 @@ +package seng302.Networking.Utils; + + +/** + * Created by fwy13 on 25/04/17. + */ +public abstract class AC35Data { + + protected MessageType type; + + public AC35Data (MessageType type){ + this.type = type; + } + +} diff --git a/network/src/main/java/seng302/Networking/Utils/AverageWind.java b/network/src/main/java/seng302/Networking/Utils/AverageWind.java new file mode 100644 index 00000000..575942ca --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/AverageWind.java @@ -0,0 +1,33 @@ +package seng302.Networking.Utils; + +/** + * Created by fwy13 on 25/04/17. + */ +public class AverageWind extends AC35Data{ + + private int msgNum; + private long lngTime; + private int rawPeriod; + private int rawSpeed; + private int period2; + private int speed2; + private int period3; + private int speed3; + private int period4; + private int speed4; + + public AverageWind(int msgNum, long lngTime, int rawPeriod, int rawSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ + super(MessageType.AVGWIND); + this.msgNum = msgNum; + this.lngTime = lngTime; + this.rawPeriod = rawPeriod; + this.rawSpeed = rawSpeed; + this.period2 = period2; + this.speed2 = speed2; + this.period3 = period3; + this.speed3 = speed3; + this.period4 = period4; + this.speed4 = speed4; + } + +} diff --git a/mock/src/main/java/seng302/RaceEventMessages/BoatLocationMessage.java b/network/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java similarity index 80% rename from mock/src/main/java/seng302/RaceEventMessages/BoatLocationMessage.java rename to network/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java index 425b86f0..0a4709c0 100644 --- a/mock/src/main/java/seng302/RaceEventMessages/BoatLocationMessage.java +++ b/network/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java @@ -1,30 +1,16 @@ -package seng302.RaceEventMessages; +package seng302.Networking.Utils; /** * Created by f123 on 21-Apr-17. */ -import seng302.Constants; +import SharedModel.Constants; /** * Represents the information in a boat location message (AC streaming spec: 4.9). */ -public class BoatLocationMessage +public class BoatLocationMessage extends AC35Data { - ///Version number of the message - is always 1. - private byte messageVersionNumber = 1; - - ///Time of the event - milliseconds since jan 1 1970. Proper type is 6 byte int. - private long time; - - ///Source ID of the boat. - private int sourceID; - - ///Sequence number of the message. - private long sequenceNumber; - - ///Device type of the message (physical source of the message). - private byte deviceType; public static final byte Unknown = 0; public static final byte RacingYacht = 1; public static final byte CommitteeBoat = 2; @@ -39,8 +25,16 @@ public class BoatLocationMessage public static final byte WeatherStation = 11; public static final byte Helicopter = 12; public static final byte DataProcessingApplication = 13; - - + ///Version number of the message - is always 1. + private byte messageVersionNumber = 1; + ///Time of the event - milliseconds since jan 1 1970. Proper type is 6 byte int. + private long time; + ///Source ID of the boat. + private int sourceID; + ///Sequence number of the message. + private long sequenceNumber; + ///Device type of the message (physical source of the message). + private byte deviceType; ///Latitude of the boat. private int latitude; @@ -77,6 +71,9 @@ public class BoatLocationMessage ///True wind speed. Proper type is unsigned 2 byte int. millimeters per second. private int trueWindSpeed; + ///True wind direction. Proper type is unsigned 2 byte int. 0x0000 = North, etc.. + private int trueWindDirection; + ///True wind angle. Clockwise compass direction, 0 = north. private short trueWindAngle; @@ -93,12 +90,13 @@ public class BoatLocationMessage /** * Ctor. Default. */ - public BoatLocationMessage() - { + public BoatLocationMessage() { + super(MessageType.BOATLOCATION); } /** * Ctor, with all parameters. + * * @param messageVersionNumber * @param time * @param sourceID @@ -116,13 +114,15 @@ public class BoatLocationMessage * @param apparentWindSpeed * @param apparentWindAngle * @param trueWindSpeed + * @param trueWindDirection * @param trueWindAngle * @param currentDrift * @param currentSet * @param rudderAngle */ - public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, long sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) - { + public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, long sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, int trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) { + super(MessageType.BOATLOCATION); + this.messageVersionNumber = messageVersionNumber; this.time = time; this.sourceID = sourceID; @@ -140,6 +140,7 @@ public class BoatLocationMessage this.apparentWindSpeed = apparentWindSpeed; this.apparentWindAngle = apparentWindAngle; this.trueWindSpeed = trueWindSpeed; + this.trueWindDirection = trueWindDirection; this.trueWindAngle = trueWindAngle; this.currentDrift = currentDrift; this.currentSet = currentSet; @@ -149,342 +150,299 @@ public class BoatLocationMessage //Getters and setters for message properties. + /** + * Converts a double representing a latitude or longitude coordinate to an int, as required by the streaming spec format. + * + * @param coordinate Latitude or longitude to convert. Double. + * @return int representation of coordinate. + */ + public static int convertCoordinateDoubleToInt(double coordinate) { + int coordinateInt = (int) ((coordinate / 180.0) * 2147483648.0); + + return coordinateInt; - public byte getMessageVersionNumber() - { + + } + + /** + * Converts an int representing a latitude or longitude coordinate to a double, as required by the streaming spec format. + * + * @param coordinate Latitude or longitude to convert. int. + * @return double representation of coordinate. + */ + public static double convertCoordinateIntToDouble(int coordinate) { + double coordinateDouble = (double) ((coordinate * 180.0) / 2147483648.0); + + return coordinateDouble; + } + + /** + * Converts an int representing a heading to a double, as required by the streaming spec format. + * + * @param heading Heading to convert. int. + * @return double representation of heading. + */ + public static double convertHeadingIntToDouble(int heading) { + + double headingDouble = (double) ((heading * 360.0) / 65536.0); + + return headingDouble; + } + + /** + * Converts a double representing a heading to an int, as required by the streaming spec format. + * + * @param heading Heading to convert. double. + * @return int representation of heading. + */ + public static int convertHeadingDoubleToInt(double heading) { + + int headingInt = (int) ((heading / 360.0) * 65536.0); + + return headingInt; + } + + /** + * Converts a short representing the wind's true angle to a double, as required by the streaming spec format. + * + * @param angle Angle to convert. short. + * @return double representation of heading. + */ + public static double convertTrueWindAngleShortToDouble(short angle) { + + double angleDouble = (double) ((angle * 180.0) / 32768.0); + + return angleDouble; + } + + /** + * Converts a double representing the wind's true angle to a short, as required by the streaming spec format. + * + * @param angle Angle to convert. double. + * @return short representation of heading. + */ + public static short convertTrueWindAngleShortToDouble(double angle) { + + short angleShort = (short) ((angle / 180.0) * 32768.0); + + return angleShort; + } + + /** + * Converts a double representing the speed of a boat in knots to an int in millimeters per second, as required by the streaming spec format. + * + * @param speed Speed in knots, stored as a double. + * @return Speed in millimeters per second, stored as an int (using only the two least significant bytes). + */ + public static int convertBoatSpeedDoubleToInt(double speed) { + //Calculate meters per second. + double metersPerSecond = speed * Constants.KnotsToMetersPerSecondConversionFactor; + + //Calculate millimeters per second. + double millimetersPerSecond = metersPerSecond * 1000.0; + + //Convert to an int. + int millimetersPerSecondInt = (int) Math.round(millimetersPerSecond); + + return millimetersPerSecondInt; + } + + /** + * Converts an int representing the speed of a boat in millimeters per second to a double in knots, as required by the streaming spec format. + * + * @param speed Speed in millimeters per second, stored as an int. + * @return Speed in knots, stored as a double. + */ + public static double convertBoatSpeedIntToDouble(int speed) { + //Calculate meters per second. + double metersPerSecond = speed / 1000.0; + + //Calculate knots. + double knots = metersPerSecond / Constants.KnotsToMetersPerSecondConversionFactor; + + return knots; + } + + public byte getMessageVersionNumber() { return messageVersionNumber; } - public void setMessageVersionNumber(byte messageVersionNumber) - { + public void setMessageVersionNumber(byte messageVersionNumber) { this.messageVersionNumber = messageVersionNumber; } - public long getTime() - { + public long getTime() { return time; } - public void setTime(long time) - { + public void setTime(long time) { this.time = time; } - public int getSourceID() - { + public int getSourceID() { return sourceID; } - public void setSourceID(int sourceID) - { + public void setSourceID(int sourceID) { this.sourceID = sourceID; } - public long getSequenceNumber() - { + public long getSequenceNumber() { return sequenceNumber; } - public void setSequenceNumber(long sequenceNumber) - { + public void setSequenceNumber(long sequenceNumber) { this.sequenceNumber = sequenceNumber; } - public byte getDeviceType() - { + public byte getDeviceType() { return deviceType; } - public void setDeviceType(byte deviceType) - { + public void setDeviceType(byte deviceType) { this.deviceType = deviceType; } - public int getLatitude() - { + public int getLatitude() { return latitude; } - public void setLatitude(int latitude) - { + public void setLatitude(int latitude) { this.latitude = latitude; } - public int getLongitude() - { + public int getLongitude() { return longitude; } - public void setLongitude(int longitude) - { + public void setLongitude(int longitude) { this.longitude = longitude; } - public int getAltitude() - { + public int getAltitude() { return altitude; } - public void setAltitude(int altitude) - { + public void setAltitude(int altitude) { this.altitude = altitude; } - public int getHeading() - { + public int getHeading() { return heading; } - public void setHeading(int heading) - { + public void setHeading(int heading) { this.heading = heading; } - public short getPitch() - { + public short getPitch() { return pitch; } - public void setPitch(short pitch) - { + public void setPitch(short pitch) { this.pitch = pitch; } - public short getRoll() - { + public short getRoll() { return roll; } - public void setRoll(short roll) - { + public void setRoll(short roll) { this.roll = roll; } - public int getBoatSpeed() - { + public int getBoatSpeed() { return boatSpeed; } - public void setBoatSpeed(int boatSpeed) - { + public void setBoatSpeed(int boatSpeed) { this.boatSpeed = boatSpeed; } - public int getBoatCOG() - { + public int getBoatCOG() { return boatCOG; } - public void setBoatCOG(int boatCOG) - { + public void setBoatCOG(int boatCOG) { this.boatCOG = boatCOG; } - public int getBoatSOG() - { + public int getBoatSOG() { return boatSOG; } - public void setBoatSOG(int boatSOG) - { + public void setBoatSOG(int boatSOG) { this.boatSOG = boatSOG; } - public int getApparentWindSpeed() - { + public int getApparentWindSpeed() { return apparentWindSpeed; } - public void setApparentWindSpeed(int apparentWindSpeed) - { + public void setApparentWindSpeed(int apparentWindSpeed) { this.apparentWindSpeed = apparentWindSpeed; } - public short getApparentWindAngle() - { + public short getApparentWindAngle() { return apparentWindAngle; } - public void setApparentWindAngle(short apparentWindAngle) - { + public void setApparentWindAngle(short apparentWindAngle) { this.apparentWindAngle = apparentWindAngle; } - public int getTrueWindSpeed() - { + public int getTrueWindSpeed() { return trueWindSpeed; } - public void setTrueWindSpeed(int trueWindSpeed) - { + public void setTrueWindSpeed(int trueWindSpeed) { this.trueWindSpeed = trueWindSpeed; } - public short getTrueWindAngle() + public int getTrueWindDirection() { - return trueWindAngle; + return trueWindDirection; } - public void setTrueWindAngle(short trueWindAngle) + public void setTrueWindDirection(int trueWindDirection) { + this.trueWindDirection = trueWindDirection; + } + + public short getTrueWindAngle() { + return trueWindAngle; + } + + public void setTrueWindAngle(short trueWindAngle) { this.trueWindAngle = trueWindAngle; } - public int getCurrentDrift() - { + public int getCurrentDrift() { return currentDrift; } - public void setCurrentDrift(int currentDrift) - { + public void setCurrentDrift(int currentDrift) { this.currentDrift = currentDrift; } - public int getCurrentSet() - { + public int getCurrentSet() { return currentSet; } - public void setCurrentSet(int currentSet) - { + public void setCurrentSet(int currentSet) { this.currentSet = currentSet; } - public short getRudderAngle() - { + public short getRudderAngle() { return rudderAngle; } - public void setRudderAngle(short rudderAngle) - { + public void setRudderAngle(short rudderAngle) { this.rudderAngle = rudderAngle; } - /** - * Converts a double representing a latitude or longitude coordinate to an int, as required by the streaming spec format. - * @param coordinate Latitude or longitude to convert. Double. - * @return int representation of coordinate. - */ - public static int convertCoordinateDoubleToInt(double coordinate) - { - int coordinateInt = (int) ((coordinate / 180.0) * 2147483648.0); - - return coordinateInt; - - - } - - - /** - * Converts an int representing a latitude or longitude coordinate to a double, as required by the streaming spec format. - * @param coordinate Latitude or longitude to convert. int. - * @return double representation of coordinate. - */ - public static double convertCoordinateIntToDouble(int coordinate) - { - double coordinateDouble = (double) ((coordinate * 180.0) / 2147483648.0); - - return coordinateDouble; - } - - - /** - * Converts an int representing a heading to a double, as required by the streaming spec format. - * @param heading Heading to convert. int. - * @return double representation of heading. - */ - public static double convertHeadingIntToDouble(int heading) - { - - double headingDouble = (double) ((heading * 360.0) / 65536.0); - - return headingDouble; - } - - - /** - * Converts a double representing a heading to an int, as required by the streaming spec format. - * @param heading Heading to convert. double. - * @return int representation of heading. - */ - public static int convertHeadingDoubleToInt(double heading) - { - - int headingInt = (int) ((heading / 360.0) * 65536.0); - - return headingInt; - } - - - - /** - * Converts a short representing the wind's true angle to a double, as required by the streaming spec format. - * @param angle Angle to convert. short. - * @return double representation of heading. - */ - public static double convertTrueWindAngleShortToDouble(short angle) - { - - double angleDouble = (double) ((angle * 180.0) / 32768.0); - - return angleDouble; - } - - - /** - * Converts a double representing the wind's true angle to a short, as required by the streaming spec format. - * @param angle Angle to convert. double. - * @return short representation of heading. - */ - public static short convertTrueWindAngleShortToDouble(double angle) - { - - short angleShort = (short) ((angle / 180.0) * 32768.0); - - return angleShort; - } - - - /** - * Converts a double representing the speed of a boat in knots to an int in millimeters per second, as required by the streaming spec format. - * @param speed Speed in knots, stored as a double. - * @return Speed in millimeters per second, stored as an int (using only the two least significant bytes). - */ - public static int convertBoatSpeedDoubleToInt(double speed) - { - //Calculate meters per second. - double metersPerSecond = speed * Constants.KnotsToMetersPerSecondConversionFactor; - - //Calculate millimeters per second. - double millimetersPerSecond = metersPerSecond * 1000.0; - - //Convert to an int. - int millimetersPerSecondInt = (int)Math.round(millimetersPerSecond); - - return millimetersPerSecondInt; - } - - - /** - * Converts an int representing the speed of a boat in millimeters per second to a double in knots, as required by the streaming spec format. - * @param speed Speed in millimeters per second, stored as an int. - * @return Speed in knots, stored as a double. - */ - public static double convertBoatSpeedIntToDouble(int speed) - { - //Calculate meters per second. - double metersPerSecond = speed / 1000.0; - - //Calculate knots. - double knots = metersPerSecond / Constants.KnotsToMetersPerSecondConversionFactor; - - return knots; - } - - @Override - public String toString() - { + public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Message version number: "); diff --git a/mock/src/main/java/seng302/Networking/Utils/BoatStatus.java b/network/src/main/java/seng302/Networking/Utils/BoatStatus.java similarity index 98% rename from mock/src/main/java/seng302/Networking/Utils/BoatStatus.java rename to network/src/main/java/seng302/Networking/Utils/BoatStatus.java index 9de6ef39..62c6cf0f 100644 --- a/mock/src/main/java/seng302/Networking/Utils/BoatStatus.java +++ b/network/src/main/java/seng302/Networking/Utils/BoatStatus.java @@ -3,7 +3,7 @@ package seng302.Networking.Utils; /** * Created by hba56 on 23/04/17. */ -public class BoatStatus { +public class BoatStatus{ private int sourceID; private byte boatStatus; private byte legNumber; diff --git a/network/src/main/java/seng302/Networking/Utils/ByteConverter.java b/network/src/main/java/seng302/Networking/Utils/ByteConverter.java new file mode 100644 index 00000000..fcbc36ea --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/ByteConverter.java @@ -0,0 +1,253 @@ +package seng302.Networking.Utils; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +/** + * Created by fwy13 on 25/04/17. + */ +public class ByteConverter { + + public static int IntegerSize = 4; + public static int LongSize = 8; + public static int CharSize = 2; + public static int ShortSize = 2; + + + //default for AC35 is Little Endian therefore all overloads will be done with Little_Endian unless told else wise + + ////////////////////////////////////////////////// + //Bytes[] to number conversions + ////////////////////////////////////////////////// + + ////////////////////////////////////////////////// + //Integer + ////////////////////////////////////////////////// + + public static int bytesToInt(byte bite){ + byte[] bytes = {bite}; + return bytesToInt(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static int bytesToInt(byte[] bytes){ + return bytesToInt(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static int bytesToInt(byte[] bytes, ByteOrder byteOrder){ + byte[] bites = convertBytesToNum(bytes,byteOrder, IntegerSize); + return ByteBuffer.wrap(bites).order(byteOrder).getInt(); + } + + ////////////////////////////////////////////////// + //Long + ////////////////////////////////////////////////// + + public static long bytesToLong(byte bite){ + byte[] bytes = {bite}; + return bytesToLong(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static long bytesToLong(byte[] bytes){ + return bytesToLong(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static long bytesToLong(byte[] bytes, ByteOrder byteOrder){ + byte[] bites = convertBytesToNum(bytes,byteOrder, LongSize); + return ByteBuffer.wrap(bites).order(byteOrder).getLong(); + } + + ////////////////////////////////////////////////// + //Short + ////////////////////////////////////////////////// + + public static short bytesToShort(byte bite){ + byte[] bytes = {bite}; + return bytesToShort(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static short bytesToShort(byte[] bytes){ + return bytesToShort(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static short bytesToShort(byte[] bytes, ByteOrder byteOrder){ + byte[] bites = convertBytesToNum(bytes,byteOrder, ShortSize); + return ByteBuffer.wrap(bites).order(byteOrder).getShort(); + } + + ////////////////////////////////////////////////// + //Char + ////////////////////////////////////////////////// + + public static char bytesToChar(byte bite){ + byte[] bytes = {bite}; + return bytesToChar(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static char bytesToChar(byte[] bytes){ + return bytesToChar(bytes, ByteOrder.LITTLE_ENDIAN); + } + + public static char bytesToChar(byte[] bytes, ByteOrder byteOrder){ + byte[] bites = convertBytesToNum(bytes,byteOrder, CharSize); + return ByteBuffer.wrap(bites).order(byteOrder).getChar(); + } + + ////////////////////////////////////////////////// + //Conversion Function + ////////////////////////////////////////////////// + + private static byte[] convertBytesToNum(byte[] bytes, ByteOrder byteOrder, int maxSize){ + byte[] bites = new byte[maxSize]; + if (byteOrder == ByteOrder.LITTLE_ENDIAN) { + for (int i = 0; i < bytes.length; i++) { + bites[i] = bytes[i]; + if (i > maxSize){//break if over hte limit + break; + } + } + for (int i = bytes.length; i < maxSize; i++) { + bites[i] = 0b0; + } + }else{//if big endian + for (int i = 0; i < maxSize - bytes.length; i++) { + bites[i] = 0b0; + } + for (int i = maxSize - bytes.length; i < maxSize; i++) { + bites[i] = bytes[i - maxSize + bytes.length]; + if (i > maxSize){//break if over the limit + break; + } + } + } + return bites; + } + + ////////////////////////////////////////////////////////// + //Number to Byte[] conversions + ////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////// + //Integer + ////////////////////////////////////////////////// + + public static byte[] intToBytes(int i){ + return intToBytes(i, 4, ByteOrder.LITTLE_ENDIAN); + } + + public static byte[] intToBytes(int i ,int size){ + return intToBytes(i, size, ByteOrder.LITTLE_ENDIAN); + } + + /** + * Converts an Integer to a Byte Array + * @param i the integer to be converted + * @param size Size that the byte array should be + * @param byteOrder the order that the bytes should be ie Big Endian + * @return + */ + public static byte[] intToBytes(int i ,int size, ByteOrder byteOrder){ + ByteBuffer buffer = ByteBuffer.allocate(IntegerSize); + buffer.order(byteOrder); + buffer.putInt(i); + byte[] copy = buffer.array(); + return convertNumtoBytes(copy, size, byteOrder, IntegerSize); + } + + ////////////////////////////////////////////////// + //Long + ////////////////////////////////////////////////// + + public static byte[] longToBytes(long i){ + return longToBytes(i, LongSize, ByteOrder.LITTLE_ENDIAN); + } + + public static byte[] longToBytes(long i ,int size){ + return longToBytes(i, size, ByteOrder.LITTLE_ENDIAN); + } + + /** + * Converts an Long to a Byte Array + * @param i the Long to be converted + * @param size Size that the byte array should be + * @param byteOrder the order that the bytes should be ie Big Endian + * @return + */ + public static byte[] longToBytes(long i ,int size, ByteOrder byteOrder){ + ByteBuffer buffer = ByteBuffer.allocate(LongSize); + buffer.order(byteOrder); + buffer.putLong(i); + byte[] copy = buffer.array(); + return convertNumtoBytes(copy, size, byteOrder, LongSize); + } + + ////////////////////////////////////////////////// + //Short + ////////////////////////////////////////////////// + + public static byte[] shortToBytes(short i){ + return shortToBytes(i, ShortSize, ByteOrder.LITTLE_ENDIAN); + } + + public static byte[] shortToBytes(short i ,int size){ + return shortToBytes(i, size, ByteOrder.LITTLE_ENDIAN); + } + + /** + * Converts an Short to a Byte Array + * @param i the Short to be converted + * @param size Size that the byte array should be + * @param byteOrder the order that the bytes should be ie Big Endian + * @return + */ + public static byte[] shortToBytes(short i ,int size, ByteOrder byteOrder){ + ByteBuffer buffer = ByteBuffer.allocate(ShortSize); + buffer.order(byteOrder); + buffer.putShort(i); + byte[] copy = buffer.array(); + return convertNumtoBytes(copy, size, byteOrder, ShortSize); + } + + ////////////////////////////////////////////////// + //Char + ////////////////////////////////////////////////// + + public static byte[] charToBytes(char i){ + return charToBytes(i, CharSize, ByteOrder.LITTLE_ENDIAN); + } + + public static byte[] charToBytes(char i ,int size){ + return charToBytes(i, size, ByteOrder.LITTLE_ENDIAN); + } + + /** + * Converts an Char to a Byte Array + * @param i the Char to be converted + * @param size Size that the byte array should be + * @param byteOrder the order that the bytes should be ie Big Endian + * @return + */ + public static byte[] charToBytes(char i ,int size, ByteOrder byteOrder){ + ByteBuffer buffer = ByteBuffer.allocate(CharSize); + buffer.order(byteOrder); + buffer.putChar(i); + byte[] copy = buffer.array(); + return convertNumtoBytes(copy, size, byteOrder, CharSize); + } + + ////////////////////////////////////////////////// + //Conversion Function + ////////////////////////////////////////////////// + + private static byte[] convertNumtoBytes(byte[] copy ,int size, ByteOrder byteOrder, int fullsize){ + byte[] bytes = new byte[size]; + if (byteOrder == ByteOrder.LITTLE_ENDIAN){ + bytes = Arrays.copyOfRange(copy, 0, size); + }else{// if it is Big Endian + bytes = Arrays.copyOfRange(copy, fullsize - size, fullsize); + } + return bytes; + } + + +} diff --git a/mock/src/main/java/seng302/Networking/Utils/CourseWind.java b/network/src/main/java/seng302/Networking/Utils/CourseWind.java similarity index 93% rename from mock/src/main/java/seng302/Networking/Utils/CourseWind.java rename to network/src/main/java/seng302/Networking/Utils/CourseWind.java index 142c7c11..aa50c89a 100644 --- a/mock/src/main/java/seng302/Networking/Utils/CourseWind.java +++ b/network/src/main/java/seng302/Networking/Utils/CourseWind.java @@ -3,13 +3,14 @@ package seng302.Networking.Utils; /** * Created by fwy13 on 21/04/17. */ -public class CourseWind { +public class CourseWind extends AC35Data{ private int ID, raceID, windDirection, windSpeed, bestUpwindAngle, bestDownwindAngle, flags; private long time; public CourseWind(int ID, long time, int raceID, int windDirection, int windSpeed, int bestUpwindAngle, int bestDownwindAngle, int flags){ + super(MessageType.COURSEWIND); this.ID = ID; this.time = time; this.raceID = raceID; diff --git a/network/src/main/java/seng302/Networking/Utils/CourseWinds.java b/network/src/main/java/seng302/Networking/Utils/CourseWinds.java new file mode 100644 index 00000000..ededfe0f --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/CourseWinds.java @@ -0,0 +1,21 @@ +package seng302.Networking.Utils; + +import java.util.ArrayList; + +/** + * Created by fwy13 on 25/04/17. + */ +public class CourseWinds extends AC35Data{ + + private int msgVerNum; + private int selectedWindID; + private ArrayList courseWinds; + + public CourseWinds(int msgVerNum, int selectedWindID, ArrayList courseWinds){ + super(MessageType.COURSEWIND); + this.msgVerNum = msgVerNum; + this.selectedWindID = selectedWindID; + this.courseWinds = courseWinds; + } + +} diff --git a/network/src/main/java/seng302/Networking/Utils/Heartbeat.java b/network/src/main/java/seng302/Networking/Utils/Heartbeat.java new file mode 100644 index 00000000..b486baaa --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/Heartbeat.java @@ -0,0 +1,12 @@ +package seng302.Networking.Utils; + +/** + * Created by fwy13 on 25/04/17. + */ +public class Heartbeat extends AC35Data{ + + public Heartbeat(){ + super(MessageType.HEARTBEAT); + } + +} diff --git a/network/src/main/java/seng302/Networking/Utils/MarkRounding.java b/network/src/main/java/seng302/Networking/Utils/MarkRounding.java new file mode 100644 index 00000000..7ca9ae6a --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/MarkRounding.java @@ -0,0 +1,52 @@ +package seng302.Networking.Utils; + +/** + * Created by fwy13 on 25/04/17. + */ +public class MarkRounding extends AC35Data{ + + private int msgVerNum; + private long time; + private int ackNum; + private int raceID; + private int sourceID; + private int boatStatus; + private int roundingSide; + private int markType; + private int markID; + + public static int BoatStatusUnknown = 0; + public static int BoatStatusRacing = 1; + public static int BoatStatusDSQ = 2; + public static int BoatStatusWithdrawn = 3; + + public static int RoundingSideUnknown = 0; + public static int RoundingSidePort = 1; + public static int RoundingSideStarboard = 2; + + public static int MarkTypeUnknown = 0; + public static int MarkTypeRoundingMark = 1; + public static int MarkTypeGate = 2; + + public static int MarkIDEntryLimitLine = 100; + public static int MarkIDEntryLine = 101; + public static int MarkIDRaceStartStartline = 102; + public static int MarkIDRaceFinishline = 103; + public static int MarkIDSpeedTestStart = 104; + public static int MarkIDSpeedTestFinish = 105; + public static int MarkIDClearStart = 106; + + public MarkRounding(int msgVerNum, long time, int ackNum, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ + super(MessageType.MARKROUNDING); + this.msgVerNum = msgVerNum; + this.time = time; + this.ackNum = ackNum; + this.raceID = raceID; + this.sourceID = sourceID; + this.boatStatus = boatStatus; + this.roundingSide = roundingSide; + this.markType = markType; + this.markID = markID; + } + +} diff --git a/network/src/main/java/seng302/Networking/Utils/MessageType.java b/network/src/main/java/seng302/Networking/Utils/MessageType.java new file mode 100644 index 00000000..f5aa088c --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/MessageType.java @@ -0,0 +1,49 @@ +package seng302.Networking.Utils; + +/** + * Created by hba56 on 21/04/17. + */ +public enum MessageType { + HEARTBEAT(1), RACESTATUS(12), DISPLAYTEXTMESSAGE(20), + XMLMESSAGE(26), RACESTARTSTATUS(27), YACHTEVENTCODE(29), YACHTACTIONCODE(31), + CHATTERTEXT(36), BOATLOCATION(37), MARKROUNDING(38), COURSEWIND(44), AVGWIND(47), NOTAMESSAGE(0); + + private byte value; + + private MessageType(int value) { this.value = (byte)value; } + + public byte getValue() { + return value; + } + + public static MessageType valueOf(byte bite){ + switch(bite){ + case 1: + return HEARTBEAT; + case 12: + return RACESTATUS; + case 20: + return DISPLAYTEXTMESSAGE; + case 26: + return XMLMESSAGE; + case 27: + return RACESTARTSTATUS; + case 29: + return YACHTEVENTCODE; + case 31: + return YACHTACTIONCODE; + case 36: + return CHATTERTEXT; + case 37: + return BOATLOCATION; + case 38: + return MARKROUNDING; + case 44: + return COURSEWIND; + case 47: + return AVGWIND; + default: + return NOTAMESSAGE; + } + } +} diff --git a/mock/src/main/java/seng302/Networking/Utils/RaceMessage.java b/network/src/main/java/seng302/Networking/Utils/RaceMessage.java similarity index 82% rename from mock/src/main/java/seng302/Networking/Utils/RaceMessage.java rename to network/src/main/java/seng302/Networking/Utils/RaceMessage.java index 1a705574..b063c9d4 100644 --- a/mock/src/main/java/seng302/Networking/Utils/RaceMessage.java +++ b/network/src/main/java/seng302/Networking/Utils/RaceMessage.java @@ -3,12 +3,13 @@ package seng302.Networking.Utils; /** * Created by fwy13 on 19/04/17. */ -public class RaceMessage { +public class RaceMessage extends AC35Data { private int lineNumber; private String messageText; public RaceMessage(int lineNumber, String messageText){ + super(MessageType.DISPLAYTEXTMESSAGE); this.lineNumber = lineNumber; this.messageText = messageText; } diff --git a/network/src/main/java/seng302/Networking/Utils/RaceStartStatus.java b/network/src/main/java/seng302/Networking/Utils/RaceStartStatus.java new file mode 100644 index 00000000..15398f6c --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/RaceStartStatus.java @@ -0,0 +1,24 @@ +package seng302.Networking.Utils; + +import java.util.ArrayList; + +/** + * Created by fwy13 on 25/04/17. + */ +public class RaceStartStatus extends AC35Data{ + private long timestamp; + private int ackNum; + private long raceStartTime; + private int raceID; + private int notificationType; + + public RaceStartStatus(long timestamp, int ackNum, long raceStartTime, int raceID, int notificationType){ + super(MessageType.RACESTARTSTATUS); + this.timestamp = timestamp; + this.ackNum = ackNum; + this.raceStartTime = raceStartTime; + this.raceID = raceID; + this.notificationType = notificationType; + } + +} diff --git a/network/src/main/java/seng302/Networking/Utils/RaceStatus.java b/network/src/main/java/seng302/Networking/Utils/RaceStatus.java new file mode 100644 index 00000000..b749d433 --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/RaceStatus.java @@ -0,0 +1,72 @@ +package seng302.Networking.Utils; + +import java.util.ArrayList; + +/** + * Created by fwy13 on 25/04/17. + */ +public class RaceStatus extends AC35Data{ + private long currentTime; + private int raceID; + private int raceStatus; + private long expectedStartTime; + private int windDirection; + private int windSpeed; + private int raceType; + private ArrayList boatStatuses; + + public RaceStatus(long currentTime, int raceID, int raceStatus, long expectedStartTime, int windDirection, int windSpeed, int raceType, ArrayList boatStatuses){ + super(MessageType.RACESTATUS); + this.currentTime = currentTime; + this.raceID = raceID; + this.raceStatus = raceStatus; + this.expectedStartTime = expectedStartTime; + this.windDirection = windDirection; + this.windSpeed = windSpeed; + this.raceType = raceType; + this.boatStatuses = boatStatuses;//note this is a copy so any alterations to the parent will affect this. + } + + + ///Getters. + + public long getCurrentTime() + { + return currentTime; + } + + public int getRaceID() + { + return raceID; + } + + public int getRaceStatus() + { + return raceStatus; + } + + public long getExpectedStartTime() + { + return expectedStartTime; + } + + public int getWindDirection() + { + return windDirection; + } + + public int getWindSpeed() + { + return windSpeed; + } + + public int getRaceType() + { + return raceType; + } + + public ArrayList getBoatStatuses() + { + return boatStatuses; + } +} diff --git a/network/src/main/java/seng302/Networking/Utils/XMLMessage.java b/network/src/main/java/seng302/Networking/Utils/XMLMessage.java new file mode 100644 index 00000000..733123e3 --- /dev/null +++ b/network/src/main/java/seng302/Networking/Utils/XMLMessage.java @@ -0,0 +1,31 @@ +package seng302.Networking.Utils; + +import org.xml.sax.InputSource; + +/** + * Created by fwy13 on 25/04/17. + */ +public class XMLMessage extends AC35Data{ + + private int ackNumber; + private long timeStamp; + private int xmlMsgSubType; + private int sequenceNumber; + private int xmlMsgLength; + private InputSource xmlMessage; + + public static int XMLTypeRegatta = 5; + public static int XMLTypeRace = 6; + public static int XMLTypeBoat = 7; + + public XMLMessage(int ackNumber, long timeStamp, int xmlMsgSubType, int sequenceNumber, int xmlMsgLength, InputSource xmlMessage){ + super(MessageType.XMLMESSAGE); + this.ackNumber = ackNumber; + this.timeStamp = timeStamp; + this.xmlMsgSubType = xmlMsgSubType; + this.sequenceNumber = sequenceNumber; + this.xmlMsgLength = xmlMsgLength; + this.xmlMessage = xmlMessage; + } + +} diff --git a/network/src/main/java/seng302/Networking/VisualiserInput.java b/network/src/main/java/seng302/Networking/VisualiserInput.java new file mode 100644 index 00000000..942be07f --- /dev/null +++ b/network/src/main/java/seng302/Networking/VisualiserInput.java @@ -0,0 +1,157 @@ +package seng302.Networking; +import seng302.Networking.BinaryMessageDecoder; +import seng302.Networking.MessageDecoders.*; +import seng302.Networking.Utils.*; + +import java.io.*; +import java.net.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import static seng302.Networking.Utils.ByteConverter.bytesToInt; +import static seng302.Networking.Utils.ByteConverter.bytesToShort; +import static seng302.Networking.Utils.MessageType.*; + +/** + * TCP server to act as the mock AC35 streaming interface + */ +public class VisualiserInput +{ + //time since last heartbeat + private long lastHeartbeatTime; + + //socket port 4942 as 4940 is ac35 live port and 4941 is ac35 test port + private ServerSocket visualiserSocket; + private Socket connectionSocket; + + long heartbeatSeqNum; + + + + VisualiserInput() throws IOException{ + + //sockets to connect to +// ServerSocket visualiserSocket = new ServerSocket(4942); +// Socket connectionSocket = visualiserSocket.accept(); + + //this is the test data that streams form the AC35 website + Socket connectionSocket = new Socket("livedata.americascup.com",4941); + + + //start Time + lastHeartbeatTime = System.currentTimeMillis(); + + + //receiver loop that gets the input + boolean receiverLoop = true; + while(receiverLoop) { + //gets the input from the socket + InputStream inFromClient = connectionSocket.getInputStream(); + + //converts the input into a byte array that can be read by the decoder + byte[] binaryMessage = getBytes(inFromClient); + + //decode the binary message into readable date + BinaryMessageDecoder testDecoder = new BinaryMessageDecoder(binaryMessage); + testDecoder.decode(); + + //checks which message is being received and does what is needed for that message + MessageType mType = MessageType.valueOf((byte) testDecoder.getMessageType()); + switch (mType) { + case HEARTBEAT: + lastHeartbeatTime = System.currentTimeMillis(); + //note: if the program runs for over 340 years, this will crash. + heartbeatSeqNum = ByteConverter.bytesToLong(testDecoder.getMessage()); + System.out.println("HeartBeat Message! " + heartbeatSeqNum); + break; + case RACESTATUS: +// System.out.println("Race Status Message"); + break; + case DISPLAYTEXTMESSAGE: +// System.out.println("Display Text Message"); + //no decoder for this. + break; + case XMLMESSAGE: +// System.out.println("XML Message!"); + XMLMessageDecoder xmlMessageDecoder = new XMLMessageDecoder(testDecoder.getMessage()); + xmlMessageDecoder.decode(); + System.out.println(xmlMessageDecoder.getXmlMessageInputSource()); + break; + case RACESTARTSTATUS: +// System.out.println("Race Start Status Message"); + break; + case YACHTEVENTCODE: +// System.out.println("Yacht Action Code!"); + //no decoder + break; + case YACHTACTIONCODE: +// System.out.println("Yacht Action Code!"); + //no decoder + break; + case CHATTERTEXT: +// System.out.println("Chatter Text Message!"); + //no decoder + break; + case BOATLOCATION: +// System.out.println("Boat Location Message!"); + break; + case MARKROUNDING: +// System.out.println("Mark Rounding Message!"); + break; + case COURSEWIND: +// System.out.println("Course Wind Message!"); + break; + case AVGWIND: +// System.out.println("Average Wind Message!"); + break; + default: +// System.out.println("Broken Message!"); + break; + } + + //if no heartbeat has been received in more than 6 seconds + //the connection will need to be restarted + if (timeSinceHeartbeat() > 6){ + System.out.println("Connection has stopped, trying to reconnect"); + receiverLoop = false; + } + } + } + + /** + * calculates the time since last heartbeat + * @return time since last heartbeat + */ + private double timeSinceHeartbeat() { + long now = System.currentTimeMillis(); + return (now - lastHeartbeatTime) / 1000.0; + } + + /** + * Takes an inputStream and reads the first 15 bytes (the header) and gets the message length + * for the whole message then reads that and returns the byte array + * @param inStream inputStream from socket + * @return encoded binary messsage bytes + * @throws IOException + */ + private static byte[] getBytes(InputStream inStream) throws IOException { + byte[] headerBytes = new byte[15]; + int i = inStream.read(headerBytes); + byte[] messageLenBytes = Arrays.copyOfRange(headerBytes, 13, 15); + short messageLen = bytesToShort(messageLenBytes); + byte[] messageBytesWithCRC = new byte[messageLen+4]; + int j = inStream.read(messageBytesWithCRC); + ByteBuffer binaryMessageBytes = ByteBuffer.allocate(headerBytes.length+messageBytesWithCRC.length); + binaryMessageBytes.put(headerBytes); + binaryMessageBytes.put(messageBytesWithCRC); + return binaryMessageBytes.array(); + } + + public static void main(String argv[]) throws Exception + { + VisualiserInput reciever = new VisualiserInput(); + } + +} diff --git a/network/src/main/resources/dataDumps/ac35.bin b/network/src/main/resources/dataDumps/ac35.bin new file mode 100644 index 00000000..2889c3c2 Binary files /dev/null and b/network/src/main/resources/dataDumps/ac35.bin differ diff --git a/network/src/main/resources/raceXML/Boats.xml b/network/src/main/resources/raceXML/Boats.xml new file mode 100644 index 00000000..ed4b6ded --- /dev/null +++ b/network/src/main/resources/raceXML/Boats.xml @@ -0,0 +1,119 @@ + + + + 2017-04-19T15:49:40+1200 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network/src/main/resources/raceXML/Race.xml b/network/src/main/resources/raceXML/Race.xml new file mode 100644 index 00000000..29478c60 --- /dev/null +++ b/network/src/main/resources/raceXML/Race.xml @@ -0,0 +1,58 @@ + + + 17041901 + Fleet + 2017-04-19T15:30:00+1200 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network/src/main/resources/raceXML/Regatta.xml b/network/src/main/resources/raceXML/Regatta.xml new file mode 100644 index 00000000..23fde025 --- /dev/null +++ b/network/src/main/resources/raceXML/Regatta.xml @@ -0,0 +1,12 @@ + + + + 1 + Seng302 Mock Test + Bermuda AC35 + -32.296577 + 64.854304 + 0.00 + -4 + -14.78 + \ No newline at end of file diff --git a/mock/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java b/network/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java similarity index 84% rename from mock/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java rename to network/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java index 016e4355..29c2d932 100644 --- a/mock/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java +++ b/network/src/test/java/seng302/Networking/BinaryMessageDecoderTest.java @@ -2,15 +2,12 @@ package seng302.Networking; import org.junit.Assert; import org.junit.Test; -import seng302.Networking.BinaryMesageEncoder; -import seng302.Networking.BinaryMessageDecoder; +import org.xml.sax.InputSource; import seng302.Networking.MessageDecoders.XMLMessageDecoder; import seng302.Networking.MessageEncoders.XMLMessageEncoder; import seng302.Networking.Utils.MessageType; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; /** * Created by hba56 on 21/04/17. @@ -28,7 +25,7 @@ public class BinaryMessageDecoderTest { xmlString.append(line.trim()); } long time = System.currentTimeMillis(); - XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); + XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); byte[] encodedMessage = testEncoder.encode(); @@ -56,7 +53,14 @@ public class BinaryMessageDecoderTest { Assert.assertEquals((byte)7, decoderXML.getXmlMsgSubType()); Assert.assertEquals((short)1, decoderXML.getSequenceNumber()); Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength()); - Assert.assertEquals(xmlString.toString(), decoderXML.getXmlMessage()); + + Reader reader = decoderXML.getXmlMessageInputSource().getCharacterStream(); + int c; + String contents = ""; + while((c = reader.read()) != -1) { + contents += (char)c; + } + Assert.assertEquals(xmlString.toString(), contents); }catch (IOException e){ System.out.println(e); diff --git a/network/src/test/java/seng302/Networking/ByteConverterTest.java b/network/src/test/java/seng302/Networking/ByteConverterTest.java new file mode 100644 index 00000000..a1390b59 --- /dev/null +++ b/network/src/test/java/seng302/Networking/ByteConverterTest.java @@ -0,0 +1,165 @@ +package seng302.Networking; + +import org.junit.Test; +import seng302.Networking.Utils.ByteConverter; + +import java.nio.ByteOrder; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +/** + * Created by fwy13 on 25/04/17. + */ +public class ByteConverterTest { + + @Test + public void testLargerIntToByte(){ + int int1 = 1532158456; //100 in bytes + byte[] bytes1 = {(byte)0xF8, (byte)0xE1, 0x52, 0x5B};//this is in little endian + assertTrue(testArrayContents(ByteConverter.intToBytes(int1), bytes1)); + byte[] bytes2 = {0x5B, 0x52, (byte)0xE1, (byte)0xF8};// this is big endian + assertTrue(testArrayContents(ByteConverter.intToBytes(int1, ByteConverter.IntegerSize, ByteOrder.BIG_ENDIAN), bytes2)); + //test chopping + byte[] chopped1 = ByteConverter.intToBytes(int1, 3, ByteOrder.LITTLE_ENDIAN); + byte[] bytes3 = {(byte)0xF8, (byte)0xE1, 0x52}; + assertTrue(testArrayContents(chopped1, bytes3)); + byte[] chopped2 = ByteConverter.intToBytes(int1, 2, ByteOrder.LITTLE_ENDIAN); + byte[] bytes4 = {(byte)0xF8, (byte)0xE1}; + assertTrue(testArrayContents(chopped2, bytes4)); + byte[] chopped3 = ByteConverter.intToBytes(int1, 1, ByteOrder.LITTLE_ENDIAN); + byte[] bytes5 = {(byte)0xF8}; + assertTrue(testArrayContents(chopped3, bytes5)); + + byte[] chopped4 = ByteConverter.intToBytes(int1, 3, ByteOrder.BIG_ENDIAN); + byte[] bytes6 = {0x52, (byte)0xE1, (byte)0xF8}; + assertTrue(testArrayContents(chopped4, bytes6)); + byte[] chopped5 = ByteConverter.intToBytes(int1, 2, ByteOrder.BIG_ENDIAN); + byte[] bytes7 = {(byte)0xE1, (byte)0xF8}; + assertTrue(testArrayContents(chopped5, bytes7)); + byte[] chopped6 = ByteConverter.intToBytes(int1, 1, ByteOrder.BIG_ENDIAN); + byte[] bytes8 = {(byte)0xF8}; + assertTrue(testArrayContents(chopped6, bytes8)); + } + + @Test + public void testByteToInt(){ + int int1 = 100; //100 in bytes + byte[] bytes1 = {100, 0, 0, 0};//this is in little endian + assertTrue(ByteConverter.bytesToInt(bytes1) == int1); + assertTrue(ByteConverter.bytesToInt(bytes1, ByteOrder.LITTLE_ENDIAN) == int1); + byte[] bytes2 = {0, 0, 0, 100};// this is big endian + assertTrue(ByteConverter.bytesToInt(bytes2, ByteOrder.BIG_ENDIAN) == int1); + //check single bytes to integers + assertTrue(ByteConverter.bytesToInt((byte)100) == int1); + } + + @Test + public void testByteToLong(){ + long lng1 = 15; //100 in bytes + byte[] bytes1 = {15, 0, 0, 0, 0, 0, 0, 0};//this is in little endian + assertTrue(ByteConverter.bytesToLong(bytes1) == lng1); + assertTrue(ByteConverter.bytesToLong(bytes1, ByteOrder.LITTLE_ENDIAN) == lng1); + byte[] bytes2 = {0, 0, 0, 0, 0, 0, 0, 15};// this is big endian + assertTrue(ByteConverter.bytesToLong(bytes2, ByteOrder.BIG_ENDIAN) == lng1); + //check single bytes to integers + assertTrue(ByteConverter.bytesToLong((byte)15) == lng1); + } + + @Test + public void testByteToShort(){ + short short1 = 20; //100 in bytes + byte[] bytes1 = {20, 0};//this is in little endian + assertTrue(ByteConverter.bytesToShort(bytes1) == short1); + assertTrue(ByteConverter.bytesToShort(bytes1, ByteOrder.LITTLE_ENDIAN) == short1); + byte[] bytes2 = {0, 20};// this is big endian + assertTrue(ByteConverter.bytesToShort(bytes2, ByteOrder.BIG_ENDIAN) == short1); + //check single bytes to integers + assertTrue(ByteConverter.bytesToShort((byte)20) == short1); + } + + @Test + public void testByteToChar(){ + char char1 = 20; //100 in bytes + byte[] bytes1 = {20, 0};//this is in little endian + assertTrue(ByteConverter.bytesToChar(bytes1) == char1); + assertTrue(ByteConverter.bytesToChar(bytes1, ByteOrder.LITTLE_ENDIAN) == char1); + byte[] bytes2 = {0, 20};// this is big endian + assertTrue(ByteConverter.bytesToChar(bytes2, ByteOrder.BIG_ENDIAN) == char1); + //check single bytes to integers + assertTrue(ByteConverter.bytesToChar((byte)20) == char1); + } + + @Test + public void testIntToByte(){ + int int1 = 100; //100 in bytes + byte[] bytes1 = {100, 0, 0, 0};//this is in little endian + assertTrue(testArrayContents(ByteConverter.intToBytes(int1), bytes1)); + byte[] bytes2 = {0, 0, 0, 100};// this is big endian + assertTrue(testArrayContents(ByteConverter.intToBytes(int1, ByteConverter.IntegerSize, ByteOrder.BIG_ENDIAN), bytes2)); + //test chopping + byte[] chopped1 = ByteConverter.intToBytes(int1, 3, ByteOrder.LITTLE_ENDIAN); + byte[] bytes3 = {100, 0, 0}; + assertTrue(testArrayContents(chopped1, bytes3)); + byte[] chopped2 = ByteConverter.intToBytes(int1, 2, ByteOrder.LITTLE_ENDIAN); + byte[] bytes4 = {100, 0}; + assertTrue(testArrayContents(chopped2, bytes4)); + byte[] chopped3 = ByteConverter.intToBytes(int1, 1, ByteOrder.LITTLE_ENDIAN); + byte[] bytes5 = {100}; + assertTrue(testArrayContents(chopped3, bytes5)); + + byte[] chopped4 = ByteConverter.intToBytes(int1, 3, ByteOrder.BIG_ENDIAN); + byte[] bytes6 = {0, 0, 100}; + assertTrue(testArrayContents(chopped4, bytes6)); + byte[] chopped5 = ByteConverter.intToBytes(int1, 2, ByteOrder.BIG_ENDIAN); + byte[] bytes7 = {0, 100}; + assertTrue(testArrayContents(chopped5, bytes7)); + byte[] chopped6 = ByteConverter.intToBytes(int1, 1, ByteOrder.BIG_ENDIAN); + byte[] bytes8 = {100}; + assertTrue(testArrayContents(chopped6, bytes8)); + } + + @Test + public void testLongToBytes(){ + long lng1 = 15; //100 in bytes + byte[] bytes1 = {15, 0, 0, 0, 0, 0, 0, 0};//this is in little endian + assertTrue(testArrayContents(ByteConverter.longToBytes(lng1), bytes1)); + byte[] bytes2 = {0, 0, 0, 0, 0, 0, 0, 15};// this is big endian + assertTrue(testArrayContents(ByteConverter.longToBytes(lng1, ByteConverter.LongSize, ByteOrder.BIG_ENDIAN), bytes2)); + //test chopping + byte[] chopped1 = ByteConverter.longToBytes(lng1, 3, ByteOrder.LITTLE_ENDIAN); + byte[] bytes3 = {15, 0, 0}; + assertTrue(testArrayContents(chopped1, bytes3)); + byte[] chopped2 = ByteConverter.longToBytes(lng1, 2, ByteOrder.LITTLE_ENDIAN); + byte[] bytes4 = {15, 0}; + assertTrue(testArrayContents(chopped2, bytes4)); + byte[] chopped3 = ByteConverter.longToBytes(lng1, 1, ByteOrder.LITTLE_ENDIAN); + byte[] bytes5 = {15}; + assertTrue(testArrayContents(chopped3, bytes5)); + + byte[] chopped4 = ByteConverter.longToBytes(lng1, 3, ByteOrder.BIG_ENDIAN); + byte[] bytes6 = {0, 0, 15}; + assertTrue(testArrayContents(chopped4, bytes6)); + byte[] chopped5 = ByteConverter.longToBytes(lng1, 2, ByteOrder.BIG_ENDIAN); + byte[] bytes7 = {0, 15}; + assertTrue(testArrayContents(chopped5, bytes7)); + byte[] chopped6 = ByteConverter.longToBytes(lng1, 1, ByteOrder.BIG_ENDIAN); + byte[] bytes8 = {15}; + assertTrue(testArrayContents(chopped6, bytes8)); + } + + public boolean testArrayContents(byte[] bytes1, byte[] bytes2){ + if (bytes1.length != bytes2.length){ + return false; + } + for (int i = 0; i < bytes1.length; i++){ + if (bytes1[i] != bytes2[i]){ + return false; + } + } + return true; + } + +} diff --git a/mock/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java b/network/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java similarity index 91% rename from mock/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java rename to network/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java index 45f950e5..808b879e 100644 --- a/mock/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java +++ b/network/src/test/java/seng302/Networking/MessageDecoders/BoatLocationDecoderTest.java @@ -2,7 +2,6 @@ package seng302.Networking.MessageDecoders; import org.junit.Assert; import org.junit.Test; -import seng302.Networking.MessageDecoders.BoatLocationDecoder; import seng302.Networking.Utils.BoatLocationMessage; import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; @@ -14,10 +13,10 @@ public class BoatLocationDecoderTest { @Test public void getByteArrayTest(){ long time = System.currentTimeMillis(); - BoatLocationMessage testMessage = new BoatLocationMessage((byte)1, time, (byte)2, - 3, (byte) 1, 180, -180, 4, (short)5, - (short)6, (short)7, 8, 9, 10, 11, - (short) 12, 13,(short) 14 ,(short) 15, + BoatLocationMessage testMessage = new BoatLocationMessage((byte) 1, time, 2, + 3, (byte) 1, 180, -180, 4, 5, + (short) 6, (short) 7, 8, 9, 10, 11, + (short) 12, 13, 14 , (short) 15, 16, 17, (short) 18); RaceVisionByteEncoder raceVisionByteEncoder = new RaceVisionByteEncoder(); byte [] testEncodedMessage = raceVisionByteEncoder.boatLocation(testMessage); diff --git a/mock/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java b/network/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java similarity index 98% rename from mock/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java rename to network/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java index 6508aaef..bbe6ea8d 100644 --- a/mock/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java +++ b/network/src/test/java/seng302/Networking/MessageDecoders/CourseWindDecoderTest.java @@ -2,7 +2,6 @@ package seng302.Networking.MessageDecoders; import org.junit.Assert; import org.junit.Test; -import seng302.Networking.MessageDecoders.CourseWindDecoder; import seng302.Networking.Utils.CourseWind; import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; diff --git a/mock/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java b/network/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java similarity index 94% rename from mock/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java rename to network/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java index 04bb028f..1dad9635 100644 --- a/mock/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java +++ b/network/src/test/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoderTest.java @@ -2,7 +2,6 @@ package seng302.Networking.MessageDecoders; import org.junit.Assert; import org.junit.Test; -import seng302.Networking.MessageDecoders.RaceStartStatusDecoder; import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; /** diff --git a/network/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java b/network/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java new file mode 100644 index 00000000..b9c2bd86 --- /dev/null +++ b/network/src/test/java/seng302/Networking/MessageDecoders/RaceStatusDecoderTest.java @@ -0,0 +1,75 @@ +package seng302.Networking.MessageDecoders; + +import org.junit.Assert; +import org.junit.Test; +import seng302.Networking.MessageEncoders.RaceVisionByteEncoder; +import seng302.Networking.Utils.BoatStatus; +import seng302.Networking.Utils.RaceStatus; + +import java.util.ArrayList; + +/** + * Created by hba56 on 23/04/17. + */ +public class RaceStatusDecoderTest { + @Test + public void getByteArrayTest(){ + long time = System.currentTimeMillis(); + + //Create data to serialize. + int boat1SourceID = 5; + int boat2SourceID = 8; + byte boat1Status = 2; + byte boat2Status = 2; + byte boat1LegNumber = 5; + byte boat2LegNumber = 3; + byte boat1PenaltiesAwarded = 4; + byte boat2PenaltiesAwarded = 0; + byte boat1PenaltiesServed = 2; + byte boat2PenaltiesServed = 0; + long boat1TimeAtNextMark = time + (1000 * 3); + long boat2TimeAtNextMark = time + (1000 * 2); + long boat1TimeAtFinish = boat1TimeAtNextMark + (1000 * 15); + long boat2TimeAtFinish = boat2TimeAtNextMark + (1000 * 7); + + BoatStatus boatStatus1 = new BoatStatus(boat1SourceID, boat1Status, boat1LegNumber, boat1PenaltiesAwarded, boat1PenaltiesServed, boat1TimeAtNextMark, boat1TimeAtFinish); + BoatStatus boatStatus2 = new BoatStatus(boat2SourceID, boat2Status, boat2LegNumber, boat2PenaltiesAwarded, boat2PenaltiesServed, boat2TimeAtNextMark, boat2TimeAtFinish); + + int raceID = 585; + int raceStatus = 3; + long raceStartTime = time - (1000 * 31); + int windDirection = 2341; + int windSpeed = 10201; + int raceType = 1; + ArrayList boatStatuses = new ArrayList<>(2); + boatStatuses.add(boatStatus1); + boatStatuses.add(boatStatus2); + + RaceStatus raceStatusObject = new RaceStatus(time, raceID, raceStatus, raceStartTime, windDirection, windSpeed, raceType, boatStatuses); + + + byte[] encodedRaceStatus = RaceVisionByteEncoder.raceStatus(raceStatusObject); + + RaceStatusDecoder decoderTest = new RaceStatusDecoder(encodedRaceStatus); + + Assert.assertEquals(0b10, decoderTest.getVersionNum()); + Assert.assertEquals(time, decoderTest.getTime()); + Assert.assertEquals(raceID, decoderTest.getRace()); + Assert.assertEquals(raceStatus, decoderTest.getRaceState()); + Assert.assertEquals(raceStartTime, decoderTest.getStartTime()); + Assert.assertEquals(windDirection, decoderTest.getRaceWindDir()); + Assert.assertEquals(windSpeed, decoderTest.getRaceWindSpeed()); + + + BoatStatus boat1 = decoderTest.getBoats().get(0); + + Assert.assertEquals(boat1SourceID, boat1.getSourceID()); + Assert.assertEquals(boat1Status, boat1.getBoatStatus()); + Assert.assertEquals(boat1LegNumber, boat1.getLegNumber()); + Assert.assertEquals(boat1PenaltiesAwarded, boat1.getNumPenaltiesAwarded()); + Assert.assertEquals(boat1PenaltiesServed, boat1.getNumPenaltiesServed()); + Assert.assertEquals(boat1TimeAtNextMark, boat1.getEstTimeAtNextMark()); + Assert.assertEquals(boat1TimeAtFinish, boat1.getEstTimeAtFinish()); + + } +} diff --git a/mock/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java b/network/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java similarity index 79% rename from mock/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java rename to network/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java index fd71370b..12dd089c 100644 --- a/mock/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java +++ b/network/src/test/java/seng302/Networking/MessageDecoders/XMLMessageDecoderTest.java @@ -2,12 +2,12 @@ package seng302.Networking.MessageDecoders; import org.junit.Assert; import org.junit.Test; -import seng302.Networking.MessageDecoders.XMLMessageDecoder; import seng302.Networking.MessageEncoders.XMLMessageEncoder; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.Reader; /** * Created by hba56 on 20/04/17. @@ -25,7 +25,7 @@ public class XMLMessageDecoderTest { xmlString.append(line.trim()); } long time = System.currentTimeMillis(); - XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); + XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, time, (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); byte[] encodedXML = testEncoder.encode(); @@ -39,7 +39,14 @@ public class XMLMessageDecoderTest { Assert.assertEquals((byte)7, decoderXML.getXmlMsgSubType()); Assert.assertEquals((short)1, decoderXML.getSequenceNumber()); Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength()); - Assert.assertEquals(xmlString.toString(), decoderXML.getXmlMessage()); + + Reader reader = decoderXML.getXmlMessageInputSource().getCharacterStream(); + int c; + String contents = ""; + while((c = reader.read()) != -1) { + contents += (char)c; + } + Assert.assertEquals(xmlString.toString(), contents); }catch (IOException e){ System.out.println(e); diff --git a/mock/src/test/java/seng302/Networking/XMLMessageEncoderTest.java b/network/src/test/java/seng302/Networking/XMLMessageEncoderTest.java similarity index 88% rename from mock/src/test/java/seng302/Networking/XMLMessageEncoderTest.java rename to network/src/test/java/seng302/Networking/XMLMessageEncoderTest.java index ad64d927..fb1bbe87 100644 --- a/mock/src/test/java/seng302/Networking/XMLMessageEncoderTest.java +++ b/network/src/test/java/seng302/Networking/XMLMessageEncoderTest.java @@ -21,7 +21,7 @@ public class XMLMessageEncoderTest { while((line=br.readLine())!= null){ xmlString.append(line.trim()); } - XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); + XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)xmlString.length(), xmlString.toString()); byte[] encodedXML = testEncoder.encode(); @@ -43,7 +43,7 @@ public class XMLMessageEncoderTest { while((line=br.readLine())!= null){ xmlString.append(line.trim()); } - XMLMessageEncoder testEncoder = new XMLMessageEncoder((byte)1, (short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)1, xmlString.toString()); + XMLMessageEncoder testEncoder = new XMLMessageEncoder((short)1, System.currentTimeMillis(), (byte)7, (short)1, (short)1, xmlString.toString()); byte[] encodedXML = testEncoder.encode(); diff --git a/network/src/test/resources/raceXML/Regatta.xml b/network/src/test/resources/raceXML/Regatta.xml new file mode 100644 index 00000000..23fde025 --- /dev/null +++ b/network/src/test/resources/raceXML/Regatta.xml @@ -0,0 +1,12 @@ + + + + 1 + Seng302 Mock Test + Bermuda AC35 + -32.296577 + 64.854304 + 0.00 + -4 + -14.78 + \ No newline at end of file diff --git a/pom.xml b/pom.xml index cd0a669d..2003bb14 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,8 @@ mock visualiser + network + sharedModel https://eng-git.canterbury.ac.nz/SENG302-2016/team-7 diff --git a/sharedModel/pom.xml b/sharedModel/pom.xml new file mode 100644 index 00000000..4b814efa --- /dev/null +++ b/sharedModel/pom.xml @@ -0,0 +1,155 @@ + + 4.0.0 + + seng302 + team-7 + 1.0-SNAPSHOT + + + jar + sharedModel + sharedModel + 1.0-SNAPSHOT + + + + junit + junit + 4.12 + test + + + + + + + org.mockito + mockito-all + 1.9.5 + + + + + + org.testng + testng + 6.11 + test + + + + + org.geotools + gt-referencing + 9.0 + + + + + + + + maven2-repository.dev.java.net + Java.net repository + http://download.java.net/maven/2 + + + + + osgeo + Open Source Geospatial Foundation Repository + http://download.osgeo.org/webdav/geotools/ + + + + + + + + + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + org.apache.maven.plugins + maven-shade-plugin + 2.4.3 + + + + + seng302.App + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + package + + shade + + + + + + + + + + org.apache.maven.plugins + maven-jxr-plugin + 2.5 + + + org.apache.maven.plugins + maven-pmd-plugin + 3.6 + + true + ${maven.compiler.target} + + /rulesets/java/basic.xml + /rulesets/java/imports.xml + /rulesets/java/codesize.xml + /rulesets/java/design.xml + /rulesets/java/empty.xml + /rulesets/java/junit.xml + /rulesets/java/unusedcode.xml + + true + utf-8 + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 2.19.1 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8.1 + + + + diff --git a/mock/src/main/java/seng302/Model/Boat.java b/sharedModel/src/main/java/SharedModel/Boat.java similarity index 94% rename from mock/src/main/java/seng302/Model/Boat.java rename to sharedModel/src/main/java/SharedModel/Boat.java index 5edb9aa4..ac7baeb1 100644 --- a/mock/src/main/java/seng302/Model/Boat.java +++ b/sharedModel/src/main/java/SharedModel/Boat.java @@ -1,4 +1,4 @@ -package seng302.Model; +package SharedModel; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; @@ -19,7 +19,7 @@ public class Boat { * * @param name Name of the Boat. * @param velocity Speed in m/s that the boat travels at. - * @param abbrev nam abbreviation + * @param abbrev nam abbreviation */ public Boat(String name, double velocity, String abbrev, int sourceID) { this.velocity = velocity; @@ -52,8 +52,6 @@ public class Boat { return velocity; } - public int getSourceID() { return sourceID; } - /** * Sets the speed of the boat in knots. * @@ -64,6 +62,10 @@ public class Boat { this.velocityProp.setValue(String.valueOf(Math.round(velocity))); } + public int getSourceID() { + return sourceID; + } + /** * Print method prints the name of the boat * diff --git a/mock/src/main/java/seng302/Model/BoatInRace.java b/sharedModel/src/main/java/SharedModel/BoatInRace.java similarity index 97% rename from mock/src/main/java/seng302/Model/BoatInRace.java rename to sharedModel/src/main/java/SharedModel/BoatInRace.java index 2935d5c9..5ece3b1f 100644 --- a/mock/src/main/java/seng302/Model/BoatInRace.java +++ b/sharedModel/src/main/java/SharedModel/BoatInRace.java @@ -1,15 +1,12 @@ -package seng302.Model; +package SharedModel; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.scene.paint.Color; import org.geotools.referencing.GeodeticCalculator; -import seng302.Constants; -import seng302.GPSCoordinate; + import java.awt.geom.Point2D; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; /** * Boat in the Race extends Boat. @@ -40,7 +37,7 @@ public class BoatInRace extends Boat { * @param name Name of the boat. * @param velocity Speed that the boat travels. * @param colour Colour the boat will be displayed as on the map - * @param abbrev of boat + * @param abbrev of boat */ public BoatInRace(String name, double velocity, Color colour, String abbrev, int sourceID) { super(name, velocity, abbrev, sourceID); @@ -49,6 +46,20 @@ public class BoatInRace extends Boat { position = new SimpleStringProperty("-"); } + /** + * Converts an azimuth to a bearing + * + * @param azimuth azimuth value to be converted + * @return the bearings in degrees (0 to 360). + */ + public static double calculateHeading(double azimuth) { + if (azimuth >= 0) { + return azimuth; + } else { + return azimuth + 360; + } + } + /** * Calculates the azimuth of the travel via map coordinates of the raceMarkers * @@ -66,20 +77,6 @@ public class BoatInRace extends Boat { return calc.getAzimuth(); } - /** - * Converts an azimuth to a bearing - * - * @param azimuth azimuth value to be converted - * @return the bearings in degrees (0 to 360). - */ - public static double calculateHeading(double azimuth) { - if (azimuth >= 0) { - return azimuth; - } else { - return azimuth + 360; - } - } - public double getHeading() { return heading; } @@ -258,20 +255,20 @@ public class BoatInRace extends Boat { return position.get(); } - public StringProperty positionProperty() { - return position; - } - public void setPosition(String position) { this.position.set(position); } + public StringProperty positionProperty() { + return position; + } /** * Returns the current sequence number, and increments the internal value, such that that next call will return a value 1 larger than the current call. + * * @return Current sequence number. */ - public long getNextSequenceNumber(){ + public long getNextSequenceNumber() { //Make a copy of current value. long oldNumber = this.sequenceNumber; //Increment. diff --git a/mock/src/main/java/seng302/Constants.java b/sharedModel/src/main/java/SharedModel/Constants.java similarity index 82% rename from mock/src/main/java/seng302/Constants.java rename to sharedModel/src/main/java/SharedModel/Constants.java index 36d97e9e..ab10bf08 100644 --- a/mock/src/main/java/seng302/Constants.java +++ b/sharedModel/src/main/java/SharedModel/Constants.java @@ -1,7 +1,4 @@ -package seng302; - -import javafx.scene.paint.Color; -import seng302.Model.BoatInRace; +package SharedModel; /** * Constants that are used throughout the program diff --git a/mock/src/main/java/seng302/GPSCoordinate.java b/sharedModel/src/main/java/SharedModel/GPSCoordinate.java similarity index 98% rename from mock/src/main/java/seng302/GPSCoordinate.java rename to sharedModel/src/main/java/SharedModel/GPSCoordinate.java index 44249833..9eefbb0d 100644 --- a/mock/src/main/java/seng302/GPSCoordinate.java +++ b/sharedModel/src/main/java/SharedModel/GPSCoordinate.java @@ -1,4 +1,4 @@ -package seng302; +package SharedModel; /** * GPS Coordinate for the world map. diff --git a/mock/src/main/java/seng302/Model/Leg.java b/sharedModel/src/main/java/SharedModel/Leg.java similarity index 92% rename from mock/src/main/java/seng302/Model/Leg.java rename to sharedModel/src/main/java/SharedModel/Leg.java index 2cd45249..6ea7a065 100644 --- a/mock/src/main/java/seng302/Model/Leg.java +++ b/sharedModel/src/main/java/SharedModel/Leg.java @@ -1,8 +1,7 @@ -package seng302.Model; +package SharedModel; import org.geotools.referencing.GeodeticCalculator; -import seng302.Constants; -import seng302.GPSCoordinate; + /** * Created by cbt24 on 6/03/17. @@ -17,9 +16,9 @@ public class Leg { /** * Leg Initialiser * - * @param name Name of the Leg - * @param start marker - * @param end marker + * @param name Name of the Leg + * @param start marker + * @param end marker * @param number Leg's position in race */ public Leg(String name, Marker start, Marker end, int number) { @@ -33,7 +32,7 @@ public class Leg { /** * Construction Method * - * @param name Name of the Leg + * @param name Name of the Leg * @param number leg number */ public Leg(String name, int number) { @@ -74,16 +73,14 @@ public class Leg { return startMarker; } + public void setStartMarker(Marker startMarker) { + this.startMarker = startMarker; + } public Marker getEndMarker() { return endMarker; } - - public void setStartMarker(Marker startMarker) { - this.startMarker = startMarker; - } - public void setEndMarker(Marker endMarker) { this.endMarker = endMarker; } diff --git a/mock/src/main/java/seng302/Model/Marker.java b/sharedModel/src/main/java/SharedModel/Marker.java similarity index 97% rename from mock/src/main/java/seng302/Model/Marker.java rename to sharedModel/src/main/java/SharedModel/Marker.java index 17f9ebe2..c194725d 100644 --- a/mock/src/main/java/seng302/Model/Marker.java +++ b/sharedModel/src/main/java/SharedModel/Marker.java @@ -1,7 +1,6 @@ -package seng302.Model; +package SharedModel; import org.geotools.referencing.GeodeticCalculator; -import seng302.GPSCoordinate; import java.awt.geom.Point2D; diff --git a/mock/src/main/java/seng302/Model/Regatta.java b/sharedModel/src/main/java/SharedModel/Regatta.java similarity index 99% rename from mock/src/main/java/seng302/Model/Regatta.java rename to sharedModel/src/main/java/SharedModel/Regatta.java index 0060f2c4..95db9f35 100644 --- a/mock/src/main/java/seng302/Model/Regatta.java +++ b/sharedModel/src/main/java/SharedModel/Regatta.java @@ -1,4 +1,4 @@ -package seng302.Model; +package SharedModel; /** * Created by jjg64 on 19/04/17. diff --git a/sharedModel/src/main/java/seng302/App.java b/sharedModel/src/main/java/seng302/App.java new file mode 100644 index 00000000..3f8ee22d --- /dev/null +++ b/sharedModel/src/main/java/seng302/App.java @@ -0,0 +1,13 @@ +package seng302; + +/** + * Created by f123 on 27-Apr-17. + */ +public class App { + + public static void main(String[] args) { + + } + + +} diff --git a/visualiser/pom.xml b/visualiser/pom.xml index b49bde4d..f8e9b6f8 100644 --- a/visualiser/pom.xml +++ b/visualiser/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 @@ -90,7 +90,8 @@ 2.4.3 - + seng302.App ${maven.compiler.source} diff --git a/visualiser/src/main/java/seng302/App.java b/visualiser/src/main/java/seng302/App.java index cf9d3ed2..dfb983f3 100644 --- a/visualiser/src/main/java/seng302/App.java +++ b/visualiser/src/main/java/seng302/App.java @@ -29,54 +29,4 @@ public class App extends Application { stage.show(); } -// /** -// * Loads and sets up the GUI elements -// * -// * @param primaryStage Base for all scenes -// * @throws Exception Error in initialising programme -// */ -// @Override -// public void start(Stage primaryStage) throws Exception { -// this.primaryStage = primaryStage; -// primaryStage.minHeightProperty().setValue(600); -// primaryStage.minWidthProperty().setValue(780); -// //load the first container -// try { -// FXMLLoader loader = new FXMLLoader(); -// InputStream in = getClass().getClassLoader().getResourceAsStream("scenes/main.fxml"); -// mainContainer = (BorderPane) loader.load(in); -// mainScene = new Scene(mainContainer, 1200, 800); -// primaryStage.setScene(mainScene); -// primaryStage.sizeToScene(); -// MainController mainController = (MainController) loader.getController(); -// mainController.setParent(this); -// in.close(); -// //add the center -// loadPane("race.fxml"); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// primaryStage.show(); -// } -// -// /** -// * Loads panes for use in the GUI -// * -// * @param fxmlName name of resource fxml file -// * @throws Exception critical error in loading file -// */ -// public void loadPane(String fxmlName) throws Exception { -// FXMLLoader loader = new FXMLLoader(); -// InputStream in = getClass().getClassLoader().getResourceAsStream("scenes/" + fxmlName); -// Parent page; -// try { -// page = (Parent) loader.load(in); -// } finally { -// in.close(); -// } -// mainContainer.getChildren().remove(mainContainer.getCenter()); -// mainContainer.setCenter(page); -// Controller controller = (Controller) loader.getController(); -// controller.setParent(this); -// } } diff --git a/visualiser/src/main/java/seng302/Controllers/Controller.java b/visualiser/src/main/java/seng302/Controllers/Controller.java index c5d160e7..ca6b922e 100644 --- a/visualiser/src/main/java/seng302/Controllers/Controller.java +++ b/visualiser/src/main/java/seng302/Controllers/Controller.java @@ -1,7 +1,6 @@ package seng302.Controllers; import javafx.fxml.Initializable; -import seng302.App; import java.net.URL; import java.util.ResourceBundle; @@ -25,7 +24,7 @@ public abstract class Controller implements Initializable { /** * Initialisation class that is run on start up. * - * @param location resources location + * @param location resources location * @param resources resources bundle */ @Override diff --git a/visualiser/src/main/java/seng302/Controllers/MainController.java b/visualiser/src/main/java/seng302/Controllers/MainController.java index 796c47b4..1ca8d4e9 100644 --- a/visualiser/src/main/java/seng302/Controllers/MainController.java +++ b/visualiser/src/main/java/seng302/Controllers/MainController.java @@ -1,11 +1,8 @@ package seng302.Controllers; import javafx.fxml.FXML; -import javafx.scene.control.SplitPane; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.GridPane; import seng302.RaceDataSource; -import seng302.RaceXMLReader; import java.net.URL; import java.util.ResourceBundle; @@ -14,20 +11,20 @@ import java.util.ResourceBundle; * Created by fwy13 on 15/03/2017. */ public class MainController extends Controller { - @FXML StartController startController; - @FXML RaceController raceController; + @FXML + StartController startController; + @FXML + RaceController raceController; public void beginRace(int scaleFactor, RaceDataSource raceData) { raceController.startRace(scaleFactor, raceData); } - - /** * Main Controller for the applications will house the menu and the displayed pane. * - * @param location of resources + * @param location of resources * @param resources bundle */ @Override diff --git a/visualiser/src/main/java/seng302/Controllers/RaceController.java b/visualiser/src/main/java/seng302/Controllers/RaceController.java index 69bbf74b..a96f1436 100644 --- a/visualiser/src/main/java/seng302/Controllers/RaceController.java +++ b/visualiser/src/main/java/seng302/Controllers/RaceController.java @@ -1,25 +1,19 @@ package seng302.Controllers; -import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.layout.GridPane; -import org.xml.sax.SAXException; import seng302.Mock.StreamedRace; -import seng302.Model.*; +import seng302.Model.BoatInRace; +import seng302.Model.Race; +import seng302.Model.RaceClock; +import seng302.Model.ResizableRaceCanvas; import seng302.RaceDataSource; -import seng302.RaceXMLReader; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; import java.net.URL; import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.ResourceBundle; /** @@ -28,16 +22,11 @@ import java.util.ResourceBundle; public class RaceController extends Controller { @FXML GridPane canvasBase; - - //user saved data for annotation display - private ArrayList presetAnno; - ResizableRaceCanvas raceMap; @FXML SplitPane race; @FXML CheckBox showFPS; - @FXML CheckBox showBoatPath; @FXML @@ -48,7 +37,6 @@ public class RaceController extends Controller { Label FPS; @FXML Label timeZone; - @FXML CheckBox showName; @FXML @@ -59,7 +47,6 @@ public class RaceController extends Controller { Button saveAnno; @FXML Button showSetAnno; - @FXML TableView boatInfoTable; @FXML @@ -70,6 +57,8 @@ public class RaceController extends Controller { TableColumn boatMarkColumn; @FXML TableColumn boatSpeedColumn; + //user saved data for annotation display + private ArrayList presetAnno; /** * Updates the ResizableRaceCanvas (raceMap) with most recent data diff --git a/visualiser/src/main/java/seng302/Controllers/StartController.java b/visualiser/src/main/java/seng302/Controllers/StartController.java index 4c70a1a2..95ce2198 100644 --- a/visualiser/src/main/java/seng302/Controllers/StartController.java +++ b/visualiser/src/main/java/seng302/Controllers/StartController.java @@ -17,7 +17,6 @@ import seng302.Mock.*; import seng302.Model.BoatInRace; import seng302.Model.RaceClock; import seng302.RaceDataSource; -import seng302.RaceXMLReader; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; @@ -31,20 +30,28 @@ import java.util.ResourceBundle; */ public class StartController extends Controller { - @FXML private GridPane start; - @FXML private AnchorPane startWrapper; - - @FXML private TableView boatNameTable; - @FXML private TableColumn boatNameColumn; - @FXML private TableColumn boatCodeColumn; - @FXML private Label timeZoneTime; - @FXML private Label timer; - @FXML private int PRERACE_TIME = 15000; - - @FXML Button oneMinButton; - @FXML Button fiveMinButton; - @FXML Button fifteenMinButton; - + @FXML + Button oneMinButton; + @FXML + Button fiveMinButton; + @FXML + Button fifteenMinButton; + @FXML + private GridPane start; + @FXML + private AnchorPane startWrapper; + @FXML + private TableView boatNameTable; + @FXML + private TableColumn boatNameColumn; + @FXML + private TableColumn boatCodeColumn; + @FXML + private Label timeZoneTime; + @FXML + private Label timer; + @FXML + private int PRERACE_TIME = 15000; private RaceClock raceClock; private RaceDataSource raceData; @@ -71,7 +78,7 @@ public class StartController extends Controller { startRace(1); } - private void startRace(int raceScale){ + private void startRace(int raceScale) { oneMinButton.setDisable(true); fiveMinButton.setDisable(true); @@ -80,7 +87,7 @@ public class StartController extends Controller { } @Override - public void initialize(URL location, ResourceBundle resources){ + public void initialize(URL location, ResourceBundle resources) { raceData = null; try { StreamedCourse streamedCourse = new StreamedCourse(new BoatXMLReader("mockXML/boatXML/boatTest.xml")); @@ -102,7 +109,7 @@ public class StartController extends Controller { setRaceClock(); } - public AnchorPane startWrapper(){ + public AnchorPane startWrapper() { return startWrapper; } @@ -133,7 +140,7 @@ public class StartController extends Controller { protected void countdownTimer(int scaleFactor) { new AnimationTimer() { long currentTime = System.currentTimeMillis(); - long startTime = currentTime + (PRERACE_TIME/scaleFactor); + long startTime = currentTime + (PRERACE_TIME / scaleFactor); long minutes; long currentTimeInSeconds; long remainingSeconds; @@ -149,7 +156,7 @@ public class StartController extends Controller { startWrapper.setVisible(false); } else { - currentTimeInSeconds = (timeLeft*scaleFactor) / 1000; + currentTimeInSeconds = (timeLeft * scaleFactor) / 1000; minutes = currentTimeInSeconds / 60; remainingSeconds = currentTimeInSeconds % 60; hours = minutes / 60; diff --git a/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java b/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java index a7d429dc..5d386c0a 100644 --- a/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java +++ b/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java @@ -3,13 +3,11 @@ package seng302.Mock; import javafx.scene.paint.Color; import org.w3c.dom.Element; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import seng302.XMLReader; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; -import java.lang.annotation.ElementType; import java.text.ParseException; import java.util.*; @@ -17,16 +15,17 @@ import java.util.*; * Created by Joseph on 24/04/2017. */ public class BoatXMLReader extends XMLReader { + private static int currentColourIndex = 0; Map streamedBoatMap = new HashMap<>(); Map participants = new HashMap<>(); private List colours; - private static int currentColourIndex = 0; /** * Constructor for Boat XML Reader + * * @param filePath path of the file - * @throws IOException error - * @throws SAXException error + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public BoatXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException, ParseException { @@ -36,10 +35,11 @@ public class BoatXMLReader extends XMLReader { /** * Constructor for Boat XML Reader + * * @param filePath file path to read - * @param read whether or not to read and store the files straight away. - * @throws IOException error - * @throws SAXException error + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public BoatXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException, ParseException { @@ -98,7 +98,8 @@ public class BoatXMLReader extends XMLReader { String shortName = null; String country = null; if (exists(boat, "Type")) type = boat.getAttributes().getNamedItem("Type").getTextContent(); - if (exists(boat, "SourceID")) sourceID = Integer.parseInt(boat.getAttributes().getNamedItem("SourceID").getTextContent()); + if (exists(boat, "SourceID")) + sourceID = Integer.parseInt(boat.getAttributes().getNamedItem("SourceID").getTextContent()); if (exists(boat, "BoatName")) boatName = boat.getAttributes().getNamedItem("BoatName").getTextContent(); if (exists(boat, "ShortName")) shortName = boat.getAttributes().getNamedItem("ShortName").getTextContent(); if (exists(boat, "Country")) country = boat.getAttributes().getNamedItem("Country").getTextContent(); diff --git a/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java b/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java index 6c9cc5f6..d670c499 100644 --- a/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java +++ b/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java @@ -3,7 +3,6 @@ package seng302.Mock; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import seng302.RaceDataSource; import seng302.XMLReader; import javax.xml.parsers.ParserConfigurationException; @@ -17,9 +16,10 @@ public class RegattaXMLReader extends XMLReader { /** * Constructor for Regatta XML + * * @param filePath path of the file - * @throws IOException error - * @throws SAXException error + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RegattaXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { @@ -28,10 +28,11 @@ public class RegattaXMLReader extends XMLReader { /** * Constructor for Regatta XML + * * @param filePath file path to read - * @param read whether or not to read and store the files straight away. - * @throws IOException error - * @throws SAXException error + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RegattaXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { diff --git a/visualiser/src/main/java/seng302/Mock/StreamedBoat.java b/visualiser/src/main/java/seng302/Mock/StreamedBoat.java index 0ff629a0..f31d2a71 100644 --- a/visualiser/src/main/java/seng302/Mock/StreamedBoat.java +++ b/visualiser/src/main/java/seng302/Mock/StreamedBoat.java @@ -1,8 +1,6 @@ package seng302.Mock; import javafx.scene.paint.Color; -import seng302.GPSCoordinate; -import seng302.Model.Boat; import seng302.Model.BoatInRace; /** @@ -27,8 +25,9 @@ public class StreamedBoat extends BoatInRace { /** * Overridden to ignore this function - * @deprecated + * * @return 0 + * @deprecated */ public double getScaledVelocity() { return 0; @@ -36,8 +35,9 @@ public class StreamedBoat extends BoatInRace { /** * Overridden to ignore this function - * @deprecated + * * @param velocity of boat + * @deprecated */ public void setScaledVelocity(double velocity) { } diff --git a/visualiser/src/main/java/seng302/Mock/StreamedCourse.java b/visualiser/src/main/java/seng302/Mock/StreamedCourse.java index f2bcfed0..85831bd8 100644 --- a/visualiser/src/main/java/seng302/Mock/StreamedCourse.java +++ b/visualiser/src/main/java/seng302/Mock/StreamedCourse.java @@ -8,7 +8,8 @@ import seng302.Model.RaceClock; import seng302.RaceDataSource; import java.time.ZonedDateTime; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Created by jjg64 on 21/04/17. @@ -43,14 +44,14 @@ public class StreamedCourse implements RaceDataSource { } } - public void setRegattaXMLReader(RegattaXMLReader regattaXMLReader) { - this.regattaXMLReader = regattaXMLReader; - } - public RegattaXMLReader getRegattaXMLReader() { return regattaXMLReader; } + public void setRegattaXMLReader(RegattaXMLReader regattaXMLReader) { + this.regattaXMLReader = regattaXMLReader; + } + public List getBoats() { return new ArrayList<>(boatXMLReader.getStreamedBoatMap().values()); } diff --git a/visualiser/src/main/java/seng302/Mock/StreamedRace.java b/visualiser/src/main/java/seng302/Mock/StreamedRace.java index 56b6a114..c44b6ce6 100644 --- a/visualiser/src/main/java/seng302/Mock/StreamedRace.java +++ b/visualiser/src/main/java/seng302/Mock/StreamedRace.java @@ -1,14 +1,10 @@ package seng302.Mock; -import javafx.collections.FXCollections; import seng302.Controllers.RaceController; import seng302.Model.BoatInRace; -import seng302.Model.Leg; import seng302.Model.Race; import seng302.RaceDataSource; -import java.util.*; - /** * Created by jjg64 on 21/04/17. */ @@ -26,6 +22,7 @@ public class StreamedRace extends Race { /** * Checks if the boat cannot finish the race + * * @return True if boat cannot finish the race */ protected boolean doNotFinish() { @@ -46,7 +43,7 @@ public class StreamedRace extends Race { /** * Updates the boat's gps coordinates * - * @param boat to be updated + * @param boat to be updated * @param millisecondsElapsed time since last update */ protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { diff --git a/visualiser/src/main/java/seng302/Model/Boat.java b/visualiser/src/main/java/seng302/Model/Boat.java index a3e269d4..5b9842f2 100644 --- a/visualiser/src/main/java/seng302/Model/Boat.java +++ b/visualiser/src/main/java/seng302/Model/Boat.java @@ -18,7 +18,7 @@ public class Boat { * * @param name Name of the Boat. * @param velocity Speed in m/s that the boat travels at. - * @param abbrev nam abbreviation + * @param abbrev nam abbreviation */ public Boat(String name, double velocity, String abbrev) { this.velocity = velocity; @@ -30,7 +30,7 @@ public class Boat { /** * Boat initialiser which keeps all of the information of the boat. * - * @param name Name of the Boat. + * @param name Name of the Boat. * @param abbrev nam abbreviation */ public Boat(String name, String abbrev) { diff --git a/visualiser/src/main/java/seng302/Model/BoatInRace.java b/visualiser/src/main/java/seng302/Model/BoatInRace.java index 6f835593..6b55c567 100644 --- a/visualiser/src/main/java/seng302/Model/BoatInRace.java +++ b/visualiser/src/main/java/seng302/Model/BoatInRace.java @@ -17,8 +17,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; */ public class BoatInRace extends Boat { + protected static final float BASE_TRACK_POINT_TIME_INTERVAL = 5000; + protected static float trackPointTimeInterval = 5000; // every 1 seconds + protected final int TRACK_POINT_LIMIT = 10; protected Leg currentLeg; - private double scaledVelocity; protected double distanceTravelledInLeg; protected GPSCoordinate currentPosition; protected long timeFinished; @@ -28,14 +30,10 @@ public class BoatInRace extends Boat { protected boolean started = false; protected StringProperty position; protected double heading; - protected Queue track = new ConcurrentLinkedQueue<>(); protected long nextValidTime = 0; - - protected static final float BASE_TRACK_POINT_TIME_INTERVAL = 5000; - protected static float trackPointTimeInterval = 5000; // every 1 seconds - protected final int TRACK_POINT_LIMIT = 10; protected boolean trackVisible = true; + private double scaledVelocity; /** * Constructor method. @@ -43,7 +41,7 @@ public class BoatInRace extends Boat { * @param name Name of the boat. * @param velocity Speed that the boat travels. * @param colour Colour the boat will be displayed as on the map - * @param abbrev of boat + * @param abbrev of boat */ public BoatInRace(String name, double velocity, Color colour, String abbrev) { super(name, velocity, abbrev); @@ -55,8 +53,8 @@ public class BoatInRace extends Boat { /** * Constructor method. * - * @param name Name of the boat. - * @param colour Colour the boat will be displayed as on the map + * @param name Name of the boat. + * @param colour Colour the boat will be displayed as on the map * @param abbrev of boat */ public BoatInRace(String name, Color colour, String abbrev) { @@ -66,6 +64,38 @@ public class BoatInRace extends Boat { position = new SimpleStringProperty("-"); } + /** + * Converts an azimuth to a bearing + * + * @param azimuth azimuth value to be converted + * @return the bearings in degrees (0 to 360). + */ + public static double calculateHeading(double azimuth) { + if (azimuth >= 0) { + return azimuth; + } else { + return azimuth + 360; + } + } + + /** + * Get base track point time interval + * + * @return base track point time interval + */ + public static float getBaseTrackPointTimeInterval() { + return BASE_TRACK_POINT_TIME_INTERVAL; + } + + /** + * Set track point time interval + * + * @param value track point time interval value + */ + public static void setTrackPointTimeInterval(float value) { + trackPointTimeInterval = value; + } + /** * Calculates the azimuth of the travel via map coordinates of the raceMarkers * @@ -83,20 +113,6 @@ public class BoatInRace extends Boat { return calc.getAzimuth(); } - /** - * Converts an azimuth to a bearing - * - * @param azimuth azimuth value to be converted - * @return the bearings in degrees (0 to 360). - */ - public static double calculateHeading(double azimuth) { - if (azimuth >= 0) { - return azimuth; - } else { - return azimuth + 360; - } - } - public double getHeading() { return heading; } @@ -276,16 +292,17 @@ public class BoatInRace extends Boat { return position.get(); } - public StringProperty positionProperty() { - return position; - } - public void setPosition(String position) { this.position.set(position); } + public StringProperty positionProperty() { + return position; + } + /** * Adds a new point to boat's track. + * * @param coordinate of point on track * @return whether add is successful * @see seng302.Model.TrackPoint @@ -302,6 +319,7 @@ public class BoatInRace extends Boat { /** * Returns the boat's sampled track between start of race and current time. + * * @return queue of track points * @see seng302.Model.TrackPoint */ @@ -311,6 +329,7 @@ public class BoatInRace extends Boat { /** * Returns whether track is visible + * * @return true if visible */ public boolean isTrackVisible() { @@ -319,25 +338,10 @@ public class BoatInRace extends Boat { /** * Sets track visibility. + * * @param trackVisible visible if true. */ public void setTrackVisible(boolean trackVisible) { this.trackVisible = trackVisible; } - - /** - * Get base track point time interval - * @return base track point time interval - */ - public static float getBaseTrackPointTimeInterval() { - return BASE_TRACK_POINT_TIME_INTERVAL; - } - - /** - * Set track point time interval - * @param value track point time interval value - */ - public static void setTrackPointTimeInterval(float value) { - trackPointTimeInterval = value; - } } diff --git a/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java b/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java index 84fdab19..a0f415eb 100644 --- a/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java +++ b/visualiser/src/main/java/seng302/Model/ConstantVelocityRace.java @@ -25,9 +25,9 @@ public class ConstantVelocityRace extends Race { * Initialiser for a constant velocity race without standard data source * * @param startingBoats in race - * @param legs in race - * @param controller for graphics - * @param scaleFactor of timer + * @param legs in race + * @param controller for graphics + * @param scaleFactor of timer */ public ConstantVelocityRace(List startingBoats, List legs, RaceController controller, int scaleFactor) { super(startingBoats, legs, controller, scaleFactor); @@ -37,10 +37,9 @@ public class ConstantVelocityRace extends Race { * Initialiser for legacy tests * * @param startingBoats in race - * @param legs in race - * @param controller for graphics - * @param scaleFactor of timer - * + * @param legs in race + * @param controller for graphics + * @param scaleFactor of timer * @deprecated Please use {@link #ConstantVelocityRace(List, List, RaceController, int) } for future tests. */ public ConstantVelocityRace(BoatInRace[] startingBoats, List legs, RaceController controller, int scaleFactor) { @@ -49,14 +48,39 @@ public class ConstantVelocityRace extends Race { /** * Initialiser for constant velocity race with standard data source - * @param raceData for race - * @param controller for graphics + * + * @param raceData for race + * @param controller for graphics * @param scaleFactor of timer */ public ConstantVelocityRace(RaceDataSource raceData, RaceController controller, int scaleFactor) { super(raceData, controller, scaleFactor); } + /** + * Calculates the boats next GPS position based on its distance travelled and heading + * + * @param oldCoordinates GPS coordinates of the boat's starting position + * @param distanceTravelled distance in nautical miles + * @param azimuth boat's current direction. Value between -180 and 180 + * @return The boat's new coordinate + */ + public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) { + + //Find new coordinate using current heading and distance + + GeodeticCalculator geodeticCalculator = new GeodeticCalculator(); + //Load start point into calculator + Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude()); + geodeticCalculator.setStartingGeographicPoint(startPoint); + //load direction and distance tranvelled into calculator + geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion); + //get new point + Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint(); + + return new GPSCoordinate(endPoint.getY(), endPoint.getX()); + } + public void initialiseBoats() { Leg officialStart = legs.get(0); String name = officialStart.getName(); @@ -115,6 +139,7 @@ public class ConstantVelocityRace extends Race { /** * Sets the chance each boat has of failing at a gate or marker + * * @param chance percentage chance a boat has of failing per checkpoint. */ protected void setDnfChance(int chance) { @@ -131,7 +156,7 @@ public class ConstantVelocityRace extends Race { /** * Calculates the distance a boat has travelled and updates its current position according to this value. * - * @param boat to be updated + * @param boat to be updated * @param millisecondsElapsed since last update */ protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { @@ -181,28 +206,4 @@ public class ConstantVelocityRace extends Race { } } - /** - * Calculates the boats next GPS position based on its distance travelled and heading - * - * @param oldCoordinates GPS coordinates of the boat's starting position - * @param distanceTravelled distance in nautical miles - * @param azimuth boat's current direction. Value between -180 and 180 - * @return The boat's new coordinate - */ - public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) { - - //Find new coordinate using current heading and distance - - GeodeticCalculator geodeticCalculator = new GeodeticCalculator(); - //Load start point into calculator - Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude()); - geodeticCalculator.setStartingGeographicPoint(startPoint); - //load direction and distance tranvelled into calculator - geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion); - //get new point - Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint(); - - return new GPSCoordinate(endPoint.getY(), endPoint.getX()); - } - } \ No newline at end of file diff --git a/visualiser/src/main/java/seng302/Model/Leg.java b/visualiser/src/main/java/seng302/Model/Leg.java index 2cd45249..1f4f5292 100644 --- a/visualiser/src/main/java/seng302/Model/Leg.java +++ b/visualiser/src/main/java/seng302/Model/Leg.java @@ -17,9 +17,9 @@ public class Leg { /** * Leg Initialiser * - * @param name Name of the Leg - * @param start marker - * @param end marker + * @param name Name of the Leg + * @param start marker + * @param end marker * @param number Leg's position in race */ public Leg(String name, Marker start, Marker end, int number) { @@ -33,7 +33,7 @@ public class Leg { /** * Construction Method * - * @param name Name of the Leg + * @param name Name of the Leg * @param number leg number */ public Leg(String name, int number) { @@ -74,16 +74,14 @@ public class Leg { return startMarker; } + public void setStartMarker(Marker startMarker) { + this.startMarker = startMarker; + } public Marker getEndMarker() { return endMarker; } - - public void setStartMarker(Marker startMarker) { - this.startMarker = startMarker; - } - public void setEndMarker(Marker endMarker) { this.endMarker = endMarker; } diff --git a/visualiser/src/main/java/seng302/Model/Race.java b/visualiser/src/main/java/seng302/Model/Race.java index c033c8a3..8ff0aaa4 100644 --- a/visualiser/src/main/java/seng302/Model/Race.java +++ b/visualiser/src/main/java/seng302/Model/Race.java @@ -5,16 +5,11 @@ import javafx.animation.AnimationTimer; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import org.geotools.referencing.GeodeticCalculator; import seng302.Controllers.RaceController; -import seng302.GPSCoordinate; import seng302.RaceDataSource; -import java.awt.geom.Point2D; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Random; /** * Parent class for races @@ -27,19 +22,17 @@ public abstract class Race implements Runnable { protected RaceController controller; protected int boatsFinished = 0; protected long totalTimeElapsed; - private int lastFPS = 20; - protected int scaleFactor; - protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race + private int lastFPS = 20; private boolean timerEnabled = true; //boolean to determine if timer is ran /** * Initailiser for Race * - * @param boats Takes in an array of boats that are participating in the race. - * @param legs Number of marks in order that the boats pass in order to complete the race. - * @param controller race controller + * @param boats Takes in an array of boats that are participating in the race. + * @param legs Number of marks in order that the boats pass in order to complete the race. + * @param controller race controller * @param scaleFactor for race */ public Race(List boats, List legs, RaceController controller, int scaleFactor) { @@ -66,6 +59,7 @@ public abstract class Race implements Runnable { /** * Checks if the boat cannot finish the race + * * @return True if boat cannot finish the race */ protected abstract boolean doNotFinish(); @@ -82,7 +76,7 @@ public abstract class Race implements Runnable { /** * Updates the boat's gps coordinates * - * @param boat to be updated + * @param boat to be updated * @param millisecondsElapsed time since last update */ protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed); @@ -111,7 +105,7 @@ public abstract class Race implements Runnable { protected void countdownTimer() { new AnimationTimer() { long currentTime = System.currentTimeMillis(); - long startTime = currentTime + (PRERACE_TIME/scaleFactor); + long startTime = currentTime + (PRERACE_TIME / scaleFactor); long minutes; long currentTimeInSeconds; long remainingSeconds; @@ -120,22 +114,22 @@ public abstract class Race implements Runnable { @Override public void handle(long arg0) { - timeLeft = startTime - currentTime; - if (timeLeft <= 0 && controller != null) { - updateTime("Race is starting..."); - stop(); - simulateRace(); - } else { - currentTimeInSeconds = (timeLeft*scaleFactor) / 1000; - minutes = currentTimeInSeconds / 60; - remainingSeconds = currentTimeInSeconds % 60; - hours = minutes / 60; - minutes = minutes % 60; - if (controller != null) { - updateTime(String.format("Race clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds)); - } + timeLeft = startTime - currentTime; + if (timeLeft <= 0 && controller != null) { + updateTime("Race is starting..."); + stop(); + simulateRace(); + } else { + currentTimeInSeconds = (timeLeft * scaleFactor) / 1000; + minutes = currentTimeInSeconds / 60; + remainingSeconds = currentTimeInSeconds % 60; + hours = minutes / 60; + minutes = minutes % 60; + if (controller != null) { + updateTime(String.format("Race clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds)); } - currentTime = System.currentTimeMillis(); + } + currentTime = System.currentTimeMillis(); } }.start(); } @@ -234,8 +228,8 @@ public abstract class Race implements Runnable { */ protected void updatePositions() { FXCollections.sort(startingBoats, (a, b) -> b.getCurrentLeg().getLegNumber() - a.getCurrentLeg().getLegNumber()); - for(BoatInRace boat: startingBoats) { - if(boat != null) { + for (BoatInRace boat : startingBoats) { + if (boat != null) { boat.setPosition(Integer.toString(startingBoats.indexOf(boat) + 1)); if (boat.getCurrentLeg().getName().equals("DNF") || boat.getCurrentLeg().getLegNumber() == 0) boat.setPosition("-"); diff --git a/visualiser/src/main/java/seng302/Model/RaceClock.java b/visualiser/src/main/java/seng302/Model/RaceClock.java index c4ce751d..7f64e50e 100644 --- a/visualiser/src/main/java/seng302/Model/RaceClock.java +++ b/visualiser/src/main/java/seng302/Model/RaceClock.java @@ -12,7 +12,6 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAmount; /** * Created by Gondr on 19/04/2017. @@ -39,6 +38,7 @@ public class RaceClock { /** * Sets time to arbitrary zoned time. + * * @param time arbitrary time with timezone. */ public void setTime(ZonedDateTime time) { diff --git a/visualiser/src/main/java/seng302/Model/TrackPoint.java b/visualiser/src/main/java/seng302/Model/TrackPoint.java index a2c30aa0..80ffd1d0 100644 --- a/visualiser/src/main/java/seng302/Model/TrackPoint.java +++ b/visualiser/src/main/java/seng302/Model/TrackPoint.java @@ -13,9 +13,10 @@ public class TrackPoint { /** * Creates a new track point with fixed GPS coordinates and time, to reach minimum opacity on expiry. + * * @param coordinate position of point on physical race map - * @param timeAdded system clock at time of addition - * @param expiry time to minimum opacity after added + * @param timeAdded system clock at time of addition + * @param expiry time to minimum opacity after added */ public TrackPoint(GPSCoordinate coordinate, long timeAdded, long expiry) { this.coordinate = coordinate; @@ -26,6 +27,7 @@ public class TrackPoint { /** * Gets the position of the point on physical race map. + * * @return GPS coordinate of point */ public GPSCoordinate getCoordinate() { @@ -34,14 +36,16 @@ public class TrackPoint { /** * Gets opacity of point scaled by age in proportion to expiry, between 1 and minimum opacity inclusive. + * * @return greater of minimum opacity and scaled opacity */ public double getAlpha() { - return Double.max(minAlpha,1.0 - (double)(System.currentTimeMillis() - timeAdded) / expiry); + return Double.max(minAlpha, 1.0 - (double) (System.currentTimeMillis() - timeAdded) / expiry); } /** * Gets time point was added to track. + * * @return system clock at time of addition */ public long getTimeAdded() { diff --git a/visualiser/src/main/java/seng302/Networking/BinaryMesageEncoder.java b/visualiser/src/main/java/seng302/Networking/BinaryMesageEncoder.java index a4f94c91..48bc599b 100644 --- a/visualiser/src/main/java/seng302/Networking/BinaryMesageEncoder.java +++ b/visualiser/src/main/java/seng302/Networking/BinaryMesageEncoder.java @@ -16,14 +16,14 @@ public class BinaryMesageEncoder { private byte[] message; //private byte[] crc; - private byte headerSync1 = (byte)0x47; - private byte headerSync2 = (byte)0x83; + private byte headerSync1 = (byte) 0x47; + private byte headerSync2 = (byte) 0x83; private byte headerMessageType; private long headerTimeStamp; private int headerSourceID; private short headerMessageLength; - public BinaryMesageEncoder(MessageType headerMessageType, long headerTimeStamp, int headerSourceID, short headerMessageLength, byte[] message){ + public BinaryMesageEncoder(MessageType headerMessageType, long headerTimeStamp, int headerSourceID, short headerMessageLength, byte[] message) { //set the header this.headerMessageType = headerMessageType.getValue(); this.headerTimeStamp = headerTimeStamp; @@ -45,7 +45,7 @@ public class BinaryMesageEncoder { this.message = message; //set full message - ByteBuffer tempMessageByteBuffer = ByteBuffer.allocate(19+this.headerMessageLength); + ByteBuffer tempMessageByteBuffer = ByteBuffer.allocate(19 + this.headerMessageLength); tempMessageByteBuffer.put(this.header); tempMessageByteBuffer.put(this.message); diff --git a/visualiser/src/main/java/seng302/Networking/BinaryMessageDecoder.java b/visualiser/src/main/java/seng302/Networking/BinaryMessageDecoder.java index d99bf0b9..f7ae7a02 100644 --- a/visualiser/src/main/java/seng302/Networking/BinaryMessageDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/BinaryMessageDecoder.java @@ -25,7 +25,7 @@ public class BinaryMessageDecoder { this.fullMessage = fullMessage; } - public void decode() throws IndexOutOfBoundsException{ + public void decode() throws IndexOutOfBoundsException { //get the header this.header = Arrays.copyOfRange(this.fullMessage, 0, 15); @@ -43,37 +43,37 @@ public class BinaryMessageDecoder { this.crc = Arrays.copyOfRange(this.fullMessage, this.fullMessage.length - 4, fullMessage.length); //run through the checks - if (this.message.length != bytesToShort(this.headerMessageLength)){ + if (this.message.length != bytesToShort(this.headerMessageLength)) { System.err.println("message length in header does not equal the message length"); System.err.println("message length in header: " + bytesToInt(this.headerMessageLength)); System.err.println("message length: " + this.message.length); - }else if(this.headerSync1 != 0x47){ + } else if (this.headerSync1 != 0x47) { System.err.println("Sync byte 1 is wrong"); - }else if(this.headerSync2 !=(byte) 0x83){ + } else if (this.headerSync2 != (byte) 0x83) { System.err.println("Sync byte 2 is wrong"); - }else if(false){ + } else if (false) { //todo check crc } } - private short bytesToShort(byte[] bytesShort){ + private short bytesToShort(byte[] bytesShort) { ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); short num = wrapped.getShort(); return num; } - private int bytesToInt(byte[] bytesInt){ + private int bytesToInt(byte[] bytesInt) { ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; } - private long bytesToLong(byte[] bytesLong){ + private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesLong[0]); byteBuffer.put(bytesLong[1]); byteBuffer.put(bytesLong[2]); @@ -96,7 +96,7 @@ public class BinaryMessageDecoder { return bytesToShort(this.headerMessageLength); } - public int getMessageType(){ + public int getMessageType() { return (int) this.headerMessageType; } diff --git a/visualiser/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java b/visualiser/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java index cb492f51..472b73f7 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageDecoders/BoatLocationDecoder.java @@ -42,66 +42,66 @@ public class BoatLocationDecoder { seqNum = Arrays.copyOfRange(encodedBoatLocation, 11, 15); deviceType = encodedBoatLocation[15]; latitude = Arrays.copyOfRange(encodedBoatLocation, 16, 20); - longitude = Arrays.copyOfRange(encodedBoatLocation,20, 24); + longitude = Arrays.copyOfRange(encodedBoatLocation, 20, 24); altitude = Arrays.copyOfRange(encodedBoatLocation, 24, 28); - heading = Arrays.copyOfRange(encodedBoatLocation,28, 30); - pitch =Arrays.copyOfRange(encodedBoatLocation,30,32); - roll = Arrays.copyOfRange(encodedBoatLocation,32,34); - boatSpeed = Arrays.copyOfRange(encodedBoatLocation,34,36); - cog = Arrays.copyOfRange(encodedBoatLocation,36,38); - sog = Arrays.copyOfRange(encodedBoatLocation,38, 40); + heading = Arrays.copyOfRange(encodedBoatLocation, 28, 30); + pitch = Arrays.copyOfRange(encodedBoatLocation, 30, 32); + roll = Arrays.copyOfRange(encodedBoatLocation, 32, 34); + boatSpeed = Arrays.copyOfRange(encodedBoatLocation, 34, 36); + cog = Arrays.copyOfRange(encodedBoatLocation, 36, 38); + sog = Arrays.copyOfRange(encodedBoatLocation, 38, 40); apparentWindSpeed = Arrays.copyOfRange(encodedBoatLocation, 40, 42); apparentWindAngle = Arrays.copyOfRange(encodedBoatLocation, 42, 44); - trueWindSpeed = Arrays.copyOfRange(encodedBoatLocation,44, 46); + trueWindSpeed = Arrays.copyOfRange(encodedBoatLocation, 44, 46); trueWindDirection = Arrays.copyOfRange(encodedBoatLocation, 46, 48); trueWindAngle = Arrays.copyOfRange(encodedBoatLocation, 48, 50); - currentDrift = Arrays.copyOfRange(encodedBoatLocation,50,52); - currentSet = Arrays.copyOfRange(encodedBoatLocation,52, 54); - rudderAngle = Arrays.copyOfRange(encodedBoatLocation,54, 56); + currentDrift = Arrays.copyOfRange(encodedBoatLocation, 50, 52); + currentSet = Arrays.copyOfRange(encodedBoatLocation, 52, 54); + rudderAngle = Arrays.copyOfRange(encodedBoatLocation, 54, 56); message = new BoatLocationMessage(messageVersionNumber, bytesToLong(time), - bytesToInt(sourceID), bytesToInt(seqNum), - deviceType, bytesToInt(latitude), - bytesToInt(longitude), bytesToInt(altitude), - twoByteToInt(heading), bytesToShort(pitch), - bytesToShort(roll), twoByteToInt(boatSpeed), - twoByteToInt(cog), twoByteToInt(sog), - twoByteToInt(apparentWindSpeed), bytesToShort(apparentWindAngle), - twoByteToInt(trueWindSpeed), bytesToShort(trueWindDirection), - bytesToShort(trueWindAngle), twoByteToInt(currentDrift), - twoByteToInt(currentSet), bytesToShort(rudderAngle) + bytesToInt(sourceID), bytesToInt(seqNum), + deviceType, bytesToInt(latitude), + bytesToInt(longitude), bytesToInt(altitude), + twoByteToInt(heading), bytesToShort(pitch), + bytesToShort(roll), twoByteToInt(boatSpeed), + twoByteToInt(cog), twoByteToInt(sog), + twoByteToInt(apparentWindSpeed), bytesToShort(apparentWindAngle), + twoByteToInt(trueWindSpeed), bytesToShort(trueWindDirection), + bytesToShort(trueWindAngle), twoByteToInt(currentDrift), + twoByteToInt(currentSet), bytesToShort(rudderAngle) ); } - private int twoByteToInt(byte[] bytesInt){ + private int twoByteToInt(byte[] bytesInt) { ByteBuffer byteBuffer = ByteBuffer.allocate(4); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesInt); int num = byteBuffer.getInt(0); return num; } - private int bytesToInt(byte[] bytesInt){ + private int bytesToInt(byte[] bytesInt) { ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; } - private short bytesToShort(byte[] bytesShort){ + private short bytesToShort(byte[] bytesShort) { ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); short num = wrapped.getShort(); return num; } - private long bytesToLong(byte[] bytesLong){ + private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesLong); // byteBuffer.put(bytesLong[0]); // byteBuffer.put(bytesLong[1]); diff --git a/visualiser/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java b/visualiser/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java index 3ef7b905..ae44859f 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageDecoders/CourseWindDecoder.java @@ -22,11 +22,11 @@ public class CourseWindDecoder { messageVersionNumber = encodedCourseWind[0]; byteWindID = encodedCourseWind[1]; loopCount = encodedCourseWind[2]; - byte[] loopMessagesBytes = Arrays.copyOfRange(encodedCourseWind, 3, lengthInBytesOfMessages*loopCount+3); + byte[] loopMessagesBytes = Arrays.copyOfRange(encodedCourseWind, 3, lengthInBytesOfMessages * loopCount + 3); int messageLoopIndex = 0; - for (int i=0; i < loopCount; i++) { - byte[] messageBytes = Arrays.copyOfRange(loopMessagesBytes, messageLoopIndex, messageLoopIndex+20); + for (int i = 0; i < loopCount; i++) { + byte[] messageBytes = Arrays.copyOfRange(loopMessagesBytes, messageLoopIndex, messageLoopIndex + 20); ArrayList test = new ArrayList(); byte[] windId = Arrays.copyOfRange(messageBytes, 0, 1); byte[] time = Arrays.copyOfRange(messageBytes, 1, 7); @@ -38,20 +38,20 @@ public class CourseWindDecoder { byte[] flags = Arrays.copyOfRange(messageBytes, 19, 20); CourseWind message = new CourseWind(windId[0], bytesToLong(time), - bytesToInt(raceID), twoByteToInt(windDirection), - twoByteToInt(windSpeed), twoByteToInt(bestUpwindAngle), - twoByteToInt(bestDownwindAngle), flags[0]); + bytesToInt(raceID), twoByteToInt(windDirection), + twoByteToInt(windSpeed), twoByteToInt(bestUpwindAngle), + twoByteToInt(bestDownwindAngle), flags[0]); loopMessages.add(message); messageLoopIndex += 20; } } - private int twoByteToInt(byte[] bytesInt){ + private int twoByteToInt(byte[] bytesInt) { ByteBuffer byteBuffer = ByteBuffer.allocate(4); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesInt); int num = byteBuffer.getInt(0); @@ -59,17 +59,17 @@ public class CourseWindDecoder { } - private int bytesToInt(byte[] bytesInt){ + private int bytesToInt(byte[] bytesInt) { ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; } - private long bytesToLong(byte[] bytesLong){ + private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesLong[0]); byteBuffer.put(bytesLong[1]); byteBuffer.put(bytesLong[2]); diff --git a/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java b/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java index 76179872..eb48f0ef 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStartStatusDecoder.java @@ -1,10 +1,7 @@ package seng302.Networking.MessageDecoders; -import seng302.Model.BoatInRace; - import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.ArrayList; import java.util.Arrays; /** @@ -40,32 +37,32 @@ public class RaceStartStatusDecoder { notification = byteToChar(notificationType); } - private char byteToChar(byte bytesInt){ + private char byteToChar(byte bytesInt) { ByteBuffer byteBuffer = ByteBuffer.allocate(4); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesInt); char num = byteBuffer.getChar(0); return num; } - private short bytesToShort(byte[] bytesShort){ + private short bytesToShort(byte[] bytesShort) { ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); short num = wrapped.getShort(); return num; } - private int bytesToInt(byte[] bytesInt){ + private int bytesToInt(byte[] bytesInt) { ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; } - private long bytesToLong(byte[] bytesLong){ + private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesLong[0]); byteBuffer.put(bytesLong[1]); byteBuffer.put(bytesLong[2]); diff --git a/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java b/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java index 5199cc44..67f07c00 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageDecoders/RaceStatusDecoder.java @@ -33,7 +33,7 @@ public class RaceStatusDecoder { private ArrayList boats = new ArrayList<>(); - public RaceStatusDecoder(byte[] encodedRaceStatus){ + public RaceStatusDecoder(byte[] encodedRaceStatus) { versionNum = encodedRaceStatus[0]; timeBytes = Arrays.copyOfRange(encodedRaceStatus, 1, 7); raceID = Arrays.copyOfRange(encodedRaceStatus, 7, 11); @@ -43,7 +43,7 @@ public class RaceStatusDecoder { windSpeed = Arrays.copyOfRange(encodedRaceStatus, 20, 22); numBoats = encodedRaceStatus[22]; bytesRaceType = encodedRaceStatus[23]; - boatsBytes = Arrays.copyOfRange(encodedRaceStatus, 24, 25+20*this.numBoats); + boatsBytes = Arrays.copyOfRange(encodedRaceStatus, 24, 25 + 20 * this.numBoats); time = bytesToLong(timeBytes); race = bytesToInt(raceID); @@ -55,8 +55,8 @@ public class RaceStatusDecoder { int boatLoopIndex = 0; - for (int i=0; i < numberOfBoats; i++) { - byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex+20); + for (int i = 0; i < numberOfBoats; i++) { + byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex + 20); byte[] sourceID = Arrays.copyOfRange(boatBytes, 1, 5); byte boatStatus = boatBytes[5]; @@ -66,7 +66,7 @@ public class RaceStatusDecoder { byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 9, 15); byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 15, 20); - BoatStatus boat = new BoatStatus(bytesToInt(sourceID),boatStatus, + BoatStatus boat = new BoatStatus(bytesToInt(sourceID), boatStatus, legNumber, numPenaltiesAwarded, numPenaltiesServed, bytesToLong(estTimeAtNextMark), bytesToLong(estTimeAtFinish)); @@ -75,24 +75,24 @@ public class RaceStatusDecoder { } } - private int byteToInt(byte bytesInt){ + private int byteToInt(byte bytesInt) { ByteBuffer byteBuffer = ByteBuffer.allocate(4); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesInt); int intVal = byteBuffer.getInt(0); return intVal; } - private short bytesToShort(byte[] bytesShort){ + private short bytesToShort(byte[] bytesShort) { ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); short num = wrapped.getShort(); return num; } - private int bytesToInt(byte[] bytesInt){ + private int bytesToInt(byte[] bytesInt) { ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; diff --git a/visualiser/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java b/visualiser/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java index a361ca50..7a4bdcaa 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageDecoders/XMLMessageDecoder.java @@ -22,7 +22,7 @@ public class XMLMessageDecoder { this.bytes = bytes; } - public void decode(){ + public void decode() { byte[] ackNumberBytes = Arrays.copyOfRange(bytes, 1, 3); byte[] timeStampBytes = Arrays.copyOfRange(bytes, 3, 9); byte[] sequenceNumberBytes = Arrays.copyOfRange(bytes, 10, 12); @@ -40,7 +40,7 @@ public class XMLMessageDecoder { this.xmlMessage = new String(xmlMessagebytes); } - private short bytesToShort(byte[] bytesShort){ + private short bytesToShort(byte[] bytesShort) { ByteBuffer byteBuffer = ByteBuffer.allocate(2); byteBuffer.order(ByteOrder.LITTLE_ENDIAN); byteBuffer.put(bytesShort[0]); @@ -49,11 +49,11 @@ public class XMLMessageDecoder { return shortVal; } - private long bytesToLong(byte[] bytesLong){ + private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); - byteBuffer.put((byte)0); - byteBuffer.put((byte)0); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); byteBuffer.put(bytesLong[0]); byteBuffer.put(bytesLong[1]); byteBuffer.put(bytesLong[2]); diff --git a/visualiser/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java b/visualiser/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java index 9afeb4e0..88b8f10a 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageEncoders/RaceVisionByteEncoder.java @@ -15,15 +15,15 @@ import java.util.Arrays; */ public class RaceVisionByteEncoder { - public byte[] heartBeat(int seq){ + public byte[] heartBeat(int seq) { ByteBuffer heartBeat = ByteBuffer.allocate(4); heartBeat.putInt(seq); - byte [] result = heartBeat.array(); + byte[] result = heartBeat.array(); return result; } - public byte[] raceStatus(long time, int race, int raceState, long startTime, short raceWindDir, short raceWindSpeed, int raceType, ArrayList boats){ - ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20*boats.size()); + public byte[] raceStatus(long time, int race, int raceState, long startTime, short raceWindDir, short raceWindSpeed, int raceType, ArrayList boats) { + ByteBuffer raceStatusMessage = ByteBuffer.allocate(24 + 20 * boats.size()); //Version Number 1 bytes byte versionNum = 0b10; //this changes with the pdf. (2) byte[] timeBytes = convert(time, 6);//time (6 bytes) @@ -45,12 +45,12 @@ public class RaceVisionByteEncoder { raceStatusMessage.put(numBoats); raceStatusMessage.put(bytesRaceType); - for (int i = 0; i < boats.size(); i++){ + for (int i = 0; i < boats.size(); i++) { int sourceID = 0; //TODO use boats source id. byte[] legNum = convert(boats.get(i).getCurrentLeg().getLegNumber(), 1); byte[] numPenalties = convert(0, 1); //TODO use boats in race penalties class byte[] numPenaltiesServed = convert(0, 1);//TODO use boats in race penalites served. - byte[] estNextMarkTime = convert((long)0, 6);//TODO use boats estimated time to next mark. + byte[] estNextMarkTime = convert((long) 0, 6);//TODO use boats estimated time to next mark. byte[] estFinishTime = convert((long) 0, 6);//TODO use boats estimated time to the finish. raceStatusMessage.putInt(sourceID); @@ -64,7 +64,7 @@ public class RaceVisionByteEncoder { return raceStatusMessage.array(); } - public byte[] displayTextMessage(RaceMessage[] message){ + public byte[] displayTextMessage(RaceMessage[] message) { //ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32); int messageVersionNumber = 0b1;//version number short ackNum = 0;//no clue what this does just a placeholder for 2 bytes. @@ -77,16 +77,16 @@ public class RaceVisionByteEncoder { ArrayList messages = new ArrayList(); int size = 4; - for (int i = 0; i < message.length; i ++){ + for (int i = 0; i < message.length; i++) { int messageLen = message[i].getMessageText().getBytes().length; byte[] messageAsBytes = message[i].getMessageText().getBytes(); - if (messageLen < 30){ + if (messageLen < 30) { messageLen = 30; } ByteBuffer mess = ByteBuffer.allocate(2 + messageLen); mess.put(convert(message[i].getLineNumber(), 1)); mess.put(convert(messageLen, 1)); - for (int j = 0; j < messageLen; j ++){ + for (int j = 0; j < messageLen; j++) { mess.put(messageAsBytes[j]); } messages.add(mess.array()); @@ -98,14 +98,14 @@ public class RaceVisionByteEncoder { result.putShort(ackNum); result.put(messLines); - for(byte[] mess: messages){ + for (byte[] mess : messages) { result.put(mess); } return result.array(); } - public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){ + public byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification) { int messageVersion = 0b1; byte[] timestamp = convert(time, 6); byte[] ackNumber = convert(ack, 2); @@ -125,7 +125,7 @@ public class RaceVisionByteEncoder { } public byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID, - int eventID){ + int eventID) { int messageVersion = 0b10; byte[] encodeTime = convert(time, 6); short ackNum = acknowledgeNumber; @@ -145,7 +145,7 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] chatterText(int messageType, String message){ + public byte[] chatterText(int messageType, String message) { int messageVersion = 0b1; byte[] type = convert(messageType, 1); byte[] length = convert(message.length(), 1); @@ -160,7 +160,7 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] boatLocation(BoatLocationMessage boatLocationMessage){ + public byte[] boatLocation(BoatLocationMessage boatLocationMessage) { int messageVersionNumber = 0b1; byte[] time = convert(boatLocationMessage.getTime(), 6); byte[] sourceID = convert(boatLocationMessage.getSourceID(), 4); @@ -210,7 +210,7 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ + public byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID) { int messageVersionNumber = 0b1; byte[] byteTime = convert(time, 6); byte[] byteAck = convert(ackNumber, 2); @@ -234,7 +234,7 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] courseWind(byte windID, ArrayList courseWinds){ + public byte[] courseWind(byte windID, ArrayList courseWinds) { int messageVersionNumber = 0b1; byte byteWindID = windID; byte[] loopcount = convert(courseWinds.size(), 1); @@ -242,7 +242,7 @@ public class RaceVisionByteEncoder { result.put(convert(messageVersionNumber, 1)); result.put(byteWindID); result.put(loopcount); - for (CourseWind wind: courseWinds){ + for (CourseWind wind : courseWinds) { result.put(convert(wind.getID(), 1)); result.put(convert(wind.getTime(), 6)); result.put(convert(wind.getRaceID(), 4)); @@ -255,9 +255,9 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ + public byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4) { int messageVersionNumber = 0b1; - byte[] byteTime = convert(time,6); + byte[] byteTime = convert(time, 6); byte[] byteRawPeriod = convert(rawPeriod, 2); byte[] byteRawSpeed = convert(rawSampleSpeed, 2); byte[] bytePeriod2 = convert(period2, 2); @@ -281,13 +281,13 @@ public class RaceVisionByteEncoder { return result.array(); } - public byte[] convert(String s, int size){ + public byte[] convert(String s, int size) { byte[] m = s.getBytes(Charset.forName("UTF-8")); int length = m.length; byte[] result; - if (length > 255){ + if (length > 255) { length = 255; - } else if (size < 1){ + } else if (size < 1) { result = new byte[0]; return result; } @@ -295,12 +295,12 @@ public class RaceVisionByteEncoder { return result; } - public byte[] convert(int n, int size){ + public byte[] convert(int n, int size) { byte[] result; - if (size > 4){ + if (size > 4) { result = new byte[4]; return result; - } else if (size < 1){ + } else if (size < 1) { result = new byte[0]; return result; } @@ -311,12 +311,12 @@ public class RaceVisionByteEncoder { return result; } - public byte[] convert(long n, int size){ + public byte[] convert(long n, int size) { byte[] result; - if (size > 8){ + if (size > 8) { result = new byte[8]; return result; - } else if (size < 1){ + } else if (size < 1) { result = new byte[0]; return result; } @@ -328,12 +328,12 @@ public class RaceVisionByteEncoder { } - public byte[] convert(short n, int size){ + public byte[] convert(short n, int size) { byte[] result; - if (size > 2){ + if (size > 2) { result = new byte[2]; return result; - } else if (size < 1){ + } else if (size < 1) { result = new byte[0]; return result; } diff --git a/visualiser/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java b/visualiser/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java index 570f9a2c..e28823b0 100644 --- a/visualiser/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java +++ b/visualiser/src/main/java/seng302/Networking/MessageEncoders/XMLMessageEncoder.java @@ -1,7 +1,6 @@ package seng302.Networking.MessageEncoders; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.util.Arrays; /** diff --git a/visualiser/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java b/visualiser/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java index 0fd59c79..e43d30c8 100644 --- a/visualiser/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java +++ b/visualiser/src/main/java/seng302/Networking/Utils/BoatLocationMessage.java @@ -7,8 +7,7 @@ package seng302.Networking.Utils; /** * Represents the information in a boat location message (AC streaming spec: 4.9). */ -public class BoatLocationMessage -{ +public class BoatLocationMessage { ///Version number of the message - is always 1. private byte messageVersionNumber = 1; @@ -78,12 +77,12 @@ public class BoatLocationMessage /** * Ctor. */ - public BoatLocationMessage() - { + public BoatLocationMessage() { } /** * Ctor, with all parameters. + * * @param messageVersionNumber * @param time * @param sourceID @@ -107,8 +106,7 @@ public class BoatLocationMessage * @param currentSet * @param rudderAngle */ - public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, int sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) - { + public BoatLocationMessage(byte messageVersionNumber, long time, int sourceID, int sequenceNumber, byte deviceType, int latitude, int longitude, int altitude, int heading, short pitch, short roll, int boatSpeed, int boatCOG, int boatSOG, int apparentWindSpeed, short apparentWindAngle, int trueWindSpeed, short trueWindDirection, short trueWindAngle, int currentDrift, int currentSet, short rudderAngle) { this.messageVersionNumber = messageVersionNumber; this.time = time; this.sourceID = sourceID; @@ -136,174 +134,140 @@ public class BoatLocationMessage //Getters and setters for message properties. - - public byte getMessageVersionNumber() - { + + public byte getMessageVersionNumber() { return messageVersionNumber; } - public void setMessageVersionNumber(byte messageVersionNumber) - { + public void setMessageVersionNumber(byte messageVersionNumber) { this.messageVersionNumber = messageVersionNumber; } - public long getTime() - { + public long getTime() { return time; } - public void setTime(long time) - { + public void setTime(long time) { this.time = time; } - public int getSourceID() - { + public int getSourceID() { return sourceID; } - public void setSourceID(int sourceID) - { + public void setSourceID(int sourceID) { this.sourceID = sourceID; } - public int getSequenceNumber() - { + public int getSequenceNumber() { return sequenceNumber; } - public void setSequenceNumber(int sequenceNumber) - { + public void setSequenceNumber(int sequenceNumber) { this.sequenceNumber = sequenceNumber; } - public byte getDeviceType() - { + public byte getDeviceType() { return deviceType; } - public void setDeviceType(byte deviceType) - { + public void setDeviceType(byte deviceType) { this.deviceType = deviceType; } - public int getLatitude() - { + public int getLatitude() { return latitude; } - public void setLatitude(int latitude) - { + public void setLatitude(int latitude) { this.latitude = latitude; } - public int getLongitude() - { + public int getLongitude() { return longitude; } - public void setLongitude(int longitude) - { + public void setLongitude(int longitude) { this.longitude = longitude; } - public int getAltitude() - { + public int getAltitude() { return altitude; } - public void setAltitude(int altitude) - { + public void setAltitude(int altitude) { this.altitude = altitude; } - public int getHeading() - { + public int getHeading() { return heading; } - public void setHeading(int heading) - { + public void setHeading(int heading) { this.heading = heading; } - public short getPitch() - { + public short getPitch() { return pitch; } - public void setPitch(short pitch) - { + public void setPitch(short pitch) { this.pitch = pitch; } - public short getRoll() - { + public short getRoll() { return roll; } - public void setRoll(short roll) - { + public void setRoll(short roll) { this.roll = roll; } - public int getBoatSpeed() - { + public int getBoatSpeed() { return boatSpeed; } - public void setBoatSpeed(int boatSpeed) - { + public void setBoatSpeed(int boatSpeed) { this.boatSpeed = boatSpeed; } - public int getBoatCOG() - { + public int getBoatCOG() { return boatCOG; } - public void setBoatCOG(int boatCOG) - { + public void setBoatCOG(int boatCOG) { this.boatCOG = boatCOG; } - public int getBoatSOG() - { + public int getBoatSOG() { return boatSOG; } - public void setBoatSOG(int boatSOG) - { + public void setBoatSOG(int boatSOG) { this.boatSOG = boatSOG; } - public int getApparentWindSpeed() - { + public int getApparentWindSpeed() { return apparentWindSpeed; } - public void setApparentWindSpeed(int apparentWindSpeed) - { + public void setApparentWindSpeed(int apparentWindSpeed) { this.apparentWindSpeed = apparentWindSpeed; } - public short getApparentWindAngle() - { + public short getApparentWindAngle() { return apparentWindAngle; } - public void setApparentWindAngle(short apparentWindAngle) - { + public void setApparentWindAngle(short apparentWindAngle) { this.apparentWindAngle = apparentWindAngle; } - public int getTrueWindSpeed() - { + public int getTrueWindSpeed() { return trueWindSpeed; } - public void setTrueWindSpeed(int trueWindSpeed) - { + public void setTrueWindSpeed(int trueWindSpeed) { this.trueWindSpeed = trueWindSpeed; } @@ -315,43 +279,35 @@ public class BoatLocationMessage this.trueWindDirection = trueWindDirection; } - public short getTrueWindAngle() - { + public short getTrueWindAngle() { return trueWindAngle; } - public void setTrueWindAngle(short trueWindAngle) - { + public void setTrueWindAngle(short trueWindAngle) { this.trueWindAngle = trueWindAngle; } - public int getCurrentDrift() - { + public int getCurrentDrift() { return currentDrift; } - public void setCurrentDrift(int currentDrift) - { + public void setCurrentDrift(int currentDrift) { this.currentDrift = currentDrift; } - public int getCurrentSet() - { + public int getCurrentSet() { return currentSet; } - public void setCurrentSet(int currentSet) - { + public void setCurrentSet(int currentSet) { this.currentSet = currentSet; } - public short getRudderAngle() - { + public short getRudderAngle() { return rudderAngle; } - public void setRudderAngle(short rudderAngle) - { + public void setRudderAngle(short rudderAngle) { this.rudderAngle = rudderAngle; } } diff --git a/visualiser/src/main/java/seng302/Networking/Utils/CourseWind.java b/visualiser/src/main/java/seng302/Networking/Utils/CourseWind.java index 142c7c11..98a31ca5 100644 --- a/visualiser/src/main/java/seng302/Networking/Utils/CourseWind.java +++ b/visualiser/src/main/java/seng302/Networking/Utils/CourseWind.java @@ -9,7 +9,7 @@ public class CourseWind { private long time; public CourseWind(int ID, long time, int raceID, int windDirection, int windSpeed, int bestUpwindAngle, int bestDownwindAngle, - int flags){ + int flags) { this.ID = ID; this.time = time; this.raceID = raceID; diff --git a/visualiser/src/main/java/seng302/Networking/Utils/MessageType.java b/visualiser/src/main/java/seng302/Networking/Utils/MessageType.java index fcdff527..b4ec8d10 100644 --- a/visualiser/src/main/java/seng302/Networking/Utils/MessageType.java +++ b/visualiser/src/main/java/seng302/Networking/Utils/MessageType.java @@ -10,7 +10,9 @@ public enum MessageType { private byte value; - private MessageType(int value) { this.value = (byte)value; } + private MessageType(int value) { + this.value = (byte) value; + } public byte getValue() { return value; diff --git a/visualiser/src/main/java/seng302/Networking/Utils/RaceMessage.java b/visualiser/src/main/java/seng302/Networking/Utils/RaceMessage.java index 1a705574..b9b1e2de 100644 --- a/visualiser/src/main/java/seng302/Networking/Utils/RaceMessage.java +++ b/visualiser/src/main/java/seng302/Networking/Utils/RaceMessage.java @@ -8,7 +8,7 @@ public class RaceMessage { private int lineNumber; private String messageText; - public RaceMessage(int lineNumber, String messageText){ + public RaceMessage(int lineNumber, String messageText) { this.lineNumber = lineNumber; this.messageText = messageText; } diff --git a/visualiser/src/main/java/seng302/RaceXMLReader.java b/visualiser/src/main/java/seng302/RaceXMLReader.java index a3b0dfeb..2f0df23e 100644 --- a/visualiser/src/main/java/seng302/RaceXMLReader.java +++ b/visualiser/src/main/java/seng302/RaceXMLReader.java @@ -4,7 +4,10 @@ import javafx.scene.paint.Color; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import seng302.Model.*; +import seng302.Model.BoatInRace; +import seng302.Model.Leg; +import seng302.Model.Marker; +import seng302.Model.RaceClock; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; @@ -17,19 +20,20 @@ import java.util.List; * @deprecated use {@link seng302.Mock.StreamedCourseXMLReader} */ public class RaceXMLReader extends XMLReader implements RaceDataSource { + private static double COORDINATEPADDING = 0.0005; private List 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 List legs = new ArrayList<>(); private GPSCoordinate mark, startPt1, startPt2, finishPt1, finishPt2, leewardPt1, leewardPt2, windwardPt1, windwardPt2; private GPSCoordinate mapTopLeft, mapBottomRight; private List boundary = new ArrayList<>(); - private static double COORDINATEPADDING = 0.0005; /** * Constractor for Race XML + * * @param filePath path of the file - * @throws IOException error - * @throws SAXException error + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { @@ -38,10 +42,11 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * COnstructor for Race XML + * * @param filePath file path to read - * @param read whether or not to read and store the files straight away. - * @throws IOException error - * @throws SAXException error + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error * @throws ParserConfigurationException error */ public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { @@ -62,7 +67,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * Read all the boats in the XML file - */ + */ public void readBoats() { //get all boats NodeList nBoats = doc.getElementsByTagName("boat"); @@ -169,6 +174,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file + * * @param start base nodelist this should be the tag that contains * @return */ @@ -178,7 +184,8 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex index in the node that has the coordinate tag * @return */ @@ -188,9 +195,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a marker from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex index in the node that has the coordinate tag - * @param nodeIndex coordinate index + * @param nodeIndex coordinate index * @return */ private Marker getMarker(NodeList start, int startIndex, int nodeIndex) { @@ -201,6 +209,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a changes a marker to GPS coordinates into a marker + * * @param markerNode marker to turn into coordinates * @return */ @@ -221,6 +230,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { /** * gets a coordinates from the XML file + * * @param start base nodelist this should be the tag that contains * @return */ @@ -228,9 +238,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return getCoordinates(start, 0); } - /** + /** * gets a coordinates from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex the index the tag containing the coordinate should be in * @return */ @@ -238,11 +249,12 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return getCoordinates(start, startIndex, 0); } - /** + /** * gets a coordinates from the XML file - * @param start base nodelist this should be the tag that contains + * + * @param start base nodelist this should be the tag that contains * @param startIndex the index the tag containing the coordinate should be in - * @param nodeIndex The coordinate index + * @param nodeIndex The coordinate index * @return */ private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex) { diff --git a/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml b/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml index 738502a5..51f788b0 100644 --- a/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml +++ b/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml @@ -8,13 +8,13 @@ - + - + - + - + @@ -24,13 +24,13 @@ - + - + - + - + @@ -40,13 +40,13 @@ - + - + - + - + @@ -56,13 +56,13 @@ - + - + - + - + @@ -72,13 +72,13 @@ - + - + - + - + @@ -88,83 +88,83 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -174,9 +174,9 @@ BoatName="Regardless"> - + - + @@ -184,9 +184,9 @@ BoatName="Constellation"> - + - + @@ -194,17 +194,17 @@ BoatName="Mischief"> - + - + - + - + @@ -212,9 +212,9 @@ BoatName="Volunteer"> - + - + @@ -222,17 +222,17 @@ BoatName="Defender"> - + - + - + - + @@ -240,9 +240,9 @@ BoatName="TEAM KOREA" Country="KOR"> - + - + diff --git a/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml b/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml index 64f644dd..05cb2201 100644 --- a/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml +++ b/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml @@ -6,15 +6,15 @@ Match - 2011-08-06T13:25:00-0000 + 2011-08-06T13:25:00-0000 - + - + - + @@ -22,29 +22,29 @@ - + - + - + - + - + - + @@ -52,13 +52,13 @@ - + - + - + - + diff --git a/visualiser/src/main/resources/raceXML/Boats.xml b/visualiser/src/main/resources/raceXML/Boats.xml index ed4b6ded..b94f09fb 100644 --- a/visualiser/src/main/resources/raceXML/Boats.xml +++ b/visualiser/src/main/resources/raceXML/Boats.xml @@ -4,116 +4,116 @@ 2017-04-19T15:49:40+1200 1 - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - + > - - + + - - + + - - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/visualiser/src/main/resources/raceXML/Race.xml b/visualiser/src/main/resources/raceXML/Race.xml index 29478c60..88a1be01 100644 --- a/visualiser/src/main/resources/raceXML/Race.xml +++ b/visualiser/src/main/resources/raceXML/Race.xml @@ -2,43 +2,43 @@ 17041901 Fleet - 2017-04-19T15:30:00+1200 - + 2017-04-19T15:30:00+1200 + - - - - - - + + + + + + - - + + - + - - + + - - + + - - + + - - - - - + + + + + diff --git a/visualiser/src/main/resources/scenes/main.fxml b/visualiser/src/main/resources/scenes/main.fxml index d94c8b59..e343082e 100644 --- a/visualiser/src/main/resources/scenes/main.fxml +++ b/visualiser/src/main/resources/scenes/main.fxml @@ -1,14 +1,9 @@ - - - - - - - - + + diff --git a/visualiser/src/main/resources/scenes/race.fxml b/visualiser/src/main/resources/scenes/race.fxml index 56aed929..7ab63046 100644 --- a/visualiser/src/main/resources/scenes/race.fxml +++ b/visualiser/src/main/resources/scenes/race.fxml @@ -1,20 +1,19 @@ - - - - - + + - + - + @@ -25,13 +24,28 @@ - - - - - - -