From e4e9cdb22c6685e0b7df0583998c00326adbf10d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 9 Apr 2018 18:23:33 +0200 Subject: [PATCH] changed CompetitorAndBoat[De]Serializer such that it is backward compatible for CompetitorWithBoat Change-Id: Ia5717bdef5d9db7833b8d44df061dce524cecf85 --- .../CompetitorAndBoatJsonDeserializer.java | 13 +++- .../impl/CompetitorAndBoatJsonSerializer.java | 40 ++++++++--- .../test/CompetitorJsonSerializerTest.java | 67 +++++++++++++++++++ 3 files changed, 110 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/impl/CompetitorAndBoatJsonDeserializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/impl/CompetitorAndBoatJsonDeserializer.java index 1eb176b3e8a..70cb8de3489 100644 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/impl/CompetitorAndBoatJsonDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/deserialization/impl/CompetitorAndBoatJsonDeserializer.java @@ -4,6 +4,7 @@ import org.json.simple.JSONObject; import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.domain.base.SharedDomainFactory; import com.sap.sailing.domain.base.impl.DynamicBoat; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; @@ -26,8 +27,16 @@ public class CompetitorAndBoatJsonDeserializer implements JsonDeserializer deserialize(JSONObject competitorAndBoatJsonObject) throws JsonDeserializationException { - Competitor competitor = competitorDeserializer.deserialize(Helpers.getNestedObjectSafe(competitorAndBoatJsonObject, CompetitorAndBoatJsonSerializer.FIELD_COMPETITOR)); - Boat boat = boatDeserializer.deserialize(Helpers.getNestedObjectSafe(competitorAndBoatJsonObject, CompetitorAndBoatJsonSerializer.FIELD_BOAT)); + final Competitor competitor; + final Boat boat; + if (competitorAndBoatJsonObject.containsKey(CompetitorAndBoatJsonSerializer.FIELD_COMPETITOR)) { + competitor = competitorDeserializer.deserialize(Helpers.getNestedObjectSafe(competitorAndBoatJsonObject, CompetitorAndBoatJsonSerializer.FIELD_COMPETITOR)); + boat = boatDeserializer.deserialize(Helpers.getNestedObjectSafe(competitorAndBoatJsonObject, CompetitorAndBoatJsonSerializer.FIELD_BOAT)); + } else { + final CompetitorWithBoat competitorWithBoat = (CompetitorWithBoat) competitorDeserializer.deserialize(competitorAndBoatJsonObject); + competitor = competitorWithBoat; + boat = competitorWithBoat.getBoat(); + } return new Pair(competitor, boat); } } diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorAndBoatJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorAndBoatJsonSerializer.java index e0c7f3a2b8e..9f57a1f7fc2 100644 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorAndBoatJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorAndBoatJsonSerializer.java @@ -1,9 +1,12 @@ package com.sap.sailing.server.gateway.serialization.impl; +import java.util.logging.Logger; + import org.json.simple.JSONObject; import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.server.gateway.serialization.JsonSerializer; import com.sap.sse.common.Util.Pair; @@ -11,6 +14,8 @@ import com.sap.sse.common.Util.Pair; * Serializes a competitor AND a boat as a kind of pair (e.g. in the context of a race) */ public class CompetitorAndBoatJsonSerializer implements JsonSerializer> { + private static final Logger logger = Logger.getLogger(CompetitorAndBoatJsonSerializer.class.getName()); + private final JsonSerializer competitorJsonSerializer; private final JsonSerializer boatJsonSerializer; @@ -28,14 +33,33 @@ public class CompetitorAndBoatJsonSerializer implements JsonSerializer competitorAndBoat) { - JSONObject serializedCompetitorAndBoat = new JSONObject(); - + final JSONObject result; JSONObject serializedCompetitor = competitorJsonSerializer.serialize(competitorAndBoat.getA()); - JSONObject serializedBoat = boatJsonSerializer.serialize(competitorAndBoat.getB()); - - serializedCompetitorAndBoat.put(FIELD_COMPETITOR, serializedCompetitor); - serializedCompetitorAndBoat.put(FIELD_BOAT, serializedBoat); - - return serializedCompetitorAndBoat; + // for compatibility, write a CompetitorWithBoat in the same format that a Competitor use to be + // serialized; only if the competitor has no boat, use the new format. The de-serializer will be + // able to distinguish based on the presence of the top-level FIELD_COMPETITOR field. + final boolean compatibilityMode; + if (competitorAndBoat.getA().hasBoat()) { + final CompetitorWithBoat competitorWithBoat = (CompetitorWithBoat) competitorAndBoat.getA(); + final Boat boat = competitorWithBoat.getBoat(); + if (boat != competitorAndBoat.getB()) { + logger.warning("Competitor "+competitorWithBoat+" has boat "+boat+" which is different from the boat to be serialized with it ("+ + competitorAndBoat.getB()); + compatibilityMode = false; + } else { + compatibilityMode = true; + } + } else { + compatibilityMode = false; + } + if (compatibilityMode) { + result = serializedCompetitor; + } else { + JSONObject serializedBoat = boatJsonSerializer.serialize(competitorAndBoat.getB()); + result = new JSONObject(); + result.put(FIELD_COMPETITOR, serializedCompetitor); + result.put(FIELD_BOAT, serializedBoat); + } + return result; } } diff --git a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/CompetitorJsonSerializerTest.java b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/CompetitorJsonSerializerTest.java index fef0d5a11ed..123ba94d632 100755 --- a/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/CompetitorJsonSerializerTest.java +++ b/java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/CompetitorJsonSerializerTest.java @@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.serialization.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,8 +24,11 @@ import com.sap.sailing.domain.base.Team; import com.sap.sailing.domain.base.impl.DomainFactoryImpl; import com.sap.sailing.domain.base.impl.TransientCompetitorStoreImpl; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; +import com.sap.sailing.server.gateway.deserialization.impl.CompetitorAndBoatJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.CompetitorJsonDeserializer; +import com.sap.sailing.server.gateway.serialization.impl.CompetitorAndBoatJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerializer; +import com.sap.sse.common.Util.Pair; public class CompetitorJsonSerializerTest { @@ -96,6 +100,69 @@ public class CompetitorJsonSerializerTest { assertEquals(boat.getSailID(), deserializedCompetitorWithBoat.getBoat().getSailID()); } + @Test + public void testCompetitorAndBoatWithBoat() throws JsonDeserializationException, ParseException { + final CompetitorWithBoat competitorWithBoat = mock(CompetitorWithBoat.class); + mockTeam(competitorWithBoat); + String expectedId = "123"; + when(competitorWithBoat.getId()).thenReturn(expectedId); + final Boat boat = mock(Boat.class); + when(competitorWithBoat.hasBoat()).thenReturn(true); + when(competitorWithBoat.getBoat()).thenReturn(boat); + when(boat.getId()).thenReturn(UUID.randomUUID()); + when(boat.getSailID()).thenReturn("1233"); + when(boat.getBoatClass()).thenReturn(DomainFactory.INSTANCE.getOrCreateBoatClass("Tornado")); + JSONObject result = CompetitorAndBoatJsonSerializer.create().serialize(new Pair<>(competitorWithBoat, boat)); + final Pair deserializedCompetitorAndBoat = CompetitorAndBoatJsonDeserializer + .create(new DomainFactoryImpl(new TransientCompetitorStoreImpl(), /* raceLogResolver */ null)) + .deserialize((JSONObject) new JSONParser().parse(result.toString())); + assertTrue(deserializedCompetitorAndBoat.getA().hasBoat()); + assertTrue(deserializedCompetitorAndBoat.getA() instanceof CompetitorWithBoat); + final CompetitorWithBoat deserializedCompetitorWithBoat = (CompetitorWithBoat) deserializedCompetitorAndBoat.getA(); + assertSame(deserializedCompetitorWithBoat.getBoat(), deserializedCompetitorAndBoat.getB()); + assertEquals(boat.getId(), deserializedCompetitorWithBoat.getBoat().getId()); + assertEquals(boat.getSailID(), deserializedCompetitorWithBoat.getBoat().getSailID()); + } + + @Test + public void testCompetitorAndBoatWithoutBoat() throws JsonDeserializationException, ParseException { + String expectedId = "1234"; + when(competitor.getId()).thenReturn(expectedId); + when(competitor.hasBoat()).thenReturn(false); + final Boat boat = mock(Boat.class); + when(boat.getId()).thenReturn(UUID.randomUUID()); + when(boat.getSailID()).thenReturn("12334"); + when(boat.getBoatClass()).thenReturn(DomainFactory.INSTANCE.getOrCreateBoatClass("Tornado")); + JSONObject result = CompetitorAndBoatJsonSerializer.create().serialize(new Pair<>(competitor, boat)); + final Pair deserializedCompetitorAndBoat = CompetitorAndBoatJsonDeserializer + .create(new DomainFactoryImpl(new TransientCompetitorStoreImpl(), /* raceLogResolver */ null)) + .deserialize((JSONObject) new JSONParser().parse(result.toString())); + assertFalse(deserializedCompetitorAndBoat.getA().hasBoat()); + assertFalse(deserializedCompetitorAndBoat.getA() instanceof CompetitorWithBoat); + assertEquals("12334", deserializedCompetitorAndBoat.getB().getSailID()); + } + + @Test + public void testCompetitorAndBoatWithNullBoat() throws JsonDeserializationException, ParseException { + final CompetitorWithBoat competitorWithBoat = mock(CompetitorWithBoat.class); + mockTeam(competitorWithBoat); + String expectedId = "1234"; + when(competitorWithBoat.getId()).thenReturn(expectedId); + when(competitorWithBoat.hasBoat()).thenReturn(false); + when(competitorWithBoat.getBoat()).thenReturn(null); + final Boat boat = mock(Boat.class); + when(boat.getId()).thenReturn(UUID.randomUUID()); + when(boat.getSailID()).thenReturn("1233"); + when(boat.getBoatClass()).thenReturn(DomainFactory.INSTANCE.getOrCreateBoatClass("Tornado")); + JSONObject result = CompetitorAndBoatJsonSerializer.create().serialize(new Pair<>(competitorWithBoat, boat)); + final Pair deserializedCompetitorAndBoat = CompetitorAndBoatJsonDeserializer + .create(new DomainFactoryImpl(new TransientCompetitorStoreImpl(), /* raceLogResolver */ null)) + .deserialize((JSONObject) new JSONParser().parse(result.toString())); + assertFalse(deserializedCompetitorAndBoat.getA().hasBoat()); + assertFalse(deserializedCompetitorAndBoat.getA() instanceof CompetitorWithBoat); + assertEquals("1233", deserializedCompetitorAndBoat.getB().getSailID()); + } + @Test public void testCompetitorWithNullBoat() throws JsonDeserializationException, ParseException { final CompetitorWithBoat competitorWithBoat = mock(CompetitorWithBoat.class);