Added XMLMessageEncoder.

Refactored XMLMessageDecoder to be consistent with other decoders - only needs to expose the XMLMessage.
Refactored BoatLocationDecoder to be consistent with other decoders - only needs to expose the BoatLocation.
Updated XMLMessageDecoderTest to use new encoder/decoder. Also tests all three message types.
Removed XMLMessageEncoderTest as it was redundant.
Updated BinaryMessageDecoderTest.xmlMessageTest() to use updated XMLMessage encoder/decoder.
issue #35 #36
#story[1095]
This commit is contained in:
fjc40
2017-08-06 01:01:05 +12:00
parent 8ef906472b
commit b486f99dbe
13 changed files with 535 additions and 317 deletions
@@ -2,6 +2,7 @@ package network;
import network.Exceptions.InvalidMessageException;
import network.MessageDecoders.XMLMessageDecoder;
import network.MessageDecoders.XMLMessageDecoderTest;
import network.MessageEncoders.RaceVisionByteEncoder;
import network.Messages.AC35Data;
import network.Messages.Enums.MessageType;
@@ -21,29 +22,46 @@ import java.nio.charset.StandardCharsets;
import static org.junit.Assert.fail;
/**
* Created by hba56 on 21/04/17.
* Tests the binary message decoder and encoder for a variety of messages.
*/
public class BinaryMessageDecoderTest {
/**
* Tests if an XMLMessage can be encoded and decoded correctly.
*/
@Test
public void decodeTest(){
try{
String xmlString = XMLReader.readXMLFileToString("network/raceXML/Regatta.xml", StandardCharsets.UTF_8);
public void xmlMessageTest() throws Exception {
try {
String filePath = "network/raceXML/Regatta.xml";
XMLMessageType messageType = XMLMessageType.REGATTA;
String xmlString = XMLReader.readXMLFileToString(filePath, StandardCharsets.UTF_8);
long time = System.currentTimeMillis();
XMLMessage xmlMessagePre = new XMLMessage(
XMLMessage xmlMessage = new XMLMessage(
(byte)1,
1,
time,
XMLMessageType.REGATTA,
messageType,
(short)1,
xmlString );
xmlString );
byte[] encodedMessage = RaceVisionByteEncoder.xmlMessage(xmlMessagePre);
byte[] encodedMessage = RaceVisionByteEncoder.encode(xmlMessage);
BinaryMessageEncoder testMessage = new BinaryMessageEncoder(MessageType.XMLMESSAGE, time, 1, (short)encodedMessage.length, encodedMessage);
BinaryMessageDecoder decoder = new BinaryMessageDecoder(testMessage.getFullMessage());
BinaryMessageEncoder encoder = new BinaryMessageEncoder(
xmlMessage.getType(),
time,
1,
(short)encodedMessage.length,
encodedMessage );
BinaryMessageDecoder decoder = new BinaryMessageDecoder(encoder.getFullMessage());
AC35Data message = null;
try {
@@ -56,7 +74,7 @@ public class BinaryMessageDecoderTest {
if (!(message instanceof XMLMessage)){
Assert.assertFalse(true);
}
XMLMessage xmlMessage = (XMLMessage) message;
XMLMessage xmlMessageDecoded = (XMLMessage) message;
//message length
@@ -66,29 +84,17 @@ public class BinaryMessageDecoderTest {
//source ID
Assert.assertEquals((short) 1, decoder.getHeaderSourceID());
//message type
Assert.assertEquals(26, decoder.getHeaderMessageType());
Assert.assertEquals(MessageType.XMLMESSAGE.getValue(), decoder.getHeaderMessageType());
XMLMessageDecoder decoderXML = new XMLMessageDecoder(decoder.getMessageBody());
decoderXML.decode();
//tests from seng302.Networking.MessageDecoders.XMLMessageDecoderTest to make sure the file is still good
Assert.assertEquals((byte)1, decoderXML.getMessageVersionNumber());
Assert.assertEquals((short)1, decoderXML.getAckNumber());
Assert.assertEquals(time, decoderXML.getTimeStamp());
Assert.assertEquals(XMLMessageType.REGATTA, decoderXML.getXmlMsgSubType());
Assert.assertEquals((short)1, decoderXML.getSequenceNumber());
Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength());
XMLMessageDecoderTest.compareXMLMessages(xmlMessage, xmlMessageDecoded);
// Reader reader = decoderXML.getXmlMessageInputStream().getCharacterStream();
// int c;
// String contents = "";
// while((c = reader.read()) != -1) {
// contents += (char)c;
// }
// Assert.assertEquals(xmlString.toString(), contents);
} catch (XMLReaderException | TransformerException e){
fail("couldn't read file" + e.getMessage());
}
}
//TODO add some tests for more messages types.
}
@@ -16,7 +16,7 @@ public class BoatLocationDecoderTest {
* Creates a BoatLocation message, encodes it, decodes it, and checks that the result matches the starting message.
*/
@Test
public void getByteArrayTest() throws Exception {
public void boatLocationEncodeDecodeTest() throws Exception {
//Create message.
long time = System.currentTimeMillis();
@@ -1,5 +1,6 @@
package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.MessageEncoders.RaceVisionByteEncoder;
import network.Messages.Enums.XMLMessageType;
import network.Messages.XMLMessage;
@@ -14,13 +15,21 @@ import java.nio.charset.StandardCharsets;
import static org.junit.Assert.fail;
/**
* Created by hba56 on 20/04/17.
* Test for the XMLMessage encoder and decoder
*/
public class XMLMessageDecoderTest {
@Test
public void getByteArrayTest(){
try{
String xmlString = XMLReader.readXMLFileToString("network/raceXML/Regatta.xml", StandardCharsets.UTF_8);
/**
* Creates an XML message of the given type, using the specified filePath, encodes it, decodes it, and checks that the result matches the starting message.
* @param filePath The file path for xml file.
* @param type The type of xml file.
* @throws InvalidMessageException Thrown if message cannot be encoded.
*/
private void xmlMessageTest(String filePath, XMLMessageType type) throws InvalidMessageException {
try {
String xmlString = XMLReader.readXMLFileToString(filePath, StandardCharsets.UTF_8);
long time = System.currentTimeMillis();
@@ -28,27 +37,67 @@ public class XMLMessageDecoderTest {
(byte)1,
1,
time,
XMLMessageType.REGATTA,
type,
(short)1,
xmlString );
byte[] encodedXML = RaceVisionByteEncoder.xmlMessage(message);
byte[] encodedXML = RaceVisionByteEncoder.encode(message);
XMLMessageDecoder decoderXML = new XMLMessageDecoder(encodedXML);
decoderXML.decode();
XMLMessage decodedMessage = decoderXML.getMessage();
Assert.assertEquals((byte)1, decoderXML.getMessageVersionNumber());
Assert.assertEquals((short)1, decoderXML.getAckNumber());
Assert.assertEquals(time, decoderXML.getTimeStamp());
Assert.assertEquals(XMLMessageType.REGATTA, decoderXML.getXmlMsgSubType());
Assert.assertEquals((short)1, decoderXML.getSequenceNumber());
Assert.assertEquals((short)xmlString.length(), decoderXML.getXmlMsgLength());
compareXMLMessages(message, decodedMessage);
} catch (XMLReaderException | TransformerException e){
fail("couldn't read file" + e.getMessage());
}
}
/**
* Compares two XML messages to check that they are the same.
* @param originalMessage The first message to test.
* @param decodedMessage The second message to test.
*/
public static void compareXMLMessages(XMLMessage originalMessage, XMLMessage decodedMessage) {
Assert.assertEquals(originalMessage.getVersionNumber(), decodedMessage.getVersionNumber());
Assert.assertEquals(originalMessage.getAckNumber(), decodedMessage.getAckNumber());
Assert.assertEquals(originalMessage.getTimeStamp(), decodedMessage.getTimeStamp());
Assert.assertEquals(originalMessage.getXmlMsgSubType(), decodedMessage.getXmlMsgSubType());
Assert.assertEquals(originalMessage.getSequenceNumber(), decodedMessage.getSequenceNumber());
Assert.assertEquals(originalMessage.getXmlMsgLength(), decodedMessage.getXmlMsgLength());
Assert.assertEquals(originalMessage.getXmlMessage(), decodedMessage.getXmlMessage());
}
/**
* Tests if a regatta.xml message can be encoded and decoded.
*/
@Test
public void regattaXMLMessageTest() throws Exception {
xmlMessageTest("network/raceXML/Regatta.xml", XMLMessageType.REGATTA);
}
/**
* Tests if a race.xml message can be encoded and decoded.
*/
@Test
public void raceXMLMessageTest() throws Exception {
xmlMessageTest("network/raceXML/Race.xml", XMLMessageType.RACE);
}
/**
* Tests if a boat.xml message can be encoded and decoded.
*/
@Test
public void boatXMLMessageTest() throws Exception {
xmlMessageTest("network/raceXML/Boats.xml", XMLMessageType.BOAT);
}
}
@@ -1,50 +0,0 @@
package network;
import network.MessageEncoders.RaceVisionByteEncoder;
import network.Messages.Enums.XMLMessageType;
import network.Messages.XMLMessage;
import org.junit.Assert;
import org.junit.Test;
import shared.dataInput.XMLReader;
import shared.exceptions.XMLReaderException;
import javax.xml.transform.TransformerException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import static org.junit.Assert.fail;
/**
* Created by hba56 on 19/04/17.
*/
public class XMLMessageEncoderTest {
@Test
public void getByteArrayTest() {
try {
String xmlString = XMLReader.readXMLFileToString("network/raceXML/Regatta.xml", StandardCharsets.UTF_8);
XMLMessage message = new XMLMessage(
(byte)1,
1,
System.currentTimeMillis(),
XMLMessageType.REGATTA,
(short)1,
xmlString );
int xmlMessageLength = xmlString.getBytes().length;
byte[] encodedXML = RaceVisionByteEncoder.xmlMessage(message);
//1 + 2 + 6 + 1 + 2 + 2 + xml.byteLength
Assert.assertEquals(14 + xmlMessageLength, encodedXML.length);
} catch (XMLReaderException | TransformerException e){
fail("couldn't read file" + e.getMessage());
}
}
}
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<BoatConfig>
<Modified>2017-04-19T15:49:40+1200</Modified>
<Version>1</Version>
<Settings>
<RaceBoatType Type="AC45" />
<BoatDimension BoatLength="14.019" HullLength="13.449" />
<ZoneSize MarkZoneSize="40.347" CourseZoneSize="40.347" />
<ZoneLimits Limit1="200" Limit2="100" Limit3="40.347" Limit4="0" Limit5="-100" />
</Settings>
<BoatShapes>
<BoatShape ShapeID="0">
<Vertices>
<Vtx Seq="1" Y="0" X="-2.659" />
<Vtx Seq="2" Y="18.359" X="-2.659" />
<Vtx Seq="3" Y="18.359" X="2.659" />
<Vtx Seq="4" Y="0" X="2.659" />
</Vertices>
</BoatShape>
<BoatShape ShapeID="1">
<Vertices>
<Vtx Seq="1" Y="0" X="-1.278" />
<Vtx Seq="2" Y="8.876" X="-1.278" />
<Vtx Seq="3" Y="8.876" X="1.278" />
<Vtx Seq="4" Y="0" X="1.278" />
</Vertices>
</BoatShape>
<BoatShape ShapeID="2">
<Vertices>
<Vtx Seq="1" Y="0" X="-1.1" />
<Vtx Seq="2" Y="8.3" X="-1.1" />
<Vtx Seq="3" Y="8.3" X="1.1" />
<Vtx Seq="4" Y="0" X="1.1" />
</Vertices>
</BoatShape>
<BoatShape ShapeID="3">
<Vertices>
<Vtx Seq="1" Y="0" X="-0.75" />
<Vtx Seq="2" Y="3" X="-0.75" />
<Vtx Seq="3" Y="3" X="0.75" />
<Vtx Seq="4" Y="0" X="0.75" />
</Vertices>
</BoatShape>
<BoatShape ShapeID="4">
<Vertices>
<Vtx Seq="1" Y="0" X="-3.46" />
<Vtx Seq="2" Y="13.449" X="-3.46" />
<Vtx Seq="3" Y="14.019" X="0" />
<Vtx Seq="4" Y="13.449" X="3.46" />
<Vtx Seq="5" Y="0" X="3.46" />
</Vertices>
<Catamaran>
<Vtx Seq="1" Y="1.769" X="-2.752" />
<Vtx Seq="2" Y="0" X="-2.813" />
<Vtx Seq="3" Y="0" X="-3.34" />
<Vtx Seq="4" Y="5.351" X="-3.46" />
<Vtx Seq="5" Y="10.544" X="-3.387" />
<Vtx Seq="6" Y="13.449" X="-3.075" />
<Vtx Seq="7" Y="10.851" X="-2.793" />
<Vtx Seq="8" Y="6.669" X="-2.699" />
<Vtx Seq="9" Y="6.669" X="2.699" />
<Vtx Seq="10" Y="10.851" X="2.793" />
<Vtx Seq="11" Y="13.449" X="3.075" />
<Vtx Seq="12" Y="10.544" X="3.387" />
<Vtx Seq="13" Y="5.351" X="3.46" />
<Vtx Seq="14" Y="0" X="3.34" />
<Vtx Seq="15" Y="0" X="2.813" />
<Vtx Seq="16" Y="1.769" X="2.752" />
</Catamaran>
<Bowsprit>
<Vtx Seq="1" Y="6.669" X="-0.2" />
<Vtx Seq="2" Y="11.377" X="-0.2" />
<Vtx Seq="3" Y="14.019" X="0" />
<Vtx Seq="4" Y="11.377" X="0.2" />
<Vtx Seq="5" Y="6.669" X="0.2" />
</Bowsprit>
<Trampoline>
<Vtx Seq="1" Y="2" X="-2.699" />
<Vtx Seq="2" Y="6.438" X="-2.699" />
<Vtx Seq="3" Y="6.438" X="2.699" />
<Vtx Seq="4" Y="2" X="2.699" />
</Trampoline>
</BoatShape>
<BoatShape ShapeID="5" />
</BoatShapes>
<Boats>>
<Boat Type="Yacht" SourceID="101" ShapeID="4" HullNum="AC4501" ShortName="USA"
BoatName="ORACLE TEAM USA" Country="USA">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
<Boat Type="Yacht" SourceID="102" ShapeID="4" HullNum="AC4502" ShortName="GBR"
BoatName="Land Rover BAR" Country="United Kingdom">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
<Boat Type="Yacht" SourceID="103" ShapeID="4" HullNum="AC4503" ShortName="JPN"
BoatName="SoftBank Team Japan" Country="Japan">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
<Boat Type="Yacht" SourceID="104" ShapeID="4" HullNum="AC4504" ShortName="FRA"
BoatName="Groupama Team France" Country="France">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
<Boat Type="Yacht" SourceID="105" ShapeID="4" HullNum="AC4505" ShortName="SWE"
BoatName="Artemis Racing" Country="Sweden">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
<Boat Type="Yacht" SourceID="106" ShapeID="4" HullNum="AC4506" ShortName="NZL"
BoatName="Emirates Team New Zealand" Country="New Zealand">
<GPSposition Z="1.738" Y="0.625" X="0.001" />
<MastTop Z="21.496" Y="4.233" X="0.000" />
</Boat>
</Boats>
</BoatConfig>
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Race>
<RaceID>17041901</RaceID>
<RaceType>Fleet</RaceType>
<CreationTimeDate>2017-04-19T15:30:00+1200</CreationTimeDate >
<RaceStartTime Time="2019-06-01T13:30:00-0400" Postpone="false" />
<Participants>
<Yacht SourceID="001" Entry="Port" />
<Yacht SourceID="002" Entry="Port" />
<Yacht SourceID="003" Entry="Port" />
<Yacht SourceID="004" Entry="Port" />
<Yacht SourceID="005" Entry="Port" />
<Yacht SourceID="006" Entry="Port" />
</Participants>
<Course>
<CompoundMark CompoundMarkID="1" Name="StartLine">
<Mark SeqID="1" Name="PRO" TargetLat="32.296577" TargetLng="-64.854304" SourceID="101" />
<Mark SeqID="2" Name="PIN" TargetLat="32.293771" TargetLng="-64.855242" SourceID="102" />
</CompoundMark>
<CompoundMark CompoundMarkID="2" Name="M1">
<Mark Name="M1" TargetLat="32.293039" TargetLng="-64.843983" SourceID="103" />
</CompoundMark>
<CompoundMark CompoundMarkID="3" Name="WindwardGate">
<Mark SeqID="1" Name="G1" TargetLat="32.284680" TargetLng="-64.850045" SourceID="104" />
<Mark SeqID="2" Name="G2" TargetLat="32.280164" TargetLng="-64.847591" SourceID="105" />
</CompoundMark>
<CompoundMark CompoundMarkID="4" Name="LeewardGate">
<Mark SeqID="1" Name="G1" TargetLat="32.309693" TargetLng="-64.835249" SourceID="106" />
<Mark SeqID="2" Name="G2" TargetLat="32.308046" TargetLng="-64.831785" SourceID="107" />
</CompoundMark>
<CompoundMark CompoundMarkID="5" Name="FinishLine">
<Mark SeqID="1" Name="PRO" TargetLat="32.317379" TargetLng="-64.839291" SourceID="108" />
<Mark SeqID="2" Name="PIN" TargetLat="32.317257" TargetLng="-64.836260" SourceID="109" />
</CompoundMark>
</Course>
<CompoundMarkSequence>
<Corner SeqID="1" CompoundMarkID="1" Rounding="SP" ZoneSize="3" />
<Corner SeqID="2" CompoundMarkID="2" Rounding="Port" ZoneSize="3" />
<Corner SeqID="3" CompoundMarkID="3" Rounding="Port" ZoneSize="3" />
<Corner SeqID="4" CompoundMarkID="4" Rounding="Port" ZoneSize="3" />
<Corner SeqID="3" CompoundMarkID="3" Rounding="Port" ZoneSize="3" />
<Corner SeqID="5" CompoundMarkID="5" Rounding="SP" ZoneSize="3"/>
</CompoundMarkSequence>
<CourseLimit>
<Limit SeqID="1" Lat="32.313922" Lon="-64.837168"/>
<Limit SeqID="2" Lat="32.317379" Lon="-64.839291"/>
<Limit SeqID="3" Lat="32.317911" Lon="-64.836996"/>
<Limit SeqID="4" Lat="32.317257" Lon="-64.836260"/>
<Limit SeqID="5" Lat="32.304273" Lon="-64.822834"/>
<Limit SeqID="6" Lat="32.279097" Lon="-64.841545"/>
<Limit SeqID="7" Lat="32.279604" Lon="-64.849871"/>
<Limit SeqID="8" Lat="32.289545" Lon="-64.854162"/>
<Limit SeqID="9" Lat="32.290198" Lon="-64.858711"/>
<Limit SeqID="10" Lat="32.297164" Lon="-64.856394"/>
<Limit SeqID="11" Lat="32.296148" Lon="-64.849184"/>
</CourseLimit>
</Race>