From 9d76b04a1c237a727b269d87d34495fbdd8d9284 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Fri, 14 Jun 2019 11:38:24 +0100 Subject: [PATCH] Remove duplicate JSON keys. Closes #2068. --- .../com/google/refine/browsing/facets/FacetConfig.java | 4 ++-- .../com/google/refine/clustering/ClustererConfig.java | 3 ++- main/src/com/google/refine/model/AbstractOperation.java | 3 ++- .../com/google/refine/preference/PreferenceValue.java | 4 ++-- main/src/com/google/refine/sorting/Criterion.java | 2 +- .../com/google/refine/tests/preference/TopListTests.java | 8 +++++++- .../src/com/google/refine/tests/util/TestUtils.java | 9 ++++++++- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/main/src/com/google/refine/browsing/facets/FacetConfig.java b/main/src/com/google/refine/browsing/facets/FacetConfig.java index 94117fbff..05f005c1d 100644 --- a/main/src/com/google/refine/browsing/facets/FacetConfig.java +++ b/main/src/com/google/refine/browsing/facets/FacetConfig.java @@ -26,7 +26,7 @@ ******************************************************************************/ package com.google.refine.browsing.facets; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -63,6 +63,6 @@ public interface FacetConfig { /** * The facet type as stored in json. */ - @JsonProperty("type") + @JsonIgnore // already included by @JsonTypeInfo public String getJsonType(); } diff --git a/main/src/com/google/refine/clustering/ClustererConfig.java b/main/src/com/google/refine/clustering/ClustererConfig.java index d824bc3ae..47a4590bf 100644 --- a/main/src/com/google/refine/clustering/ClustererConfig.java +++ b/main/src/com/google/refine/clustering/ClustererConfig.java @@ -26,6 +26,7 @@ ******************************************************************************/ package com.google.refine.clustering; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; @@ -70,6 +71,6 @@ public abstract class ClustererConfig { /** * Type string used in Json serialization */ - @JsonProperty("type") + @JsonIgnore // already added by @JsonTypeInfo public abstract String getType(); } diff --git a/main/src/com/google/refine/model/AbstractOperation.java b/main/src/com/google/refine/model/AbstractOperation.java index 5dd401197..6828ffb0c 100644 --- a/main/src/com/google/refine/model/AbstractOperation.java +++ b/main/src/com/google/refine/model/AbstractOperation.java @@ -35,6 +35,7 @@ package com.google.refine.model; import java.util.Properties; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; @@ -72,7 +73,7 @@ abstract public class AbstractOperation { throw new UnsupportedOperationException(); } - @JsonProperty("op") + @JsonIgnore // the operation id is already added as "op" by the JsonTypeInfo annotation public String getOperationId() { return OperationRegistry.s_opClassToName.get(this.getClass()); } diff --git a/main/src/com/google/refine/preference/PreferenceValue.java b/main/src/com/google/refine/preference/PreferenceValue.java index bbfded4e0..e4462f39a 100644 --- a/main/src/com/google/refine/preference/PreferenceValue.java +++ b/main/src/com/google/refine/preference/PreferenceValue.java @@ -26,8 +26,8 @@ ******************************************************************************/ package com.google.refine.preference; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonProperty; /** * Interface to be extended by all objects stored @@ -40,7 +40,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; @JsonTypeInfo( use=JsonTypeInfo.Id.CLASS, - include=JsonTypeInfo.As.PROPERTY, + include=JsonTypeInfo.As.EXISTING_PROPERTY, property="class") public interface PreferenceValue { diff --git a/main/src/com/google/refine/sorting/Criterion.java b/main/src/com/google/refine/sorting/Criterion.java index 7e8a56fc8..4b52391d8 100644 --- a/main/src/com/google/refine/sorting/Criterion.java +++ b/main/src/com/google/refine/sorting/Criterion.java @@ -70,7 +70,7 @@ abstract public class Criterion { @JsonProperty("reverse") public boolean reverse = false; - @JsonProperty("valueType") + @JsonIgnore // already added by @JsonTypeInfo public abstract String getValueType(); // Returns a cached cell index diff --git a/main/tests/server/src/com/google/refine/tests/preference/TopListTests.java b/main/tests/server/src/com/google/refine/tests/preference/TopListTests.java index 9e4520b13..ba441d8b2 100644 --- a/main/tests/server/src/com/google/refine/tests/preference/TopListTests.java +++ b/main/tests/server/src/com/google/refine/tests/preference/TopListTests.java @@ -27,11 +27,13 @@ package com.google.refine.tests.preference; import java.io.IOException; +import java.util.Collections; import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; +import com.google.refine.preference.PreferenceValue; import com.google.refine.preference.TopList; import com.google.refine.tests.util.TestUtils; import com.google.refine.util.ParsingUtilities; @@ -50,8 +52,12 @@ public class TopListTests { + " \"grel:value.parseJson()[\\\"employment-summary\\\"].join('###')\"," + " \"grel:\\\"https://pub.orcid.org/\\\"+value+\\\"/employments\\\"\"" + "]}"; + PreferenceValue prefValue = ParsingUtilities.mapper.readValue(json, PreferenceValue.class); TestUtils.isSerializedTo( - ParsingUtilities.mapper.readValue(json, TopList.class), + prefValue, json); + + String mapJson = "{\"key\":"+json+"}"; + TestUtils.isSerializedTo(Collections.singletonMap("key",prefValue), mapJson); } } diff --git a/main/tests/server/src/com/google/refine/tests/util/TestUtils.java b/main/tests/server/src/com/google/refine/tests/util/TestUtils.java index b762d02d9..77bf2b266 100644 --- a/main/tests/server/src/com/google/refine/tests/util/TestUtils.java +++ b/main/tests/server/src/com/google/refine/tests/util/TestUtils.java @@ -35,8 +35,11 @@ import java.io.LineNumberReader; import java.io.StringReader; import java.io.StringWriter; +import com.fasterxml.jackson.core.JsonFactory.Feature; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MapperFeature; @@ -50,7 +53,11 @@ public class TestUtils { static ObjectMapper mapper = new ObjectMapper(); static { - mapper = mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true); + mapper = mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + // Reject duplicate fields because the previous implementation with org.json + // does not accept them. It is also cleaner and more compact. + mapper = mapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION); + mapper = mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY); } /**