The message encoders and decoders now catch exceptions, and throw InvalidMessageException.

Removed the big switch statement from BinaryMessageDecoder - it now uses the decoder factory instead.
issue #35 #36
#story[1095]
main
fjc40 8 years ago
parent 9c64b678e3
commit 134586f407

@ -17,42 +17,71 @@ import java.util.zip.CRC32;
*/ */
public class BinaryMessageDecoder { public class BinaryMessageDecoder {
///Length of the header. /**
* Length of the header.
*/
private static final int headerLength = 15; private static final int headerLength = 15;
///Length of the CRC. /**
private static final int CRCLength = 4;//TODO these should probably be static defined somewhere else to be shared. * Length of the CRC.
*/
private static final int CRCLength = 4;
///The value the first sync byte should have. /**
* The value the first sync byte should have.
*/
private static final byte syncByte1 = (byte) 0x47; private static final byte syncByte1 = (byte) 0x47;
//The value the second sync byte should have. /**
* The value the second sync byte should have.
*/
private static final byte syncByte2 = (byte) 0x83; private static final byte syncByte2 = (byte) 0x83;
///The full message. /**
* The full message.
*/
private byte[] fullMessage; private byte[] fullMessage;
///The messageHeader. /**
* The messageHeader.
*/
private byte[] messageHeader; private byte[] messageHeader;
///The messageBody. /**
* The messageBody.
*/
private byte[] messageBody; private byte[] messageBody;
///The sync bytes from the header.. /**
* The sync bytes from the header.
*/
private byte headerSync1; private byte headerSync1;
private byte headerSync2; private byte headerSync2;
///The message type from the header. /**
* The message type from the header.
*/
private byte headerMessageType; private byte headerMessageType;
///The timestamp from the header. /**
* The timestamp from the header.
*/
private long headerTimeStamp; private long headerTimeStamp;
///The source ID from the header. /**
* The source ID from the header.
*/
private int headerSourceID; private int headerSourceID;
///The message body length from the header. /**
* The message body length from the header.
*/
private int messageBodyLength; private int messageBodyLength;
///CRC value read from message header. /**
* CRC value read from message header.
*/
private long messageCRCValue; private long messageCRCValue;
///Calculated CRC value from message.
/**
* Calculated CRC value from message.
*/
private long calculatedCRCValue; private long calculatedCRCValue;
@ -129,90 +158,20 @@ public class BinaryMessageDecoder {
} }
//Now we create the message object based on what is actually in the message body. //Now we create the message object based on what is actually in the message body.
MessageType mType = MessageType.fromByte(headerMessageType); MessageType messageType = MessageType.fromByte(headerMessageType);
/*MessageDecoder decoder = null; MessageDecoder decoder = null;
try { try {
decoder = DecoderFactory.create(mType); decoder = DecoderFactory.create(messageType);
} catch (InvalidMessageTypeException e) { } catch (InvalidMessageTypeException e) {
throw new InvalidMessageException("Could not create decoder for MessageType: " + mType, e); throw new InvalidMessageException("Could not create decoder for MessageType: " + messageType, e);
} }
return decoder.decode(messageBody);*/ return decoder.decode(messageBody);
switch(mType) {
case HEARTBEAT:
//System.out.println("Decoding HeartBeat Message!");
HeartBeatDecoder heartBeatDecoder = new HeartBeatDecoder();
return heartBeatDecoder.decode(messageBody);
case RACESTATUS:
//System.out.println("Race Status Message");
RaceStatusDecoder rsdecoder = new RaceStatusDecoder();
return rsdecoder.decode(messageBody);
case DISPLAYTEXTMESSAGE:
//System.out.println("Display Text Message");
//No decoder for this.
//throw new InvalidMessageException("Cannot decode DISPLAYTEXTMESSAGE - no decoder.");
case XMLMESSAGE:
//System.out.println("XML Message!");
XMLMessageDecoder xmdecoder = new XMLMessageDecoder();
return xmdecoder.decode(messageBody);
case RACESTARTSTATUS:
//System.out.println("Race Start Status Message");
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder();
return rssDecoder.decode(messageBody);
case YACHTEVENTCODE:
//System.out.println("Yacht Action Code!");
//No decoder for this.
//throw new InvalidMessageException("Cannot decode YACHTEVENTCODE - no decoder.");
case YACHTACTIONCODE:
//System.out.println("Yacht Action Code!");
//No decoder for this.
//throw new InvalidMessageException("Cannot decode YACHTACTIONCODE - no decoder.");
case CHATTERTEXT:
//System.out.println("Chatter Text Message!");
//No decoder for this.
//throw new InvalidMessageException("Cannot decode CHATTERTEXT - no decoder.");
case BOATLOCATION:
//System.out.println("Boat Location Message!");
BoatLocationDecoder blDecoder = new BoatLocationDecoder();
return blDecoder.decode(messageBody);
case MARKROUNDING:
//System.out.println("Mark Rounding Message!");
MarkRoundingDecoder mrDecoder = new MarkRoundingDecoder();
return mrDecoder.decode(messageBody);
case COURSEWIND:
//System.out.println("Course Wind Message!");
CourseWindsDecoder cwDecoder = new CourseWindsDecoder();
return cwDecoder.decode(messageBody);
case AVGWIND:
//System.out.println("Average Wind Message!");
AverageWindDecoder awDecoder = new AverageWindDecoder();
return awDecoder.decode(messageBody);
case BOATACTION:
BoatActionDecoder baDecoder = new BoatActionDecoder();
return baDecoder.decode(messageBody);
default:
//System.out.println("Broken Message!");
//throw new InvalidMessageException("Broken message! Did not recognise message type: " + headerMessageType + ".");
return null;
} }
}
/** /**

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.AverageWind; import network.Messages.AverageWind;
import network.Utils.ByteConverter; import network.Utils.ByteConverter;
@ -32,9 +33,10 @@ public class AverageWindDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte messageVersionNumber = encodedMessage[0]; byte messageVersionNumber = encodedMessage[0];
@ -75,8 +77,6 @@ public class AverageWindDecoder implements MessageDecoder {
double speed4Knots = unpackMMperSecToKnots(intSpeed4); double speed4Knots = unpackMMperSecToKnots(intSpeed4);
message = new AverageWind( message = new AverageWind(
messageVersionNumber, messageVersionNumber,
time, time,
@ -91,6 +91,10 @@ public class AverageWindDecoder implements MessageDecoder {
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode AverageWind message.", e);
}
} }
/** /**

@ -1,5 +1,6 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatAction; import network.Messages.BoatAction;
import network.Messages.Enums.BoatActionEnum; import network.Messages.Enums.BoatActionEnum;
@ -29,14 +30,19 @@ public class BoatActionDecoder implements MessageDecoder {
} }
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(encodedMessage[0]); BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(encodedMessage[0]);
message = new BoatAction(boatActionEnum); message = new BoatAction(boatActionEnum);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode BoatAction message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatLocation; import network.Messages.BoatLocation;
import network.Messages.Enums.BoatLocationDeviceEnum; import network.Messages.Enums.BoatLocationDeviceEnum;
@ -39,9 +40,11 @@ public class BoatLocationDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1); byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
byte messageVersionNumber = messageVersionNumberBytes[0]; byte messageVersionNumber = messageVersionNumberBytes[0];
@ -149,6 +152,10 @@ public class BoatLocationDecoder implements MessageDecoder {
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode BoatLocation message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.BoatStatusEnum;
@ -39,10 +40,12 @@ public class BoatStatusDecoder {
* Decodes the contained message. * Decodes the contained message.
* @param encodedMessage The message to decode. * @param encodedMessage The message to decode.
* @return The decoded message. * @return The decoded message.
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
*/ */
public BoatStatus decode(byte[] encodedMessage) { public BoatStatus decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 0, 4); byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
int sourceID = bytesToInt(sourceIDBytes); int sourceID = bytesToInt(sourceIDBytes);
@ -76,6 +79,10 @@ public class BoatStatusDecoder {
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode BoatStatus message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.CourseWind; import network.Messages.CourseWind;
import shared.model.Bearing; import shared.model.Bearing;
@ -38,10 +39,13 @@ public class CourseWindDecoder {
* Decodes the contained message. * Decodes the contained message.
* @param encodedMessage The message to decode. * @param encodedMessage The message to decode.
* @return The decoded message. * @return The decoded message.
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
*/ */
public CourseWind decode(byte[] encodedMessage) { public CourseWind decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte[] windId = Arrays.copyOfRange(encodedMessage, 0, 1); byte[] windId = Arrays.copyOfRange(encodedMessage, 0, 1);
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7); byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
@ -69,7 +73,6 @@ public class CourseWindDecoder {
byte[] flags = Arrays.copyOfRange(encodedMessage, 19, 20); byte[] flags = Arrays.copyOfRange(encodedMessage, 19, 20);
message = new CourseWind( message = new CourseWind(
windId[0], windId[0],
time, time,
@ -81,6 +84,10 @@ public class CourseWindDecoder {
flags[0]); flags[0]);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode CourseWind message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.CourseWind; import network.Messages.CourseWind;
import network.Messages.CourseWinds; import network.Messages.CourseWinds;
@ -38,9 +39,11 @@ public class CourseWindsDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
//The header is three bytes. //The header is three bytes.
byte messageVersionNumber = encodedMessage[0]; byte messageVersionNumber = encodedMessage[0];
byte byteWindID = encodedMessage[1]; byte byteWindID = encodedMessage[1];
@ -66,13 +69,16 @@ public class CourseWindsDecoder implements MessageDecoder {
} }
message = new CourseWinds( message = new CourseWinds(
messageVersionNumber, messageVersionNumber,
byteWindID, byteWindID,
loopMessages); loopMessages);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode CourseWinds message.", e);
}
} }

@ -1,5 +1,6 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.BoatActionEnum; import network.Messages.Enums.BoatActionEnum;
import network.Messages.HeartBeat; import network.Messages.HeartBeat;
@ -30,12 +31,18 @@ public class HeartBeatDecoder implements MessageDecoder {
} }
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
message = new HeartBeat(bytesToLong(encodedMessage)); message = new HeartBeat(bytesToLong(encodedMessage));
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode HeartBeat message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.JoinAcceptanceEnum; import network.Messages.Enums.JoinAcceptanceEnum;
import network.Messages.JoinAcceptance; import network.Messages.JoinAcceptance;
@ -32,9 +33,11 @@ public class JoinAcceptanceDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
//SourceID is first four bytes. //SourceID is first four bytes.
byte[] sourceIdBytes = Arrays.copyOfRange(encodedMessage, 0, 4); byte[] sourceIdBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
@ -42,7 +45,6 @@ public class JoinAcceptanceDecoder implements MessageDecoder {
byte[] acceptanceBytes = Arrays.copyOfRange(encodedMessage, 4, 5); byte[] acceptanceBytes = Arrays.copyOfRange(encodedMessage, 4, 5);
//SourceID is an int. //SourceID is an int.
int sourceID = ByteConverter.bytesToInt(sourceIdBytes); int sourceID = ByteConverter.bytesToInt(sourceIdBytes);
@ -53,6 +55,10 @@ public class JoinAcceptanceDecoder implements MessageDecoder {
message = new JoinAcceptance(acceptanceType, sourceID); message = new JoinAcceptance(acceptanceType, sourceID);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode JoinAcceptance message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.MarkRoundingBoatStatusEnum; import network.Messages.Enums.MarkRoundingBoatStatusEnum;
import network.Messages.Enums.MarkRoundingSideEnum; import network.Messages.Enums.MarkRoundingSideEnum;
@ -33,9 +34,11 @@ public class MarkRoundingDecoder implements MessageDecoder {
} }
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte messageVersionNumber = encodedMessage[0]; byte messageVersionNumber = encodedMessage[0];
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7); byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
@ -75,6 +78,10 @@ public class MarkRoundingDecoder implements MessageDecoder {
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode AverageWind message.", e);
}
} }
/** /**

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
@ -15,7 +16,8 @@ public interface MessageDecoder {
* Decodes a given message. * Decodes a given message.
* @param encodedMessage The message to decode. * @param encodedMessage The message to decode.
* @return The decoded message. * @return The decoded message.
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
*/ */
public AC35Data decode(byte[] encodedMessage); public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException;
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.RaceStartTypeEnum; import network.Messages.Enums.RaceStartTypeEnum;
import network.Messages.RaceStartStatus; import network.Messages.RaceStartStatus;
@ -35,9 +36,10 @@ public class RaceStartStatusDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte messageVersion = encodedMessage[0]; byte messageVersion = encodedMessage[0];
@ -56,7 +58,6 @@ public class RaceStartStatusDecoder implements MessageDecoder {
byte notificationType = encodedMessage[19]; byte notificationType = encodedMessage[19];
message = new RaceStartStatus( message = new RaceStartStatus(
messageVersion, messageVersion,
time, time,
@ -68,6 +69,10 @@ public class RaceStartStatusDecoder implements MessageDecoder {
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode RaceStartStatus message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RaceStatusEnum;
@ -43,9 +44,10 @@ public class RaceStatusDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte[] versionNumBytes = Arrays.copyOfRange(encodedMessage, 0, 1); byte[] versionNumBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
byte versionNum = versionNumBytes[0]; byte versionNum = versionNumBytes[0];
@ -107,6 +109,10 @@ public class RaceStatusDecoder implements MessageDecoder {
boatStatuses); boatStatuses);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode RaceStatus message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.RequestToJoinEnum; import network.Messages.Enums.RequestToJoinEnum;
import network.Messages.RequestToJoin; import network.Messages.RequestToJoin;
@ -31,9 +32,11 @@ public class RequestToJoinDecoder implements MessageDecoder{
@Override @Override
public AC35Data decode(byte[] encodedRequest) { public AC35Data decode(byte[] encodedRequest) throws InvalidMessageException {
this.encodedRequest = encodedRequest; this.encodedRequest = encodedRequest;
try {
//Request type is first four bytes. //Request type is first four bytes.
byte[] requestTypeBytes = Arrays.copyOfRange(encodedRequest, 0, 4); byte[] requestTypeBytes = Arrays.copyOfRange(encodedRequest, 0, 4);
@ -45,6 +48,10 @@ public class RequestToJoinDecoder implements MessageDecoder{
message = new RequestToJoin(requestType); message = new RequestToJoin(requestType);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode RequestToJoin message.", e);
}
} }

@ -1,5 +1,6 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.Enums.XMLMessageType; import network.Messages.Enums.XMLMessageType;
import network.Messages.XMLMessage; import network.Messages.XMLMessage;
@ -35,9 +36,11 @@ public class XMLMessageDecoder implements MessageDecoder {
@Override @Override
public AC35Data decode(byte[] encodedMessage) { public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
this.encodedMessage = encodedMessage; this.encodedMessage = encodedMessage;
try {
byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1); byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
byte[] ackNumberBytes = Arrays.copyOfRange(encodedMessage, 1, 3); byte[] ackNumberBytes = Arrays.copyOfRange(encodedMessage, 1, 3);
byte[] timeStampBytes = Arrays.copyOfRange(encodedMessage, 3, 9); byte[] timeStampBytes = Arrays.copyOfRange(encodedMessage, 3, 9);
@ -65,6 +68,10 @@ public class XMLMessageDecoder implements MessageDecoder {
xmlMessage); xmlMessage);
return message; return message;
} catch (Exception e) {
throw new InvalidMessageException("Could not decode XMLMessage message.", e);
}
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.AverageWind; import network.Messages.AverageWind;
@ -24,7 +25,9 @@ public class AverageWindEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
AverageWind averageWind = (AverageWind) message; AverageWind averageWind = (AverageWind) message;
@ -68,7 +71,6 @@ public class AverageWindEncoder implements MessageEncoder {
byte[] byteSpeed4 = intToBytes(speed4Int, 2); byte[] byteSpeed4 = intToBytes(speed4Int, 2);
ByteBuffer result = ByteBuffer.allocate(23); ByteBuffer result = ByteBuffer.allocate(23);
result.put(messageVersionNumber); result.put(messageVersionNumber);
result.put(byteTime); result.put(byteTime);
@ -82,5 +84,9 @@ public class AverageWindEncoder implements MessageEncoder {
result.put(byteSpeed4); result.put(byteSpeed4);
return result.array(); return result.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode AverageWind message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatAction; import network.Messages.BoatAction;
@ -22,7 +23,9 @@ public class BoatActionEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
BoatAction boatAction = (BoatAction) message; BoatAction boatAction = (BoatAction) message;
@ -36,5 +39,9 @@ public class BoatActionEncoder implements MessageEncoder {
return result; return result;
} catch (Exception e) {
throw new InvalidMessageException("Could not encode BoatAction message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatLocation; import network.Messages.BoatLocation;
@ -24,7 +25,9 @@ public class BoatLocationEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
BoatLocation boatLocation = (BoatLocation) message; BoatLocation boatLocation = (BoatLocation) message;
@ -80,5 +83,9 @@ public class BoatLocationEncoder implements MessageEncoder {
return result.array(); return result.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode BoatLocation message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -25,8 +26,12 @@ public class BoatStatusEncoder {
* Encodes a given BoatStatus message. * Encodes a given BoatStatus message.
* @param message The message to encode. * @param message The message to encode.
* @return The encoded message. * @return The encoded message.
* @throws InvalidMessageException Thrown if the message is invalid in some way, or cannot be encoded.
*/ */
public byte[] encode(BoatStatus message) { public byte[] encode(BoatStatus message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
BoatStatus boatStatus = (BoatStatus) message; BoatStatus boatStatus = (BoatStatus) message;
@ -52,5 +57,9 @@ public class BoatStatusEncoder {
return boatStatusBuffer.array(); return boatStatusBuffer.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode BoatStatus message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.CourseWind; import network.Messages.CourseWind;
import shared.model.Bearing; import shared.model.Bearing;
@ -28,8 +29,11 @@ public class CourseWindEncoder {
* Encodes a given CourseWind message. * Encodes a given CourseWind message.
* @param message The message to encode. * @param message The message to encode.
* @return The encoded message. * @return The encoded message.
* @throws InvalidMessageException Thrown if the message is invalid in some way, or cannot be encoded.
*/ */
public byte[] encode(CourseWind message) { public byte[] encode(CourseWind message) throws InvalidMessageException {
try {
CourseWind courseWind = message; CourseWind courseWind = message;
@ -69,5 +73,9 @@ public class CourseWindEncoder {
return courseWindBuffer.array(); return courseWindBuffer.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode CourseWind message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatAction; import network.Messages.BoatAction;
import network.Messages.CourseWind; import network.Messages.CourseWind;
@ -24,7 +25,9 @@ public class CourseWindsEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
CourseWinds courseWinds = (CourseWinds) message; CourseWinds courseWinds = (CourseWinds) message;
@ -52,6 +55,10 @@ public class CourseWindsEncoder implements MessageEncoder {
} }
return result.array(); return result.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode CourseWinds message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.HeartBeat; import network.Messages.HeartBeat;
@ -22,7 +23,9 @@ public class HeartBeatEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
HeartBeat heartbeat = (HeartBeat) message; HeartBeat heartbeat = (HeartBeat) message;
@ -35,5 +38,9 @@ public class HeartBeatEncoder implements MessageEncoder {
return result; return result;
} catch (Exception e) {
throw new InvalidMessageException("Could not encode HeartBeat message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.JoinAcceptance; import network.Messages.JoinAcceptance;
import network.Utils.ByteConverter; import network.Utils.ByteConverter;
@ -23,7 +24,9 @@ public class JoinAcceptanceEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
JoinAcceptance joinAcceptance = (JoinAcceptance) message; JoinAcceptance joinAcceptance = (JoinAcceptance) message;
@ -40,5 +43,9 @@ public class JoinAcceptanceEncoder implements MessageEncoder {
return result; return result;
} catch (Exception e) {
throw new InvalidMessageException("Could not encode JoinAcceptance message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.MarkRounding; import network.Messages.MarkRounding;
@ -23,7 +24,9 @@ public class MarkRoundingEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
MarkRounding markRounding = (MarkRounding) message; MarkRounding markRounding = (MarkRounding) message;
@ -53,5 +56,9 @@ public class MarkRoundingEncoder implements MessageEncoder {
return result.array(); return result.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode MarkRounding message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
@ -15,7 +16,8 @@ public interface MessageEncoder {
* Encodes a given message. * Encodes a given message.
* @param message The message to encode. * @param message The message to encode.
* @return Message in byte encoded form. * @return Message in byte encoded form.
* @throws InvalidMessageException Thrown if the message is invalid in some way, or cannot be encoded.
*/ */
public byte[] encode(AC35Data message); public byte[] encode(AC35Data message) throws InvalidMessageException;
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.RaceStartStatus; import network.Messages.RaceStartStatus;
import network.Utils.ByteConverter; import network.Utils.ByteConverter;
@ -24,7 +25,9 @@ public class RaceStartStatusEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
RaceStartStatus raceStartStatus = (RaceStartStatus) message; RaceStartStatus raceStartStatus = (RaceStartStatus) message;
@ -47,5 +50,9 @@ public class RaceStartStatusEncoder implements MessageEncoder {
return result.array(); return result.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode RaceStartStatus message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
import network.Messages.RaceStatus; import network.Messages.RaceStatus;
@ -28,7 +29,9 @@ public class RaceStatusEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
RaceStatus raceStatus = (RaceStatus) message; RaceStatus raceStatus = (RaceStatus) message;
@ -91,5 +94,9 @@ public class RaceStatusEncoder implements MessageEncoder {
return raceStatusMessage.array(); return raceStatusMessage.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode RaceStatus message.", e);
}
} }
} }

@ -113,8 +113,10 @@ public class RaceVisionByteEncoder {
MessageEncoder encoder = null; MessageEncoder encoder = null;
try { try {
encoder = EncoderFactory.create(message.getType()); encoder = EncoderFactory.create(message.getType());
} catch (InvalidMessageTypeException e) { } catch (InvalidMessageTypeException e) {
throw new InvalidMessageException("Could not create encoder for MessageType: " + message.getType(), e); throw new InvalidMessageException("Could not create encoder for MessageType: " + message.getType(), e);
} }
byte[] encodedMessage = encoder.encode(message); byte[] encodedMessage = encoder.encode(message);

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.RequestToJoin; import network.Messages.RequestToJoin;
import network.Utils.ByteConverter; import network.Utils.ByteConverter;
@ -21,7 +22,9 @@ public class RequestToJoinEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
RequestToJoin requestToJoin = (RequestToJoin) message; RequestToJoin requestToJoin = (RequestToJoin) message;
@ -35,5 +38,9 @@ public class RequestToJoinEncoder implements MessageEncoder {
return result; return result;
} catch (Exception e) {
throw new InvalidMessageException("Could not encode RequestToJoin message.", e);
}
} }
} }

@ -1,6 +1,7 @@
package network.MessageEncoders; package network.MessageEncoders;
import network.Exceptions.InvalidMessageException;
import network.Messages.AC35Data; import network.Messages.AC35Data;
import network.Messages.XMLMessage; import network.Messages.XMLMessage;
@ -24,7 +25,9 @@ public class XMLMessageEncoder implements MessageEncoder {
@Override @Override
public byte[] encode(AC35Data message) { public byte[] encode(AC35Data message) throws InvalidMessageException {
try {
//Downcast. //Downcast.
XMLMessage xmlMessage = (XMLMessage) message; XMLMessage xmlMessage = (XMLMessage) message;
@ -58,5 +61,9 @@ public class XMLMessageEncoder implements MessageEncoder {
return tempOutputByteBuffer.array(); return tempOutputByteBuffer.array();
} catch (Exception e) {
throw new InvalidMessageException("Could not encode XMLMessage message.", e);
}
} }
} }

@ -56,18 +56,21 @@ public class ControllerClient {
BoatAction boatAction = new BoatAction(protocolCode); BoatAction boatAction = new BoatAction(protocolCode);
//Encode BoatAction. //Encode BoatAction.
byte[] encodedBoatAction = new byte[0];
try { try {
encodedBoatAction = RaceVisionByteEncoder.encode(boatAction); byte[] encodedBoatAction = RaceVisionByteEncoder.encode(boatAction);
} catch (InvalidMessageException e) {
Logger.getGlobal().log(Level.WARNING, "Could not encode BoatAction: " + boatAction, e);
}
BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0, BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0,
(short) encodedBoatAction.length, encodedBoatAction); (short) encodedBoatAction.length, encodedBoatAction);
System.out.println("Sending out key: " + protocolCode); System.out.println("Sending out key: " + protocolCode);
outputStream.write(binaryMessage.getFullMessage()); outputStream.write(binaryMessage.getFullMessage());
} catch (InvalidMessageException e) {
Logger.getGlobal().log(Level.WARNING, "Could not encode BoatAction: " + boatAction, e);
}
} }
} }
} }

@ -1,6 +1,7 @@
package visualiser.gameController; package visualiser.gameController;
import network.BinaryMessageDecoder; import network.BinaryMessageDecoder;
import network.Exceptions.InvalidMessageException;
import network.MessageDecoders.BoatActionDecoder; import network.MessageDecoders.BoatActionDecoder;
import network.Messages.BoatAction; import network.Messages.BoatAction;
import network.Messages.Enums.BoatActionEnum; import network.Messages.Enums.BoatActionEnum;
@ -10,6 +11,8 @@ import visualiser.gameController.Keys.KeyFactory;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Service for dispatching key press data to race from client * Service for dispatching key press data to race from client
@ -46,12 +49,22 @@ public class ControllerServer implements Runnable {
byte[] message = new byte[20]; byte[] message = new byte[20];
try { try {
if (inputStream.available() > 0) { if (inputStream.available() > 0) {
inputStream.read(message); inputStream.read(message);
BinaryMessageDecoder encodedMessage = new BinaryMessageDecoder(message); BinaryMessageDecoder encodedMessage = new BinaryMessageDecoder(message);
BoatActionDecoder boatActionDecoder = new BoatActionDecoder(); BoatActionDecoder boatActionDecoder = new BoatActionDecoder();
try {
boatActionDecoder.decode(encodedMessage.getMessageBody()); boatActionDecoder.decode(encodedMessage.getMessageBody());
BoatAction boatAction = boatActionDecoder.getMessage(); BoatAction boatAction = boatActionDecoder.getMessage();
System.out.println("Received key: " + boatAction.getBoatAction()); System.out.println("Received key: " + boatAction.getBoatAction());
} catch (InvalidMessageException e) {
Logger.getGlobal().log(Level.WARNING, "Could not decode BoatAction message.", e);
}
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

@ -1,5 +1,6 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.MessageEncoders.BoatStatusEncoder; import network.MessageEncoders.BoatStatusEncoder;
import network.MessageEncoders.RaceVisionByteEncoder; import network.MessageEncoders.RaceVisionByteEncoder;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
@ -55,8 +56,9 @@ public class BoatStatusDecoderTest {
* Encodes and decodes a BoatStatus, and returns it. * Encodes and decodes a BoatStatus, and returns it.
* @param boatStatus The BoatStatus to encode and decode. * @param boatStatus The BoatStatus to encode and decode.
* @return The decoded BoatStatus. * @return The decoded BoatStatus.
* @throws InvalidMessageException Thrown if message cannot be encoded or decoded.
*/ */
private static BoatStatus encodeDecodeBoatStatus(BoatStatus boatStatus) { private static BoatStatus encodeDecodeBoatStatus(BoatStatus boatStatus) throws InvalidMessageException {
BoatStatusEncoder boatStatusEncoder = new BoatStatusEncoder(); BoatStatusEncoder boatStatusEncoder = new BoatStatusEncoder();
byte[] boatStatusEncoded = boatStatusEncoder.encode(boatStatus); byte[] boatStatusEncoded = boatStatusEncoder.encode(boatStatus);

@ -1,5 +1,6 @@
package network.MessageDecoders; package network.MessageDecoders;
import network.Exceptions.InvalidMessageException;
import network.MessageEncoders.CourseWindEncoder; import network.MessageEncoders.CourseWindEncoder;
import network.Messages.BoatStatus; import network.Messages.BoatStatus;
import network.Messages.CourseWind; import network.Messages.CourseWind;
@ -43,8 +44,9 @@ public class CourseWindDecoderTest {
* Encodes and decodes a CourseWind, and returns it. * Encodes and decodes a CourseWind, and returns it.
* @param courseWind The CourseWind to encode and decode. * @param courseWind The CourseWind to encode and decode.
* @return The decoded CourseWind. * @return The decoded CourseWind.
* @throws InvalidMessageException Thrown if message cannot be encoded or decoded.
*/ */
private static CourseWind encodeDecodeCourseWind(CourseWind courseWind) { private static CourseWind encodeDecodeCourseWind(CourseWind courseWind) throws InvalidMessageException {
CourseWindEncoder courseWindEncoder = new CourseWindEncoder(); CourseWindEncoder courseWindEncoder = new CourseWindEncoder();
byte[] courseWindEncoded = courseWindEncoder.encode(courseWind); byte[] courseWindEncoded = courseWindEncoder.encode(courseWind);

Loading…
Cancel
Save