feat: completed RequestDeserializer

This commit is contained in:
Yannik Bretschneider 2021-05-28 14:50:38 +02:00
parent b2b963579e
commit a92f437412
5 changed files with 148 additions and 33 deletions

View File

@ -0,0 +1,18 @@
package uulm.teamname.marvelous.gamelibrary.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonNodeUnwrapper {
private static final ObjectMapper mapper = new ObjectMapper();
public static <T> T unwrap (JsonNode rootNode, String key, Class<T> type) throws JsonProcessingException {
JsonNode subNode;
if ((subNode = rootNode.get(key)) != null) {
return mapper.readValue(subNode.toString(), type);
}
return null;
}
}

View File

@ -16,6 +16,8 @@ import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
import uulm.teamname.marvelous.gamelibrary.events.EventType;
import uulm.teamname.marvelous.gamelibrary.events.GamestateEvent;
import static uulm.teamname.marvelous.gamelibrary.json.JsonNodeUnwrapper.unwrap;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
@ -74,40 +76,40 @@ public class EventDeserializer extends JsonDeserializer<Event> {
// }
// necessary because of exact type mismatch
var stoneTypeID = getIfNodeValid(node, "stoneType", EntityID.class);
var stoneTypeID = unwrap(node, "stoneType", EntityID.class);
builder.withTargetEntity(getIfNodeValid(node, "targetEntity", EntityID.class))
.withTargetField(getIfNodeValid(node, "targetField", IntVector2.class))
.withAmount(getIfNodeValid(node, "targetField", Integer.class))
.withEntity(getIfNodeValid(node, "entity", Entity.class))
builder.withTargetEntity(unwrap(node, "targetEntity", EntityID.class))
.withTargetField(unwrap(node, "targetField", IntVector2.class))
.withAmount(unwrap(node, "targetField", Integer.class))
.withEntity(unwrap(node, "entity", Entity.class))
.withOriginEntity(getIfNodeValid(node, "originEntity", EntityID.class))
.withOriginField(getIfNodeValid(node, "originField", IntVector2.class))
.withOriginEntity(unwrap(node, "originEntity", EntityID.class))
.withOriginField(unwrap(node, "originField", IntVector2.class))
.withStoneType(stoneTypeID != null ? StoneType.valueOf(stoneTypeID.id) : null)
.withRoundCount(getIfNodeValid(node, "roundCount", Integer.class))
.withTurnCount(getIfNodeValid(node, "turnCount", Integer.class))
.withCharacterOrder(getIfNodeValid(node, "characterOrder", EntityID[].class))
.withNextCharacter(getIfNodeValid(node, "nextCharacter", EntityID.class))
.withRoundCount(unwrap(node, "roundCount", Integer.class))
.withTurnCount(unwrap(node, "turnCount", Integer.class))
.withCharacterOrder(unwrap(node, "characterOrder", EntityID[].class))
.withNextCharacter(unwrap(node, "nextCharacter", EntityID.class))
.withPlayerWon(getIfNodeValid(node, "playerWon", Integer.class))
.withPlayerWon(unwrap(node, "playerWon", Integer.class))
.withMessage(getIfNodeValid(node, "message", String.class))
.withTimeLeft(getIfNodeValid(node, "timeLeft", Integer.class))
.withMessage(unwrap(node, "message", String.class))
.withTimeLeft(unwrap(node, "timeLeft", Integer.class))
.withEntities(getIfNodeValid(node, "entities", Entity[].class))
.withTurnOrder(getIfNodeValid(node, "turnOrder", EntityID[].class))
.withMapSize(getIfNodeValid(node, "mapSize", IntVector2.class))
.withActiveCharacter(getIfNodeValid(node, "activeCharacter", EntityID.class))
.withStoneCooldowns(getIfNodeValid(node, "stoneCooldowns",Integer[].class))
.withWinCondition(getIfNodeValid(node, "winCondition",Boolean.class))
.withEntities(unwrap(node, "entities", Entity[].class))
.withTurnOrder(unwrap(node, "turnOrder", EntityID[].class))
.withMapSize(unwrap(node, "mapSize", IntVector2.class))
.withActiveCharacter(unwrap(node, "activeCharacter", EntityID.class))
.withStoneCooldowns(unwrap(node, "stoneCooldowns",Integer[].class))
.withWinCondition(unwrap(node, "winCondition",Boolean.class))
.withTeamIdentifier(getIfNodeValid(node, "teamIdentifier", String.class))
.withCustomContent((HashMap<String, Object>) getIfNodeValid(node,"customContent", HashMap.class));
.withTeamIdentifier(unwrap(node, "teamIdentifier", String.class))
.withCustomContent(unwrap(node,"customContent", HashMap.class));
builder.withTargetEntity(getIfNodeValid(node, "targetEntity", EntityID.class));
builder.withTargetField(getIfNodeValid(node, "targetField", IntVector2.class));
builder.withTargetEntity(unwrap(node, "targetEntity", EntityID.class));
builder.withTargetField(unwrap(node, "targetField", IntVector2.class));
switch (eventType) {
case Ack, Nack, GamestateEvent -> { return builder.buildGameStateEvent(); }
@ -136,11 +138,5 @@ public class EventDeserializer extends JsonDeserializer<Event> {
return null;
}
private <T> T getIfNodeValid (JsonNode rootNode, String key, Class<T> type) throws JsonProcessingException {
JsonNode subNode;
if ((subNode = rootNode.get(key)) != null) {
return mapper.readValue(subNode.toString(), type);
}
return null;
}
}

View File

@ -0,0 +1,67 @@
package uulm.teamname.marvelous.gamelibrary.json.ingame;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import uulm.teamname.marvelous.gamelibrary.IntVector2;
import uulm.teamname.marvelous.gamelibrary.entities.Entity;
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
import uulm.teamname.marvelous.gamelibrary.events.Event;
import uulm.teamname.marvelous.gamelibrary.requests.*;
import java.io.IOException;
import java.util.Optional;
import static uulm.teamname.marvelous.gamelibrary.json.JsonNodeUnwrapper.unwrap;
public class RequestDeserializer extends JsonDeserializer<Request> {
// static so that no reinitializations are needed
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public Request deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectCodec codec = p.getCodec();
JsonNode node = codec.readTree(p);
JsonNode requestTypeNode;
RequestType requestType;
if ((requestTypeNode = node.get("requestType")) != null) {
requestType = RequestType.valueOf(requestTypeNode.textValue());
} else {
throw new IOException("No RequestType found. JSON does not represent a request");
}
var requestBuilder = new RequestBuilder(requestType)
.withValue(unwrap(node, "value", int.class))
.withOriginEntity(unwrap(node, "originEntity", EntityID.class))
.withTargetEntity(unwrap(node, "targetEntity", EntityID.class))
.withOriginField(unwrap(node, "originField", IntVector2.class))
.withTargetField(unwrap(node, "targetField", IntVector2.class))
.withStoneType(unwrap(node, "stoneType", StoneType.class));
switch (requestType) {
case DisconnectRequest,
Req,
PauseStartRequest,
PauseStopRequest,
EndRoundRequest -> {
return requestBuilder.buildGameRequest();
}
case ExchangeInfinityStoneRequest,
MeleeAttackRequest,
MoveRequest,
RangedAttackRequest,
UseInfinityStoneRequest -> {
return requestBuilder.buildCharacterRequest();
}
}
return null; // if there is no request type
}
}

View File

@ -1,10 +1,13 @@
package uulm.teamname.marvelous.gamelibrary.requests;
import uulm.teamname.marvelous.gamelibrary.json.ingame.MessageStructure;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
import uulm.teamname.marvelous.gamelibrary.json.ingame.RequestDeserializer;
import java.util.Objects;
/** Represents an abstract request sent inside a {@link MessageStructure} between client and server. */
/** Represents an abstract request sent inside a {@link EventMessage} between client and server. */
@JsonDeserialize(using = RequestDeserializer.class)
public abstract class Request {
public RequestType type;

View File

@ -0,0 +1,31 @@
package uulm.teamname.marvelous.gamelibrary.json.ingame;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
import uulm.teamname.marvelous.gamelibrary.requests.GameRequest;
import uulm.teamname.marvelous.gamelibrary.requests.Request;
import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
public class RequestDeserializerTest {
private ObjectMapper mapper;
@BeforeEach
void beforeEach() {
mapper = new ObjectMapper();
}
@Test
void gameRequestDeserialization() throws JsonProcessingException {
var request = new GameRequest();
request.type = RequestType.DisconnectRequest;
var jsonRepresentingRequest = "{ \"requestType\": \"DisconnectRequest\" }";
assertThat((GameRequest) (mapper.readValue(jsonRepresentingRequest, Request.class)))
.isEqualTo(request);
}
}