From e1b411999f2f5387d597eae09d8f06702668d0bc Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 24 Jul 2020 11:04:04 +0200 Subject: [PATCH 1/7] added useTypeHint option to VPack.Builder --- ChangeLog.md | 2 + .../java/com/arangodb/velocypack/VPack.java | 28 ++- .../velocypack/VPackWithoutTypeHintTest.java | 208 ++++++++++++++++++ 3 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java diff --git a/ChangeLog.md b/ChangeLog.md index ac54b93..62c5057 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +- added useTypeHint option to VPack.Builder + ## [2.3.1] - 2020-05-05 - shaded jackson dependency diff --git a/src/main/java/com/arangodb/velocypack/VPack.java b/src/main/java/com/arangodb/velocypack/VPack.java index 0e46fac..f2f7103 100644 --- a/src/main/java/com/arangodb/velocypack/VPack.java +++ b/src/main/java/com/arangodb/velocypack/VPack.java @@ -49,6 +49,7 @@ public class VPack { private static final String ATTR_KEY = "key"; private static final String ATTR_VALUE = "value"; private static final String DEFAULT_TYPE_KEY = "_class"; + private static final boolean DEFAULT_USE_TYPE_HINT = true; private final Map> serializers; private final Map> enclosingSerializers; @@ -65,6 +66,7 @@ public class VPack { private final VPackDeserializationContext deserializationContext; private final boolean serializeNullValues; private final String typeKey; + private final boolean useTypeHint; private final VPackBuilderUtils builderUtils; private final VPackCreatorMethodUtils vPackCreatorMethodUtils; @@ -83,6 +85,7 @@ public static class Builder implements VPackSetupContext { private final Map, VPackAnnotationFieldNaming> annotationFieldNaming; private final Map> keyMapAdapters; private String typeKey; + private Boolean useTypeHint; public Builder() { super(); @@ -99,6 +102,7 @@ public Builder() { annotationFieldNaming = new HashMap<>(); keyMapAdapters = new HashMap<>(); typeKey = null; + useTypeHint = null; instanceCreators.put(Iterable.class, VPackInstanceCreators.ITERABLE); instanceCreators.put(Collection.class, VPackInstanceCreators.COLLECTION); @@ -324,6 +328,17 @@ public Builder typeKey(final String typeKey) { return this; } + /** + * Enables storing type information of the serialized object + * + * @param useTypeHint (default: {@code true}) + * @return {@link VPack.Builder} + */ + public Builder useTypeHint(final boolean useTypeHint) { + this.useTypeHint = useTypeHint; + return this; + } + public synchronized VPack build() { return new VPack(new HashMap<>(serializers), new HashMap<>(enclosingSerializers), new HashMap<>(deserializers), new HashMap<>(deserializersWithSelfNullHandle), @@ -331,7 +346,10 @@ public synchronized VPack build() { fieldNamingStrategy, new HashMap<>(deserializersByName), new HashMap<>(deserializersByNameWithSelfNullHandle), new HashMap<>(annotationFieldFilter), new HashMap<>(annotationFieldNaming), - keyMapAdapters, typeKey != null ? typeKey : DEFAULT_TYPE_KEY); + keyMapAdapters, + typeKey != null ? typeKey : DEFAULT_TYPE_KEY, + useTypeHint != null ? useTypeHint : DEFAULT_USE_TYPE_HINT + ); } } @@ -345,7 +363,7 @@ private VPack(final Map> serializers, final Map>> deserializersByNameWithSelfNullHandle, final Map, VPackAnnotationFieldFilter> annotationFieldFilter, final Map, VPackAnnotationFieldNaming> annotationFieldNaming, - final Map> keyMapAdapters, final String typeKey) { + final Map> keyMapAdapters, final String typeKey, final boolean useTypeHint) { super(); this.serializers = serializers; this.enclosingSerializers = enclosingSerializers; @@ -358,6 +376,7 @@ private VPack(final Map> serializers, this.deserializersByNameWithSelfNullHandle = deserializersByNameWithSelfNullHandle; this.keyMapAdapters = keyMapAdapters; this.typeKey = typeKey; + this.useTypeHint = useTypeHint; builderUtils = new VPackBuilderUtils(); vPackCreatorMethodUtils = new VPackCreatorMethodUtils(); @@ -480,7 +499,7 @@ private T deserializeObject( } private Type determineType(final VPackSlice vpack, final Type type) { - if (!vpack.isObject()) { + if (!useTypeHint || !vpack.isObject()) { return type; } final VPackSlice clazz = vpack.get(typeKey); @@ -944,6 +963,9 @@ private boolean shouldAddTypeHint( final Object value, final FieldInfo fieldInfo ) { + if (!useTypeHint) { + return false; + } final AnnotatedElement referencingElement = fieldInfo != null ? fieldInfo.getReferencingElement() : null; final BuilderInfo builderInfo = builderUtils.getBuilderInfo(type, referencingElement); if (builderInfo != null) { diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java new file mode 100644 index 0000000..aad44de --- /dev/null +++ b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java @@ -0,0 +1,208 @@ +/* + * DISCLAIMER + * + * Copyright 2016 ArangoDB GmbH, Cologne, Germany + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.velocypack; + +import org.junit.Test; + +import java.util.*; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * @author Michele Rastelli + */ +public class VPackWithoutTypeHintTest { + + public static class NestedCollection { + public Collection value; + } + + @Test + public void nestedCollectionWithoutTypeInformation() { + NestedCollection input = new NestedCollection(); + input.value = Arrays.asList("a", "b", "c"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + + NestedCollection output = vpack.deserialize(slice, NestedCollection.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + + public static class NestedMap { + public Map value; + } + + @Test + public void nestedMapWithoutTypeInformation() { + NestedMap input = new NestedMap(); + input.value = Collections.singletonMap("a", "b"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isObject(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + + NestedMap output = vpack.deserialize(slice, NestedMap.class); + assertThat(output.value, instanceOf(Map.class)); + + assertThat(output.value, equalTo(input.value)); + } + + public static class NestedObject { + public Object value; + } + + @Test + public void nestedObjectWithoutTypeInformation() { + NestedObject input = new NestedObject(); + input.value = Collections.singletonMap("a", "b"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isObject(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + + NestedObject output = vpack.deserialize(slice, NestedObject.class); + assertThat(output.value, instanceOf(Map.class)); + + assertThat(output.value, equalTo(input.value)); + } + + public static class NestedGeneric { + public T value; + } + + @Test + public void nestedGenericOfCollectionWithoutTypeInformation() { + NestedGeneric> input = new NestedGeneric<>(); + input.value = Arrays.asList("a", "b", "c"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + + NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + + @Test + public void nestedGenericOfMapWithoutTypeInformation() { + NestedGeneric> input = new NestedGeneric<>(); + input.value = Collections.singletonMap("a", "b"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isObject(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + + NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); + assertThat(output.value, instanceOf(Map.class)); + + assertThat(output.value, equalTo(input.value)); + } + + @Test + public void nestedGenericOfObjectWithoutTypeInformation() { + NestedGeneric input = new NestedGeneric<>(); + input.value = Collections.singletonMap("a", "b"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isObject(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + + NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); + assertThat(output.value, instanceOf(Map.class)); + + assertThat(output.value, equalTo(input.value)); + } + + public static class NestedGenericBoundedCollection> { + public T value; + } + + @Test + public void nestedGenericBoundedCollectionWithoutTypeInformation() { + NestedGenericBoundedCollection> input = new NestedGenericBoundedCollection<>(); + input.value = Arrays.asList("a", "b", "c"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + + NestedGenericBoundedCollection output = vpack.deserialize(slice, NestedGenericBoundedCollection.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + + public static class NestedGenericBoundedMap> { + public T value; + } + + @Test + public void nestedGenericBoundedMapWithoutTypeInformation() { + NestedGenericBoundedMap> input = new NestedGenericBoundedMap<>(); + input.value = Collections.singletonMap("a", "b"); + + final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isObject(), is(true)); + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + + NestedGenericBoundedMap output = vpack.deserialize(slice, NestedGenericBoundedMap.class); + assertThat(output.value, instanceOf(Map.class)); + + assertThat(output.value, equalTo(input.value)); + } + +} From 590693baa53683f05883237ad72a009837e20c18 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 13:23:22 +0200 Subject: [PATCH 2/7] parameterized useTypeHint tests --- pom.xml | 2 +- .../velocypack/VPackWithoutTypeHintTest.java | 167 +++++++++++------- 2 files changed, 101 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index 538a878..bae10de 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.arangodb velocypack - 2.3.1 + 2.4.0-SNAPSHOT 2017 jar diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java index aad44de..18e7a91 100644 --- a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java @@ -21,6 +21,8 @@ package com.arangodb.velocypack; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import java.util.*; @@ -30,8 +32,43 @@ /** * @author Michele Rastelli */ +@RunWith(Parameterized.class) public class VPackWithoutTypeHintTest { + private final boolean useTypeHint; + + @Parameterized.Parameters + public static Collection useTypeHint() { + return Arrays.asList(true, false); + } + + public VPackWithoutTypeHintTest(final boolean useTypeHint) { + this.useTypeHint = useTypeHint; + } + + public static class NestedIterable { + public Iterable value; + } + + @Test + public void nestedIterableWithoutTypeInformation() { + NestedCollection input = new NestedCollection(); + input.value = Arrays.asList("a", "b", "c"); + + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHint) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedIterable output = vpack.deserialize(slice, NestedIterable.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + public static class NestedCollection { public Collection value; } @@ -41,12 +78,13 @@ public void nestedCollectionWithoutTypeInformation() { NestedCollection input = new NestedCollection(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); + if (!useTypeHint) + assertThat(slice.get("_class").isNone(), is(true)); NestedCollection output = vpack.deserialize(slice, NestedCollection.class); assertThat(output.value, instanceOf(List.class)); @@ -60,17 +98,21 @@ public static class NestedMap { @Test public void nestedMapWithoutTypeInformation() { + Map map = new HashMap<>(); + map.put("a", "b"); + NestedMap input = new NestedMap(); - input.value = Collections.singletonMap("a", "b"); + input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - + if (!useTypeHint) { + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + } NestedMap output = vpack.deserialize(slice, NestedMap.class); assertThat(output.value, instanceOf(Map.class)); @@ -82,21 +124,44 @@ public static class NestedObject { } @Test - public void nestedObjectWithoutTypeInformation() { + public void nestedObjectListWithoutTypeInformation() { NestedObject input = new NestedObject(); - input.value = Collections.singletonMap("a", "b"); + input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHint) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedObject output = vpack.deserialize(slice, NestedObject.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + + @Test + public void nestedObjectMapWithoutTypeInformation() { + Map map = new HashMap<>(); + map.put("a", "b"); + + NestedObject input = new NestedObject(); + input.value = map; + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); + if (!useTypeHint) { + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + } NestedObject output = vpack.deserialize(slice, NestedObject.class); assertThat(output.value, instanceOf(Map.class)); + ((Map) output.value).remove("_class"); assertThat(output.value, equalTo(input.value)); } @@ -109,12 +174,13 @@ public void nestedGenericOfCollectionWithoutTypeInformation() { NestedGeneric> input = new NestedGeneric<>(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); + if (!useTypeHint) + assertThat(slice.get("_class").isNone(), is(true)); NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); assertThat(output.value, instanceOf(List.class)); @@ -124,84 +190,51 @@ public void nestedGenericOfCollectionWithoutTypeInformation() { @Test public void nestedGenericOfMapWithoutTypeInformation() { + Map map = new HashMap<>(); + map.put("a", "b"); + NestedGeneric> input = new NestedGeneric<>(); - input.value = Collections.singletonMap("a", "b"); + input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); + if (!useTypeHint) { + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + } NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); assertThat(output.value, instanceOf(Map.class)); + ((Map) output.value).remove("_class"); assertThat(output.value, equalTo(input.value)); } @Test public void nestedGenericOfObjectWithoutTypeInformation() { + Map map = new HashMap<>(); + map.put("a", "b"); + NestedGeneric input = new NestedGeneric<>(); - input.value = Collections.singletonMap("a", "b"); + input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); + final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); + if (!useTypeHint) { + assertThat(slice.get("_class").isNone(), is(true)); + assertThat(slice.get("value").get("_class").isNone(), is(true)); + } NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); assertThat(output.value, instanceOf(Map.class)); - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedGenericBoundedCollection> { - public T value; - } - - @Test - public void nestedGenericBoundedCollectionWithoutTypeInformation() { - NestedGenericBoundedCollection> input = new NestedGenericBoundedCollection<>(); - input.value = Arrays.asList("a", "b", "c"); - - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isArray(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - - NestedGenericBoundedCollection output = vpack.deserialize(slice, NestedGenericBoundedCollection.class); - assertThat(output.value, instanceOf(List.class)); - - assertThat(output.value, equalTo(input.value)); - } - - public static class NestedGenericBoundedMap> { - public T value; - } - - @Test - public void nestedGenericBoundedMapWithoutTypeInformation() { - NestedGenericBoundedMap> input = new NestedGenericBoundedMap<>(); - input.value = Collections.singletonMap("a", "b"); - - final VPack vpack = new VPack.Builder().useTypeHint(false).build(); - final VPackSlice slice = vpack.serialize(input); - - assertThat(slice.isObject(), is(true)); - assertThat(slice.get("value").isObject(), is(true)); - assertThat(slice.get("_class").isNone(), is(true)); - assertThat(slice.get("value").get("_class").isNone(), is(true)); - - NestedGenericBoundedMap output = vpack.deserialize(slice, NestedGenericBoundedMap.class); - assertThat(output.value, instanceOf(Map.class)); - + ((Map) output.value).remove("_class"); assertThat(output.value, equalTo(input.value)); } From 84b29754d3ded5a422c39826fa1cc657a54ae4a2 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 14:19:24 +0200 Subject: [PATCH 3/7] renamed config parameter useTypeHint to useTypeHints --- .../java/com/arangodb/velocypack/VPack.java | 24 ++++++------ .../velocypack/VPackWithoutTypeHintTest.java | 38 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/arangodb/velocypack/VPack.java b/src/main/java/com/arangodb/velocypack/VPack.java index f2f7103..b2128f4 100644 --- a/src/main/java/com/arangodb/velocypack/VPack.java +++ b/src/main/java/com/arangodb/velocypack/VPack.java @@ -49,7 +49,7 @@ public class VPack { private static final String ATTR_KEY = "key"; private static final String ATTR_VALUE = "value"; private static final String DEFAULT_TYPE_KEY = "_class"; - private static final boolean DEFAULT_USE_TYPE_HINT = true; + private static final boolean DEFAULT_USE_TYPE_HINTS = true; private final Map> serializers; private final Map> enclosingSerializers; @@ -66,7 +66,7 @@ public class VPack { private final VPackDeserializationContext deserializationContext; private final boolean serializeNullValues; private final String typeKey; - private final boolean useTypeHint; + private final boolean useTypeHints; private final VPackBuilderUtils builderUtils; private final VPackCreatorMethodUtils vPackCreatorMethodUtils; @@ -85,7 +85,7 @@ public static class Builder implements VPackSetupContext { private final Map, VPackAnnotationFieldNaming> annotationFieldNaming; private final Map> keyMapAdapters; private String typeKey; - private Boolean useTypeHint; + private Boolean useTypeHints; public Builder() { super(); @@ -102,7 +102,7 @@ public Builder() { annotationFieldNaming = new HashMap<>(); keyMapAdapters = new HashMap<>(); typeKey = null; - useTypeHint = null; + useTypeHints = null; instanceCreators.put(Iterable.class, VPackInstanceCreators.ITERABLE); instanceCreators.put(Collection.class, VPackInstanceCreators.COLLECTION); @@ -331,11 +331,11 @@ public Builder typeKey(final String typeKey) { /** * Enables storing type information of the serialized object * - * @param useTypeHint (default: {@code true}) + * @param useTypeHints (default: {@code true}) * @return {@link VPack.Builder} */ - public Builder useTypeHint(final boolean useTypeHint) { - this.useTypeHint = useTypeHint; + public Builder useTypeHints(final boolean useTypeHints) { + this.useTypeHints = useTypeHints; return this; } @@ -348,7 +348,7 @@ public synchronized VPack build() { new HashMap<>(annotationFieldFilter), new HashMap<>(annotationFieldNaming), keyMapAdapters, typeKey != null ? typeKey : DEFAULT_TYPE_KEY, - useTypeHint != null ? useTypeHint : DEFAULT_USE_TYPE_HINT + useTypeHints != null ? useTypeHints : DEFAULT_USE_TYPE_HINTS ); } @@ -363,7 +363,7 @@ private VPack(final Map> serializers, final Map>> deserializersByNameWithSelfNullHandle, final Map, VPackAnnotationFieldFilter> annotationFieldFilter, final Map, VPackAnnotationFieldNaming> annotationFieldNaming, - final Map> keyMapAdapters, final String typeKey, final boolean useTypeHint) { + final Map> keyMapAdapters, final String typeKey, final boolean useTypeHints) { super(); this.serializers = serializers; this.enclosingSerializers = enclosingSerializers; @@ -376,7 +376,7 @@ private VPack(final Map> serializers, this.deserializersByNameWithSelfNullHandle = deserializersByNameWithSelfNullHandle; this.keyMapAdapters = keyMapAdapters; this.typeKey = typeKey; - this.useTypeHint = useTypeHint; + this.useTypeHints = useTypeHints; builderUtils = new VPackBuilderUtils(); vPackCreatorMethodUtils = new VPackCreatorMethodUtils(); @@ -499,7 +499,7 @@ private T deserializeObject( } private Type determineType(final VPackSlice vpack, final Type type) { - if (!useTypeHint || !vpack.isObject()) { + if (!useTypeHints || !vpack.isObject()) { return type; } final VPackSlice clazz = vpack.get(typeKey); @@ -963,7 +963,7 @@ private boolean shouldAddTypeHint( final Object value, final FieldInfo fieldInfo ) { - if (!useTypeHint) { + if (!useTypeHints) { return false; } final AnnotatedElement referencingElement = fieldInfo != null ? fieldInfo.getReferencingElement() : null; diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java index 18e7a91..23f9bd0 100644 --- a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java @@ -35,15 +35,15 @@ @RunWith(Parameterized.class) public class VPackWithoutTypeHintTest { - private final boolean useTypeHint; + private final boolean useTypeHints; @Parameterized.Parameters public static Collection useTypeHint() { return Arrays.asList(true, false); } - public VPackWithoutTypeHintTest(final boolean useTypeHint) { - this.useTypeHint = useTypeHint; + public VPackWithoutTypeHintTest(final boolean useTypeHints) { + this.useTypeHints = useTypeHints; } public static class NestedIterable { @@ -55,12 +55,12 @@ public void nestedIterableWithoutTypeInformation() { NestedCollection input = new NestedCollection(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHint) + if (!useTypeHints) assertThat(slice.get("_class").isNone(), is(true)); NestedIterable output = vpack.deserialize(slice, NestedIterable.class); @@ -78,12 +78,12 @@ public void nestedCollectionWithoutTypeInformation() { NestedCollection input = new NestedCollection(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHint) + if (!useTypeHints) assertThat(slice.get("_class").isNone(), is(true)); NestedCollection output = vpack.deserialize(slice, NestedCollection.class); @@ -104,12 +104,12 @@ public void nestedMapWithoutTypeInformation() { NestedMap input = new NestedMap(); input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHint) { + if (!useTypeHints) { assertThat(slice.get("_class").isNone(), is(true)); assertThat(slice.get("value").get("_class").isNone(), is(true)); } @@ -128,11 +128,11 @@ public void nestedObjectListWithoutTypeInformation() { NestedObject input = new NestedObject(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHint) + if (!useTypeHints) assertThat(slice.get("_class").isNone(), is(true)); NestedObject output = vpack.deserialize(slice, NestedObject.class); @@ -149,11 +149,11 @@ public void nestedObjectMapWithoutTypeInformation() { NestedObject input = new NestedObject(); input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHint) { + if (!useTypeHints) { assertThat(slice.get("_class").isNone(), is(true)); assertThat(slice.get("value").get("_class").isNone(), is(true)); } @@ -174,12 +174,12 @@ public void nestedGenericOfCollectionWithoutTypeInformation() { NestedGeneric> input = new NestedGeneric<>(); input.value = Arrays.asList("a", "b", "c"); - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isArray(), is(true)); - if (!useTypeHint) + if (!useTypeHints) assertThat(slice.get("_class").isNone(), is(true)); NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); @@ -196,12 +196,12 @@ public void nestedGenericOfMapWithoutTypeInformation() { NestedGeneric> input = new NestedGeneric<>(); input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHint) { + if (!useTypeHints) { assertThat(slice.get("_class").isNone(), is(true)); assertThat(slice.get("value").get("_class").isNone(), is(true)); } @@ -221,12 +221,12 @@ public void nestedGenericOfObjectWithoutTypeInformation() { NestedGeneric input = new NestedGeneric<>(); input.value = map; - final VPack vpack = new VPack.Builder().useTypeHint(useTypeHint).build(); + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); final VPackSlice slice = vpack.serialize(input); assertThat(slice.isObject(), is(true)); assertThat(slice.get("value").isObject(), is(true)); - if (!useTypeHint) { + if (!useTypeHints) { assertThat(slice.get("_class").isNone(), is(true)); assertThat(slice.get("value").get("_class").isNone(), is(true)); } From 2b9adb5ee6a331633b64d319c71c7e1af5cc8683 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 15:06:20 +0200 Subject: [PATCH 4/7] arrays tests without type hint --- .../velocypack/VPackWithoutTypeHintTest.java | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java index 23f9bd0..93ef1a8 100644 --- a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java @@ -46,13 +46,36 @@ public VPackWithoutTypeHintTest(final boolean useTypeHints) { this.useTypeHints = useTypeHints; } + public static class NestedArray { + public String[] value; + } + + @Test + public void nestedArrayWithoutTypeInformation() { + NestedArray input = new NestedArray(); + input.value = new String[]{"a", "b", "c"}; + + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHints) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedArray output = vpack.deserialize(slice, NestedArray.class); + assertThat(output.value, instanceOf(String[].class)); + + assertThat(output.value, equalTo(input.value)); + } + public static class NestedIterable { public Iterable value; } @Test public void nestedIterableWithoutTypeInformation() { - NestedCollection input = new NestedCollection(); + NestedIterable input = new NestedIterable(); input.value = Arrays.asList("a", "b", "c"); final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); @@ -169,6 +192,44 @@ public static class NestedGeneric { public T value; } + @Test + public void nestedGenericOfArrayWithoutTypeInformation() { + NestedGeneric input = new NestedGeneric<>(); + input.value = new String[]{"a", "b", "c"}; + + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHints) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(Arrays.asList(input.value))); + } + + @Test + public void nestedGenericOfIterableWithoutTypeInformation() { + NestedGeneric> input = new NestedGeneric<>(); + input.value = Arrays.asList("a", "b", "c"); + + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); + final VPackSlice slice = vpack.serialize(input); + + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHints) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedGeneric output = vpack.deserialize(slice, NestedGeneric.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(output.value, equalTo(input.value)); + } + @Test public void nestedGenericOfCollectionWithoutTypeInformation() { NestedGeneric> input = new NestedGeneric<>(); From 8f22da67315851822725555b24d98447a439eb6a Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 15:58:19 +0200 Subject: [PATCH 5/7] deserialization of iterable, arrays and maps without type hint --- src/main/java/com/arangodb/velocypack/VPack.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/arangodb/velocypack/VPack.java b/src/main/java/com/arangodb/velocypack/VPack.java index b2128f4..83c55a0 100644 --- a/src/main/java/com/arangodb/velocypack/VPack.java +++ b/src/main/java/com/arangodb/velocypack/VPack.java @@ -952,6 +952,12 @@ private void addValue( } else if (shouldAddTypeHint(type, value, fieldInfo)) { addValue(name, value.getClass(), value, builder, fieldInfo, Collections.singletonMap(typeKey, value.getClass().getName())); + } else if (value instanceof Iterable) { + serializeIterable(name, value, builder, null); + } else if (value instanceof Map) { + serializeMap(name, value, builder, String.class, additionalFields); + } else if (value.getClass().isArray()) { + serializeArray(name, value, builder, null); } else { serializeObject(name, value, builder, additionalFields); } From 3681139f1aa1495f901de6bdcb327c1ff339d36d Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 16:27:16 +0200 Subject: [PATCH 6/7] nestedObjectArrayWithoutTypeInformation test --- .../velocypack/VPackWithoutTypeHintTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java index 93ef1a8..aa3846a 100644 --- a/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java +++ b/src/test/java/com/arangodb/velocypack/VPackWithoutTypeHintTest.java @@ -164,6 +164,24 @@ public void nestedObjectListWithoutTypeInformation() { assertThat(output.value, equalTo(input.value)); } + @Test + public void nestedObjectArrayWithoutTypeInformation() { + NestedObject input = new NestedObject(); + input.value = new String[]{"a", "b", "c"}; + + final VPack vpack = new VPack.Builder().useTypeHints(useTypeHints).build(); + final VPackSlice slice = vpack.serialize(input); + assertThat(slice.isObject(), is(true)); + assertThat(slice.get("value").isArray(), is(true)); + if (!useTypeHints) + assertThat(slice.get("_class").isNone(), is(true)); + + NestedObject output = vpack.deserialize(slice, NestedObject.class); + assertThat(output.value, instanceOf(List.class)); + + assertThat(((List) output.value).toArray(), equalTo(input.value)); + } + @Test public void nestedObjectMapWithoutTypeInformation() { Map map = new HashMap<>(); From dee1da33945e41aebed4593153436e442efafb8b Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 27 Jul 2020 17:11:02 +0200 Subject: [PATCH 7/7] added useTypeHints to VPackSetupContext --- src/main/java/com/arangodb/velocypack/VPack.java | 6 ++++-- .../java/com/arangodb/velocypack/VPackSetupContext.java | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/arangodb/velocypack/VPack.java b/src/main/java/com/arangodb/velocypack/VPack.java index 83c55a0..929b52d 100644 --- a/src/main/java/com/arangodb/velocypack/VPack.java +++ b/src/main/java/com/arangodb/velocypack/VPack.java @@ -323,7 +323,8 @@ public Builder registerKeyMapAdapter(final Type type, final VPackKeyMapAdapter C annotationFieldFilter( final VPackAnnotationFieldFilter fieldFilter); C annotationFieldNaming( - final Class type, - final VPackAnnotationFieldNaming fieldNaming); + final Class type, + final VPackAnnotationFieldNaming fieldNaming); C registerKeyMapAdapter(final Type type, final VPackKeyMapAdapter adapter); @@ -69,4 +69,8 @@ C annotationFieldNaming( C registerModules(VPackModule... modules); + C typeKey(final String typeKey); + + C useTypeHints(final boolean useTypeHints); + }