You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/08/16 12:07:57 UTC
[johnzon] branch master updated: JOHNZON-255 JOHNZON-256
JOHNZON-257 JOHNZON-258 JOHNZON-259 disable enummap/enumset deserialization
by default (jsonb tck) + support some container impl deserialization
without falling back on the generic interface
This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push:
new cf35aff JOHNZON-255 JOHNZON-256 JOHNZON-257 JOHNZON-258 JOHNZON-259 disable enummap/enumset deserialization by default (jsonb tck) + support some container impl deserialization without falling back on the generic interface
cf35aff is described below
commit cf35affe65d8a4a4789071b86d04423a8ab41a03
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Fri Aug 16 14:07:52 2019 +0200
JOHNZON-255 JOHNZON-256 JOHNZON-257 JOHNZON-258 JOHNZON-259 disable enummap/enumset deserialization by default (jsonb tck) + support some container impl deserialization without falling back on the generic interface
---
.../java/org/apache/johnzon/jsonb/JohnzonBuilder.java | 4 ++++
.../java/org/apache/johnzon/mapper/MapperBuilder.java | 9 ++++++++-
.../java/org/apache/johnzon/mapper/MapperConfig.java | 9 ++++++++-
.../org/apache/johnzon/mapper/MappingParserImpl.java | 19 ++++++++++++++-----
.../main/java/org/apache/johnzon/mapper/Mappings.java | 13 ++++++++++++-
.../org/apache/johnzon/mapper/MapperConfigTest.java | 2 +-
.../src/test/java/org/superbiz/ExtendMappingTest.java | 2 +-
src/site/markdown/index.md | 9 +++++++++
8 files changed, 57 insertions(+), 10 deletions(-)
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index 431e589..6f7572e 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -141,8 +141,12 @@ public class JohnzonBuilder implements JsonbBuilder {
config = new JsonbConfig();
}
+ // todo: global spec toggle to disable all these ones at once?
builder.setUseBigDecimalForObjectNumbers(
config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
+ builder.setSupportEnumContainerDeserialization( // https://github.com/eclipse-ee4j/jakartaee-tck/issues/103
+ config.getProperty("johnzon.support-enum-container-deserialization")
+ .map(this::toBool).orElse(false));
final boolean ijson = config.getProperty(JsonbConfig.STRICT_IJSON)
.map(Boolean.class::cast)
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index d17468e..b05667c 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -145,6 +145,7 @@ public class MapperBuilder {
private Boolean deduplicateObjects = null;
private boolean useJsRange;
private boolean useBigDecimalForObjectNumbers;
+ private boolean supportEnumContainerDeserialization = true;
public Mapper build() {
if (readerFactory == null || generatorFactory == null) {
@@ -256,7 +257,8 @@ public class MapperBuilder {
treatByteArrayAsBase64, treatByteArrayAsBase64URL, readAttributeBeforeWrite,
accessMode, encoding, attributeOrder, enforceQuoteString, failOnUnknownProperties,
serializeValueFilter, useBigDecimalForFloats, deduplicateObjects,
- interfaceImplementationMapping, useJsRange, useBigDecimalForObjectNumbers),
+ interfaceImplementationMapping, useJsRange, useBigDecimalForObjectNumbers,
+ supportEnumContainerDeserialization),
closeables);
}
@@ -528,4 +530,9 @@ public class MapperBuilder {
this.useBigDecimalForObjectNumbers = value;
return this;
}
+
+ public MapperBuilder setSupportEnumContainerDeserialization(final boolean supportEnumContainerDeserialization) {
+ this.supportEnumContainerDeserialization = supportEnumContainerDeserialization;
+ return this;
+ }
}
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
index 18184d0..1f3eafb 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java
@@ -58,6 +58,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
private final boolean treatByteArrayAsBase64;
private final boolean treatByteArrayAsBase64URL;
private final boolean readAttributeBeforeWrite;
+ private final boolean supportEnumMapDeserialization; // for tck
private final AccessMode accessMode;
private final Charset encoding;
private final ConcurrentMap<AdapterKey, Adapter<?, ?>> adapters;
@@ -94,7 +95,8 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
final Boolean deduplicateObjects,
final Map<Class<?>, Class<?>> interfaceImplementationMapping,
final boolean useJsRange,
- final boolean useBigDecimalForObjectNumbers) {
+ final boolean useBigDecimalForObjectNumbers,
+ final boolean supportEnumMapDeserialization) {
//CHECKSTYLE:ON
this.objectConverterWriters = objectConverterWriters;
this.objectConverterReaders = objectConverterReaders;
@@ -109,6 +111,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
this.encoding = encoding;
this.useJsRange = useJsRange;
this.useBigDecimalForObjectNumbers = useBigDecimalForObjectNumbers;
+ this.supportEnumMapDeserialization = supportEnumMapDeserialization;
// handle Adapters
this.adapters = adapters;
@@ -342,4 +345,8 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable {
public Boolean isDeduplicateObjects() {
return deduplicateObjects;
}
+
+ public boolean isSupportEnumContainerDeserialization() {
+ return supportEnumMapDeserialization;
+ }
}
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index 76b5329..a182a5a 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -55,6 +55,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
@@ -264,13 +265,15 @@ public class MappingParserImpl implements MappingParser {
final Class<?> raw = Class.class.cast(aType.getRawType());
final Map map;
- if (LinkedHashMap.class == raw) {
- map = new LinkedHashMap();
- } else if (SortedMap.class.isAssignableFrom(raw) || NavigableMap.class == raw || TreeMap.class == raw) {
+ if (SortedMap.class.isAssignableFrom(raw) || NavigableMap.class == raw || TreeMap.class == raw) {
map = config.getAttributeOrder() == null ? new TreeMap() : new TreeMap(config.getAttributeOrder());
} else if (ConcurrentMap.class.isAssignableFrom(raw)) {
map = new ConcurrentHashMap(object.size());
} else if (EnumMap.class.isAssignableFrom(raw)) {
+ if (!config.isSupportEnumContainerDeserialization()) {
+ throw new MapperException("JSON-B forbids EnumMap deserialization, " +
+ "set supportEnumMapDeserialization=true to disable that arbitrary limitation");
+ }
map = new EnumMap(Class.class.cast(fieldArgTypes[0]));
} else if (Map.class.isAssignableFrom(raw)) {
map = new LinkedHashMap(object.size()); // todo: configurable from config.getNewDefaultMap()?
@@ -303,7 +306,7 @@ public class MappingParserImpl implements MappingParser {
}
}
} else if (Map.class == type || HashMap.class == type || LinkedHashMap.class == type) {
- final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
+ final Map<String, Object> map = new LinkedHashMap<String, Object>();
for (final Map.Entry<String, JsonValue> value : object.entrySet()) {
map.put(value.getKey(), toObject(null, value.getValue(), Object.class, null, jsonPointer, Object.class));
}
@@ -923,9 +926,11 @@ public class MappingParserImpl implements MappingParser {
collection = new ArrayList<T>(jsonArray.size());
} else if (LinkedHashSet.class == mapping.raw) {
collection = new LinkedHashSet<T>(jsonArray.size());
+ } else if (LinkedList.class == mapping.raw) {
+ collection = new LinkedList<T>();
} else if (Deque.class == mapping.raw || ArrayDeque.class == mapping.raw) {
collection = new ArrayDeque(jsonArray.size());
- } else if (Queue.class == mapping.raw || PriorityQueue.class == mapping.raw) {
+ } else if (PriorityQueue.class == mapping.raw) {
collection = new PriorityQueue(jsonArray.size());
} else {
throw new IllegalStateException("not supported collection type: " + mapping.raw.getName());
@@ -941,6 +946,10 @@ public class MappingParserImpl implements MappingParser {
}
if (EnumSet.class == mapping.raw) {
+ if (!config.isSupportEnumContainerDeserialization()) {
+ throw new MapperException("Enum container deserialization disabled, " +
+ "set supportEnumContainerDeserialization=true to enable it");
+ }
if (collection.isEmpty()) {
return EnumSet.noneOf(Class.class.cast(mapping.arg));
} else if (collection.size() == 1) {
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
index e60e8f8..1e7ea18 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
@@ -42,13 +42,16 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -295,7 +298,15 @@ public class Mappings {
if (fieldArgTypes.length == 1 && Class.class.isInstance(raw)) {
final Class<?> r = Class.class.cast(raw);
final Class<?> collectionType;
- if (List.class.isAssignableFrom(r)) {
+ if (PriorityQueue.class.isAssignableFrom(r)) {
+ collectionType = PriorityQueue.class;
+ } else if (LinkedHashSet.class.isAssignableFrom(r)) {
+ collectionType = LinkedHashSet.class;
+ } else if (LinkedList.class.isAssignableFrom(r)) {
+ collectionType = LinkedList.class;
+ } else if (TreeSet.class.isAssignableFrom(r)) {
+ collectionType = TreeSet.class;
+ } else if (List.class.isAssignableFrom(r)) {
collectionType = List.class;
} else if (SortedSet.class.isAssignableFrom(r)) {
collectionType = SortedSet.class;
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
index e770b7d..3becb92 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
@@ -169,7 +169,7 @@ public class MapperConfigTest {
new FieldAccessMode(true, true),
Charset.forName("UTF-8"),
null,
- false, false, null, false, false, emptyMap(), true, false);
+ false, false, null, false, false, emptyMap(), true, false, true);
}
diff --git a/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java b/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
index bbfdc31..559302a 100644
--- a/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
+++ b/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
@@ -66,7 +66,7 @@ public class ExtendMappingTest {
-1, true, true, true, false, false, false,
new FieldAccessMode(false, false),
Charset.forName("UTF-8"), String::compareTo, false, false, null, false, false,
- emptyMap(), true, false));
+ emptyMap(), true, false, true));
}
@Override
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 7e97dc1..0dd4b7b 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -306,6 +306,15 @@ However it supports some specific properties to wire to the native johnzon confi
One example is `johnzon.interfaceImplementationMapping` which will support a `Map<Class,Class>` to map interfaces to implementations
to use for deserialization.
+JsonbConfig specific properties:
+
+* johnzon.use-big-decimal-for-object: true to use BigDecimal for numbers not typed (Object), false to adjust the type to the number size, true by default.
+* johnzon.support-enum-container-deserialization: prevent EnumMap/EnumSet instantiation, true by default.
+* johnzon.attributeOrder: Comparator instance to sort properties by name.
+* johnzon.deduplicateObjects: should instances be deduplicated.
+
+TIP: more in JohnzonBuilder class.
+
#### Integration with `JsonValue`
You can use some optimization to map a `JsonObject` to a POJO using Johnzon `JsonValueReader` and `JsonValueWriter`: