diff --git a/racevisionGame/src/main/java/network/Exceptions/InvalidMessageTypeException.java b/racevisionGame/src/main/java/network/Exceptions/InvalidMessageTypeException.java new file mode 100644 index 00000000..02867eaa --- /dev/null +++ b/racevisionGame/src/main/java/network/Exceptions/InvalidMessageTypeException.java @@ -0,0 +1,17 @@ +package network.Exceptions; + + +/** + * An exception thrown when we encounter a message type that isn't recognised. + */ +public class InvalidMessageTypeException extends Exception { + + + public InvalidMessageTypeException(String message) { + super(message); + } + + public InvalidMessageTypeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java b/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java new file mode 100644 index 00000000..620107fa --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/EncoderFactory.java @@ -0,0 +1,44 @@ +package network.MessageEncoders; + + +import network.Exceptions.InvalidMessageTypeException; +import network.Messages.Enums.MessageType; + +/** + * Factory to create the appropriate encoder for a given message. + */ +public class EncoderFactory { + + + /** + * Private constructor. Currently doesn't need to be constructed. + */ + private EncoderFactory(){ + + } + + + /** + * Creates the correct type of encoder for a given message type. + * @param type Type of message you want an encoder for. + * @return The encoder. + * @throws InvalidMessageTypeException If you pass in a {@link MessageType} that isn't recognised. + */ + public static MessageEncoder create(MessageType type) throws InvalidMessageTypeException { + + + switch (type) { + + case REQUEST_TO_JOIN: return new RequestToJoinEncoder(); + + case JOIN_ACCEPTANCE: return new JoinAcceptanceEncoder(); + + + default: throw new InvalidMessageTypeException("Unrecognised message type: " + type); + } + + + + } + +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/JoinAcceptanceEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/JoinAcceptanceEncoder.java new file mode 100644 index 00000000..2b23c0dd --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/JoinAcceptanceEncoder.java @@ -0,0 +1,44 @@ +package network.MessageEncoders; + + +import network.Messages.AC35Data; +import network.Messages.JoinAcceptance; +import network.Utils.ByteConverter; + +import java.nio.ByteBuffer; + +import static network.Utils.ByteConverter.intToBytes; + +/** + * This encoder can encode a {@link JoinAcceptance} message. + */ +public class JoinAcceptanceEncoder implements MessageEncoder { + + + /** + * Constructor. + */ + public JoinAcceptanceEncoder() { + } + + + @Override + public byte[] encode(AC35Data message) { + + //Downcast. + JoinAcceptance joinAcceptance = (JoinAcceptance) message; + + //Message is 5 bytes. + ByteBuffer joinAcceptanceBuffer = ByteBuffer.allocate(5); + + //Source ID is first four bytes. + joinAcceptanceBuffer.put(intToBytes(joinAcceptance.getSourceID(), 4)); + //Acceptance type is next byte. + joinAcceptanceBuffer.put(intToBytes(joinAcceptance.getAcceptanceType().getValue(), 1)); + + byte [] result = joinAcceptanceBuffer.array(); + + return result; + + } +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/MessageEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/MessageEncoder.java new file mode 100644 index 00000000..d5ec4cd8 --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/MessageEncoder.java @@ -0,0 +1,21 @@ +package network.MessageEncoders; + + +import network.Messages.AC35Data; + + +/** + * This is the interface that all message encoders must implement. + * It allows for {@link #encode(AC35Data)}ing messages. + */ +public interface MessageEncoder { + + + /** + * Encodes a given message. + * @param message The message to encode. + * @return Message in byte encoded form. + */ + public byte[] encode(AC35Data message); + +} diff --git a/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java index 88dcb024..78498457 100644 --- a/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java +++ b/racevisionGame/src/main/java/network/MessageEncoders/RaceVisionByteEncoder.java @@ -1,6 +1,8 @@ package network.MessageEncoders; +import network.Exceptions.InvalidMessageException; +import network.Exceptions.InvalidMessageTypeException; import network.Messages.*; import static network.Utils.ByteConverter.*; @@ -348,40 +350,24 @@ public class RaceVisionByteEncoder { /** - * Encodes a {@link RequestToJoin} message. - * @param requestToJoin Message to encode. + * Encodes a given message. + * @param message Message to encode. * @return Encoded message. + * @throws InvalidMessageException If the message cannot be encoded. */ - public static byte[] requestToJoin(RequestToJoin requestToJoin) { + public static byte[] encode(AC35Data message) throws InvalidMessageException { - ByteBuffer requestToJoinBuffer = ByteBuffer.allocate(4); - - requestToJoinBuffer.put(intToBytes(requestToJoin.getRequestType().getValue(), 4)); - - byte [] result = requestToJoinBuffer.array(); + MessageEncoder encoder = null; + try { + encoder = EncoderFactory.create(message.getType()); + } catch (InvalidMessageTypeException e) { + throw new InvalidMessageException("Could not create encoder for MessageType: " + message.getType(), e); + } - return result; + byte[] encodedMessage = encoder.encode(message); + return encodedMessage; } - /** - * Encodes a {@link JoinAcceptance} message. - * @param joinAcceptance Message to encode. - * @return Encoded message. - */ - public static byte[] joinAcceptance(JoinAcceptance joinAcceptance) { - //Message is 5 bytes. - ByteBuffer joinAcceptanceBuffer = ByteBuffer.allocate(5); - - //Source ID is first four bytes. - joinAcceptanceBuffer.put(intToBytes(joinAcceptance.getSourceID(), 4)); - //Acceptance type is next byte. - joinAcceptanceBuffer.put(intToBytes(joinAcceptance.getAcceptanceType().getValue(), 1)); - - byte [] result = joinAcceptanceBuffer.array(); - - return result; - - } } diff --git a/racevisionGame/src/main/java/network/MessageEncoders/RequestToJoinEncoder.java b/racevisionGame/src/main/java/network/MessageEncoders/RequestToJoinEncoder.java new file mode 100644 index 00000000..b01e92de --- /dev/null +++ b/racevisionGame/src/main/java/network/MessageEncoders/RequestToJoinEncoder.java @@ -0,0 +1,39 @@ +package network.MessageEncoders; + + +import network.Messages.AC35Data; +import network.Messages.RequestToJoin; +import network.Utils.ByteConverter; + +import java.nio.ByteBuffer; + +/** + * This encoder can encode a {@link network.Messages.RequestToJoin} message. + */ +public class RequestToJoinEncoder implements MessageEncoder { + + + /** + * Constructor. + */ + public RequestToJoinEncoder() { + } + + + @Override + public byte[] encode(AC35Data message) { + + //Downcast. + RequestToJoin requestToJoin = (RequestToJoin) message; + + + ByteBuffer requestToJoinBuffer = ByteBuffer.allocate(4); + + requestToJoinBuffer.put(ByteConverter.intToBytes(requestToJoin.getRequestType().getValue(), 4)); + + byte [] result = requestToJoinBuffer.array(); + + return result; + + } +} diff --git a/racevisionGame/src/test/java/network/MessageDecoders/JoinAcceptanceDecoderTest.java b/racevisionGame/src/test/java/network/MessageDecoders/JoinAcceptanceDecoderTest.java index cca27fb2..5cefe5ea 100644 --- a/racevisionGame/src/test/java/network/MessageDecoders/JoinAcceptanceDecoderTest.java +++ b/racevisionGame/src/test/java/network/MessageDecoders/JoinAcceptanceDecoderTest.java @@ -1,5 +1,6 @@ package network.MessageDecoders; +import network.Exceptions.InvalidMessageException; import network.MessageEncoders.RaceVisionByteEncoder; import network.Messages.Enums.JoinAcceptanceEnum; import network.Messages.JoinAcceptance; @@ -19,10 +20,10 @@ public class JoinAcceptanceDecoderTest { * @param message Message to encode/decode. * @return The decoded message. */ - private JoinAcceptance encodeDecodeMessage(JoinAcceptance message) { + private JoinAcceptance encodeDecodeMessage(JoinAcceptance message) throws InvalidMessageException { //Encode. - byte [] testEncodedMessage = RaceVisionByteEncoder.joinAcceptance(message); + byte [] testEncodedMessage = RaceVisionByteEncoder.encode(message); //Decode. JoinAcceptanceDecoder testDecoder = new JoinAcceptanceDecoder(testEncodedMessage); diff --git a/racevisionGame/src/test/java/network/MessageDecoders/RequestToJoinDecoderTest.java b/racevisionGame/src/test/java/network/MessageDecoders/RequestToJoinDecoderTest.java index 5ea9f5ee..ddfd11bd 100644 --- a/racevisionGame/src/test/java/network/MessageDecoders/RequestToJoinDecoderTest.java +++ b/racevisionGame/src/test/java/network/MessageDecoders/RequestToJoinDecoderTest.java @@ -1,5 +1,6 @@ package network.MessageDecoders; +import network.Exceptions.InvalidMessageException; import network.MessageEncoders.RaceVisionByteEncoder; import network.Messages.Enums.RequestToJoinEnum; import network.Messages.RequestToJoin; @@ -20,10 +21,10 @@ public class RequestToJoinDecoderTest { * @param message Message to encode/decode. * @return The decoded message. */ - private RequestToJoin encodeDecodeMessage(RequestToJoin message) { + private RequestToJoin encodeDecodeMessage(RequestToJoin message) throws InvalidMessageException { //Encode. - byte [] testEncodedMessage = RaceVisionByteEncoder.requestToJoin(message); + byte [] testEncodedMessage = RaceVisionByteEncoder.encode(message); //Decode. RequestToJoinDecoder testDecoder = new RequestToJoinDecoder(testEncodedMessage);