Merge pull request #437 from aguibert/108-backports
Version 1.0.8 backports
diff --git a/etc/checkstyle.xml b/etc/checkstyle.xml
index 766b1b6..9c180fb 100644
--- a/etc/checkstyle.xml
+++ b/etc/checkstyle.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
@@ -78,8 +78,6 @@
<module name="SuppressWarningsFilter"/>
<module name="TreeWalker">
- <property name="cacheFile" value="${checkstyle.cache.file}"/>
-
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
@@ -91,8 +89,8 @@
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
- <property name="allowUndeclaredRTE" value="true"/>
- <property name="allowMissingPropertyJavadoc" value="true"/>
+ <property name="allowMissingReturnTag" value="true"/>
+ <property name="allowMissingParamTags" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
@@ -121,7 +119,7 @@
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="ImportOrder">
- <property name="groups" value="java, javax, org.eclipse.yasson"/>
+ <property name="groups" value="java, jakarta, javax, org.eclipse.yasson"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
diff --git a/pom.xml b/pom.xml
index 2ec825b..cee815d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -506,7 +506,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
- <version>8.18</version>
+ <version>8.29</version>
<exclusions>
<exclusion>
<groupId>com.sun</groupId>
diff --git a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
index 57948a4..280a1e5 100644
--- a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
+++ b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -137,7 +137,6 @@
* @param customization with component info
* @return serializer optional
*/
- @SuppressWarnings("unchecked")
public Optional<SerializerBinding<?>> getSerializerBinding(Type propertyRuntimeType,
ComponentBoundCustomization customization) {
@@ -154,7 +153,6 @@
* @param customization customization with component info
* @return serializer optional
*/
- @SuppressWarnings("unchecked")
public Optional<DeserializerBinding<?>> getDeserializerBinding(Type propertyRuntimeType,
ComponentBoundCustomization customization) {
if (customization == null || customization.getDeserializerBinding() == null) {
@@ -196,12 +194,46 @@
}
private <T extends AbstractComponentBinding> Optional<T> searchComponentBinding(Type runtimeType, Function<ComponentBindings, T> supplier) {
- for (ComponentBindings componentBindings : userComponents.values()) {
- final T component = supplier.apply(componentBindings);
- if (component != null && matches(runtimeType, componentBindings.getBindingType())) {
- return Optional.of(component);
+ // First check if there is an exact match
+ ComponentBindings binding = userComponents.get(runtimeType);
+ if (binding != null) {
+ Optional<T> match = getMatchingBinding(runtimeType, binding, supplier);
+ if (match.isPresent()) {
+ return match;
}
}
+
+ if (runtimeType instanceof Class) {
+ Class<?> runtimeClass = (Class<?>) runtimeType;
+ // Check if any interfaces have a match
+ for (Class<?> ifc : runtimeClass.getInterfaces()) {
+ ComponentBindings ifcBinding = userComponents.get(ifc);
+ if (ifcBinding != null) {
+ Optional<T> match = getMatchingBinding(ifc, ifcBinding, supplier);
+ if (match.isPresent()) {
+ return match;
+ }
+ }
+ }
+
+ // check if the superclass has a match
+ Class<?> superClass = runtimeClass.getSuperclass();
+ if (superClass != null && superClass != Object.class) {
+ Optional<T> superBinding = searchComponentBinding(superClass, supplier);
+ if (superBinding.isPresent()) {
+ return superBinding;
+ }
+ }
+ }
+
+ return Optional.empty();
+ }
+
+ private <T> Optional<T> getMatchingBinding(Type runtimeType, ComponentBindings binding, Function<ComponentBindings, T> supplier) {
+ final T component = supplier.apply(binding);
+ if (component != null && matches(runtimeType, binding.getBindingType())) {
+ return Optional.of(component);
+ }
return Optional.empty();
}
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/DefaultSerializers.java b/src/main/java/org/eclipse/yasson/internal/serializer/DefaultSerializers.java
index 9f2fd22..a12273a 100644
--- a/src/main/java/org/eclipse/yasson/internal/serializer/DefaultSerializers.java
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/DefaultSerializers.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -16,6 +16,7 @@
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
+import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
@@ -118,6 +119,8 @@
new SerializerProviderWrapper(OptionalIntTypeSerializer::new, OptionalIntTypeDeserializer::new));
serializers.put(OptionalLong.class,
new SerializerProviderWrapper(OptionalLongTypeSerializer::new, OptionalLongTypeDeserializer::new));
+ serializers.put(Path.class,
+ new SerializerProviderWrapper(PathTypeSerializer::new, PathTypeDeserializer::new));
serializers.put(Short.class, new SerializerProviderWrapper(ShortTypeSerializer::new, ShortTypeDeserializer::new));
serializers.put(Short.TYPE, new SerializerProviderWrapper(ShortTypeSerializer::new, ShortTypeDeserializer::new));
serializers.put(String.class, new SerializerProviderWrapper(StringTypeSerializer::new, StringTypeDeserializer::new));
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/MapDeserializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/MapDeserializer.java
index b277223..51b0269 100644
--- a/src/main/java/org/eclipse/yasson/internal/serializer/MapDeserializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/MapDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -16,8 +16,12 @@
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
+import java.util.NavigableMap;
import java.util.SortedMap;
import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import javax.json.bind.serializer.JsonbDeserializer;
import javax.json.stream.JsonParser;
@@ -48,7 +52,6 @@
*
* @param builder {@link DeserializerBuilder} used to build this instance
*/
- @SuppressWarnings({"unchecked", "rawtypes"})
protected MapDeserializer(DeserializerBuilder builder) {
super(builder);
mapValueRuntimeType = getRuntimeType() instanceof ParameterizedType
@@ -67,6 +70,13 @@
}
private Map getMapImpl(Class ifcType, DeserializerBuilder builder) {
+ if (ConcurrentMap.class.isAssignableFrom(ifcType)) {
+ if (SortedMap.class.isAssignableFrom(ifcType) || NavigableMap.class.isAssignableFrom(ifcType)) {
+ return new ConcurrentSkipListMap<>();
+ } else {
+ return new ConcurrentHashMap<>();
+ }
+ }
// SortedMap, NavigableMap
if (SortedMap.class.isAssignableFrom(ifcType)) {
Class<?> defaultMapImplType = builder.getJsonbContext().getConfigProperties().getDefaultMapImplType();
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeDeserializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeDeserializer.java
new file mode 100644
index 0000000..87d231a
--- /dev/null
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeDeserializer.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 IBM and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.internal.serializer;
+
+import java.lang.reflect.Type;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.eclipse.yasson.internal.Unmarshaller;
+import org.eclipse.yasson.internal.model.customization.Customization;
+
+public class PathTypeDeserializer extends AbstractValueTypeDeserializer<Path> {
+ public PathTypeDeserializer(Customization customization) {
+ super(Path.class, customization);
+ }
+
+ @Override
+ protected Path deserialize(String jsonValue, Unmarshaller unmarshaller, Type rtType) {
+ return Paths.get(jsonValue);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeSerializer.java
new file mode 100644
index 0000000..491ca13
--- /dev/null
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/PathTypeSerializer.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 IBM and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.internal.serializer;
+
+import java.nio.file.Path;
+
+import javax.json.stream.JsonGenerator;
+
+import org.eclipse.yasson.internal.Marshaller;
+import org.eclipse.yasson.internal.model.customization.Customization;
+
+public class PathTypeSerializer extends AbstractValueTypeSerializer<Path> {
+ public PathTypeSerializer(Customization customization) {
+ super(customization);
+ }
+
+ @Override
+ protected void serialize(Path obj, JsonGenerator generator, Marshaller marshaller) {
+ generator.write(obj.toString());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeDeserializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeDeserializer.java
index d73ba0e..2756fbd 100644
--- a/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeDeserializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeSerializer.java
index 4c2b9f4..1d4ba39 100644
--- a/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeSerializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/serializer/ZoneIdTypeSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java
index 25871c0..f4ac39d 100644
--- a/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,15 +12,36 @@
package org.eclipse.yasson.defaultmapping.collections;
-import org.junit.jupiter.api.*;
-import static org.junit.jupiter.api.Assertions.*;
import static org.eclipse.yasson.Jsonbs.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.math.BigDecimal;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import org.eclipse.yasson.TestTypeToken;
import org.eclipse.yasson.defaultmapping.generics.model.Circle;
-
-import java.math.BigDecimal;
-import java.util.*;
+import org.junit.jupiter.api.Test;
/**
* Default mapping arrays/collections/enums tests.
@@ -255,4 +276,50 @@
assertEquals("abc", result.get("first"));
assertEquals("def", result.get("second"));
}
+
+ public static class ConcurrentMapContainer {
+ public ConcurrentMap<String, String> concurrentMap;
+ public ConcurrentHashMap<String,String> concurrentHashMap;
+ public ConcurrentNavigableMap<String, String> concurrentNavigableMap;
+ public ConcurrentSkipListMap<String, String> concurrentSkipListMap;
+ }
+
+ @Test
+ public void testConcurrentMaps() {
+ // ConcurrentMap
+ ConcurrentMapContainer c = new ConcurrentMapContainer();
+ c.concurrentMap = new ConcurrentHashMap<String, String>();
+ c.concurrentMap.put("foo", "fooVal");
+ c.concurrentMap.put("bar", "barVal");
+ String expectedJson = "{\"concurrentMap\":{\"bar\":\"barVal\",\"foo\":\"fooVal\"}}";
+ assertEquals(expectedJson, defaultJsonb.toJson(c));
+ assertEquals(c.concurrentMap, defaultJsonb.fromJson(expectedJson, ConcurrentMapContainer.class).concurrentMap);
+
+ // ConcurrentHashMap
+ c = new ConcurrentMapContainer();
+ c.concurrentHashMap = new ConcurrentHashMap<String, String>();
+ c.concurrentHashMap.put("foo", "fooVal2");
+ c.concurrentHashMap.put("bar", "barVal2");
+ expectedJson = "{\"concurrentHashMap\":{\"bar\":\"barVal2\",\"foo\":\"fooVal2\"}}";
+ assertEquals(expectedJson, defaultJsonb.toJson(c));
+ assertEquals(c.concurrentHashMap, defaultJsonb.fromJson(expectedJson, ConcurrentMapContainer.class).concurrentHashMap);
+
+ // ConcurrentNavigableMap
+ c = new ConcurrentMapContainer();
+ c.concurrentNavigableMap = new ConcurrentSkipListMap<String, String>();
+ c.concurrentNavigableMap.put("foo", "fooVal3");
+ c.concurrentNavigableMap.put("bar", "barVal3");
+ expectedJson = "{\"concurrentNavigableMap\":{\"bar\":\"barVal3\",\"foo\":\"fooVal3\"}}";
+ assertEquals(expectedJson, defaultJsonb.toJson(c));
+ assertEquals(c.concurrentNavigableMap, defaultJsonb.fromJson(expectedJson, ConcurrentMapContainer.class).concurrentNavigableMap);
+
+ // ConcurrentSkipListMap
+ c = new ConcurrentMapContainer();
+ c.concurrentSkipListMap = new ConcurrentSkipListMap<String, String>();
+ c.concurrentSkipListMap.put("foo", "fooVal4");
+ c.concurrentSkipListMap.put("bar", "barVal4");
+ expectedJson = "{\"concurrentSkipListMap\":{\"bar\":\"barVal4\",\"foo\":\"fooVal4\"}}";
+ assertEquals(expectedJson, defaultJsonb.toJson(c));
+ assertEquals(c.concurrentSkipListMap, defaultJsonb.fromJson(expectedJson, ConcurrentMapContainer.class).concurrentSkipListMap);
+ }
}
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java
index 6002377..9a2211a 100644
--- a/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/typeConvertors/DefaultSerializersTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/typeConvertors/DefaultSerializersTest.java
index 20a4f83..74475e4 100644
--- a/src/test/java/org/eclipse/yasson/defaultmapping/typeConvertors/DefaultSerializersTest.java
+++ b/src/test/java/org/eclipse/yasson/defaultmapping/typeConvertors/DefaultSerializersTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -13,6 +13,7 @@
package org.eclipse.yasson.defaultmapping.typeConvertors;
import org.junit.jupiter.api.*;
+
import static org.junit.jupiter.api.Assertions.*;
import static org.eclipse.yasson.Jsonbs.*;
@@ -24,6 +25,9 @@
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbConfig;
import javax.json.bind.config.BinaryDataStrategy;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Base64;
import java.util.UUID;
@@ -108,7 +112,7 @@
result = jsonb.fromJson(base64UrlEncodedJson, ByteArrayWrapper.class);
assertArrayEquals(array, result.array);
}
-
+
@Test
public void testUUID() {
UUID uuid = UUID.randomUUID();
@@ -116,4 +120,23 @@
UUID result = defaultJsonb.fromJson(json, UUID.class);
assertEquals(uuid, result);
}
+
+ @Test
+ public void serializeObjectWithPth() {
+
+ Path expectedPath = Paths.get("/tmp/hello/me.txt");
+ String expectedPathString = expectedPath.toString().replace("\\", "\\\\");
+ String expectedJson = "{\"path\":\"" + expectedPathString + "\"}";
+ final ObjectWithPath objectWithPath = new ObjectWithPath();
+ objectWithPath.path = expectedPath;
+ final String s = defaultJsonb.toJson(objectWithPath);
+ assertEquals(expectedJson, s);
+
+ ObjectWithPath actualObject = defaultJsonb.fromJson(expectedJson, ObjectWithPath.class);
+ assertEquals(expectedPath, actualObject.path);
+ }
+
+ public static class ObjectWithPath {
+ public Path path;
+ }
}
diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
index 8336d2f..b35f184 100644
--- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
+++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,11 +12,13 @@
package org.eclipse.yasson.serializers;
-import org.junit.jupiter.api.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.eclipse.yasson.Jsonbs.*;
-
import static java.util.Collections.singletonMap;
+import static org.eclipse.yasson.Jsonbs.defaultJsonb;
+import static org.eclipse.yasson.Jsonbs.nullableJsonb;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import java.io.StringReader;
import java.lang.reflect.Type;
@@ -39,6 +41,9 @@
import javax.json.bind.config.PropertyOrderStrategy;
import javax.json.bind.serializer.DeserializationContext;
import javax.json.bind.serializer.JsonbDeserializer;
+import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.bind.serializer.SerializationContext;
+import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonParser;
import org.eclipse.yasson.TestTypeToken;
@@ -64,6 +69,7 @@
import org.eclipse.yasson.serializers.model.SimpleContainer;
import org.eclipse.yasson.serializers.model.StringWrapper;
import org.eclipse.yasson.serializers.model.SupertypeSerializerPojo;
+import org.junit.jupiter.api.Test;
/**
* @author Roman Grigoriadi
@@ -514,4 +520,81 @@
crateInner.crateInnerBigDec = BigDecimal.TEN;
return crateInner;
}
+
+ public static class Foo { }
+
+ public static class Bar extends Foo { }
+
+ public static class Baz extends Bar { }
+
+ public static class FooSerializer implements JsonbSerializer<Foo> {
+ public void serialize(Foo obj, JsonGenerator generator, SerializationContext ctx) {
+ generator.write("foo");
+ }
+ }
+
+ public static class BazSerializer implements JsonbSerializer<Baz> {
+ public void serialize(Baz obj, JsonGenerator generator, SerializationContext ctx) {
+ generator.write("baz");
+ }
+ }
+
+ /**
+ * Test for issue: https://github.com/quarkusio/quarkus/issues/8925
+ * Ensure that if multiple customizations (serializer, deserializer, or adapter) are applied
+ * for different types in the same class hierarchy, we use the customization for the most
+ * specific type in the class hierarchy.
+ */
+ @Test
+ public void testSerializerMatching() {
+ Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
+ .withSerializers(new FooSerializer(), new BazSerializer()));
+ assertEquals("\"foo\"", jsonb.toJson(new Foo()));
+ // Since 'Bar' does not have its own serializer, it should use
+ // the next serializer in the tree (FooSerializer)
+ assertEquals("\"foo\"", jsonb.toJson(new Bar()));
+ assertEquals("\"baz\"", jsonb.toJson(new Baz()));
+ }
+
+ public static interface One { }
+ public static interface Two { }
+ public static interface Three { }
+
+ public static class OneTwo implements One, Two { }
+ public static class OneTwoThree implements One, Two, Three { }
+
+ public static class OneSerializer implements JsonbSerializer<One> {
+ public void serialize(One obj, JsonGenerator generator, SerializationContext ctx) {
+ generator.write("one");
+ }
+ }
+
+ public static class TwoSerializer implements JsonbSerializer<Two> {
+ public void serialize(Two obj, JsonGenerator generator, SerializationContext ctx) {
+ generator.write("two");
+ }
+ }
+
+ public static class ThreeSerializer implements JsonbSerializer<Three> {
+ public void serialize(Three obj, JsonGenerator generator, SerializationContext ctx) {
+ generator.write("three");
+ }
+ }
+
+ @Test
+ public void testSerializerMatchingInterfaces01() {
+ Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
+ .withSerializers(new OneSerializer(), new TwoSerializer(), new ThreeSerializer()));
+ assertEquals("\"one\"", jsonb.toJson(new OneTwo()));
+ assertEquals("\"one\"", jsonb.toJson(new OneTwoThree()));
+ }
+
+ @Test
+ public void testSerializerMatchingInterfaces02() {
+ Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
+ .withSerializers(new ThreeSerializer(), new TwoSerializer()));
+ assertEquals("\"two\"", jsonb.toJson(new OneTwo()));
+ assertEquals("\"two\"", jsonb.toJson(new OneTwoThree()));
+ }
+
}