From 444d92929be3d32a2c4ef829dd77c51ef681d199 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 7 Oct 2023 23:29:30 +0200 Subject: [PATCH 01/68] [#617]User defined deserializer always should be used before standard ones --- .../DeserializationModelCreator.java | 19 ++++--- .../yasson/serializers/SerializersTest.java | 12 ++++ .../yasson/serializers/model/Colors.java | 15 +++++ .../serializers/model/ColorsDeserializer.java | 8 +++ .../serializers/model/ColorsSerializer.java | 7 +++ .../EnumWithJsonbPropertyDeserializer.java | 57 +++++++++++++++++++ .../EnumWithJsonbPropertySerializer.java | 48 ++++++++++++++++ 7 files changed, 158 insertions(+), 8 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/Colors.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java index 0ac3f980..6c12822c 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java @@ -152,6 +152,17 @@ private ModelDeserializer deserializerChainInternal(LinkedList models.put(cachedItem, deserializer); return deserializer; } + + ClassCustomization classCustomization = classModel.getClassCustomization(); + Optional> deserializerBinding = userDeserializer(type, + (ComponentBoundCustomization) propertyCustomization); + if (deserializerBinding.isPresent()) { + UserDefinedDeserializer user = new UserDefinedDeserializer(deserializerBinding.get().getJsonbDeserializer(), + JustReturn.instance(), type, classCustomization); + models.put(cachedItem, user); + return user; + } + Optional adapterBinding = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization); if (adapterBinding.isPresent()) { AdapterBinding adapter = adapterBinding.get(); @@ -201,14 +212,6 @@ private ModelDeserializer createObjectDeserializer(LinkedList Class rawType, CachedItem cachedItem) { ClassCustomization classCustomization = classModel.getClassCustomization(); - Optional> deserializerBinding = userDeserializer(type, - (ComponentBoundCustomization) propertyCustomization); - if (deserializerBinding.isPresent()) { - UserDefinedDeserializer user = new UserDefinedDeserializer(deserializerBinding.get().getJsonbDeserializer(), - JustReturn.instance(), type, classCustomization); - models.put(cachedItem, user); - return user; - } JsonbCreator creator = classCustomization.getCreator(); boolean hasCreator = creator != null; List params = hasCreator ? creatorParamsList(creator) : Collections.emptyList(); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index db0efdf1..04caa8d0 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -51,6 +51,7 @@ import org.eclipse.yasson.serializers.model.Author; import org.eclipse.yasson.serializers.model.Box; import org.eclipse.yasson.serializers.model.BoxWithAnnotations; +import org.eclipse.yasson.serializers.model.Colors; import org.eclipse.yasson.serializers.model.Containee; import org.eclipse.yasson.serializers.model.Container; import org.eclipse.yasson.serializers.model.Crate; @@ -812,4 +813,15 @@ public void testCustomSerializersInContainer(){ } + @Test + void testCustomSerializersAndDeserializersInEnum(){ + Jsonb jsonb = JsonbBuilder.create(); + + Colors expected = Colors.GREEN; + + String expectedJson = jsonb.toJson(expected); + + assertEquals(expected, jsonb.fromJson(expectedJson, Colors.class)); + } + } diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Colors.java b/src/test/java/org/eclipse/yasson/serializers/model/Colors.java new file mode 100644 index 00000000..154d09f0 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/Colors.java @@ -0,0 +1,15 @@ +package org.eclipse.yasson.serializers.model; + +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.json.bind.annotation.JsonbTypeDeserializer; +import jakarta.json.bind.annotation.JsonbTypeSerializer; + +@JsonbTypeSerializer(ColorsSerializer.class) +@JsonbTypeDeserializer(ColorsDeserializer.class) +public enum Colors { + @JsonbProperty("Red") + RED, + @JsonbProperty("Green") + GREEN +} + diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java new file mode 100644 index 00000000..201d61bf --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java @@ -0,0 +1,8 @@ +package org.eclipse.yasson.serializers.model; + +public class ColorsDeserializer extends EnumWithJsonbPropertyDeserializer { + + public ColorsDeserializer() { + super(); + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java new file mode 100644 index 00000000..a8dd33b5 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java @@ -0,0 +1,7 @@ +package org.eclipse.yasson.serializers.model; + +public class ColorsSerializer extends EnumWithJsonbPropertySerializer { + public ColorsSerializer() { + super(); + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java new file mode 100644 index 00000000..f26df2a1 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java @@ -0,0 +1,57 @@ +package org.eclipse.yasson.serializers.model; + +import static java.util.Optional.ofNullable; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.json.bind.serializer.DeserializationContext; +import jakarta.json.bind.serializer.JsonbDeserializer; +import jakarta.json.stream.JsonParser; + +public class EnumWithJsonbPropertyDeserializer> implements JsonbDeserializer { + + private final Map jsonToJavaMapping; + + public EnumWithJsonbPropertyDeserializer() { + super(); + + Class enumType = getEnumType(); + jsonToJavaMapping = new HashMap<>(); + + Stream.of(enumType.getEnumConstants()).forEach(constant -> { + final String asString; + try { + asString = ofNullable( + constant.getClass() + .getDeclaredField(constant.name()) + .getAnnotation(JsonbProperty.class)) + .map(JsonbProperty::value) + .orElseGet(constant::name); + } catch (final NoSuchFieldException e) { + throw new IllegalArgumentException(e); + } + jsonToJavaMapping.put(asString, constant); + }); + } + + private Class getEnumType() { + return Class.class.cast(ParameterizedType.class.cast( + getClass().getGenericSuperclass()) + .getActualTypeArguments()[0]); + } + + @Override + public E deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + String key = parser.getString(); + + assert key != null; + + return ofNullable(jsonToJavaMapping.get(key)) + .orElseThrow(() -> new IllegalArgumentException("Unknown enum value: '" + key + "'")); + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java new file mode 100644 index 00000000..5ef34776 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java @@ -0,0 +1,48 @@ +package org.eclipse.yasson.serializers.model; + +import static java.util.Optional.ofNullable; + +import java.lang.reflect.ParameterizedType; +import java.util.EnumMap; +import java.util.stream.Stream; + +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.json.bind.serializer.JsonbSerializer; +import jakarta.json.bind.serializer.SerializationContext; +import jakarta.json.stream.JsonGenerator; + +public class EnumWithJsonbPropertySerializer> implements JsonbSerializer { + private final EnumMap javaToJsonMapping; + + public EnumWithJsonbPropertySerializer() { + super(); + + Class enumType = getEnumType(); + javaToJsonMapping = new EnumMap<>(enumType); + + Stream.of(enumType.getEnumConstants()).forEach(constant -> { + final String asString; + try { + asString = ofNullable( + constant.getClass() + .getDeclaredField(constant.name()) + .getAnnotation(JsonbProperty.class)) + .map(JsonbProperty::value) + .orElseGet(constant::name); + } catch (final NoSuchFieldException e) { + throw new IllegalArgumentException(e); + } + javaToJsonMapping.put(constant, asString); + }); + } + + private Class getEnumType() { + return Class.class.cast(ParameterizedType.class.cast( + getClass().getGenericSuperclass()) + .getActualTypeArguments()[0]); + } + + @Override public void serialize(E obj, JsonGenerator generator, SerializationContext ctx) { + generator.write(javaToJsonMapping.get(obj)); + } +} From 170103e00418c943c58184ff316bf61655a09fe0 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 8 Oct 2023 17:04:55 +0200 Subject: [PATCH 02/68] [#617]Test for enum with registered adapter It is working fine right now, but it also could be tested. Signed-off-by: Anton Pinsky --- .../eclipse/yasson/adapters/AdaptersTest.java | 50 +++++++++++----- .../model/EnumWithJsonbPropertyAdapter.java | 57 +++++++++++++++++++ .../yasson/adapters/model/Vegetables.java | 13 +++++ .../adapters/model/VegetablesAdapter.java | 7 +++ 4 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java create mode 100644 src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java create mode 100644 src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index d3db6c94..4df7df42 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -12,21 +12,12 @@ package org.eclipse.yasson.adapters; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.eclipse.yasson.Jsonbs.*; +import static java.util.Collections.unmodifiableMap; -import org.eclipse.yasson.TestTypeToken; -import org.eclipse.yasson.adapters.model.*; -import org.eclipse.yasson.defaultmapping.generics.model.ScalarValueWrapper; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; -import jakarta.json.Json; -import jakarta.json.JsonObject; -import jakarta.json.JsonString; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; -import jakarta.json.bind.JsonbConfig; -import jakarta.json.bind.adapter.JsonbAdapter; import java.lang.reflect.Type; import java.math.BigDecimal; import java.time.Instant; @@ -38,7 +29,27 @@ import java.util.Optional; import java.util.UUID; -import static java.util.Collections.unmodifiableMap; +import org.eclipse.yasson.TestTypeToken; +import org.eclipse.yasson.adapters.model.AdaptedPojo; +import org.eclipse.yasson.adapters.model.Author; +import org.eclipse.yasson.adapters.model.Box; +import org.eclipse.yasson.adapters.model.BoxToCrateCompatibleGenericsAdapter; +import org.eclipse.yasson.adapters.model.BoxToCratePropagatedIntegerStringAdapter; +import org.eclipse.yasson.adapters.model.Crate; +import org.eclipse.yasson.adapters.model.GenericBox; +import org.eclipse.yasson.adapters.model.IntegerListToStringAdapter; +import org.eclipse.yasson.adapters.model.JsonObjectPojo; +import org.eclipse.yasson.adapters.model.ReturnNullAdapter; +import org.eclipse.yasson.adapters.model.SupertypeAdapterPojo; +import org.eclipse.yasson.adapters.model.UUIDContainer; +import org.eclipse.yasson.adapters.model.Vegetables; +import org.eclipse.yasson.defaultmapping.generics.model.ScalarValueWrapper; +import org.junit.jupiter.api.Test; + +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; +import jakarta.json.bind.adapter.JsonbAdapter; /** * Tests adapters to behave correctly. @@ -583,4 +594,15 @@ public void testAdaptedRootType() { assertEquals("\"HELLO WORLD!\"", jsonb.toJson(original)); assertEquals(original, jsonb.fromJson("\"HELLO WORLD!\"", String.class)); } + + @Test + void testCustomAdapterInEnum(){ + Jsonb jsonb = JsonbBuilder.create(); + + Vegetables expected = Vegetables.TOMATO; + + String expectedJson = jsonb.toJson(expected); + + assertEquals(expected, jsonb.fromJson(expectedJson, Vegetables.class)); + } } diff --git a/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java new file mode 100644 index 00000000..5a190d3b --- /dev/null +++ b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java @@ -0,0 +1,57 @@ +package org.eclipse.yasson.adapters.model; + +import static java.util.Optional.ofNullable; + +import java.lang.reflect.ParameterizedType; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +import jakarta.json.bind.adapter.JsonbAdapter; +import jakarta.json.bind.annotation.JsonbProperty; + +public class EnumWithJsonbPropertyAdapter> implements JsonbAdapter { + private final Map jsonToJavaMapping = new HashMap<>(); + private final EnumMap javaToJsonMapping; + + public EnumWithJsonbPropertyAdapter() { + super(); + + Class enumType = getEnumType(); + javaToJsonMapping = new EnumMap<>(enumType); + + Stream.of(enumType.getEnumConstants()).forEach(constant -> { + final String asString; + try { + asString = ofNullable( + constant.getClass() + .getDeclaredField(constant.name()) + .getAnnotation(JsonbProperty.class)) + .map(JsonbProperty::value) + .orElseGet(constant::name); + } catch (final NoSuchFieldException e) { + throw new IllegalArgumentException(e); + } + javaToJsonMapping.put(constant, asString); + jsonToJavaMapping.put(asString, constant); + }); + } + + private Class getEnumType() { + return Class.class.cast(ParameterizedType.class.cast( + getClass().getGenericSuperclass()) + .getActualTypeArguments()[0]); + } + + @Override + public String adaptToJson(final E obj) { + return javaToJsonMapping.get(obj); + } + + @Override + public E adaptFromJson(final String obj) { + return ofNullable(jsonToJavaMapping.get(obj)) + .orElseThrow(() -> new IllegalArgumentException("Unknown enum value: '" + obj + "'")); + } +} diff --git a/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java b/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java new file mode 100644 index 00000000..a3a2c736 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java @@ -0,0 +1,13 @@ +package org.eclipse.yasson.adapters.model; + +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.json.bind.annotation.JsonbTypeAdapter; + +@JsonbTypeAdapter(VegetablesAdapter.class) +public enum Vegetables { + @JsonbProperty("Tomato") + TOMATO, + @JsonbProperty("Cucumber") + CUCUMBER +} + diff --git a/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java new file mode 100644 index 00000000..e2c9f378 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java @@ -0,0 +1,7 @@ +package org.eclipse.yasson.adapters.model; + +public class VegetablesAdapter extends EnumWithJsonbPropertyAdapter { + public VegetablesAdapter() { + super(); + } +} From 80611725f31478fb053f5ad55a22cb950e1f28ca Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 8 Oct 2023 22:25:49 +0200 Subject: [PATCH 03/68] [#616]Suggested solution for recognizing @JsonbProperty annotation on enum constants Signed-off-by: Anton Pinsky --- .../DeserializationModelCreator.java | 2 +- .../deserializer/types/EnumDeserializer.java | 46 +++++++++++++--- .../types/TypeDeserializerBuilder.java | 13 +++-- .../deserializer/types/TypeDeserializers.java | 10 ++-- .../serializer/types/EnumSerializer.java | 54 ++++++++++++++----- .../yasson/serializers/SerializersTest.java | 23 ++++++++ .../yasson/serializers/model/Cars.java | 22 ++++++++ 7 files changed, 140 insertions(+), 30 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/Cars.java diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java index 6c12822c..5039e0a6 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java @@ -503,7 +503,7 @@ private ModelDeserializer typeDeserializer(Class rawType, ModelDeserializer delegate, Set events) { return TypeDeserializers - .getTypeDeserializer(rawType, customization, jsonbContext.getConfigProperties(), delegate, events); + .getTypeDeserializer(rawType, customization, jsonbContext, delegate, events); } private Class resolveImplClass(Class rawType, Customization customization) { diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java index f32aeb86..ec1e28d3 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java @@ -13,21 +13,51 @@ package org.eclipse.yasson.internal.deserializer.types; import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; import org.eclipse.yasson.internal.DeserializationContextImpl; +import org.eclipse.yasson.internal.model.ClassModel; +import org.eclipse.yasson.internal.model.PropertyModel; /** * Deserializer of the {@link Enum}. */ class EnumDeserializer extends TypeDeserializer { - EnumDeserializer(TypeDeserializerBuilder builder) { - super(builder); - } + private final Map> nameToConstantMap; - @SuppressWarnings("unchecked") - @Override - Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { - return Enum.valueOf((Class) rType, value); - } + EnumDeserializer(TypeDeserializerBuilder builder) { + super(builder); + + nameToConstantMap = createNameToConstantMap(builder); + } + + private static > Map createNameToConstantMap(TypeDeserializerBuilder builder) { + Map nameToConstantMap = null; + Class clazz = builder.getClazz(); + + if (clazz.isEnum()) { + try { + @SuppressWarnings("unchecked") + Class enumClazz = (Class) clazz; + nameToConstantMap = new HashMap<>(); + ClassModel classModel = builder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); + + for (E enumConstant : enumClazz.getEnumConstants()) { + PropertyModel model = classModel.getPropertyModel(enumConstant.name()); + nameToConstantMap.put(model.getReadName(), enumConstant); + } + } catch (ClassCastException classCastException) { + throw new IllegalArgumentException("EnumDeserializer can only be used with Enum types"); + } + } + return nameToConstantMap; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { + return nameToConstantMap == null ? Enum.valueOf((Class) rType, value) : nameToConstantMap.get(value); + } } diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java index c15ee2fc..2b866d6b 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java @@ -15,6 +15,7 @@ import java.util.Objects; import org.eclipse.yasson.internal.JsonbConfigProperties; +import org.eclipse.yasson.internal.JsonbContext; import org.eclipse.yasson.internal.deserializer.ModelDeserializer; import org.eclipse.yasson.internal.model.customization.ClassCustomization; import org.eclipse.yasson.internal.model.customization.Customization; @@ -23,16 +24,16 @@ class TypeDeserializerBuilder { private final Class clazz; private final Customization customization; - private final JsonbConfigProperties configProperties; + private final JsonbContext jsonbContext; private final ModelDeserializer delegate; TypeDeserializerBuilder(Class clazz, Customization customization, - JsonbConfigProperties configProperties, + JsonbContext jsonbContext, ModelDeserializer delegate) { this.clazz = Objects.requireNonNull(clazz); this.customization = customization == null ? ClassCustomization.empty() : customization; - this.configProperties = configProperties; + this.jsonbContext = jsonbContext; this.delegate = Objects.requireNonNull(delegate); } @@ -41,7 +42,11 @@ public Class getClazz() { } public JsonbConfigProperties getConfigProperties() { - return configProperties; + return jsonbContext.getConfigProperties(); + } + + public JsonbContext getJsonbContext() { + return jsonbContext; } public ModelDeserializer getDelegate() { diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java index de1f7e00..1e72c3d1 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java @@ -51,7 +51,7 @@ import jakarta.json.bind.JsonbException; import jakarta.json.stream.JsonParser; -import org.eclipse.yasson.internal.JsonbConfigProperties; +import org.eclipse.yasson.internal.JsonbContext; import org.eclipse.yasson.internal.deserializer.JustReturn; import org.eclipse.yasson.internal.deserializer.ModelDeserializer; import org.eclipse.yasson.internal.deserializer.NullCheckDeserializer; @@ -135,14 +135,14 @@ private TypeDeserializers() { * * @param clazz type to create deserializer for * @param customization type customization - * @param properties config properties + * @param jsonbContext config properties * @param delegate delegate to be called by the created deserializer * @param events expected parser events at the beginning when deserializing the type * @return type deserializer */ public static ModelDeserializer getTypeDeserializer(Class clazz, Customization customization, - JsonbConfigProperties properties, + JsonbContext jsonbContext, ModelDeserializer delegate, Set events) { JsonParser.Event[] eventArray = events.toArray(new JsonParser.Event[0]); @@ -150,7 +150,7 @@ public static ModelDeserializer getTypeDeserializer(Class clazz, Class optionalType = OPTIONAL_TYPES.get(clazz); TypeDeserializerBuilder builder = new TypeDeserializerBuilder(optionalType, customization, - properties, + jsonbContext, JustReturn.instance()); ValueExtractor valueExtractor = new ValueExtractor(DESERIALIZERS.get(optionalType).apply(builder)); PositionChecker positionChecker = new PositionChecker(valueExtractor, clazz, eventArray); @@ -165,7 +165,7 @@ public static ModelDeserializer getTypeDeserializer(Class clazz, } } - TypeDeserializerBuilder builder = new TypeDeserializerBuilder(clazz, customization, properties, delegate); + TypeDeserializerBuilder builder = new TypeDeserializerBuilder(clazz, customization, jsonbContext, delegate); if (DESERIALIZERS.containsKey(clazz)) { ValueExtractor valueExtractor = new ValueExtractor(DESERIALIZERS.get(clazz).apply(builder)); return new NullCheckDeserializer(new PositionChecker(valueExtractor, clazz, eventArray), delegate); diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java index 39b14ae1..e9588420 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java @@ -12,26 +12,56 @@ package org.eclipse.yasson.internal.serializer.types; -import jakarta.json.stream.JsonGenerator; +import java.util.EnumMap; import org.eclipse.yasson.internal.SerializationContextImpl; +import org.eclipse.yasson.internal.model.ClassModel; +import org.eclipse.yasson.internal.model.PropertyModel; + +import jakarta.json.stream.JsonGenerator; /** * Serializer of the {@link Enum} types. */ class EnumSerializer extends TypeSerializer> { - EnumSerializer(TypeSerializerBuilder serializerBuilder) { - super(serializerBuilder); - } + private final EnumMap, String> constantToNameMap; + + EnumSerializer(TypeSerializerBuilder serializerBuilder) { + super(serializerBuilder); + + constantToNameMap = createConstantToNameMap(serializerBuilder); + } + + private static > EnumMap createConstantToNameMap(TypeSerializerBuilder serializerBuilder) { + EnumMap constantToNameMap = null; + Class clazz = serializerBuilder.getClazz(); + + if (clazz.isEnum()) { + try{ + @SuppressWarnings("unchecked") + Class enumClazz = (Class) clazz; + constantToNameMap = new EnumMap<>(enumClazz); + ClassModel classModel = serializerBuilder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); + + for (E enumConstant : enumClazz.getEnumConstants()) { + PropertyModel model = classModel.getPropertyModel(enumConstant.name()); + constantToNameMap.put(enumConstant, model.getWriteName()); + } + } catch (ClassCastException classCastException) { + throw new IllegalArgumentException("EnumSerializer can only be used with Enum types"); + } + } + return constantToNameMap; + } - @Override - void serializeValue(Enum value, JsonGenerator generator, SerializationContextImpl context) { - generator.write(value.name()); - } + @Override + void serializeValue(Enum value, JsonGenerator generator, SerializationContextImpl context) { + generator.write(constantToNameMap == null ? value.name() : constantToNameMap.get(value)); + } - @Override - void serializeKey(Enum key, JsonGenerator generator, SerializationContextImpl context) { - generator.writeKey(key.name()); - } + @Override + void serializeKey(Enum key, JsonGenerator generator, SerializationContextImpl context) { + generator.writeKey(constantToNameMap == null ? key.name() : constantToNameMap.get(key)); + } } diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 04caa8d0..1abbdc02 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -51,6 +51,7 @@ import org.eclipse.yasson.serializers.model.Author; import org.eclipse.yasson.serializers.model.Box; import org.eclipse.yasson.serializers.model.BoxWithAnnotations; +import org.eclipse.yasson.serializers.model.Cars; import org.eclipse.yasson.serializers.model.Colors; import org.eclipse.yasson.serializers.model.Containee; import org.eclipse.yasson.serializers.model.Container; @@ -824,4 +825,26 @@ void testCustomSerializersAndDeserializersInEnum(){ assertEquals(expected, jsonb.fromJson(expectedJson, Colors.class)); } + @Test + void testJsonbPropertyInEnum(){ + Jsonb jsonb = JsonbBuilder.create(); + + Cars expected = Cars.FORD; + + String expectedJson = jsonb.toJson(expected); + + assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + } + + @Test + void testNoJsonbPropertyInEnum(){ + Jsonb jsonb = JsonbBuilder.create(); + + Cars expected = Cars.FIAT; + + String expectedJson = jsonb.toJson(expected); + + assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + } + } diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Cars.java b/src/test/java/org/eclipse/yasson/serializers/model/Cars.java new file mode 100644 index 00000000..3fd5f31c --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/Cars.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; + +import jakarta.json.bind.annotation.JsonbProperty; + +public enum Cars { + @JsonbProperty("Ford") + FORD, + FIAT +} + From 429bf76c5da4eb181c645444374d0f6a4538a87a Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 8 Oct 2023 22:45:09 +0200 Subject: [PATCH 04/68] [#617]Forgot the copyright Signed-off-by: Anton Pinsky --- .../adapters/model/EnumWithJsonbPropertyAdapter.java | 12 ++++++++++++ .../eclipse/yasson/adapters/model/Vegetables.java | 12 ++++++++++++ .../yasson/adapters/model/VegetablesAdapter.java | 12 ++++++++++++ .../org/eclipse/yasson/serializers/model/Colors.java | 12 ++++++++++++ .../yasson/serializers/model/ColorsDeserializer.java | 12 ++++++++++++ .../yasson/serializers/model/ColorsSerializer.java | 12 ++++++++++++ .../model/EnumWithJsonbPropertyDeserializer.java | 12 ++++++++++++ .../model/EnumWithJsonbPropertySerializer.java | 12 ++++++++++++ 8 files changed, 96 insertions(+) diff --git a/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java index 5a190d3b..6197b78c 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.adapters.model; import static java.util.Optional.ofNullable; diff --git a/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java b/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java index a3a2c736..1b76ad99 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/Vegetables.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.adapters.model; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java index e2c9f378..19754ca1 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/VegetablesAdapter.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.adapters.model; public class VegetablesAdapter extends EnumWithJsonbPropertyAdapter { diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Colors.java b/src/test/java/org/eclipse/yasson/serializers/model/Colors.java index 154d09f0..5eb21739 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/Colors.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/Colors.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java index 201d61bf..5d874699 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/ColorsDeserializer.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; public class ColorsDeserializer extends EnumWithJsonbPropertyDeserializer { diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java index a8dd33b5..dcdd9cbf 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/ColorsSerializer.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; public class ColorsSerializer extends EnumWithJsonbPropertySerializer { diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java index f26df2a1..caf0342c 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; import static java.util.Optional.ofNullable; diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java index 5ef34776..5204bd49 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; import static java.util.Optional.ofNullable; From 97f708f6a3f9e653a1ca6a58e7085b74a4582e64 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 8 Oct 2023 23:12:05 +0200 Subject: [PATCH 05/68] [#617]Small refactoring of the creators Signed-off-by: Anton Pinsky --- .../deserializer/DeserializationModelCreator.java | 9 +++------ .../serializer/SerializationModelCreator.java | 15 +++++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java index 5039e0a6..b381c1b9 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java @@ -191,7 +191,7 @@ private ModelDeserializer deserializerChainInternal(LinkedList return typeDeserializer; } if (Collection.class.isAssignableFrom(rawType)) { - return createCollectionDeserializer(cachedItem, rawType, chain, propertyCustomization); + return createCollectionDeserializer(cachedItem, rawType, chain); } else if (Map.class.isAssignableFrom(rawType)) { return createMapDeserializer(cachedItem, rawType, chain, propertyCustomization); } else if (rawType.isArray()) { @@ -201,13 +201,11 @@ private ModelDeserializer deserializerChainInternal(LinkedList } else if (Optional.class.isAssignableFrom(rawType)) { return createOptionalDeserializer(chain, type, propertyCustomization, cachedItem); } else { - return createObjectDeserializer(chain, type, propertyCustomization, classModel, rawType, cachedItem); + return createObjectDeserializer(chain, classModel, rawType, cachedItem); } } private ModelDeserializer createObjectDeserializer(LinkedList chain, - Type type, - Customization propertyCustomization, ClassModel classModel, Class rawType, CachedItem cachedItem) { @@ -265,8 +263,7 @@ private ModelDeserializer createObjectDeserializer(LinkedList private ModelDeserializer createCollectionDeserializer(CachedItem cachedItem, Class rawType, - LinkedList chain, - Customization propertyCustomization) { + LinkedList chain) { Type type = cachedItem.type; Type colType = type instanceof ParameterizedType ? ((ParameterizedType) type).getActualTypeArguments()[0] diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java index 315fe4a8..fe830e04 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java @@ -317,6 +317,13 @@ private ModelSerializer createArraySerializer(LinkedList chain, Class raw, Customization propertyCustomization) { Class arrayComponent = raw.getComponentType(); + return createArraySerializerInternal(chain, raw, propertyCustomization, arrayComponent); + } + + private ModelSerializer createArraySerializerInternal(LinkedList chain, + Class raw, + Customization propertyCustomization, + Class arrayComponent) { ModelSerializer modelSerializer = memberSerializer(chain, arrayComponent, propertyCustomization, false); ModelSerializer arraySerializer = ArraySerializer.create(raw, jsonbContext, modelSerializer); KeyWriter keyWriter = new KeyWriter(arraySerializer); @@ -329,11 +336,7 @@ private ModelSerializer createGenericArraySerializer(LinkedList chain, Customization propertyCustomization) { Class raw = ReflectionUtils.getRawType(type); Class component = ReflectionUtils.getRawType(((GenericArrayType) type).getGenericComponentType()); - ModelSerializer modelSerializer = memberSerializer(chain, component, propertyCustomization, false); - ModelSerializer arraySerializer = ArraySerializer.create(raw, jsonbContext, modelSerializer); - KeyWriter keyWriter = new KeyWriter(arraySerializer); - NullVisibilitySwitcher nullVisibilitySwitcher = new NullVisibilitySwitcher(true, keyWriter); - return new NullSerializer(nullVisibilitySwitcher, propertyCustomization, jsonbContext); + return createArraySerializerInternal(chain, raw, propertyCustomization, component); } private ModelSerializer createOptionalSerializer(LinkedList chain, @@ -373,7 +376,7 @@ private ModelSerializer memberSerializer(LinkedList chain, } ModelSerializer typeSerializer = TypeSerializers.getTypeSerializer(chain, rawType, customization, jsonbContext, key); if (typeSerializer == null) { - //Final classes dont have any child classes. It is safe to assume that there will be instance of that specific class. + //Final classes don't have any child classes. It is safe to assume that there will be instance of that specific class. boolean isFinal = Modifier.isFinal(rawType.getModifiers()); if (isFinal || Collection.class.isAssignableFrom(rawType) From f0eff31f59288a681d8bffe102a6ffa7dc94b1a2 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 18:00:33 +0200 Subject: [PATCH 06/68] [#617]Extra copyright changes Signed-off-by: Anton Pinsky --- .../yasson/internal/ReflectionUtils.java | 3 +-- .../defaultmapping/generics/GenericsTest.java | 22 +++++++++---------- ...eVariableWithCollectionAttributeClass.java | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java index a5eac94c..87cfa4f5 100644 --- a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java +++ b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -47,7 +47,6 @@ private ReflectionUtils() { /** * Get raw type by type. * Only for ParametrizedTypes, GenericArrayTypes and Classes. - * * Empty optional is returned if raw type cannot be resolved. * * @param type Type to get class information from, not null. diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index b193521c..c3ba5d45 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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,6 +12,12 @@ package org.eclipse.yasson.defaultmapping.generics; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Field; import java.lang.reflect.Type; import java.math.BigDecimal; import java.text.ParseException; @@ -26,11 +32,6 @@ import java.util.Optional; import java.util.TimeZone; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; -import jakarta.json.bind.JsonbConfig; -import java.lang.reflect.Field; -import java.util.Collection; import org.eclipse.yasson.TestTypeToken; import org.eclipse.yasson.adapters.model.GenericBox; import org.eclipse.yasson.defaultmapping.generics.model.AnotherGenericTestClass; @@ -44,6 +45,7 @@ import org.eclipse.yasson.defaultmapping.generics.model.GenericArrayClass; import org.eclipse.yasson.defaultmapping.generics.model.GenericTestClass; import org.eclipse.yasson.defaultmapping.generics.model.GenericWithUnboundedWildcardClass; +import org.eclipse.yasson.defaultmapping.generics.model.LowerBoundTypeVariableWithCollectionAttributeClass; import org.eclipse.yasson.defaultmapping.generics.model.MultiLevelExtendedGenericTestClass; import org.eclipse.yasson.defaultmapping.generics.model.MultipleBoundsContainer; import org.eclipse.yasson.defaultmapping.generics.model.MyCyclicGenericClass; @@ -55,11 +57,9 @@ import org.eclipse.yasson.serializers.model.Crate; import org.junit.jupiter.api.Test; -import static org.eclipse.yasson.Jsonbs.defaultJsonb; -import org.eclipse.yasson.defaultmapping.generics.model.LowerBoundTypeVariableWithCollectionAttributeClass; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; /** * This class contains JSONB default mapping generics tests. diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/LowerBoundTypeVariableWithCollectionAttributeClass.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/LowerBoundTypeVariableWithCollectionAttributeClass.java index 3b7198a6..7f58792a 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/LowerBoundTypeVariableWithCollectionAttributeClass.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/LowerBoundTypeVariableWithCollectionAttributeClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 From 819d38f9aebfabb1873215626573d3cfb0a0a152 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 19:44:48 +0200 Subject: [PATCH 07/68] [#624]Tests for the deserializer as a lambda expression Signed-off-by: Anton Pinsky --- .../yasson/serializers/SerializersTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 1abbdc02..3f361c4d 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -107,6 +107,18 @@ public void serialize(Box box, JsonGenerator out, SerializationContext ctx) { out.write(box.secondBoxStr); out.writeEnd(); } + }; + + private static final JsonbSerializer BOX_ARRAY_SERIALIZER_CHAINED_AS_LAMBDA = (box, out, ctx) -> out.writeStartArray() + .write(box.boxStr) + .write(box.secondBoxStr) + .writeEnd(); + + private static final JsonbSerializer BOX_ARRAY_SERIALIZER_AS_LAMBDA = (box, out, ctx) -> { + out.writeStartArray(); + out.write(box.boxStr); + out.write(box.secondBoxStr); + out.writeEnd(); }; @Test @@ -801,6 +813,30 @@ public void testBoxToArray() { assertThat(jsonb.toJson(box), is(expected)); } + @Test + public void testBoxToArrayChainedWithLambda() { + JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED_AS_LAMBDA); + assertThrows(JsonbException.class, () -> JsonbBuilder.create(cfg)); + /*Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; + + assertThat(jsonb.toJson(box), is(expected));*/ + } + + @Test + public void testBoxToArrayWithLambda() { + JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_AS_LAMBDA); + assertThrows(JsonbException.class, () -> JsonbBuilder.create(cfg)); + /*Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; + + assertThat(jsonb.toJson(box), is(expected));*/ + } + @Test public void testCustomSerializersInContainer(){ Jsonb jsonb = JsonbBuilder.create(); From 22612314c80d2c5e1dcc4ebf12ea31a004e34841 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 20:03:45 +0200 Subject: [PATCH 08/68] [#617]Even more copyright changes Signed-off-by: Anton Pinsky --- .../yasson/internal/deserializer/types/EnumDeserializer.java | 2 +- .../internal/deserializer/types/TypeDeserializerBuilder.java | 2 +- .../yasson/internal/deserializer/types/TypeDeserializers.java | 2 +- .../yasson/internal/serializer/types/EnumSerializer.java | 2 +- src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java index ec1e28d3..087cac39 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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/deserializer/types/TypeDeserializerBuilder.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java index 2b866d6b..bc049cfd 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializerBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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/deserializer/types/TypeDeserializers.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java index 1e72c3d1..787ba5df 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/TypeDeserializers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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/types/EnumSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java index e9588420..f01f52c1 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 4df7df42..3f4d1dab 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 From c63bdf6fd5b2d9104d40a65e2bba8d8068c82680 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 20:45:28 +0200 Subject: [PATCH 09/68] [#617]Checkstyle chnages Signed-off-by: Anton Pinsky --- .../deserializer/types/EnumDeserializer.java | 70 +++++++++---------- .../customization/StrategiesProvider.java | 1 - .../serializer/SerializationModelCreator.java | 6 +- .../serializer/types/EnumSerializer.java | 67 +++++++++--------- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java index 087cac39..1c8426c7 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/EnumDeserializer.java @@ -25,39 +25,39 @@ */ class EnumDeserializer extends TypeDeserializer { - private final Map> nameToConstantMap; - - EnumDeserializer(TypeDeserializerBuilder builder) { - super(builder); - - nameToConstantMap = createNameToConstantMap(builder); - } - - private static > Map createNameToConstantMap(TypeDeserializerBuilder builder) { - Map nameToConstantMap = null; - Class clazz = builder.getClazz(); - - if (clazz.isEnum()) { - try { - @SuppressWarnings("unchecked") - Class enumClazz = (Class) clazz; - nameToConstantMap = new HashMap<>(); - ClassModel classModel = builder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); - - for (E enumConstant : enumClazz.getEnumConstants()) { - PropertyModel model = classModel.getPropertyModel(enumConstant.name()); - nameToConstantMap.put(model.getReadName(), enumConstant); - } - } catch (ClassCastException classCastException) { - throw new IllegalArgumentException("EnumDeserializer can only be used with Enum types"); - } - } - return nameToConstantMap; - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - @Override - Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { - return nameToConstantMap == null ? Enum.valueOf((Class) rType, value) : nameToConstantMap.get(value); - } + private final Map> nameToConstantMap; + + EnumDeserializer(TypeDeserializerBuilder builder) { + super(builder); + + nameToConstantMap = createNameToConstantMap(builder); + } + + private static > Map createNameToConstantMap(TypeDeserializerBuilder builder) { + Map nameToConstantMap = null; + Class clazz = builder.getClazz(); + + if (clazz.isEnum()) { + try { + @SuppressWarnings("unchecked") + Class enumClazz = (Class) clazz; + nameToConstantMap = new HashMap<>(); + ClassModel classModel = builder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); + + for (E enumConstant : enumClazz.getEnumConstants()) { + PropertyModel model = classModel.getPropertyModel(enumConstant.name()); + nameToConstantMap.put(model.getReadName(), enumConstant); + } + } catch (ClassCastException classCastException) { + throw new IllegalArgumentException("EnumDeserializer can only be used with Enum types"); + } + } + return nameToConstantMap; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + Object deserializeStringValue(String value, DeserializationContextImpl context, Type rType) { + return nameToConstantMap == null ? Enum.valueOf((Class) rType, value) : nameToConstantMap.get(value); + } } diff --git a/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java b/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java index 4855daad..006e82fa 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java +++ b/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java @@ -25,7 +25,6 @@ import org.eclipse.yasson.internal.properties.Messages; import static java.util.Comparator.comparing; - import static jakarta.json.bind.config.PropertyNamingStrategy.CASE_INSENSITIVE; import static jakarta.json.bind.config.PropertyNamingStrategy.IDENTITY; import static jakarta.json.bind.config.PropertyNamingStrategy.LOWER_CASE_WITH_DASHES; diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java index fe830e04..b23e3071 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java @@ -321,9 +321,9 @@ private ModelSerializer createArraySerializer(LinkedList chain, } private ModelSerializer createArraySerializerInternal(LinkedList chain, - Class raw, - Customization propertyCustomization, - Class arrayComponent) { + Class raw, + Customization propertyCustomization, + Class arrayComponent) { ModelSerializer modelSerializer = memberSerializer(chain, arrayComponent, propertyCustomization, false); ModelSerializer arraySerializer = ArraySerializer.create(raw, jsonbContext, modelSerializer); KeyWriter keyWriter = new KeyWriter(arraySerializer); diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java index f01f52c1..fbaf7df3 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/types/EnumSerializer.java @@ -14,54 +14,55 @@ import java.util.EnumMap; +import jakarta.json.stream.JsonGenerator; + import org.eclipse.yasson.internal.SerializationContextImpl; import org.eclipse.yasson.internal.model.ClassModel; import org.eclipse.yasson.internal.model.PropertyModel; -import jakarta.json.stream.JsonGenerator; /** * Serializer of the {@link Enum} types. */ class EnumSerializer extends TypeSerializer> { - private final EnumMap, String> constantToNameMap; + private final EnumMap, String> constantToNameMap; - EnumSerializer(TypeSerializerBuilder serializerBuilder) { - super(serializerBuilder); + EnumSerializer(TypeSerializerBuilder serializerBuilder) { + super(serializerBuilder); - constantToNameMap = createConstantToNameMap(serializerBuilder); - } + constantToNameMap = createConstantToNameMap(serializerBuilder); + } - private static > EnumMap createConstantToNameMap(TypeSerializerBuilder serializerBuilder) { - EnumMap constantToNameMap = null; - Class clazz = serializerBuilder.getClazz(); + private static > EnumMap createConstantToNameMap(TypeSerializerBuilder serializerBuilder) { + EnumMap constantToNameMap = null; + Class clazz = serializerBuilder.getClazz(); - if (clazz.isEnum()) { - try{ - @SuppressWarnings("unchecked") - Class enumClazz = (Class) clazz; - constantToNameMap = new EnumMap<>(enumClazz); - ClassModel classModel = serializerBuilder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); + if (clazz.isEnum()) { + try { + @SuppressWarnings("unchecked") + Class enumClazz = (Class) clazz; + constantToNameMap = new EnumMap<>(enumClazz); + ClassModel classModel = serializerBuilder.getJsonbContext().getMappingContext().getOrCreateClassModel(clazz); - for (E enumConstant : enumClazz.getEnumConstants()) { - PropertyModel model = classModel.getPropertyModel(enumConstant.name()); - constantToNameMap.put(enumConstant, model.getWriteName()); - } - } catch (ClassCastException classCastException) { - throw new IllegalArgumentException("EnumSerializer can only be used with Enum types"); - } - } - return constantToNameMap; - } + for (E enumConstant : enumClazz.getEnumConstants()) { + PropertyModel model = classModel.getPropertyModel(enumConstant.name()); + constantToNameMap.put(enumConstant, model.getWriteName()); + } + } catch (ClassCastException classCastException) { + throw new IllegalArgumentException("EnumSerializer can only be used with Enum types"); + } + } + return constantToNameMap; + } - @Override - void serializeValue(Enum value, JsonGenerator generator, SerializationContextImpl context) { - generator.write(constantToNameMap == null ? value.name() : constantToNameMap.get(value)); - } + @Override + void serializeValue(Enum value, JsonGenerator generator, SerializationContextImpl context) { + generator.write(constantToNameMap == null ? value.name() : constantToNameMap.get(value)); + } - @Override - void serializeKey(Enum key, JsonGenerator generator, SerializationContextImpl context) { - generator.writeKey(constantToNameMap == null ? key.name() : constantToNameMap.get(key)); - } + @Override + void serializeKey(Enum key, JsonGenerator generator, SerializationContextImpl context) { + generator.writeKey(constantToNameMap == null ? key.name() : constantToNameMap.get(key)); + } } From c92319fe1b5703902564cec7f9cced8edcb31d1a Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 21:14:48 +0200 Subject: [PATCH 10/68] [#617]And once again the copyright Signed-off-by: Anton Pinsky --- .../yasson/serializers/SerializersTest.java | 58 ++++++++++--------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 3f361c4d..7b33eb9e 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -81,6 +81,7 @@ 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.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.hamcrest.CoreMatchers.is; @@ -121,6 +122,7 @@ public void serialize(Box box, JsonGenerator out, SerializationContext ctx) { out.writeEnd(); }; + @Test public void testClassLevelAnnotation() { Crate crate = new Crate(); @@ -173,46 +175,50 @@ public void testClassLevelAnnotationOnGenericRoot() { * Tests JSONB deserialization of arbitrary type invoked from a Deserializer. */ @Test - public void testDeserializerDeserializationByType() { + public void testDeserializerDeserializationByType() throws Exception { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializer()); - Jsonb jsonb = JsonbBuilder.create(config); + try (Jsonb jsonb = JsonbBuilder.create(config)) { - Box box = createPojoWithDates(); + Box box = createPojoWithDates(); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; - Box result = jsonb.fromJson(expected, Box.class); + Box result = jsonb.fromJson(expected, Box.class); - //deserialized by deserializationContext.deserialize(Class c) - assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + //deserialized by deserializationContext.deserialize(Class c) + assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); - assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); + assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); + assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); - //set by deserializer statically - assertEquals(new BigDecimal("123"), result.crate.crateBigDec); - assertEquals("abc", result.crate.crateStr); + //set by deserializer statically + assertEquals(new BigDecimal("123"), result.crate.crateBigDec); + assertEquals("abc", result.crate.crateStr); + } } /** * Tests JSONB serialization of arbitrary type invoked from a Serializer. */ @Test - public void testSerializerSerializationOfType() { + public void testSerializerSerializationOfType() throws Exception { JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - Jsonb jsonb = JsonbBuilder.create(config); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box pojo = createPojo(); - - assertEquals(expected, jsonb.toJson(pojo)); - - Box result = jsonb.fromJson(expected, Box.class); - assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); - //result.crate.crateStr is mapped to crate_str by jsonb property - assertNull(result.crate.crateStr); - assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + try (Jsonb jsonb = JsonbBuilder.create(config)) { + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box pojo = createPojo(); + + assertEquals(expected, jsonb.toJson(pojo)); + + Box result = jsonb.fromJson(expected, Box.class); + assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); + //result.crate.crateStr is mapped to crate_str by jsonb property + assertNull(result.crate.crateStr); + assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + } } @Test From efc574e98d987bc499ab5c88971fbacc2d471524 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 21:24:05 +0200 Subject: [PATCH 11/68] Revert "[#617]And once again the copyright" This reverts commit c92319fe1b5703902564cec7f9cced8edcb31d1a. --- .../yasson/serializers/SerializersTest.java | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 7b33eb9e..3f361c4d 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -81,7 +81,6 @@ 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.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.hamcrest.CoreMatchers.is; @@ -122,7 +121,6 @@ public void serialize(Box box, JsonGenerator out, SerializationContext ctx) { out.writeEnd(); }; - @Test public void testClassLevelAnnotation() { Crate crate = new Crate(); @@ -175,50 +173,46 @@ public void testClassLevelAnnotationOnGenericRoot() { * Tests JSONB deserialization of arbitrary type invoked from a Deserializer. */ @Test - public void testDeserializerDeserializationByType() throws Exception { + public void testDeserializerDeserializationByType() { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + Jsonb jsonb = JsonbBuilder.create(config); - Box box = createPojoWithDates(); + Box box = createPojoWithDates(); - String expected = - "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; + String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; - Box result = jsonb.fromJson(expected, Box.class); + Box result = jsonb.fromJson(expected, Box.class); - //deserialized by deserializationContext.deserialize(Class c) - assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + //deserialized by deserializationContext.deserialize(Class c) + assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); - assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); + assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); + assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); - //set by deserializer statically - assertEquals(new BigDecimal("123"), result.crate.crateBigDec); - assertEquals("abc", result.crate.crateStr); - } + //set by deserializer statically + assertEquals(new BigDecimal("123"), result.crate.crateBigDec); + assertEquals("abc", result.crate.crateStr); } /** * Tests JSONB serialization of arbitrary type invoked from a Serializer. */ @Test - public void testSerializerSerializationOfType() throws Exception { + public void testSerializerSerializationOfType() { JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { - String expected = - "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box pojo = createPojo(); - - assertEquals(expected, jsonb.toJson(pojo)); - - Box result = jsonb.fromJson(expected, Box.class); - assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); - //result.crate.crateStr is mapped to crate_str by jsonb property - assertNull(result.crate.crateStr); - assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - } + Jsonb jsonb = JsonbBuilder.create(config); + String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box pojo = createPojo(); + + assertEquals(expected, jsonb.toJson(pojo)); + + Box result = jsonb.fromJson(expected, Box.class); + assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); + //result.crate.crateStr is mapped to crate_str by jsonb property + assertNull(result.crate.crateStr); + assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); } @Test From 87fce398519c6e4520ab0fe7745ee84e0ef4bdb1 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 21:26:07 +0200 Subject: [PATCH 12/68] [#617]And once again the copyright Signed-off-by: Anton Pinsky --- .../yasson/internal/model/customization/StrategiesProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java b/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java index 006e82fa..eeb7738d 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java +++ b/src/main/java/org/eclipse/yasson/internal/model/customization/StrategiesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 From 4e5a0a1962124044691ffb9b8579d4df2b92eba3 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Thu, 12 Oct 2023 22:54:58 +0200 Subject: [PATCH 13/68] [#617]Put every call of JsonbBuilder.create in the tests into try-with-resources. Signed-off-by: Anton Pinsky --- .../eclipse/yasson/adapters/AdaptersTest.java | 443 +++++++------ .../defaultmapping/generics/GenericsTest.java | 61 +- .../yasson/serializers/SerializersTest.java | 583 ++++++++++-------- 3 files changed, 583 insertions(+), 504 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 3f4d1dab..ba1f9e43 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -84,19 +84,20 @@ public Box adaptFromJson(Crate crate) { } } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo pojo = new AdaptedPojo(); - Box box = new Box(); - box.setBoxStrField("BoxStr"); - box.setBoxIntegerField(10); - pojo.box = box; - String json = jsonb.toJson(pojo); - assertEquals("{\"box\":{\"crateIntField\":11,\"crateStrField\":\"crateAdaptedBoxStr\"}}", json); - - AdaptedPojo result = jsonb.fromJson("{\"box\":{\"crateIntField\":10,\"crateStrField\":\"CrateStr\"}}", AdaptedPojo.class); - assertEquals(Integer.valueOf(11), result.box.getBoxIntegerField()); - assertEquals("boxAdaptedCrateStr", result.box.getBoxStrField()); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo pojo = new AdaptedPojo(); + Box box = new Box(); + box.setBoxStrField("BoxStr"); + box.setBoxIntegerField(10); + pojo.box = box; + String json = jsonb.toJson(pojo); + assertEquals("{\"box\":{\"crateIntField\":11,\"crateStrField\":\"crateAdaptedBoxStr\"}}", json); + + AdaptedPojo result = jsonb.fromJson("{\"box\":{\"crateIntField\":10,\"crateStrField\":\"CrateStr\"}}", AdaptedPojo.class); + assertEquals(Integer.valueOf(11), result.box.getBoxIntegerField()); + assertEquals("boxAdaptedCrateStr", result.box.getBoxStrField()); + } } @Test @@ -114,126 +115,141 @@ public Integer adaptFromJson(String s) { } } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo pojo = new AdaptedPojo(); - pojo.intField = 11; - String json = jsonb.toJson(pojo); - assertEquals("{\"intField\":\"11\"}", json); + AdaptedPojo pojo = new AdaptedPojo(); + pojo.intField = 11; + String json = jsonb.toJson(pojo); + assertEquals("{\"intField\":\"11\"}", json); - AdaptedPojo result = jsonb.fromJson("{\"intField\":\"10\"}", AdaptedPojo.class); - assertEquals(Integer.valueOf(10), result.intField); + AdaptedPojo result = jsonb.fromJson("{\"intField\":\"10\"}", AdaptedPojo.class); + assertEquals(Integer.valueOf(10), result.intField); + } } @Test public void testGenericAdapter() throws Exception { JsonbAdapter[] adapters = {new BoxToCrateCompatibleGenericsAdapter() { }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo pojo = new AdaptedPojo<>(); - pojo.strField = "POJO_STRING"; - pojo.intBox = new GenericBox<>("INT_BOX_STR", 11); - pojo.tBox = new GenericBox<>("T_BOX_STR", 110); - - String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>(){}.getType()); - assertEquals("{\"intBox\":{\"adaptedT\":11,\"crateStrField\":\"INT_BOX_STR\"}," + - "\"strField\":\"POJO_STRING\"," + - "\"tBox\":{\"adaptedT\":110,\"crateStrField\":\"T_BOX_STR\"}}", marshalledJson); - - String toUnmarshall = "{\"intBox\":{\"crateStrField\":\"Box3\",\"adaptedT\":33}," + - "\"tBox\":{\"crateStrField\":\"tGenBoxCrateStr\",\"adaptedT\":22}," + - "\"strField\":\"POJO_STRING\"," + - "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>(){}.getType()); - assertEquals("POJO_STRING", result.strField); - assertEquals("Box3", result.intBox.getStrField()); - assertEquals(33, result.intBox.getX()); - assertEquals("tGenBoxCrateStr", result.tBox.getStrField()); - assertEquals(22, result.tBox.getX()); - assertEquals("strBoxStr", result.strBox.getStrField()); - assertEquals("44", result.strBox.getX()); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo pojo = new AdaptedPojo<>(); + pojo.strField = "POJO_STRING"; + pojo.intBox = new GenericBox<>("INT_BOX_STR", 11); + pojo.tBox = new GenericBox<>("T_BOX_STR", 110); + + String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>() { + }.getType()); + assertEquals("{\"intBox\":{\"adaptedT\":11,\"crateStrField\":\"INT_BOX_STR\"}," + + "\"strField\":\"POJO_STRING\"," + + "\"tBox\":{\"adaptedT\":110,\"crateStrField\":\"T_BOX_STR\"}}", marshalledJson); + + String toUnmarshall = "{\"intBox\":{\"crateStrField\":\"Box3\",\"adaptedT\":33}," + + "\"tBox\":{\"crateStrField\":\"tGenBoxCrateStr\",\"adaptedT\":22}," + + "\"strField\":\"POJO_STRING\"," + + "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { + }.getType()); + assertEquals("POJO_STRING", result.strField); + assertEquals("Box3", result.intBox.getStrField()); + assertEquals(33, result.intBox.getX()); + assertEquals("tGenBoxCrateStr", result.tBox.getStrField()); + assertEquals(22, result.tBox.getX()); + assertEquals("strBoxStr", result.strBox.getStrField()); + assertEquals("44", result.strBox.getX()); + } } @Test public void testPropagatedTypeArgs() throws Exception { JsonbAdapter[] adapters = {new BoxToCratePropagatedIntegerStringAdapter()}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo pojo = new AdaptedPojo<>(); - pojo.intBox = new GenericBox<>("INT_BOX_STR", 110); - pojo.tBox = new GenericBox<>("T_BOX_STR", 111); - pojo.strBox = new GenericBox<>("STR_BOX_STR", "101"); - - String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>(){}.getType()); - assertEquals("{\"intBox\":{\"adaptedT\":{\"x\":[\"110\"]},\"crateStrField\":\"INT_BOX_STR\"}," + - "\"strBox\":{\"strField\":\"STR_BOX_STR\",\"x\":\"101\"}," + - "\"tBox\":{\"adaptedT\":{\"x\":[\"111\"]},\"crateStrField\":\"T_BOX_STR\"}}", - marshalledJson); - - String toUnmarshall = "{\"intBox\":{\"crateStrField\":\"strCrateStr\",\"adaptedT\":{\"strField\":\"crateBoxStrField\",\"x\":[\"77\"]}}," + - "\"tBox\":{\"crateStrField\":\"tStrCrateStr\",\"adaptedT\":{\"strField\":\"crateBoxStrField\",\"x\":[\"88\"]}}," + - "\"strField\":\"POJO_STRING\"," + - "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; - - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>(){}.getType()); - assertEquals("POJO_STRING", result.strField); - assertEquals("strCrateStr", result.intBox.getStrField()); - assertEquals(77, result.intBox.getX()); - assertEquals("tStrCrateStr", result.tBox.getStrField()); - assertEquals(88, result.tBox.getX()); - assertEquals("strBoxStr", result.strBox.getStrField()); - assertEquals("44", result.strBox.getX()); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo pojo = new AdaptedPojo<>(); + pojo.intBox = new GenericBox<>("INT_BOX_STR", 110); + pojo.tBox = new GenericBox<>("T_BOX_STR", 111); + pojo.strBox = new GenericBox<>("STR_BOX_STR", "101"); + + String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>() { + }.getType()); + assertEquals("{\"intBox\":{\"adaptedT\":{\"x\":[\"110\"]},\"crateStrField\":\"INT_BOX_STR\"}," + + "\"strBox\":{\"strField\":\"STR_BOX_STR\",\"x\":\"101\"}," + + "\"tBox\":{\"adaptedT\":{\"x\":[\"111\"]},\"crateStrField\":\"T_BOX_STR\"}}", + marshalledJson); + + String toUnmarshall = "{\"intBox\":{\"crateStrField\":\"strCrateStr\",\"adaptedT\":{\"strField\":\"crateBoxStrField\",\"x\":[\"77\"]}}," + + "\"tBox\":{\"crateStrField\":\"tStrCrateStr\",\"adaptedT\":{\"strField\":\"crateBoxStrField\",\"x\":[\"88\"]}}," + + "\"strField\":\"POJO_STRING\"," + + "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; + + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { + }.getType()); + assertEquals("POJO_STRING", result.strField); + assertEquals("strCrateStr", result.intBox.getStrField()); + assertEquals(77, result.intBox.getX()); + assertEquals("tStrCrateStr", result.tBox.getStrField()); + assertEquals(88, result.tBox.getX()); + assertEquals("strBoxStr", result.strBox.getStrField()); + assertEquals("44", result.strBox.getX()); + } } @Test public void testStringToGenericCollectionAdapter() throws Exception { JsonbAdapter[] adapters = {new IntegerListToStringAdapter()}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo> pojo = new AdaptedPojo<>(); - pojo.tVar = Arrays.asList(11, 22, 33); - pojo.integerList = Arrays.asList(110, 111, 101); - String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>>(){}.getType()); - assertEquals("{\"integerList\":\"110#111#101\"," + - "\"tVar\":\"11#22#33\"}", marshalledJson); - - String toUnmarshall = "{\"integerList\":\"11#22#33#44\",\"stringList\":[\"first\",\"second\"]," + - "\"tVar\":\"110#111#101\"}"; - - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>>(){}.getType()); - List expectedIntegerList = Arrays.asList(11, 22, 33, 44); - List expectedStringList = Arrays.asList("first", "second"); - List expectedTList = Arrays.asList(110, 111, 101); - - assertEquals(expectedIntegerList, result.integerList); - assertEquals(expectedStringList, result.stringList); - assertEquals(expectedTList, result.tVar); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo> pojo = new AdaptedPojo<>(); + pojo.tVar = Arrays.asList(11, 22, 33); + pojo.integerList = Arrays.asList(110, 111, 101); + String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>>() { + }.getType()); + assertEquals("{\"integerList\":\"110#111#101\"," + + "\"tVar\":\"11#22#33\"}", marshalledJson); + + String toUnmarshall = "{\"integerList\":\"11#22#33#44\",\"stringList\":[\"first\",\"second\"]," + + "\"tVar\":\"110#111#101\"}"; + + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>>() { + }.getType()); + List expectedIntegerList = Arrays.asList(11, 22, 33, 44); + List expectedStringList = Arrays.asList("first", "second"); + List expectedTList = Arrays.asList(110, 111, 101); + + assertEquals(expectedIntegerList, result.integerList); + assertEquals(expectedStringList, result.stringList); + assertEquals(expectedTList, result.tVar); + } } @Test public void testAdaptObjectInCollection() throws Exception { JsonbAdapter[] adapters = {new BoxToCrateCompatibleGenericsAdapter() { }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo pojo = new AdaptedPojo<>(); + AdaptedPojo pojo = new AdaptedPojo<>(); - pojo.tGenericBoxList = new ArrayList<>(); - pojo.tGenericBoxList.add(new GenericBox<>("GEN_BOX_STR_1", 110)); - pojo.tGenericBoxList.add(new GenericBox<>("GEN_BOX_STR_2", 101)); + pojo.tGenericBoxList = new ArrayList<>(); + pojo.tGenericBoxList.add(new GenericBox<>("GEN_BOX_STR_1", 110)); + pojo.tGenericBoxList.add(new GenericBox<>("GEN_BOX_STR_2", 101)); - String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>(){}.getType()); - assertEquals("{\"tGenericBoxList\":[{\"adaptedT\":110,\"crateStrField\":\"GEN_BOX_STR_1\"},{\"adaptedT\":101,\"crateStrField\":\"GEN_BOX_STR_2\"}]}", marshalledJson); + String marshalledJson = jsonb.toJson(pojo, new TestTypeToken>() { + }.getType()); + assertEquals( + "{\"tGenericBoxList\":[{\"adaptedT\":110,\"crateStrField\":\"GEN_BOX_STR_1\"},{\"adaptedT\":101,\"crateStrField\":\"GEN_BOX_STR_2\"}]}", + marshalledJson); - String toUnmarshall = "{\"integerList\":[11,22,33,44],\"stringList\":[\"first\",\"second\"]," + - "\"tGenericBoxList\":[{\"crateStrField\":\"FirstCrate\",\"adaptedT\":11},{\"crateStrField\":\"SecondCrate\",\"adaptedT\":22}]}"; + String toUnmarshall = "{\"integerList\":[11,22,33,44],\"stringList\":[\"first\",\"second\"]," + + "\"tGenericBoxList\":[{\"crateStrField\":\"FirstCrate\",\"adaptedT\":11},{\"crateStrField\":\"SecondCrate\",\"adaptedT\":22}]}"; - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>(){}.getType()); - assertEquals("FirstCrate", result.tGenericBoxList.get(0).getStrField()); - assertEquals("SecondCrate", result.tGenericBoxList.get(1).getStrField()); - assertEquals(Integer.valueOf(11), result.tGenericBoxList.get(0).getX()); - assertEquals(Integer.valueOf(22), result.tGenericBoxList.get(1).getX()); + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { + }.getType()); + assertEquals("FirstCrate", result.tGenericBoxList.get(0).getStrField()); + assertEquals("SecondCrate", result.tGenericBoxList.get(1).getStrField()); + assertEquals(Integer.valueOf(11), result.tGenericBoxList.get(0).getX()); + assertEquals(Integer.valueOf(22), result.tGenericBoxList.get(1).getX()); + } } @Test @@ -262,30 +278,36 @@ public String adaptFromJson(List ints) { } } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - String json = "{\"strValues\":[11,22,33]}"; - final NonGenericPojo object = new NonGenericPojo(); - object.strValues = "11,22,33"; - assertEquals(json, jsonb.toJson(object)); - NonGenericPojo pojo = jsonb.fromJson(json, NonGenericPojo.class); - assertEquals("11,22,33", pojo.strValues); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + String json = "{\"strValues\":[11,22,33]}"; + final NonGenericPojo object = new NonGenericPojo(); + object.strValues = "11,22,33"; + assertEquals(json, jsonb.toJson(object)); + NonGenericPojo pojo = jsonb.fromJson(json, NonGenericPojo.class); + assertEquals("11,22,33", pojo.strValues); + } } @Test public void testMarshallGenericField() throws Exception { JsonbAdapter[] adapters = {new BoxToCratePropagatedIntegerStringAdapter()}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo adaptedPojo = new AdaptedPojo<>(); - adaptedPojo.tBox = new GenericBox<>("tGenBoxStrField", 22); - adaptedPojo.intBox = new GenericBox<>("genBoxStrField", 11); - String json = jsonb.toJson(adaptedPojo, new TestTypeToken>(){}.getType()); - assertEquals("{\"intBox\":{\"adaptedT\":{\"x\":[\"11\"]},\"crateStrField\":\"genBoxStrField\"},\"tBox\":{\"adaptedT\":{\"x\":[\"22\"]},\"crateStrField\":\"tGenBoxStrField\"}}", json); - - AdaptedPojo unmarshalledAdaptedPojo = jsonb.fromJson(json, new TestTypeToken>(){}.getType()); - assertEquals("genBoxStrField", unmarshalledAdaptedPojo.intBox.getStrField()); - assertEquals(Integer.valueOf(11), unmarshalledAdaptedPojo.intBox.getX()); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo adaptedPojo = new AdaptedPojo<>(); + adaptedPojo.tBox = new GenericBox<>("tGenBoxStrField", 22); + adaptedPojo.intBox = new GenericBox<>("genBoxStrField", 11); + String json = jsonb.toJson(adaptedPojo, new TestTypeToken>() { + }.getType()); + assertEquals( + "{\"intBox\":{\"adaptedT\":{\"x\":[\"11\"]},\"crateStrField\":\"genBoxStrField\"},\"tBox\":{\"adaptedT\":{\"x\":[\"22\"]},\"crateStrField\":\"tGenBoxStrField\"}}", + json); + + AdaptedPojo unmarshalledAdaptedPojo = jsonb.fromJson(json, new TestTypeToken>() { + }.getType()); + assertEquals("genBoxStrField", unmarshalledAdaptedPojo.intBox.getStrField()); + assertEquals(Integer.valueOf(11), unmarshalledAdaptedPojo.intBox.getX()); + } } @Test @@ -303,18 +325,21 @@ public List> adaptFromJson(BigDecimal bigDecimal) { return list; } }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo>> intBoxPojo = new AdaptedPojo<>(); - List> intBoxList = new ArrayList<>(); - intBoxList.add(new GenericBox<>("", 11d)); - intBoxPojo.tVar = intBoxList; + AdaptedPojo>> intBoxPojo = new AdaptedPojo<>(); + List> intBoxList = new ArrayList<>(); + intBoxList.add(new GenericBox<>("", 11d)); + intBoxPojo.tVar = intBoxList; - String json = jsonb.toJson(intBoxPojo, new TestTypeToken>>>(){}.getType()); - assertEquals("{\"tVar\":11.0}", json); + String json = jsonb.toJson(intBoxPojo, new TestTypeToken>>>() { + }.getType()); + assertEquals("{\"tVar\":11.0}", json); - AdaptedPojo>> result = jsonb.fromJson(json, new TestTypeToken>>>(){}.getType()); - assertEquals(Double.valueOf(11), result.tVar.get(0).getX()); + AdaptedPojo>> result = jsonb.fromJson(json, new TestTypeToken>>>() { + }.getType()); + assertEquals(Double.valueOf(11), result.tVar.get(0).getX()); + } } @Test @@ -331,15 +356,16 @@ public Box adaptFromJson(Crate crate) { return new Box(crate.getCrateStrField(), crate.getCrateIntField()); } }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - Box pojo = new Box("BOX_STR", 101); - String marshalledJson = jsonb.toJson(pojo); - assertEquals("{\"crateIntField\":101,\"crateStrField\":\"BOX_STR\"}", marshalledJson); + Box pojo = new Box("BOX_STR", 101); + String marshalledJson = jsonb.toJson(pojo); + assertEquals("{\"crateIntField\":101,\"crateStrField\":\"BOX_STR\"}", marshalledJson); - Box result = jsonb.fromJson("{\"crateIntField\":110,\"crateStrField\":\"CRATE_STR\"}", Box.class); - assertEquals("CRATE_STR", result.getBoxStrField()); - assertEquals(Integer.valueOf(110), result.getBoxIntegerField()); + Box result = jsonb.fromJson("{\"crateIntField\":110,\"crateStrField\":\"CRATE_STR\"}", Box.class); + assertEquals("CRATE_STR", result.getBoxStrField()); + assertEquals(Integer.valueOf(110), result.getBoxIntegerField()); + } } @Test @@ -365,19 +391,23 @@ public String adaptToJson(Map obj) throws Exception { return sb.toString(); } }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); - - AdaptedPojo pojo = new AdaptedPojo<>(); - pojo.stringIntegerMap = new HashMap<>(); - pojo.stringIntegerMap.put("first", 11); - pojo.stringIntegerMap.put("second", 22); - pojo.tMap = new HashMap<>(pojo.stringIntegerMap); - String marshalledJson = jsonb.toJson(pojo, new AdaptedPojo(){}.getClass()); - assertEquals("{\"stringIntegerMap\":\"first-11#second-22\",\"tMap\":\"first-11#second-22\"}", marshalledJson); - - AdaptedPojo result = jsonb.fromJson("{\"stringIntegerMap\":\"fake-value\",\"tMap\":\"fake-value\"}", new TestTypeToken>(){}.getType()); - assertEquals(Integer.valueOf(101), result.stringIntegerMap.get("fake")); - assertEquals(Integer.valueOf(101), result.tMap.get("fake")); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + + AdaptedPojo pojo = new AdaptedPojo<>(); + pojo.stringIntegerMap = new HashMap<>(); + pojo.stringIntegerMap.put("first", 11); + pojo.stringIntegerMap.put("second", 22); + pojo.tMap = new HashMap<>(pojo.stringIntegerMap); + String marshalledJson = jsonb.toJson(pojo, new AdaptedPojo() { + }.getClass()); + assertEquals("{\"stringIntegerMap\":\"first-11#second-22\",\"tMap\":\"first-11#second-22\"}", marshalledJson); + + AdaptedPojo result = + jsonb.fromJson("{\"stringIntegerMap\":\"fake-value\",\"tMap\":\"fake-value\"}", new TestTypeToken>() { + }.getType()); + assertEquals(Integer.valueOf(101), result.stringIntegerMap.get("fake")); + assertEquals(Integer.valueOf(101), result.tMap.get("fake")); + } } @Test @@ -396,19 +426,21 @@ public Crate adaptToJson(Map obj) throws Exception { return new Crate(next.getKey(), Integer.parseInt(next.getValue())); } }}; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo pojo = new AdaptedPojo<>(); - pojo.tMap = new HashMap<>(); - pojo.tMap.put("first", "101"); + AdaptedPojo pojo = new AdaptedPojo<>(); + pojo.tMap = new HashMap<>(); + pojo.tMap.put("first", "101"); - TestTypeToken> typeToken = new TestTypeToken>() {}; + TestTypeToken> typeToken = new TestTypeToken>() { + }; - String marshalledJson = jsonb.toJson(pojo, typeToken.getType()); - assertEquals("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", marshalledJson); + String marshalledJson = jsonb.toJson(pojo, typeToken.getType()); + assertEquals("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", marshalledJson); - AdaptedPojo result = jsonb.fromJson("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", typeToken.getType()); - assertEquals("11", result.tMap.get("fake")); + AdaptedPojo result = jsonb.fromJson("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", typeToken.getType()); + assertEquals("11", result.tMap.get("fake")); + } } @Test @@ -439,19 +471,20 @@ public void testAdaptAuthor() { } @Test - public void testAdapterReturningNull() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new ReturnNullAdapter()).withNullValues(true)); + public void testAdapterReturningNull() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new ReturnNullAdapter()).withNullValues(true))) { - ScalarValueWrapper wrapper = new ScalarValueWrapper<>(); - wrapper.setValue(10); - Type type = new TestTypeToken>() { - }.getType(); - String json = jsonb.toJson(wrapper, type); + ScalarValueWrapper wrapper = new ScalarValueWrapper<>(); + wrapper.setValue(10); + Type type = new TestTypeToken>() { + }.getType(); + String json = jsonb.toJson(wrapper, type); - assertEquals("{\"value\":null}", json); + assertEquals("{\"value\":null}", json); - ScalarValueWrapper result = jsonb.fromJson("{\"value\":null}", type); - assertNull(result.getValue()); + ScalarValueWrapper result = jsonb.fromJson("{\"value\":null}", type); + assertNull(result.getValue()); + } } @Test @@ -518,14 +551,15 @@ public Throwable adaptFromJson(Map obj) throws Exception { * adapter for Throwable should still be called. */ @Test - public void testOptionalAdapter() { + public void testOptionalAdapter() throws Exception { ThrowableAdapter adapter = new ThrowableAdapter(); - Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(new JsonbConfig().withAdapters(adapter)).build(); - - PropertyTypeMismatch obj = new PropertyTypeMismatch(); - String json = jsonb.toJson(obj); - assertEquals("{\"error\":{\"message\":\"foo\",\"type\":\"java.lang.RuntimeException\"}}", json); - assertEquals(1, adapter.callCount, "The user-defined ThrowableAdapter should have been called"); + try (Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(new JsonbConfig().withAdapters(adapter)).build()) { + + PropertyTypeMismatch obj = new PropertyTypeMismatch(); + String json = jsonb.toJson(obj); + assertEquals("{\"error\":{\"message\":\"foo\",\"type\":\"java.lang.RuntimeException\"}}", json); + assertEquals(1, adapter.callCount, "The user-defined ThrowableAdapter should have been called"); + } } public static class InstantAdapter implements JsonbAdapter { @@ -551,22 +585,23 @@ public Instant adaptFromJson(String obj) throws Exception { * serialization and deserialization. */ @Test - public void testDifferentAdapters() { + public void testDifferentAdapters() throws Exception { ThrowableAdapter throwableAdapter = new ThrowableAdapter(); InstantAdapter instantAdapter = new InstantAdapter(); - Jsonb jsonb = JsonbBuilder.newBuilder() + try (Jsonb jsonb = JsonbBuilder.newBuilder() .withConfig(new JsonbConfig().withAdapters(throwableAdapter, instantAdapter)) - .build(); - - String json = "{\"error\":\"CUSTOM_VALUE\"}"; - PropertyTypeMismatch obj = jsonb.fromJson(json, PropertyTypeMismatch.class); - assertEquals("Error at: +1000000000-12-31T23:59:59.999999999Z", obj.getError().get().getMessage()); - assertEquals(1, instantAdapter.callCount); - - String afterJson = jsonb.toJson(obj); - assertEquals("{\"error\":{\"message\":\"Error at: +1000000000-12-31T23:59:59.999999999Z\",\"type\":\"java.lang.RuntimeException\"}}", - afterJson); - assertEquals(1, throwableAdapter.callCount); + .build()) { + + String json = "{\"error\":\"CUSTOM_VALUE\"}"; + PropertyTypeMismatch obj = jsonb.fromJson(json, PropertyTypeMismatch.class); + assertEquals("Error at: +1000000000-12-31T23:59:59.999999999Z", obj.getError().get().getMessage()); + assertEquals(1, instantAdapter.callCount); + + String afterJson = jsonb.toJson(obj); + assertEquals("{\"error\":{\"message\":\"Error at: +1000000000-12-31T23:59:59.999999999Z\",\"type\":\"java.lang.RuntimeException\"}}", + afterJson); + assertEquals(1, throwableAdapter.callCount); + } } public static class StringAdapter implements JsonbAdapter { @@ -585,24 +620,26 @@ public String adaptFromJson(String obj) throws Exception { * Test for: https://github.com/eclipse-ee4j/yasson/issues/346 */ @Test - public void testAdaptedRootType() { - Jsonb jsonb = JsonbBuilder.newBuilder() + public void testAdaptedRootType() throws Exception { + try (Jsonb jsonb = JsonbBuilder.newBuilder() .withConfig(new JsonbConfig().withAdapters(new StringAdapter())) - .build(); - - String original = "hello world!"; - assertEquals("\"HELLO WORLD!\"", jsonb.toJson(original)); - assertEquals(original, jsonb.fromJson("\"HELLO WORLD!\"", String.class)); + .build()) { + + String original = "hello world!"; + assertEquals("\"HELLO WORLD!\"", jsonb.toJson(original)); + assertEquals(original, jsonb.fromJson("\"HELLO WORLD!\"", String.class)); + } } @Test - void testCustomAdapterInEnum(){ - Jsonb jsonb = JsonbBuilder.create(); + void testCustomAdapterInEnum() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - Vegetables expected = Vegetables.TOMATO; + Vegetables expected = Vegetables.TOMATO; - String expectedJson = jsonb.toJson(expected); + String expectedJson = jsonb.toJson(expected); - assertEquals(expected, jsonb.fromJson(expectedJson, Vegetables.class)); + assertEquals(expected, jsonb.fromJson(expectedJson, Vegetables.class)); + } } } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index c3ba5d45..90e0ba7b 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -288,7 +288,7 @@ public void setValue(String value) { } @Test - public void testBoundedGenerics() { + public void testBoundedGenerics() throws Exception { //bounded generics BoundedGenericClass, Circle> boundedGenericClass = new BoundedGenericClass<>(); List shapeList = new ArrayList<>(); @@ -311,18 +311,20 @@ public void testBoundedGenerics() { String expected = "{\"boundedSet\":[3],\"lowerBoundedList\":[{\"radius\":2.5}],\"upperBoundedList\":[{\"radius\":3.5,\"color\":\"0,0,255\"}]}"; assertEquals(expected, defaultJsonb.toJson(boundedGenericClass)); - Jsonb localJsonb = JsonbBuilder.create(new JsonbConfig()); - BoundedGenericClass, Circle> result = localJsonb.fromJson(expected, - new TestTypeToken, Circle>>(){}.getType()); - assertEquals(Circle.class, result.lowerBoundedList.get(0).getClass()); - assertEquals(Double.valueOf(2.5), ((Circle) result.lowerBoundedList.get(0)).getRadius()); - - //There is no way of identifying precise class (ColoredCircle) during json unmarshalling. - //Fields that are missing in upper bounds are skipped. - assertEquals(Circle.class, result.upperBoundedList.get(0).getClass()); - assertEquals(Double.valueOf(3.5), result.upperBoundedList.get(0).getRadius()); - //If it was possible we could assert following, but it is not. - //assertEquals("0,0,255", ((ColoredCircle) result.upperBoundedList.get(0)).color); + try (Jsonb localJsonb = JsonbBuilder.create(new JsonbConfig())) { + BoundedGenericClass, Circle> result = localJsonb.fromJson(expected, + new TestTypeToken, Circle>>() { + }.getType()); + assertEquals(Circle.class, result.lowerBoundedList.get(0).getClass()); + assertEquals(Double.valueOf(2.5), ((Circle) result.lowerBoundedList.get(0)).getRadius()); + + //There is no way of identifying precise class (ColoredCircle) during json unmarshalling. + //Fields that are missing in upper bounds are skipped. + assertEquals(Circle.class, result.upperBoundedList.get(0).getClass()); + assertEquals(Double.valueOf(3.5), result.upperBoundedList.get(0).getRadius()); + //If it was possible we could assert following, but it is not. + //assertEquals("0,0,255", ((ColoredCircle) result.upperBoundedList.get(0)).color); + } } @Test @@ -436,17 +438,18 @@ public void collectionWrapperTest() { } @Test - public void multipleGenericLevels() { + public void multipleGenericLevels() throws Exception { FinalMember member = new FinalMember(); member.setName("Jason"); FinalGenericWrapper concreteContainer = new FinalGenericWrapper(); concreteContainer.setMember(member); String expected = "{\"member\":{\"name\":\"Jason\"}}"; - Jsonb jsonb = JsonbBuilder.create(); - assertEquals(expected, jsonb.toJson(concreteContainer)); - FinalGenericWrapper finalGenericWrapper = jsonb.fromJson(expected, FinalGenericWrapper.class); - assertEquals(concreteContainer, finalGenericWrapper); + try (Jsonb jsonb = JsonbBuilder.create()) { + assertEquals(expected, jsonb.toJson(concreteContainer)); + FinalGenericWrapper finalGenericWrapper = jsonb.fromJson(expected, FinalGenericWrapper.class); + assertEquals(concreteContainer, finalGenericWrapper); + } } @Test @@ -461,18 +464,18 @@ public void lowerBoundTypeVariableInCollectionAttribute() throws Exception { List> asList = Arrays.asList(anotherGenericTestClass); - Jsonb jsonb = JsonbBuilder.create(); - String toJson = jsonb.toJson(asList); - - Field field = LowerBoundTypeVariableWithCollectionAttributeClass.class.getDeclaredField("value"); - - Type genericType = field.getGenericType(); - - List> fromJson = jsonb.fromJson(toJson, genericType); + try (Jsonb jsonb = JsonbBuilder.create()) { + String toJson = jsonb.toJson(asList); - assertEquals(5, fromJson.get(0).field2.getArea()); - assertEquals(6, fromJson.get(0).field1); - + Field field = LowerBoundTypeVariableWithCollectionAttributeClass.class.getDeclaredField("value"); + + Type genericType = field.getGenericType(); + + List> fromJson = jsonb.fromJson(toJson, genericType); + + assertEquals(5, fromJson.get(0).field2.getArea()); + assertEquals(6, fromJson.get(0).field1); + } } public interface FunctionalInterface { diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 3f361c4d..e505b140 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -81,6 +81,7 @@ 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.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.hamcrest.CoreMatchers.is; @@ -173,91 +174,100 @@ public void testClassLevelAnnotationOnGenericRoot() { * Tests JSONB deserialization of arbitrary type invoked from a Deserializer. */ @Test - public void testDeserializerDeserializationByType() { + public void testDeserializerDeserializationByType() throws Exception { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializer()); - Jsonb jsonb = JsonbBuilder.create(config); + try (Jsonb jsonb = JsonbBuilder.create(config)) { - Box box = createPojoWithDates(); + Box box = createPojoWithDates(); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; + String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"date\":\"2015-05-14T11:10:01\"},\"secondBoxStr\":\"Second box string\"}"; - Box result = jsonb.fromJson(expected, Box.class); + Box result = jsonb.fromJson(expected, Box.class); - //deserialized by deserializationContext.deserialize(Class c) - assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + //deserialized by deserializationContext.deserialize(Class c) + assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); - assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); + assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); + assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); - //set by deserializer statically - assertEquals(new BigDecimal("123"), result.crate.crateBigDec); - assertEquals("abc", result.crate.crateStr); + //set by deserializer statically + assertEquals(new BigDecimal("123"), result.crate.crateBigDec); + assertEquals("abc", result.crate.crateStr); + } } /** * Tests JSONB serialization of arbitrary type invoked from a Serializer. */ @Test - public void testSerializerSerializationOfType() { + public void testSerializerSerializationOfType() throws Exception { JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - Jsonb jsonb = JsonbBuilder.create(config); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box pojo = createPojo(); - - assertEquals(expected, jsonb.toJson(pojo)); - - Box result = jsonb.fromJson(expected, Box.class); - assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); - //result.crate.crateStr is mapped to crate_str by jsonb property - assertNull(result.crate.crateStr); - assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + try (Jsonb jsonb = JsonbBuilder.create(config)) { + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box pojo = createPojo(); + + assertEquals(expected, jsonb.toJson(pojo)); + + Box result = jsonb.fromJson(expected, Box.class); + assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); + //result.crate.crateStr is mapped to crate_str by jsonb property + assertNull(result.crate.crateStr); + assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + } } @Test - public void testSerializerSerializationOfTypeWithExplicitType() { + public void testSerializerSerializationOfTypeWithExplicitType() throws Exception { JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - Jsonb jsonb = JsonbBuilder.create(config); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box pojo = createPojo(); - - assertEquals(expected, jsonb.toJson(pojo, Box.class)); - - Box result = jsonb.fromJson(expected, Box.class); - assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); - //result.crate.crateStr is mapped to crate_str by jsonb property - assertNull(result.crate.crateStr); - assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + try (Jsonb jsonb = JsonbBuilder.create(config)) { + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box pojo = createPojo(); + + assertEquals(expected, jsonb.toJson(pojo, Box.class)); + + Box result = jsonb.fromJson(expected, Box.class); + assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); + //result.crate.crateStr is mapped to crate_str by jsonb property + assertNull(result.crate.crateStr); + assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + } } /** * Tests jsonb type conversion, including property customization. */ @Test - public void testDeserializersUsingConversion() { + public void testDeserializersUsingConversion() throws Exception { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializerWithConversion()); - Jsonb jsonb = JsonbBuilder.create(config); - - String json = "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box result = jsonb.fromJson(json, Box.class); - final Date expected = getExpectedDate(); - assertEquals(expected, result.crate.date); - assertEquals("Box string", result.boxStr); - assertEquals("Second box string", result.secondBoxStr); + try (Jsonb jsonb = JsonbBuilder.create(config)) { + + String json = + "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box result = jsonb.fromJson(json, Box.class); + final Date expected = getExpectedDate(); + assertEquals(expected, result.crate.date); + assertEquals("Box string", result.boxStr); + assertEquals("Second box string", result.secondBoxStr); + } } @Test - public void testCrateJsonObjectDeserializer() { + public void testCrateJsonObjectDeserializer() throws Exception { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()); - Jsonb jsonb = JsonbBuilder.create(config); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crateInnerStr\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; - Box result = jsonb.fromJson(expected, Box.class); - assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); - assertEquals("REPLACED crate str", result.crate.crateStr); - assertEquals("Single inner", result.crate.crateInner.crateInnerStr); - assertEquals(BigDecimal.TEN, result.crate.crateInner.crateInnerBigDec); + try (Jsonb jsonb = JsonbBuilder.create(config)) { + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crateInnerStr\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; + Box result = jsonb.fromJson(expected, Box.class); + assertEquals(new BigDecimal("54321"), result.crate.crateBigDec); + assertEquals("REPLACED crate str", result.crate.crateStr); + assertEquals("Single inner", result.crate.crateInner.crateInnerStr); + assertEquals(BigDecimal.TEN, result.crate.crateInner.crateInnerBigDec); + } } private static Date getExpectedDate() { @@ -265,12 +275,14 @@ private static Date getExpectedDate() { } @Test - public void testSerializationUsingConversion() { + public void testSerializationUsingConversion() throws Exception { JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializerWithConversion()); - Jsonb jsonb = JsonbBuilder.create(config); + try (Jsonb jsonb = JsonbBuilder.create(config)) { - String json = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321,\"date-converted\":\"2015-05-14T11:10:01Z[UTC]\"},\"secondBoxStr\":\"Second box string\"}"; - assertEquals(json, jsonb.toJson(createPojoWithDates())); + String json = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321,\"date-converted\":\"2015-05-14T11:10:01Z[UTC]\"},\"secondBoxStr\":\"Second box string\"}"; + assertEquals(json, jsonb.toJson(createPojoWithDates())); + } } @Test @@ -306,38 +318,40 @@ public void testAnnotations() { } @Test - public void testAnnotationsOverride() { + public void testAnnotationsOverride() throws Exception { JsonbConfig config = new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()).withSerializers(new CrateSerializer()); - Jsonb jsonb = JsonbBuilder.create(config); + try (Jsonb jsonb = JsonbBuilder.create(config)) { - BoxWithAnnotations box = new BoxWithAnnotations(); - box.boxStr = "Box string"; - box.secondBoxStr = "Second box string"; - box.crate = new Crate(); - box.crate.crateInner = createCrateInner("Single inner"); - box.crate.date = getExpectedDate(); + BoxWithAnnotations box = new BoxWithAnnotations(); + box.boxStr = "Box string"; + box.secondBoxStr = "Second box string"; + box.crate = new Crate(); + box.crate.crateInner = createCrateInner("Single inner"); + box.crate.date = getExpectedDate(); - box.crate.crateInnerList = new ArrayList<>(); - box.crate.crateInnerList.add(createCrateInner("List inner 0")); - box.crate.crateInnerList.add(createCrateInner("List inner 1")); + box.crate.crateInnerList = new ArrayList<>(); + box.crate.crateInnerList.add(createCrateInner("List inner 0")); + box.crate.crateInnerList.add(createCrateInner("List inner 1")); - String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321,\"date-converted\":\"2015-05-14T11:10:01Z[UTC]\"},\"secondBoxStr\":\"Second box string\"}"; + String expected = + "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321,\"date-converted\":\"2015-05-14T11:10:01Z[UTC]\"},\"secondBoxStr\":\"Second box string\"}"; - assertEquals(expected, jsonb.toJson(box)); + assertEquals(expected, jsonb.toJson(box)); - BoxWithAnnotations result = jsonb.fromJson(expected, BoxWithAnnotations.class); + BoxWithAnnotations result = jsonb.fromJson(expected, BoxWithAnnotations.class); - //deserialized by deserializationContext.deserialize(Class c) - assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); + //deserialized by deserializationContext.deserialize(Class c) + assertEquals(box.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); + assertEquals(box.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); - assertEquals(2L, result.crate.crateInnerList.size()); - assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); - assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); + assertEquals(2L, result.crate.crateInnerList.size()); + assertEquals("List inner 0", result.crate.crateInnerList.get(0).crateInnerStr); + assertEquals("List inner 1", result.crate.crateInnerList.get(1).crateInnerStr); - //set by deserializer statically - assertEquals(new BigDecimal("123"), result.crate.crateBigDec); - assertEquals("abc", result.crate.crateStr); + //set by deserializer statically + assertEquals(new BigDecimal("123"), result.crate.crateBigDec); + assertEquals("abc", result.crate.crateStr); + } } @Test @@ -377,21 +391,22 @@ public void testContainerSerializer() { * Tests avoiding StackOverflowError. */ @Test - public void testRecursiveSerializer() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new RecursiveSerializer()).withDeserializers(new RecursiveDeserializer())); + public void testRecursiveSerializer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new RecursiveSerializer()).withDeserializers(new RecursiveDeserializer()))) { - Box box = new Box(); - box.boxStr = "Box to serialize"; - try { - jsonb.toJson(box); - fail(); - } catch (JsonbException ex) { - } + Box box = new Box(); + box.boxStr = "Box to serialize"; + try { + jsonb.toJson(box); + fail(); + } catch (JsonbException ex) { + } - try { - jsonb.fromJson("{\"boxStr\":\"Box to deserialize\"}", Box.class); - fail(); - } catch (StackOverflowError error){ + try { + jsonb.fromJson("{\"boxStr\":\"Box to deserialize\"}", Box.class); + fail(); + } catch (StackOverflowError error) { + } } } @@ -409,75 +424,82 @@ public void testAuthor() { } @Test - public void testSupertypeSerializer() { - Jsonb jsonb = JsonbBuilder.create( + public void testSupertypeSerializer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create( new JsonbConfig().withSerializers(new NumberSerializer()) - .withDeserializers(new NumberDeserializer())); - SupertypeSerializerPojo pojo = new SupertypeSerializerPojo(); - pojo.setNumberInteger(10); - pojo.setAnotherNumberInteger(11); - assertEquals("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", jsonb.toJson(pojo)); - - pojo = jsonb.fromJson("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", SupertypeSerializerPojo.class); - assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); - assertEquals(Integer.valueOf(11), pojo.getAnotherNumberInteger()); + .withDeserializers(new NumberDeserializer()))) { + SupertypeSerializerPojo pojo = new SupertypeSerializerPojo(); + pojo.setNumberInteger(10); + pojo.setAnotherNumberInteger(11); + assertEquals("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", jsonb.toJson(pojo)); + + pojo = jsonb.fromJson("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", SupertypeSerializerPojo.class); + assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); + assertEquals(Integer.valueOf(11), pojo.getAnotherNumberInteger()); + } } @Test - public void testObjectDeserializerWithLexOrderStrategy() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL)); - Object pojo = jsonb.fromJson("{\"first\":{},\"third\":{},\"second\":{\"second\":2,\"first\":1}}", Object.class); - assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap"); - @SuppressWarnings("unchecked") - SortedMap pojoAsMap = (SortedMap) pojo; - assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); - assertEquals("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", jsonb.toJson(pojo)); + public void testObjectDeserializerWithLexOrderStrategy() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))) { + Object pojo = jsonb.fromJson("{\"first\":{},\"third\":{},\"second\":{\"second\":2,\"first\":1}}", Object.class); + assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap"); + @SuppressWarnings("unchecked") + SortedMap pojoAsMap = (SortedMap) pojo; + assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); + assertEquals("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", jsonb.toJson(pojo)); + } } @Test - public void testObjectDeserializerWithReverseOrderStrategy() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE)); - Object pojo = jsonb.fromJson("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", Object.class); - assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap"); - @SuppressWarnings("unchecked") - SortedMap pojoAsMap = (SortedMap) pojo; - assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); - assertEquals("{\"third\":{},\"second\":{\"second\":2,\"first\":1},\"first\":{}}", jsonb.toJson(pojo)); + public void testObjectDeserializerWithReverseOrderStrategy() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE))) { + Object pojo = jsonb.fromJson("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", Object.class); + assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap"); + @SuppressWarnings("unchecked") + SortedMap pojoAsMap = (SortedMap) pojo; + assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); + assertEquals("{\"third\":{},\"second\":{\"second\":2,\"first\":1},\"first\":{}}", jsonb.toJson(pojo)); + } } @Test - public void testObjectDeserializerWithAnyOrNoneOrderStrategy() { + public void testObjectDeserializerWithAnyOrNoneOrderStrategy() throws Exception { String json = "{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}"; // ANY - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY)); - Object pojo = jsonb.fromJson(json, Object.class); - assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with \"ANY\" strategy"); - // none - pojo = defaultJsonb.fromJson(json, Object.class); - assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with no strategy"); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY))) { + Object pojo = jsonb.fromJson(json, Object.class); + assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with \"ANY\" strategy"); + // none + pojo = defaultJsonb.fromJson(json, Object.class); + assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with no strategy"); + } } @Test - public void testSortedMapDerializer() { + public void testSortedMapDerializer() throws Exception { String json = "{\"first\":1,\"third\":3,\"second\":2}"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY)); - SortedMap pojo = jsonb.fromJson(json, SortedMap.class); - assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with \"ANY\" strategy"); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY))) { + SortedMap pojo = jsonb.fromJson(json, SortedMap.class); + assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with \"ANY\" strategy"); + } - jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL)); - pojo = jsonb.fromJson(json, SortedMap.class); - assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); - assertEquals("{\"first\":1,\"second\":2,\"third\":3}", jsonb.toJson(pojo)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))){ + SortedMap pojo = jsonb.fromJson(json, SortedMap.class); + assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); + assertEquals("{\"first\":1,\"second\":2,\"third\":3}", jsonb.toJson(pojo)); + } - jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE)); - pojo = jsonb.fromJson(json, SortedMap.class); - assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap with no strategy"); - assertEquals("{\"third\":3,\"second\":2,\"first\":1}", jsonb.toJson(pojo)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE))) { + SortedMap pojo = jsonb.fromJson(json, SortedMap.class); + assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap with no strategy"); + assertEquals("{\"third\":3,\"second\":2,\"first\":1}", jsonb.toJson(pojo)); - pojo = defaultJsonb.fromJson(json, SortedMap.class); - assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); - assertEquals("{\"first\":1,\"second\":2,\"third\":3}", defaultJsonb.toJson(pojo)); + pojo = defaultJsonb.fromJson(json, SortedMap.class); + assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); + assertEquals("{\"first\":1,\"second\":2,\"third\":3}", defaultJsonb.toJson(pojo)); + } } @Test @@ -504,13 +526,14 @@ public void testSerializeMapWithNulls() { } @Test - public void testSerializeMapWithNullsForceArraySerializer() { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig() + public void testSerializeMapWithNullsForceArraySerializer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new YassonConfig() .withForceMapArraySerializerForNullKeys(Boolean.TRUE) - .withNullValues(Boolean.TRUE)); - assertEquals("[{\"key\":null,\"value\":null}]", jsonb.toJson(singletonMap(null, null))); - assertEquals("{\"key\":null}", jsonb.toJson(singletonMap("key", null))); - assertEquals("[{\"key\":null,\"value\":\"value\"}]", jsonb.toJson(singletonMap(null, "value"))); + .withNullValues(Boolean.TRUE))) { + assertEquals("[{\"key\":null,\"value\":null}]", jsonb.toJson(singletonMap(null, null))); + assertEquals("{\"key\":null}", jsonb.toJson(singletonMap("key", null))); + assertEquals("[{\"key\":null,\"value\":\"value\"}]", jsonb.toJson(singletonMap(null, "value"))); + } } /** @@ -518,25 +541,27 @@ public void testSerializeMapWithNullsForceArraySerializer() { * Map shall be stored as a single JsonObject with keys as object properties names. */ @Test - public void testSerializeMapToJsonObject() { + public void testSerializeMapToJsonObject() throws Exception { Map map = new HashMap<>(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - map.put("name", "John SMith"); - map.put("age", 35); - map.put("married", true); - String json = jsonb.toJson(map); - JsonObject jobj = Json.createReader(new StringReader(json)).read().asJsonObject(); - assertEquals("John SMith", jobj.getString("name")); - assertEquals(35, jobj.getInt("age")); - assertEquals(true, jobj.getBoolean("married")); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { + map.put("name", "John SMith"); + map.put("age", 35); + map.put("married", true); + String json = jsonb.toJson(map); + JsonObject jobj = Json.createReader(new StringReader(json)).read().asJsonObject(); + assertEquals("John SMith", jobj.getString("name")); + assertEquals(35, jobj.getInt("age")); + assertEquals(true, jobj.getBoolean("married")); + } } @Test - public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() { + public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() throws Exception { String json = "[{\"stringProperty\":\"Property 1 value\"},{\"stringProperty\":\"Property 2 value\"}]"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoDeserializer())); - SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); - assertEquals(2, result.length); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoDeserializer()))) { + SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); + assertEquals(2, result.length); + } } public class SimplePojoDeserializer implements JsonbDeserializer { @@ -551,11 +576,12 @@ public SimplePojo deserialize(JsonParser parser, DeserializationContext ctx, Typ } @Test - public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() { + public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() throws Exception { String json = "[{\"stringProperty\":\"Property 1 value\"},{\"stringProperty\":\"Property 2 value\"}]"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoValueDeserializer())); - SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); - assertEquals(2, result.length); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoValueDeserializer()))) { + SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); + assertEquals(2, result.length); + } } public class SimplePojoValueDeserializer implements JsonbDeserializer { @@ -637,14 +663,15 @@ public void serialize(Baz obj, JsonGenerator generator, SerializationContext ctx * 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 void testSerializerMatching() throws Exception { + try (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 { } @@ -674,19 +701,21 @@ public void serialize(Three obj, JsonGenerator generator, SerializationContext c } @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())); + public void testSerializerMatchingInterfaces01() throws Exception { + try (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())); + public void testSerializerMatchingInterfaces02() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() + .withSerializers(new ThreeSerializer(), new TwoSerializer()))) { + assertEquals("\"two\"", jsonb.toJson(new OneTwo())); + assertEquals("\"two\"", jsonb.toJson(new OneTwoThree())); + } } public class GenericBean { @@ -731,156 +760,166 @@ public GenericBean deserialize(JsonParser parser, DeserializationContext ctx, Ty } @Test - public void testCustomDeserializerWithParameterizedType() { + public void testCustomDeserializerWithParameterizedType() throws Exception { GenericBeanSerializer genericBeanSerializer = new GenericBeanSerializer(); GenericBeanDeserializer genericBeanDeserializer = new GenericBeanDeserializer(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(genericBeanDeserializer).withSerializers(genericBeanSerializer)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(genericBeanDeserializer).withSerializers(genericBeanSerializer))) { - GenericBean bean1 = new GenericBean<>(); - bean1.value = "test1"; - GenericBean bean2 = new GenericBean<>(); - bean2.value = "test2"; - GenericBean bean3 = new GenericBean<>(); - bean3.value = "test3"; + GenericBean bean1 = new GenericBean<>(); + bean1.value = "test1"; + GenericBean bean2 = new GenericBean<>(); + bean2.value = "test2"; + GenericBean bean3 = new GenericBean<>(); + bean3.value = "test3"; - Collection> asList = Arrays.asList(bean1, bean2, bean3); + Collection> asList = Arrays.asList(bean1, bean2, bean3); - String toJson = jsonb.toJson(asList); + String toJson = jsonb.toJson(asList); - assertEquals(toJson, "[{\"value\":\"test1\"},{\"value\":\"test2\"},{\"value\":\"test3\"}]"); - assertTrue(genericBeanSerializer.called); + assertEquals(toJson, "[{\"value\":\"test1\"},{\"value\":\"test2\"},{\"value\":\"test3\"}]"); + assertTrue(genericBeanSerializer.called); - List> fromJson = jsonb.fromJson( - toJson, - new ParameterizedType() { - @Override - public Type[] getActualTypeArguments() { - return new Type[]{GenericBean.class}; - } + List> fromJson = jsonb.fromJson( + toJson, + new ParameterizedType() { + @Override + public Type[] getActualTypeArguments() { + return new Type[] {GenericBean.class}; + } - @Override - public Type getRawType() { - return Collection.class; - } - - @Override - public Type getOwnerType() { - return null; - } - } - ); + @Override + public Type getRawType() { + return Collection.class; + } - assertEquals(asList, fromJson); - assertTrue(genericBeanDeserializer.called); + @Override + public Type getOwnerType() { + return null; + } + } + ); + assertEquals(asList, fromJson); + assertTrue(genericBeanDeserializer.called); + } } @Test - public void testImplicitJsonbSerializers() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ExplicitJsonbSerializer())); + public void testImplicitJsonbSerializers() throws Exception { String expected = "{\"value\":\"123\"}"; Box box = new Box(); box.boxStr = "Box"; - assertEquals(expected, jsonb.toJson(box)); - jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ImplicitJsonbSerializer())); - assertEquals(expected, jsonb.toJson(box)); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ExplicitJsonbSerializer()))) { + assertEquals(expected, jsonb.toJson(box)); + } + + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ImplicitJsonbSerializer()))) { + assertEquals(expected, jsonb.toJson(box)); + } } @Test - public void testBoxToArrayChained() { + public void testBoxToArrayChained() throws Exception { JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED); - Jsonb jsonb = JsonbBuilder.create(cfg); - Box box = new Box(); - box.boxStr = "str1"; - box.secondBoxStr = "str2"; - String expected = "[\"str1\",\"str2\"]"; + try (Jsonb jsonb = JsonbBuilder.create(cfg)) { + Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; - assertThat(jsonb.toJson(box), is(expected)); + assertThat(jsonb.toJson(box), is(expected)); + } } @Test - public void testBoxToArray() { + public void testBoxToArray() throws Exception { JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER); - Jsonb jsonb = JsonbBuilder.create(cfg); - Box box = new Box(); - box.boxStr = "str1"; - box.secondBoxStr = "str2"; - String expected = "[\"str1\",\"str2\"]"; + try (Jsonb jsonb = JsonbBuilder.create(cfg)) { + Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; - assertThat(jsonb.toJson(box), is(expected)); + assertThat(jsonb.toJson(box), is(expected)); + } } @Test public void testBoxToArrayChainedWithLambda() { JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED_AS_LAMBDA); - assertThrows(JsonbException.class, () -> JsonbBuilder.create(cfg)); - /*Box box = new Box(); - box.boxStr = "str1"; - box.secondBoxStr = "str2"; - String expected = "[\"str1\",\"str2\"]"; + assertThrows(JsonbException.class, () -> {try (Jsonb jsonb = JsonbBuilder.create(cfg)){ + Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; - assertThat(jsonb.toJson(box), is(expected));*/ + assertThat(jsonb.toJson(box), is(expected)); + }}); } @Test public void testBoxToArrayWithLambda() { JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_AS_LAMBDA); - assertThrows(JsonbException.class, () -> JsonbBuilder.create(cfg)); - /*Box box = new Box(); - box.boxStr = "str1"; - box.secondBoxStr = "str2"; - String expected = "[\"str1\",\"str2\"]"; + assertThrows(JsonbException.class, () -> {try (Jsonb jsonb = JsonbBuilder.create(cfg)){ + Box box = new Box(); + box.boxStr = "str1"; + box.secondBoxStr = "str2"; + String expected = "[\"str1\",\"str2\"]"; - assertThat(jsonb.toJson(box), is(expected));*/ + assertThat(jsonb.toJson(box), is(expected)); + }}); } @Test - public void testCustomSerializersInContainer(){ - Jsonb jsonb = JsonbBuilder.create(); - - Container expected = new Container(List.of(new Containee("k", "v"))); + public void testCustomSerializersInContainer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - String expectedJson = jsonb.toJson(expected); - System.out.println(expectedJson); + Container expected = new Container(List.of(new Containee("k", "v"))); - assertEquals(expected, jsonb.fromJson(expectedJson, Container.class)); + String expectedJson = jsonb.toJson(expected); + System.out.println(expectedJson); + assertEquals(expected, jsonb.fromJson(expectedJson, Container.class)); + } } @Test - void testCustomSerializersAndDeserializersInEnum(){ - Jsonb jsonb = JsonbBuilder.create(); + void testCustomSerializersAndDeserializersInEnum() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - Colors expected = Colors.GREEN; + Colors expected = Colors.GREEN; - String expectedJson = jsonb.toJson(expected); + String expectedJson = jsonb.toJson(expected); - assertEquals(expected, jsonb.fromJson(expectedJson, Colors.class)); + assertEquals(expected, jsonb.fromJson(expectedJson, Colors.class)); + } } @Test - void testJsonbPropertyInEnum(){ - Jsonb jsonb = JsonbBuilder.create(); + void testJsonbPropertyInEnum() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - Cars expected = Cars.FORD; + Cars expected = Cars.FORD; - String expectedJson = jsonb.toJson(expected); + String expectedJson = jsonb.toJson(expected); - assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + } } @Test - void testNoJsonbPropertyInEnum(){ - Jsonb jsonb = JsonbBuilder.create(); + void testNoJsonbPropertyInEnum() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - Cars expected = Cars.FIAT; + Cars expected = Cars.FIAT; - String expectedJson = jsonb.toJson(expected); + String expectedJson = jsonb.toJson(expected); - assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); + } } } From e5346b30a548a7ddc4c08f2ef63c1cc7dc28070b Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Fri, 13 Oct 2023 20:58:10 +0200 Subject: [PATCH 14/68] [#617]Made new tests public Signed-off-by: Anton Pinsky --- .gitignore | 1 + src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java | 2 +- .../org/eclipse/yasson/serializers/SerializersTest.java | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3160630c..82953369 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .idea/ .settings/ /.DS_Store +/.sdkmanrc diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index ba1f9e43..5e8683f1 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -632,7 +632,7 @@ public void testAdaptedRootType() throws Exception { } @Test - void testCustomAdapterInEnum() throws Exception { + public void testCustomAdapterInEnum() throws Exception { try (Jsonb jsonb = JsonbBuilder.create()) { Vegetables expected = Vegetables.TOMATO; diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index e505b140..f4a6d8ff 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -887,7 +887,7 @@ public void testCustomSerializersInContainer() throws Exception { } @Test - void testCustomSerializersAndDeserializersInEnum() throws Exception { + public void testCustomSerializersAndDeserializersInEnum() throws Exception { try (Jsonb jsonb = JsonbBuilder.create()) { Colors expected = Colors.GREEN; @@ -899,7 +899,7 @@ void testCustomSerializersAndDeserializersInEnum() throws Exception { } @Test - void testJsonbPropertyInEnum() throws Exception { + public void testJsonbPropertyInEnum() throws Exception { try (Jsonb jsonb = JsonbBuilder.create()) { Cars expected = Cars.FORD; @@ -911,7 +911,7 @@ void testJsonbPropertyInEnum() throws Exception { } @Test - void testNoJsonbPropertyInEnum() throws Exception { + public void testNoJsonbPropertyInEnum() throws Exception { try (Jsonb jsonb = JsonbBuilder.create()) { Cars expected = Cars.FIAT; From d3e84ec8e120aebd539dbd44de2609b19a5c63b6 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 14 Oct 2023 23:48:31 +0200 Subject: [PATCH 15/68] [#617]Warnings on static inner classes and interfaces removed Signed-off-by: Anton Pinsky --- .../yasson/serializers/SerializersTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index f4a6d8ff..068b48e9 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -564,7 +564,7 @@ public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() throws Excep } } - public class SimplePojoDeserializer implements JsonbDeserializer { + public static class SimplePojoDeserializer implements JsonbDeserializer { @Override public SimplePojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { //parser.getObject advances the parser to END_OBJECT. @@ -584,7 +584,7 @@ public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() th } } - public class SimplePojoValueDeserializer implements JsonbDeserializer { + public static class SimplePojoValueDeserializer implements JsonbDeserializer { @Override public SimplePojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { //parser.getValue advances the parser to END_OBJECT in case of object. @@ -595,7 +595,7 @@ public SimplePojo deserialize(JsonParser parser, DeserializationContext ctx, Typ } } - public class SimplePojo { + public static class SimplePojo { private String stringProperty; public String getStringProperty() { @@ -674,10 +674,10 @@ public void testSerializerMatching() throws Exception { } } - public static interface One { } - public static interface Two { } + public interface One { } + public interface Two { } - public static interface Three { } + public interface Three { } public static class OneTwo implements One, Two { } public static class OneTwoThree implements One, Two, Three { } @@ -718,7 +718,7 @@ public void testSerializerMatchingInterfaces02() throws Exception { } } - public class GenericBean { + public static class GenericBean { public T value; @@ -732,7 +732,7 @@ public boolean equals(Object obj) { } - public class GenericBeanSerializer implements JsonbSerializer { + public static class GenericBeanSerializer implements JsonbSerializer { private Boolean called = Boolean.FALSE; @@ -745,7 +745,7 @@ public void serialize(GenericBean t, JsonGenerator jg, SerializationContext sc) } } - public class GenericBeanDeserializer implements JsonbDeserializer { + public static class GenericBeanDeserializer implements JsonbDeserializer { private Boolean called = Boolean.FALSE; From d54416c3aed15d1993e5690c5e2739a763d2ab15 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 14 Oct 2023 23:52:20 +0200 Subject: [PATCH 16/68] [#617]Removed som not thrown Exceptions in the tests Signed-off-by: Anton Pinsky --- .../java/org/eclipse/yasson/adapters/AdaptersTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 5e8683f1..ee8f2243 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -373,14 +373,14 @@ public void testAdaptMapString() throws Exception { JsonbAdapter[] adapters = {new JsonbAdapter, String>() { @Override - public Map adaptFromJson(String obj) throws Exception { + public Map adaptFromJson(String obj) { final HashMap result = new HashMap<>(); result.put("fake", 101); return result; } @Override - public String adaptToJson(Map obj) throws Exception { + public String adaptToJson(Map obj) { StringBuilder sb = new StringBuilder(); for (Map.Entry entry : obj.entrySet()) { if (sb.length() > 0) { @@ -414,14 +414,14 @@ public String adaptToJson(Map obj) throws Exception { public void testAdaptMapToObject() throws Exception { JsonbAdapter[] adapters = {new JsonbAdapter, Crate>() { @Override - public Map adaptFromJson(Crate obj) throws Exception { + public Map adaptFromJson(Crate obj) { final HashMap fake = new HashMap<>(); fake.put("fake", "11"); return fake; } @Override - public Crate adaptToJson(Map obj) throws Exception { + public Crate adaptToJson(Map obj) { final Map.Entry next = obj.entrySet().iterator().next(); return new Crate(next.getKey(), Integer.parseInt(next.getValue())); } From 9c1a95f020c01fa94ec8e93fdd0863d36bca934e Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 15 Oct 2023 01:12:30 +0200 Subject: [PATCH 17/68] [#617]Less raw usage warnings Signed-off-by: Anton Pinsky --- .../eclipse/yasson/internal/ReflectionUtils.java | 8 ++++---- .../org/eclipse/yasson/adapters/AdaptersTest.java | 14 +++++++------- .../defaultmapping/generics/GenericsTest.java | 11 +++++------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java index 87cfa4f5..faacc594 100644 --- a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java +++ b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java @@ -327,7 +327,7 @@ public static Constructor getDefaultConstructor(Class clazz, boolean r * @return type of JsonbAdapter */ public static ParameterizedType findParameterizedType(Class classToSearch, Class parameterizedInterface) { - Class current = classToSearch; + Class current = classToSearch; while (current != Object.class) { for (Type currentInterface : current.getGenericInterfaces()) { if (currentInterface instanceof ParameterizedType @@ -360,15 +360,15 @@ public static boolean isResolvedType(Type type) { return type instanceof Class; } - private static ParameterizedType findParameterizedSuperclass(Type type) { + /*private static ParameterizedType findParameterizedSuperclass(Type type) { if (type == null || type instanceof ParameterizedType) { return (ParameterizedType) type; } if (!(type instanceof Class)) { throw new JsonbException("Can't resolve ParameterizedType superclass for: " + type); } - return findParameterizedSuperclass(((Class) type).getGenericSuperclass()); - } + return findParameterizedSuperclass(((Class) type).getGenericSuperclass()); + }*/ /** * Resolves a wildcard most specific upper or lower bound. diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index ee8f2243..7cb810db 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -86,7 +86,7 @@ public Box adaptFromJson(Crate crate) { }; try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo pojo = new AdaptedPojo(); + AdaptedPojo pojo = new AdaptedPojo<>(); Box box = new Box(); box.setBoxStrField("BoxStr"); box.setBoxIntegerField(10); @@ -117,7 +117,7 @@ public Integer adaptFromJson(String s) { }; try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - AdaptedPojo pojo = new AdaptedPojo(); + AdaptedPojo pojo = new AdaptedPojo<>(); pojo.intField = 11; String json = jsonb.toJson(pojo); assertEquals("{\"intField\":\"11\"}", json); @@ -148,7 +148,7 @@ public void testGenericAdapter() throws Exception { "\"tBox\":{\"crateStrField\":\"tGenBoxCrateStr\",\"adaptedT\":22}," + "\"strField\":\"POJO_STRING\"," + "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { }.getType()); assertEquals("POJO_STRING", result.strField); assertEquals("Box3", result.intBox.getStrField()); @@ -182,7 +182,7 @@ public void testPropagatedTypeArgs() throws Exception { "\"strField\":\"POJO_STRING\"," + "\"strBox\":{\"strField\":\"strBoxStr\",\"x\":\"44\"}}"; - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>() { }.getType()); assertEquals("POJO_STRING", result.strField); assertEquals("strCrateStr", result.intBox.getStrField()); @@ -210,7 +210,7 @@ public void testStringToGenericCollectionAdapter() throws Exception { String toUnmarshall = "{\"integerList\":\"11#22#33#44\",\"stringList\":[\"first\",\"second\"]," + "\"tVar\":\"110#111#101\"}"; - AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>>() { + AdaptedPojo result = jsonb.fromJson(toUnmarshall, new TestTypeToken>>() { }.getType()); List expectedIntegerList = Arrays.asList(11, 22, 33, 44); List expectedStringList = Arrays.asList("first", "second"); @@ -432,8 +432,8 @@ public Crate adaptToJson(Map obj) { pojo.tMap = new HashMap<>(); pojo.tMap.put("first", "101"); - TestTypeToken> typeToken = new TestTypeToken>() { - }; + TestTypeToken> typeToken = new TestTypeToken<>() { + }; String marshalledJson = jsonb.toJson(pojo, typeToken.getType()); assertEquals("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", marshalledJson); diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 90e0ba7b..397451ca 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -172,8 +172,8 @@ public void testGenericWithUnboundedWildcard() { GenericWithUnboundedWildcardClass result = defaultJsonb.fromJson(expected, GenericWithUnboundedWildcardClass.class); assertTrue(result.wildcardList.get(0) instanceof Map); - assertEquals("v1", ((Map) result.wildcardList.get(0)).get("k1")); - assertEquals("v2", ((Map) result.wildcardList.get(0)).get("k2")); + assertEquals("v1", ((Map) result.wildcardList.get(0)).get("k1")); + assertEquals("v2", ((Map) result.wildcardList.get(0)).get("k2")); } @Test @@ -270,7 +270,7 @@ public void testMarshallPropagatedGenericsRaw() { @Test public void testFunctional() { - FunctionalInterface myFunction = new FunctionalInterface() { + FunctionalInterface myFunction = new FunctionalInterface() { private String value = "initValue"; @@ -384,9 +384,8 @@ public void testGenericArray() { } @Test - @SuppressWarnings("unchecked") public void testMarshallRawList() throws ParseException { - List rawList = new ArrayList(); + List rawList = new ArrayList<>(); final SimpleDateFormat ddMMyyyy = new SimpleDateFormat("ddMMyyyy"); ddMMyyyy.setTimeZone(TimeZone.getTimeZone("Z")); rawList.add(ddMMyyyy.parse("24031981")); @@ -422,7 +421,7 @@ public void testMultipleBounds() { @SuppressWarnings("unchecked") public void testDeserializeIntoRaw() { - GenericTestClass result = defaultJsonb.fromJson("{\"field1\":{\"val1\":\"abc\"},\"field2\":{\"val1\":\"def\"}}", GenericTestClass.class); + GenericTestClass result = defaultJsonb.fromJson("{\"field1\":{\"val1\":\"abc\"},\"field2\":{\"val1\":\"def\"}}", GenericTestClass.class); assertEquals(((HashMap) result.getField1()).get("val1"), "abc"); assertEquals(((HashMap) result.getField2()).get("val1"), "def"); } From 2e9bfe27d8c62f39432f3ba4ecaf2cb44dcc4572 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 15 Oct 2023 02:11:28 +0200 Subject: [PATCH 18/68] [#617]Small call and variable optimisation Signed-off-by: Anton Pinsky --- .../yasson/internal/ReflectionUtils.java | 39 +++++++++---------- .../eclipse/yasson/adapters/AdaptersTest.java | 6 +-- .../defaultmapping/generics/GenericsTest.java | 18 ++------- .../yasson/serializers/SerializersTest.java | 16 ++++---- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java index faacc594..8830f2c1 100644 --- a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java +++ b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.logging.Logger; import jakarta.json.bind.JsonbException; @@ -38,7 +37,7 @@ */ public class ReflectionUtils { - private static final Logger LOGGER = Logger.getLogger(ReflectionUtils.class.getName()); + /*private static final Logger LOGGER = Logger.getLogger(ReflectionUtils.class.getName());*/ private ReflectionUtils() { throw new IllegalStateException("Utility classes should not be instantiated."); @@ -66,8 +65,8 @@ public static Optional> getOptionalRawType(Type type) { for (Type bound : typeVariable.getBounds()) { Optional> boundRawType = getOptionalRawType(bound); if (boundRawType.isPresent() && !Object.class.equals(boundRawType.get())) { - if (!specializedClass.isPresent() || specializedClass.get().isAssignableFrom(boundRawType.get())) { - specializedClass = Optional.of(boundRawType.get()); + if (specializedClass.isEmpty() || specializedClass.get().isAssignableFrom(boundRawType.get())) { + specializedClass = boundRawType; } } } @@ -80,7 +79,7 @@ public static Optional> getOptionalRawType(Type type) { /** * Get raw type by type. * Resolves only ParametrizedTypes, GenericArrayTypes and Classes. - * + *

* Exception is thrown if raw type cannot be resolved. * * @param type Type to get class information from, not null. @@ -168,20 +167,20 @@ public static Optional resolveOptionalType(List chain, Type type) { * @return Type of a generic "runtime" bound, not null. */ public static Type resolveItemVariableType(List chain, TypeVariable typeVariable, boolean warn) { -// if (chain == null) { -// Optional> optionalRawType = getOptionalRawType(typeVariable); -// if (optionalRawType.isPresent()) { -// return optionalRawType.get(); -// } + /*if (chain == null) { + Optional> optionalRawType = getOptionalRawType(typeVariable); + if (optionalRawType.isPresent()) { + return optionalRawType.get(); + } - // //Bound not found, treat it as an Object.class -// if (warn) { -// LOGGER.warning(Messages.getMessage(MessageKeys.GENERIC_BOUND_NOT_FOUND, -// typeVariable, -// typeVariable.getGenericDeclaration())); -// } -// return Object.class; -// } + //Bound not found, treat it as an Object.class + if (warn) { + LOGGER.warning(Messages.getMessage(MessageKeys.GENERIC_BOUND_NOT_FOUND, + typeVariable, + typeVariable.getGenericDeclaration())); + } + return Object.class; + }*/ Type returnType = typeVariable; for (int i = chain.size() - 1; i >= 0; i--) { Type type = chain.get(i); @@ -428,9 +427,7 @@ public String toString() { @Override public boolean equals(Object o) { - if (o instanceof GenericArrayType) { - GenericArrayType that = (GenericArrayType) o; - + if (o instanceof GenericArrayType that) { return Objects.equals(genericComponentType, that.getGenericComponentType()); } else { return false; diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 7cb810db..ec929c71 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -383,7 +383,7 @@ public Map adaptFromJson(String obj) { public String adaptToJson(Map obj) { StringBuilder sb = new StringBuilder(); for (Map.Entry entry : obj.entrySet()) { - if (sb.length() > 0) { + if (!sb.isEmpty()) { sb.append("#"); } sb.append(entry.getKey()).append("-").append(entry.getValue()); @@ -594,7 +594,7 @@ public void testDifferentAdapters() throws Exception { String json = "{\"error\":\"CUSTOM_VALUE\"}"; PropertyTypeMismatch obj = jsonb.fromJson(json, PropertyTypeMismatch.class); - assertEquals("Error at: +1000000000-12-31T23:59:59.999999999Z", obj.getError().get().getMessage()); + assertEquals("Error at: +1000000000-12-31T23:59:59.999999999Z", obj.getError().orElseThrow().getMessage()); assertEquals(1, instantAdapter.callCount); String afterJson = jsonb.toJson(obj); @@ -617,7 +617,7 @@ public String adaptFromJson(String obj) throws Exception { } /** - * Test for: https://github.com/eclipse-ee4j/yasson/issues/346 + * Test for: issue 346 */ @Test public void testAdaptedRootType() throws Exception { diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 397451ca..3261c0c8 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -270,19 +270,7 @@ public void testMarshallPropagatedGenericsRaw() { @Test public void testFunctional() { - FunctionalInterface myFunction = new FunctionalInterface() { - - private String value = "initValue"; - - @Override - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - }; + FunctionalInterface myFunction = () -> "initValue"; assertEquals("{\"value\":\"initValue\"}", defaultJsonb.toJson(myFunction)); } @@ -433,7 +421,7 @@ public void collectionWrapperTest() { collectionWrapper.setWrappedCollection(new ArrayList<>()); collectionWrapper.setWrappedMap(new HashMap<>()); - String s = defaultJsonb.toJson(collectionWrapper); + defaultJsonb.toJson(collectionWrapper); } @Test @@ -461,7 +449,7 @@ public void lowerBoundTypeVariableInCollectionAttribute() throws Exception { anotherGenericTestClass.field1 = 6; anotherGenericTestClass.field2 = shape; - List> asList = Arrays.asList(anotherGenericTestClass); + List> asList = List.of(anotherGenericTestClass); try (Jsonb jsonb = JsonbBuilder.create()) { String toJson = jsonb.toJson(asList); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 068b48e9..18c2e057 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -399,13 +399,13 @@ public void testRecursiveSerializer() throws Exception { try { jsonb.toJson(box); fail(); - } catch (JsonbException ex) { + } catch (JsonbException ignored) { } try { jsonb.fromJson("{\"boxStr\":\"Box to deserialize\"}", Box.class); fail(); - } catch (StackOverflowError error) { + } catch (StackOverflowError ignored) { } } } @@ -477,7 +477,7 @@ public void testObjectDeserializerWithAnyOrNoneOrderStrategy() throws Exception } @Test - public void testSortedMapDerializer() throws Exception { + public void testSortedMapDeserializer() throws Exception { String json = "{\"first\":1,\"third\":3,\"second\":2}"; try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY))) { @@ -551,7 +551,7 @@ public void testSerializeMapToJsonObject() throws Exception { JsonObject jobj = Json.createReader(new StringReader(json)).read().asJsonObject(); assertEquals("John SMith", jobj.getString("name")); assertEquals(35, jobj.getInt("age")); - assertEquals(true, jobj.getBoolean("married")); + assertTrue(jobj.getBoolean("married")); } } @@ -561,6 +561,7 @@ public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() throws Excep try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoDeserializer()))) { SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); assertEquals(2, result.length); + assertEquals("Property 1 value", result[0].getStringProperty()); } } @@ -581,6 +582,7 @@ public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() th try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoValueDeserializer()))) { SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); assertEquals(2, result.length); + assertEquals("Property 1 value", result[0].getStringProperty()); } } @@ -657,7 +659,7 @@ public void serialize(Baz obj, JsonGenerator generator, SerializationContext ctx } /** - * Test for issue: https://github.com/quarkusio/quarkus/issues/8925 + * Test for issue: issue 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. @@ -724,8 +726,8 @@ public static class GenericBean { @Override public boolean equals(Object obj) { - if (obj instanceof GenericBean){ - return Objects.equals(GenericBean.class.cast(obj).value, this.value); + if (obj instanceof GenericBean genericBean){ + return Objects.equals(genericBean.value, this.value); } return Boolean.FALSE; } From 6fb1442ea99693b5815d27f2692a11d9a84dcc62 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 15 Oct 2023 02:19:31 +0200 Subject: [PATCH 19/68] [#617]Pattern Matching for instanceof removed - not before Java 16 Signed-off-by: Anton Pinsky --- src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java index 8830f2c1..e297d6a0 100644 --- a/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java +++ b/src/main/java/org/eclipse/yasson/internal/ReflectionUtils.java @@ -427,7 +427,8 @@ public String toString() { @Override public boolean equals(Object o) { - if (o instanceof GenericArrayType that) { + if (o instanceof GenericArrayType) { + GenericArrayType that = (GenericArrayType) o; return Objects.equals(genericComponentType, that.getGenericComponentType()); } else { return false; From 062a161205d436bce2def7f43793cd9ff0066839 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 15 Oct 2023 02:39:21 +0200 Subject: [PATCH 20/68] [#617]Use defaultJsonb where JsonbBuilder.create() without configuration is used Signed-off-by: Anton Pinsky --- .../eclipse/yasson/adapters/AdaptersTest.java | 11 ++-- .../defaultmapping/generics/GenericsTest.java | 24 +++---- .../yasson/serializers/SerializersTest.java | 66 ++++++++----------- 3 files changed, 40 insertions(+), 61 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index ec929c71..54260a8d 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -632,14 +632,11 @@ public void testAdaptedRootType() throws Exception { } @Test - public void testCustomAdapterInEnum() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testCustomAdapterInEnum() { + Vegetables expected = Vegetables.TOMATO; - Vegetables expected = Vegetables.TOMATO; + String expectedJson = defaultJsonb.toJson(expected); - String expectedJson = jsonb.toJson(expected); - - assertEquals(expected, jsonb.fromJson(expectedJson, Vegetables.class)); - } + assertEquals(expected, defaultJsonb.fromJson(expectedJson, Vegetables.class)); } } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 3261c0c8..90c1f718 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -425,18 +425,16 @@ public void collectionWrapperTest() { } @Test - public void multipleGenericLevels() throws Exception { + public void multipleGenericLevels() { FinalMember member = new FinalMember(); member.setName("Jason"); FinalGenericWrapper concreteContainer = new FinalGenericWrapper(); concreteContainer.setMember(member); String expected = "{\"member\":{\"name\":\"Jason\"}}"; - try (Jsonb jsonb = JsonbBuilder.create()) { - assertEquals(expected, jsonb.toJson(concreteContainer)); - FinalGenericWrapper finalGenericWrapper = jsonb.fromJson(expected, FinalGenericWrapper.class); - assertEquals(concreteContainer, finalGenericWrapper); - } + assertEquals(expected, defaultJsonb.toJson(concreteContainer)); + FinalGenericWrapper finalGenericWrapper = defaultJsonb.fromJson(expected, FinalGenericWrapper.class); + assertEquals(concreteContainer, finalGenericWrapper); } @Test @@ -451,18 +449,16 @@ public void lowerBoundTypeVariableInCollectionAttribute() throws Exception { List> asList = List.of(anotherGenericTestClass); - try (Jsonb jsonb = JsonbBuilder.create()) { - String toJson = jsonb.toJson(asList); + String toJson = defaultJsonb.toJson(asList); - Field field = LowerBoundTypeVariableWithCollectionAttributeClass.class.getDeclaredField("value"); + Field field = LowerBoundTypeVariableWithCollectionAttributeClass.class.getDeclaredField("value"); - Type genericType = field.getGenericType(); + Type genericType = field.getGenericType(); - List> fromJson = jsonb.fromJson(toJson, genericType); + List> fromJson = defaultJsonb.fromJson(toJson, genericType); - assertEquals(5, fromJson.get(0).field2.getArea()); - assertEquals(6, fromJson.get(0).field1); - } + assertEquals(5, fromJson.get(0).field2.getArea()); + assertEquals(6, fromJson.get(0).field1); } public interface FunctionalInterface { diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 18c2e057..5d63c138 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -541,18 +541,16 @@ public void testSerializeMapWithNullsForceArraySerializer() throws Exception { * Map shall be stored as a single JsonObject with keys as object properties names. */ @Test - public void testSerializeMapToJsonObject() throws Exception { + public void testSerializeMapToJsonObject() { Map map = new HashMap<>(); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { - map.put("name", "John SMith"); - map.put("age", 35); - map.put("married", true); - String json = jsonb.toJson(map); - JsonObject jobj = Json.createReader(new StringReader(json)).read().asJsonObject(); - assertEquals("John SMith", jobj.getString("name")); - assertEquals(35, jobj.getInt("age")); - assertTrue(jobj.getBoolean("married")); - } + map.put("name", "John SMith"); + map.put("age", 35); + map.put("married", true); + String json = defaultJsonb.toJson(map); + JsonObject jobj = Json.createReader(new StringReader(json)).read().asJsonObject(); + assertEquals("John SMith", jobj.getString("name")); + assertEquals(35, jobj.getInt("age")); + assertTrue(jobj.getBoolean("married")); } @Test @@ -876,52 +874,40 @@ public void testBoxToArrayWithLambda() { } @Test - public void testCustomSerializersInContainer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { - - Container expected = new Container(List.of(new Containee("k", "v"))); + public void testCustomSerializersInContainer() { + Container expected = new Container(List.of(new Containee("k", "v"))); - String expectedJson = jsonb.toJson(expected); - System.out.println(expectedJson); + String expectedJson = defaultJsonb.toJson(expected); + System.out.println(expectedJson); - assertEquals(expected, jsonb.fromJson(expectedJson, Container.class)); - } + assertEquals(expected, defaultJsonb.fromJson(expectedJson, Container.class)); } @Test - public void testCustomSerializersAndDeserializersInEnum() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testCustomSerializersAndDeserializersInEnum() { + Colors expected = Colors.GREEN; - Colors expected = Colors.GREEN; + String expectedJson = defaultJsonb.toJson(expected); - String expectedJson = jsonb.toJson(expected); - - assertEquals(expected, jsonb.fromJson(expectedJson, Colors.class)); - } + assertEquals(expected, defaultJsonb.fromJson(expectedJson, Colors.class)); } @Test - public void testJsonbPropertyInEnum() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testJsonbPropertyInEnum() { + Cars expected = Cars.FORD; - Cars expected = Cars.FORD; + String expectedJson = defaultJsonb.toJson(expected); - String expectedJson = jsonb.toJson(expected); - - assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); - } + assertEquals(expected, defaultJsonb.fromJson(expectedJson, Cars.class)); } @Test - public void testNoJsonbPropertyInEnum() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testNoJsonbPropertyInEnum() { + Cars expected = Cars.FIAT; - Cars expected = Cars.FIAT; + String expectedJson = defaultJsonb.toJson(expected); - String expectedJson = jsonb.toJson(expected); - - assertEquals(expected, jsonb.fromJson(expectedJson, Cars.class)); - } + assertEquals(expected, defaultJsonb.fromJson(expectedJson, Cars.class)); } } From 5703629c753cfde6f3826edeaedfeb89602a5c86 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sun, 15 Oct 2023 13:34:57 +0200 Subject: [PATCH 21/68] [#617]Pattern Matching for instanceof removed - not before Java 16 Signed-off-by: Anton Pinsky --- .../java/org/eclipse/yasson/serializers/SerializersTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 5d63c138..416fb0e0 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -724,8 +724,8 @@ public static class GenericBean { @Override public boolean equals(Object obj) { - if (obj instanceof GenericBean genericBean){ - return Objects.equals(genericBean.value, this.value); + if (obj instanceof GenericBean){ + return Objects.equals(GenericBean.class.cast(obj).value, this.value); } return Boolean.FALSE; } From 38e48083c61d30ef800092db98d841c17af53e40 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 23 Oct 2023 17:09:54 +0200 Subject: [PATCH 22/68] [#620]Updated some of the Maven plugins and their corresponding configurations. Signed-off-by: Anton Pinsky --- etc/checkstyle.xml | 4 +-- pom.xml | 53 ++++++++++++++++++---------------- src/test/resources/test.policy | 5 ++++ 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/etc/checkstyle.xml b/etc/checkstyle.xml index 3479136a..c9bc6a2a 100644 --- a/etc/checkstyle.xml +++ b/etc/checkstyle.xml @@ -1,7 +1,7 @@ - + diff --git a/pom.xml b/pom.xml index 0abc66b7..d6c26e7a 100644 --- a/pom.xml +++ b/pom.xml @@ -34,11 +34,12 @@ UTF-8 - 2.1.0 + 2.1.2 2.1.0 3.0.0 4.0.1 JDK_9 + 5.10.0 @@ -51,7 +52,7 @@ jakarta.el jakarta.el-api - 5.0.0 + 5.0.1 jakarta.interceptor @@ -61,7 +62,7 @@ jakarta.annotation jakarta.annotation-api - 2.1.0 + 2.1.1 @@ -81,7 +82,7 @@ org.eclipse.parsson parsson - 1.1.0 + 1.1.4 @@ -93,19 +94,19 @@ org.jboss.weld.se weld-se-core - 5.0.0.Final + 5.1.2.Final test org.junit.jupiter junit-jupiter-api - 5.8.2 + ${junit.version} test org.junit.jupiter junit-jupiter-engine - 5.8.2 + ${junit.version} test @@ -262,7 +263,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.11.0 default-testCompile @@ -345,7 +346,7 @@ org.codehaus.mojo findbugs-maven-plugin - 3.0.4 + 3.0.5 Max Low @@ -364,12 +365,12 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.0.0-M3 + 3.1.2 org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.11.0 default-compile @@ -413,7 +414,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.3.0 ${project.build.outputDirectory}/META-INF/MANIFEST.MF @@ -427,7 +428,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 1.4 + 3.2.0 {0,date,MM/dd/yyyy hh:mm aa} @@ -446,7 +447,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.6.0 Yasson ${basedir}/src/main/java/org/eclipse/yasson @@ -468,7 +469,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.3.0 attach-sources @@ -481,7 +482,7 @@ org.apache.felix maven-bundle-plugin - 5.1.1 + 5.1.9 osgi-bundle @@ -514,7 +515,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 + 3.1.2 default-test @@ -538,6 +539,9 @@ --add-exports org.eclipse.yasson/org.eclipse.yasson.internal.cdi=java.naming + + false @@ -562,7 +566,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0-M2 + 3.4.1 enforce-versions @@ -577,7 +581,7 @@ [11,) - [3.3.9,) + [3.9.4,) @@ -586,7 +590,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.4.0 add-resource @@ -612,11 +616,10 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.0 + 3.3.0 etc/checkstyle.xml etc/checkstyle-suppressions.xml - UTF-8 true true false @@ -625,7 +628,7 @@ com.puppycrawl.tools checkstyle - 8.29 + 10.12.4 com.sun @@ -638,7 +641,7 @@ org.glassfish.copyright glassfish-copyright-maven-plugin - 2.3 + 2.4 etc/copyright.txt etc/copyright-exclude.txt @@ -697,7 +700,7 @@ org.codehaus.mojo findbugs-maven-plugin - 3.0.4 + 3.0.5 diff --git a/src/test/resources/test.policy b/src/test/resources/test.policy index e247b53d..e8f5a478 100644 --- a/src/test/resources/test.policy +++ b/src/test/resources/test.policy @@ -14,4 +14,9 @@ grant { permission "java.util.PropertyPermission" "jsonb.creator-parameters-required", "read"; permission "java.util.PropertyPermission" "yasson.time-in-millis-as-a-string", "read"; permission "java.util.PropertyPermission" "jakarta.json.provider", "read"; + permission "java.util.PropertyPermission" "org.eclipse.parsson.maxBigIntegerScale", "read"; + permission "java.util.PropertyPermission" "org.eclipse.parsson.maxBigDecimalLength", "read"; + permission "java.util.PropertyPermission" "org.eclipse.parsson.maxDepth", "read"; + permission "java.util.PropertyPermission" "org.eclipse.parsson.rejectDuplicateKeys", "read"; + permission "java.util.PropertyPermission" "jakarta.json.stream.JsonGenerator.prettyPrinting", "read"; }; \ No newline at end of file From d4c18ee18f0ddd0dc577637f479c655c27333fa2 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Tue, 24 Oct 2023 23:59:25 +0200 Subject: [PATCH 23/68] [#620]Setup and use Maven 3.9.5; maybe this is temporary Signed-off-by: Anton Pinsky --- .github/workflows/maven.yml | 4 ++++ pom.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 37888591..19c25ee5 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -24,6 +24,10 @@ jobs: java_version: [ 11, 17 ] steps: + - name: Set up Maven + uses: stCarolas/setup-maven@v4.5 + with: + maven-version: 3.9.5 - name: Checkout for build uses: actions/checkout@v2.3.4 with: diff --git a/pom.xml b/pom.xml index d6c26e7a..0aedfbc8 100644 --- a/pom.xml +++ b/pom.xml @@ -581,7 +581,7 @@ [11,) - [3.9.4,) + [3.9.5,) From 7915430e0aa84050334dc911bb52c1714887f707 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 25 Oct 2023 20:36:18 +0200 Subject: [PATCH 24/68] [#620]No need of --add-module for maven-javadoc-plugin:3.6.0 Signed-off-by: Anton Pinsky --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0aedfbc8..08b3d1f6 100644 --- a/pom.xml +++ b/pom.xml @@ -451,10 +451,6 @@ Yasson ${basedir}/src/main/java/org/eclipse/yasson - - --add-modules - jakarta.json.bind,jakarta.json - 11 From 451246a5eacda97e35a9b9d2edadd07d6324d128 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 25 Oct 2023 20:46:10 +0200 Subject: [PATCH 25/68] [#617]StringBuilder.isEmpty() only available since Java 15 Signed-off-by: Anton Pinsky --- src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 54260a8d..24f35c90 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -383,7 +383,7 @@ public Map adaptFromJson(String obj) { public String adaptToJson(Map obj) { StringBuilder sb = new StringBuilder(); for (Map.Entry entry : obj.entrySet()) { - if (!sb.isEmpty()) { + if (!sb.toString().isEmpty()) { sb.append("#"); } sb.append(entry.getKey()).append("-").append(entry.getValue()); From d5f3bac80fd39e2da0663fe6ad36dcec86c8c7bb Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Fri, 27 Oct 2023 18:02:55 +0200 Subject: [PATCH 26/68] [#620]Corrected the errors because of new version of surefire plugin Signed-off-by: Anton Pinsky --- pom.xml | 15 ++++++--------- .../types/AbstractNumberDeserializer.java | 13 ++++++------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 08b3d1f6..ff065b51 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ UTF-8 - 2.1.2 + 2.1.3 2.1.0 3.0.0 4.0.1 @@ -82,7 +82,7 @@ org.eclipse.parsson parsson - 1.1.4 + 1.1.5 @@ -365,7 +365,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.1.2 + 3.2.1 org.apache.maven.plugins @@ -511,7 +511,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.2 + 3.2.1 default-test @@ -535,9 +535,6 @@ --add-exports org.eclipse.yasson/org.eclipse.yasson.internal.cdi=java.naming - - false @@ -549,7 +546,7 @@ - --limit-modules java.base,java.logging,java.sql,jakarta.json.bind,jakarta.json,java.management,jdk.localedata + --limit-modules java.base,java.logging,java.sql,jakarta.json.bind,jakarta.json,java.management,jdk.localedata,org.eclipse.yasson,org.eclipse.parsson **/JavaxNamingExcludedTest.class @@ -612,7 +609,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.3.0 + 3.3.1 etc/checkstyle.xml etc/checkstyle-suppressions.xml diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java index e50e003a..f5387d7b 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -20,15 +20,15 @@ import java.util.Locale; import java.util.function.Function; -import jakarta.json.bind.JsonbException; - import org.eclipse.yasson.internal.DeserializationContextImpl; import org.eclipse.yasson.internal.JsonbNumberFormatter; import org.eclipse.yasson.internal.deserializer.ModelDeserializer; -import org.eclipse.yasson.internal.model.customization.Customization; import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; +import jakarta.json.bind.JsonbException; + + /** * Base deserializer for all the number types. */ @@ -44,8 +44,8 @@ abstract class AbstractNumberDeserializer extends TypeDeserial } private ModelDeserializer actualDeserializer(TypeDeserializerBuilder builder) { - Customization customization = builder.getCustomization(); - if (customization.getDeserializeNumberFormatter() == null) { + final JsonbNumberFormatter numberFormat = builder.getCustomization().getDeserializeNumberFormatter(); + if (numberFormat == null) { return (value, context) -> { try { return parseNumberValue(value); @@ -55,7 +55,6 @@ private ModelDeserializer actualDeserializer(TypeDeserializerBuilder bui }; } - final JsonbNumberFormatter numberFormat = customization.getDeserializeNumberFormatter(); //consider synchronizing on format instance or per thread cache. Locale locale = builder.getConfigProperties().getLocale(numberFormat.getLocale()); final NumberFormat format = NumberFormat.getInstance(locale); From ae4663cd564378f9d78c8c76fbf3ca4bd3ba6f29 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Fri, 27 Oct 2023 18:10:24 +0200 Subject: [PATCH 27/68] [#620]Wrongfully optimised import Signed-off-by: Anton Pinsky --- .../deserializer/types/AbstractNumberDeserializer.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java index f5387d7b..4b406404 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/types/AbstractNumberDeserializer.java @@ -20,15 +20,14 @@ import java.util.Locale; import java.util.function.Function; +import jakarta.json.bind.JsonbException; + import org.eclipse.yasson.internal.DeserializationContextImpl; import org.eclipse.yasson.internal.JsonbNumberFormatter; import org.eclipse.yasson.internal.deserializer.ModelDeserializer; import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; -import jakarta.json.bind.JsonbException; - - /** * Base deserializer for all the number types. */ From a8edee59a54b236b083d971c05c649fcf2b6b8e0 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Tue, 31 Oct 2023 16:13:17 +0100 Subject: [PATCH 28/68] [#626]Corrected the tests to respect the current default locale Signed-off-by: Anton Pinsky --- .../documented/DocumentationExampleTest.java | 1072 +++++++++-------- 1 file changed, 551 insertions(+), 521 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java index d49e4a07..c88324ba 100644 --- a/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java +++ b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,17 +12,22 @@ package org.eclipse.yasson.documented; -import org.junit.jupiter.api.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.eclipse.yasson.Jsonbs.*; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.formattingJsonb; +import static org.eclipse.yasson.Jsonbs.nullableJsonb; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import java.lang.reflect.Type; import java.math.BigDecimal; +import java.text.DecimalFormat; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Test; + import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; @@ -45,521 +50,546 @@ */ public class DocumentationExampleTest { - public static class Dog { - public String name; - public int age; - public boolean bitable; - } - - @Test - public void testMappingExample() { - // Create a dog instance - Dog dog = new Dog(); - dog.name = "Falco"; - dog.age = 4; - dog.bitable = false; - - // Create Jsonb and serialize - String result = defaultJsonb.toJson(dog); - assertEquals("{\"age\":4,\"bitable\":false,\"name\":\"Falco\"}", result); - - // Deserialize back - dog = defaultJsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class); - assertEquals("Falco", dog.name); - assertEquals(4, dog.age); - assertEquals(false, dog.bitable); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void testMappingCollection() { - Dog falco = new Dog(); - falco.name = "Falco"; - falco.age = 4; - Dog cassidy = new Dog(); - cassidy.name = "Cassidy"; - cassidy.age = 5; - - // List of dogs - List dogs = new ArrayList(); - dogs.add(falco); - dogs.add(cassidy); - - // Create Jsonb and serialize - String result = defaultJsonb.toJson(dogs); - assertEquals( - "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]", - result); - - // We can also deserialize back into a raw collection, but since there is no way - // to infer a type here, - // the result will be a list of java.util.Map instances with string keys. - dogs = defaultJsonb.fromJson(result, ArrayList.class); - assertEquals(2, dogs.size()); - assertEquals("Falco", ((Map) dogs.get(0)).get("name")); - assertEquals("Cassidy", ((Map) dogs.get(1)).get("name")); - // assertEquals(4, ((Map) dogs.get(0)).get("age")); // TODO should these - // actually be BigDecimals? - // assertEquals(5, ((Map) dogs.get(1)).get("age")); - } - - @SuppressWarnings("serial") - @Test - public void testMappingGenericCollection() { - Dog falco = new Dog(); - falco.name = "Falco"; - falco.age = 4; - Dog cassidy = new Dog(); - cassidy.name = "Cassidy"; - cassidy.age = 5; - - // List of dogs - List dogs = new ArrayList<>(); - dogs.add(falco); - dogs.add(cassidy); - - // Create Jsonb and serialize - String result = defaultJsonb.toJson(dogs); - assertEquals( - "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]", - result); - - // Deserialize back - dogs = defaultJsonb.fromJson(result, new ArrayList() { - }.getClass().getGenericSuperclass()); - assertEquals(2, dogs.size()); - assertEquals("Falco", dogs.get(0).name); - assertEquals("Cassidy", dogs.get(1).name); - } - - @Test - public void testFormattedOutput() { - Dog pojo = new Dog(); - pojo.name = "Falco"; - pojo.age = 4; - - // Use it! - String result = formattingJsonb.toJson(pojo); - assertEquals("{\n" + - " \"age\": 4,\n" + - " \"bitable\": false,\n" + - " \"name\": \"Falco\"\n" + - "}", result); - } - - public static class Person1 { - @JsonbProperty("person-name") - public String name; - public String profession; - } - - @Test - public void testChangingPropertyNames1() { - Person1 p = new Person1(); - p.name = "Jason Bourne"; - p.profession = "Super Agent"; - - String result = formattingJsonb.toJson(p); - assertEquals("{\n" + - " \"person-name\": \"Jason Bourne\",\n" + - " \"profession\": \"Super Agent\"\n" + - "}", result); - } - - public class Person2 { - private String name; - private String profession; - - @JsonbProperty("person-name") - public String getName() { - return name; - } - - public String getProfession() { - return profession; - } - - // public setters ... - public void setName(String name) { - this.name = name; - } - public void setProfession(String profession) { - this.profession = profession; - } - } - - @Test - public void testChangingPropertyNames2() { - Person2 p = new Person2(); - p.name = "Jason Bourne"; - p.profession = "Super Agent"; - - String result = formattingJsonb.toJson(p); - assertEquals("{\n" + - " \"person-name\": \"Jason Bourne\",\n" + - " \"profession\": \"Super Agent\"\n" + - "}", result); - } - - public static class Person3 { - private String name; - - @JsonbProperty("name-to-write") - public String getName() { - return name; - } - - @JsonbProperty("name-to-read") - public void setName(String name) { - this.name = name; - } - } - - @Test - public void testChangingPropertyNames3() { - Person3 p = new Person3(); - p.name = "Jason Bourne"; - String result = defaultJsonb.toJson(p); - assertEquals("{\"name-to-write\":\"Jason Bourne\"}", result); - - String json = "{\"name-to-read\":\"Jason Bourne\"}"; - Person3 after = defaultJsonb.fromJson(json, Person3.class); - assertEquals("Jason Bourne", after.name); - } - - public static class Person4 { // TODO: a non-static class results in an NPE - @JsonbTransient - private String name; - - private String profession; - - // public getters/setters ... - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getProfession() { - return this.profession; - } - public void setProfession(String profession) { - this.profession = profession; - } - } - - @Test - public void testIgnoringProperties() { - Person4 p = new Person4(); - p.name = "Jason Bourne"; - p.profession = "Super Agent"; - String result = defaultJsonb.toJson(p); - assertEquals("{\"profession\":\"Super Agent\"}", result); - - String json = "{\"profession\":\"Super Agent\"}"; - Person4 after = defaultJsonb.fromJson(json, Person4.class); - assertEquals("Super Agent", after.profession); - assertNull(after.name); - } - - @JsonbNillable - public class Person5 { - private String name; - private String profession; - - // public getters/setters ... - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getProfession() { - return profession; - } - public void setProfession(String profession) { - this.profession = profession; - } - } - - @Test - public void testNullHandling1() { - Person5 p = new Person5(); - String result = defaultJsonb.toJson(p); - assertEquals("{\"name\":null,\"profession\":null}", result); - } - - public class Person6 { - @JsonbProperty(nillable=true) - private String name; - - private String profession; - - // public getters/setters ... - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getProfession() { - return profession; - } - public void setProfession(String profession) { - this.profession = profession; - } - } - - @Test - public void testNullHandling2() { - Person6 p = new Person6(); - String result = defaultJsonb.toJson(p); - assertEquals("{\"name\":null}", result); - } - - public static class Person { - public String name; - public String profession; - } - - @Test - public void testNullHandling3() { - Person p = new Person(); - String result = nullableJsonb.toJson(p); - assertEquals("{\"name\":null,\"profession\":null}", result); - } - - public static class Person8 { // TODO: obscure error here if non-static - public final String name; - public String profession; - - @JsonbCreator - public Person8(@JsonbProperty("name") String name) { - this.name = name; - } - } - - @Test - public void testCustomInstantiation() { - Person8 p = defaultJsonb.fromJson("{\"name\":\"Jason Bourne\"}", Person8.class); - assertEquals("Jason Bourne", p.name); - } - - public static class Person9 { - public String name; - - @JsonbDateFormat("dd.MM.yyyy") - public LocalDate birthDate; - - @JsonbNumberFormat("#0.00") - public BigDecimal salary; - } - - @Test - public void testDateNumberFormats1() { - Person9 p = new Person9(); - p.name = "Jason Bourne"; - p.birthDate = LocalDate.of(1999, 8, 7); - p.salary = new BigDecimal("123.45678"); - String json = defaultJsonb.toJson(p); - assertEquals("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":\"123.46\"}", json); - - Person9 after = defaultJsonb.fromJson("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":\"123.46\"}", Person9.class); - assertEquals(p.name, after.name); - assertEquals(p.birthDate, after.birthDate); - assertEquals(new BigDecimal("123.46"), after.salary); - } - - public static class Person10 { - public String name; - - public LocalDate birthDate; - - public BigDecimal salary; - } - - @Test - public void testDateNumberFormats2() { - Person10 p = new Person10(); - p.name = "Jason Bourne"; - p.birthDate = LocalDate.of(1999, 8, 7); - p.salary = new BigDecimal("123.45678"); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()// - .withDateFormat("dd.MM.yyyy", null)); // TODO: why no withNumberFormat? - String json = jsonb.toJson(p); - assertEquals("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}", json); - - Person9 after = jsonb.fromJson("{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}", Person9.class); - assertEquals(p.name, after.name); - assertEquals(p.birthDate, after.birthDate); - assertEquals(p.salary, after.salary); - } - - public static class Customer { - private int id; - private String name; - private String organization; - private String position; - - public int getId() { - return id; - } - public void setId(int id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public String getOrganization() { - return organization; - } - public void setOrganization(String organization) { - this.organization = organization; - } - public String getPosition() { - return position; - } - public void setPosition(String position) { - this.position = position; - } - } - - public static class CustomerAnnotated { - @JsonbProperty("customer_id") - private int id; - - @JsonbProperty("customer_name") - private String name; - - public int getId() { - return id; - } - public void setId(int id) { - this.id = id; - } - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - } - - public static class CustomerAdapter implements JsonbAdapter { - @Override - public CustomerAnnotated adaptToJson(Customer c) throws Exception { - CustomerAnnotated customer = new CustomerAnnotated(); - customer.setId(c.getId()); - customer.setName(c.getName()); - return customer; - } - - @Override - public Customer adaptFromJson(CustomerAnnotated adapted) throws Exception { - Customer customer = new Customer(); - customer.setId(adapted.getId()); - customer.setName(adapted.getName()); - return customer; - } - } - - @Test - public void testAdapters1() { - // Create customer - Customer customer = new Customer(); - - customer.setId(1); - customer.setName("Jason Bourne"); - customer.setOrganization("Super Agents"); - customer.setPosition("Super Agent"); - - // Serialize - String json = defaultJsonb.toJson(customer); - assertEquals("{\"id\":1,\"name\":\"Jason Bourne\",\"organization\":\"Super Agents\",\"position\":\"Super Agent\"}", json); - } - - @Test - public void testAdapters2() { - // Create custom configuration - JsonbConfig config = new JsonbConfig() - .withAdapters(new CustomerAdapter()); - - // Create Jsonb with custom configuration - Jsonb jsonb = JsonbBuilder.create(config); - - // Create customer - Customer customer = new Customer(); - - customer.setId(1); - customer.setName("Jason Bourne"); - customer.setOrganization("Super Agents"); - customer.setPosition("Super Agent"); - - // Serialize - String json = jsonb.toJson(customer); - assertEquals("{\"customer_id\":1,\"customer_name\":\"Jason Bourne\"}", json); - } - - public static class CustomerSerializer implements JsonbSerializer { - @Override - public void serialize(Customer customer, JsonGenerator generator, SerializationContext ctx) { - generator.writeStartObject(); - generator.write("customer_id", customer.getId()); - generator.write("customer_name", customer.getName()); - generator.writeEnd(); - } - } - - public static class CustomerDeserializer implements JsonbDeserializer { - @Override - public Customer deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { - Customer customer = new Customer(); - JsonParser.Event next; - - // Moving parser by hand looking for customer_id and customer_name properties - while ((next = parser.next()) != JsonParser.Event.END_OBJECT) { - if (next == JsonParser.Event.KEY_NAME) { - String jsonKeyName = parser.getString(); - - // Move to json value - parser.next(); - - if ("customer_id".equals(jsonKeyName)) { - customer.setId(parser.getInt()); - } else if ("customer_name".equals(jsonKeyName)) { - customer.setName(parser.getString()); - } - } - } - return customer; - } - } - - @Test - public void testSerializerDeserializer() { - // Create pojo - Customer customer = new Customer(); - customer.setId(1); - customer.setName("Freddie"); - customer.setOrganization("Super Agents"); - customer.setPosition("Super Agent"); - - // Also configurable with @JsonbSerializer / JsonbDeserializer on properties and class. - JsonbConfig config = new JsonbConfig() - .withSerializers(new CustomerSerializer()) - .withDeserializers(new CustomerDeserializer()); - - Jsonb jsonb = JsonbBuilder.create(config); - String json = jsonb.toJson(customer); - assertEquals("{\"customer_id\":1,\"customer_name\":\"Freddie\"}", json); - - Customer result = jsonb.fromJson(json, Customer.class); - assertEquals(customer.getId(), result.getId()); - assertEquals(customer.getName(), result.getName()); - assertNull(result.getOrganization()); - assertNull(result.getPosition()); - } + private static final DecimalFormat DEFAULT_PERSON_SALARY_DECIMAL_FORMAT = new DecimalFormat("#0.00"); + + public static class Dog { + public String name; + public int age; + public boolean bitable; + } + + @Test + public void testMappingExample() { + // Create a dog instance + Dog dog = new Dog(); + dog.name = "Falco"; + dog.age = 4; + dog.bitable = false; + + // Create Jsonb and serialize + String result = defaultJsonb.toJson(dog); + assertEquals("{\"age\":4,\"bitable\":false,\"name\":\"Falco\"}", result); + + // Deserialize back + dog = defaultJsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class); + assertEquals("Falco", dog.name); + assertEquals(4, dog.age); + assertEquals(false, dog.bitable); + } + + @Test + @SuppressWarnings({"rawtypes", "unchecked"}) + public void testMappingCollection() { + Dog falco = new Dog(); + falco.name = "Falco"; + falco.age = 4; + Dog cassidy = new Dog(); + cassidy.name = "Cassidy"; + cassidy.age = 5; + + // List of dogs + List dogs = new ArrayList(); + dogs.add(falco); + dogs.add(cassidy); + + // Create Jsonb and serialize + String result = defaultJsonb.toJson(dogs); + assertEquals( + "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]", + result); + + // We can also deserialize back into a raw collection, but since there is no way + // to infer a type here, + // the result will be a list of java.util.Map instances with string keys. + dogs = defaultJsonb.fromJson(result, ArrayList.class); + assertEquals(2, dogs.size()); + assertEquals("Falco", ((Map) dogs.get(0)).get("name")); + assertEquals("Cassidy", ((Map) dogs.get(1)).get("name")); + // assertEquals(4, ((Map) dogs.get(0)).get("age")); // TODO should these + // actually be BigDecimals? + // assertEquals(5, ((Map) dogs.get(1)).get("age")); + } + + @SuppressWarnings("serial") + @Test + public void testMappingGenericCollection() { + Dog falco = new Dog(); + falco.name = "Falco"; + falco.age = 4; + Dog cassidy = new Dog(); + cassidy.name = "Cassidy"; + cassidy.age = 5; + + // List of dogs + List dogs = new ArrayList<>(); + dogs.add(falco); + dogs.add(cassidy); + + // Create Jsonb and serialize + String result = defaultJsonb.toJson(dogs); + assertEquals( + "[{\"age\":4,\"bitable\":false,\"name\":\"Falco\"},{\"age\":5,\"bitable\":false,\"name\":\"Cassidy\"}]", + result); + + // Deserialize back + dogs = defaultJsonb.fromJson(result, new ArrayList() { + }.getClass().getGenericSuperclass()); + assertEquals(2, dogs.size()); + assertEquals("Falco", dogs.get(0).name); + assertEquals("Cassidy", dogs.get(1).name); + } + + @Test + public void testFormattedOutput() { + Dog pojo = new Dog(); + pojo.name = "Falco"; + pojo.age = 4; + + // Use it! + String result = formattingJsonb.toJson(pojo); + assertEquals("{\n" + + " \"age\": 4,\n" + + " \"bitable\": false,\n" + + " \"name\": \"Falco\"\n" + + "}", result); + } + + public static class Person1 { + @JsonbProperty("person-name") + public String name; + public String profession; + } + + @Test + public void testChangingPropertyNames1() { + Person1 p = new Person1(); + p.name = "Jason Bourne"; + p.profession = "Super Agent"; + + String result = formattingJsonb.toJson(p); + assertEquals("{\n" + + " \"person-name\": \"Jason Bourne\",\n" + + " \"profession\": \"Super Agent\"\n" + + "}", result); + } + + public class Person2 { + private String name; + private String profession; + + @JsonbProperty("person-name") + public String getName() { + return name; + } + + public String getProfession() { + return profession; + } + + // public setters ... + public void setName(String name) { + this.name = name; + } + + public void setProfession(String profession) { + this.profession = profession; + } + } + + @Test + public void testChangingPropertyNames2() { + Person2 p = new Person2(); + p.name = "Jason Bourne"; + p.profession = "Super Agent"; + + String result = formattingJsonb.toJson(p); + assertEquals("{\n" + + " \"person-name\": \"Jason Bourne\",\n" + + " \"profession\": \"Super Agent\"\n" + + "}", result); + } + + public static class Person3 { + private String name; + + @JsonbProperty("name-to-write") + public String getName() { + return name; + } + + @JsonbProperty("name-to-read") + public void setName(String name) { + this.name = name; + } + } + + @Test + public void testChangingPropertyNames3() { + Person3 p = new Person3(); + p.name = "Jason Bourne"; + String result = defaultJsonb.toJson(p); + assertEquals("{\"name-to-write\":\"Jason Bourne\"}", result); + + String json = "{\"name-to-read\":\"Jason Bourne\"}"; + Person3 after = defaultJsonb.fromJson(json, Person3.class); + assertEquals("Jason Bourne", after.name); + } + + public static class Person4 { // TODO: a non-static class results in an NPE + @JsonbTransient + private String name; + + private String profession; + + // public getters/setters ... + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getProfession() { + return this.profession; + } + + public void setProfession(String profession) { + this.profession = profession; + } + } + + @Test + public void testIgnoringProperties() { + Person4 p = new Person4(); + p.name = "Jason Bourne"; + p.profession = "Super Agent"; + String result = defaultJsonb.toJson(p); + assertEquals("{\"profession\":\"Super Agent\"}", result); + + String json = "{\"profession\":\"Super Agent\"}"; + Person4 after = defaultJsonb.fromJson(json, Person4.class); + assertEquals("Super Agent", after.profession); + assertNull(after.name); + } + + @JsonbNillable + public class Person5 { + private String name; + private String profession; + + // public getters/setters ... + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getProfession() { + return profession; + } + + public void setProfession(String profession) { + this.profession = profession; + } + } + + @Test + public void testNullHandling1() { + Person5 p = new Person5(); + String result = defaultJsonb.toJson(p); + assertEquals("{\"name\":null,\"profession\":null}", result); + } + + public class Person6 { + @JsonbProperty(nillable = true) + private String name; + + private String profession; + + // public getters/setters ... + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getProfession() { + return profession; + } + + public void setProfession(String profession) { + this.profession = profession; + } + } + + @Test + public void testNullHandling2() { + Person6 p = new Person6(); + String result = defaultJsonb.toJson(p); + assertEquals("{\"name\":null}", result); + } + + public static class Person { + public String name; + public String profession; + } + + @Test + public void testNullHandling3() { + Person p = new Person(); + String result = nullableJsonb.toJson(p); + assertEquals("{\"name\":null,\"profession\":null}", result); + } + + public static class Person8 { // TODO: obscure error here if non-static + public final String name; + public String profession; + + @JsonbCreator + public Person8(@JsonbProperty("name") String name) { + this.name = name; + } + } + + @Test + public void testCustomInstantiation() { + Person8 p = defaultJsonb.fromJson("{\"name\":\"Jason Bourne\"}", Person8.class); + assertEquals("Jason Bourne", p.name); + } + + public static class Person9 { + public String name; + + @JsonbDateFormat("dd.MM.yyyy") + public LocalDate birthDate; + + @JsonbNumberFormat("#0.00") + public BigDecimal salary; + } + + @Test + public void testDateNumberFormats1() { + Person9 p = new Person9(); + p.name = "Jason Bourne"; + p.birthDate = LocalDate.of(1999, 8, 7); + p.salary = new BigDecimal("123.45678"); + String json = defaultJsonb.toJson(p); + String expectedJson = "{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":\"" + DEFAULT_PERSON_SALARY_DECIMAL_FORMAT.format(p.salary) + + "\"}"; + assertEquals(expectedJson, json); + + Person9 after = defaultJsonb.fromJson(expectedJson, Person9.class); + assertEquals(p.name, after.name); + assertEquals(p.birthDate, after.birthDate); + assertEquals(new BigDecimal("123.46"), after.salary); + } + + public static class Person10 { + public String name; + + public LocalDate birthDate; + + public BigDecimal salary; + } + + @Test + public void testDateNumberFormats2() { + Person10 p = new Person10(); + p.name = "Jason Bourne"; + p.birthDate = LocalDate.of(1999, 8, 7); + p.salary = new BigDecimal("123.45678"); + Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()// + .withDateFormat("dd.MM.yyyy", null)); // TODO: why no withNumberFormat? + String json = jsonb.toJson(p); + String expectedJson = "{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}"; + assertEquals(expectedJson, json); + + Person10 after = jsonb.fromJson(expectedJson, Person10.class); + assertEquals(p.name, after.name); + assertEquals(p.birthDate, after.birthDate); + assertEquals(p.salary, after.salary); + } + + public static class Customer { + private int id; + private String name; + private String organization; + private String position; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + } + + public static class CustomerAnnotated { + @JsonbProperty("customer_id") + private int id; + + @JsonbProperty("customer_name") + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class CustomerAdapter implements JsonbAdapter { + @Override + public CustomerAnnotated adaptToJson(Customer c) throws Exception { + CustomerAnnotated customer = new CustomerAnnotated(); + customer.setId(c.getId()); + customer.setName(c.getName()); + return customer; + } + + @Override + public Customer adaptFromJson(CustomerAnnotated adapted) throws Exception { + Customer customer = new Customer(); + customer.setId(adapted.getId()); + customer.setName(adapted.getName()); + return customer; + } + } + + @Test + public void testAdapters1() { + // Create customer + Customer customer = new Customer(); + + customer.setId(1); + customer.setName("Jason Bourne"); + customer.setOrganization("Super Agents"); + customer.setPosition("Super Agent"); + + // Serialize + String json = defaultJsonb.toJson(customer); + assertEquals("{\"id\":1,\"name\":\"Jason Bourne\",\"organization\":\"Super Agents\",\"position\":\"Super Agent\"}", json); + } + + @Test + public void testAdapters2() { + // Create custom configuration + JsonbConfig config = new JsonbConfig() + .withAdapters(new CustomerAdapter()); + + // Create Jsonb with custom configuration + Jsonb jsonb = JsonbBuilder.create(config); + + // Create customer + Customer customer = new Customer(); + + customer.setId(1); + customer.setName("Jason Bourne"); + customer.setOrganization("Super Agents"); + customer.setPosition("Super Agent"); + + // Serialize + String json = jsonb.toJson(customer); + assertEquals("{\"customer_id\":1,\"customer_name\":\"Jason Bourne\"}", json); + } + + public static class CustomerSerializer implements JsonbSerializer { + @Override + public void serialize(Customer customer, JsonGenerator generator, SerializationContext ctx) { + generator.writeStartObject(); + generator.write("customer_id", customer.getId()); + generator.write("customer_name", customer.getName()); + generator.writeEnd(); + } + } + + public static class CustomerDeserializer implements JsonbDeserializer { + @Override + public Customer deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + Customer customer = new Customer(); + JsonParser.Event next; + + // Moving parser by hand looking for customer_id and customer_name properties + while ((next = parser.next()) != JsonParser.Event.END_OBJECT) { + if (next == JsonParser.Event.KEY_NAME) { + String jsonKeyName = parser.getString(); + + // Move to json value + parser.next(); + + if ("customer_id".equals(jsonKeyName)) { + customer.setId(parser.getInt()); + } else if ("customer_name".equals(jsonKeyName)) { + customer.setName(parser.getString()); + } + } + } + return customer; + } + } + + @Test + public void testSerializerDeserializer() { + // Create pojo + Customer customer = new Customer(); + customer.setId(1); + customer.setName("Freddie"); + customer.setOrganization("Super Agents"); + customer.setPosition("Super Agent"); + + // Also configurable with @JsonbSerializer / JsonbDeserializer on properties and class. + JsonbConfig config = new JsonbConfig() + .withSerializers(new CustomerSerializer()) + .withDeserializers(new CustomerDeserializer()); + + Jsonb jsonb = JsonbBuilder.create(config); + String json = jsonb.toJson(customer); + assertEquals("{\"customer_id\":1,\"customer_name\":\"Freddie\"}", json); + + Customer result = jsonb.fromJson(json, Customer.class); + assertEquals(customer.getId(), result.getId()); + assertEquals(customer.getName(), result.getName()); + assertNull(result.getOrganization()); + assertNull(result.getPosition()); + } } From 84f05f194510945151e20cc73a3367a734e18eef Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Tue, 31 Oct 2023 18:52:11 +0100 Subject: [PATCH 29/68] [#620]Reduced the number of the warning for the raw generic types usage; only three cases in the wrong test are left Signed-off-by: Anton Pinsky --- .../internal/AnnotationIntrospector.java | 48 +++++--- .../yasson/internal/ComponentMatcher.java | 110 ++++++++++-------- .../VariableTypeInheritanceSearch.java | 10 +- .../internal/components/AdapterBinding.java | 13 ++- .../BeanManagerInstanceCreator.java | 9 +- .../components/ComponentBindings.java | 30 +++-- .../deserializer/AdapterDeserializer.java | 6 +- .../DeserializationModelCreator.java | 10 +- .../yasson/internal/model/CreatorModel.java | 4 +- .../yasson/internal/model/PropertyModel.java | 4 +- .../ComponentBoundCustomization.java | 6 +- .../customization/CustomizationBase.java | 12 +- .../customization/PropertyCustomization.java | 18 +-- .../serializer/AdapterSerializer.java | 6 +- .../serializer/SerializationModelCreator.java | 10 +- .../yasson/adapters/JsonbTypeAdapterTest.java | 6 +- .../model/LocalPolymorphicAdapter.java | 4 +- .../ImplementationClassTest.java | 4 +- .../collections/CollectionsTest.java | 13 ++- .../defaultmapping/generics/GenericsTest.java | 7 +- .../model/MultipleBoundsContainer.java | 10 +- .../defaultmapping/specific/OptionalTest.java | 6 +- .../internal/cdi/MockInjectionTarget.java | 15 +-- .../cdi/MockInjectionTargetFactory.java | 6 +- .../yasson/internal/cdi/WeldManager.java | 4 +- .../JsonStructureToParserAdapterTest.java | 15 ++- .../MapToObjectSerializerTest.java | 4 +- 27 files changed, 220 insertions(+), 170 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java index 36c29431..8102235f 100644 --- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java +++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java @@ -222,7 +222,7 @@ JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Cl * @param property property not null * @return components info */ - public AdapterBinding getAdapterBinding(Property property) { + public AdapterBinding getAdapterBinding(Property property) { Objects.requireNonNull(property); JsonbTypeAdapter adapterAnnotation = getAnnotationFromProperty(JsonbTypeAdapter.class, property) .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeAdapter.class)); @@ -239,7 +239,7 @@ public AdapterBinding getAdapterBinding(Property property) { * @param clsElement type not null * @return components info */ - public AdapterBinding getAdapterBinding(JsonbAnnotatedElement> clsElement) { + public AdapterBinding getAdapterBinding(JsonbAnnotatedElement> clsElement) { Objects.requireNonNull(clsElement); JsonbTypeAdapter adapterAnnotation = clsElement.getElement().getAnnotation(JsonbTypeAdapter.class); @@ -250,9 +250,11 @@ public AdapterBinding getAdapterBinding(JsonbAnnotatedElement> clsEleme return getAdapterBindingFromAnnotation(adapterAnnotation, Optional.ofNullable(clsElement.getElement())); } - private AdapterBinding getAdapterBindingFromAnnotation(JsonbTypeAdapter adapterAnnotation, Optional> expectedClass) { + private AdapterBinding getAdapterBindingFromAnnotation(JsonbTypeAdapter adapterAnnotation, Optional> expectedClass) { + @SuppressWarnings("rawtypes") final Class adapterClass = adapterAnnotation.value(); - final AdapterBinding adapterBinding = jsonbContext.getComponentMatcher().introspectAdapterBinding(adapterClass, null); + @SuppressWarnings("unchecked") + final AdapterBinding adapterBinding = jsonbContext.getComponentMatcher().introspectAdapterBinding(adapterClass, null); if (expectedClass.isPresent() && !( ReflectionUtils.getRawType(adapterBinding.getBindingType()).isAssignableFrom(expectedClass.get()))) { @@ -269,7 +271,7 @@ private AdapterBinding getAdapterBindingFromAnnotation(JsonbTypeAdapter adapterA * @param property property not null * @return components info */ - public DeserializerBinding getDeserializerBinding(Property property) { + public DeserializerBinding getDeserializerBinding(Property property) { Objects.requireNonNull(property); JsonbTypeDeserializer deserializerAnnotation = getAnnotationFromProperty(JsonbTypeDeserializer.class, property) .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeDeserializer.class)); @@ -277,8 +279,11 @@ public DeserializerBinding getDeserializerBinding(Property property) { return null; } + @SuppressWarnings("rawtypes") final Class deserializerClass = deserializerAnnotation.value(); - return jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + @SuppressWarnings("unchecked") + DeserializerBinding deserializerBinding = jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + return deserializerBinding; } /** @@ -296,8 +301,11 @@ public DeserializerBinding getDeserializerBinding(Parameter parameter) { return null; } + @SuppressWarnings("rawtypes") final Class deserializerClass = deserializerAnnotation.value(); - return jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + @SuppressWarnings("unchecked") + DeserializerBinding deserializerBinding = jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + return deserializerBinding; } /** @@ -306,7 +314,7 @@ public DeserializerBinding getDeserializerBinding(Parameter parameter) { * @param parameter parameter not null * @return components info */ - public AdapterBinding getAdapterBinding(Parameter parameter) { + public AdapterBinding getAdapterBinding(Parameter parameter) { Objects.requireNonNull(parameter); JsonbTypeAdapter adapter = Optional.ofNullable(parameter.getDeclaredAnnotation(JsonbTypeAdapter.class)) @@ -331,15 +339,18 @@ private T getAnnotationFromParameterType(Parameter parame * @param clsElement type not null * @return components info */ - public DeserializerBinding getDeserializerBinding(JsonbAnnotatedElement> clsElement) { + public DeserializerBinding getDeserializerBinding(JsonbAnnotatedElement> clsElement) { Objects.requireNonNull(clsElement); JsonbTypeDeserializer deserializerAnnotation = clsElement.getElement().getAnnotation(JsonbTypeDeserializer.class); if (deserializerAnnotation == null) { return null; } + @SuppressWarnings("rawtypes") final Class deserializerClass = deserializerAnnotation.value(); - return jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + @SuppressWarnings("unchecked") + DeserializerBinding deserializerBinding = jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); + return deserializerBinding; } /** @@ -348,7 +359,7 @@ public DeserializerBinding getDeserializerBinding(JsonbAnnotatedElement * @param property property not null * @return components info */ - public SerializerBinding getSerializerBinding(Property property) { + public SerializerBinding getSerializerBinding(Property property) { Objects.requireNonNull(property); JsonbTypeSerializer serializerAnnotation = getAnnotationFromProperty(JsonbTypeSerializer.class, property) .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeSerializer.class)); @@ -356,9 +367,11 @@ public SerializerBinding getSerializerBinding(Property property) { return null; } + @SuppressWarnings("rawtypes") final Class serializerClass = serializerAnnotation.value(); - return jsonbContext.getComponentMatcher().introspectSerializerBinding(serializerClass, null); - + @SuppressWarnings("unchecked") + SerializerBinding serializerBinding = jsonbContext.getComponentMatcher().introspectSerializerBinding(serializerClass, null); + return serializerBinding; } /** @@ -367,15 +380,18 @@ public SerializerBinding getSerializerBinding(Property property) { * @param clsElement type not null * @return components info */ - public SerializerBinding getSerializerBinding(JsonbAnnotatedElement> clsElement) { + public SerializerBinding getSerializerBinding(JsonbAnnotatedElement> clsElement) { Objects.requireNonNull(clsElement); JsonbTypeSerializer serializerAnnotation = clsElement.getElement().getAnnotation(JsonbTypeSerializer.class); if (serializerAnnotation == null) { return null; } + @SuppressWarnings("rawtypes") final Class serializerClass = serializerAnnotation.value(); - return jsonbContext.getComponentMatcher().introspectSerializerBinding(serializerClass, null); + @SuppressWarnings("unchecked") + SerializerBinding serializerBinding = jsonbContext.getComponentMatcher().introspectSerializerBinding(serializerClass, null); + return serializerBinding; } private T getAnnotationFromPropertyType(Property property, Class annotationClass) { @@ -476,7 +492,7 @@ public Map getJsonbDateFormatCategorized(P Map annotationFromPropertyCategorized = getAnnotationFromPropertyCategorized( JsonbDateFormat.class, property); - if (annotationFromPropertyCategorized.size() != 0) { + if (!annotationFromPropertyCategorized.isEmpty()) { annotationFromPropertyCategorized.forEach((key, annotation) -> result .put(key, createJsonbDateFormatter(annotation.value(), annotation.locale(), property))); } diff --git a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java index b4a2cf83..ab5825d4 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, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -46,7 +46,7 @@ public class ComponentMatcher { */ private volatile boolean genericComponents; - private final ConcurrentMap userComponents; + private final ConcurrentMap> userComponents; /** * Create component matcher. @@ -67,12 +67,14 @@ void init() { final JsonbSerializer[] serializers = (JsonbSerializer[]) jsonbContext.getConfig() .getProperty(JsonbConfig.SERIALIZERS).orElseGet(() -> new JsonbSerializer[] {}); for (JsonbSerializer serializer : serializers) { + @SuppressWarnings("unchecked") SerializerBinding serializerBinding = introspectSerializerBinding(serializer.getClass(), serializer); addSerializer(serializerBinding.getBindingType(), serializerBinding); } final JsonbDeserializer[] deserializers = (JsonbDeserializer[]) jsonbContext.getConfig() .getProperty(JsonbConfig.DESERIALIZERS).orElseGet(() -> new JsonbDeserializer[] {}); for (JsonbDeserializer deserializer : deserializers) { + @SuppressWarnings("unchecked") DeserializerBinding deserializerBinding = introspectDeserializerBinding(deserializer.getClass(), deserializer); addDeserializer(deserializerBinding.getBindingType(), deserializerBinding); } @@ -80,43 +82,52 @@ void init() { final JsonbAdapter[] adapters = (JsonbAdapter[]) jsonbContext.getConfig().getProperty(JsonbConfig.ADAPTERS) .orElseGet(() -> new JsonbAdapter[] {}); for (JsonbAdapter adapter : adapters) { - AdapterBinding adapterBinding = introspectAdapterBinding(adapter.getClass(), adapter); + @SuppressWarnings("unchecked") + AdapterBinding adapterBinding = introspectAdapterBinding(adapter.getClass(), adapter); addAdapter(adapterBinding.getBindingType(), adapterBinding); } } - private ComponentBindings getBindingInfo(Type type) { + private ComponentBindings getBindingInfo(Type type) { return userComponents - .compute(type, (type1, bindingInfo) -> bindingInfo != null ? bindingInfo : new ComponentBindings(type1)); + .compute(type, (type1, bindingInfo) -> bindingInfo != null ? bindingInfo : new ComponentBindings<>(type1)); } - private void addSerializer(Type bindingType, SerializerBinding serializer) { + private void addSerializer(Type bindingType, SerializerBinding serializer) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { if (bindings.getSerializer() != null) { return bindings; } registerGeneric(bindingType); - return new ComponentBindings(bindingType, serializer, bindings.getDeserializer(), bindings.getAdapterInfo()); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindings componentBindings = + new ComponentBindings(bindingType, serializer, bindings.getDeserializer(), bindings.getAdapterInfo()); + return componentBindings; }); } - private void addDeserializer(Type bindingType, DeserializerBinding deserializer) { + private void addDeserializer(Type bindingType, DeserializerBinding deserializer) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { if (bindings.getDeserializer() != null) { return bindings; } registerGeneric(bindingType); - return new ComponentBindings(bindingType, bindings.getSerializer(), deserializer, bindings.getAdapterInfo()); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindings componentBindings = + new ComponentBindings(bindingType, bindings.getSerializer(), deserializer, bindings.getAdapterInfo()); + return componentBindings; }); } - private void addAdapter(Type bindingType, AdapterBinding adapter) { + private void addAdapter(Type bindingType, AdapterBinding adapter) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { if (bindings.getAdapterInfo() != null) { return bindings; } registerGeneric(bindingType); - return new ComponentBindings(bindingType, bindings.getSerializer(), bindings.getDeserializer(), adapter); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindings componentBindings = new ComponentBindings(bindingType, bindings.getSerializer(), bindings.getDeserializer(), adapter); + return componentBindings; }); } @@ -170,7 +181,7 @@ public Optional> getDeserializerBinding(Type propertyRunt * @param customization customization with component info * @return components info if present */ - public Optional getSerializeAdapterBinding(Type propertyRuntimeType, + public Optional> getSerializeAdapterBinding(Type propertyRuntimeType, ComponentBoundCustomization customization) { if (customization == null || customization.getSerializeAdapterBinding() == null) { return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterInfo); @@ -186,7 +197,7 @@ public Optional getSerializeAdapterBinding(Type propertyRuntimeT * @param customization customization with component info * @return components info if present */ - public Optional getDeserializeAdapterBinding(Type propertyRuntimeType, + public Optional> getDeserializeAdapterBinding(Type propertyRuntimeType, ComponentBoundCustomization customization) { if (customization == null || customization.getDeserializeAdapterBinding() == null) { return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterInfo); @@ -194,26 +205,20 @@ public Optional getDeserializeAdapterBinding(Type propertyRuntim return Optional.of(customization.getDeserializeAdapterBinding()); } - private Optional searchComponentBinding(Type runtimeType, Function supplier) { + private Optional searchComponentBinding(Type runtimeType, Function, T> supplier) { // First check if there is an exact match - ComponentBindings binding = userComponents.get(runtimeType); - if (binding != null) { - Optional match = getMatchingBinding(runtimeType, binding, supplier); - if (match.isPresent()) { - return match; - } + Optional match = getMatchingBinding(runtimeType, supplier); + if (match.isPresent()) { + return match; } - + Optional> runtimeClass = ReflectionUtils.getOptionalRawType(runtimeType); if (runtimeClass.isPresent()) { // Check if any interfaces have a match for (Class ifc : runtimeClass.get().getInterfaces()) { - ComponentBindings ifcBinding = userComponents.get(ifc); - if (ifcBinding != null) { - Optional match = getMatchingBinding(ifc, ifcBinding, supplier); - if (match.isPresent()) { - return match; - } + match = getMatchingBinding(ifc, supplier); + if (match.isPresent()) { + return match; } } @@ -229,11 +234,24 @@ private Optional searchComponentBinding( return Optional.empty(); } - - private Optional getMatchingBinding(Type runtimeType, ComponentBindings binding, Function supplier) { - final T component = supplier.apply(binding); - if (component != null && matches(runtimeType, binding.getBindingType())) { - return Optional.of(component); + + private Optional getMatchingBinding(Type runtimeType, Function, T> supplier) { + ComponentBindings binding = userComponents.get(runtimeType); + if (binding != null) { + Optional match = getMatchingBinding(runtimeType, binding, supplier); + if (match.isPresent()) { + return match; + } + } + return Optional.empty(); + } + + private Optional getMatchingBinding(Type runtimeType, ComponentBindings binding, Function, T> supplier) { + if (matches(runtimeType, binding.getBindingType())) { + final T component = supplier.apply(binding); + if (component != null) { + return Optional.of(component); + } } return Optional.empty(); } @@ -282,20 +300,20 @@ private boolean matchTypeArguments(ParameterizedType requiredType, Parameterized * @param instance components instance * @return introspected info with resolved typevar types. */ - AdapterBinding introspectAdapterBinding(Class adapterClass, JsonbAdapter instance) { + > AdapterBinding introspectAdapterBinding(Class adapterClass, A instance) { final ParameterizedType adapterRuntimeType = ReflectionUtils.findParameterizedType(adapterClass, JsonbAdapter.class); final Type[] adapterTypeArguments = adapterRuntimeType.getActualTypeArguments(); Type adaptFromType = resolveTypeArg(adapterTypeArguments[0], adapterClass); Type adaptToType = resolveTypeArg(adapterTypeArguments[1], adapterClass); - final ComponentBindings componentBindings = getBindingInfo(adaptFromType); + final ComponentBindings componentBindings = getBindingInfo(adaptFromType); if (componentBindings.getAdapterInfo() != null && componentBindings.getAdapterInfo().getAdapter().getClass() .equals(adapterClass)) { return componentBindings.getAdapterInfo(); } - JsonbAdapter newAdapter = instance != null + A newAdapter = instance != null ? instance : jsonbContext.getComponentInstanceCreator().getOrCreateComponent(adapterClass); - return new AdapterBinding(adaptFromType, adaptToType, newAdapter); + return new AdapterBinding<>(adaptFromType, adaptToType, newAdapter); } /** @@ -306,20 +324,18 @@ AdapterBinding introspectAdapterBinding(Class adapterCla * @param instance instance to use if not cached already * @return wrapper used in property models */ - @SuppressWarnings("unchecked") - DeserializerBinding introspectDeserializerBinding(Class deserializerClass, - JsonbDeserializer instance) { + > DeserializerBinding introspectDeserializerBinding(Class deserializerClass, D instance) { final ParameterizedType deserializerRuntimeType = ReflectionUtils .findParameterizedType(deserializerClass, JsonbDeserializer.class); Type deserializerBindingType = resolveTypeArg(deserializerRuntimeType.getActualTypeArguments()[0], deserializerClass); - final ComponentBindings componentBindings = getBindingInfo(deserializerBindingType); + final ComponentBindings componentBindings = getBindingInfo(deserializerBindingType); if (componentBindings.getDeserializer() != null && componentBindings.getDeserializer().getClass() .equals(deserializerClass)) { return componentBindings.getDeserializer(); } else { - JsonbDeserializer deserializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() + D deserializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() .getOrCreateComponent(deserializerClass); - return new DeserializerBinding(deserializerBindingType, deserializer); + return new DeserializerBinding<>(deserializerBindingType, deserializer); } } @@ -331,18 +347,18 @@ DeserializerBinding introspectDeserializerBinding(Class serializerClass, JsonbSerializer instance) { + + > SerializerBinding introspectSerializerBinding(Class serializerClass, S instance) { final ParameterizedType serializerRuntimeType = ReflectionUtils .findParameterizedType(serializerClass, JsonbSerializer.class); Type serBindingType = resolveTypeArg(serializerRuntimeType.getActualTypeArguments()[0], serializerClass); - final ComponentBindings componentBindings = getBindingInfo(serBindingType); + final ComponentBindings componentBindings = getBindingInfo(serBindingType); if (componentBindings.getSerializer() != null && componentBindings.getSerializer().getClass().equals(serializerClass)) { return componentBindings.getSerializer(); } else { - JsonbSerializer serializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() + S serializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() .getOrCreateComponent(serializerClass); - return new SerializerBinding(serBindingType, serializer); + return new SerializerBinding<>(serBindingType, serializer); } } diff --git a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java index 263cc4e2..1a144f10 100644 --- a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java +++ b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -86,7 +86,7 @@ Type searchParametrizedType(Type typeToSearch, TypeVariable typeVar) { return searchParametrizedType(((Class) parameterizedType.getRawType()).getGenericSuperclass(), typeVar); } - private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { + private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { if (parameterizedSubclasses.size() == 0) { return typeVar; } @@ -94,17 +94,17 @@ private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { return searchRuntimeTypeArgument(parametrizedSubclass, typeVar); } - private Type searchRuntimeTypeArgument(ParameterizedType runtimeType, TypeVariable typeVar) { + private Type searchRuntimeTypeArgument(ParameterizedType runtimeType, TypeVariable typeVar) { if (ReflectionUtils.getRawType(runtimeType) != typeVar.getGenericDeclaration()) { return null; } - TypeVariable[] bounds = typeVar.getGenericDeclaration().getTypeParameters(); + TypeVariable[] bounds = typeVar.getGenericDeclaration().getTypeParameters(); for (int i = 0; i < bounds.length; i++) { if (bounds[i].equals(typeVar)) { Type matchedGenericType = runtimeType.getActualTypeArguments()[i]; //Propagated generic types to another generic classes if (matchedGenericType instanceof TypeVariable) { - return checkSubclassRuntimeInfo((TypeVariable) matchedGenericType); + return checkSubclassRuntimeInfo((TypeVariable) matchedGenericType); } //found runtime matchedGenericType return matchedGenericType; diff --git a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java index 16c57d7a..d9dffc0c 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -19,12 +19,15 @@ /** * Wrapper for JsonbAdapter generic information and an components itself. + * + * @param The type for the @{@link JsonbAdapter} that JSONB doesn't know how to handle. + * @param The type for the @{@link JsonbAdapter} that JSONB knows how to handle out of the box. */ -public class AdapterBinding extends AbstractComponentBinding { +public class AdapterBinding extends AbstractComponentBinding { private final Type toType; - private final JsonbAdapter adapter; + private final JsonbAdapter adapter; /** * Adapter info with type to "adapt from", type to "adapt to" and an components itself. @@ -33,7 +36,7 @@ public class AdapterBinding extends AbstractComponentBinding { * @param toType to not null * @param adapter components not null */ - public AdapterBinding(Type fromType, Type toType, JsonbAdapter adapter) { + public AdapterBinding(Type fromType, Type toType, JsonbAdapter adapter) { super(fromType); Objects.requireNonNull(toType); Objects.requireNonNull(adapter); @@ -58,7 +61,7 @@ public Type getToType() { * * @return components */ - public JsonbAdapter getAdapter() { + public JsonbAdapter getAdapter() { return adapter; } diff --git a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java index 456015a0..29e7f024 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -61,9 +61,9 @@ public BeanManagerInstanceCreator(Object beanManager) { * @return New instance of bean class with injected content. */ @Override - @SuppressWarnings("unchecked") public T getOrCreateComponent(Class componentClass) { - return (T) injectionTargets.computeIfAbsent(componentClass, clazz -> { + @SuppressWarnings("unchecked") + T instance = (T) injectionTargets.computeIfAbsent(componentClass, clazz -> { final AnnotatedType aType = beanManager.createAnnotatedType(componentClass); final InjectionTarget injectionTarget = beanManager.getInjectionTargetFactory(aType) .createInjectionTarget(null); @@ -71,8 +71,9 @@ public T getOrCreateComponent(Class componentClass) { final T beanInstance = injectionTarget.produce(creationalContext); injectionTarget.inject(beanInstance, creationalContext); injectionTarget.postConstruct(beanInstance); - return new CDIManagedBean(beanInstance, injectionTarget, creationalContext); + return new CDIManagedBean(beanInstance, injectionTarget, creationalContext); }).getInstance(); + return instance; } @Override diff --git a/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java b/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java index 3033bd5b..43ce0ec7 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java +++ b/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -14,18 +14,26 @@ import java.lang.reflect.Type; +import jakarta.json.bind.adapter.JsonbAdapter; +import jakarta.json.bind.serializer.JsonbDeserializer; +import jakarta.json.bind.serializer.JsonbSerializer; + /** * Wrapper holding singleton instances of user defined components - Adapters, (De)Serializers. + * + * @param The type for the @{@link JsonbAdapter} that JSONB doesn't know how to handle. + * Also type for the @{@link JsonbSerializer} to serialize and for the @{@link JsonbDeserializer} to deserialize. + * @param The type for @{@link JsonbAdapter} that JSONB knows how to handle out of the box. */ -public class ComponentBindings { +public class ComponentBindings { private final Type bindingType; - private final SerializerBinding serializer; + private final SerializerBinding serializer; - private final DeserializerBinding deserializer; + private final DeserializerBinding deserializer; - private final AdapterBinding adapterInfo; + private final AdapterBinding adapterInfo; /** * Construct empty bindings for a given type. @@ -45,9 +53,9 @@ public ComponentBindings(Type bindingType) { * @param adapter Adapter. */ public ComponentBindings(Type bindingType, - SerializerBinding serializer, - DeserializerBinding deserializer, - AdapterBinding adapter) { + SerializerBinding serializer, + DeserializerBinding deserializer, + AdapterBinding adapter) { this.bindingType = bindingType; this.serializer = serializer; this.deserializer = deserializer; @@ -68,7 +76,7 @@ public Type getBindingType() { * * @return serializer */ - public SerializerBinding getSerializer() { + public SerializerBinding getSerializer() { return serializer; } @@ -77,7 +85,7 @@ public SerializerBinding getSerializer() { * * @return deserializer */ - public DeserializerBinding getDeserializer() { + public DeserializerBinding getDeserializer() { return deserializer; } @@ -86,7 +94,7 @@ public DeserializerBinding getDeserializer() { * * @return adapterInfo */ - public AdapterBinding getAdapterInfo() { + public AdapterBinding getAdapterInfo() { return adapterInfo; } diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java index b54e72ab..7d7775f0 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -26,11 +26,11 @@ class AdapterDeserializer implements ModelDeserializer { private final JsonbAdapter adapter; - private final AdapterBinding adapterBinding; + private final AdapterBinding adapterBinding; private final ModelDeserializer delegate; @SuppressWarnings("unchecked") - AdapterDeserializer(AdapterBinding adapterBinding, + AdapterDeserializer(AdapterBinding adapterBinding, ModelDeserializer delegate) { this.adapterBinding = adapterBinding; this.adapter = (JsonbAdapter) adapterBinding.getAdapter(); diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java index b381c1b9..7e4a29d1 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java @@ -163,9 +163,9 @@ private ModelDeserializer deserializerChainInternal(LinkedList return user; } - Optional adapterBinding = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization); + Optional> adapterBinding = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization); if (adapterBinding.isPresent()) { - AdapterBinding adapter = adapterBinding.get(); + AdapterBinding adapter = adapterBinding.get(); Class toType = ReflectionUtils.getRawType(adapter.getToType()); ClassModel targetModel = jsonbContext.getMappingContext().getOrCreateClassModel(toType); ModelDeserializer typeDeserializer = typeDeserializer(toType, @@ -399,7 +399,7 @@ private Function propertyRenamer() { : value -> value; } - private Optional adapterBinding(Type type, ComponentBoundCustomization classCustomization) { + private Optional> adapterBinding(Type type, ComponentBoundCustomization classCustomization) { return jsonbContext.getComponentMatcher().getDeserializeAdapterBinding(type, classCustomization); } @@ -453,9 +453,9 @@ private ModelDeserializer typeProcessor(LinkedList chain, resolved, customization); } - Optional adapterBinding = adapterBinding(resolved, (ComponentBoundCustomization) customization); + Optional> adapterBinding = adapterBinding(resolved, (ComponentBoundCustomization) customization); if (adapterBinding.isPresent()) { - AdapterBinding adapter = adapterBinding.get(); + AdapterBinding adapter = adapterBinding.get(); ModelDeserializer typeDeserializer = typeDeserializer(ReflectionUtils.getRawType(adapter.getToType()), customization, JustReturn.instance(), events); diff --git a/src/main/java/org/eclipse/yasson/internal/model/CreatorModel.java b/src/main/java/org/eclipse/yasson/internal/model/CreatorModel.java index 3ab3d905..60da62d4 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/CreatorModel.java +++ b/src/main/java/org/eclipse/yasson/internal/model/CreatorModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -54,7 +54,7 @@ public CreatorModel(String name, Parameter parameter, Executable executable, Jso .getConstructorNumberFormatter(annotated); JsonbDateFormatter constructorDateFormatter = context.getAnnotationIntrospector().getConstructorDateFormatter(annotated); DeserializerBinding deserializerBinding = annotationIntrospector.getDeserializerBinding(parameter); - AdapterBinding adapterBinding = annotationIntrospector.getAdapterBinding(parameter); + AdapterBinding adapterBinding = annotationIntrospector.getAdapterBinding(parameter); final JsonbAnnotatedElement> clsElement = annotationIntrospector.collectAnnotations(parameter.getType()); deserializerBinding = deserializerBinding == null ? annotationIntrospector.getDeserializerBinding(clsElement) diff --git a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java index 707b03a6..0a243e90 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java +++ b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -243,7 +243,7 @@ private PropertyCustomization introspectCustomization(Property property, JsonbCo builder.deserializerBinding(introspector.getDeserializerBinding(property)); } - final AdapterBinding adapterBinding = jsonbContext.getAnnotationIntrospector().getAdapterBinding(property); + final AdapterBinding adapterBinding = jsonbContext.getAnnotationIntrospector().getAdapterBinding(property); if (adapterBinding != null) { builder.serializeAdapter(adapterBinding); builder.deserializeAdapter(adapterBinding); diff --git a/src/main/java/org/eclipse/yasson/internal/model/customization/ComponentBoundCustomization.java b/src/main/java/org/eclipse/yasson/internal/model/customization/ComponentBoundCustomization.java index e964ed80..4a237793 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/customization/ComponentBoundCustomization.java +++ b/src/main/java/org/eclipse/yasson/internal/model/customization/ComponentBoundCustomization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -24,12 +24,12 @@ public interface ComponentBoundCustomization { /** * @return Adapter wrapper class with resolved generic information. */ - AdapterBinding getSerializeAdapterBinding(); + AdapterBinding getSerializeAdapterBinding(); /** * @return Adapter wrapper class with resolved generic information. */ - AdapterBinding getDeserializeAdapterBinding(); + AdapterBinding getDeserializeAdapterBinding(); /** * Serializer wrapper with resolved generic info. diff --git a/src/main/java/org/eclipse/yasson/internal/model/customization/CustomizationBase.java b/src/main/java/org/eclipse/yasson/internal/model/customization/CustomizationBase.java index 2b49180d..9e920e7c 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/customization/CustomizationBase.java +++ b/src/main/java/org/eclipse/yasson/internal/model/customization/CustomizationBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -21,7 +21,7 @@ */ abstract class CustomizationBase implements Customization, ComponentBoundCustomization { - private final AdapterBinding adapterBinding; + private final AdapterBinding adapterBinding; private final SerializerBinding serializerBinding; private final DeserializerBinding deserializerBinding; private final boolean nillable; @@ -47,12 +47,12 @@ public boolean isNillable() { return nillable; } - public AdapterBinding getSerializeAdapterBinding() { + public AdapterBinding getSerializeAdapterBinding() { return adapterBinding; } @Override - public AdapterBinding getDeserializeAdapterBinding() { + public AdapterBinding getDeserializeAdapterBinding() { return adapterBinding; } @@ -77,7 +77,7 @@ public DeserializerBinding getDeserializerBinding() { @SuppressWarnings("unchecked") abstract static class Builder, B extends CustomizationBase> { - private AdapterBinding adapterBinding; + private AdapterBinding adapterBinding; private SerializerBinding serializerBinding; private DeserializerBinding deserializerBinding; private boolean nillable; @@ -93,7 +93,7 @@ public T of(B customization) { return (T) this; } - public T adapterBinding(AdapterBinding adapterBinding) { + public T adapterBinding(AdapterBinding adapterBinding) { this.adapterBinding = adapterBinding; return (T) this; } diff --git a/src/main/java/org/eclipse/yasson/internal/model/customization/PropertyCustomization.java b/src/main/java/org/eclipse/yasson/internal/model/customization/PropertyCustomization.java index 022e458b..747cb8c2 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/customization/PropertyCustomization.java +++ b/src/main/java/org/eclipse/yasson/internal/model/customization/PropertyCustomization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -30,8 +30,8 @@ public class PropertyCustomization extends CustomizationBase { private final JsonbDateFormatter serializeDateFormatter; private final JsonbDateFormatter deserializeDateFormatter; - private final AdapterBinding serializeAdapter; - private final AdapterBinding deserializeAdapter; + private final AdapterBinding serializeAdapter; + private final AdapterBinding deserializeAdapter; private final boolean readTransient; private final boolean writeTransient; @@ -132,12 +132,12 @@ public Class getImplementationClass() { } @Override - public AdapterBinding getDeserializeAdapterBinding() { + public AdapterBinding getDeserializeAdapterBinding() { return deserializeAdapter; } @Override - public AdapterBinding getSerializeAdapterBinding() { + public AdapterBinding getSerializeAdapterBinding() { return serializeAdapter; } @@ -149,8 +149,8 @@ public static final class Builder extends CustomizationBase.Builder serializeAdapter; + private AdapterBinding deserializeAdapter; private boolean readTransient; private boolean writeTransient; private Class implementationClass; @@ -234,12 +234,12 @@ public Builder deserializeDateFormatter(JsonbDateFormatter deserializeDateFormat return this; } - public Builder serializeAdapter(AdapterBinding serializeAdapter) { + public Builder serializeAdapter(AdapterBinding serializeAdapter) { this.serializeAdapter = serializeAdapter; return this; } - public Builder deserializeAdapter(AdapterBinding deserializeAdapter) { + public Builder deserializeAdapter(AdapterBinding deserializeAdapter) { this.deserializeAdapter = deserializeAdapter; return this; } diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java index 582c581d..673a31f0 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -27,10 +27,10 @@ class AdapterSerializer extends AbstractSerializer { private final JsonbAdapter adapter; - private final AdapterBinding adapterBinding; + private final AdapterBinding adapterBinding; @SuppressWarnings("unchecked") - AdapterSerializer(AdapterBinding adapterBinding, + AdapterSerializer(AdapterBinding adapterBinding, ModelSerializer delegate) { super(delegate); this.adapter = (JsonbAdapter) adapterBinding.getAdapter(); diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java index 1d73ce60..8e24ac65 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java @@ -152,9 +152,9 @@ private ModelSerializer serializerChainInternal(LinkedList chain, return serializerBinding.get(); } if (resolveRootAdapter) { - Optional maybeAdapter = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization); + Optional> maybeAdapter = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization); if (maybeAdapter.isPresent()) { - AdapterBinding adapterBinding = maybeAdapter.get(); + AdapterBinding adapterBinding = maybeAdapter.get(); Type toType = adapterBinding.getToType(); Class rawToType = ReflectionUtils.getRawType(toType); ModelSerializer typeSerializer = TypeSerializers @@ -358,9 +358,9 @@ private ModelSerializer memberSerializer(LinkedList chain, if (serializerBinding.isPresent()) { return serializerBinding.get(); } - Optional maybeAdapter = adapterBinding(resolved, (ComponentBoundCustomization) customization); + Optional> maybeAdapter = adapterBinding(resolved, (ComponentBoundCustomization) customization); if (maybeAdapter.isPresent()) { - AdapterBinding adapterBinding = maybeAdapter.get(); + AdapterBinding adapterBinding = maybeAdapter.get(); Type toType = adapterBinding.getToType(); Class rawToType = ReflectionUtils.getRawType(toType); ModelSerializer typeSerializer = TypeSerializers.getTypeSerializer(rawToType, customization, jsonbContext); @@ -427,7 +427,7 @@ private Optional userSerializer(Type type, ComponentBoundCustom jsonbContext)); } - private Optional adapterBinding(Type type, ComponentBoundCustomization classCustomization) { + private Optional> adapterBinding(Type type, ComponentBoundCustomization classCustomization) { return jsonbContext.getComponentMatcher().getSerializeAdapterBinding(type, classCustomization); } diff --git a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java index df1ecbc5..8d918688 100644 --- a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -61,7 +61,7 @@ public static class AnnotatedPojo { @Test public void testIncompatibleAdapter() throws Exception { - IncompatibleAdapterPojo incompatibleAdapterFieldPojo = new IncompatibleAdapterPojo(); + IncompatibleAdapterPojo incompatibleAdapterFieldPojo = new IncompatibleAdapterPojo<>(); incompatibleAdapterFieldPojo.str = "STR"; try { defaultJsonb.toJson(incompatibleAdapterFieldPojo); @@ -86,7 +86,7 @@ public void testGenericFieldsMatch() { @Test public void testAnnotatedTbox() throws Exception { - AnnotatedPojo pojo = new AnnotatedPojo(); + AnnotatedPojo pojo = new AnnotatedPojo<>(); pojo.box = new Box("STR", 101); String marshalledJson = defaultJsonb.toJson(pojo); assertEquals("{\"box\":\"STR:101\"}", marshalledJson); diff --git a/src/test/java/org/eclipse/yasson/adapters/model/LocalPolymorphicAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/LocalPolymorphicAdapter.java index c77530b0..6fdbd436 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/LocalPolymorphicAdapter.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/LocalPolymorphicAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -28,7 +28,7 @@ public abstract class LocalPolymorphicAdapter implements JsonbAdapter... allowedClasses) { this.allowedClasses = Stream.of(allowedClasses).map(Class::getName).toArray(value -> new String[allowedClasses.length]); } diff --git a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java index 51f0e7ca..bd90af95 100644 --- a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java +++ b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023 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 @@ -45,7 +45,7 @@ public void testAnnotatedImplementation() { @Test public void testJsonbConfigUserImplementation() { - HashMap userMapping = new HashMap<>(); + HashMap, Class> userMapping = new HashMap<>(); userMapping.put(Animal.class, Dog.class); Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(USER_TYPE_MAPPING, userMapping)); Animal animal = new Dog("Bulldog"); 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 0e7fdb42..d930d3d3 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, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.NavigableMap; +import java.util.Optional; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -199,6 +200,7 @@ public void testMarshallArray() { final String[][] stringMultiArray = {{"first", "second"},{"third", "fourth"}}; assertEquals("[[\"first\",\"second\"],[\"third\",\"fourth\"]]", nullableJsonb.toJson(stringMultiArray)); + @SuppressWarnings("rawtypes") final Map[][] mapMultiArray = new LinkedHashMap[2][2]; mapMultiArray[0][0] = new LinkedHashMap<>(1); mapMultiArray[0][0].put("0", 0); @@ -233,9 +235,8 @@ public void testMarshallEnumMap() { } @Test - @SuppressWarnings("unchecked") public void testRawCollection() { - List rawList = new ArrayList(); + List rawList = new ArrayList<>(); rawList.add("first"); Circle circle = new Circle(); circle.setRadius(2.0); @@ -244,10 +245,10 @@ public void testRawCollection() { String expected = "[\"first\",{\"area\":1.0,\"radius\":2.0}]"; assertEquals(expected, nullableJsonb.toJson(rawList)); - List result = nullableJsonb.fromJson(expected, List.class); + List result = nullableJsonb.fromJson(expected, List.class); assertEquals("first", result.get(0)); - assertEquals(new BigDecimal("2.0"), ((Map)result.get(1)).get("radius")); - assertEquals(new BigDecimal("1.0"), ((Map)result.get(1)).get("area")); + assertEquals(new BigDecimal("2.0"), ((Map)result.get(1)).get("radius")); + assertEquals(new BigDecimal("1.0"), ((Map)result.get(1)).get("area")); } @Test diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 90c1f718..3f6cb1d2 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -390,17 +390,17 @@ public void testMarshallRawList() throws ParseException { @Test public void testMultipleBounds() { final LinkedList list = new LinkedList<>(Arrays.asList("Test 1", "Test 2")); - MultipleBoundsContainer> container = new MultipleBoundsContainer<>(); + MultipleBoundsContainer> container = new MultipleBoundsContainer<>(); container.setInstance(new ArrayList<>()); container.getInstance().add(list); - final Type type = new TestTypeToken>>() { + final Type type = new TestTypeToken>>() { }.getType(); String jsonString = defaultJsonb.toJson(container, type); assertEquals("{\"instance\":[[\"Test 1\",\"Test 2\"]]}", jsonString); - MultipleBoundsContainer> result = defaultJsonb.fromJson(jsonString, type); + MultipleBoundsContainer> result = defaultJsonb.fromJson(jsonString, type); assertEquals(container.getInstance(), result.getInstance()); } @@ -473,4 +473,3 @@ public ExtendsBigDecimal(String val) { } } - diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/MultipleBoundsContainer.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/MultipleBoundsContainer.java index 39682cf4..dba690ff 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/MultipleBoundsContainer.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/model/MultipleBoundsContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023 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 @@ -19,16 +19,16 @@ import java.util.List; import java.util.Queue; -public class MultipleBoundsContainer implements TypeContainer> { - protected List instance; +public class MultipleBoundsContainer & Queue> implements TypeContainer> { + protected List instance; @Override - public List getInstance() { + public List getInstance() { return instance; } @Override - public void setInstance(List instance) { + public void setInstance(List instance) { this.instance = instance; } } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java index 8bb2444a..e1468250 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2020 Payara Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -44,7 +44,7 @@ public class OptionalTest { public void testOptionalString() { assertEquals("{\"value\":\"abc\"}", bindingJsonb.toJson(new ScalarValueWrapper<>(Optional.of("abc")))); - ScalarValueWrapper result = bindingJsonb.fromJson("{\"value\":\"abc\"}", new TestTypeToken>() {}.getType()); + ScalarValueWrapper> result = bindingJsonb.fromJson("{\"value\":\"abc\"}", new TestTypeToken>>() {}.getType()); assertEquals(Optional.of("abc"), result.getValue()); } @@ -100,7 +100,7 @@ public void testMarshallOptionalIntArray() { @Test public void testMarshallOptionalArray() { - final Optional[] array = {Optional.of(new Customer(1, "Cust1")), Optional.of(new Customer(2, "Cust2")), Optional.empty()}; + final Optional[] array = {Optional.of(new Customer(1, "Cust1")), Optional.of(new Customer(2, "Cust2")), Optional.empty()}; assertEquals("[{\"id\":1,\"name\":\"Cust1\"},{\"id\":2,\"name\":\"Cust2\"},null]", bindingJsonb.toJson(array)); } diff --git a/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTarget.java b/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTarget.java index a006739a..38b16381 100644 --- a/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTarget.java +++ b/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -21,29 +21,30 @@ /** * For JNDI Bean Manager resolution testing purposes. */ -public class MockInjectionTarget implements InjectionTarget { +public class MockInjectionTarget implements InjectionTarget> { @Override - public void inject(JsonbAdapter instance, CreationalContext ctx) { + public void inject(JsonbAdapter instance, CreationalContext> ctx) { } @Override - public void postConstruct(JsonbAdapter instance) { + public void postConstruct(JsonbAdapter instance) { } @Override - public void preDestroy(JsonbAdapter instance) { + public void preDestroy(JsonbAdapter instance) { } @Override - public JsonbAdapter produce(CreationalContext ctx) { + public JsonbAdapter produce(CreationalContext> ctx) { + // for the test we only need this adapter; so it's OK to always return just this one return new NonCdiAdapter(); } @Override - public void dispose(JsonbAdapter instance) { + public void dispose(JsonbAdapter instance) { } diff --git a/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTargetFactory.java b/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTargetFactory.java index 3a6d8bc9..42f9a22a 100644 --- a/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTargetFactory.java +++ b/src/test/java/org/eclipse/yasson/internal/cdi/MockInjectionTargetFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023 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 @@ -22,6 +22,8 @@ public class MockInjectionTargetFactory implements InjectionTargetFactory { @Override public InjectionTarget createInjectionTarget(Bean bean) { - return (InjectionTarget) new MockInjectionTarget(); + @SuppressWarnings("unchecked") + InjectionTarget injectionTarget = (InjectionTarget) new MockInjectionTarget(); + return injectionTarget; } } diff --git a/src/test/java/org/eclipse/yasson/internal/cdi/WeldManager.java b/src/test/java/org/eclipse/yasson/internal/cdi/WeldManager.java index 513a9e07..ae86b90a 100644 --- a/src/test/java/org/eclipse/yasson/internal/cdi/WeldManager.java +++ b/src/test/java/org/eclipse/yasson/internal/cdi/WeldManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -31,7 +31,7 @@ public class WeldManager { private InitialContext initialContext; - public void startWeld(Class... scannedClasses) throws NamingException { + public void startWeld(Class... scannedClasses) throws NamingException { weld = new Weld().beanClasses(scannedClasses).disableDiscovery(); WeldContainer container = weld.initialize(); initialContext = new InitialContext(); diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index f6d042ac..12f340cf 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -142,7 +142,7 @@ public void testSimpleArray() { JsonArrayBuilder arrayBuilder = jsonProvider.createArrayBuilder(); arrayBuilder.add(BigDecimal.TEN).add("String value").addNull(); JsonArray jsonArray = arrayBuilder.build(); - List result = yassonJsonb.fromJsonStructure(jsonArray, ArrayList.class); + List result = yassonJsonb.fromJsonStructure(jsonArray, ArrayList.class); assertEquals(3, result.size()); assertEquals(BigDecimal.TEN, result.get(0)); assertEquals("String value", result.get(1)); @@ -182,11 +182,12 @@ public void testNestedArrays() { JsonArray jsonArray = arrayBuilder.build(); - ArrayList result = yassonJsonb.fromJsonStructure(jsonArray, ArrayList.class); + ArrayList result = yassonJsonb.fromJsonStructure(jsonArray, ArrayList.class); assertEquals(2, result.size()); assertEquals(BigDecimal.TEN, result.get(0)); assertTrue(result.get(1) instanceof List); - List inner = (List) result.get(1); + @SuppressWarnings("unchecked") + List inner = (List) result.get(1); assertEquals(2, inner.size()); assertEquals("first", inner.get(0)); assertEquals("second", inner.get(1)); @@ -242,13 +243,15 @@ public void testObjectsNestedInArraysRaw() { List result = yassonJsonb.fromJsonStructure(rootArray, new TestTypeToken>(){}.getType()); assertEquals(new BigDecimal("10"), result.get(0)); assertTrue(result.get(1) instanceof Map); - Map pojo = (Map) result.get(1); + @SuppressWarnings("unchecked") + Map pojo = (Map) result.get(1); assertNotNull(pojo); assertEquals("value 1", pojo.get("stringProperty")); assertEquals(new BigDecimal("1.1"), pojo.get("bigDecimalProperty")); assertEquals(new BigDecimal(10), pojo.get("longProperty")); assertTrue(pojo.get("strings") instanceof List); - List strings = (List) pojo.get("strings"); + @SuppressWarnings("unchecked") + List strings = (List) pojo.get("strings"); assertNotNull(strings); assertEquals(1, strings.size()); assertEquals("String value 1", strings.get(0)); diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java index 796f3d1f..9e6a3f9e 100644 --- a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -194,7 +194,7 @@ public void testNotParametrizedMap() { mapObject.put(256, "two hundred fifty-six"); String json = jsonb.toJson(mapObject); - Map resObject = jsonb.fromJson(json, Map.class); + Map resObject = jsonb.fromJson(json, Map.class); assertEquals(3, resObject.size()); assertTrue(resObject.keySet().iterator().next() instanceof String); } From f660a9fe2d3b51dc4e738288bb8e746a341f5d6f Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 14:40:53 +0100 Subject: [PATCH 30/68] [#620]Small Javadoc, type, import corrections. Rewrite one of CollectionsTest's test with stream. Signed-off-by: Anton Pinsky --- .../VariableTypeInheritanceSearch.java | 4 +- .../internal/components/AdapterBinding.java | 2 +- .../BeanManagerInstanceCreator.java | 4 +- .../yasson/internal/model/PropertyModel.java | 2 +- .../yasson/adapters/JsonbTypeAdapterTest.java | 4 +- .../collections/CollectionsTest.java | 47 +++++++++---------- .../defaultmapping/specific/OptionalTest.java | 3 -- .../MapToObjectSerializerTest.java | 14 +++--- 8 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java index 1a144f10..bfc2060a 100644 --- a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java +++ b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java @@ -83,7 +83,7 @@ Type searchParametrizedType(Type typeToSearch, TypeVariable typeVar) { return matchedGenericType; } parameterizedSubclasses.push(parameterizedType); - return searchParametrizedType(((Class) parameterizedType.getRawType()).getGenericSuperclass(), typeVar); + return searchParametrizedType(((Class) parameterizedType.getRawType()).getGenericSuperclass(), typeVar); } private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { @@ -120,6 +120,6 @@ private static ParameterizedType findParameterizedSuperclass(Type type) { if (!(type instanceof Class)) { throw new JsonbException(Messages.getMessage(MessageKeys.RESOLVE_PARAMETRIZED_TYPE, type)); } - return findParameterizedSuperclass(((Class) type).getGenericSuperclass()); + return findParameterizedSuperclass(((Class) type).getGenericSuperclass()); } } diff --git a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java index d9dffc0c..8a377299 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java @@ -46,7 +46,7 @@ public AdapterBinding(Type fromType, Type toType, JsonbAdapter * During marshalling object property is adapted to this type and result is marshalled. * During unmarshalling object is unmarshalled into this type first, than converted to field type and set. * diff --git a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java index 29e7f024..0e2f60b2 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java @@ -31,7 +31,7 @@ * CDI instance manager. * Instances are created and stored per instance of {@link JsonBinding}. * Calling close on JsonBinding, cleans up Jsonb CDI instances and in case of "dependant" scope its dependencies. - * + *

* CDI API dependency is optional, this class is never referenced / loaded if CDI API is not resolvable. */ public class BeanManagerInstanceCreator implements JsonbComponentInstanceCreator { @@ -71,7 +71,7 @@ public T getOrCreateComponent(Class componentClass) { final T beanInstance = injectionTarget.produce(creationalContext); injectionTarget.inject(beanInstance, creationalContext); injectionTarget.postConstruct(beanInstance); - return new CDIManagedBean(beanInstance, injectionTarget, creationalContext); + return new CDIManagedBean<>(beanInstance, injectionTarget, creationalContext); }).getInstance(); return instance; } diff --git a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java index 0a243e90..8f074017 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java +++ b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java @@ -356,7 +356,7 @@ public Object getValue(Object object) { /** * Sets a property. - * + *

* If not writable (final, transient, static), ignores property. * * @param object Object to set value in. diff --git a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java index 8d918688..266bd96e 100644 --- a/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/JsonbTypeAdapterTest.java @@ -60,7 +60,7 @@ public static class AnnotatedPojo { } @Test - public void testIncompatibleAdapter() throws Exception { + public void testIncompatibleAdapter() { IncompatibleAdapterPojo incompatibleAdapterFieldPojo = new IncompatibleAdapterPojo<>(); incompatibleAdapterFieldPojo.str = "STR"; try { @@ -85,7 +85,7 @@ public void testGenericFieldsMatch() { } @Test - public void testAnnotatedTbox() throws Exception { + public void testAnnotatedTbox() { AnnotatedPojo pojo = new AnnotatedPojo<>(); pojo.box = new Box("STR", 101); String marshalledJson = defaultJsonb.toJson(pojo); 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 d930d3d3..e7ceb987 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java @@ -24,7 +24,6 @@ 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; @@ -32,13 +31,15 @@ import java.util.List; import java.util.Map; import java.util.NavigableMap; -import java.util.Optional; 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 java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.eclipse.yasson.TestTypeToken; import org.eclipse.yasson.defaultmapping.generics.model.Circle; @@ -87,6 +88,7 @@ public void testListOfNumbers() { numberList.add(10); String result = nullableJsonb.toJson(numberList, new TestTypeToken>(){}.getType()); + assertEquals("[1,2.0,10]", result); } @Test @@ -108,26 +110,19 @@ public void testListOfListsOfStrings() { @Test public void listOfMapsOfListsOfMaps() { - List>>> listOfMapsOfListsOfMaps = new ArrayList<>(); - - for(int i = 0; i < 3; i++) { - Map>> mapOfListsOfMap = new HashMap<>(); - - for(int j = 0; j < 3; j++) { - List> listOfMaps = new ArrayList<>(); - - for(int k = 0; k < 3; k++) { - Map stringIntegerMap = new HashMap<>(); - stringIntegerMap.put("first", 1); - stringIntegerMap.put("second", 2); - stringIntegerMap.put("third", 3); - listOfMaps.add(stringIntegerMap); - } - mapOfListsOfMap.put(String.valueOf(j), listOfMaps); - } - listOfMapsOfListsOfMaps.add(mapOfListsOfMap); - } - + List>>> listOfMapsOfListsOfMaps = IntStream.range(0, 3).mapToObj(i -> + IntStream.range(0, 3).boxed().collect(Collectors.toMap(String::valueOf, j -> + IntStream.range(0, 3).mapToObj(k -> + IntStream.range(1, 4).boxed().collect(Collectors.toMap(l -> switch (l) { + case 1 -> "first"; + case 2 -> "second"; + case 3 -> "third"; + default -> throw new IllegalStateException("Unexpected value: " + l); + }, Function.identity())) + ).toList() + )) + ).toList(); + String expected = "[{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]},{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]},{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]}]"; assertEquals(expected, nullableJsonb.toJson(listOfMapsOfListsOfMaps)); ArrayList>>> result = nullableJsonb.fromJson(expected, new TestTypeToken>>>>(){}.getType()); @@ -290,7 +285,7 @@ public static class ConcurrentMapContainer { public void testConcurrentMaps() { // ConcurrentMap ConcurrentMapContainer c = new ConcurrentMapContainer(); - c.concurrentMap = new ConcurrentHashMap(); + c.concurrentMap = new ConcurrentHashMap<>(); c.concurrentMap.put("foo", "fooVal"); c.concurrentMap.put("bar", "barVal"); String expectedJson = "{\"concurrentMap\":{\"bar\":\"barVal\",\"foo\":\"fooVal\"}}"; @@ -299,7 +294,7 @@ public void testConcurrentMaps() { // ConcurrentHashMap c = new ConcurrentMapContainer(); - c.concurrentHashMap = new ConcurrentHashMap(); + c.concurrentHashMap = new ConcurrentHashMap<>(); c.concurrentHashMap.put("foo", "fooVal2"); c.concurrentHashMap.put("bar", "barVal2"); expectedJson = "{\"concurrentHashMap\":{\"bar\":\"barVal2\",\"foo\":\"fooVal2\"}}"; @@ -308,7 +303,7 @@ public void testConcurrentMaps() { // ConcurrentNavigableMap c = new ConcurrentMapContainer(); - c.concurrentNavigableMap = new ConcurrentSkipListMap(); + c.concurrentNavigableMap = new ConcurrentSkipListMap<>(); c.concurrentNavigableMap.put("foo", "fooVal3"); c.concurrentNavigableMap.put("bar", "barVal3"); expectedJson = "{\"concurrentNavigableMap\":{\"bar\":\"barVal3\",\"foo\":\"fooVal3\"}}"; @@ -317,7 +312,7 @@ public void testConcurrentMaps() { // ConcurrentSkipListMap c = new ConcurrentMapContainer(); - c.concurrentSkipListMap = new ConcurrentSkipListMap(); + c.concurrentSkipListMap = new ConcurrentSkipListMap<>(); c.concurrentSkipListMap.put("foo", "fooVal4"); c.concurrentSkipListMap.put("bar", "barVal4"); expectedJson = "{\"concurrentSkipListMap\":{\"bar\":\"barVal4\",\"foo\":\"fooVal4\"}}"; diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java index e1468250..291df09a 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/specific/OptionalTest.java @@ -26,10 +26,7 @@ import org.eclipse.yasson.defaultmapping.specific.model.OptionalWrapper; import org.eclipse.yasson.defaultmapping.specific.model.NotMatchingGettersAndSetters; import org.eclipse.yasson.defaultmapping.specific.model.Street; -import org.eclipse.yasson.internal.JsonBindingBuilder; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import java.util.*; /** diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java index 9e6a3f9e..db8c615b 100644 --- a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java @@ -40,10 +40,10 @@ public class MapToObjectSerializerTest { enum TestEnum { ONE, TWO; - @Override /** * Force to lower case to check toString is not used during serialization of maps */ + @Override public String toString() { return this.name().toLowerCase(); } @@ -90,17 +90,17 @@ public String toString() { } } - public static class MapObjectIntegerString extends MapObject {}; + public static class MapObjectIntegerString extends MapObject {} - public static class MapObjectBigIntegerString extends MapObject {}; + public static class MapObjectBigIntegerString extends MapObject {} - public static class MapObjectEnumString extends MapObject {}; + public static class MapObjectEnumString extends MapObject {} - public static class MapObjectStringString extends MapObject {}; + public static class MapObjectStringString extends MapObject {} - public static class MapObjectBooleanString extends MapObject {}; + public static class MapObjectBooleanString extends MapObject {} - /** + /** * Test serialization of Map with Number keys and String values. */ @Test From 0a24b2547e830da24ff2cb468aa1f067c0e8dfd7 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 15:14:22 +0100 Subject: [PATCH 31/68] [#620]Used a "new" switch from Java 14 in CollectionsTest, corrected this. Signed-off-by: Anton Pinsky --- .../defaultmapping/collections/CollectionsTest.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) 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 e7ceb987..fb31ec15 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java @@ -24,6 +24,7 @@ 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; @@ -37,7 +38,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -110,15 +110,10 @@ public void testListOfListsOfStrings() { @Test public void listOfMapsOfListsOfMaps() { - List>>> listOfMapsOfListsOfMaps = IntStream.range(0, 3).mapToObj(i -> + List>>> listOfMapsOfListsOfMaps = IntStream.range(0, 3).mapToObj(i -> IntStream.range(0, 3).boxed().collect(Collectors.toMap(String::valueOf, j -> IntStream.range(0, 3).mapToObj(k -> - IntStream.range(1, 4).boxed().collect(Collectors.toMap(l -> switch (l) { - case 1 -> "first"; - case 2 -> "second"; - case 3 -> "third"; - default -> throw new IllegalStateException("Unexpected value: " + l); - }, Function.identity())) + new HashMap<>(Map.of("first", 1, "second", 2, "third", 3)) ).toList() )) ).toList(); From 05844778355f949ed09d288f0347a67d19a8ba64 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 15:24:56 +0100 Subject: [PATCH 32/68] [#620]Stream.toList() only available from Java 16 on, replaced it in CollectionsTest, use collect(Collectors.toList()). Signed-off-by: Anton Pinsky --- .../yasson/defaultmapping/collections/CollectionsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 fb31ec15..b7b90c0f 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/collections/CollectionsTest.java @@ -114,9 +114,9 @@ public void listOfMapsOfListsOfMaps() { IntStream.range(0, 3).boxed().collect(Collectors.toMap(String::valueOf, j -> IntStream.range(0, 3).mapToObj(k -> new HashMap<>(Map.of("first", 1, "second", 2, "third", 3)) - ).toList() + ).collect(Collectors.toList()) )) - ).toList(); + ).collect(Collectors.toList()); String expected = "[{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]},{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]},{\"0\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"1\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}],\"2\":[{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2},{\"third\":3,\"first\":1,\"second\":2}]}]"; assertEquals(expected, nullableJsonb.toJson(listOfMapsOfListsOfMaps)); From 83af63332a51f774fbcb5435ff04d07223e0469d Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 15:27:30 +0100 Subject: [PATCH 33/68] [#620]Stream.toList() only available from Java 16 on, replaced it in CollectionsTest, use collect(Collectors.toList()). Signed-off-by: Anton Pinsky --- .../yasson/internal/AnnotationIntrospector.java | 11 ++++------- .../internal/VariableTypeInheritanceSearch.java | 2 +- .../eclipse/yasson/internal/model/PropertyModel.java | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java index 8102235f..26669049 100644 --- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java +++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java @@ -396,12 +396,9 @@ public SerializerBinding getSerializerBinding(JsonbAnnotatedElement> private T getAnnotationFromPropertyType(Property property, Class annotationClass) { final Optional> optionalRawType = ReflectionUtils.getOptionalRawType(property.getPropertyType()); - if (!optionalRawType.isPresent()) { - //will not work for type variable properties, which are bound to class that is annotated. - return null; - } - return findAnnotation(collectAnnotations(optionalRawType.get()).getAnnotations(), annotationClass); - } + //will not work for type variable properties, which are bound to class that is annotated. + return optionalRawType.map(aClass -> findAnnotation(collectAnnotations(aClass).getAnnotations(), annotationClass)).orElse(null); + } /** * Checks if property is nillable. @@ -469,7 +466,7 @@ public EnumSet getJsonbTransientCategorized(Property property) Map annotationFromPropertyCategorized = getAnnotationFromPropertyCategorized( JsonbTransient.class, property); - if (annotationFromPropertyCategorized.size() > 0) { + if (!annotationFromPropertyCategorized.isEmpty()) { transientTarget.addAll(annotationFromPropertyCategorized.keySet()); return transientTarget; } diff --git a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java index bfc2060a..6076be72 100644 --- a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java +++ b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java @@ -87,7 +87,7 @@ Type searchParametrizedType(Type typeToSearch, TypeVariable typeVar) { } private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { - if (parameterizedSubclasses.size() == 0) { + if (parameterizedSubclasses.isEmpty()) { return typeVar; } ParameterizedType parametrizedSubclass = parameterizedSubclasses.pop(); diff --git a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java index 8f074017..42c4514a 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java +++ b/src/main/java/org/eclipse/yasson/internal/model/PropertyModel.java @@ -209,7 +209,7 @@ private PropertyCustomization introspectCustomization(Property property, JsonbCo } } } - if (transientInfo.size() != 0) { + if (!transientInfo.isEmpty()) { builder.readTransient(transientInfo.contains(AnnotationTarget.GETTER)); builder.writeTransient(transientInfo.contains(AnnotationTarget.SETTER)); From 1cfc5b6ef490998ca6f8d2c99a5e253a38bba79b Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 15:31:13 +0100 Subject: [PATCH 34/68] [#620]Use more isEmpty() in previous changeset. Signed-off-by: Anton Pinsky --- .../org/eclipse/yasson/internal/AnnotationIntrospector.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java index 26669049..3039ee66 100644 --- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java +++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java @@ -396,9 +396,9 @@ public SerializerBinding getSerializerBinding(JsonbAnnotatedElement> private T getAnnotationFromPropertyType(Property property, Class annotationClass) { final Optional> optionalRawType = ReflectionUtils.getOptionalRawType(property.getPropertyType()); - //will not work for type variable properties, which are bound to class that is annotated. - return optionalRawType.map(aClass -> findAnnotation(collectAnnotations(aClass).getAnnotations(), annotationClass)).orElse(null); - } + //will not work for type variable properties, which are bound to class that is annotated. + return optionalRawType.map(aClass -> findAnnotation(collectAnnotations(aClass).getAnnotations(), annotationClass)).orElse(null); + } /** * Checks if property is nillable. From 57d2a810f8272d37abfcf8648c0b25fbdc8dfb49 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 1 Nov 2023 15:38:02 +0100 Subject: [PATCH 35/68] [#620]Use try-with-resource in tests on JsoB creation. Signed-off-by: Anton Pinsky --- .../ImplementationClassTest.java | 17 ++- .../JsonStructureToParserAdapterTest.java | 13 +- .../MapToObjectSerializerTest.java | 138 +++++++++--------- 3 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java index bd90af95..db53c101 100644 --- a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java +++ b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java @@ -44,17 +44,18 @@ public void testAnnotatedImplementation() { } @Test - public void testJsonbConfigUserImplementation() { + public void testJsonbConfigUserImplementation() throws Exception { HashMap, Class> userMapping = new HashMap<>(); userMapping.put(Animal.class, Dog.class); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(USER_TYPE_MAPPING, userMapping)); - Animal animal = new Dog("Bulldog"); - String expected = "{\"dogProperty\":\"Bulldog\"}"; - String json = jsonb.toJson(animal); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(USER_TYPE_MAPPING, userMapping))) { + Animal animal = new Dog("Bulldog"); + String expected = "{\"dogProperty\":\"Bulldog\"}"; + String json = jsonb.toJson(animal); - assertEquals(expected, json); + assertEquals(expected, json); - Dog result = (Dog) jsonb.fromJson("{\"dogProperty\":\"Bulldog\"}", Animal.class); - assertEquals("Bulldog", result.getDogProperty()); + Dog result = (Dog) jsonb.fromJson("{\"dogProperty\":\"Bulldog\"}", Animal.class); + assertEquals("Bulldog", result.getDogProperty()); + } } } diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index 12f340cf..d3025a2e 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -259,7 +259,7 @@ public void testObjectsNestedInArraysRaw() { @Test - public void testCustomJsonbDeserializer() { + public void testCustomJsonbDeserializer() throws Exception { JsonObjectBuilder outerBuilder = jsonProvider.createObjectBuilder(); JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); innerBuilder.add("first", "String value 1"); @@ -267,10 +267,11 @@ public void testCustomJsonbDeserializer() { outerBuilder.add("inner", innerBuilder.build()); JsonObject object = outerBuilder.build(); - YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create(new JsonbConfig().withDeserializers(new InnerPojoDeserializer())); - Pojo result = jsonb.fromJsonStructure(object, Pojo.class); - assertNotNull(result.getInner()); - assertEquals("String value 1", result.getInner().getInnerFirst()); - assertEquals("String value 2", result.getInner().getInnerSecond()); + try (YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create(new JsonbConfig().withDeserializers(new InnerPojoDeserializer()))) { + Pojo result = jsonb.fromJsonStructure(object, Pojo.class); + assertNotNull(result.getInner()); + assertEquals("String value 1", result.getInner().getInnerFirst()); + assertEquals("String value 2", result.getInner().getInnerSecond()); + } } } diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java index db8c615b..7542f597 100644 --- a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java @@ -104,14 +104,15 @@ public static class MapObjectBooleanString extends MapObject {} * Test serialization of Map with Number keys and String values. */ @Test - public void testSerializeEnumMapToObject() { + public void testSerializeEnumMapToObject() throws Exception { Map map = new EnumMap<>(TestEnum.class); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true)); - map.put(TestEnum.ONE, "value1"); - map.put(TestEnum.TWO, "value2"); - String json = jsonb.toJson(map); - for (TestEnum e : TestEnum.values()) { - assertTrue(json.contains(e.name()), "Enumeration not well serialized"); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true))) { + map.put(TestEnum.ONE, "value1"); + map.put(TestEnum.TWO, "value2"); + String json = jsonb.toJson(map); + for (TestEnum e : TestEnum.values()) { + assertTrue(json.contains(e.name()), "Enumeration not well serialized"); + } } } @@ -119,84 +120,89 @@ public void testSerializeEnumMapToObject() { * Test for Integer/String map. */ @Test - public void testIntegerString() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); + public void testIntegerString() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { - MapObjectIntegerString mapObject = new MapObjectIntegerString(); - mapObject.getValues().put(12, "twelve"); - mapObject.getValues().put(48, "forty eight"); - mapObject.getValues().put(256, "two hundred fifty-six"); + MapObjectIntegerString mapObject = new MapObjectIntegerString(); + mapObject.getValues().put(12, "twelve"); + mapObject.getValues().put(48, "forty eight"); + mapObject.getValues().put(256, "two hundred fifty-six"); - String json = jsonb.toJson(mapObject); - MapObjectIntegerString resObject = jsonb.fromJson(json, MapObjectIntegerString.class); - assertEquals(mapObject, resObject); + String json = jsonb.toJson(mapObject); + MapObjectIntegerString resObject = jsonb.fromJson(json, MapObjectIntegerString.class); + assertEquals(mapObject, resObject); + } } /** * Test for BigInteger/String map. */ @Test - public void testBigIntegerString() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); + public void testBigIntegerString() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { - MapObjectBigIntegerString mapObject = new MapObjectBigIntegerString(); - mapObject.getValues().put(new BigInteger("12"), "twelve"); - mapObject.getValues().put(new BigInteger("48"), "forty eight"); - mapObject.getValues().put(new BigInteger("256"), "two hundred fifty-six"); + MapObjectBigIntegerString mapObject = new MapObjectBigIntegerString(); + mapObject.getValues().put(new BigInteger("12"), "twelve"); + mapObject.getValues().put(new BigInteger("48"), "forty eight"); + mapObject.getValues().put(new BigInteger("256"), "two hundred fifty-six"); - String json = jsonb.toJson(mapObject); - MapObjectBigIntegerString resObject = jsonb.fromJson(json, MapObjectBigIntegerString.class); - assertEquals(mapObject, resObject); + String json = jsonb.toJson(mapObject); + MapObjectBigIntegerString resObject = jsonb.fromJson(json, MapObjectBigIntegerString.class); + assertEquals(mapObject, resObject); + } } /** * Test for Enum/String map. */ @Test - public void testEnumString() { - Jsonb jsonb = JsonbBuilder.create(); + public void testEnumString() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - MapObjectEnumString mapObject = new MapObjectEnumString(); - mapObject.getValues().put(TestEnum.ONE, "one"); - mapObject.getValues().put(TestEnum.TWO, "two"); + MapObjectEnumString mapObject = new MapObjectEnumString(); + mapObject.getValues().put(TestEnum.ONE, "one"); + mapObject.getValues().put(TestEnum.TWO, "two"); - String json = jsonb.toJson(mapObject); - MapObjectEnumString resObject = jsonb.fromJson(json, MapObjectEnumString.class); - assertEquals(mapObject, resObject); + String json = jsonb.toJson(mapObject); + MapObjectEnumString resObject = jsonb.fromJson(json, MapObjectEnumString.class); + assertEquals(mapObject, resObject); + } } /** * Test for String/String map. */ @Test - public void testStringString() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty("lala", "lala")); + public void testStringString() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty("lala", "lala"))) { - MapObjectStringString mapObject = new MapObjectStringString(); - mapObject.getValues().put("one", "one"); - mapObject.getValues().put("two", "two"); + MapObjectStringString mapObject = new MapObjectStringString(); + mapObject.getValues().put("one", "one"); + mapObject.getValues().put("two", "two"); - String json = jsonb.toJson(mapObject); - MapObjectStringString resObject = jsonb.fromJson(json, MapObjectStringString.class); - assertEquals(mapObject, resObject); + String json = jsonb.toJson(mapObject); + MapObjectStringString resObject = jsonb.fromJson(json, MapObjectStringString.class); + assertEquals(mapObject, resObject); + } } /** * Test for a non parametrized map that should use Strings as keys. */ @Test - public void testNotParametrizedMap() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - - Map mapObject = new HashMap<>(); - mapObject.put(12, "twelve"); - mapObject.put(48, "forty eight"); - mapObject.put(256, "two hundred fifty-six"); - - String json = jsonb.toJson(mapObject); - Map resObject = jsonb.fromJson(json, Map.class); - assertEquals(3, resObject.size()); - assertTrue(resObject.keySet().iterator().next() instanceof String); + public void testNotParametrizedMap() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { + + Map mapObject = new HashMap<>(); + mapObject.put(12, "twelve"); + mapObject.put(48, "forty eight"); + mapObject.put(256, "two hundred fifty-six"); + + String json = jsonb.toJson(mapObject); + Map resObject = jsonb.fromJson(json, Map.class); + assertEquals(3, resObject.size()); + assertTrue(resObject.keySet().iterator().next() instanceof String); + } } /** @@ -205,14 +211,15 @@ public void testNotParametrizedMap() { * But the json string should be deserialized in the same way. */ @Test - public void testBooleanStringMapToObjectSerializer() { - Jsonb jsonb = JsonbBuilder.create(); - - String json = "{\"values\":{\"true\":\"TRUE\",\"false\":\"FALSE\"}}"; - MapObjectBooleanString resObject = jsonb.fromJson(json, MapObjectBooleanString.class); - assertEquals(2, resObject.getValues().size()); - assertEquals("TRUE", resObject.getValues().get(true)); - assertEquals("FALSE", resObject.getValues().get(false)); + public void testBooleanStringMapToObjectSerializer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { + + String json = "{\"values\":{\"true\":\"TRUE\",\"false\":\"FALSE\"}}"; + MapObjectBooleanString resObject = jsonb.fromJson(json, MapObjectBooleanString.class); + assertEquals(2, resObject.getValues().size()); + assertEquals("TRUE", resObject.getValues().get(true)); + assertEquals("FALSE", resObject.getValues().get(false)); + } } /** @@ -220,10 +227,11 @@ public void testBooleanStringMapToObjectSerializer() { * JsonbException is expected. */ @Test - public void testIncorrectTypeMapToObjectSerializer() { - Jsonb jsonb = JsonbBuilder.create(); + public void testIncorrectTypeMapToObjectSerializer() throws Exception { + try (Jsonb jsonb = JsonbBuilder.create()) { - String json = "{\"values\":{\"1\":\"OK\",\"error\":\"KO\"}}"; - shouldFail(() -> jsonb.fromJson(json, MapObjectIntegerString.class)); + String json = "{\"values\":{\"1\":\"OK\",\"error\":\"KO\"}}"; + shouldFail(() -> jsonb.fromJson(json, MapObjectIntegerString.class)); + } } } From c90d1aafa86be5518d56591b6db3595443ef16b2 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 4 Nov 2023 16:55:36 +0100 Subject: [PATCH 36/68] [#625]Wrote the missing methods in JsonStructureToParserAdapter and tests for them; more fulfill of the JSON-P's JsonParser Signed-off-by: Anton Pinsky --- .../jsonstructure/JsonStructureIterator.java | 6 +- .../JsonStructureToParserAdapter.java | 217 ++++++++-- .../PolymorphismWithJsonValuesTest.java | 75 ++++ .../JsonStructureToParserAdapterTest.java | 400 +++++++++++++++++- 4 files changed, 670 insertions(+), 28 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureIterator.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureIterator.java index 1e402b57..70bcd361 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureIterator.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -67,9 +67,11 @@ JsonParser.Event getValueEvent(JsonValue value) { case NUMBER: return JsonParser.Event.VALUE_NUMBER; case STRING: + return JsonParser.Event.VALUE_STRING; case TRUE: + return JsonParser.Event.VALUE_TRUE; case FALSE: - return JsonParser.Event.VALUE_STRING; + return JsonParser.Event.VALUE_FALSE; case OBJECT: return JsonParser.Event.START_OBJECT; case ARRAY: diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index dfa9d64f..29f89501 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -13,10 +13,22 @@ package org.eclipse.yasson.internal.jsonstructure; import java.math.BigDecimal; +import java.util.AbstractMap; import java.util.ArrayDeque; import java.util.Deque; +import java.util.EnumSet; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import jakarta.json.JsonArray; +import jakarta.json.JsonException; import jakarta.json.JsonNumber; import jakarta.json.JsonObject; import jakarta.json.JsonStructure; @@ -28,19 +40,27 @@ import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; +import static java.util.Spliterator.ORDERED; + /** * Adapter for {@link JsonParser}, that reads a {@link JsonStructure} content tree instead of JSON text. - * + *

* Yasson and jsonb API components are using {@link JsonParser} as its input API. * This adapter allows deserialization of {@link JsonStructure} into java content tree using same components * as when parsing JSON text. */ public class JsonStructureToParserAdapter implements JsonParser { - private Deque iterators = new ArrayDeque<>(); + private static final EnumSet GET_STRING_EVENTS = EnumSet.of(Event.KEY_NAME, Event.VALUE_STRING, Event.VALUE_NUMBER); + + private static final EnumSet NOT_GET_VALUE_EVENT_ENUM_SET = EnumSet.of(JsonParser.Event.END_OBJECT, JsonParser.Event.END_ARRAY); + + private final Deque iterators = new ArrayDeque<>(); private final JsonStructure rootStructure; + private Event currentEvent; + /** * Creates new {@link JsonStructure} parser. * @@ -52,35 +72,51 @@ public JsonStructureToParserAdapter(JsonStructure structure) { @Override public boolean hasNext() { - return iterators.peek().hasNext(); + JsonStructureIterator iterator = iterators.peek(); + return (iterator != null) && iterator.hasNext(); } @Override public Event next() { if (iterators.isEmpty()) { - if (rootStructure instanceof JsonObject) { - iterators.push(new JsonObjectIterator((JsonObject) rootStructure)); - return Event.START_OBJECT; - } else if (rootStructure instanceof JsonArray) { - iterators.push(new JsonArrayIterator((JsonArray) rootStructure)); - return Event.START_ARRAY; - } + currentEvent = pushIntoIterators(rootStructure, rootStructure instanceof JsonObject, Event.START_OBJECT, + rootStructure instanceof JsonArray, Event.START_ARRAY); + return currentEvent; } JsonStructureIterator current = iterators.peek(); - Event next = current.next(); - if (next == Event.START_OBJECT) { - iterators.push(new JsonObjectIterator((JsonObject) current.getValue())); - } else if (next == Event.START_ARRAY) { - iterators.push(new JsonArrayIterator((JsonArray) current.getValue())); - } else if (next == Event.END_OBJECT || next == Event.END_ARRAY) { + currentEvent = current.next(); + pushIntoIterators(current.getValue(), currentEvent == Event.START_OBJECT, null, currentEvent == Event.START_ARRAY, null); + if (currentEvent == Event.END_OBJECT || currentEvent == Event.END_ARRAY) { iterators.pop(); } - return next; + return currentEvent; + } + + private Event pushIntoIterators(JsonValue value, boolean isObject, Event objectEvent, boolean isArray, Event arrayEvent) { + if (isObject) { + iterators.push(new JsonObjectIterator((JsonObject) value)); + return objectEvent; + } else if (isArray) { + iterators.push(new JsonArrayIterator((JsonArray) value)); + return arrayEvent; + } + return null; + } + + @Override + public Event currentEvent() { + return currentEvent; } @Override public String getString() { - return iterators.peek().getString(); + JsonStructureIterator iterator = iterators.peek(); + if (iterator == null || !GET_STRING_EVENTS.contains(currentEvent)) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getString() call with current event: " + + (iterator == null ? "null" : currentEvent) + "; should be in " + GET_STRING_EVENTS)); + } else { + return iterator.getString(); + } } @Override @@ -111,12 +147,15 @@ public JsonObject getObject() { iterators.pop(); return current.getValue().asJsonObject(); } else { - throw new JsonbException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); } } private JsonNumber getJsonNumberValue() { JsonStructureIterator iterator = iterators.peek(); + if (iterator == null) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Call of the number method on empty context")); + } JsonValue value = iterator.getValue(); if (value.getValueType() != JsonValue.ValueType.NUMBER) { throw iterator.createIncompatibleValueError(); @@ -130,20 +169,148 @@ public JsonLocation getLocation() { } @Override - public void skipArray() { - if (!iterators.isEmpty()) { - JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonArrayIterator) { - iterators.pop(); + public JsonValue getValue() { + if (currentEvent == null || NOT_GET_VALUE_EVENT_ENUM_SET.contains(currentEvent)) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call with current event: " + + currentEvent + "; should not be in " + NOT_GET_VALUE_EVENT_ENUM_SET)); + } else { + JsonStructureIterator iterator = iterators.peek(); + if (iterator == null) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call on empty context")); + } else { + switch (currentEvent) { + case START_OBJECT: + return getObject(); + case START_ARRAY: + return getArray(); + default: + return iterator.getValue(); + } + } + } + } + + @Override + public JsonArray getArray() { + JsonStructureIterator current = iterators.peek(); + if (current instanceof JsonArrayIterator) { + //Remove child iterator as getArray() method contract says + iterators.pop(); + current = iterators.peek(); + if (current == null) { + throw new NoSuchElementException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "No more elements in JSON structure")); } + return current.getValue().asJsonArray(); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); + } + } + + @Override + public Stream getArrayStream() { + JsonStructureIterator current = iterators.peek(); + if (current instanceof JsonArrayIterator) { + return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { + public Spliterator trySplit() { + return null; + } + + public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + if (!JsonStructureToParserAdapter.this.hasNext() || JsonStructureToParserAdapter.this.next() == Event.END_ARRAY) { + return false; + } else { + action.accept(JsonStructureToParserAdapter.this.getValue()); + return true; + } + } + }, false); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); } } + @Override + public Stream> getObjectStream() { + JsonStructureIterator current = iterators.peek(); + if (current instanceof JsonObjectIterator) { + return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { + public Spliterator> trySplit() { + return null; + } + + public boolean tryAdvance(Consumer> action) { + Objects.requireNonNull(action); + if (!JsonStructureToParserAdapter.this.hasNext()) { + return false; + } else { + Event e = JsonStructureToParserAdapter.this.next(); + if (e == Event.END_OBJECT) { + return false; + } else if (e != Event.KEY_NAME) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); + } else { + String key = JsonStructureToParserAdapter.this.getString(); + if (!JsonStructureToParserAdapter.this.hasNext()) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); + } else { + JsonStructureToParserAdapter.this.next(); + JsonValue value = JsonStructureToParserAdapter.this.getValue(); + action.accept(new AbstractMap.SimpleImmutableEntry<>(key, value)); + return true; + } + } + } + } + }, false); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); + } + } + + @Override + public Stream getValueStream() { + if (iterators.isEmpty()) { + //JsonParserImpl delivers the whole object - so we have to do this the same way + JsonStructureToParserAdapter.this.next(); + return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { + public Spliterator trySplit() { + return null; + } + + public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + if (!JsonStructureToParserAdapter.this.hasNext()) { + return false; + } else { + //JsonParserImpl delivers the whole object - so we have to do this the same way + /*JsonStructureToParserAdapter.this.next();*/ + JsonValue value = JsonStructureToParserAdapter.this.getValue(); + action.accept(value); + return true; + } + } + }, false); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValueStream can be only called at the root level of JSON structure")); + } + } + + @Override + public void skipArray() { + skipJsonPart(iterator -> iterator instanceof JsonArrayIterator); + } + @Override public void skipObject() { + skipJsonPart(iterator -> iterator instanceof JsonObjectIterator); + } + + private void skipJsonPart(Predicate predicate) { + Objects.requireNonNull(predicate); if (!iterators.isEmpty()) { JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonObjectIterator) { + if (predicate.test(current)) { iterators.pop(); } } diff --git a/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java b/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java new file mode 100644 index 00000000..f3674d46 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java @@ -0,0 +1,75 @@ +package org.eclipse.yasson.customization.polymorphism; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.eclipse.yasson.Jsonbs; +import org.junit.jupiter.api.Test; + +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.annotation.JsonbSubtype; +import jakarta.json.bind.annotation.JsonbTypeInfo; + +public class PolymorphismWithJsonValuesTest { + + /** + * This test shows that the default Jsonb implementation support polymorphism with JsonValues. + * See GitHub issue + */ + @Test + public void testObjectWithJsonValue() { + Jsonb jsonb = Jsonbs.defaultJsonb; + var container = new PolyContainer.JsValueContainer(); + String containerSerialized = jsonb.toJson(container); + assertEquals("{\"type\":\"jsv\",\"jsonArray\":[\"an array json string\"],\"jsonBigDecimalValue\":10,\"jsonBigIntegerValue\":10," + + "\"jsonDoubleValue\":1.0,\"jsonIntValue\":1,\"jsonLongValue\":1,\"jsonObject\":{\"field\":\"an object json string\"}," + + "\"jsonStringValue\":\"a json string\"}", containerSerialized); + + var deserializedDirectly = jsonb.fromJson(containerSerialized, PolyContainer.JsValueContainer.class);//good + assertInstanceOf(PolyContainer.JsValueContainer.class, deserializedDirectly); + assertEquals(container.jsonStringValue, deserializedDirectly.jsonStringValue); + assertEquals(container.jsonIntValue, deserializedDirectly.jsonIntValue); + assertEquals(container.jsonLongValue, deserializedDirectly.jsonLongValue); + assertEquals(container.jsonDoubleValue, deserializedDirectly.jsonDoubleValue); + assertEquals(container.jsonBigDecimalValue, deserializedDirectly.jsonBigDecimalValue); + assertEquals(container.jsonBigIntegerValue, deserializedDirectly.jsonBigIntegerValue); + assertEquals(container.jsonArray, deserializedDirectly.jsonArray); + assertEquals(container.jsonObject, deserializedDirectly.jsonObject); + + var deserializedFromPoly = jsonb.fromJson(containerSerialized, PolyContainer.class);//bad + assertInstanceOf(PolyContainer.JsValueContainer.class, deserializedFromPoly); + assertEquals(container.jsonStringValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonStringValue); + assertEquals(container.jsonIntValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonIntValue); + assertEquals(container.jsonLongValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonLongValue); + assertEquals(container.jsonDoubleValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonDoubleValue); + assertEquals(container.jsonBigDecimalValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonBigDecimalValue); + assertEquals(container.jsonBigIntegerValue, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonBigIntegerValue); + assertEquals(container.jsonArray, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonArray); + assertEquals(container.jsonObject, ((PolyContainer.JsValueContainer)deserializedFromPoly).jsonObject); + } + + @JsonbTypeInfo( + key = "type", + value = {@JsonbSubtype(alias = "jsv", type = PolyContainer.JsValueContainer.class)} + ) + interface PolyContainer { + class JsValueContainer implements PolyContainer { + //fields should not be final, otherwise the test couldn't test + public /*final*/ JsonValue jsonStringValue = Json.createValue("a json string"); + public /*final*/ JsonValue jsonIntValue = Json.createValue(1); + public /*final*/ JsonValue jsonLongValue = Json.createValue(1L); + public /*final*/ JsonValue jsonDoubleValue = Json.createValue(1d); + public /*final*/ JsonValue jsonBigDecimalValue = Json.createValue(BigDecimal.TEN); + public /*final*/ JsonValue jsonBigIntegerValue = Json.createValue(BigInteger.TEN); + public /*final*/ JsonArray jsonArray = Json.createArrayBuilder().add("an array json string").build(); + public /*final*/ JsonObject jsonObject = Json.createObjectBuilder().add("field", "an object json string").build(); + } + } +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index d3025a2e..0137d795 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -12,27 +12,60 @@ package org.eclipse.yasson.jsonstructure; +import org.eclipse.yasson.internal.jsonstructure.JsonStructureToParserAdapter; +import org.hamcrest.Matcher; import org.junit.jupiter.api.*; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; import static org.junit.jupiter.api.Assertions.*; import static org.eclipse.yasson.Jsonbs.*; import org.eclipse.yasson.TestTypeToken; import org.eclipse.yasson.YassonJsonb; +import jakarta.json.Json; import jakarta.json.JsonArray; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.spi.JsonProvider; +import jakarta.json.stream.JsonParser; +import jakarta.json.stream.JsonParserFactory; + +import java.io.StringReader; import java.math.BigDecimal; +import java.math.BigInteger; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collector; +import java.util.stream.Collectors; public class JsonStructureToParserAdapterTest { - private final JsonProvider jsonProvider = JsonProvider.provider(); + private static final EnumSet GET_STRING_EVENT_ENUM_SET = + EnumSet.of(JsonParser.Event.KEY_NAME, JsonParser.Event.VALUE_STRING, JsonParser.Event.VALUE_NUMBER); + + private static final EnumSet NOT_GET_VALUE_EVENT_ENUM_SET = EnumSet.of(JsonParser.Event.END_OBJECT, JsonParser.Event.END_ARRAY); + + private static final Collector, ?, ArrayList> MAP_TO_LIST_COLLECTOR = Collector.of(ArrayList::new, + (list, entry) -> { + list.add(entry.getKey()); + list.add(entry.getValue().toString()); + }, + (left, right) -> { + left.addAll(right); + return left; + }, + Collector.Characteristics.IDENTITY_FINISH); + + private static final JsonProvider jsonProvider = JsonProvider.provider(); @Test public void testBasicJsonObject() { @@ -274,4 +307,369 @@ public void testCustomJsonbDeserializer() throws Exception { assertEquals("String value 2", result.getInner().getInnerSecond()); } } + + @Nested + public class DirectParserTests { + @Test + public void testNumbers() { + JsonObject jsonObject = jsonProvider.createObjectBuilder() + .add("int", 1) + .add("long", 1L) + .add("double", 1d) + .add("BigInteger", BigInteger.TEN) + .add("BigDecimal", BigDecimal.TEN) + .build(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + parser.next(); + parser.getString(); + parser.next(); + assertTrue(parser.isIntegralNumber()); + assertEquals(1, parser.getInt()); + + parser.next(); + parser.getString(); + parser.next(); + assertTrue(parser.isIntegralNumber()); + assertEquals(1L, parser.getLong()); + + parser.next(); + parser.getString(); + parser.next(); + assertFalse(parser.isIntegralNumber()); + assertEquals(BigDecimal.valueOf(1d), parser.getBigDecimal()); + + parser.next(); + parser.getString(); + parser.next(); + assertTrue(parser.isIntegralNumber()); + assertEquals(BigDecimal.TEN, parser.getBigDecimal()); + + parser.next(); + parser.getString(); + parser.next(); + assertTrue(parser.isIntegralNumber()); + assertEquals(BigDecimal.TEN, parser.getBigDecimal()); + } + } + + @Test + public void testParser_getString(){ + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + List values = new ArrayList<>(); + parser.next(); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + if (GET_STRING_EVENT_ENUM_SET.contains(event)) { + String strValue = Objects.toString(parser.getString(), "null"); + values.add(strValue); + } + } + + assertThat(values,TestData.FAMILY_MATCHER_WITH_NO_QUOTATION); + } + } + + @Test + public void testParser_getValue(){ + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + List values = new ArrayList<>(); + parser.next(); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + if (!NOT_GET_VALUE_EVENT_ENUM_SET.contains(event)) { + String strValue = Objects.toString(parser.getValue(), "null"); + values.add(strValue); + } + } + + //should look like this with a correct implementation -> FAMILY_MATCHER_KEYS_WITH_QUOTATION + /*assertThat(values, contains("\"name\"", "\"John\"", "\"surname\"", "\"Smith\"", "\"age\"", "30", "\"married\"", "true", + "\"wife\"", "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "\"children\"", "[\"Jack\",\"Mike\"]"));*/ + assertThat(values, contains("\"John\"", "\"John\"", "\"Smith\"", "\"Smith\"", "30", "30", "true", "true", + "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", + "[\"Jack\",\"Mike\"]", "[\"Jack\",\"Mike\"]")); + } + } + + @Test + public void testSkipArray() { + JsonObject jsonObject = TestData.createObjectWithArrays(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + parser.next(); + parser.getString(); + parser.next(); + parser.skipArray(); + parser.next(); + String key = parser.getString(); + + assertEquals("secondElement", key); + } + } + + @Test + public void testSkipObject() { + JsonObject jsonObject = TestData.createJsonObject(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + parser.next(); + parser.getString(); + parser.next(); + parser.skipObject(); + parser.next(); + String key = parser.getString(); + + assertEquals("secondPerson", key); + } + } + } + + @Nested + public class StreamTests { + @Test + public void testGetValueStream_GetOneElement() { + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + JsonString name = (JsonString) parser.getValueStream() + .map(JsonValue::asJsonObject) + .map(JsonObject::values) + .findFirst() + .orElseThrow() + .stream() + .filter(e -> e.getValueType() == JsonValue.ValueType.STRING) + .findFirst() + .orElseThrow(() -> new RuntimeException("Name not found")); + + assertEquals("John", name.getString()); + } + } + + @Test + public void testGetValueStream_GetList() { + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); + + assertThat(values, contains(TestData.JSON_FAMILY_STRING)); + } + } + + @Test + public void testGetArrayStream_GetOneElement() { + JsonObject jsonObject = TestData.createObjectWithArrays(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + parser.next(); + String key = parser.getString(); + parser.next(); + JsonString element = (JsonString) parser.getArrayStream().filter(e -> e.getValueType() == JsonValue.ValueType.STRING) + .findFirst() + .orElseThrow(() -> new RuntimeException("Element not found")); + + assertEquals("first", element.getString()); + assertEquals("firstElement", key); + } + } + + @Test + public void testGetArrayStream_GetList() { + JsonObject jsonObject = TestData.createObjectWithArrays(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + parser.next(); + String key = parser.getString(); + parser.next(); + List values = parser.getArrayStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); + + assertThat(values, TestData.ARRAY_STREAM_MATCHER); + assertEquals("firstElement", key); + } + } + + @Test + public void testGetObjectStream_GetOneElement() { + JsonObject jsonObject = TestData.createJsonObject(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + String surname = parser.getObjectStream().filter(e -> e.getKey().equals("firstPerson")) + .map(Map.Entry::getValue) + .map(JsonValue::asJsonObject) + .map(obj -> obj.getString("surname")) + .findFirst() + .orElseThrow(() -> new RuntimeException("Surname not found")); + + assertEquals("Smith", surname); + } + } + + @Test + public void testGetObjectStream_GetList() { + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + parser.next(); + List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); + + assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITHOUT_QUOTATION); + } + } + } + + @Nested + public class JSONPStandardParserTests { + @Test + public void testStandardStringParser_getValueStream() { + try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); + + assertThat(values, contains(TestData.JSON_FAMILY_STRING)); + } + } + + @Test + public void testStandardStringParser_getArrayStream() { + try (JsonParser parser = Json.createParser(new StringReader("{\"firstElement\":[\"first\", \"second\"],\"secondElement\":[\"third\", \"fourth\"]}"))) { + parser.next(); + parser.next(); + String key = parser.getString(); + parser.next(); + List values = parser.getArrayStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); + + assertThat(values, TestData.ARRAY_STREAM_MATCHER); + assertEquals("firstElement", key); + } + } + + @Test + public void testStandardStringParser_getObjectStream() { + try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + + parser.next(); + List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); + + assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITHOUT_QUOTATION); + } + } + + @Test + public void testStandardStringParser_getValue() { + try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + List values = new ArrayList<>(); + parser.next(); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + if (!NOT_GET_VALUE_EVENT_ENUM_SET.contains(event)) { + String strValue = Objects.toString(parser.getValue(), "null"); + values.add(strValue); + } + } + + assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITH_QUOTATION); + } + } + + @Test + public void testStandardStringParser_getString() { + try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + List values = new ArrayList<>(); + parser.next(); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + if (GET_STRING_EVENT_ENUM_SET.contains(event)) { + String strValue = Objects.toString(parser.getString(), "null"); + values.add(strValue); + } + } + + assertThat(values, TestData.FAMILY_MATCHER_WITH_NO_QUOTATION); + } + } + + @Test + public void testStandardStructureParser_getString() { + JsonParserFactory factory = Json.createParserFactory(Map.of()); + JsonObject jsonObject = TestData.createFamilyPerson(); + + try (JsonParser parser = factory.createParser(jsonObject)) { + List values = new ArrayList<>(); + parser.next(); + while (parser.hasNext()) { + JsonParser.Event event = parser.next(); + if (GET_STRING_EVENT_ENUM_SET.contains(event)) { + String strValue = Objects.toString(parser.getString(), "null"); + values.add(strValue); + } + } + + assertThat(values, TestData.FAMILY_MATCHER_WITH_NO_QUOTATION); + } + } + } + + private static class TestData { + private static final String JSON_FAMILY_STRING = "{\"name\":\"John\",\"surname\":\"Smith\",\"age\":30,\"married\":true," + + "\"wife\":{\"name\":\"Deborah\",\"surname\":\"Harris\"},\"children\":[\"Jack\",\"Mike\"]}"; + + private static final Matcher> FAMILY_MATCHER_KEYS_WITHOUT_QUOTATION = + contains("name", "\"John\"", "surname", "\"Smith\"", "age", "30", "married", "true", "wife", + "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "children", "[\"Jack\",\"Mike\"]"); + + private static final Matcher> FAMILY_MATCHER_KEYS_WITH_QUOTATION = + contains("\"name\"", "\"John\"", "\"surname\"", "\"Smith\"", "\"age\"", "30", "\"married\"", "true", + "\"wife\"", "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "\"children\"", "[\"Jack\",\"Mike\"]"); + + private static final Matcher> FAMILY_MATCHER_WITH_NO_QUOTATION = + contains("name", "John", "surname", "Smith", "age", "30", "married", + "wife", "name", "Deborah", "surname", "Harris", "children", "Jack", "Mike"); + + private static final Matcher> ARRAY_STREAM_MATCHER = contains("\"first\"", "\"second\""); + + private static JsonObject createFamilyPerson() { + return jsonProvider.createObjectBuilder() + .add("name", "John") + .add("surname", "Smith") + .add("age", 30) + .add("married", true) + .add("wife", createPerson("Deborah", "Harris")) + .add("children", createArray("Jack", "Mike")) + .build(); + } + + private static JsonObject createObjectWithArrays() { + return jsonProvider.createObjectBuilder() + .add("firstElement", createArray("first", "second")) + .add("secondElement", createArray("third", "fourth")) + .build(); + } + + private static JsonArrayBuilder createArray(String firstElement, String secondElement) { + return jsonProvider.createArrayBuilder().add(firstElement).add(secondElement); + } + + private static JsonObject createJsonObject() { + return jsonProvider.createObjectBuilder() + .add("firstPerson", createPerson("John", "Smith")) + .add("secondPerson", createPerson("Deborah", "Harris")) + .build(); + } + + private static JsonObjectBuilder createPerson(String name, String surname) { + return jsonProvider.createObjectBuilder() + .add("name", name) + .add("surname", surname); + } + } } From 2efa478be67d1b933f25353a41254659584aa81a Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 4 Nov 2023 17:09:51 +0100 Subject: [PATCH 37/68] fixup! [#625]Wrote the missing methods in JsonStructureToParserAdapter and tests for them; more fulfill of the JSON-P's JsonParser --- .../JsonStructureToParserAdapter.java | 84 +++++++++---------- .../PolymorphismWithJsonValuesTest.java | 12 +++ 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index 29f89501..ab94a4a4 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -211,20 +211,20 @@ public Stream getArrayStream() { JsonStructureIterator current = iterators.peek(); if (current instanceof JsonArrayIterator) { return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { - public Spliterator trySplit() { - return null; - } - - public boolean tryAdvance(Consumer action) { - Objects.requireNonNull(action); - if (!JsonStructureToParserAdapter.this.hasNext() || JsonStructureToParserAdapter.this.next() == Event.END_ARRAY) { - return false; - } else { - action.accept(JsonStructureToParserAdapter.this.getValue()); - return true; - } - } - }, false); + public Spliterator trySplit() { + return null; + } + + public boolean tryAdvance(Consumer action) { + Objects.requireNonNull(action); + if (!JsonStructureToParserAdapter.this.hasNext() || JsonStructureToParserAdapter.this.next() == Event.END_ARRAY) { + return false; + } else { + action.accept(JsonStructureToParserAdapter.this.getValue()); + return true; + } + } + }, false); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); } @@ -235,34 +235,34 @@ public Stream> getObjectStream() { JsonStructureIterator current = iterators.peek(); if (current instanceof JsonObjectIterator) { return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { - public Spliterator> trySplit() { - return null; - } - - public boolean tryAdvance(Consumer> action) { - Objects.requireNonNull(action); - if (!JsonStructureToParserAdapter.this.hasNext()) { - return false; - } else { - Event e = JsonStructureToParserAdapter.this.next(); - if (e == Event.END_OBJECT) { - return false; - } else if (e != Event.KEY_NAME) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); - } else { - String key = JsonStructureToParserAdapter.this.getString(); - if (!JsonStructureToParserAdapter.this.hasNext()) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); - } else { - JsonStructureToParserAdapter.this.next(); - JsonValue value = JsonStructureToParserAdapter.this.getValue(); - action.accept(new AbstractMap.SimpleImmutableEntry<>(key, value)); - return true; - } - } - } - } - }, false); + public Spliterator> trySplit() { + return null; + } + + public boolean tryAdvance(Consumer> action) { + Objects.requireNonNull(action); + if (!JsonStructureToParserAdapter.this.hasNext()) { + return false; + } else { + Event e = JsonStructureToParserAdapter.this.next(); + if (e == Event.END_OBJECT) { + return false; + } else if (e != Event.KEY_NAME) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); + } else { + String key = JsonStructureToParserAdapter.this.getString(); + if (!JsonStructureToParserAdapter.this.hasNext()) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); + } else { + JsonStructureToParserAdapter.this.next(); + JsonValue value = JsonStructureToParserAdapter.this.getValue(); + action.accept(new AbstractMap.SimpleImmutableEntry<>(key, value)); + return true; + } + } + } + } + }, false); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); } diff --git a/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java b/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java index f3674d46..5b682d82 100644 --- a/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java +++ b/src/test/java/org/eclipse/yasson/customization/polymorphism/PolymorphismWithJsonValuesTest.java @@ -1,3 +1,15 @@ +/* + * Copyright (c) 2019, 2023 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 + * 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.customization.polymorphism; import static org.junit.jupiter.api.Assertions.assertEquals; From 40db71eb20e9b7d2cb10d613999e6409ab3c5b55 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 4 Nov 2023 19:22:38 +0100 Subject: [PATCH 38/68] [#625]Replaced StreamSupport.stream() with Stream.iterate() in stream methods implementation Signed-off-by: Anton Pinsky --- .../JsonStructureToParserAdapter.java | 92 ++++++------------- 1 file changed, 30 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index ab94a4a4..4a73a00f 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -20,12 +20,9 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Stream; -import java.util.stream.StreamSupport; import jakarta.json.JsonArray; import jakarta.json.JsonException; @@ -40,8 +37,6 @@ import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; -import static java.util.Spliterator.ORDERED; - /** * Adapter for {@link JsonParser}, that reads a {@link JsonStructure} content tree instead of JSON text. *

@@ -70,6 +65,17 @@ public JsonStructureToParserAdapter(JsonStructure structure) { this.rootStructure = structure; } + /** + * Creates new {@link Stream} from values from {@link Supplier}. The stream delivers the values as long as supplier delivers non-null values + * @param supplier supplier of the values + * @return stream of values from given supplier + * @param type of the values which are delivered by the supplier and the stream + */ + private static Stream streamFromSupplier(Supplier supplier){ + Objects.requireNonNull(supplier); + return Stream.iterate(supplier.get(), Objects::nonNull, value -> supplier.get()); + } + @Override public boolean hasNext() { JsonStructureIterator iterator = iterators.peek(); @@ -210,21 +216,7 @@ public JsonArray getArray() { public Stream getArrayStream() { JsonStructureIterator current = iterators.peek(); if (current instanceof JsonArrayIterator) { - return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { - public Spliterator trySplit() { - return null; - } - - public boolean tryAdvance(Consumer action) { - Objects.requireNonNull(action); - if (!JsonStructureToParserAdapter.this.hasNext() || JsonStructureToParserAdapter.this.next() == Event.END_ARRAY) { - return false; - } else { - action.accept(JsonStructureToParserAdapter.this.getValue()); - return true; - } - } - }, false); + return streamFromSupplier(() -> (hasNext() && next() != Event.END_ARRAY) ? getValue() : null); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); } @@ -234,35 +226,22 @@ public boolean tryAdvance(Consumer action) { public Stream> getObjectStream() { JsonStructureIterator current = iterators.peek(); if (current instanceof JsonObjectIterator) { - return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { - public Spliterator> trySplit() { + return streamFromSupplier(() -> { + Event e = next(); + if (e == Event.END_OBJECT) { return null; - } - - public boolean tryAdvance(Consumer> action) { - Objects.requireNonNull(action); - if (!JsonStructureToParserAdapter.this.hasNext()) { - return false; + } else if (e != Event.KEY_NAME) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); + } else { + String key = getString(); + if (!hasNext()) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); } else { - Event e = JsonStructureToParserAdapter.this.next(); - if (e == Event.END_OBJECT) { - return false; - } else if (e != Event.KEY_NAME) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); - } else { - String key = JsonStructureToParserAdapter.this.getString(); - if (!JsonStructureToParserAdapter.this.hasNext()) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); - } else { - JsonStructureToParserAdapter.this.next(); - JsonValue value = JsonStructureToParserAdapter.this.getValue(); - action.accept(new AbstractMap.SimpleImmutableEntry<>(key, value)); - return true; - } - } + next(); + return new AbstractMap.SimpleImmutableEntry<>(key, getValue()); } } - }, false); + }); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); } @@ -273,24 +252,13 @@ public Stream getValueStream() { if (iterators.isEmpty()) { //JsonParserImpl delivers the whole object - so we have to do this the same way JsonStructureToParserAdapter.this.next(); - return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, ORDERED) { - public Spliterator trySplit() { + return streamFromSupplier(() -> { + if (hasNext()) { + return getValue(); + } else { return null; } - - public boolean tryAdvance(Consumer action) { - Objects.requireNonNull(action); - if (!JsonStructureToParserAdapter.this.hasNext()) { - return false; - } else { - //JsonParserImpl delivers the whole object - so we have to do this the same way - /*JsonStructureToParserAdapter.this.next();*/ - JsonValue value = JsonStructureToParserAdapter.this.getValue(); - action.accept(value); - return true; - } - } - }, false); + }); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValueStream can be only called at the root level of JSON structure")); } From 339043ac283afe1f4921f091b4a41424dfac766b Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 4 Nov 2023 21:34:21 +0100 Subject: [PATCH 39/68] [#625]Forward JsonProvider to JsonStructureToParserAdapter so it can be used for creation of JsonString for key in the getValue() Signed-off-by: Anton Pinsky --- .../eclipse/yasson/internal/JsonBinding.java | 49 ++++++------------- .../InheritanceInstanceCreator.java | 8 ++- .../jsonstructure/JsonObjectIterator.java | 10 ++-- .../JsonStructureToParserAdapter.java | 10 +++- .../JsonStructureToParserAdapterTest.java | 29 +++++------ 5 files changed, 44 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/JsonBinding.java b/src/main/java/org/eclipse/yasson/internal/JsonBinding.java index cd4764a3..c994a0f5 100644 --- a/src/main/java/org/eclipse/yasson/internal/JsonBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/JsonBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -21,7 +21,9 @@ import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.function.Supplier; import jakarta.json.JsonStructure; import jakarta.json.bind.JsonbConfig; @@ -51,70 +53,51 @@ public class JsonBinding implements YassonJsonb { } } - private T deserialize(final Type type, final JsonParser parser, final DeserializationContextImpl unmarshaller) { - return unmarshaller.deserialize(type, parser); + private T deserialize(final Type type, final Supplier parserSupplier) { + Objects.requireNonNull(parserSupplier); + try (JsonParser parser = parserSupplier.get()) { + return new DeserializationContextImpl(jsonbContext).deserialize(type, parser); + } } @Override public T fromJson(String str, Class type) throws JsonbException { - try (JsonParser parser = jsonbContext.getJsonProvider().createParser(new StringReader(str))) { - final DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - return deserialize(type, parser, unmarshaller); - } + return deserialize(type, () -> jsonbContext.getJsonProvider().createParser(new StringReader(str))); } @Override public T fromJson(String str, Type type) throws JsonbException { - try (JsonParser parser = jsonbContext.getJsonProvider().createParser(new StringReader(str))) { - DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - return deserialize(type, parser, unmarshaller); - } + return deserialize(type, () -> jsonbContext.getJsonProvider().createParser(new StringReader(str))); } @Override public T fromJson(Reader reader, Class type) throws JsonbException { - try (JsonParser parser = jsonbContext.getJsonProvider().createParser(reader)) { - DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - return deserialize(type, parser, unmarshaller); - } + return deserialize(type, () -> jsonbContext.getJsonProvider().createParser(reader)); } @Override public T fromJson(Reader reader, Type type) throws JsonbException { - try (JsonParser parser = jsonbContext.getJsonProvider().createParser(reader)) { - DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - return deserialize(type, parser, unmarshaller); - } + return deserialize(type, () -> jsonbContext.getJsonProvider().createParser(reader)); } @Override public T fromJson(InputStream stream, Class clazz) throws JsonbException { - DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - try (JsonParser parser = inputStreamParser(stream)) { - return deserialize(clazz, inputStreamParser(stream), unmarshaller); - } + return deserialize(clazz, () -> inputStreamParser(stream)); } @Override public T fromJson(InputStream stream, Type type) throws JsonbException { - DeserializationContextImpl unmarshaller = new DeserializationContextImpl(jsonbContext); - try (JsonParser parser = inputStreamParser(stream)) { - return deserialize(type, inputStreamParser(stream), unmarshaller); - } + return deserialize(type, () -> inputStreamParser(stream)); } @Override public T fromJsonStructure(JsonStructure jsonStructure, Class type) throws JsonbException { - try (JsonParser parser = new JsonStructureToParserAdapter(jsonStructure)) { - return deserialize(type, parser, new DeserializationContextImpl(jsonbContext)); - } + return deserialize(type, () -> new JsonStructureToParserAdapter(jsonStructure, jsonbContext.getJsonProvider())); } @Override public T fromJsonStructure(JsonStructure jsonStructure, Type runtimeType) throws JsonbException { - try (JsonParser parser = new JsonStructureToParserAdapter(jsonStructure)) { - return deserialize(runtimeType, parser, new DeserializationContextImpl(jsonbContext)); - } + return deserialize(runtimeType, () -> new JsonStructureToParserAdapter(jsonStructure, jsonbContext.getJsonProvider())); } private JsonParser inputStreamParser(InputStream stream) { diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/InheritanceInstanceCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/InheritanceInstanceCreator.java index efcc6c54..6379ce92 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/InheritanceInstanceCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/InheritanceInstanceCreator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -48,15 +48,13 @@ class InheritanceInstanceCreator implements ModelDeserializer { @Override public Object deserialize(JsonParser parser, DeserializationContextImpl context) { - String alias; - JsonParser jsonParser; String polymorphismKeyName = typeInheritanceConfiguration.getFieldName(); JsonObject object = parser.getObject(); - alias = object.getString(polymorphismKeyName, null); + String alias = object.getString(polymorphismKeyName, null); JsonObject newJsonObject = context.getJsonbContext().getJsonProvider().createObjectBuilder(object) .remove(polymorphismKeyName) .build(); - jsonParser = new JsonStructureToParserAdapter(newJsonObject); + JsonParser jsonParser = new JsonStructureToParserAdapter(newJsonObject, context.getJsonbContext().getJsonProvider()); //To get to the first event Event event = jsonParser.next(); context.setLastValueEvent(event); diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonObjectIterator.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonObjectIterator.java index 4ba94c7d..e1b983b3 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonObjectIterator.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonObjectIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -75,20 +75,20 @@ public JsonParser.Event next() { case START: if (keyIterator.hasNext()) { nextKey(); - setState(JsonObjectIterator.State.KEY); + setState(State.KEY); return JsonParser.Event.KEY_NAME; } else { setState(State.END); return JsonParser.Event.END_OBJECT; } case KEY: - setState(JsonObjectIterator.State.VALUE); + setState(State.VALUE); JsonValue value = getValue(); return getValueEvent(value); case VALUE: if (keyIterator.hasNext()) { nextKey(); - setState(JsonObjectIterator.State.KEY); + setState(State.KEY); return JsonParser.Event.KEY_NAME; } setState(State.END); @@ -119,7 +119,7 @@ public JsonValue getValue() { @Override String getString() { - if (state == JsonObjectIterator.State.KEY) { + if (state == State.KEY) { return currentKey; } return super.getString(); diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index 4a73a00f..ab8e9d86 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -31,6 +31,7 @@ import jakarta.json.JsonStructure; import jakarta.json.JsonValue; import jakarta.json.bind.JsonbException; +import jakarta.json.spi.JsonProvider; import jakarta.json.stream.JsonLocation; import jakarta.json.stream.JsonParser; @@ -53,16 +54,19 @@ public class JsonStructureToParserAdapter implements JsonParser { private final Deque iterators = new ArrayDeque<>(); private final JsonStructure rootStructure; + private final JsonProvider jsonProvider; private Event currentEvent; /** * Creates new {@link JsonStructure} parser. * - * @param structure json structure + * @param structure json structure + * @param jsonProvider json provider for creation of {@link JsonValue} for keys */ - public JsonStructureToParserAdapter(JsonStructure structure) { + public JsonStructureToParserAdapter(JsonStructure structure, JsonProvider jsonProvider) { this.rootStructure = structure; + this.jsonProvider = jsonProvider; } /** @@ -189,6 +193,8 @@ public JsonValue getValue() { return getObject(); case START_ARRAY: return getArray(); + case KEY_NAME: + return jsonProvider.createValue(iterator.getString()); default: return iterator.getValue(); } diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index 0137d795..8f47d362 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -320,7 +320,7 @@ public void testNumbers() { .add("BigDecimal", BigDecimal.TEN) .build(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); parser.next(); parser.getString(); @@ -358,7 +358,7 @@ public void testNumbers() { public void testParser_getString(){ JsonObject jsonObject = TestData.createFamilyPerson(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -377,7 +377,7 @@ public void testParser_getString(){ public void testParser_getValue(){ JsonObject jsonObject = TestData.createFamilyPerson(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -388,12 +388,7 @@ public void testParser_getValue(){ } } - //should look like this with a correct implementation -> FAMILY_MATCHER_KEYS_WITH_QUOTATION - /*assertThat(values, contains("\"name\"", "\"John\"", "\"surname\"", "\"Smith\"", "\"age\"", "30", "\"married\"", "true", - "\"wife\"", "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "\"children\"", "[\"Jack\",\"Mike\"]"));*/ - assertThat(values, contains("\"John\"", "\"John\"", "\"Smith\"", "\"Smith\"", "30", "30", "true", "true", - "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", "{\"name\":\"Deborah\",\"surname\":\"Harris\"}", - "[\"Jack\",\"Mike\"]", "[\"Jack\",\"Mike\"]")); + assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITH_QUOTATION); } } @@ -401,7 +396,7 @@ public void testParser_getValue(){ public void testSkipArray() { JsonObject jsonObject = TestData.createObjectWithArrays(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); parser.next(); parser.getString(); @@ -418,7 +413,7 @@ public void testSkipArray() { public void testSkipObject() { JsonObject jsonObject = TestData.createJsonObject(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); parser.next(); parser.getString(); @@ -438,7 +433,7 @@ public class StreamTests { public void testGetValueStream_GetOneElement() { JsonObject jsonObject = TestData.createFamilyPerson(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { JsonString name = (JsonString) parser.getValueStream() .map(JsonValue::asJsonObject) .map(JsonObject::values) @@ -457,7 +452,7 @@ public void testGetValueStream_GetOneElement() { public void testGetValueStream_GetList() { JsonObject jsonObject = TestData.createFamilyPerson(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); assertThat(values, contains(TestData.JSON_FAMILY_STRING)); @@ -468,7 +463,7 @@ public void testGetValueStream_GetList() { public void testGetArrayStream_GetOneElement() { JsonObject jsonObject = TestData.createObjectWithArrays(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); parser.next(); String key = parser.getString(); @@ -486,7 +481,7 @@ public void testGetArrayStream_GetOneElement() { public void testGetArrayStream_GetList() { JsonObject jsonObject = TestData.createObjectWithArrays(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); parser.next(); String key = parser.getString(); @@ -502,7 +497,7 @@ public void testGetArrayStream_GetList() { public void testGetObjectStream_GetOneElement() { JsonObject jsonObject = TestData.createJsonObject(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); String surname = parser.getObjectStream().filter(e -> e.getKey().equals("firstPerson")) .map(Map.Entry::getValue) @@ -519,7 +514,7 @@ public void testGetObjectStream_GetOneElement() { public void testGetObjectStream_GetList() { JsonObject jsonObject = TestData.createFamilyPerson(); - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject)) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { parser.next(); List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); From 44c7b734bd8180597d663bfb644bf5d4efe82d45 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 6 Nov 2023 00:21:39 +0100 Subject: [PATCH 40/68] [#627]Corrected the introspectXXX methods in the ComponentMatcher to compare the right classes; extended tests for this issue; more generics in the bindings Signed-off-by: Anton Pinsky --- .../yasson/internal/ComponentMatcher.java | 38 +++++----- .../components/AbstractComponentBinding.java | 30 ++++++-- .../internal/components/AdapterBinding.java | 22 +----- .../components/ComponentBindings.java | 75 ++++++++++++++----- .../components/DeserializerBinding.java | 23 +----- .../components/SerializerBinding.java | 28 +------ .../deserializer/AdapterDeserializer.java | 4 +- .../DeserializationModelCreator.java | 4 +- .../serializer/AdapterSerializer.java | 4 +- .../serializer/SerializationModelCreator.java | 2 +- .../eclipse/yasson/adapters/AdaptersTest.java | 20 +++++ .../yasson/adapters/model/NumberAdapter.java | 15 +++- .../yasson/serializers/SerializersTest.java | 32 ++++++-- .../yasson/serializers/model/Counter.java | 32 ++++++++ .../serializers/model/NumberDeserializer.java | 15 +++- .../serializers/model/NumberSerializer.java | 13 +++- 16 files changed, 230 insertions(+), 127 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/Counter.java diff --git a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java index ab5825d4..0e2aa931 100644 --- a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java +++ b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java @@ -95,38 +95,36 @@ void init() { private void addSerializer(Type bindingType, SerializerBinding serializer) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getSerializer() != null) { + if (bindings.getSerializerBinding() != null) { return bindings; } registerGeneric(bindingType); @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = - new ComponentBindings(bindingType, serializer, bindings.getDeserializer(), bindings.getAdapterInfo()); + ComponentBindings componentBindings = new ComponentBindings(bindings, serializer); return componentBindings; }); } private void addDeserializer(Type bindingType, DeserializerBinding deserializer) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getDeserializer() != null) { + if (bindings.getDeserializerBinding() != null) { return bindings; } registerGeneric(bindingType); @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = - new ComponentBindings(bindingType, bindings.getSerializer(), deserializer, bindings.getAdapterInfo()); + ComponentBindings componentBindings = new ComponentBindings(bindings, deserializer); return componentBindings; }); } private void addAdapter(Type bindingType, AdapterBinding adapter) { userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getAdapterInfo() != null) { + if (bindings.getAdapterBinding() != null) { return bindings; } registerGeneric(bindingType); @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = new ComponentBindings(bindingType, bindings.getSerializer(), bindings.getDeserializer(), adapter); + ComponentBindings componentBindings = new ComponentBindings(bindings, adapter); return componentBindings; }); } @@ -153,7 +151,7 @@ public Optional> getSerializerBinding(Type propertyRuntimeT ComponentBoundCustomization customization) { if (customization == null || customization.getSerializerBinding() == null) { - return searchComponentBinding(propertyRuntimeType, ComponentBindings::getSerializer); + return searchComponentBinding(propertyRuntimeType, ComponentBindings::getSerializerBinding); } return Optional.of(customization.getSerializerBinding()); } @@ -168,7 +166,7 @@ public Optional> getSerializerBinding(Type propertyRuntimeT public Optional> getDeserializerBinding(Type propertyRuntimeType, ComponentBoundCustomization customization) { if (customization == null || customization.getDeserializerBinding() == null) { - return searchComponentBinding(propertyRuntimeType, ComponentBindings::getDeserializer); + return searchComponentBinding(propertyRuntimeType, ComponentBindings::getDeserializerBinding); } return Optional.of(customization.getDeserializerBinding()); } @@ -184,7 +182,7 @@ public Optional> getDeserializerBinding(Type propertyRunt public Optional> getSerializeAdapterBinding(Type propertyRuntimeType, ComponentBoundCustomization customization) { if (customization == null || customization.getSerializeAdapterBinding() == null) { - return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterInfo); + return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterBinding); } return Optional.of(customization.getSerializeAdapterBinding()); } @@ -200,12 +198,12 @@ public Optional> getDeserializerBinding(Type propertyRunt public Optional> getDeserializeAdapterBinding(Type propertyRuntimeType, ComponentBoundCustomization customization) { if (customization == null || customization.getDeserializeAdapterBinding() == null) { - return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterInfo); + return searchComponentBinding(propertyRuntimeType, ComponentBindings::getAdapterBinding); } return Optional.of(customization.getDeserializeAdapterBinding()); } - private Optional searchComponentBinding(Type runtimeType, Function, T> supplier) { + private > Optional searchComponentBinding(Type runtimeType, Function, T> supplier) { // First check if there is an exact match Optional match = getMatchingBinding(runtimeType, supplier); if (match.isPresent()) { @@ -235,7 +233,7 @@ private Optional searchComponentBinding( return Optional.empty(); } - private Optional getMatchingBinding(Type runtimeType, Function, T> supplier) { + private > Optional getMatchingBinding(Type runtimeType, Function, T> supplier) { ComponentBindings binding = userComponents.get(runtimeType); if (binding != null) { Optional match = getMatchingBinding(runtimeType, binding, supplier); @@ -306,9 +304,9 @@ private boolean matchTypeArguments(ParameterizedType requiredType, Parameterized Type adaptFromType = resolveTypeArg(adapterTypeArguments[0], adapterClass); Type adaptToType = resolveTypeArg(adapterTypeArguments[1], adapterClass); final ComponentBindings componentBindings = getBindingInfo(adaptFromType); - if (componentBindings.getAdapterInfo() != null && componentBindings.getAdapterInfo().getAdapter().getClass() + if (componentBindings.getAdapterBinding() != null && componentBindings.getAdapterBinding().getComponentClass() .equals(adapterClass)) { - return componentBindings.getAdapterInfo(); + return componentBindings.getAdapterBinding(); } A newAdapter = instance != null ? instance @@ -329,9 +327,9 @@ > DeserializerBinding introspectDeserialize .findParameterizedType(deserializerClass, JsonbDeserializer.class); Type deserializerBindingType = resolveTypeArg(deserializerRuntimeType.getActualTypeArguments()[0], deserializerClass); final ComponentBindings componentBindings = getBindingInfo(deserializerBindingType); - if (componentBindings.getDeserializer() != null && componentBindings.getDeserializer().getClass() + if (componentBindings.getDeserializerBinding() != null && componentBindings.getDeserializerBinding().getComponentClass() .equals(deserializerClass)) { - return componentBindings.getDeserializer(); + return componentBindings.getDeserializerBinding(); } else { D deserializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() .getOrCreateComponent(deserializerClass); @@ -353,8 +351,8 @@ > SerializerBinding introspectSerializerBindi .findParameterizedType(serializerClass, JsonbSerializer.class); Type serBindingType = resolveTypeArg(serializerRuntimeType.getActualTypeArguments()[0], serializerClass); final ComponentBindings componentBindings = getBindingInfo(serBindingType); - if (componentBindings.getSerializer() != null && componentBindings.getSerializer().getClass().equals(serializerClass)) { - return componentBindings.getSerializer(); + if (componentBindings.getSerializerBinding() != null && componentBindings.getSerializerBinding().getComponentClass().equals(serializerClass)) { + return componentBindings.getSerializerBinding(); } else { S serializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() .getOrCreateComponent(serializerClass); diff --git a/src/main/java/org/eclipse/yasson/internal/components/AbstractComponentBinding.java b/src/main/java/org/eclipse/yasson/internal/components/AbstractComponentBinding.java index f3be5887..a2a24dc5 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/AbstractComponentBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/AbstractComponentBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -17,24 +17,31 @@ /** * Wrapper for user components, components, (de)serializer. - * Contains resolved binding type an component. + * Contains resolved binding type and component. + * + * @param type of component */ -public abstract class AbstractComponentBinding { +public abstract class AbstractComponentBinding { private final Type bindingType; + private final C component; + /** * Creates info. * * @param bindingType type to which component is bound. + * @param component bound component. */ - public AbstractComponentBinding(Type bindingType) { + public AbstractComponentBinding(Type bindingType, C component) { Objects.requireNonNull(bindingType); + Objects.requireNonNull(component); this.bindingType = bindingType; + this.component = component; } /** - * Resolved binding type of a component. + * Resolved binding type of the component. * * @return binding type */ @@ -42,10 +49,21 @@ public Type getBindingType() { return bindingType; } + /** + * Get actual user component. + * + * @return user component. + */ + public C getComponent(){ + return component; + } + /** * Class of user component. * * @return component class */ - public abstract Class getComponentClass(); + public Class getComponentClass(){ + return component.getClass(); + } } diff --git a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java index 8a377299..360261c8 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/AdapterBinding.java @@ -23,12 +23,10 @@ * @param The type for the @{@link JsonbAdapter} that JSONB doesn't know how to handle. * @param The type for the @{@link JsonbAdapter} that JSONB knows how to handle out of the box. */ -public class AdapterBinding extends AbstractComponentBinding { +public class AdapterBinding extends AbstractComponentBinding> { private final Type toType; - private final JsonbAdapter adapter; - /** * Adapter info with type to "adapt from", type to "adapt to" and an components itself. * @@ -37,11 +35,9 @@ public class AdapterBinding extends AbstractComponentBinding * @param adapter components not null */ public AdapterBinding(Type fromType, Type toType, JsonbAdapter adapter) { - super(fromType); + super(fromType, adapter); Objects.requireNonNull(toType); - Objects.requireNonNull(adapter); this.toType = toType; - this.adapter = adapter; } /** @@ -55,18 +51,4 @@ public AdapterBinding(Type fromType, Type toType, JsonbAdapter getAdapter() { - return adapter; - } - - @Override - public Class getComponentClass() { - return adapter.getClass(); - } } diff --git a/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java b/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java index 43ce0ec7..d9c53ddf 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java +++ b/src/main/java/org/eclipse/yasson/internal/components/ComponentBindings.java @@ -13,6 +13,7 @@ package org.eclipse.yasson.internal.components; import java.lang.reflect.Type; +import java.util.Objects; import jakarta.json.bind.adapter.JsonbAdapter; import jakarta.json.bind.serializer.JsonbDeserializer; @@ -29,11 +30,11 @@ public class ComponentBindings { private final Type bindingType; - private final SerializerBinding serializer; + private final SerializerBinding serializerBinding; - private final DeserializerBinding deserializer; + private final DeserializerBinding deserializerBinding; - private final AdapterBinding adapterInfo; + private final AdapterBinding adapterBinding; /** * Construct empty bindings for a given type. @@ -47,19 +48,53 @@ public ComponentBindings(Type bindingType) { /** * Creates an instance and populates it with bindings for a given type. * - * @param bindingType Type components are bound to. - * @param serializer Serializer. - * @param deserializer Deserializer. - * @param adapter Adapter. + * @param bindingType Type components are bound to. + * @param serializerBinding Serializer. + * @param deserializerBinding Deserializer. + * @param adapterBinding Adapter. */ - public ComponentBindings(Type bindingType, - SerializerBinding serializer, - DeserializerBinding deserializer, - AdapterBinding adapter) { + private ComponentBindings(Type bindingType, + SerializerBinding serializerBinding, + DeserializerBinding deserializerBinding, + AdapterBinding adapterBinding) { + Objects.requireNonNull(bindingType); this.bindingType = bindingType; - this.serializer = serializer; - this.deserializer = deserializer; - this.adapterInfo = adapter; + this.serializerBinding = serializerBinding; + this.deserializerBinding = deserializerBinding; + this.adapterBinding = adapterBinding; + } + + /** + * Creates a copy of the given bindings and new serializer. + * + * @param bindings Deserializer and adapter will be copied from this instance. + * @param serializerBinding New serializer. The bound type for the copy will be also taken from this serializer. + */ + public ComponentBindings(ComponentBindings bindings, + SerializerBinding serializerBinding) { + this(Objects.requireNonNull(serializerBinding).getBindingType(), serializerBinding, bindings.deserializerBinding, bindings.adapterBinding); + } + + /** + * Creates a copy of the given bindings and new deserializer. + * + * @param bindings Serializer and adapter will be copied from this instance. + * @param deserializerBinding New deserializer. The bound type for the copy will be also taken from this deserializer. + */ + public ComponentBindings(ComponentBindings bindings, + DeserializerBinding deserializerBinding) { + this(Objects.requireNonNull(deserializerBinding).getBindingType(), bindings.serializerBinding, deserializerBinding, bindings.adapterBinding); + } + + /** + * Creates a copy of the given bindings and new adapter. + * + * @param bindings Serializer and serializer will be copied from this instance. + * @param adapterBinding New adapter. The bound type for the copy will be also taken from this adapter. + */ + public ComponentBindings(ComponentBindings bindings, + AdapterBinding adapterBinding) { + this(Objects.requireNonNull(adapterBinding).getBindingType(), bindings.serializerBinding, bindings.deserializerBinding, adapterBinding); } /** @@ -76,8 +111,8 @@ public Type getBindingType() { * * @return serializer */ - public SerializerBinding getSerializer() { - return serializer; + public SerializerBinding getSerializerBinding() { + return serializerBinding; } /** @@ -85,8 +120,8 @@ public SerializerBinding getSerializer() { * * @return deserializer */ - public DeserializerBinding getDeserializer() { - return deserializer; + public DeserializerBinding getDeserializerBinding() { + return deserializerBinding; } /** @@ -94,8 +129,8 @@ public DeserializerBinding getDeserializer() { * * @return adapterInfo */ - public AdapterBinding getAdapterInfo() { - return adapterInfo; + public AdapterBinding getAdapterBinding() { + return adapterBinding; } } diff --git a/src/main/java/org/eclipse/yasson/internal/components/DeserializerBinding.java b/src/main/java/org/eclipse/yasson/internal/components/DeserializerBinding.java index b2ed21bb..fcecdfe8 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/DeserializerBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/DeserializerBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -21,9 +21,7 @@ * * @param type of contained deserializer */ -public class DeserializerBinding extends AbstractComponentBinding { - - private final JsonbDeserializer jsonbDeserializer; +public class DeserializerBinding extends AbstractComponentBinding> { /** * Creates a new instance. @@ -32,21 +30,6 @@ public class DeserializerBinding extends AbstractComponentBinding { * @param jsonbDeserializer Deserializer. */ public DeserializerBinding(Type bindingType, JsonbDeserializer jsonbDeserializer) { - super(bindingType); - this.jsonbDeserializer = jsonbDeserializer; - } - - /** - * Gets deserializer if any. - * - * @return Deserializer. - */ - public JsonbDeserializer getJsonbDeserializer() { - return jsonbDeserializer; - } - - @Override - public Class getComponentClass() { - return jsonbDeserializer.getClass(); + super(bindingType, jsonbDeserializer); } } diff --git a/src/main/java/org/eclipse/yasson/internal/components/SerializerBinding.java b/src/main/java/org/eclipse/yasson/internal/components/SerializerBinding.java index 6baafde3..e179498e 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/SerializerBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/components/SerializerBinding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -21,9 +21,7 @@ * * @param type of jsonb serializer */ -public class SerializerBinding extends AbstractComponentBinding { - - private final JsonbSerializer jsonbSerializer; +public class SerializerBinding extends AbstractComponentBinding> { /** * Creates a new instance. @@ -32,26 +30,6 @@ public class SerializerBinding extends AbstractComponentBinding { * @param jsonbSerializer Serializer. Can be null. */ public SerializerBinding(Type bindingType, JsonbSerializer jsonbSerializer) { - super(bindingType); - this.jsonbSerializer = jsonbSerializer; - } - - /** - * Returns a serializer if any. - * - * @return Serializer. - */ - public JsonbSerializer getJsonbSerializer() { - return jsonbSerializer; - } - - /** - * Class of user component. - * - * @return Component class. - */ - @Override - public Class getComponentClass() { - return jsonbSerializer.getClass(); + super(bindingType, jsonbSerializer); } } diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java index 7d7775f0..6f5245ba 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/AdapterDeserializer.java @@ -33,7 +33,7 @@ class AdapterDeserializer implements ModelDeserializer { AdapterDeserializer(AdapterBinding adapterBinding, ModelDeserializer delegate) { this.adapterBinding = adapterBinding; - this.adapter = (JsonbAdapter) adapterBinding.getAdapter(); + this.adapter = (JsonbAdapter) adapterBinding.getComponent(); this.delegate = delegate; } @@ -45,7 +45,7 @@ public Object deserialize(Object value, DeserializationContextImpl context) { throw new JsonbException(Messages.getMessage(MessageKeys.ADAPTER_EXCEPTION, adapterBinding.getBindingType(), adapterBinding.getToType(), - adapterBinding.getAdapter().getClass()), e); + adapterBinding.getComponentClass()), e); } } diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java index 7e4a29d1..31d5c99b 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java @@ -157,7 +157,7 @@ private ModelDeserializer deserializerChainInternal(LinkedList Optional> deserializerBinding = userDeserializer(type, (ComponentBoundCustomization) propertyCustomization); if (deserializerBinding.isPresent()) { - UserDefinedDeserializer user = new UserDefinedDeserializer(deserializerBinding.get().getJsonbDeserializer(), + UserDefinedDeserializer user = new UserDefinedDeserializer(deserializerBinding.get().getComponent(), JustReturn.instance(), type, classCustomization); models.put(cachedItem, user); return user; @@ -448,7 +448,7 @@ private ModelDeserializer typeProcessor(LinkedList chain, // memberDeserializer, // resolved, // customization); - return new UserDefinedDeserializer(deserializerBinding.get().getJsonbDeserializer(), + return new UserDefinedDeserializer(deserializerBinding.get().getComponent(), memberDeserializer, resolved, customization); diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java index 673a31f0..742a0c05 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/AdapterSerializer.java @@ -33,7 +33,7 @@ class AdapterSerializer extends AbstractSerializer { AdapterSerializer(AdapterBinding adapterBinding, ModelSerializer delegate) { super(delegate); - this.adapter = (JsonbAdapter) adapterBinding.getAdapter(); + this.adapter = (JsonbAdapter) adapterBinding.getComponent(); this.adapterBinding = adapterBinding; } @@ -45,7 +45,7 @@ public void serialize(Object value, JsonGenerator generator, SerializationContex throw new JsonbException(Messages.getMessage(MessageKeys.ADAPTER_EXCEPTION, adapterBinding.getBindingType(), adapterBinding.getToType(), - adapter.getClass()), e); + adapterBinding.getComponentClass()), e); } } diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java index 8e24ac65..f563dc5c 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java @@ -419,7 +419,7 @@ private ModelSerializer memberSerializer(LinkedList chain, private Optional userSerializer(Type type, ComponentBoundCustomization classCustomization) { final ComponentMatcher componentMatcher = jsonbContext.getComponentMatcher(); return componentMatcher.getSerializerBinding(type, classCustomization) - .map(SerializerBinding::getJsonbSerializer) + .map(SerializerBinding::getComponent) .map(UserDefinedSerializer::new) .map(RecursionChecker::new) .map(serializer -> SerializationModelCreator.wrapInCommonSet(serializer, diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 24f35c90..47c0fe01 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -39,6 +39,7 @@ import org.eclipse.yasson.adapters.model.GenericBox; import org.eclipse.yasson.adapters.model.IntegerListToStringAdapter; import org.eclipse.yasson.adapters.model.JsonObjectPojo; +import org.eclipse.yasson.adapters.model.NumberAdapter; import org.eclipse.yasson.adapters.model.ReturnNullAdapter; import org.eclipse.yasson.adapters.model.SupertypeAdapterPojo; import org.eclipse.yasson.adapters.model.UUIDContainer; @@ -504,6 +505,7 @@ public void testAdaptUUID() { @Test public void testSupertypeAdapter() { + NumberAdapter.getCounter().resetCount(); SupertypeAdapterPojo pojo = new SupertypeAdapterPojo(); pojo.setNumberInteger(10); pojo.setSerializableInteger(11); @@ -511,8 +513,26 @@ public void testSupertypeAdapter() { pojo = defaultJsonb.fromJson("{\"numberInteger\":\"11\",\"serializableInteger\":12}", SupertypeAdapterPojo.class); assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); assertEquals(Integer.valueOf(11), pojo.getSerializableInteger()); + //assert that the adapter was used just once + assertEquals(1, NumberAdapter.getCounter().getCount()); } + @Test + public void testSupertypeAdapter_withConfiguration() throws Exception { + NumberAdapter.getCounter().resetCount(); + SupertypeAdapterPojo pojo = new SupertypeAdapterPojo(); + pojo.setNumberInteger(10); + pojo.setSerializableInteger(11); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new NumberAdapter()))) { + assertEquals("{\"numberInteger\":\"11\",\"serializableInteger\":12}", jsonb.toJson(pojo)); + pojo = jsonb.fromJson("{\"numberInteger\":\"11\",\"serializableInteger\":12}", SupertypeAdapterPojo.class); + assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); + assertEquals(Integer.valueOf(11), pojo.getSerializableInteger()); + //assert that the adapter was reused + assertEquals(1, NumberAdapter.getCounter().getCount()); + } + } + public static class PropertyTypeMismatch { private Throwable error = new RuntimeException("foo"); diff --git a/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java index 2439807d..397a6297 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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,9 +12,22 @@ package org.eclipse.yasson.adapters.model; +import org.eclipse.yasson.serializers.model.Counter; + import jakarta.json.bind.adapter.JsonbAdapter; public class NumberAdapter implements JsonbAdapter { + + private final static Counter counter = new Counter(); + + public static Counter getCounter() { + return counter; + } + + { + counter.add(); + } + @Override public String adaptToJson(Number obj) throws Exception { return Integer.valueOf(((Integer)obj) + 1).toString(); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 416fb0e0..db423408 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -424,10 +424,12 @@ public void testAuthor() { } @Test - public void testSupertypeSerializer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create( - new JsonbConfig().withSerializers(new NumberSerializer()) - .withDeserializers(new NumberDeserializer()))) { + public void testSupertypeSerializer_withConfiguration() throws Exception { + NumberSerializer.getCounter().resetCount(); + NumberDeserializer.getCounter().resetCount(); + try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() + .withSerializers(new NumberSerializer()) + .withDeserializers(new NumberDeserializer()))) { SupertypeSerializerPojo pojo = new SupertypeSerializerPojo(); pojo.setNumberInteger(10); pojo.setAnotherNumberInteger(11); @@ -436,9 +438,29 @@ public void testSupertypeSerializer() throws Exception { pojo = jsonb.fromJson("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", SupertypeSerializerPojo.class); assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); assertEquals(Integer.valueOf(11), pojo.getAnotherNumberInteger()); + //assert that deserializer and serializer were reused + assertEquals(1, NumberSerializer.getCounter().getCount()); + assertEquals(1, NumberDeserializer.getCounter().getCount()); } } - + + @Test + public void testSupertypeSerializer() { + NumberSerializer.getCounter().resetCount(); + NumberDeserializer.getCounter().resetCount(); + SupertypeSerializerPojo pojo = new SupertypeSerializerPojo(); + pojo.setNumberInteger(9); + pojo.setAnotherNumberInteger(11); + assertEquals("{\"anotherNumberInteger\":11,\"numberInteger\":\"10\"}", defaultJsonb.toJson(pojo)); + + pojo = defaultJsonb.fromJson("{\"anotherNumberInteger\":11,\"numberInteger\":\"10\"}", SupertypeSerializerPojo.class); + assertEquals(Integer.valueOf(9), pojo.getNumberInteger()); + assertEquals(Integer.valueOf(11), pojo.getAnotherNumberInteger()); + //assert that deserializer and serializer were used just once + assertEquals(1, NumberSerializer.getCounter().getCount()); + assertEquals(1, NumberDeserializer.getCounter().getCount()); + } + @Test public void testObjectDeserializerWithLexOrderStrategy() throws Exception { try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))) { diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Counter.java b/src/test/java/org/eclipse/yasson/serializers/model/Counter.java new file mode 100644 index 00000000..d6239e20 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/Counter.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018, 2023 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 + * 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.serializers.model; + +public class Counter { + + private long counter = 0; + + public Counter() {} + + public void add() { + counter++; + } + + public long getCount() { + return counter; + } + + public void resetCount() { + counter=0; + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java index c5bd8f2f..344ada98 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -18,8 +18,19 @@ import java.lang.reflect.Type; public class NumberDeserializer implements JsonbDeserializer { + + private final static Counter counter = new Counter(); + + public static Counter getCounter() { + return counter; + } + + { + counter.add(); + } + @Override public Number deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { - return Integer.valueOf(parser.getString()) - 1; + return Integer.parseInt(parser.getString()) - 1; } } diff --git a/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java index 9ec4f1fc..fe74dc22 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -17,6 +17,17 @@ import jakarta.json.stream.JsonGenerator; public class NumberSerializer implements JsonbSerializer { + + private final static Counter counter = new Counter(); + + public static Counter getCounter() { + return counter; + } + + { + counter.add(); + } + @Override public void serialize(Number obj, JsonGenerator generator, SerializationContext ctx) { generator.write(Integer.valueOf(obj.intValue() + 1).toString()); From 3c1092225e042bfd9f89017238f9e04f9270b20e Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 6 Nov 2023 00:32:58 +0100 Subject: [PATCH 41/68] [#627]More functional interfaces, less repeating code Signed-off-by: Anton Pinsky --- .../internal/AnnotationIntrospector.java | 102 ++++------- .../yasson/internal/ComponentMatcher.java | 162 ++++++++---------- .../VariableTypeInheritanceSearch.java | 12 +- 3 files changed, 119 insertions(+), 157 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java index 3039ee66..5d9f01f8 100644 --- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java +++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java @@ -224,33 +224,16 @@ JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Cl */ public AdapterBinding getAdapterBinding(Property property) { Objects.requireNonNull(property); - JsonbTypeAdapter adapterAnnotation = getAnnotationFromProperty(JsonbTypeAdapter.class, property) - .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeAdapter.class)); - if (adapterAnnotation == null) { - return null; - } - - return getAdapterBindingFromAnnotation(adapterAnnotation, ReflectionUtils.getOptionalRawType(property.getPropertyType())); + return getAdapterBindingFromAnnotation(getAnnotationFromProperty(JsonbTypeAdapter.class, property) + .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeAdapter.class)), + ReflectionUtils.getOptionalRawType(property.getPropertyType())); } - /** - * Checks for {@link JsonbAdapter} on a type. - * - * @param clsElement type not null - * @return components info - */ - public AdapterBinding getAdapterBinding(JsonbAnnotatedElement> clsElement) { - Objects.requireNonNull(clsElement); - - JsonbTypeAdapter adapterAnnotation = clsElement.getElement().getAnnotation(JsonbTypeAdapter.class); + private AdapterBinding getAdapterBindingFromAnnotation(JsonbTypeAdapter adapterAnnotation, Optional> expectedClass) { if (adapterAnnotation == null) { return null; } - return getAdapterBindingFromAnnotation(adapterAnnotation, Optional.ofNullable(clsElement.getElement())); - } - - private AdapterBinding getAdapterBindingFromAnnotation(JsonbTypeAdapter adapterAnnotation, Optional> expectedClass) { @SuppressWarnings("rawtypes") final Class adapterClass = adapterAnnotation.value(); @SuppressWarnings("unchecked") @@ -259,12 +242,24 @@ JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Cl if (expectedClass.isPresent() && !( ReflectionUtils.getRawType(adapterBinding.getBindingType()).isAssignableFrom(expectedClass.get()))) { throw new JsonbException(Messages.getMessage(MessageKeys.ADAPTER_INCOMPATIBLE, - adapterBinding.getBindingType(), - expectedClass.get())); + adapterBinding.getBindingType(), + expectedClass.get())); } return adapterBinding; } + /** + * Checks for {@link JsonbAdapter} on a type. + * + * @param clsElement type not null + * @return components info + */ + public AdapterBinding getAdapterBinding(JsonbAnnotatedElement> clsElement) { + Objects.requireNonNull(clsElement); + return getAdapterBindingFromAnnotation(clsElement.getElement().getAnnotation(JsonbTypeAdapter.class), + Optional.ofNullable(clsElement.getElement())); + } + /** * Checks for {@link JsonbDeserializer} on a property. * @@ -273,8 +268,11 @@ JsonbCreator createJsonbCreator(Executable executable, JsonbCreator existing, Cl */ public DeserializerBinding getDeserializerBinding(Property property) { Objects.requireNonNull(property); - JsonbTypeDeserializer deserializerAnnotation = getAnnotationFromProperty(JsonbTypeDeserializer.class, property) - .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeDeserializer.class)); + return getDeserializerBindingFromAnnotation(getAnnotationFromProperty(JsonbTypeDeserializer.class, property) + .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeDeserializer.class))); + } + + private DeserializerBinding getDeserializerBindingFromAnnotation(JsonbTypeDeserializer deserializerAnnotation) { if (deserializerAnnotation == null) { return null; } @@ -294,18 +292,8 @@ public DeserializerBinding getDeserializerBinding(Property property) { */ public DeserializerBinding getDeserializerBinding(Parameter parameter) { Objects.requireNonNull(parameter); - JsonbTypeDeserializer deserializerAnnotation = - Optional.ofNullable(parameter.getDeclaredAnnotation(JsonbTypeDeserializer.class)) - .orElseGet(() -> getAnnotationFromParameterType(parameter, JsonbTypeDeserializer.class)); - if (deserializerAnnotation == null) { - return null; - } - - @SuppressWarnings("rawtypes") - final Class deserializerClass = deserializerAnnotation.value(); - @SuppressWarnings("unchecked") - DeserializerBinding deserializerBinding = jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); - return deserializerBinding; + return getDeserializerBindingFromAnnotation(Optional.ofNullable(parameter.getDeclaredAnnotation(JsonbTypeDeserializer.class)) + .orElseGet(() -> getAnnotationFromParameterType(parameter, JsonbTypeDeserializer.class))); } /** @@ -316,14 +304,9 @@ public DeserializerBinding getDeserializerBinding(Parameter parameter) { */ public AdapterBinding getAdapterBinding(Parameter parameter) { Objects.requireNonNull(parameter); - JsonbTypeAdapter adapter = - Optional.ofNullable(parameter.getDeclaredAnnotation(JsonbTypeAdapter.class)) - .orElseGet(() -> getAnnotationFromParameterType(parameter, JsonbTypeAdapter.class)); - if (adapter == null) { - return null; - } - - return getAdapterBindingFromAnnotation(adapter, ReflectionUtils.getOptionalRawType(parameter.getParameterizedType())); + return getAdapterBindingFromAnnotation(Optional.ofNullable(parameter.getDeclaredAnnotation(JsonbTypeAdapter.class)) + .orElseGet(() -> getAnnotationFromParameterType(parameter, JsonbTypeAdapter.class)), + ReflectionUtils.getOptionalRawType(parameter.getParameterizedType())); } private T getAnnotationFromParameterType(Parameter parameter, Class annotationClass) { @@ -341,16 +324,7 @@ private T getAnnotationFromParameterType(Parameter parame */ public DeserializerBinding getDeserializerBinding(JsonbAnnotatedElement> clsElement) { Objects.requireNonNull(clsElement); - JsonbTypeDeserializer deserializerAnnotation = clsElement.getElement().getAnnotation(JsonbTypeDeserializer.class); - if (deserializerAnnotation == null) { - return null; - } - - @SuppressWarnings("rawtypes") - final Class deserializerClass = deserializerAnnotation.value(); - @SuppressWarnings("unchecked") - DeserializerBinding deserializerBinding = jsonbContext.getComponentMatcher().introspectDeserializerBinding(deserializerClass, null); - return deserializerBinding; + return getDeserializerBindingFromAnnotation(clsElement.getElement().getAnnotation(JsonbTypeDeserializer.class)); } /** @@ -361,8 +335,11 @@ public DeserializerBinding getDeserializerBinding(JsonbAnnotatedElement getSerializerBinding(Property property) { Objects.requireNonNull(property); - JsonbTypeSerializer serializerAnnotation = getAnnotationFromProperty(JsonbTypeSerializer.class, property) - .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeSerializer.class)); + return getSerializerBindingFromAnnotation(getAnnotationFromProperty(JsonbTypeSerializer.class, property) + .orElseGet(() -> getAnnotationFromPropertyType(property, JsonbTypeSerializer.class))); + } + + private SerializerBinding getSerializerBindingFromAnnotation(JsonbTypeSerializer serializerAnnotation) { if (serializerAnnotation == null) { return null; } @@ -382,16 +359,7 @@ public SerializerBinding getSerializerBinding(Property property) { */ public SerializerBinding getSerializerBinding(JsonbAnnotatedElement> clsElement) { Objects.requireNonNull(clsElement); - JsonbTypeSerializer serializerAnnotation = clsElement.getElement().getAnnotation(JsonbTypeSerializer.class); - if (serializerAnnotation == null) { - return null; - } - - @SuppressWarnings("rawtypes") - final Class serializerClass = serializerAnnotation.value(); - @SuppressWarnings("unchecked") - SerializerBinding serializerBinding = jsonbContext.getComponentMatcher().introspectSerializerBinding(serializerClass, null); - return serializerBinding; + return getSerializerBindingFromAnnotation(clsElement.getElement().getAnnotation(JsonbTypeSerializer.class)); } private T getAnnotationFromPropertyType(Property property, Class annotationClass) { diff --git a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java index 0e2aa931..a8976ce4 100644 --- a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java +++ b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.BiFunction; import java.util.function.Function; import jakarta.json.bind.JsonbConfig; @@ -60,32 +61,44 @@ public class ComponentMatcher { init(); } + private interface ComponentBindingsFunction> + extends BiFunction, B, ComponentBindings> {} + /** * Called during context creation, introspecting user components provided with JsonbConfig. */ void init() { + //Process serializers final JsonbSerializer[] serializers = (JsonbSerializer[]) jsonbContext.getConfig() .getProperty(JsonbConfig.SERIALIZERS).orElseGet(() -> new JsonbSerializer[] {}); - for (JsonbSerializer serializer : serializers) { - @SuppressWarnings("unchecked") - SerializerBinding serializerBinding = introspectSerializerBinding(serializer.getClass(), serializer); - addSerializer(serializerBinding.getBindingType(), serializerBinding); - } + @SuppressWarnings("unchecked") + Function, SerializerBinding> introspectSerializerFunction = (serializer) -> + introspectSerializerBinding(serializer.getClass(), serializer); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindingsFunction, SerializerBinding> createSerializerBindingFunction = (bindings, newBinding) -> + new ComponentBindings(bindings, newBinding); + addToComponentBindings(serializers, introspectSerializerFunction, ComponentBindings::getSerializerBinding, createSerializerBindingFunction); + + //Process deserializers final JsonbDeserializer[] deserializers = (JsonbDeserializer[]) jsonbContext.getConfig() .getProperty(JsonbConfig.DESERIALIZERS).orElseGet(() -> new JsonbDeserializer[] {}); - for (JsonbDeserializer deserializer : deserializers) { - @SuppressWarnings("unchecked") - DeserializerBinding deserializerBinding = introspectDeserializerBinding(deserializer.getClass(), deserializer); - addDeserializer(deserializerBinding.getBindingType(), deserializerBinding); - } - + @SuppressWarnings("unchecked") + Function, DeserializerBinding> introspectDeserializerFunction = (deserializer) -> + introspectDeserializerBinding(deserializer.getClass(), deserializer); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindingsFunction, DeserializerBinding> createDeserializerBindingFunction = (bindings, newBinding) -> + new ComponentBindings(bindings, newBinding); + addToComponentBindings(deserializers, introspectDeserializerFunction, ComponentBindings::getDeserializerBinding, createDeserializerBindingFunction); + + //Process adapters final JsonbAdapter[] adapters = (JsonbAdapter[]) jsonbContext.getConfig().getProperty(JsonbConfig.ADAPTERS) .orElseGet(() -> new JsonbAdapter[] {}); - for (JsonbAdapter adapter : adapters) { - @SuppressWarnings("unchecked") - AdapterBinding adapterBinding = introspectAdapterBinding(adapter.getClass(), adapter); - addAdapter(adapterBinding.getBindingType(), adapterBinding); - } + @SuppressWarnings("unchecked") + Function, AdapterBinding> introspectAdapterFunction = (adapter) -> introspectAdapterBinding(adapter.getClass(), adapter); + @SuppressWarnings({"unchecked", "rawtypes"}) + ComponentBindingsFunction, AdapterBinding> createAdapterBindingFunction = (bindings, newBinding) -> + new ComponentBindings(bindings, newBinding); + addToComponentBindings(adapters, introspectAdapterFunction, ComponentBindings::getAdapterBinding, createAdapterBindingFunction); } private ComponentBindings getBindingInfo(Type type) { @@ -93,40 +106,27 @@ void init() { .compute(type, (type1, bindingInfo) -> bindingInfo != null ? bindingInfo : new ComponentBindings<>(type1)); } - private void addSerializer(Type bindingType, SerializerBinding serializer) { - userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getSerializerBinding() != null) { - return bindings; - } - registerGeneric(bindingType); - @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = new ComponentBindings(bindings, serializer); - return componentBindings; - }); - } + private > void addToComponentBindings(C[] customisations, Function introspectFunction, + Function, B> getExistingBinding, + ComponentBindingsFunction createNewComponentBindings) { - private void addDeserializer(Type bindingType, DeserializerBinding deserializer) { - userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getDeserializerBinding() != null) { - return bindings; - } - registerGeneric(bindingType); - @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = new ComponentBindings(bindings, deserializer); - return componentBindings; - }); - } + Objects.requireNonNull(customisations); + Objects.requireNonNull(introspectFunction); + Objects.requireNonNull(getExistingBinding); + Objects.requireNonNull(createNewComponentBindings); - private void addAdapter(Type bindingType, AdapterBinding adapter) { - userComponents.computeIfPresent(bindingType, (type, bindings) -> { - if (bindings.getAdapterBinding() != null) { - return bindings; - } - registerGeneric(bindingType); - @SuppressWarnings({"unchecked", "rawtypes"}) - ComponentBindings componentBindings = new ComponentBindings(bindings, adapter); - return componentBindings; - }); + for (C customisation : customisations) { + B componentBinding = introspectFunction.apply(customisation); + Type bindingType = componentBinding.getBindingType(); + + userComponents.computeIfPresent(bindingType, (type, bindings) -> { + if (getExistingBinding.apply(bindings) != null) { + return bindings; + } + registerGeneric(bindingType); + return createNewComponentBindings.apply(bindings, componentBinding); + }); + } } /** @@ -233,7 +233,7 @@ private > Optional searchC return Optional.empty(); } - private > Optional getMatchingBinding(Type runtimeType, Function, T> supplier) { + private > Optional getMatchingBinding(Type runtimeType, Function, T> supplier) { ComponentBindings binding = userComponents.get(runtimeType); if (binding != null) { Optional match = getMatchingBinding(runtimeType, binding, supplier); @@ -291,6 +291,27 @@ private boolean matchTypeArguments(ParameterizedType requiredType, Parameterized return true; } + private > B introspectBinding(Class customisationClass, T customisationInstance, + Class customisationClassToFind, Function, B> getExistingBinding, + BiFunction createNewBinding) { + + Objects.requireNonNull(customisationClass); + Objects.requireNonNull(customisationClassToFind); + Objects.requireNonNull(getExistingBinding); + Objects.requireNonNull(createNewBinding); + final ParameterizedType customisationRuntimeType = ReflectionUtils.findParameterizedType(customisationClass, customisationClassToFind); + Type customisationBindingType = resolveTypeArg(customisationRuntimeType.getActualTypeArguments()[0], customisationClass); + final ComponentBindings componentBindings = getBindingInfo(customisationBindingType); + B binding = getExistingBinding.apply(componentBindings); + if (binding != null && customisationClass.equals(binding.getComponentClass())) { + return binding; + } else { + T customisation = customisationInstance != null ? customisationInstance : jsonbContext.getComponentInstanceCreator() + .getOrCreateComponent(customisationClass); + return createNewBinding.apply(customisationRuntimeType.getActualTypeArguments(), customisation); + } + } + /** * Introspect components generic information and put resolved types into metadata wrapper. * @@ -299,19 +320,8 @@ private boolean matchTypeArguments(ParameterizedType requiredType, Parameterized * @return introspected info with resolved typevar types. */ > AdapterBinding introspectAdapterBinding(Class adapterClass, A instance) { - final ParameterizedType adapterRuntimeType = ReflectionUtils.findParameterizedType(adapterClass, JsonbAdapter.class); - final Type[] adapterTypeArguments = adapterRuntimeType.getActualTypeArguments(); - Type adaptFromType = resolveTypeArg(adapterTypeArguments[0], adapterClass); - Type adaptToType = resolveTypeArg(adapterTypeArguments[1], adapterClass); - final ComponentBindings componentBindings = getBindingInfo(adaptFromType); - if (componentBindings.getAdapterBinding() != null && componentBindings.getAdapterBinding().getComponentClass() - .equals(adapterClass)) { - return componentBindings.getAdapterBinding(); - } - A newAdapter = instance != null - ? instance - : jsonbContext.getComponentInstanceCreator().getOrCreateComponent(adapterClass); - return new AdapterBinding<>(adaptFromType, adaptToType, newAdapter); + return introspectBinding(adapterClass, instance, JsonbAdapter.class, ComponentBindings::getAdapterBinding, + (typeArgs, adapter) -> new AdapterBinding<>(resolveTypeArg(typeArgs[0], adapterClass), resolveTypeArg(typeArgs[1], adapterClass), adapter)); } /** @@ -323,18 +333,8 @@ private boolean matchTypeArguments(ParameterizedType requiredType, Parameterized * @return wrapper used in property models */ > DeserializerBinding introspectDeserializerBinding(Class deserializerClass, D instance) { - final ParameterizedType deserializerRuntimeType = ReflectionUtils - .findParameterizedType(deserializerClass, JsonbDeserializer.class); - Type deserializerBindingType = resolveTypeArg(deserializerRuntimeType.getActualTypeArguments()[0], deserializerClass); - final ComponentBindings componentBindings = getBindingInfo(deserializerBindingType); - if (componentBindings.getDeserializerBinding() != null && componentBindings.getDeserializerBinding().getComponentClass() - .equals(deserializerClass)) { - return componentBindings.getDeserializerBinding(); - } else { - D deserializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() - .getOrCreateComponent(deserializerClass); - return new DeserializerBinding<>(deserializerBindingType, deserializer); - } + return introspectBinding(deserializerClass, instance, JsonbDeserializer.class, ComponentBindings::getDeserializerBinding, + (typeArgs, deserializer) -> new DeserializerBinding<>(resolveTypeArg(typeArgs[0], deserializerClass), deserializer)); } /** @@ -347,18 +347,8 @@ > DeserializerBinding introspectDeserialize */ > SerializerBinding introspectSerializerBinding(Class serializerClass, S instance) { - final ParameterizedType serializerRuntimeType = ReflectionUtils - .findParameterizedType(serializerClass, JsonbSerializer.class); - Type serBindingType = resolveTypeArg(serializerRuntimeType.getActualTypeArguments()[0], serializerClass); - final ComponentBindings componentBindings = getBindingInfo(serBindingType); - if (componentBindings.getSerializerBinding() != null && componentBindings.getSerializerBinding().getComponentClass().equals(serializerClass)) { - return componentBindings.getSerializerBinding(); - } else { - S serializer = instance != null ? instance : jsonbContext.getComponentInstanceCreator() - .getOrCreateComponent(serializerClass); - return new SerializerBinding<>(serBindingType, serializer); - } - + return introspectBinding(serializerClass, instance, JsonbSerializer.class, ComponentBindings::getSerializerBinding, + (typeArgs, serializer) -> new SerializerBinding<>(resolveTypeArg(typeArgs[0], serializerClass), serializer)); } private Type resolveTypeArg(Type adapterTypeArg, Type adapterType) { diff --git a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java index 6076be72..d1648b0c 100644 --- a/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java +++ b/src/main/java/org/eclipse/yasson/internal/VariableTypeInheritanceSearch.java @@ -94,14 +94,17 @@ private Type checkSubclassRuntimeInfo(TypeVariable typeVar) { return searchRuntimeTypeArgument(parametrizedSubclass, typeVar); } - private Type searchRuntimeTypeArgument(ParameterizedType runtimeType, TypeVariable typeVar) { + private Type searchRuntimeTypeArgument(ParameterizedType runtimeType, TypeVariable typeVar) { if (ReflectionUtils.getRawType(runtimeType) != typeVar.getGenericDeclaration()) { return null; } TypeVariable[] bounds = typeVar.getGenericDeclaration().getTypeParameters(); - for (int i = 0; i < bounds.length; i++) { - if (bounds[i].equals(typeVar)) { - Type matchedGenericType = runtimeType.getActualTypeArguments()[i]; + Type[] actualTypeArguments = runtimeType.getActualTypeArguments(); + int i = 0; + + for (TypeVariable bound : bounds) { + if (bound.equals(typeVar)) { + Type matchedGenericType = actualTypeArguments[i]; //Propagated generic types to another generic classes if (matchedGenericType instanceof TypeVariable) { return checkSubclassRuntimeInfo((TypeVariable) matchedGenericType); @@ -109,6 +112,7 @@ private Type searchRuntimeTypeArgument(ParameterizedType runtimeType, TypeVariab //found runtime matchedGenericType return matchedGenericType; } + i++; } return null; } From e72508856d25bd1aa46c6f419b005a8a9da9a0b5 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Tue, 7 Nov 2023 21:34:06 +0100 Subject: [PATCH 42/68] [#627]First part of reducing "auto-closeable resource" warning during the compilation Signed-off-by: Anton Pinsky --- src/test/java/org/eclipse/yasson/Jsonbs.java | 33 ++- .../eclipse/yasson/adapters/AdaptersTest.java | 118 +++++------ .../ImplementationClassTest.java | 8 +- .../defaultmapping/dates/DatesTest.java | 186 ++++++++--------- .../defaultmapping/generics/GenericsTest.java | 12 +- .../MapToObjectSerializerTest.java | 51 +++-- .../yasson/serializers/SerializersTest.java | 191 +++++++++--------- 7 files changed, 311 insertions(+), 288 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/Jsonbs.java b/src/test/java/org/eclipse/yasson/Jsonbs.java index 2640e7da..6945edd0 100644 --- a/src/test/java/org/eclipse/yasson/Jsonbs.java +++ b/src/test/java/org/eclipse/yasson/Jsonbs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,6 +12,9 @@ package org.eclipse.yasson; +import java.util.function.Consumer; +import java.util.function.Supplier; + import jakarta.json.bind.*; import org.eclipse.yasson.internal.*; @@ -22,4 +25,32 @@ public class Jsonbs { public static final Jsonb nullableJsonb = JsonbBuilder.create(new JsonbConfig().withNullValues(Boolean.TRUE)); public static final YassonJsonb yassonJsonb = (YassonJsonb) JsonbBuilder.create(); public static final YassonJsonb bindingYassonJsonb = (YassonJsonb) new JsonBindingProvider().create().build(); + + private static void testWithJsonb(Supplier supplier, Consumer consumer){ + try (Jsonb jsonb = supplier.get()) { + consumer.accept(jsonb); + } catch (InterruptedException ie) { + throw new RuntimeException("InterruptedException was thrown", ie); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void testWithJsonbBuilderNewBuilder(JsonbConfig jsonbConfig, Consumer consumer){ + testWithJsonb(() -> jsonbConfig == null ? JsonbBuilder.newBuilder().build() : JsonbBuilder.newBuilder().withConfig(jsonbConfig).build(), consumer); + } + + public static void testWithJsonbBuilderNewBuilder(Consumer consumer){ + testWithJsonbBuilderNewBuilder(null, consumer); + } + + public static void testWithJsonbBuilderCreate(JsonbConfig jsonbConfig, Consumer consumer){ + testWithJsonb(() -> jsonbConfig == null ? JsonbBuilder.create() : JsonbBuilder.create(jsonbConfig), consumer); + } + + public static void testWithJsonbBuilderCreate(Consumer consumer) { + testWithJsonbBuilderCreate(null, consumer); + } + + private Jsonbs() {} } diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java index 47c0fe01..0e2f88e8 100644 --- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java +++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java @@ -15,6 +15,8 @@ import static java.util.Collections.unmodifiableMap; import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderNewBuilder; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -47,8 +49,6 @@ import org.eclipse.yasson.defaultmapping.generics.model.ScalarValueWrapper; import org.junit.jupiter.api.Test; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.adapter.JsonbAdapter; @@ -65,7 +65,7 @@ public static class NonGenericPojo { } @Test - public void testBoxToCrateNoGenerics() throws Exception { + public void testBoxToCrateNoGenerics() { JsonbAdapter[] adapters = { new JsonbAdapter() { @Override @@ -85,8 +85,7 @@ public Box adaptFromJson(Crate crate) { } } }; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { - + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); Box box = new Box(); box.setBoxStrField("BoxStr"); @@ -98,11 +97,11 @@ public Box adaptFromJson(Crate crate) { AdaptedPojo result = jsonb.fromJson("{\"box\":{\"crateIntField\":10,\"crateStrField\":\"CrateStr\"}}", AdaptedPojo.class); assertEquals(Integer.valueOf(11), result.box.getBoxIntegerField()); assertEquals("boxAdaptedCrateStr", result.box.getBoxStrField()); - } + }); } @Test - public void testValueFieldAdapter() throws Exception { + public void testValueFieldAdapter() { JsonbAdapter[] adapters = { new JsonbAdapter() { @Override @@ -116,7 +115,7 @@ public Integer adaptFromJson(String s) { } } }; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); pojo.intField = 11; @@ -125,14 +124,14 @@ public Integer adaptFromJson(String s) { AdaptedPojo result = jsonb.fromJson("{\"intField\":\"10\"}", AdaptedPojo.class); assertEquals(Integer.valueOf(10), result.intField); - } + }); } @Test - public void testGenericAdapter() throws Exception { + public void testGenericAdapter() { JsonbAdapter[] adapters = {new BoxToCrateCompatibleGenericsAdapter() { }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); pojo.strField = "POJO_STRING"; @@ -158,13 +157,13 @@ public void testGenericAdapter() throws Exception { assertEquals(22, result.tBox.getX()); assertEquals("strBoxStr", result.strBox.getStrField()); assertEquals("44", result.strBox.getX()); - } + }); } @Test - public void testPropagatedTypeArgs() throws Exception { + public void testPropagatedTypeArgs() { JsonbAdapter[] adapters = {new BoxToCratePropagatedIntegerStringAdapter()}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); pojo.intBox = new GenericBox<>("INT_BOX_STR", 110); @@ -192,13 +191,13 @@ public void testPropagatedTypeArgs() throws Exception { assertEquals(88, result.tBox.getX()); assertEquals("strBoxStr", result.strBox.getStrField()); assertEquals("44", result.strBox.getX()); - } + }); } @Test - public void testStringToGenericCollectionAdapter() throws Exception { + public void testStringToGenericCollectionAdapter() { JsonbAdapter[] adapters = {new IntegerListToStringAdapter()}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo> pojo = new AdaptedPojo<>(); pojo.tVar = Arrays.asList(11, 22, 33); @@ -220,14 +219,14 @@ public void testStringToGenericCollectionAdapter() throws Exception { assertEquals(expectedIntegerList, result.integerList); assertEquals(expectedStringList, result.stringList); assertEquals(expectedTList, result.tVar); - } + }); } @Test - public void testAdaptObjectInCollection() throws Exception { + public void testAdaptObjectInCollection() { JsonbAdapter[] adapters = {new BoxToCrateCompatibleGenericsAdapter() { }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); @@ -250,11 +249,11 @@ public void testAdaptObjectInCollection() throws Exception { assertEquals("SecondCrate", result.tGenericBoxList.get(1).getStrField()); assertEquals(Integer.valueOf(11), result.tGenericBoxList.get(0).getX()); assertEquals(Integer.valueOf(22), result.tGenericBoxList.get(1).getX()); - } + }); } @Test - public void testAdaptTypeIntoCollection() throws Exception { + public void testAdaptTypeIntoCollection() { JsonbAdapter[] adapters = {new JsonbAdapter>() { @Override @@ -279,7 +278,7 @@ public String adaptFromJson(List ints) { } } }; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { String json = "{\"strValues\":[11,22,33]}"; final NonGenericPojo object = new NonGenericPojo(); @@ -287,13 +286,13 @@ public String adaptFromJson(List ints) { assertEquals(json, jsonb.toJson(object)); NonGenericPojo pojo = jsonb.fromJson(json, NonGenericPojo.class); assertEquals("11,22,33", pojo.strValues); - } + }); } @Test - public void testMarshallGenericField() throws Exception { + public void testMarshallGenericField() { JsonbAdapter[] adapters = {new BoxToCratePropagatedIntegerStringAdapter()}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo adaptedPojo = new AdaptedPojo<>(); adaptedPojo.tBox = new GenericBox<>("tGenBoxStrField", 22); @@ -308,11 +307,11 @@ public void testMarshallGenericField() throws Exception { }.getType()); assertEquals("genBoxStrField", unmarshalledAdaptedPojo.intBox.getStrField()); assertEquals(Integer.valueOf(11), unmarshalledAdaptedPojo.intBox.getX()); - } + }); } @Test - public void testTypeVariable() throws Exception { + public void testTypeVariable() { JsonbAdapter[] adapters = {new JsonbAdapter>, BigDecimal>() { @Override public BigDecimal adaptToJson(List> genericBoxes) { @@ -326,7 +325,7 @@ public List> adaptFromJson(BigDecimal bigDecimal) { return list; } }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo>> intBoxPojo = new AdaptedPojo<>(); List> intBoxList = new ArrayList<>(); @@ -340,11 +339,11 @@ public List> adaptFromJson(BigDecimal bigDecimal) { AdaptedPojo>> result = jsonb.fromJson(json, new TestTypeToken>>>() { }.getType()); assertEquals(Double.valueOf(11), result.tVar.get(0).getX()); - } + }); } @Test - public void testAdaptRoot() throws Exception { + public void testAdaptRoot() { JsonbAdapter[] adapters = {new JsonbAdapter() { @Override @@ -357,7 +356,7 @@ public Box adaptFromJson(Crate crate) { return new Box(crate.getCrateStrField(), crate.getCrateIntField()); } }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { Box pojo = new Box("BOX_STR", 101); String marshalledJson = jsonb.toJson(pojo); @@ -366,11 +365,11 @@ public Box adaptFromJson(Crate crate) { Box result = jsonb.fromJson("{\"crateIntField\":110,\"crateStrField\":\"CRATE_STR\"}", Box.class); assertEquals("CRATE_STR", result.getBoxStrField()); assertEquals(Integer.valueOf(110), result.getBoxIntegerField()); - } + }); } @Test - public void testAdaptMapString() throws Exception { + public void testAdaptMapString() { JsonbAdapter[] adapters = {new JsonbAdapter, String>() { @Override @@ -392,7 +391,7 @@ public String adaptToJson(Map obj) { return sb.toString(); } }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); pojo.stringIntegerMap = new HashMap<>(); @@ -408,11 +407,11 @@ public String adaptToJson(Map obj) { }.getType()); assertEquals(Integer.valueOf(101), result.stringIntegerMap.get("fake")); assertEquals(Integer.valueOf(101), result.tMap.get("fake")); - } + }); } @Test - public void testAdaptMapToObject() throws Exception { + public void testAdaptMapToObject() { JsonbAdapter[] adapters = {new JsonbAdapter, Crate>() { @Override public Map adaptFromJson(Crate obj) { @@ -427,7 +426,7 @@ public Crate adaptToJson(Map obj) { return new Crate(next.getKey(), Integer.parseInt(next.getValue())); } }}; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.ADAPTERS, adapters), jsonb -> { AdaptedPojo pojo = new AdaptedPojo<>(); pojo.tMap = new HashMap<>(); @@ -441,7 +440,7 @@ public Crate adaptToJson(Map obj) { AdaptedPojo result = jsonb.fromJson("{\"tMap\":{\"crateIntField\":101,\"crateStrField\":\"first\"}}", typeToken.getType()); assertEquals("11", result.tMap.get("fake")); - } + }); } @Test @@ -472,8 +471,8 @@ public void testAdaptAuthor() { } @Test - public void testAdapterReturningNull() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new ReturnNullAdapter()).withNullValues(true))) { + public void testAdapterReturningNull() { + testWithJsonbBuilderCreate(new JsonbConfig().withAdapters(new ReturnNullAdapter()).withNullValues(true), jsonb -> { ScalarValueWrapper wrapper = new ScalarValueWrapper<>(); wrapper.setValue(10); @@ -485,7 +484,7 @@ public void testAdapterReturningNull() throws Exception { ScalarValueWrapper result = jsonb.fromJson("{\"value\":null}", type); assertNull(result.getValue()); - } + }); } @Test @@ -518,19 +517,19 @@ public void testSupertypeAdapter() { } @Test - public void testSupertypeAdapter_withConfiguration() throws Exception { + public void testSupertypeAdapter_withConfiguration() { NumberAdapter.getCounter().resetCount(); - SupertypeAdapterPojo pojo = new SupertypeAdapterPojo(); - pojo.setNumberInteger(10); - pojo.setSerializableInteger(11); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withAdapters(new NumberAdapter()))) { + testWithJsonbBuilderCreate(new JsonbConfig().withAdapters(new NumberAdapter()), jsonb -> { + SupertypeAdapterPojo pojo = new SupertypeAdapterPojo(); + pojo.setNumberInteger(10); + pojo.setSerializableInteger(11); assertEquals("{\"numberInteger\":\"11\",\"serializableInteger\":12}", jsonb.toJson(pojo)); pojo = jsonb.fromJson("{\"numberInteger\":\"11\",\"serializableInteger\":12}", SupertypeAdapterPojo.class); assertEquals(Integer.valueOf(10), pojo.getNumberInteger()); assertEquals(Integer.valueOf(11), pojo.getSerializableInteger()); //assert that the adapter was reused assertEquals(1, NumberAdapter.getCounter().getCount()); - } + }); } public static class PropertyTypeMismatch { @@ -571,15 +570,15 @@ public Throwable adaptFromJson(Map obj) throws Exception { * adapter for Throwable should still be called. */ @Test - public void testOptionalAdapter() throws Exception { + public void testOptionalAdapter() { ThrowableAdapter adapter = new ThrowableAdapter(); - try (Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(new JsonbConfig().withAdapters(adapter)).build()) { + testWithJsonbBuilderNewBuilder(new JsonbConfig().withAdapters(adapter), jsonb -> { PropertyTypeMismatch obj = new PropertyTypeMismatch(); String json = jsonb.toJson(obj); assertEquals("{\"error\":{\"message\":\"foo\",\"type\":\"java.lang.RuntimeException\"}}", json); assertEquals(1, adapter.callCount, "The user-defined ThrowableAdapter should have been called"); - } + }); } public static class InstantAdapter implements JsonbAdapter { @@ -605,12 +604,10 @@ public Instant adaptFromJson(String obj) throws Exception { * serialization and deserialization. */ @Test - public void testDifferentAdapters() throws Exception { + public void testDifferentAdapters() { ThrowableAdapter throwableAdapter = new ThrowableAdapter(); InstantAdapter instantAdapter = new InstantAdapter(); - try (Jsonb jsonb = JsonbBuilder.newBuilder() - .withConfig(new JsonbConfig().withAdapters(throwableAdapter, instantAdapter)) - .build()) { + testWithJsonbBuilderNewBuilder(new JsonbConfig().withAdapters(throwableAdapter, instantAdapter), jsonb -> { String json = "{\"error\":\"CUSTOM_VALUE\"}"; PropertyTypeMismatch obj = jsonb.fromJson(json, PropertyTypeMismatch.class); @@ -621,7 +618,7 @@ public void testDifferentAdapters() throws Exception { assertEquals("{\"error\":{\"message\":\"Error at: +1000000000-12-31T23:59:59.999999999Z\",\"type\":\"java.lang.RuntimeException\"}}", afterJson); assertEquals(1, throwableAdapter.callCount); - } + }); } public static class StringAdapter implements JsonbAdapter { @@ -640,15 +637,12 @@ public String adaptFromJson(String obj) throws Exception { * Test for: issue 346 */ @Test - public void testAdaptedRootType() throws Exception { - try (Jsonb jsonb = JsonbBuilder.newBuilder() - .withConfig(new JsonbConfig().withAdapters(new StringAdapter())) - .build()) { - + public void testAdaptedRootType() { + testWithJsonbBuilderNewBuilder(new JsonbConfig().withAdapters(new StringAdapter()), jsonb -> { String original = "hello world!"; assertEquals("\"HELLO WORLD!\"", jsonb.toJson(original)); assertEquals(original, jsonb.fromJson("\"HELLO WORLD!\"", String.class)); - } + }); } @Test diff --git a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java index db53c101..423c0c4a 100644 --- a/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java +++ b/src/test/java/org/eclipse/yasson/customization/ImplementationClassTest.java @@ -20,8 +20,6 @@ import org.eclipse.yasson.customization.model.Dog; import org.eclipse.yasson.customization.model.ImplementationClassPojo; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import java.util.HashMap; @@ -44,10 +42,10 @@ public void testAnnotatedImplementation() { } @Test - public void testJsonbConfigUserImplementation() throws Exception { + public void testJsonbConfigUserImplementation() { HashMap, Class> userMapping = new HashMap<>(); userMapping.put(Animal.class, Dog.class); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty(USER_TYPE_MAPPING, userMapping))) { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(USER_TYPE_MAPPING, userMapping), jsonb -> { Animal animal = new Dog("Bulldog"); String expected = "{\"dogProperty\":\"Bulldog\"}"; String json = jsonb.toJson(animal); @@ -56,6 +54,6 @@ public void testJsonbConfigUserImplementation() throws Exception { Dog result = (Dog) jsonb.fromJson("{\"dogProperty\":\"Bulldog\"}", Animal.class); assertEquals("Bulldog", result.getDogProperty()); - } + }); } } 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 287afca8..124d196b 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, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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,6 +12,7 @@ package org.eclipse.yasson.defaultmapping.dates; +import java.io.Serial; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -46,8 +47,6 @@ import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbDateFormat; import jakarta.json.bind.annotation.JsonbTypeDeserializer; @@ -73,6 +72,7 @@ import static org.eclipse.yasson.Jsonbs.bindingJsonb; import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -85,13 +85,17 @@ public class DatesTest { private static LocalDate localDate = LocalDate.of(2018, 1, 31); - @SuppressWarnings("serial") public static class LocalDateObj implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + public LocalDate date = localDate; } - @SuppressWarnings("serial") public static class SqlDateObj implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + public java.sql.Date sqlDate = java.sql.Date.valueOf("2018-01-31"); //no way for runtime to choose java.sql.Date deserializer here without a hint @JsonbTypeDeserializer(SqlDateDeserializer.class) @@ -138,11 +142,12 @@ private void testSqlDateWithTZFormatted(TimeZone tz) { final TimeZone originalTZ = TimeZone.getDefault(); TimeZone.setDefault(tz); try { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDateFormat("yyyy-MM-dd", Locale.getDefault())); - java.sql.Date d = java.sql.Date.valueOf("1966-11-04"); - String json = jsonb.toJson(d); - assertEquals("\"1966-11-04\"", json); - assertEquals("1966-11-04", jsonb.fromJson(json, java.sql.Date.class).toString()); + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat("yyyy-MM-dd", Locale.getDefault()), (jsonb) -> { + java.sql.Date d = java.sql.Date.valueOf("1966-11-04"); + String json = jsonb.toJson(d); + assertEquals("\"1966-11-04\"", json); + assertEquals("1966-11-04", jsonb.fromJson(json, java.sql.Date.class).toString()); + }); } finally { TimeZone.setDefault(originalTZ); } @@ -158,14 +163,13 @@ public void testSqlDateTimeZonesMillis() { private void testSqlDateTimeZonesMillis(TimeZone tz, long expectedMs) { final TimeZone originalTZ = TimeZone.getDefault(); TimeZone.setDefault(tz); - JsonbConfig jsonbConfig = new JsonbConfig().withDateFormat(JsonbDateFormat.TIME_IN_MILLIS, Locale.getDefault()); - try (Jsonb jsonb = JsonbBuilder.create(jsonbConfig)) { - java.sql.Date d = java.sql.Date.valueOf("1966-11-04"); - String json = jsonb.toJson(d); - assertEquals("" + expectedMs, json); - assertEquals(d, jsonb.fromJson(json, java.sql.Date.class)); - } catch (Exception e) { - throw new RuntimeException(e); + try { + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat(JsonbDateFormat.TIME_IN_MILLIS, Locale.getDefault()), (jsonb) -> { + java.sql.Date d = java.sql.Date.valueOf("1966-11-04"); + String json = jsonb.toJson(d); + assertEquals("" + expectedMs, json); + assertEquals(d, jsonb.fromJson(json, java.sql.Date.class)); + }); } finally { TimeZone.setDefault(originalTZ); } @@ -358,19 +362,20 @@ public void testMarshalInstant() { @Test public void testDateFormattedAsMillisInString() { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig().withTimeInMillisAsAString(true)); - final Instant instant = Instant.parse("2015-03-03T23:00:00Z"); - InstantPojo instantPojo = new InstantPojo(instant); - - final String expected = "{\"defaultFormatted\":\"2015-03-03T23:00:00Z\"," + - "\"millisFormatted\":\"1425423600000\"," + - "\"instant\":\"23:00:00 | 03-03-2015\"}"; - assertEquals(expected, jsonb.toJson(instantPojo)); - - InstantPojo result = jsonb.fromJson(expected, InstantPojo.class); - assertEquals(instant, result.defaultFormatted); - assertEquals(instant, result.millisFormatted); - assertEquals(instant, result.instant); + testWithJsonbBuilderCreate(new YassonConfig().withTimeInMillisAsAString(true), jsonb -> { + final Instant instant = Instant.parse("2015-03-03T23:00:00Z"); + InstantPojo instantPojo = new InstantPojo(instant); + + final String expected = "{\"defaultFormatted\":\"2015-03-03T23:00:00Z\"," + + "\"millisFormatted\":\"1425423600000\"," + + "\"instant\":\"23:00:00 | 03-03-2015\"}"; + assertEquals(expected, jsonb.toJson(instantPojo)); + + InstantPojo result = jsonb.fromJson(expected, InstantPojo.class); + assertEquals(instant, result.defaultFormatted); + assertEquals(instant, result.millisFormatted); + assertEquals(instant, result.instant); + }); } @Test @@ -406,20 +411,20 @@ public void testLocalDate() { @Test public void testlLocalTime() { - final Jsonb jsonb = getJsonbWithMillisIgnored(); - final LocalTime localTime = LocalTime.of(22, 33); - final LocalTimePojo localTimePojo = new LocalTimePojo(localTime); - final String expected = "{\"defaultFormatted\":\"22:33:00\",\"localTime\":\"22:33:00\"}"; - assertEquals(expected, jsonb.toJson(localTimePojo)); - - final LocalTimePojo result = jsonb.fromJson(expected, LocalTimePojo.class); - assertEquals(localTime, result.defaultFormatted); - assertEquals(localTime, result.localTime); + testWithJsonbBuilderCreate(getJsonbConfigWithMillisIgnored(), jsonb -> { + final LocalTime localTime = LocalTime.of(22, 33); + final LocalTimePojo localTimePojo = new LocalTimePojo(localTime); + final String expected = "{\"defaultFormatted\":\"22:33:00\",\"localTime\":\"22:33:00\"}"; + assertEquals(expected, jsonb.toJson(localTimePojo)); + + final LocalTimePojo result = jsonb.fromJson(expected, LocalTimePojo.class); + assertEquals(localTime, result.defaultFormatted); + assertEquals(localTime, result.localTime); + }); } - private Jsonb getJsonbWithMillisIgnored() { - final JsonbConfig config = new JsonbConfig(); - config.withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { + private JsonbConfig getJsonbConfigWithMillisIgnored() { + return new JsonbConfig().withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { @Override public boolean isVisible(Field field) { return !field.getName().startsWith("millis"); @@ -430,7 +435,6 @@ public boolean isVisible(Method method) { return false; } }); - return JsonbBuilder.create(config); } @Test @@ -475,14 +479,17 @@ public void testDifferentConfigsLocalDateTime() { final String expected = "{\"value\":\"2015-02-16T13:21:00\"}"; assertEquals(expected, bindingJsonb.toJson(pojo)); - final Jsonb jsonbCustom = JsonbBuilder.create(new JsonbConfig().withDateFormat(JsonbDateFormat.TIME_IN_MILLIS, Locale.FRENCH)); - assertEquals("{\"value\":" + millis + "}", jsonbCustom.toJson(pojo)); + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat(JsonbDateFormat.TIME_IN_MILLIS, Locale.FRENCH), jsonb -> { + assertEquals("{\"value\":" + millis + "}", jsonb.toJson(pojo)); - ScalarValueWrapper result = bindingJsonb.fromJson(expected, new TestTypeToken>(){}.getType()); - assertEquals(dateTime, result.getValue()); + ScalarValueWrapper result = bindingJsonb.fromJson(expected, new TestTypeToken>() { + }.getType()); + assertEquals(dateTime, result.getValue()); - result = jsonbCustom.fromJson("{\"value\":\"" + millis + "\"}", new TestTypeToken>(){}.getType()); - assertEquals(dateTime, result.getValue()); + result = jsonb.fromJson("{\"value\":\"" + millis + "\"}", new TestTypeToken>() { + }.getType()); + assertEquals(dateTime, result.getValue()); + }); } @Test @@ -533,16 +540,17 @@ public void testMarshalOffsetDateTime() { @Test public void testMarshalOffsetTime() { - final Jsonb jsonb = getJsonbWithMillisIgnored(); - final OffsetTime dateTime = OffsetTime.of(13, 21, 15, 0, ZoneOffset.of("+05:00")); - final OffsetTimePojo pojo = new OffsetTimePojo(dateTime); + testWithJsonbBuilderCreate(getJsonbConfigWithMillisIgnored(), jsonb -> { + final OffsetTime dateTime = OffsetTime.of(13, 21, 15, 0, ZoneOffset.of("+05:00")); + final OffsetTimePojo pojo = new OffsetTimePojo(dateTime); - final String expected = "{\"defaultFormatted\":\"13:21:15+05:00\",\"offsetTime\":\"13:21:15+0500\"}"; - assertEquals(expected, jsonb.toJson(pojo)); + final String expected = "{\"defaultFormatted\":\"13:21:15+05:00\",\"offsetTime\":\"13:21:15+0500\"}"; + assertEquals(expected, jsonb.toJson(pojo)); - final OffsetTimePojo result = jsonb.fromJson(expected, OffsetTimePojo.class); - assertEquals(dateTime, result.defaultFormatted); - assertEquals(dateTime, result.offsetTime); + final OffsetTimePojo result = jsonb.fromJson(expected, OffsetTimePojo.class); + assertEquals(dateTime, result.defaultFormatted); + assertEquals(dateTime, result.offsetTime); + }); } @Test @@ -574,30 +582,32 @@ public void testClassLevel() throws ParseException { @Test public void testGlobalConfigDateFormat() { - final JsonbConfig config = new JsonbConfig(); - config.withDateFormat("X z E MMMM dd-MM-yyyy HH:mm:ss", Locale.FRENCH); - - final Jsonb jsonb = JsonbBuilder.create(config); + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat("X z E MMMM dd-MM-yyyy HH:mm:ss", Locale.FRENCH), jsonb -> { - final ZonedDateTime dateTime = ZonedDateTime.of(2015, 4, 3, 13, 21, 0, 0, ZoneId.of("Asia/Almaty")); - final String expected = "{\"value\":\"+06 ALMT ven. avril 03-04-2015 13:21:00\"}"; - assertEquals(expected, jsonb.toJson(new ScalarValueWrapper<>(dateTime))); + final ZonedDateTime dateTime = ZonedDateTime.of(2015, 4, 3, 13, 21, 0, 0, ZoneId.of("Asia/Almaty")); + final String expected = "{\"value\":\"+06 ALMT ven. avril 03-04-2015 13:21:00\"}"; + assertEquals(expected, jsonb.toJson(new ScalarValueWrapper<>(dateTime))); - final ScalarValueWrapper result = jsonb.fromJson(expected, new TestTypeToken>(){}.getType()); - assertEquals(dateTime, result.getValue()); + final ScalarValueWrapper result = jsonb.fromJson(expected, new TestTypeToken>() { + }.getType()); + assertEquals(dateTime, result.getValue()); + }); } @Test public void testDateFrenchLocale() { String format = "E DD MMM yyyy HH:mm:ss z"; Locale locale = Locale.forLanguageTag("fr-FR"); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDateFormat(format, locale)); + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat(format, locale), jsonb -> { - final ScalarValueWrapper result = jsonb.fromJson("{ \"value\" : \"lun. 93 avr. 2017 16:51:12 CEST\" }", new TestTypeToken>(){}.getType()); + final ScalarValueWrapper result = + jsonb.fromJson("{ \"value\" : \"lun. 93 avr. 2017 16:51:12 CEST\" }", new TestTypeToken>() { + }.getType()); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); - final Instant instant = Instant.from(formatter.withLocale(locale).parse("lun. 93 avr. 2017 16:51:12 CEST")); - assertEquals(instant, result.getValue().toInstant()); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + final Instant instant = Instant.from(formatter.withLocale(locale).parse("lun. 93 avr. 2017 16:51:12 CEST")); + assertEquals(instant, result.getValue().toInstant()); + }); } @Test @@ -614,28 +624,24 @@ public void testSimpleTimeZone() { @Test public void testDateInMap() { + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat("yyyy", Locale.ENGLISH), jsonb -> { + LocalDate localDate = LocalDate.of(2017, 9, 14); - JsonbConfig config = new JsonbConfig() - .withDateFormat("yyyy", Locale.ENGLISH); - - Jsonb jsonb = JsonbBuilder.create(config); - LocalDate localDate = LocalDate.of(2017, 9, 14); + DateInMapPojo pojo = new DateInMapPojo(); + pojo.setLocalDate(localDate); + pojo.setDateMap(new HashMap<>()); + pojo.getDateMap().put("first", localDate); - DateInMapPojo pojo = new DateInMapPojo(); - pojo.setLocalDate(localDate); - pojo.setDateMap(new HashMap<>()); - pojo.getDateMap().put("first", localDate); + String json = jsonb.toJson(pojo); - String json = jsonb.toJson(pojo); - - assertEquals("{\"dateMap\":{\"first\":\"2017\"},\"localDate\":\"2017\"}", json); + assertEquals("{\"dateMap\":{\"first\":\"2017\"},\"localDate\":\"2017\"}", json); + }); - config = new JsonbConfig() - .withDateFormat("dd.MM.yyyy", Locale.ENGLISH); - jsonb = JsonbBuilder.create(config); - DateInMapPojo result = jsonb.fromJson("{\"dateMap\":{\"first\":\"01.01.2017\"},\"localDate\":\"01.01.2017\"}", DateInMapPojo.class); - assertEquals(LocalDate.of(2017,1,1), result.localDate); - assertEquals(LocalDate.of(2017,1,1), result.dateMap.get("first")); + testWithJsonbBuilderCreate(new JsonbConfig().withDateFormat("dd.MM.yyyy", Locale.ENGLISH), jsonb -> { + DateInMapPojo result = jsonb.fromJson("{\"dateMap\":{\"first\":\"01.01.2017\"},\"localDate\":\"01.01.2017\"}", DateInMapPojo.class); + assertEquals(LocalDate.of(2017, 1, 1), result.localDate); + assertEquals(LocalDate.of(2017, 1, 1), result.dateMap.get("first")); + }); } @Test diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 3f6cb1d2..408540cf 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -13,10 +13,12 @@ package org.eclipse.yasson.defaultmapping.generics; import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.Serial; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -57,8 +59,6 @@ import org.eclipse.yasson.serializers.model.Crate; import org.junit.jupiter.api.Test; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; /** @@ -276,7 +276,7 @@ public void testFunctional() { } @Test - public void testBoundedGenerics() throws Exception { + public void testBoundedGenerics() { //bounded generics BoundedGenericClass, Circle> boundedGenericClass = new BoundedGenericClass<>(); List shapeList = new ArrayList<>(); @@ -299,7 +299,7 @@ public void testBoundedGenerics() throws Exception { String expected = "{\"boundedSet\":[3],\"lowerBoundedList\":[{\"radius\":2.5}],\"upperBoundedList\":[{\"radius\":3.5,\"color\":\"0,0,255\"}]}"; assertEquals(expected, defaultJsonb.toJson(boundedGenericClass)); - try (Jsonb localJsonb = JsonbBuilder.create(new JsonbConfig())) { + testWithJsonbBuilderCreate(new JsonbConfig(), localJsonb -> { BoundedGenericClass, Circle> result = localJsonb.fromJson(expected, new TestTypeToken, Circle>>() { }.getType()); @@ -312,7 +312,7 @@ public void testBoundedGenerics() throws Exception { assertEquals(Double.valueOf(3.5), result.upperBoundedList.get(0).getRadius()); //If it was possible we could assert following, but it is not. //assertEquals("0,0,255", ((ColoredCircle) result.upperBoundedList.get(0)).color); - } + }); } @Test @@ -466,6 +466,8 @@ public interface FunctionalInterface { } public static class ExtendsBigDecimal extends BigDecimal { + @Serial + private static final long serialVersionUID = 1L; public ExtendsBigDecimal(String val) { super(val); diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java index 7542f597..b2c6e5c0 100644 --- a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java @@ -12,13 +12,12 @@ package org.eclipse.yasson.serializers; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import org.junit.jupiter.api.Test; import static org.eclipse.yasson.Assertions.shouldFail; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -104,24 +103,24 @@ public static class MapObjectBooleanString extends MapObject {} * Test serialization of Map with Number keys and String values. */ @Test - public void testSerializeEnumMapToObject() throws Exception { + public void testSerializeEnumMapToObject() { Map map = new EnumMap<>(TestEnum.class); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true))) { + testWithJsonbBuilderCreate(new JsonbConfig().withFormatting(true), jsonb -> { map.put(TestEnum.ONE, "value1"); map.put(TestEnum.TWO, "value2"); String json = jsonb.toJson(map); for (TestEnum e : TestEnum.values()) { assertTrue(json.contains(e.name()), "Enumeration not well serialized"); } - } + }); } /** * Test for Integer/String map. */ @Test - public void testIntegerString() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { + public void testIntegerString() { + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { MapObjectIntegerString mapObject = new MapObjectIntegerString(); mapObject.getValues().put(12, "twelve"); @@ -131,15 +130,15 @@ public void testIntegerString() throws Exception { String json = jsonb.toJson(mapObject); MapObjectIntegerString resObject = jsonb.fromJson(json, MapObjectIntegerString.class); assertEquals(mapObject, resObject); - } + }); } /** * Test for BigInteger/String map. */ @Test - public void testBigIntegerString() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { + public void testBigIntegerString() { + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { MapObjectBigIntegerString mapObject = new MapObjectBigIntegerString(); mapObject.getValues().put(new BigInteger("12"), "twelve"); @@ -149,15 +148,15 @@ public void testBigIntegerString() throws Exception { String json = jsonb.toJson(mapObject); MapObjectBigIntegerString resObject = jsonb.fromJson(json, MapObjectBigIntegerString.class); assertEquals(mapObject, resObject); - } + }); } /** * Test for Enum/String map. */ @Test - public void testEnumString() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testEnumString() { + testWithJsonbBuilderCreate(jsonb -> { MapObjectEnumString mapObject = new MapObjectEnumString(); mapObject.getValues().put(TestEnum.ONE, "one"); @@ -166,15 +165,15 @@ public void testEnumString() throws Exception { String json = jsonb.toJson(mapObject); MapObjectEnumString resObject = jsonb.fromJson(json, MapObjectEnumString.class); assertEquals(mapObject, resObject); - } + }); } /** * Test for String/String map. */ @Test - public void testStringString() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().setProperty("lala", "lala"))) { + public void testStringString() { + testWithJsonbBuilderCreate(new JsonbConfig().setProperty("lala", "lala"), jsonb -> { MapObjectStringString mapObject = new MapObjectStringString(); mapObject.getValues().put("one", "one"); @@ -183,15 +182,15 @@ public void testStringString() throws Exception { String json = jsonb.toJson(mapObject); MapObjectStringString resObject = jsonb.fromJson(json, MapObjectStringString.class); assertEquals(mapObject, resObject); - } + }); } /** * Test for a non parametrized map that should use Strings as keys. */ @Test - public void testNotParametrizedMap() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig())) { + public void testNotParametrizedMap() { + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { Map mapObject = new HashMap<>(); mapObject.put(12, "twelve"); @@ -202,7 +201,7 @@ public void testNotParametrizedMap() throws Exception { Map resObject = jsonb.fromJson(json, Map.class); assertEquals(3, resObject.size()); assertTrue(resObject.keySet().iterator().next() instanceof String); - } + }); } /** @@ -211,15 +210,15 @@ public void testNotParametrizedMap() throws Exception { * But the json string should be deserialized in the same way. */ @Test - public void testBooleanStringMapToObjectSerializer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testBooleanStringMapToObjectSerializer() { + testWithJsonbBuilderCreate(jsonb -> { String json = "{\"values\":{\"true\":\"TRUE\",\"false\":\"FALSE\"}}"; MapObjectBooleanString resObject = jsonb.fromJson(json, MapObjectBooleanString.class); assertEquals(2, resObject.getValues().size()); assertEquals("TRUE", resObject.getValues().get(true)); assertEquals("FALSE", resObject.getValues().get(false)); - } + }); } /** @@ -227,11 +226,11 @@ public void testBooleanStringMapToObjectSerializer() throws Exception { * JsonbException is expected. */ @Test - public void testIncorrectTypeMapToObjectSerializer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create()) { + public void testIncorrectTypeMapToObjectSerializer() { + testWithJsonbBuilderCreate(jsonb -> { String json = "{\"values\":{\"1\":\"OK\",\"error\":\"KO\"}}"; shouldFail(() -> jsonb.fromJson(json, MapObjectIntegerString.class)); - } + }); } } diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index db423408..b384cb42 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -31,8 +31,6 @@ import jakarta.json.Json; import jakarta.json.JsonObject; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.JsonbException; import jakarta.json.bind.config.PropertyOrderStrategy; @@ -79,7 +77,9 @@ import static org.eclipse.yasson.Jsonbs.defaultJsonb; import static org.eclipse.yasson.Jsonbs.nullableJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -174,9 +174,8 @@ public void testClassLevelAnnotationOnGenericRoot() { * Tests JSONB deserialization of arbitrary type invoked from a Deserializer. */ @Test - public void testDeserializerDeserializationByType() throws Exception { - JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testDeserializerDeserializationByType() { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new CrateDeserializer()), jsonb -> { Box box = createPojoWithDates(); @@ -194,16 +193,15 @@ public void testDeserializerDeserializationByType() throws Exception { //set by deserializer statically assertEquals(new BigDecimal("123"), result.crate.crateBigDec); assertEquals("abc", result.crate.crateStr); - } + }); } /** * Tests JSONB serialization of arbitrary type invoked from a Serializer. */ @Test - public void testSerializerSerializationOfType() throws Exception { - JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testSerializerSerializationOfType() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new CrateSerializer()), jsonb -> { String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; Box pojo = createPojo(); @@ -216,13 +214,12 @@ public void testSerializerSerializationOfType() throws Exception { assertNull(result.crate.crateStr); assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - } + }); } @Test - public void testSerializerSerializationOfTypeWithExplicitType() throws Exception { - JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testSerializerSerializationOfTypeWithExplicitType() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new CrateSerializer()), jsonb -> { String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; Box pojo = createPojo(); @@ -235,16 +232,15 @@ public void testSerializerSerializationOfTypeWithExplicitType() throws Exception assertNull(result.crate.crateStr); assertEquals(pojo.crate.crateInner.crateInnerStr, result.crate.crateInner.crateInnerStr); assertEquals(pojo.crate.crateInner.crateInnerBigDec, result.crate.crateInner.crateInnerBigDec); - } + }); } /** * Tests jsonb type conversion, including property customization. */ @Test - public void testDeserializersUsingConversion() throws Exception { - JsonbConfig config = new JsonbConfig().withDeserializers(new CrateDeserializerWithConversion()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testDeserializersUsingConversion() { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new CrateDeserializerWithConversion()), jsonb -> { String json = "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; @@ -253,13 +249,12 @@ public void testDeserializersUsingConversion() throws Exception { assertEquals(expected, result.crate.date); assertEquals("Box string", result.boxStr); assertEquals("Second box string", result.secondBoxStr); - } + }); } @Test - public void testCrateJsonObjectDeserializer() throws Exception { - JsonbConfig config = new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testCrateJsonObjectDeserializer() { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()), jsonb -> { String expected = "{\"boxStr\":\"Box string\",\"crate\":{\"date-converted\":\"2015-05-14T11:10:01\",\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crateInnerStr\":\"Single inner\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321},\"secondBoxStr\":\"Second box string\"}"; Box result = jsonb.fromJson(expected, Box.class); @@ -267,7 +262,7 @@ public void testCrateJsonObjectDeserializer() throws Exception { assertEquals("REPLACED crate str", result.crate.crateStr); assertEquals("Single inner", result.crate.crateInner.crateInnerStr); assertEquals(BigDecimal.TEN, result.crate.crateInner.crateInnerBigDec); - } + }); } private static Date getExpectedDate() { @@ -275,14 +270,13 @@ private static Date getExpectedDate() { } @Test - public void testSerializationUsingConversion() throws Exception { - JsonbConfig config = new JsonbConfig().withSerializers(new CrateSerializerWithConversion()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testSerializationUsingConversion() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new CrateSerializerWithConversion()), jsonb -> { String json = "{\"boxStr\":\"Box string\",\"crate\":{\"crateStr\":\"REPLACED crate str\",\"crateInner\":{\"crateInnerBigDec\":10,\"crate_inner_str\":\"Single inner\",\"date\":\"14.05.2015 || 11:10:01\"},\"crateInnerList\":[{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 0\"},{\"crateInnerBigDec\":10,\"crate_inner_str\":\"List inner 1\"}],\"crateBigDec\":54321,\"date-converted\":\"2015-05-14T11:10:01Z[UTC]\"},\"secondBoxStr\":\"Second box string\"}"; assertEquals(json, jsonb.toJson(createPojoWithDates())); - } + }); } @Test @@ -318,9 +312,8 @@ public void testAnnotations() { } @Test - public void testAnnotationsOverride() throws Exception { - JsonbConfig config = new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()).withSerializers(new CrateSerializer()); - try (Jsonb jsonb = JsonbBuilder.create(config)) { + public void testAnnotationsOverride() { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new CrateJsonObjectDeserializer()).withSerializers(new CrateSerializer()), jsonb -> { BoxWithAnnotations box = new BoxWithAnnotations(); box.boxStr = "Box string"; @@ -351,7 +344,7 @@ public void testAnnotationsOverride() throws Exception { //set by deserializer statically assertEquals(new BigDecimal("123"), result.crate.crateBigDec); assertEquals("abc", result.crate.crateStr); - } + }); } @Test @@ -391,8 +384,8 @@ public void testContainerSerializer() { * Tests avoiding StackOverflowError. */ @Test - public void testRecursiveSerializer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new RecursiveSerializer()).withDeserializers(new RecursiveDeserializer()))) { + public void testRecursiveSerializer() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new RecursiveSerializer()).withDeserializers(new RecursiveDeserializer()), jsonb -> { Box box = new Box(); box.boxStr = "Box to serialize"; @@ -407,7 +400,7 @@ public void testRecursiveSerializer() throws Exception { fail(); } catch (StackOverflowError ignored) { } - } + }); } @Test @@ -424,12 +417,12 @@ public void testAuthor() { } @Test - public void testSupertypeSerializer_withConfiguration() throws Exception { + public void testSupertypeSerializer_withConfiguration() { NumberSerializer.getCounter().resetCount(); NumberDeserializer.getCounter().resetCount(); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() + testWithJsonbBuilderCreate(new JsonbConfig() .withSerializers(new NumberSerializer()) - .withDeserializers(new NumberDeserializer()))) { + .withDeserializers(new NumberDeserializer()), jsonb -> { SupertypeSerializerPojo pojo = new SupertypeSerializerPojo(); pojo.setNumberInteger(10); pojo.setAnotherNumberInteger(11); @@ -441,7 +434,7 @@ public void testSupertypeSerializer_withConfiguration() throws Exception { //assert that deserializer and serializer were reused assertEquals(1, NumberSerializer.getCounter().getCount()); assertEquals(1, NumberDeserializer.getCounter().getCount()); - } + }); } @Test @@ -462,58 +455,58 @@ public void testSupertypeSerializer() { } @Test - public void testObjectDeserializerWithLexOrderStrategy() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))) { + public void testObjectDeserializerWithLexOrderStrategy() { + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { Object pojo = jsonb.fromJson("{\"first\":{},\"third\":{},\"second\":{\"second\":2,\"first\":1}}", Object.class); assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap"); @SuppressWarnings("unchecked") SortedMap pojoAsMap = (SortedMap) pojo; assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); assertEquals("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", jsonb.toJson(pojo)); - } + }); } @Test - public void testObjectDeserializerWithReverseOrderStrategy() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE))) { + public void testObjectDeserializerWithReverseOrderStrategy() { + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE), jsonb -> { Object pojo = jsonb.fromJson("{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}", Object.class); assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap"); @SuppressWarnings("unchecked") SortedMap pojoAsMap = (SortedMap) pojo; assertTrue(pojoAsMap.get("second") instanceof TreeMap, "Pojo inner object is not of type TreeMap"); assertEquals("{\"third\":{},\"second\":{\"second\":2,\"first\":1},\"first\":{}}", jsonb.toJson(pojo)); - } + }); } @Test - public void testObjectDeserializerWithAnyOrNoneOrderStrategy() throws Exception { + public void testObjectDeserializerWithAnyOrNoneOrderStrategy() { String json = "{\"first\":{},\"second\":{\"first\":1,\"second\":2},\"third\":{}}"; // ANY - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY))) { + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY), jsonb -> { Object pojo = jsonb.fromJson(json, Object.class); assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with \"ANY\" strategy"); // none pojo = defaultJsonb.fromJson(json, Object.class); assertTrue(pojo instanceof HashMap, "Pojo is not of type HashMap with no strategy"); - } + }); } @Test - public void testSortedMapDeserializer() throws Exception { + public void testSortedMapDeserializer() { String json = "{\"first\":1,\"third\":3,\"second\":2}"; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY))) { + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.ANY), jsonb -> { SortedMap pojo = jsonb.fromJson(json, SortedMap.class); assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with \"ANY\" strategy"); - } + }); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))){ + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { SortedMap pojo = jsonb.fromJson(json, SortedMap.class); assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); assertEquals("{\"first\":1,\"second\":2,\"third\":3}", jsonb.toJson(pojo)); - } + }); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE))) { + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE), jsonb -> { SortedMap pojo = jsonb.fromJson(json, SortedMap.class); assertTrue(pojo instanceof ReverseTreeMap, "Pojo is not of type ReverseTreeMap with no strategy"); assertEquals("{\"third\":3,\"second\":2,\"first\":1}", jsonb.toJson(pojo)); @@ -521,7 +514,7 @@ public void testSortedMapDeserializer() throws Exception { pojo = defaultJsonb.fromJson(json, SortedMap.class); assertTrue(pojo instanceof TreeMap, "Pojo is not of type TreeMap with no strategy"); assertEquals("{\"first\":1,\"second\":2,\"third\":3}", defaultJsonb.toJson(pojo)); - } + }); } @Test @@ -548,14 +541,14 @@ public void testSerializeMapWithNulls() { } @Test - public void testSerializeMapWithNullsForceArraySerializer() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new YassonConfig() + public void testSerializeMapWithNullsForceArraySerializer() { + testWithJsonbBuilderCreate(new YassonConfig() .withForceMapArraySerializerForNullKeys(Boolean.TRUE) - .withNullValues(Boolean.TRUE))) { + .withNullValues(Boolean.TRUE), jsonb -> { assertEquals("[{\"key\":null,\"value\":null}]", jsonb.toJson(singletonMap(null, null))); assertEquals("{\"key\":null}", jsonb.toJson(singletonMap("key", null))); assertEquals("[{\"key\":null,\"value\":\"value\"}]", jsonb.toJson(singletonMap(null, "value"))); - } + }); } /** @@ -576,13 +569,13 @@ public void testSerializeMapToJsonObject() { } @Test - public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() throws Exception { + public void testDeserializeArrayWithAdvancingParserAfterObjectEnd() { String json = "[{\"stringProperty\":\"Property 1 value\"},{\"stringProperty\":\"Property 2 value\"}]"; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoDeserializer()))) { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new SimplePojoDeserializer()), jsonb -> { SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); assertEquals(2, result.length); assertEquals("Property 1 value", result[0].getStringProperty()); - } + }); } public static class SimplePojoDeserializer implements JsonbDeserializer { @@ -597,13 +590,13 @@ public SimplePojo deserialize(JsonParser parser, DeserializationContext ctx, Typ } @Test - public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() throws Exception { + public void testDeserializeArrayWithAdvancingParserAfterObjectEndUsingValue() { String json = "[{\"stringProperty\":\"Property 1 value\"},{\"stringProperty\":\"Property 2 value\"}]"; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(new SimplePojoValueDeserializer()))) { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new SimplePojoValueDeserializer()), jsonb -> { SimplePojo[] result = jsonb.fromJson(json, SimplePojo[].class); assertEquals(2, result.length); assertEquals("Property 1 value", result[0].getStringProperty()); - } + }); } public static class SimplePojoValueDeserializer implements JsonbDeserializer { @@ -685,15 +678,15 @@ public void serialize(Baz obj, JsonGenerator generator, SerializationContext ctx * specific type in the class hierarchy. */ @Test - public void testSerializerMatching() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() - .withSerializers(new FooSerializer(), new BazSerializer()))) { + public void testSerializerMatching() { + testWithJsonbBuilderCreate(new JsonbConfig() + .withSerializers(new FooSerializer(), new BazSerializer()), jsonb -> { 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 interface One { } @@ -723,21 +716,21 @@ public void serialize(Three obj, JsonGenerator generator, SerializationContext c } @Test - public void testSerializerMatchingInterfaces01() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() - .withSerializers(new OneSerializer(), new TwoSerializer(), new ThreeSerializer()))) { + public void testSerializerMatchingInterfaces01() { + testWithJsonbBuilderCreate(new JsonbConfig() + .withSerializers(new OneSerializer(), new TwoSerializer(), new ThreeSerializer()), jsonb -> { assertEquals("\"one\"", jsonb.toJson(new OneTwo())); assertEquals("\"one\"", jsonb.toJson(new OneTwoThree())); - } + }); } @Test - public void testSerializerMatchingInterfaces02() throws Exception { - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() - .withSerializers(new ThreeSerializer(), new TwoSerializer()))) { + public void testSerializerMatchingInterfaces02() { + testWithJsonbBuilderCreate(new JsonbConfig() + .withSerializers(new ThreeSerializer(), new TwoSerializer()), jsonb -> { assertEquals("\"two\"", jsonb.toJson(new OneTwo())); assertEquals("\"two\"", jsonb.toJson(new OneTwoThree())); - } + }); } public static class GenericBean { @@ -752,6 +745,10 @@ public boolean equals(Object obj) { return Boolean.FALSE; } + @Override + public int hashCode() { + return Objects.hash(value); + } } public static class GenericBeanSerializer implements JsonbSerializer { @@ -782,12 +779,12 @@ public GenericBean deserialize(JsonParser parser, DeserializationContext ctx, Ty } @Test - public void testCustomDeserializerWithParameterizedType() throws Exception { + public void testCustomDeserializerWithParameterizedType() { GenericBeanSerializer genericBeanSerializer = new GenericBeanSerializer(); GenericBeanDeserializer genericBeanDeserializer = new GenericBeanDeserializer(); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withDeserializers(genericBeanDeserializer).withSerializers(genericBeanSerializer))) { + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(genericBeanDeserializer).withSerializers(genericBeanSerializer), jsonb -> { GenericBean bean1 = new GenericBean<>(); bean1.value = "test1"; @@ -825,74 +822,70 @@ public Type getOwnerType() { assertEquals(asList, fromJson); assertTrue(genericBeanDeserializer.called); - } + }); } @Test - public void testImplicitJsonbSerializers() throws Exception { + public void testImplicitJsonbSerializers() { String expected = "{\"value\":\"123\"}"; Box box = new Box(); box.boxStr = "Box"; - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ExplicitJsonbSerializer()))) { - assertEquals(expected, jsonb.toJson(box)); - } + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new ExplicitJsonbSerializer()), jsonb -> assertEquals(expected, jsonb.toJson(box))); - try (Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withSerializers(new ImplicitJsonbSerializer()))) { - assertEquals(expected, jsonb.toJson(box)); - } + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new ImplicitJsonbSerializer()), jsonb -> assertEquals(expected, jsonb.toJson(box))); } @Test - public void testBoxToArrayChained() throws Exception { - JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED); - try (Jsonb jsonb = JsonbBuilder.create(cfg)) { + public void testBoxToArrayChained() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED), jsonb -> { Box box = new Box(); box.boxStr = "str1"; box.secondBoxStr = "str2"; String expected = "[\"str1\",\"str2\"]"; assertThat(jsonb.toJson(box), is(expected)); - } + }); } @Test - public void testBoxToArray() throws Exception { - JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER); - try (Jsonb jsonb = JsonbBuilder.create(cfg)) { + public void testBoxToArray() { + testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER), jsonb -> { Box box = new Box(); box.boxStr = "str1"; box.secondBoxStr = "str2"; String expected = "[\"str1\",\"str2\"]"; assertThat(jsonb.toJson(box), is(expected)); - } + }); } @Test public void testBoxToArrayChainedWithLambda() { - JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED_AS_LAMBDA); - assertThrows(JsonbException.class, () -> {try (Jsonb jsonb = JsonbBuilder.create(cfg)){ + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_CHAINED_AS_LAMBDA), jsonb -> { Box box = new Box(); box.boxStr = "str1"; box.secondBoxStr = "str2"; String expected = "[\"str1\",\"str2\"]"; assertThat(jsonb.toJson(box), is(expected)); - }}); + })); + + assertInstanceOf(JsonbException.class, runtimeException.getCause()); } @Test public void testBoxToArrayWithLambda() { - JsonbConfig cfg = new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_AS_LAMBDA); - assertThrows(JsonbException.class, () -> {try (Jsonb jsonb = JsonbBuilder.create(cfg)){ + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(BOX_ARRAY_SERIALIZER_AS_LAMBDA), jsonb -> { Box box = new Box(); box.boxStr = "str1"; box.secondBoxStr = "str2"; String expected = "[\"str1\",\"str2\"]"; assertThat(jsonb.toJson(box), is(expected)); - }}); + })); + + assertInstanceOf(JsonbException.class, runtimeException.getCause()); } @Test From d5daea705611789fc023e345e968fb9b08fd024a Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Tue, 7 Nov 2023 21:39:54 +0100 Subject: [PATCH 43/68] [#627]@Serial only available from Java 14 on Signed-off-by: Anton Pinsky --- .../org/eclipse/yasson/defaultmapping/dates/DatesTest.java | 3 --- .../eclipse/yasson/defaultmapping/generics/GenericsTest.java | 2 -- 2 files changed, 5 deletions(-) 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 124d196b..67a71229 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/dates/DatesTest.java @@ -12,7 +12,6 @@ package org.eclipse.yasson.defaultmapping.dates; -import java.io.Serial; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -86,14 +85,12 @@ public class DatesTest { private static LocalDate localDate = LocalDate.of(2018, 1, 31); public static class LocalDateObj implements Serializable { - @Serial private static final long serialVersionUID = 1L; public LocalDate date = localDate; } public static class SqlDateObj implements Serializable { - @Serial private static final long serialVersionUID = 1L; public java.sql.Date sqlDate = java.sql.Date.valueOf("2018-01-31"); diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java index 408540cf..f1c25415 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/generics/GenericsTest.java @@ -18,7 +18,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.Serial; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -466,7 +465,6 @@ public interface FunctionalInterface { } public static class ExtendsBigDecimal extends BigDecimal { - @Serial private static final long serialVersionUID = 1L; public ExtendsBigDecimal(String val) { From 0d8db8e3fa6c111302d8ec1a2f22faea0d90c578 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 00:56:58 +0100 Subject: [PATCH 44/68] [#627]Second part of reducing "auto-closeable resource" warning during the compilation Signed-off-by: Anton Pinsky --- .../BeanManagerInstanceCreator.java | 13 +- .../yasson/FieldAccessStrategyTest.java | 71 +-- .../java/org/eclipse/yasson/Issue454Test.java | 54 +-- .../java/org/eclipse/yasson/Issue456Test.java | 8 +- .../yasson/customization/EncodingTest.java | 56 ++- .../customization/JsonbNillableTest.java | 14 +- .../customization/JsonbPropertyTest.java | 83 ++-- .../JsonbPropertyVisibilityStrategyTest.java | 64 ++- .../customization/PropertyOrderTest.java | 83 ++-- .../YassonSpecificConfigTests.java | 20 +- .../MultiplePolymorphicInfoTest.java | 15 +- .../yasson/defaultmapping/IJsonTest.java | 8 +- .../defaultmapping/SecurityManagerTest.java | 30 +- .../defaultmapping/jsonp/JsonpTest.java | 65 ++- .../UnmarshallingUnsupportedTypesTest.java | 22 +- .../documented/DocumentationExampleTest.java | 86 ++-- .../yasson/internal/JsonBindingTest.java | 33 +- .../yasson/internal/cdi/CdiInjectionTest.java | 38 +- .../naming/PropertyNamingStrategyTest.java | 97 ++-- .../JsonGeneratorToStructureAdapterTest.java | 23 +- .../JsonStructureToParserAdapterTest.java | 9 +- .../MapToEntriesArraySerializerTest.java | 424 +++++++++--------- 22 files changed, 689 insertions(+), 627 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java index 0e2f60b2..308f7def 100644 --- a/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/components/BeanManagerInstanceCreator.java @@ -83,9 +83,16 @@ public void close() throws IOException { } private void cleanupBean(CDIManagedBean bean) { - bean.getInjectionTarget().preDestroy(bean.getInstance()); - bean.getInjectionTarget().dispose(bean.getInstance()); - bean.getCreationalContext().release(); + InjectionTarget injectionTarget = bean.getInjectionTarget(); + if (injectionTarget != null) { + injectionTarget.preDestroy(bean.getInstance()); + injectionTarget.dispose(bean.getInstance()); + } + + CreationalContext creationalContext = bean.getCreationalContext(); + if (creationalContext != null) { + creationalContext.release(); + } } /** diff --git a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java index 1f04f149..725bd60c 100644 --- a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java +++ b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -11,10 +11,10 @@ */package org.eclipse.yasson; import org.junit.jupiter.api.*; + + import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.*; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbTransient; import jakarta.json.bind.config.PropertyVisibilityStrategy; @@ -55,32 +55,34 @@ public static class PublicFields { @Test public void testPrivateFields() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyVisibilityStrategy(new FieldAccessStrategy())); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyVisibilityStrategy(new FieldAccessStrategy()), jsonb -> { - PrivateFields pojo = new PrivateFields("pojo string"); + PrivateFields pojo = new PrivateFields("pojo string"); - String expected = "{\"strField\":\"pojo string\"}"; + String expected = "{\"strField\":\"pojo string\"}"; - assertEquals(expected, jsonb.toJson(pojo)); - PrivateFields result = jsonb.fromJson(expected, PrivateFields.class); - assertEquals(false, result.getterCalled); - assertEquals(false, result.setterCalled); - assertEquals("pojo string", result.strField); + assertEquals(expected, jsonb.toJson(pojo)); + PrivateFields result = jsonb.fromJson(expected, PrivateFields.class); + assertFalse(result.getterCalled); + assertFalse(result.setterCalled); + assertEquals("pojo string", result.strField); + }); } @Test public void testHidePublicFields() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyVisibilityStrategy(new NoAccessStrategy())); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyVisibilityStrategy(new NoAccessStrategy()), jsonb -> { - PublicFields pojo = new PublicFields(); - pojo.strField = "string field"; + PublicFields pojo = new PublicFields(); + pojo.strField = "string field"; - String expected = "{}"; + String expected = "{}"; - assertEquals(expected, jsonb.toJson(pojo)); - PublicFields result = jsonb.fromJson("{\"strField\":\"pojo string\"}", PublicFields.class); - assertEquals(null, result.strField); + assertEquals(expected, jsonb.toJson(pojo)); + PublicFields result = jsonb.fromJson("{\"strField\":\"pojo string\"}", PublicFields.class); + assertNull(result.strField); + }); } /** @@ -88,23 +90,25 @@ public void testHidePublicFields() { */ @Test public void testCustomVisibityStrategy() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyVisibilityStrategy(new CustomVisibilityStrategy())); - - String json = "{\"floatInstance\":10.0,\"stringInstance\":\"Test String\"}"; - SimpleContainer simpleContainer = new SimpleContainer(); - simpleContainer.setStringInstance("Test String"); - simpleContainer.setIntegerInstance(10); - simpleContainer.setFloatInstance(10.0f); - assertEquals(json, jsonb.toJson(simpleContainer)); - - - SimpleContainer result = jsonb.fromJson("{ \"stringInstance\" : \"Test String\", \"floatInstance\" : 1.0, \"integerInstance\" : 1 }", SimpleContainer.class); - assertEquals("Test String", result.stringInstance); - assertNull(result.integerInstance); - assertNull(result.floatInstance); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyVisibilityStrategy(new CustomVisibilityStrategy()), jsonb -> { + + String json = "{\"floatInstance\":10.0,\"stringInstance\":\"Test String\"}"; + SimpleContainer simpleContainer = new SimpleContainer(); + simpleContainer.setStringInstance("Test String"); + simpleContainer.setIntegerInstance(10); + simpleContainer.setFloatInstance(10.0f); + assertEquals(json, jsonb.toJson(simpleContainer)); + + + SimpleContainer result = jsonb.fromJson("{ \"stringInstance\" : \"Test String\", \"floatInstance\" : 1.0, \"integerInstance\" : 1 }", + SimpleContainer.class); + assertEquals("Test String", result.stringInstance); + assertNull(result.integerInstance); + assertNull(result.floatInstance); + }); } - public class CustomVisibilityStrategy implements PropertyVisibilityStrategy { + public static class CustomVisibilityStrategy implements PropertyVisibilityStrategy { @Override public boolean isVisible(Field field) { return field.getName().equals("stringInstance"); @@ -115,6 +119,7 @@ public boolean isVisible(Method method) { return method.getName().equals("getFloatInstance"); } } + public static class SimpleContainer { private String stringInstance; private Integer integerInstance; diff --git a/src/test/java/org/eclipse/yasson/Issue454Test.java b/src/test/java/org/eclipse/yasson/Issue454Test.java index fa2363a5..c518d999 100644 --- a/src/test/java/org/eclipse/yasson/Issue454Test.java +++ b/src/test/java/org/eclipse/yasson/Issue454Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023 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,12 +12,11 @@ package org.eclipse.yasson; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbTransient; @@ -26,29 +25,34 @@ public class Issue454Test { @Test public void test() { final String EXPECTED = "{\"field2\":\"bbb\"}"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - assertEquals(EXPECTED, jsonb.toJson(new TheInterface() { + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + assertEquals(EXPECTED, jsonb.toJson(new TheInterface() { - @Override - public String getField1() { - return "aaa"; - } + @Override + public String getField1() { + return "aaa"; + } - @Override - public String getField2() { - return "bbb"; - }})); - assertEquals(EXPECTED, jsonb.toJson(new TheClass() { - @Override - public String getField1() { - return "aaa"; - } - @Override - public String getField2() { - return "bbb"; - }})); - assertEquals(EXPECTED, jsonb.toJson(new TheClass2())); - assertEquals(EXPECTED, jsonb.toJson(new TheClass2() {})); + @Override + public String getField2() { + return "bbb"; + } + })); + assertEquals(EXPECTED, jsonb.toJson(new TheClass() { + @Override + public String getField1() { + return "aaa"; + } + + @Override + public String getField2() { + return "bbb"; + } + })); + assertEquals(EXPECTED, jsonb.toJson(new TheClass2())); + assertEquals(EXPECTED, jsonb.toJson(new TheClass2() { + })); + }); } public static abstract class TheClass { @@ -69,7 +73,7 @@ public String getField2() { } } - public static interface TheInterface { + public interface TheInterface { @JsonbTransient String getField1(); diff --git a/src/test/java/org/eclipse/yasson/Issue456Test.java b/src/test/java/org/eclipse/yasson/Issue456Test.java index 4bb4f89e..52b603c0 100644 --- a/src/test/java/org/eclipse/yasson/Issue456Test.java +++ b/src/test/java/org/eclipse/yasson/Issue456Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023 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,11 @@ package org.eclipse.yasson; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; import static org.junit.jupiter.api.Assertions.fail; import org.junit.jupiter.api.Test; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbException; public class Issue456Test { @@ -24,7 +24,7 @@ public class Issue456Test { @Test public void dontInvokeToString() { try { - JsonbBuilder.create().toJson(new Example()); + defaultJsonb.toJson(new Example()); fail("JsonbException is expected"); } catch (JsonbException e) { // Expected @@ -39,7 +39,7 @@ public String getProperty() { @Override public String toString() { - return JsonbBuilder.create().toJson(this); + return defaultJsonb.toJson(this); } } } diff --git a/src/test/java/org/eclipse/yasson/customization/EncodingTest.java b/src/test/java/org/eclipse/yasson/customization/EncodingTest.java index a47bf636..f3531f80 100644 --- a/src/test/java/org/eclipse/yasson/customization/EncodingTest.java +++ b/src/test/java/org/eclipse/yasson/customization/EncodingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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,12 +13,13 @@ package org.eclipse.yasson.customization; import org.junit.jupiter.api.*; + +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.*; import org.eclipse.yasson.TestTypeToken; import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -50,32 +51,47 @@ public class EncodingTest { } @Test - public void testCP1250Encoding() throws UnsupportedEncodingException { + public void testCP1250Encoding() { String encoding = "cp1250"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withEncoding(encoding)); - - testMarshaller(CZECH, jsonb, encoding); - testUnmarshaller(CZECH, jsonb, encoding); + testWithJsonbBuilderCreate(new JsonbConfig().withEncoding(encoding), jsonb -> { + + try { + testMarshaller(CZECH, jsonb, encoding); + testUnmarshaller(CZECH, jsonb, encoding); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testUTF8Encoding() throws UnsupportedEncodingException { + public void testUTF8Encoding() { String encoding = "UTF-8"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withEncoding(encoding)); - - testMarshaller(CZECH, jsonb, encoding); - testUnmarshaller(CZECH, jsonb, encoding); - testMarshaller(RUSSIAN, jsonb, encoding); - testUnmarshaller(RUSSIAN, jsonb, encoding); + testWithJsonbBuilderCreate(new JsonbConfig().withEncoding(encoding), jsonb -> { + + try { + testMarshaller(CZECH, jsonb, encoding); + testUnmarshaller(CZECH, jsonb, encoding); + testMarshaller(RUSSIAN, jsonb, encoding); + testUnmarshaller(RUSSIAN, jsonb, encoding); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testcp1251Encoding() throws UnsupportedEncodingException { + public void testcp1251Encoding() { String encoding = "cp1251"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withEncoding(encoding)); - - testMarshaller(RUSSIAN, jsonb, encoding); - testUnmarshaller(RUSSIAN, jsonb, encoding); + testWithJsonbBuilderCreate(new JsonbConfig().withEncoding(encoding), jsonb -> { + + try { + testMarshaller(RUSSIAN, jsonb, encoding); + testUnmarshaller(RUSSIAN, jsonb, encoding); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + }); } private static void testMarshaller(String[] input, Jsonb jsonb, String encoding) throws UnsupportedEncodingException { @@ -92,7 +108,7 @@ private static void testUnmarshaller(String[] input, Jsonb jsonb, String encodin logger.finest("JSON for unmarshaller: "+json); InputStream bis = new ByteArrayInputStream(json.getBytes(encoding)); ArrayList result = jsonb.fromJson(bis, new TestTypeToken>(){}.getType()); - assertArrayEquals(input, result.toArray(new String[result.size()])); + assertArrayEquals(input, result.toArray(new String[0])); } private static String diacriticsToJsonArray(String[] diacritics) { diff --git a/src/test/java/org/eclipse/yasson/customization/JsonbNillableTest.java b/src/test/java/org/eclipse/yasson/customization/JsonbNillableTest.java index 1d5d40bf..e40e916a 100644 --- a/src/test/java/org/eclipse/yasson/customization/JsonbNillableTest.java +++ b/src/test/java/org/eclipse/yasson/customization/JsonbNillableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -14,8 +14,6 @@ import org.junit.jupiter.api.*; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.annotation.JsonbProperty; import static org.junit.jupiter.api.Assertions.*; @@ -65,13 +63,13 @@ public void testPackageLevelOverriddenWithClassLevel() { * Tests inheritance of annotations from interfaces. */ @Test - public void testNillableInheritFromInterface() throws Exception { + public void testNillableInheritFromInterface() { JsonbNillableClassSecondLevel pojo = new JsonbNillableClassSecondLevel(); assertEquals("{\"classNillable\":null}", defaultJsonb.toJson(pojo)); } @Test - public void testInheritanceOverride() throws Exception { + public void testInheritanceOverride() { JsonbNillableOverridesInterface overridesInterface = new JsonbNillableOverridesInterface(); assertEquals("{}", defaultJsonb.toJson(overridesInterface)); @@ -87,6 +85,7 @@ public void testNillableInConfig() { public static class PrimitiveNullBoolean { + @SuppressWarnings("deprecation") @JsonbProperty(nillable = true) private Boolean someBoolean; @@ -96,13 +95,12 @@ void setSomeBoolean(boolean value) { // note that value is a primitive boolean } /** - * Test for issue https://github.com/eclipse-ee4j/yasson/issues/399 + * Test for issue 399 */ @Test public void testNillableSomeBoolean() { - Jsonb jsonb = JsonbBuilder.create(); String input = "{\"someBoolean\": null}"; - PrimitiveNullBoolean deserialized = jsonb.fromJson(input, PrimitiveNullBoolean.class); + PrimitiveNullBoolean deserialized = defaultJsonb.fromJson(input, PrimitiveNullBoolean.class); assertNull(deserialized.someBoolean); } } diff --git a/src/test/java/org/eclipse/yasson/customization/JsonbPropertyTest.java b/src/test/java/org/eclipse/yasson/customization/JsonbPropertyTest.java index 5e6c52aa..05b97faa 100644 --- a/src/test/java/org/eclipse/yasson/customization/JsonbPropertyTest.java +++ b/src/test/java/org/eclipse/yasson/customization/JsonbPropertyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -20,8 +20,6 @@ import org.eclipse.yasson.customization.model.JsonbPropertyNameCollision; import org.eclipse.yasson.customization.model.JsonbPropertyNillable; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.JsonbException; import jakarta.json.bind.annotation.JsonbProperty; @@ -34,7 +32,7 @@ public class JsonbPropertyTest { @Test - public void testPropertyName() throws Exception { + public void testPropertyName() { JsonbPropertyName pojo = new JsonbPropertyName(); pojo.setFieldAnnotatedName("FIELD_ANNOTATED"); @@ -92,28 +90,29 @@ public void testRenamedGetterAndSetter() { @Test public void testRenamedGetterAndSetter2() { // Reported in issue: https://github.com/eclipse-ee4j/yasson/issues/81 - final Jsonb jsonb = JsonbBuilder.create( - new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE), jsonb -> { - final RenamedGetterAndSetter2 bean1 = new RenamedGetterAndSetter2(); - bean1.setAPIDocumentation("REST"); + final RenamedGetterAndSetter2 bean1 = new RenamedGetterAndSetter2(); + bean1.setAPIDocumentation("REST"); - final String json = jsonb.toJson(bean1); - final RenamedGetterAndSetter2 bean2 = jsonb.fromJson(json, RenamedGetterAndSetter2.class); - assertEquals(bean1.getAPIDocumentation(), bean2.getAPIDocumentation()); + final String json = jsonb.toJson(bean1); + final RenamedGetterAndSetter2 bean2 = jsonb.fromJson(json, RenamedGetterAndSetter2.class); + assertEquals(bean1.getAPIDocumentation(), bean2.getAPIDocumentation()); + }); } @Test public void testRenamedGetterAndSetter3() { // Reported in issue: https://github.com/eclipse-ee4j/yasson/issues/81 - final Jsonb jsonb = JsonbBuilder.create(); - - final RenamedGetterAndSetter2 bean1 = new RenamedGetterAndSetter2(); - bean1.setAPIDocumentation("REST"); + testWithJsonbBuilderCreate(jsonb -> { + + final RenamedGetterAndSetter2 bean1 = new RenamedGetterAndSetter2(); + bean1.setAPIDocumentation("REST"); - final String json = jsonb.toJson(bean1); - final RenamedGetterAndSetter2 bean2 = jsonb.fromJson(json, RenamedGetterAndSetter2.class); - assertEquals(bean1.getAPIDocumentation(), bean2.getAPIDocumentation()); + final String json = jsonb.toJson(bean1); + final RenamedGetterAndSetter2 bean2 = jsonb.fromJson(json, RenamedGetterAndSetter2.class); + assertEquals(bean1.getAPIDocumentation(), bean2.getAPIDocumentation()); + }); } public static class RenamedGetterAndSetter { @@ -152,7 +151,7 @@ public void setAPIDocumentation(String api) { * is private without getter / setter. * And property "DOI" - getter / setter without a field with customization on getter renaming it to doi * in serialized document. - * + *

* Because first of those properties is not readable this should not raise naming clash error. */ @Test @@ -174,16 +173,18 @@ public void testNonConflictingProperties() { public void testConflictingProperties() { ConflictingProperties conflictingProperties = new ConflictingProperties(); conflictingProperties.setDOI("DOI value"); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - - try { - jsonb.toJson(conflictingProperties); - fail(); - } catch (JsonbException e) { - if (!e.getMessage().equals("Property DOI clashes with property doi by read or write name in class org.eclipse.yasson.customization.JsonbPropertyTest$ConflictingProperties.")) { - throw e; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + + try { + jsonb.toJson(conflictingProperties); + fail(); + } catch (JsonbException e) { + if (!e.getMessage() + .equals("Property DOI clashes with property doi by read or write name in class org.eclipse.yasson.customization.JsonbPropertyTest$ConflictingProperties.")) { + throw e; + } } - } + }); } /** @@ -197,26 +198,26 @@ public void testConflictingWithUpperCamelStrategy() { String json = defaultJsonb.toJson(pojo); assertEquals("{\"Doi\":\"DOI value\",\"doi\":\"DOI value\"}", json); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() - .withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE), jsonb -> { - try { - jsonb.toJson(pojo); - fail(); - } catch (JsonbException e) { - if (!e.getMessage().equals("Property DOI clashes with property doi by read or write name in class org.eclipse.yasson.customization.JsonbPropertyTest$ConflictingWithUpperCamelStrategy.")) { - throw e; + try { + jsonb.toJson(pojo); + fail(); + } catch (JsonbException e) { + if (!e.getMessage() + .equals("Property DOI clashes with property doi by read or write name in class org.eclipse.yasson.customization.JsonbPropertyTest$ConflictingWithUpperCamelStrategy.")) { + throw e; + } } - } - + }); } @Test public void testConflictingWithLowercaseStrategy() { // scenario raised by user here: https://github.com/eclipse-ee4j/yasson/issues/296 - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES)); - assertEquals("{\"url\":\"http://foo.com\"}", - jsonb.toJson(new ConflictingIfLowercase())); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES), jsonb -> + assertEquals("{\"url\":\"http://foo.com\"}", jsonb.toJson(new ConflictingIfLowercase())) + ); } public static class ConflictingIfLowercase { diff --git a/src/test/java/org/eclipse/yasson/customization/JsonbPropertyVisibilityStrategyTest.java b/src/test/java/org/eclipse/yasson/customization/JsonbPropertyVisibilityStrategyTest.java index 551e059e..e6150d63 100644 --- a/src/test/java/org/eclipse/yasson/customization/JsonbPropertyVisibilityStrategyTest.java +++ b/src/test/java/org/eclipse/yasson/customization/JsonbPropertyVisibilityStrategyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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,6 @@ import static org.junit.jupiter.api.Assertions.*; import static org.eclipse.yasson.Jsonbs.*; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbVisibility; import jakarta.json.bind.config.PropertyVisibilityStrategy; @@ -110,24 +108,24 @@ public boolean isVisible(Method method) { */ @Test public void testFieldVisibilityStrategy() { - JsonbConfig customizedConfig = new JsonbConfig(); - customizedConfig.setProperty(JsonbConfig.PROPERTY_VISIBILITY_STRATEGY, new PropertyVisibilityStrategy() { - @Override - public boolean isVisible(Field field) { - final String fieldName = field.getName(); - return fieldName.equals("afield") || fieldName.equals("dfield"); - } - - @Override - public boolean isVisible(Method method) { - throw new IllegalStateException("Not supported"); - } - }); + JsonbConfig customizedConfig = new JsonbConfig() + .setProperty(JsonbConfig.PROPERTY_VISIBILITY_STRATEGY, new PropertyVisibilityStrategy() { + @Override + public boolean isVisible(Field field) { + final String fieldName = field.getName(); + return fieldName.equals("afield") || fieldName.equals("dfield"); + } + + @Override + public boolean isVisible(Method method) { + throw new IllegalStateException("Not supported"); + } + }); FieldPojo fieldPojo = new FieldPojo("avalue", "bvalue", "cvalue", "dvalue"); - Jsonb jsonb = JsonbBuilder.create(customizedConfig); - assertEquals("{\"afield\":\"avalue\",\"dfield\":\"dvalue\"}", jsonb.toJson(fieldPojo)); + testWithJsonbBuilderCreate(customizedConfig, jsonb -> + assertEquals("{\"afield\":\"avalue\",\"dfield\":\"dvalue\"}", jsonb.toJson(fieldPojo))); } /** @@ -135,24 +133,24 @@ public boolean isVisible(Method method) { */ @Test public void testMethodVisibilityStrategy() { - JsonbConfig customizedConfig = new JsonbConfig(); - customizedConfig.setProperty(JsonbConfig.PROPERTY_VISIBILITY_STRATEGY, new PropertyVisibilityStrategy() { - @Override - public boolean isVisible(Field field) { - throw new IllegalStateException("Not supported"); - } - - @Override - public boolean isVisible(Method method) { - final String methodName = method.getName(); - return methodName.equals("getAgetter") || methodName.equals("getDgetter"); - } - }); + JsonbConfig customizedConfig = new JsonbConfig() + .setProperty(JsonbConfig.PROPERTY_VISIBILITY_STRATEGY, new PropertyVisibilityStrategy() { + @Override + public boolean isVisible(Field field) { + throw new IllegalStateException("Not supported"); + } + + @Override + public boolean isVisible(Method method) { + final String methodName = method.getName(); + return methodName.equals("getAgetter") || methodName.equals("getDgetter"); + } + }); GetterPojo getterPojo = new GetterPojo(); - Jsonb jsonb = JsonbBuilder.create(customizedConfig); - assertEquals("{\"agetter\":\"avalue\",\"dgetter\":\"dvalue\"}", jsonb.toJson(getterPojo)); + testWithJsonbBuilderCreate(customizedConfig, jsonb -> + assertEquals("{\"agetter\":\"avalue\",\"dgetter\":\"dvalue\"}", jsonb.toJson(getterPojo))); } @Test diff --git a/src/test/java/org/eclipse/yasson/customization/PropertyOrderTest.java b/src/test/java/org/eclipse/yasson/customization/PropertyOrderTest.java index eee1d7dd..dda68352 100644 --- a/src/test/java/org/eclipse/yasson/customization/PropertyOrderTest.java +++ b/src/test/java/org/eclipse/yasson/customization/PropertyOrderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -23,8 +23,6 @@ import org.eclipse.yasson.customization.model.FieldSpecificOrder; import org.eclipse.yasson.customization.model.RenamedPropertiesContainer; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbCreator; import jakarta.json.bind.annotation.JsonbProperty; @@ -39,61 +37,72 @@ public class PropertyOrderTest { @Test public void testPropertySorting() { FieldOrder fieldOrder = new FieldOrder(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL)); - String expectedLexicographical = "{\"aField\":\"aValue\",\"bField\":\"bValue\",\"cField\":\"cValue\",\"dField\":\"dValue\"}"; - assertEquals(expectedLexicographical, jsonb.toJson(fieldOrder)); - - jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE)); - String expectedReverse = "{\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\",\"aField\":\"aValue\"}"; - assertEquals(expectedReverse, jsonb.toJson(fieldOrder)); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { + String expectedLexicographical = "{\"aField\":\"aValue\",\"bField\":\"bValue\",\"cField\":\"cValue\",\"dField\":\"dValue\"}"; + assertEquals(expectedLexicographical, jsonb.toJson(fieldOrder)); + }); + + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE), jsonb -> { + String expectedReverse = "{\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\",\"aField\":\"aValue\"}"; + assertEquals(expectedReverse, jsonb.toJson(fieldOrder)); + }); } @Test public void testPropertyCustomOrder() { FieldCustomOrder fieldCustomOrder = new FieldCustomOrder(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL)); - String expectedCustomOrder = "{\"aField\":\"aValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"bField\":\"bValue\"}"; - assertEquals(expectedCustomOrder, jsonb.toJson(fieldCustomOrder)); - - FieldCustomOrderWrapper fieldCustomOrderWrapper = new FieldCustomOrderWrapper(); - String expectedOrder = "{\"fieldCustomOrder\":{\"aField\":\"aValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"bField\":\"bValue\"},\"intField\":1,\"stringField\":\"stringValue\"}"; - assertEquals(expectedOrder, jsonb.toJson(fieldCustomOrderWrapper)); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { + String expectedCustomOrder = "{\"aField\":\"aValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"bField\":\"bValue\"}"; + assertEquals(expectedCustomOrder, jsonb.toJson(fieldCustomOrder)); + + FieldCustomOrderWrapper fieldCustomOrderWrapper = new FieldCustomOrderWrapper(); + String expectedOrder = + "{\"fieldCustomOrder\":{\"aField\":\"aValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"bField\":\"bValue\"},\"intField\":1,\"stringField\":\"stringValue\"}"; + assertEquals(expectedOrder, jsonb.toJson(fieldCustomOrderWrapper)); + }); } @Test public void testPropertySetCustomOrder() { FieldSpecificOrder fieldSpecificOrder = new FieldSpecificOrder(); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE), jsonb -> { String expectedSpecific = "{\"aField\":\"aValue\",\"dField\":\"dValue\",\"bField\":\"bValue\",\"cField\":\"cValue\"}"; assertEquals(expectedSpecific, defaultJsonb.toJson(fieldSpecificOrder)); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE)); - expectedSpecific = "{\"aField\":\"aValue\",\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\"}"; - assertEquals(expectedSpecific, jsonb.toJson(fieldSpecificOrder)); + expectedSpecific = "{\"aField\":\"aValue\",\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\"}"; + assertEquals(expectedSpecific, jsonb.toJson(fieldSpecificOrder)); + }); } @Test public void testPropertySortingWithNamingAnnotation() { FieldOrderNameAnnotation fieldOrderNameAnnotation = new FieldOrderNameAnnotation(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL)); - String expectedLexicographical = "{\"bField\":\"bValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"zField\":\"aValue\"}"; - assertEquals(expectedLexicographical, jsonb.toJson(fieldOrderNameAnnotation)); - - jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE)); - String expectedReverse = "{\"zField\":\"aValue\",\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\"}"; - assertEquals(expectedReverse, jsonb.toJson(fieldOrderNameAnnotation)); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { + String expectedLexicographical = "{\"bField\":\"bValue\",\"cField\":\"cValue\",\"dField\":\"dValue\",\"zField\":\"aValue\"}"; + assertEquals(expectedLexicographical, jsonb.toJson(fieldOrderNameAnnotation)); + }); + + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE), jsonb -> { + String expectedReverse = "{\"zField\":\"aValue\",\"dField\":\"dValue\",\"cField\":\"cValue\",\"bField\":\"bValue\"}"; + assertEquals(expectedReverse, jsonb.toJson(fieldOrderNameAnnotation)); + }); } @Test public void testLexicographicalPropertyOrderRenamedProperties() { - JsonbConfig config = new JsonbConfig(); - config.setProperty(JsonbConfig.PROPERTY_ORDER_STRATEGY, PropertyOrderStrategy.LEXICOGRAPHICAL); - Jsonb jsonb = JsonbBuilder.create(config); - - String jsonString = jsonb.toJson(new RenamedPropertiesContainer() {{ setStringInstance("Test String"); setLongInstance(1); }}); - assertTrue(jsonString.matches("\\{\\s*\"first\"\\s*\\:\\s*0\\s*,\\s*\"second\"\\s*\\:\\s*\"Test String\"\\s*,\\s*\"third\"\\s*\\:\\s*1\\s*\\}")); - - RenamedPropertiesContainer unmarshalledObject = jsonb.fromJson("{ \"first\" : 1, \"second\" : \"Test String\", \"third\" : 1 }", RenamedPropertiesContainer.class); - assertEquals(3, unmarshalledObject.getIntInstance()); + testWithJsonbBuilderCreate(new JsonbConfig().setProperty(JsonbConfig.PROPERTY_ORDER_STRATEGY, PropertyOrderStrategy.LEXICOGRAPHICAL), jsonb -> { + + String jsonString = jsonb.toJson(new RenamedPropertiesContainer() {{ + setStringInstance("Test String"); + setLongInstance(1); + }}); + assertTrue(jsonString.matches( + "\\{\\s*\"first\"\\s*:\\s*0\\s*,\\s*\"second\"\\s*:\\s*\"Test String\"\\s*,\\s*\"third\"\\s*:\\s*1\\s*\\}")); + + RenamedPropertiesContainer unmarshalledObject = + jsonb.fromJson("{ \"first\" : 1, \"second\" : \"Test String\", \"third\" : 1 }", RenamedPropertiesContainer.class); + assertEquals(3, unmarshalledObject.getIntInstance()); + }); } @Test @@ -106,7 +115,7 @@ public void testJsonbPropertyOrderOnRenamedProperties() { // But with JsonbPropertyOrder we will put props 'propB' and 'propA' first, and leftovers will go at the end, resulting in: // propB, propA, anExtraProp @JsonbPropertyOrder({"propB","propA"}) - public class Range { + public static class Range { @JsonbProperty("d") public final int propA; diff --git a/src/test/java/org/eclipse/yasson/customization/YassonSpecificConfigTests.java b/src/test/java/org/eclipse/yasson/customization/YassonSpecificConfigTests.java index 4364ebb0..613cad2a 100644 --- a/src/test/java/org/eclipse/yasson/customization/YassonSpecificConfigTests.java +++ b/src/test/java/org/eclipse/yasson/customization/YassonSpecificConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -14,14 +14,13 @@ import java.util.Optional; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.serializer.JsonbSerializer; import jakarta.json.bind.serializer.SerializationContext; import jakarta.json.stream.JsonGenerator; import org.eclipse.yasson.YassonConfig; import org.junit.jupiter.api.Test; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -34,20 +33,20 @@ public class YassonSpecificConfigTests { @Test public void nullRootSerializerTest() { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig().withNullRootSerializer(new RootNullSerializer())); - assertEquals(NULL_VALUE_SERIALIZED, jsonb.toJson(null)); + testWithJsonbBuilderCreate(new YassonConfig().withNullRootSerializer(new RootNullSerializer()), jsonb -> + assertEquals(NULL_VALUE_SERIALIZED, jsonb.toJson(null))); } @Test public void emptyOptionalRootSerializerTest() { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig().withNullRootSerializer(new RootNullSerializer())); - assertEquals(NULL_VALUE_SERIALIZED, jsonb.toJson(Optional.empty())); + testWithJsonbBuilderCreate(new YassonConfig().withNullRootSerializer(new RootNullSerializer()), jsonb -> + assertEquals(NULL_VALUE_SERIALIZED, jsonb.toJson(Optional.empty()))); } @Test public void nullSerializerNotUsedTest() { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig().withNullRootSerializer(new RootNullSerializer())); - assertEquals("[null]", jsonb.toJson(new String[] {null})); + testWithJsonbBuilderCreate(new YassonConfig().withNullRootSerializer(new RootNullSerializer()), jsonb -> + assertEquals("[null]", jsonb.toJson(new String[] {null}))); } private static final class RootNullSerializer implements JsonbSerializer { @@ -57,5 +56,4 @@ public void serialize(Object obj, JsonGenerator generator, SerializationContext generator.write(NULL_VALUE_STRING); } } - -} +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/yasson/customization/polymorphism/MultiplePolymorphicInfoTest.java b/src/test/java/org/eclipse/yasson/customization/polymorphism/MultiplePolymorphicInfoTest.java index 9bb575a8..33c16ce8 100644 --- a/src/test/java/org/eclipse/yasson/customization/polymorphism/MultiplePolymorphicInfoTest.java +++ b/src/test/java/org/eclipse/yasson/customization/polymorphism/MultiplePolymorphicInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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,13 +12,12 @@ package org.eclipse.yasson.customization.polymorphism; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.annotation.JsonbSubtype; import jakarta.json.bind.annotation.JsonbTypeInfo; import org.junit.jupiter.api.Test; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -28,19 +27,17 @@ */ public class MultiplePolymorphicInfoTest { - private static final Jsonb JSONB = JsonbBuilder.create(); - @Test public void testMultiplePolymorphicInfoPropertySerialization() { String expected = "{\"@something\":\"animal\",\"@animal\":\"dog\",\"@dogRace\":\"labrador\",\"isLabrador\":true}"; Labrador labrador = new Labrador(); - assertThat(JSONB.toJson(labrador), is(expected)); + assertThat(defaultJsonb.toJson(labrador), is(expected)); } @Test public void testMultiplePolymorphicInfoPropertyDeserialization() { String json = "{\"@something\":\"animal\",\"@animal\":\"dog\",\"@dogRace\":\"labrador\",\"isLabrador\":true}"; - assertThat(JSONB.fromJson(json, Labrador.class), instanceOf(Labrador.class)); + assertThat(defaultJsonb.fromJson(json, Labrador.class), instanceOf(Labrador.class)); } @Test @@ -49,13 +46,13 @@ public void testPolymorphicParentInstanceSerialization() { Area northAmerica = new Area(); northAmerica.name = "North America"; northAmerica.population = 600000000; - assertThat(JSONB.toJson(northAmerica), is(expected)); + assertThat(defaultJsonb.toJson(northAmerica), is(expected)); } @Test public void testPolymorphicParentInstanceDeserialization() { String json = "{\"@type\":\"area\",\"name\":\"North America\",\"population\":600000000}"; - assertThat(JSONB.fromJson(json, Location.class), instanceOf(Area.class)); + assertThat(defaultJsonb.fromJson(json, Location.class), instanceOf(Area.class)); } @JsonbTypeInfo(key = "@something", value = { diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/IJsonTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/IJsonTest.java index de93f7b7..dfb5f991 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/IJsonTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/IJsonTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -31,13 +31,13 @@ */ public class IJsonTest { - private Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withStrictIJSON(true)); + private final static Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withStrictIJSON(true)); @Test public void testStrictCalendar() { Calendar calendar = Calendar.getInstance(); calendar.clear(); - calendar.set(1970, 0, 1, 0, 0, 0); + calendar.set(1970, Calendar.JANUARY, 1, 0, 0, 0); calendar.setTimeZone(TimeZone.getTimeZone("Europe/Paris")); String jsonString = jsonb.toJson(new ScalarValueWrapper<>(calendar)); @@ -51,7 +51,7 @@ public void testStrictCalendar() { @Test public void testStrictDate() { Calendar calendar = Calendar.getInstance(); - calendar.set(1970, 0, 1, 0, 0, 0); + calendar.set(1970, Calendar.JANUARY, 1, 0, 0, 0); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.clear(Calendar.MILLISECOND); diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/SecurityManagerTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/SecurityManagerTest.java index 029e5540..5cc04e3f 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/SecurityManagerTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/SecurityManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,12 +12,12 @@ package org.eclipse.yasson.defaultmapping; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; + import org.junit.jupiter.api.*; import org.eclipse.yasson.serializers.model.Crate; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbProperty; import jakarta.json.bind.config.PropertyVisibilityStrategy; @@ -48,7 +48,7 @@ public static void tearDown() { @Test public void testWithSecurityManager() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { + JsonbConfig config = new JsonbConfig().withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { @Override public boolean isVisible(Field field) { return Modifier.isPublic(field.getModifiers()) || field.getName().equals("privateProperty"); @@ -58,16 +58,18 @@ public boolean isVisible(Field field) { public boolean isVisible(Method method) { return Modifier.isPublic(method.getModifiers()); } - })); - - Pojo pojo = new Pojo(); - pojo.setStrProperty("string propery"); - Crate crate = new Crate(); - crate.crateBigDec = BigDecimal.TEN; - crate.crateStr = "crate string"; - pojo.setCrate(crate); - - String result = jsonb.toJson(pojo); + }); + + testWithJsonbBuilderCreate(config, jsonb -> { + Pojo pojo = new Pojo(); + pojo.setStrProperty("string propery"); + Crate crate = new Crate(); + crate.crateBigDec = BigDecimal.TEN; + crate.crateStr = "crate string"; + pojo.setCrate(crate); + + String result = jsonb.toJson(pojo); + }); } diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/jsonp/JsonpTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/jsonp/JsonpTest.java index 731c9f70..0a65b0d9 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/jsonp/JsonpTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/jsonp/JsonpTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -22,14 +22,13 @@ import jakarta.json.JsonObjectBuilder; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.spi.JsonProvider; import org.eclipse.yasson.defaultmapping.jsonp.model.JsonpPojo; import org.junit.jupiter.api.Test; import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -114,45 +113,45 @@ public void testMarshallJsonString() { @Test public void testJsonPojo() { - JsonbConfig config = new JsonbConfig(); -// config.withFormatting(true); - Jsonb jsonb = JsonbBuilder.create(config); + // config.withFormatting(true); + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + JsonpPojo pojo = new JsonpPojo(); + final JsonObjectBuilder obj1builder = JsonProvider.provider().createObjectBuilder(); + obj1builder.add("strVal", "string value"); + obj1builder.add("numVal", 2.0d); + obj1builder.addNull("nullVal"); + obj1builder.add("boolVal", Boolean.TRUE); - JsonpPojo pojo = new JsonpPojo(); - final JsonObjectBuilder obj1builder = JsonProvider.provider().createObjectBuilder(); - obj1builder.add("strVal", "string value"); - obj1builder.add("numVal", 2.0d); - obj1builder.addNull("nullVal"); - obj1builder.add("boolVal", Boolean.TRUE); - - final JsonObjectBuilder obj2Builder = JsonProvider.provider().createObjectBuilder(); - obj2Builder.add("innerStr", "string val"); - obj2Builder.add("innerNum", 11.1d); - final JsonObject obj2 = obj2Builder.build(); + final JsonObjectBuilder obj2Builder = JsonProvider.provider().createObjectBuilder(); + obj2Builder.add("innerStr", "string val"); + obj2Builder.add("innerNum", 11.1d); + final JsonObject obj2 = obj2Builder.build(); - JsonArrayBuilder array1Builder = JsonProvider.provider().createArrayBuilder(); - array1Builder.addNull().add(false).add(11L).add(BigDecimal.TEN).add("array STR value").add(obj2); - JsonArray jsonArray1 = array1Builder.build(); + JsonArrayBuilder array1Builder = JsonProvider.provider().createArrayBuilder(); + array1Builder.addNull().add(false).add(11L).add(BigDecimal.TEN).add("array STR value").add(obj2); + JsonArray jsonArray1 = array1Builder.build(); - obj1builder.add("innerJsonObject", obj2); - obj1builder.add("innerArrayObject", jsonArray1); + obj1builder.add("innerJsonObject", obj2); + obj1builder.add("innerArrayObject", jsonArray1); - final JsonObject obj1 = obj1builder.build(); - pojo.jsonObject = obj1; + final JsonObject obj1 = obj1builder.build(); + pojo.jsonObject = obj1; - JsonArrayBuilder arrayBuilder = JsonProvider.provider().createArrayBuilder(); - arrayBuilder.add(obj1).add(true).add(obj2).add(101.0d).add(BigDecimal.TEN); - pojo.jsonArray = arrayBuilder.build(); + JsonArrayBuilder arrayBuilder = JsonProvider.provider().createArrayBuilder(); + arrayBuilder.add(obj1).add(true).add(obj2).add(101.0d).add(BigDecimal.TEN); + pojo.jsonArray = arrayBuilder.build(); - String expected = "{\"jsonArray\":[{\"strVal\":\"string value\",\"numVal\":2.0,\"nullVal\":null,\"boolVal\":true,\"innerJsonObject\":{\"innerStr\":\"string val\",\"innerNum\":11.1},\"innerArrayObject\":[null,false,11,10,\"array STR value\",{\"innerStr\":\"string val\",\"innerNum\":11.1}]},true,{\"innerStr\":\"string val\",\"innerNum\":11.1},101.0,10],\"jsonObject\":{\"strVal\":\"string value\",\"numVal\":2.0,\"nullVal\":null,\"boolVal\":true,\"innerJsonObject\":{\"innerStr\":\"string val\",\"innerNum\":11.1},\"innerArrayObject\":[null,false,11,10,\"array STR value\",{\"innerStr\":\"string val\",\"innerNum\":11.1}]}}"; - final String actual = jsonb.toJson(pojo); - assertEquals(expected, actual); + String expected = + "{\"jsonArray\":[{\"strVal\":\"string value\",\"numVal\":2.0,\"nullVal\":null,\"boolVal\":true,\"innerJsonObject\":{\"innerStr\":\"string val\",\"innerNum\":11.1},\"innerArrayObject\":[null,false,11,10,\"array STR value\",{\"innerStr\":\"string val\",\"innerNum\":11.1}]},true,{\"innerStr\":\"string val\",\"innerNum\":11.1},101.0,10],\"jsonObject\":{\"strVal\":\"string value\",\"numVal\":2.0,\"nullVal\":null,\"boolVal\":true,\"innerJsonObject\":{\"innerStr\":\"string val\",\"innerNum\":11.1},\"innerArrayObject\":[null,false,11,10,\"array STR value\",{\"innerStr\":\"string val\",\"innerNum\":11.1}]}}"; + final String actual = jsonb.toJson(pojo); + assertEquals(expected, actual); - JsonpPojo result = jsonb.fromJson(expected, JsonpPojo.class); - assertEquals(pojo.jsonObject, result.jsonObject); - assertEquals(pojo.jsonArray, result.jsonArray); + JsonpPojo result = jsonb.fromJson(expected, JsonpPojo.class); + assertEquals(pojo.jsonObject, result.jsonObject); + assertEquals(pojo.jsonArray, result.jsonArray); + }); } @Test diff --git a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java index 4963b12e..3cccdf95 100644 --- a/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java +++ b/src/test/java/org/eclipse/yasson/defaultmapping/specific/UnmarshallingUnsupportedTypesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -23,8 +23,6 @@ import java.util.OptionalInt; import java.util.OptionalLong; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.JsonbException; @@ -37,10 +35,12 @@ import org.junit.jupiter.api.Test; import static org.eclipse.yasson.Jsonbs.defaultJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.eclipse.yasson.YassonConfig.FAIL_ON_UNKNOWN_PROPERTIES; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -120,7 +120,7 @@ public void testMissingFieldDefault() { String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}"; SupportedTypes result = defaultJsonb.fromJson(json, SupportedTypes.class); assertEquals(Integer.valueOf(10), result.getNestedPojo().getIntegerValue()); - assertEquals(11, result.getOptionalLong().getAsLong()); + assertEquals(11, result.getOptionalLong().orElseThrow(RuntimeException::new)); } @Test() @@ -128,16 +128,18 @@ public void testMissingFieldDefaultNull() { String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":null},\"optionalLong\":11}"; SupportedTypes result = defaultJsonb.fromJson(json, SupportedTypes.class); assertEquals(Integer.valueOf(10), result.getNestedPojo().getIntegerValue()); - assertEquals(11, result.getOptionalLong().getAsLong()); + assertEquals(11, result.getOptionalLong().orElseThrow(RuntimeException::new)); } @Test public void testMissingFieldIgnored() { - assertThrows(JsonbException.class, () -> { - Jsonb defaultConfig = JsonbBuilder.create(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true)); - String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}"; - SupportedTypes result = defaultConfig.fromJson(json, SupportedTypes.class); - }); + RuntimeException runtimeException + = assertThrows(RuntimeException.class, () -> testWithJsonbBuilderCreate(new JsonbConfig().setProperty(FAIL_ON_UNKNOWN_PROPERTIES, true), jsonb -> { + String json = "{\"nestedPojo\":{\"integerValue\":10,\"missingField\":5},\"optionalLong\":11}"; + SupportedTypes result = jsonb.fromJson(json, SupportedTypes.class); + })); + + assertInstanceOf(JsonbException.class, runtimeException.getCause()); } @Test diff --git a/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java index c88324ba..78bf51cb 100644 --- a/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java +++ b/src/test/java/org/eclipse/yasson/documented/DocumentationExampleTest.java @@ -15,7 +15,9 @@ import static org.eclipse.yasson.Jsonbs.defaultJsonb; import static org.eclipse.yasson.Jsonbs.formattingJsonb; import static org.eclipse.yasson.Jsonbs.nullableJsonb; +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import java.lang.reflect.Type; @@ -28,8 +30,6 @@ import org.junit.jupiter.api.Test; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.adapter.JsonbAdapter; import jakarta.json.bind.annotation.JsonbCreator; @@ -46,7 +46,7 @@ import jakarta.json.stream.JsonParser; /** - * Contains tests from http://json-b.net/docs/user-guide.html + * Contains tests from user-guide */ public class DocumentationExampleTest { @@ -74,7 +74,7 @@ public void testMappingExample() { dog = defaultJsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class); assertEquals("Falco", dog.name); assertEquals(4, dog.age); - assertEquals(false, dog.bitable); + assertFalse(dog.bitable); } @Test @@ -110,7 +110,6 @@ public void testMappingCollection() { // assertEquals(5, ((Map) dogs.get(1)).get("age")); } - @SuppressWarnings("serial") @Test public void testMappingGenericCollection() { Dog falco = new Dog(); @@ -173,7 +172,7 @@ public void testChangingPropertyNames1() { "}", result); } - public class Person2 { + public static class Person2 { private String name; private String profession; @@ -274,7 +273,7 @@ public void testIgnoringProperties() { } @JsonbNillable - public class Person5 { + public static class Person5 { private String name; private String profession; @@ -303,7 +302,8 @@ public void testNullHandling1() { assertEquals("{\"name\":null,\"profession\":null}", result); } - public class Person6 { + public static class Person6 { + @SuppressWarnings("deprecation") @JsonbProperty(nillable = true) private String name; @@ -403,16 +403,17 @@ public void testDateNumberFormats2() { p.name = "Jason Bourne"; p.birthDate = LocalDate.of(1999, 8, 7); p.salary = new BigDecimal("123.45678"); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()// - .withDateFormat("dd.MM.yyyy", null)); // TODO: why no withNumberFormat? - String json = jsonb.toJson(p); - String expectedJson = "{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}"; - assertEquals(expectedJson, json); + testWithJsonbBuilderCreate(new JsonbConfig()// + .withDateFormat("dd.MM.yyyy", null), jsonb -> { // TODO: why no withNumberFormat? + String json = jsonb.toJson(p); + String expectedJson = "{\"birthDate\":\"07.08.1999\",\"name\":\"Jason Bourne\",\"salary\":123.45678}"; + assertEquals(expectedJson, json); - Person10 after = jsonb.fromJson(expectedJson, Person10.class); - assertEquals(p.name, after.name); - assertEquals(p.birthDate, after.birthDate); - assertEquals(p.salary, after.salary); + Person10 after = jsonb.fromJson(expectedJson, Person10.class); + assertEquals(p.name, after.name); + assertEquals(p.birthDate, after.birthDate); + assertEquals(p.salary, after.salary); + }); } public static class Customer { @@ -513,24 +514,22 @@ public void testAdapters1() { @Test public void testAdapters2() { - // Create custom configuration - JsonbConfig config = new JsonbConfig() - .withAdapters(new CustomerAdapter()); - - // Create Jsonb with custom configuration - Jsonb jsonb = JsonbBuilder.create(config); + // Create custom configuration -> Create Jsonb with custom configuration + testWithJsonbBuilderCreate(new JsonbConfig() + .withAdapters(new CustomerAdapter()), jsonb -> { - // Create customer - Customer customer = new Customer(); + // Create customer + Customer customer = new Customer(); - customer.setId(1); - customer.setName("Jason Bourne"); - customer.setOrganization("Super Agents"); - customer.setPosition("Super Agent"); + customer.setId(1); + customer.setName("Jason Bourne"); + customer.setOrganization("Super Agents"); + customer.setPosition("Super Agent"); - // Serialize - String json = jsonb.toJson(customer); - assertEquals("{\"customer_id\":1,\"customer_name\":\"Jason Bourne\"}", json); + // Serialize + String json = jsonb.toJson(customer); + assertEquals("{\"customer_id\":1,\"customer_name\":\"Jason Bourne\"}", json); + }); } public static class CustomerSerializer implements JsonbSerializer { @@ -578,18 +577,17 @@ public void testSerializerDeserializer() { customer.setPosition("Super Agent"); // Also configurable with @JsonbSerializer / JsonbDeserializer on properties and class. - JsonbConfig config = new JsonbConfig() + testWithJsonbBuilderCreate(new JsonbConfig() .withSerializers(new CustomerSerializer()) - .withDeserializers(new CustomerDeserializer()); - - Jsonb jsonb = JsonbBuilder.create(config); - String json = jsonb.toJson(customer); - assertEquals("{\"customer_id\":1,\"customer_name\":\"Freddie\"}", json); - - Customer result = jsonb.fromJson(json, Customer.class); - assertEquals(customer.getId(), result.getId()); - assertEquals(customer.getName(), result.getName()); - assertNull(result.getOrganization()); - assertNull(result.getPosition()); + .withDeserializers(new CustomerDeserializer()), jsonb -> { + String json = jsonb.toJson(customer); + assertEquals("{\"customer_id\":1,\"customer_name\":\"Freddie\"}", json); + + Customer result = jsonb.fromJson(json, Customer.class); + assertEquals(customer.getId(), result.getId()); + assertEquals(customer.getName(), result.getName()); + assertNull(result.getOrganization()); + assertNull(result.getPosition()); + }); } } diff --git a/src/test/java/org/eclipse/yasson/internal/JsonBindingTest.java b/src/test/java/org/eclipse/yasson/internal/JsonBindingTest.java index dc6faf24..cf29cf55 100644 --- a/src/test/java/org/eclipse/yasson/internal/JsonBindingTest.java +++ b/src/test/java/org/eclipse/yasson/internal/JsonBindingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 IBM and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -11,6 +11,7 @@ */ package org.eclipse.yasson.internal; +import static org.eclipse.yasson.Jsonbs.defaultJsonb; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -18,8 +19,8 @@ import java.lang.reflect.Field; import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; +import org.eclipse.yasson.Jsonbs; import org.eclipse.yasson.YassonConfig; import org.eclipse.yasson.internal.model.ClassModel; import org.junit.jupiter.api.Test; @@ -31,26 +32,30 @@ public static class EagerParseClass { } @Test - public void testEagerInit() throws Exception { - Jsonb jsonb = JsonbBuilder.create(new YassonConfig() - .withEagerParsing(EagerParseClass.class)); - assertNotNull(getClassModel(jsonb, EagerParseClass.class)); - - EagerParseClass obj = new EagerParseClass(); - obj.foo = "foo"; - assertEquals("{\"foo\":\"foo\"}", jsonb.toJson(obj)); + public void testEagerInit() { + Jsonbs.testWithJsonbBuilderCreate(new YassonConfig() + .withEagerParsing(EagerParseClass.class), jsonb -> { + try { + assertNotNull(getClassModel(jsonb, EagerParseClass.class)); + } catch (Exception e) { + throw new RuntimeException(e); + } + + EagerParseClass obj = new EagerParseClass(); + obj.foo = "foo"; + assertEquals("{\"foo\":\"foo\"}", jsonb.toJson(obj)); + }); } @Test public void testNoEagerInit() throws Exception { - Jsonb jsonb = JsonbBuilder.create(); - assertNull(getClassModel(jsonb, EagerParseClass.class)); + assertNull(getClassModel(defaultJsonb, EagerParseClass.class)); EagerParseClass obj = new EagerParseClass(); obj.foo = "foo"; - assertEquals("{\"foo\":\"foo\"}", jsonb.toJson(obj)); + assertEquals("{\"foo\":\"foo\"}", defaultJsonb.toJson(obj)); - assertNotNull(getClassModel(jsonb, EagerParseClass.class)); + assertNotNull(getClassModel(defaultJsonb, EagerParseClass.class)); } private ClassModel getClassModel(Jsonb jsonb, Class clazz) throws Exception { diff --git a/src/test/java/org/eclipse/yasson/internal/cdi/CdiInjectionTest.java b/src/test/java/org/eclipse/yasson/internal/cdi/CdiInjectionTest.java index b17770c8..57b7b488 100644 --- a/src/test/java/org/eclipse/yasson/internal/cdi/CdiInjectionTest.java +++ b/src/test/java/org/eclipse/yasson/internal/cdi/CdiInjectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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,8 @@ package org.eclipse.yasson.internal.cdi; import org.junit.jupiter.api.*; + +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.*; import org.eclipse.yasson.internal.components.JsonbComponentInstanceCreatorFactory; @@ -75,34 +77,30 @@ public void testInJndiEnvironment() throws NamingException { InitialContext context = new InitialContext(); context.bind(JsonbComponentInstanceCreatorFactory.BEAN_MANAGER_NAME, new JndiBeanManager()); - String result; try { - Jsonb jsonb = JsonbBuilder.create(); - result = jsonb.toJson(new AdaptedPojo()); + testWithJsonbBuilderCreate(jsonb -> + assertEquals("{\"adaptedValue1\":1111,\"adaptedValue2\":1001,\"adaptedValue3\":1010}", jsonb.toJson(new AdaptedPojo()))); } finally { context.unbind(JsonbComponentInstanceCreatorFactory.BEAN_MANAGER_NAME); } - assertEquals("{\"adaptedValue1\":1111,\"adaptedValue2\":1001,\"adaptedValue3\":1010}", result); - } + } @Test public void testNonCdiEnvironment() { - JsonbConfig config = new JsonbConfig(); + JsonbConfig config = new JsonbConfig() //allow only field with components that doesn't has cdi dependencies. - config.withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { - @Override - public boolean isVisible(Field field) { - return "adaptedValue3".equals(field.getName()); - } - - @Override - public boolean isVisible(Method method) { - return false; - } + .withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() { + @Override + public boolean isVisible(Field field) { + return "adaptedValue3".equals(field.getName()); + } + + @Override + public boolean isVisible(Method method) { + return false; + } }); - Jsonb jsonb = JsonbBuilder.create(config); - final String result = jsonb.toJson(new AdaptedPojo()); - assertEquals("{\"adaptedValue3\":1010}", result); + testWithJsonbBuilderCreate(config, jsonb -> assertEquals("{\"adaptedValue3\":1010}", jsonb.toJson(new AdaptedPojo()))); } private CalledMethods getCalledMethods() { diff --git a/src/test/java/org/eclipse/yasson/internal/model/customization/naming/PropertyNamingStrategyTest.java b/src/test/java/org/eclipse/yasson/internal/model/customization/naming/PropertyNamingStrategyTest.java index 33c0c60a..2ae2d9f1 100644 --- a/src/test/java/org/eclipse/yasson/internal/model/customization/naming/PropertyNamingStrategyTest.java +++ b/src/test/java/org/eclipse/yasson/internal/model/customization/naming/PropertyNamingStrategyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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,10 +13,10 @@ package org.eclipse.yasson.internal.model.customization.naming; import org.junit.jupiter.api.*; + +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.*; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.config.PropertyNamingStrategy; @@ -32,7 +32,7 @@ public class PropertyNamingStrategyTest { private final NamingPojo pojo = new NamingPojo("abc", "def", "ghi"); @Test - public void testLowerCase() throws Exception { + public void testLowerCase() { PropertyNamingStrategy strategy = StrategiesProvider.getPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES); assertEquals("camel_case_property", strategy.translateName("camelCaseProperty")); assertEquals("camelcase_property", strategy.translateName("CamelcaseProperty")); @@ -40,15 +40,17 @@ public void testLowerCase() throws Exception { assertEquals("_camel_case_property", strategy.translateName("_camelCaseProperty")); assertEquals("_camel_case_property", strategy.translateName("_CamelCaseProperty")); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES)); - String lowercaseUnderscoresJson = "{\"_starting_with_underscore_property\":\"def\",\"caps_underscore_property\":\"ghi\",\"upper_cased_property\":\"abc\"}"; - assertEquals(lowercaseUnderscoresJson, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson(lowercaseUnderscoresJson, NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES), jsonb -> { + String lowercaseUnderscoresJson = + "{\"_starting_with_underscore_property\":\"def\",\"caps_underscore_property\":\"ghi\",\"upper_cased_property\":\"abc\"}"; + assertEquals(lowercaseUnderscoresJson, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson(lowercaseUnderscoresJson, NamingPojo.class); + assertResult(result); + }); } @Test - public void testLowerDashes() throws Exception { + public void testLowerDashes() { PropertyNamingStrategy strategy = StrategiesProvider.getPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES); assertEquals("camel-case-property", strategy.translateName("camelCaseProperty")); assertEquals("camelcase-property", strategy.translateName("CamelcaseProperty")); @@ -56,11 +58,13 @@ public void testLowerDashes() throws Exception { assertEquals("-camel-case-property", strategy.translateName("-camelCaseProperty")); assertEquals("-camel-case-property", strategy.translateName("-CamelCaseProperty")); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)); - String lowercaseDashesJson = "{\"_starting-with-underscore-property\":\"def\",\"caps_underscore_property\":\"ghi\",\"upper-cased-property\":\"abc\"}"; - assertEquals(lowercaseDashesJson, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson(lowercaseDashesJson, NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES), jsonb -> { + String lowercaseDashesJson = + "{\"_starting-with-underscore-property\":\"def\",\"caps_underscore_property\":\"ghi\",\"upper-cased-property\":\"abc\"}"; + assertEquals(lowercaseDashesJson, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson(lowercaseDashesJson, NamingPojo.class); + assertResult(result); + }); } @Test @@ -69,11 +73,12 @@ public void testUpperCase() { assertEquals("UpperCamelCase", upperCaseStrategy.translateName("upperCamelCase")); assertEquals("UpperCamelCase", upperCaseStrategy.translateName("UpperCamelCase")); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)); - String upperCased = "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"UpperCasedProperty\":\"abc\",\"_startingWithUnderscoreProperty\":\"def\"}"; - assertEquals(upperCased, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson(upperCased, NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE), jsonb -> { + String upperCased = "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"UpperCasedProperty\":\"abc\",\"_startingWithUnderscoreProperty\":\"def\"}"; + assertEquals(upperCased, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson(upperCased, NamingPojo.class); + assertResult(result); + }); } @Test @@ -82,39 +87,49 @@ public void testUpperCaseWithSpaces() { assertEquals("Upper Camel Case", upperCaseWithSpacesStrategy.translateName("upperCamelCase")); assertEquals("Upper Camel Case", upperCaseWithSpacesStrategy.translateName("UpperCamelCase")); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE_WITH_SPACES)); - String upperCased = "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"Upper Cased Property\":\"abc\",\"_starting With Underscore Property\":\"def\"}"; - assertEquals(upperCased, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson(upperCased, NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE_WITH_SPACES), jsonb -> { + String upperCased = + "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"Upper Cased Property\":\"abc\",\"_starting With Underscore Property\":\"def\"}"; + assertEquals(upperCased, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson(upperCased, NamingPojo.class); + assertResult(result); + }); } @Test public void testCaseInsensitive() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.CASE_INSENSITIVE)); - String upperCased = "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty\":\"def\",\"upperCasedProperty\":\"abc\"}"; - assertEquals(upperCased, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson("{\"caPS_unDERscore_prOPERty\":\"ghi\",\"_startingwithUndERSCorePrOPERTy\":\"def\",\"upPERCASedProPerty\":\"abc\"}", NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.CASE_INSENSITIVE), jsonb -> { + String upperCased = "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty\":\"def\",\"upperCasedProperty\":\"abc\"}"; + assertEquals(upperCased, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson( + "{\"caPS_unDERscore_prOPERty\":\"ghi\",\"_startingwithUndERSCorePrOPERTy\":\"def\",\"upPERCASedProPerty\":\"abc\"}", + NamingPojo.class); + assertResult(result); + }); } @Test public void testIdentityCaseSensitive() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.IDENTITY)); - NamingPojo result = jsonb.fromJson("{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty\":\"def\",\"UPPERCASEDPROPERTY\":\"abc\"}", NamingPojo.class); - assertEquals("ghi", result.CAPS_UNDERSCORE_PROPERTY); - assertEquals("def", result._startingWithUnderscoreProperty); - assertNull(result.upperCasedProperty); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.IDENTITY), jsonb -> { + NamingPojo result = jsonb.fromJson( + "{\"CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty\":\"def\",\"UPPERCASEDPROPERTY\":\"abc\"}", + NamingPojo.class); + assertEquals("ghi", result.CAPS_UNDERSCORE_PROPERTY); + assertEquals("def", result._startingWithUnderscoreProperty); + assertNull(result.upperCasedProperty); + }); } @Test public void testCustom() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyNamingStrategy(propertyName -> propertyName + "_" + propertyName.toUpperCase())); - - String custom = "{\"CAPS_UNDERSCORE_PROPERTY_CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty__STARTINGWITHUNDERSCOREPROPERTY\":\"def\",\"upperCasedProperty_UPPERCASEDPROPERTY\":\"abc\"}"; - assertEquals(custom, jsonb.toJson(pojo)); - NamingPojo result = jsonb.fromJson(custom, NamingPojo.class); - assertResult(result); + testWithJsonbBuilderCreate(new JsonbConfig().withPropertyNamingStrategy(propertyName -> propertyName + "_" + propertyName.toUpperCase()), jsonb -> { + + String custom = + "{\"CAPS_UNDERSCORE_PROPERTY_CAPS_UNDERSCORE_PROPERTY\":\"ghi\",\"_startingWithUnderscoreProperty__STARTINGWITHUNDERSCOREPROPERTY\":\"def\",\"upperCasedProperty_UPPERCASEDPROPERTY\":\"abc\"}"; + assertEquals(custom, jsonb.toJson(pojo)); + NamingPojo result = jsonb.fromJson(custom, NamingPojo.class); + assertResult(result); + }); } private static void assertResult(NamingPojo result) { diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonGeneratorToStructureAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonGeneratorToStructureAdapterTest.java index f9771c64..67a9bc6e 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonGeneratorToStructureAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonGeneratorToStructureAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,6 +12,7 @@ package org.eclipse.yasson.jsonstructure; +import org.eclipse.yasson.Jsonbs; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*; import static org.eclipse.yasson.Jsonbs.*; @@ -24,7 +25,6 @@ import jakarta.json.JsonString; import jakarta.json.JsonStructure; import jakarta.json.JsonValue; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import java.math.BigDecimal; import java.util.ArrayList; @@ -139,15 +139,16 @@ public void testCustomJsonbSerializer() { pojo.setInner(new InnerPojo()); pojo.getInner().setInnerFirst("First value"); pojo.getInner().setInnerSecond("Second value"); - YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create(new JsonbConfig().withSerializers(new InnerPojoSerializer())); - JsonStructure result = jsonb.toJsonStructure(pojo); - assertEquals(JsonValue.ValueType.OBJECT, result.getValueType()); - assertEquals(JsonValue.ValueType.OBJECT, ((JsonObject) result).get("inner").getValueType()); - JsonObject inner = (JsonObject) ((JsonObject) result).get("inner"); - assertEquals(JsonValue.ValueType.STRING, inner.get("first").getValueType()); - assertEquals("First value", ((JsonString) inner.get("first")).getString()); - assertEquals(JsonValue.ValueType.STRING, inner.get("second").getValueType()); - assertEquals("Second value", ((JsonString) inner.get("second")).getString()); + Jsonbs.testWithJsonbBuilderCreate(new JsonbConfig().withSerializers(new InnerPojoSerializer()), jsonb -> { + JsonStructure result = ((YassonJsonb)jsonb).toJsonStructure(pojo); + assertEquals(JsonValue.ValueType.OBJECT, result.getValueType()); + assertEquals(JsonValue.ValueType.OBJECT, ((JsonObject) result).get("inner").getValueType()); + JsonObject inner = (JsonObject) ((JsonObject) result).get("inner"); + assertEquals(JsonValue.ValueType.STRING, inner.get("first").getValueType()); + assertEquals("First value", ((JsonString) inner.get("first")).getString()); + assertEquals(JsonValue.ValueType.STRING, inner.get("second").getValueType()); + assertEquals("Second value", ((JsonString) inner.get("second")).getString()); + }); } private static String getString(JsonValue value) { diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index 8f47d362..1614a27e 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -31,7 +31,6 @@ import jakarta.json.JsonObjectBuilder; import jakarta.json.JsonString; import jakarta.json.JsonValue; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.spi.JsonProvider; import jakarta.json.stream.JsonParser; @@ -292,7 +291,7 @@ public void testObjectsNestedInArraysRaw() { @Test - public void testCustomJsonbDeserializer() throws Exception { + public void testCustomJsonbDeserializer() { JsonObjectBuilder outerBuilder = jsonProvider.createObjectBuilder(); JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); innerBuilder.add("first", "String value 1"); @@ -300,12 +299,12 @@ public void testCustomJsonbDeserializer() throws Exception { outerBuilder.add("inner", innerBuilder.build()); JsonObject object = outerBuilder.build(); - try (YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create(new JsonbConfig().withDeserializers(new InnerPojoDeserializer()))) { - Pojo result = jsonb.fromJsonStructure(object, Pojo.class); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(new InnerPojoDeserializer()), jsonb -> { + Pojo result = ((YassonJsonb)jsonb).fromJsonStructure(object, Pojo.class); assertNotNull(result.getInner()); assertEquals("String value 1", result.getInner().getInnerFirst()); assertEquals("String value 2", result.getInner().getInnerSecond()); - } + }); } @Nested diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToEntriesArraySerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToEntriesArraySerializerTest.java index 3961dd2a..a9a6be55 100644 --- a/src/test/java/org/eclipse/yasson/serializers/MapToEntriesArraySerializerTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/MapToEntriesArraySerializerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,8 @@ package org.eclipse.yasson.serializers; import org.junit.jupiter.api.*; + +import static org.eclipse.yasson.Jsonbs.testWithJsonbBuilderCreate; import static org.junit.jupiter.api.Assertions.*; import java.io.StringReader; @@ -30,8 +32,6 @@ import jakarta.json.JsonArray; import jakarta.json.JsonObject; import jakarta.json.JsonValue; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.serializer.DeserializationContext; import jakarta.json.bind.serializer.JsonbDeserializer; @@ -86,7 +86,7 @@ public int compare(Number n1, Number n2) { * @param source source Map for value verification * @param key Map key used to retrieve value */ - private static final void verifyMapValues(JsonObject jentry, Map source, K key) { + private static void verifyMapValues(JsonObject jentry, Map source, K key) { assertNotNull(jentry); assertNotNull(source); assertNotNull(key); @@ -129,7 +129,7 @@ private static final void verifyMapValues(JsonObject jentry, Map sour * @param jentry parsed Map entry as JsonObject * @param sourceEntry source Map entry for value verification */ - private static final void verifyMapValues(JsonObject jentry, Map.Entry sourceEntry) { + private static void verifyMapValues(JsonObject jentry, Map.Entry sourceEntry) { assertNotNull(jentry); assertNotNull(sourceEntry); switch (jentry.getValue("/value").getValueType()) { @@ -143,7 +143,7 @@ private static final void verifyMapValues(JsonObject jentry, Map.Entry 0); + assertFalse(valueArray.isEmpty()); verifyMapArrayValue(jentry, valueArray, sourceEntry); break; case STRING: @@ -177,7 +177,7 @@ private static final void verifyMapValues(JsonObject jentry, Map.Entry Map.Entry getMapEntryForArrayKey(Map source, K[] key, Comparator cmp, Set keys) { + private static Map.Entry getMapEntryForArrayKey(Map source, K[] key, Comparator cmp, Set keys) { for (Map.Entry entry : source.entrySet()) { K[] sourceKey = entry.getKey(); boolean match = key.length == sourceKey.length; @@ -206,11 +206,11 @@ private static final Map.Entry getMapEntryForArrayKey(Map * @param sourceValue source Map value * @param cmp optional comparator to use for verification */ - private static final void verifyMapArrayValues(V[] value, V[] sourceValue, Comparator cmp) { + private static void verifyMapArrayValues(V[] value, V[] sourceValue, Comparator cmp) { assertEquals(sourceValue.length, value.length); for (int i = 0; i < sourceValue.length; i++) { if (cmp != null) { - assertTrue(cmp.compare(sourceValue[i], value[i]) == 0); + assertEquals(0, cmp.compare(sourceValue[i], value[i])); } else { assertEquals(sourceValue[i], value[i]); } @@ -224,7 +224,7 @@ private static final void verifyMapArrayValues(V[] value, V[] sourceValue, C * @param sourceEntry source Map */ @SuppressWarnings("unchecked") - private static final void verifyMapArrayValue(JsonObject jentry, final JsonArray valueArray, Map.Entry sourceEntry) { + private static void verifyMapArrayValue(JsonObject jentry, final JsonArray valueArray, Map.Entry sourceEntry) { int size = valueArray.size(); // All array elements in the tests are of the same type. switch (valueArray.get(0).getValueType()) { @@ -270,7 +270,7 @@ private static final void verifyMapArrayValue(JsonObject jentry, final Jso * @param source source Map */ @SuppressWarnings("unchecked") - private static final void verifyMapArrayKey(JsonObject jentry, final JsonArray keyArray, Map source, Set keys) { + private static void verifyMapArrayKey(JsonObject jentry, final JsonArray keyArray, Map source, Set keys) { int size = keyArray.size(); // All array elements in the tests are of the same type. switch (keyArray.get(0).getValueType()) { @@ -320,7 +320,7 @@ private static final void verifyMapArrayKey(JsonObject jentry, final JsonA * @param array serialized Map parsed and provided as JsonArray */ @SuppressWarnings("unchecked") - private static final void verifySerialization(Map source, JsonArray array) { + private static void verifySerialization(Map source, JsonArray array) { assertEquals(source.size(), array.size()); Set keys = source.keySet(); array.forEach(entry -> { @@ -337,7 +337,7 @@ private static final void verifySerialization(Map source, JsonArray break; case ARRAY: { JsonArray keyArray = jentry.getJsonArray("key"); - assertTrue(keyArray.size() > 0); + assertFalse(keyArray.isEmpty()); verifyMapArrayKey(jentry, keyArray, source, keys); } break; @@ -375,13 +375,14 @@ private static final void verifySerialization(Map source, JsonArray // @Test // public void testSerializeNumberStringMapToEntriesArray() { // Map map = new TreeMap<>(CMP_NUM); -// Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true)); +// testWithJsonbBuilderCreate(new JsonbConfig().withFormatting(true), jsonb -> { // map.put(Integer.valueOf(12), "twelve"); // map.put(Short.valueOf((short)48), "forty eight"); // map.put(Long.valueOf(256), "two hundred fifty-six"); // String json = jsonb.toJson(map); // JsonArray jarr = Json.createReader(new StringReader(json)).read().asJsonArray(); // verifySerialization(map, jarr); +// }); // } /** @@ -390,14 +391,15 @@ private static final void verifySerialization(Map source, JsonArray @Test public void testSerializePoJoPoJoMapToEntriesArray() { Map map = new HashMap<>(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true)); - map.put(new Trainer("John Smith", 35), new Pokemon("Charmander", "fire", 980)); - map.put(new Trainer("Tom Jones", 24), new Pokemon("Caterpie", "bug", 437)); - map.put(new Trainer("Peter Wright", 27), new Pokemon("Houndour", "dark", 1234)); - map.put(new Trainer("Bob Parker", 19), new Pokemon("Sneasel", "ice", 2051)); - String json = jsonb.toJson(map); - JsonArray jarr = Json.createReader(new StringReader(json)).read().asJsonArray(); - verifySerialization(map, jarr); + testWithJsonbBuilderCreate(new JsonbConfig().withFormatting(true), jsonb -> { + map.put(new Trainer("John Smith", 35), new Pokemon("Charmander", "fire", 980)); + map.put(new Trainer("Tom Jones", 24), new Pokemon("Caterpie", "bug", 437)); + map.put(new Trainer("Peter Wright", 27), new Pokemon("Houndour", "dark", 1234)); + map.put(new Trainer("Bob Parker", 19), new Pokemon("Sneasel", "ice", 2051)); + String json = jsonb.toJson(map); + JsonArray jarr = Json.createReader(new StringReader(json)).read().asJsonArray(); + verifySerialization(map, jarr); + }); } /** @@ -407,12 +409,13 @@ public void testSerializePoJoPoJoMapToEntriesArray() { public void testSerializeSimpleSimpleMapToEntriesArray() { String expected = "{\"false\":true,\"10\":24,\"Name\":\"John Smith\"}"; Map map = new HashMap<>(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - map.put("Name", "John Smith"); - map.put(Integer.valueOf(10), Long.valueOf(24l)); - map.put(Boolean.FALSE, Boolean.TRUE); - String json = jsonb.toJson(map); - assertEquals(expected, json); + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + map.put("Name", "John Smith"); + map.put(10, 24L); + map.put(Boolean.FALSE, Boolean.TRUE); + String json = jsonb.toJson(map); + assertEquals(expected, json); + }); } /** @@ -421,15 +424,16 @@ public void testSerializeSimpleSimpleMapToEntriesArray() { @Test public void testSerializeSimpleArraySimpleArrayMapToEntriesArray() { Map map = new HashMap<>(); - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true)); - map.put(new String[] {"John", "Smith"}, new String[] {"first name", "second name"}); - map.put(new String[] {"Pikachu", "electric"}, new String[] {"pokemon name", "pokemon type"}); - map.put( - new Trainer[] {new Trainer("Bob", 15), new Trainer("Ash", 12)}, - new Pokemon[] {new Pokemon("Charmander", "fire", 1245), new Pokemon("Kyogre", "water", 3056)}); - String json = jsonb.toJson(map); - JsonArray jarr = Json.createReader(new StringReader(json)).read().asJsonArray(); - verifySerialization(map, jarr); + testWithJsonbBuilderCreate(new JsonbConfig().withFormatting(true), jsonb -> { + map.put(new String[] {"John", "Smith"}, new String[] {"first name", "second name"}); + map.put(new String[] {"Pikachu", "electric"}, new String[] {"pokemon name", "pokemon type"}); + map.put( + new Trainer[] {new Trainer("Bob", 15), new Trainer("Ash", 12)}, + new Pokemon[] {new Pokemon("Charmander", "fire", 1245), new Pokemon("Kyogre", "water", 3056)}); + String json = jsonb.toJson(map); + JsonArray jarr = Json.createReader(new StringReader(json)).read().asJsonArray(); + verifySerialization(map, jarr); + }); } /** @@ -453,34 +457,35 @@ public void testDeSerializePrimitivesMapToEntriesArray() { " \"value\": 21" + " }" + "]"; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - Map map = jsonb.fromJson(jsonString, Map.class); - assertEquals(3, map.size()); - // Make sure that all 3 pokemons were checked. - int valueCheck = 0x00; - for (Map.Entry entry : map.entrySet()) { - if ((entry.getKey() instanceof String) && "first".equals(entry.getKey())) { - assertEquals("Peter Parker", entry.getValue()); - valueCheck |= 0x01; - } - if ((entry.getKey() instanceof Number) && entry.getKey().equals(new BigDecimal(42))) { - assertEquals(true, entry.getValue()); - valueCheck |= 0x02; - } - if ((entry.getKey() instanceof Boolean) && entry.getKey().equals(false)) { - assertEquals(new BigDecimal(21), entry.getValue()); - valueCheck |= 0x04; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + Map map = jsonb.fromJson(jsonString, Map.class); + assertEquals(3, map.size()); + // Make sure that all 3 pokemons were checked. + int valueCheck = 0x00; + for (Map.Entry entry : map.entrySet()) { + if ((entry.getKey() instanceof String) && "first".equals(entry.getKey())) { + assertEquals("Peter Parker", entry.getValue()); + valueCheck |= 0x01; + } + if ((entry.getKey() instanceof Number) && entry.getKey().equals(new BigDecimal(42))) { + assertEquals(true, entry.getValue()); + valueCheck |= 0x02; + } + if ((entry.getKey() instanceof Boolean) && entry.getKey().equals(false)) { + assertEquals(new BigDecimal(21), entry.getValue()); + valueCheck |= 0x04; + } } - } - if ((valueCheck & 0x01) == 0) { - fail("Did not find key \"first\" in the Map"); - } - if ((valueCheck & 0x02) == 0) { - fail("Did not find key 42 in the Map"); - } - if ((valueCheck & 0x04) == 0) { - fail("Did not find key false in the Map"); - } + if ((valueCheck & 0x01) == 0) { + fail("Did not find key \"first\" in the Map"); + } + if ((valueCheck & 0x02) == 0) { + fail("Did not find key 42 in the Map"); + } + if ((valueCheck & 0x04) == 0) { + fail("Did not find key false in the Map"); + } + }); } /** @@ -531,41 +536,42 @@ public Type getOwnerType() { return null; } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - Map map = jsonb.fromJson(jsonString, pt); - assertEquals(3, map.size()); - // Make sure that all 3 pokemons were checked. - int valueCheck = 0x00; - for (Map.Entry entry : map.entrySet()) { - Pokemon pokemon = entry.getValue(); - if ("Pikachu".equals(entry.getKey())) { - assertEquals("Pikachu", pokemon.name); - assertEquals("electric", pokemon.type); - assertEquals(456, pokemon.cp); - valueCheck |= 0x01; - } - if ("Squirtle".equals(entry.getKey())) { - assertEquals("Squirtle", pokemon.name); - assertEquals("water", pokemon.type); - assertEquals(124, pokemon.cp); - valueCheck |= 0x02; - } - if ("Rayquaza".equals(entry.getKey())) { - assertEquals("Rayquaza", pokemon.name); - assertEquals("dragon", pokemon.type); - assertEquals(3273, pokemon.cp); - valueCheck |= 0x04; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + Map map = jsonb.fromJson(jsonString, pt); + assertEquals(3, map.size()); + // Make sure that all 3 pokemons were checked. + int valueCheck = 0x00; + for (Map.Entry entry : map.entrySet()) { + Pokemon pokemon = entry.getValue(); + if ("Pikachu".equals(entry.getKey())) { + assertEquals("Pikachu", pokemon.name); + assertEquals("electric", pokemon.type); + assertEquals(456, pokemon.cp); + valueCheck |= 0x01; + } + if ("Squirtle".equals(entry.getKey())) { + assertEquals("Squirtle", pokemon.name); + assertEquals("water", pokemon.type); + assertEquals(124, pokemon.cp); + valueCheck |= 0x02; + } + if ("Rayquaza".equals(entry.getKey())) { + assertEquals("Rayquaza", pokemon.name); + assertEquals("dragon", pokemon.type); + assertEquals(3273, pokemon.cp); + valueCheck |= 0x04; + } } - } - if ((valueCheck & 0x01) == 0) { - fail("Did not find key \"Pikachu\" in the Map"); - } - if ((valueCheck & 0x02) == 0) { - fail("Did not find key \"Squirtle\" in the Map"); - } - if ((valueCheck & 0x04) == 0) { - fail("Did not find key \"Rayquaza\" in the Map"); - } + if ((valueCheck & 0x01) == 0) { + fail("Did not find key \"Pikachu\" in the Map"); + } + if ((valueCheck & 0x02) == 0) { + fail("Did not find key \"Squirtle\" in the Map"); + } + if ((valueCheck & 0x04) == 0) { + fail("Did not find key \"Rayquaza\" in the Map"); + } + }); } /** @@ -624,45 +630,46 @@ public Type getOwnerType() { return null; } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - Map map = jsonb.fromJson(jsonString, pt); - assertEquals(3, map.size()); - // Make sure that all 3 pokemons were checked. - int valueCheck = 0x00; - for (Map.Entry entry : map.entrySet()) { - Trainer trainer = entry.getKey(); - Pokemon pokemon = entry.getValue(); - if ("Bob".equals(trainer.name)) { - assertEquals(12, trainer.age); - assertEquals("Pikachu", pokemon.name); - assertEquals("electric", pokemon.type); - assertEquals(456, pokemon.cp); - valueCheck |= 0x01; - } - if ("Ash".equals(trainer.name)) { - assertEquals(10, trainer.age); - assertEquals("Squirtle", pokemon.name); - assertEquals("water", pokemon.type); - assertEquals(124, pokemon.cp); - valueCheck |= 0x02; - } - if ("Joe".equals(trainer.name)) { - assertEquals(15, trainer.age); - assertEquals("Rayquaza", pokemon.name); - assertEquals("dragon", pokemon.type); - assertEquals(3273, pokemon.cp); - valueCheck |= 0x04; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + Map map = jsonb.fromJson(jsonString, pt); + assertEquals(3, map.size()); + // Make sure that all 3 pokemons were checked. + int valueCheck = 0x00; + for (Map.Entry entry : map.entrySet()) { + Trainer trainer = entry.getKey(); + Pokemon pokemon = entry.getValue(); + if ("Bob".equals(trainer.name)) { + assertEquals(12, trainer.age); + assertEquals("Pikachu", pokemon.name); + assertEquals("electric", pokemon.type); + assertEquals(456, pokemon.cp); + valueCheck |= 0x01; + } + if ("Ash".equals(trainer.name)) { + assertEquals(10, trainer.age); + assertEquals("Squirtle", pokemon.name); + assertEquals("water", pokemon.type); + assertEquals(124, pokemon.cp); + valueCheck |= 0x02; + } + if ("Joe".equals(trainer.name)) { + assertEquals(15, trainer.age); + assertEquals("Rayquaza", pokemon.name); + assertEquals("dragon", pokemon.type); + assertEquals(3273, pokemon.cp); + valueCheck |= 0x04; + } } - } - if ((valueCheck & 0x01) == 0) { - fail("Did not find key \"Bob\" in the Map"); - } - if ((valueCheck & 0x02) == 0) { - fail("Did not find key \"Ash\" in the Map"); - } - if ((valueCheck & 0x04) == 0) { - fail("Did not find key \"Joe\" in the Map"); - } + if ((valueCheck & 0x01) == 0) { + fail("Did not find key \"Bob\" in the Map"); + } + if ((valueCheck & 0x02) == 0) { + fail("Did not find key \"Ash\" in the Map"); + } + if ((valueCheck & 0x04) == 0) { + fail("Did not find key \"Joe\" in the Map"); + } + }); } /** @@ -703,31 +710,32 @@ public Type getOwnerType() { return null; } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - Map map = jsonb.fromJson(jsonString, pt); - assertEquals(2, map.size()); - // Make sure that all map entries were checked. - int valueCheck = 0x00; - for (Map.Entry entry : map.entrySet()) { - Integer[] key = entry.getKey(); - String[] value = entry.getValue(); - if (key[0] == 1 && key[1] == 2) { - assertEquals("Bob" ,value[0]); - assertEquals("Tom" ,value[1]); - valueCheck |= 0x01; - } - if (key[0] == 3 && key[1] == 4) { - assertEquals("John" ,value[0]); - assertEquals("Greg" ,value[1]); - valueCheck |= 0x02; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + Map map = jsonb.fromJson(jsonString, pt); + assertEquals(2, map.size()); + // Make sure that all map entries were checked. + int valueCheck = 0x00; + for (Map.Entry entry : map.entrySet()) { + Integer[] key = entry.getKey(); + String[] value = entry.getValue(); + if (key[0] == 1 && key[1] == 2) { + assertEquals("Bob", value[0]); + assertEquals("Tom", value[1]); + valueCheck |= 0x01; + } + if (key[0] == 3 && key[1] == 4) { + assertEquals("John", value[0]); + assertEquals("Greg", value[1]); + valueCheck |= 0x02; + } } - } - if ((valueCheck & 0x01) == 0) { - fail("Did not find key [1,2] in the Map"); - } - if ((valueCheck & 0x02) == 0) { - fail("Did not find key [3,4] in the Map"); - } + if ((valueCheck & 0x01) == 0) { + fail("Did not find key [1,2] in the Map"); + } + if ((valueCheck & 0x02) == 0) { + fail("Did not find key [3,4] in the Map"); + } + }); } /** @@ -797,42 +805,43 @@ public Type getOwnerType() { return null; } }; - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()); - Map map = jsonb.fromJson(jsonString, pt); - assertEquals(2, map.size()); - int valueCheck = 0x00; - for (Map.Entry entry : map.entrySet()) { - Trainer[] key = entry.getKey(); - Pokemon[] value = entry.getValue(); - if (key[0].name.equals("Ash") && key[1].name.equals("Joe")) { - assertEquals(12, key[0].age); - assertEquals(14, key[1].age); - assertEquals("Rayquaza", value[0].name); - assertEquals("dragon", value[0].type); - assertEquals(3273, value[0].cp); - assertEquals("Tyranitar", value[1].name); - assertEquals("dark", value[1].type); - assertEquals(3181, value[1].cp); - valueCheck |= 0x01; - } - if (key[0].name.equals("Bob") && key[1].name.equals("Maggie")) { - assertEquals(13, key[0].age); - assertEquals(15, key[1].age); - assertEquals("Raikou", value[0].name); - assertEquals("electric", value[0].type); - assertEquals(3095, value[0].cp); - assertEquals("Mamoswine", value[1].name); - assertEquals("ice", value[1].type); - assertEquals(3055, value[1].cp); - valueCheck |= 0x02; + testWithJsonbBuilderCreate(new JsonbConfig(), jsonb -> { + Map map = jsonb.fromJson(jsonString, pt); + assertEquals(2, map.size()); + int valueCheck = 0x00; + for (Map.Entry entry : map.entrySet()) { + Trainer[] key = entry.getKey(); + Pokemon[] value = entry.getValue(); + if (key[0].name.equals("Ash") && key[1].name.equals("Joe")) { + assertEquals(12, key[0].age); + assertEquals(14, key[1].age); + assertEquals("Rayquaza", value[0].name); + assertEquals("dragon", value[0].type); + assertEquals(3273, value[0].cp); + assertEquals("Tyranitar", value[1].name); + assertEquals("dark", value[1].type); + assertEquals(3181, value[1].cp); + valueCheck |= 0x01; + } + if (key[0].name.equals("Bob") && key[1].name.equals("Maggie")) { + assertEquals(13, key[0].age); + assertEquals(15, key[1].age); + assertEquals("Raikou", value[0].name); + assertEquals("electric", value[0].type); + assertEquals(3095, value[0].cp); + assertEquals("Mamoswine", value[1].name); + assertEquals("ice", value[1].type); + assertEquals(3055, value[1].cp); + valueCheck |= 0x02; + } } - } - if ((valueCheck & 0x01) == 0) { - fail("Did not find key with \"Ash\" and \"Joe\" in the Map"); - } - if ((valueCheck & 0x02) == 0) { - fail("Did not find key with \"Bob\" and \"Maggie\" in the Map"); - } + if ((valueCheck & 0x01) == 0) { + fail("Did not find key with \"Ash\" and \"Joe\" in the Map"); + } + if ((valueCheck & 0x02) == 0) { + fail("Did not find key with \"Bob\" and \"Maggie\" in the Map"); + } + }); } public static class LocaleSerializer implements JsonbSerializer { @@ -890,7 +899,7 @@ public String toString() { } } - public static class MapObjectLocaleString extends MapObject {}; + public static class MapObjectLocaleString extends MapObject {} private void verifyMapObjectLocaleStringSerialization(JsonObject jsonObject, MapObjectLocaleString mapObject) { // Expected serialization is: {"values":[{"key":"lang-tag","value":"string"},...]} @@ -918,20 +927,21 @@ private void verifyMapObjectLocaleStringSerialization(JsonObject jsonObject, Map */ @Test public void testMapLocaleString() { - Jsonb jsonb = JsonbBuilder.create(new JsonbConfig() + testWithJsonbBuilderCreate(new JsonbConfig() .withSerializers(new LocaleSerializer()) - .withDeserializers(new LocaleDeserializer())); + .withDeserializers(new LocaleDeserializer()), jsonb -> { - MapObjectLocaleString mapObject = new MapObjectLocaleString(); - mapObject.getValues().put(Locale.US, "us"); - mapObject.getValues().put(Locale.ENGLISH, "en"); - mapObject.getValues().put(Locale.JAPAN, "jp"); + MapObjectLocaleString mapObject = new MapObjectLocaleString(); + mapObject.getValues().put(Locale.US, "us"); + mapObject.getValues().put(Locale.ENGLISH, "en"); + mapObject.getValues().put(Locale.JAPAN, "jp"); - String json = jsonb.toJson(mapObject); - JsonObject jsonObject = Json.createReader(new StringReader(json)).read().asJsonObject(); - verifyMapObjectLocaleStringSerialization(jsonObject, mapObject); + String json = jsonb.toJson(mapObject); + JsonObject jsonObject = Json.createReader(new StringReader(json)).read().asJsonObject(); + verifyMapObjectLocaleStringSerialization(jsonObject, mapObject); - MapObjectLocaleString resObject = jsonb.fromJson(json, MapObjectLocaleString.class); - assertEquals(mapObject, resObject); + MapObjectLocaleString resObject = jsonb.fromJson(json, MapObjectLocaleString.class); + assertEquals(mapObject, resObject); + }); } } From fe4afe0194d6934cc46ad47e89c4f17355b36546 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 10:07:40 +0100 Subject: [PATCH 45/68] [#627]Reduced Exception to IOException(which is really thrown here), so there would be less of "auto-close" warnings Signed-off-by: Anton Pinsky --- src/main/java/org/eclipse/yasson/YassonJsonb.java | 12 +++++++++++- .../org/eclipse/yasson/internal/JsonBinding.java | 6 +++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/YassonJsonb.java b/src/main/java/org/eclipse/yasson/YassonJsonb.java index f484300f..3a870317 100644 --- a/src/main/java/org/eclipse/yasson/YassonJsonb.java +++ b/src/main/java/org/eclipse/yasson/YassonJsonb.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,6 +12,7 @@ package org.eclipse.yasson; +import java.io.IOException; import java.lang.reflect.Type; import jakarta.json.JsonStructure; @@ -131,4 +132,13 @@ public interface YassonJsonb extends jakarta.json.bind.Jsonb { * @since JSON Binding 1.0 */ JsonStructure toJsonStructure(Object object, Type runtimeType) throws JsonbException; + + /** + * Closes this Jsonb instance and releases any system resources associated. + * See @{@link jakarta.json.bind.Jsonb} and @{@link jakarta.json.bind.Jsonb#close()} for more details on closing. + * + * @throws IOException if an I/O error occurs; reducing from @{@link Exception} in @{@link AutoCloseable}. + */ + @Override + void close() throws IOException; } diff --git a/src/main/java/org/eclipse/yasson/internal/JsonBinding.java b/src/main/java/org/eclipse/yasson/internal/JsonBinding.java index c994a0f5..5b768af8 100644 --- a/src/main/java/org/eclipse/yasson/internal/JsonBinding.java +++ b/src/main/java/org/eclipse/yasson/internal/JsonBinding.java @@ -12,6 +12,7 @@ package org.eclipse.yasson.internal; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; @@ -213,8 +214,7 @@ private JsonGenerator streamGenerator(OutputStream stream) { } @Override - public void close() throws Exception { + public void close() throws IOException { jsonbContext.getComponentInstanceCreator().close(); } - -} +} \ No newline at end of file From a2966bb1d49f1040e5d294a675122747c211e73b Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 10:12:17 +0100 Subject: [PATCH 46/68] [#627]Created default constructors, so we would have fewer warnings from module system Signed-off-by: Anton Pinsky --- .../eclipse/yasson/FieldAccessStrategy.java | 6 +++- .../eclipse/yasson/JsonBindingProvider.java | 5 ++- .../java/org/eclipse/yasson/YassonConfig.java | 5 ++- .../java/org/eclipse/yasson/Assertions.java | 13 +++++--- .../yasson/DefaultGetterInInterface.java | 32 +++++++++++++++---- .../yasson/FieldAccessStrategyTest.java | 16 ++++++++++ .../java/org/eclipse/yasson/Issue454Test.java | 11 +++++++ .../java/org/eclipse/yasson/Issue456Test.java | 6 ++++ .../yasson/JavaxNamingExcludedTest.java | 9 +++++- .../java/org/eclipse/yasson/SimpleTest.java | 8 ++++- .../org/eclipse/yasson/TestTypeToken.java | 6 +++- .../org/eclipse/yasson/YassonConfigTest.java | 7 ++-- 12 files changed, 103 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/FieldAccessStrategy.java b/src/main/java/org/eclipse/yasson/FieldAccessStrategy.java index 1ce711ff..68db366d 100644 --- a/src/main/java/org/eclipse/yasson/FieldAccessStrategy.java +++ b/src/main/java/org/eclipse/yasson/FieldAccessStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023 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 @@ -28,6 +28,10 @@ * when SecurityManager is turned on.

*/ public class FieldAccessStrategy implements PropertyVisibilityStrategy { + + FieldAccessStrategy() { + } + @Override public boolean isVisible(Field field) { return true; diff --git a/src/main/java/org/eclipse/yasson/JsonBindingProvider.java b/src/main/java/org/eclipse/yasson/JsonBindingProvider.java index 3e4f4d40..f7aa7e23 100644 --- a/src/main/java/org/eclipse/yasson/JsonBindingProvider.java +++ b/src/main/java/org/eclipse/yasson/JsonBindingProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 @@ -22,6 +22,9 @@ */ public class JsonBindingProvider extends JsonbProvider { + public JsonBindingProvider() { + } + @Override public JsonbBuilder create() { return new JsonBindingBuilder(); diff --git a/src/main/java/org/eclipse/yasson/YassonConfig.java b/src/main/java/org/eclipse/yasson/YassonConfig.java index 9387eeab..d0a14535 100644 --- a/src/main/java/org/eclipse/yasson/YassonConfig.java +++ b/src/main/java/org/eclipse/yasson/YassonConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 IBM and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -21,6 +21,9 @@ * Custom properties for configuring Yasson outside of the specification {@link jakarta.json.bind.JsonbConfig} scope. */ public class YassonConfig extends JsonbConfig { + + public YassonConfig() { + } /** * @see #withFailOnUnknownProperties(boolean) diff --git a/src/test/java/org/eclipse/yasson/Assertions.java b/src/test/java/org/eclipse/yasson/Assertions.java index 8b23d7cb..aee564a7 100644 --- a/src/test/java/org/eclipse/yasson/Assertions.java +++ b/src/test/java/org/eclipse/yasson/Assertions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -20,6 +20,9 @@ import jakarta.json.bind.JsonbException; public class Assertions { + + private Assertions() { + } /** * Asserts that the given operation will fail with a JsonbException @@ -58,13 +61,13 @@ public static void shouldFail(Supplier operation, Class operation.get(); fail("The operation should have failed with a " + expectedType.getCanonicalName() + " but it succeeded."); } catch (Throwable t) { - String fullErrorMessage = ""; + StringBuilder fullErrorMessage = new StringBuilder(); for (Throwable current = t; current != null && current.getCause() != current; current = current.getCause()) { - fullErrorMessage += current.getClass().getCanonicalName() + ": "; - fullErrorMessage += current.getMessage() + "\n"; + fullErrorMessage.append(current.getClass().getCanonicalName()).append(": "); + fullErrorMessage.append(current.getMessage()).append("\n"); } if (expectedType.isAssignableFrom(t.getClass())) { - if (!checkExceptionMessage.apply(fullErrorMessage)) { + if (!checkExceptionMessage.apply(fullErrorMessage.toString())) { t.printStackTrace(); fail("Exception did not contain the proper content: " + fullErrorMessage); } diff --git a/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java b/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java index 9b5954ed..75dda715 100644 --- a/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java +++ b/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -29,14 +29,19 @@ */ public class DefaultGetterInInterface { - public static interface Defaulted { + private DefaultGetterInInterface() { + } + + public interface Defaulted { - default public String getGetterA() { + default String getGetterA() { return "valueA"; } } public static class PojoWithDefault implements Defaulted { + protected PojoWithDefault() { + } } @Test @@ -46,13 +51,13 @@ public void testWithDefault() { assertEquals("{\"getterA\":\"valueA\"}", result); } - public static interface WithGetterI { + public interface WithGetterI { @JsonbProperty("withGetterI") String getGetterI(); } - public static interface WithDefaultGetterI extends WithGetterI { + public interface WithDefaultGetterI extends WithGetterI { @Override @JsonbProperty("default") @@ -61,7 +66,7 @@ default String getGetterI() { } } - public static interface OtherWithDefaultGetterI extends WithGetterI { + public interface OtherWithDefaultGetterI extends WithGetterI { @Override @JsonbProperty("otherDefault") @@ -72,6 +77,9 @@ default String getGetterI() { public static class Pojo implements WithGetterI { + protected Pojo() { + } + @Override @JsonbProperty("implementation") public String getGetterI() { @@ -82,6 +90,9 @@ public String getGetterI() { public static class PojoNoAnnotation implements WithGetterI { + protected PojoNoAnnotation() { + } + @Override public String getGetterI() { return "withGetterI"; @@ -89,10 +100,15 @@ public String getGetterI() { } public static class PojoWithDefaultSuperImplementation extends Pojo implements WithDefaultGetterI { + protected PojoWithDefaultSuperImplementation() { + } } public static class PojoWithDefaultImplementation implements WithDefaultGetterI { + protected PojoWithDefaultImplementation() { + } + @Override @JsonbProperty("defaultImplementation") public String getGetterI() { @@ -102,9 +118,13 @@ public String getGetterI() { } public static class PojoWithDefaultOnly implements WithDefaultGetterI { + protected PojoWithDefaultOnly() { + } } public static class PojoGetterDefaultedTwice extends PojoWithDefaultImplementation implements OtherWithDefaultGetterI { + protected PojoGetterDefaultedTwice() { + } } @Test diff --git a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java index 725bd60c..5f8f5f01 100644 --- a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java +++ b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java @@ -23,6 +23,9 @@ public class FieldAccessStrategyTest { + private FieldAccessStrategyTest() { + } + public static class PrivateFields { private String strField; @JsonbTransient @@ -49,6 +52,10 @@ public void setStrField(String strField) { } public static class PublicFields { + + protected PublicFields() { + } + public String strField; } @@ -109,6 +116,9 @@ public void testCustomVisibityStrategy() { } public static class CustomVisibilityStrategy implements PropertyVisibilityStrategy { + public CustomVisibilityStrategy() { + } + @Override public boolean isVisible(Field field) { return field.getName().equals("stringInstance"); @@ -121,6 +131,9 @@ public boolean isVisible(Method method) { } public static class SimpleContainer { + protected SimpleContainer() { + } + private String stringInstance; private Integer integerInstance; private Float floatInstance; @@ -153,6 +166,9 @@ public void setFloatInstance(float floatInstance) { private static final class NoAccessStrategy implements PropertyVisibilityStrategy { + public NoAccessStrategy() { + } + @Override public boolean isVisible(Field field) { return false; diff --git a/src/test/java/org/eclipse/yasson/Issue454Test.java b/src/test/java/org/eclipse/yasson/Issue454Test.java index c518d999..8ba0cd04 100644 --- a/src/test/java/org/eclipse/yasson/Issue454Test.java +++ b/src/test/java/org/eclipse/yasson/Issue454Test.java @@ -22,6 +22,9 @@ public class Issue454Test { + private Issue454Test() { + } + @Test public void test() { final String EXPECTED = "{\"field2\":\"bbb\"}"; @@ -56,6 +59,10 @@ public String getField2() { } public static abstract class TheClass { + + private TheClass() { + } + @JsonbTransient public abstract String getField1(); @@ -63,6 +70,10 @@ public static abstract class TheClass { } public static class TheClass2 extends TheClass { + + private TheClass2() { + } + @Override public String getField1() { return "aaa"; diff --git a/src/test/java/org/eclipse/yasson/Issue456Test.java b/src/test/java/org/eclipse/yasson/Issue456Test.java index 52b603c0..3adc9991 100644 --- a/src/test/java/org/eclipse/yasson/Issue456Test.java +++ b/src/test/java/org/eclipse/yasson/Issue456Test.java @@ -21,6 +21,9 @@ public class Issue456Test { + private Issue456Test() { + } + @Test public void dontInvokeToString() { try { @@ -33,6 +36,9 @@ public void dontInvokeToString() { public static class Example { + protected Example() { + } + public String getProperty() { throw new RuntimeException("some error"); } diff --git a/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java b/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java index dac6960d..c5665c2c 100644 --- a/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java +++ b/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 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 @@ -27,6 +27,9 @@ */ public class JavaxNamingExcludedTest { + private JavaxNamingExcludedTest() { + } + @Test public void testNoJavaxNamingModule() { try { @@ -42,6 +45,10 @@ public void testNoJavaxNamingModule() { } public static final class AdaptedPojo { + + private AdaptedPojo() { + } + @JsonbTypeAdapter(NonCdiAdapter.class) public String adaptedValue1 = "1111"; diff --git a/src/test/java/org/eclipse/yasson/SimpleTest.java b/src/test/java/org/eclipse/yasson/SimpleTest.java index ca11319f..5a4ed0b4 100644 --- a/src/test/java/org/eclipse/yasson/SimpleTest.java +++ b/src/test/java/org/eclipse/yasson/SimpleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023 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 @@ -23,6 +23,9 @@ */ public class SimpleTest { + private SimpleTest() { + } + @Test public void testSimpleSerialize() { final StringWrapper wrapper = new StringWrapper(); @@ -39,6 +42,9 @@ public void testSimpleDeserializer() { public static class StringWrapper { + protected StringWrapper() { + } + public String value; public String getValue() { diff --git a/src/test/java/org/eclipse/yasson/TestTypeToken.java b/src/test/java/org/eclipse/yasson/TestTypeToken.java index 6c6c458d..621a545a 100644 --- a/src/test/java/org/eclipse/yasson/TestTypeToken.java +++ b/src/test/java/org/eclipse/yasson/TestTypeToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -19,6 +19,10 @@ * @author Roman Grigoriadi */ public abstract class TestTypeToken { + + protected TestTypeToken() { + } + public Type getType() { return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } diff --git a/src/test/java/org/eclipse/yasson/YassonConfigTest.java b/src/test/java/org/eclipse/yasson/YassonConfigTest.java index fc5eb0f8..a6bbef60 100644 --- a/src/test/java/org/eclipse/yasson/YassonConfigTest.java +++ b/src/test/java/org/eclipse/yasson/YassonConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -14,9 +14,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; - import org.junit.jupiter.api.Test; /** @@ -24,6 +21,8 @@ */ public class YassonConfigTest { + private YassonConfigTest() {} + @SuppressWarnings("deprecation") @Test public void testFailOnUnknownPropertiesUnchanged() { From 0d25125f365f982615c82a826a821ab554347b41 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 10:17:22 +0100 Subject: [PATCH 47/68] [#627]Created better way for Java 16 multi-release Signed-off-by: Anton Pinsky --- pom.xml | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index ff065b51..0d6166a8 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 3.0.0 4.0.1 JDK_9 - 5.10.0 + 5.10.1 @@ -119,7 +119,7 @@ Oracle Corporation - http://www.oracle.com/ + https://www.oracle.com/ @@ -140,13 +140,13 @@ Eclipse Public License v. 2.0 - http://www.eclipse.org/legal/epl-v20.html + https://www.eclipse.org/legal/epl-v20.html repo Standard Eclipse License Eclipse Distribution License v. 1.0 - http://www.eclipse.org/org/documents/edl-v10.php + https://www.eclipse.org/org/documents/edl-v10.php repo Standard Eclipse Distribution License @@ -260,6 +260,41 @@ + + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + + + add-test-source + generate-test-sources + + add-test-source + + + + ${project.basedir}/src/test/java + ${project.basedir}/src/test/java16 + + + + + + org.apache.maven.plugins maven-compiler-plugin @@ -269,10 +304,6 @@ default-testCompile 16 - - ${project.basedir}/src/test/java - ${project.basedir}/src/test/java16 - @@ -365,7 +396,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.2.1 + 3.2.2 org.apache.maven.plugins @@ -447,7 +478,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.0 + 3.6.2 Yasson ${basedir}/src/main/java/org/eclipse/yasson @@ -511,7 +542,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.1 + 3.2.2 default-test From 029e5bc45fb22ad2f05ec259f2cb08dc067e91c8 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 11:49:55 +0100 Subject: [PATCH 48/68] [#627]Add missing serialVersionUID Signed-off-by: Anton Pinsky --- .../org/eclipse/yasson/internal/model/ReverseTreeMap.java | 2 ++ .../eclipse/yasson/adapters/model/MultilevelAdapterClass.java | 3 ++- .../org/eclipse/yasson/adapters/model/UUIDMapperClsBased.java | 4 +++- .../org/eclipse/yasson/adapters/model/UUIDMapperIfcBased.java | 4 +++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java b/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java index e6608e9e..8f40b395 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java +++ b/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java @@ -23,6 +23,8 @@ */ public class ReverseTreeMap, V> extends TreeMap { + private static final long serialVersionUID = 1L; + /** * Default constructor of a TreeMap with reverse order. */ diff --git a/src/test/java/org/eclipse/yasson/adapters/model/MultilevelAdapterClass.java b/src/test/java/org/eclipse/yasson/adapters/model/MultilevelAdapterClass.java index 70a6211f..1a91bfac 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/MultilevelAdapterClass.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/MultilevelAdapterClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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,4 +13,5 @@ package org.eclipse.yasson.adapters.model; public abstract class MultilevelAdapterClass implements MultiinterfaceAdapter { + private static final long serialVersionUID = 1L; } diff --git a/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperClsBased.java b/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperClsBased.java index cc7a4e5a..1b42bd67 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperClsBased.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperClsBased.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -17,6 +17,8 @@ public class UUIDMapperClsBased extends MultilevelAdapterClass { + private static final long serialVersionUID = 1L; + @Override public String adaptToJson(UUID obj) throws Exception { return Optional.ofNullable(obj).map(UUID::toString).orElse(null); diff --git a/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperIfcBased.java b/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperIfcBased.java index 62e99d8c..e35bf6c4 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperIfcBased.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/UUIDMapperIfcBased.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 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 @@ -17,6 +17,8 @@ public class UUIDMapperIfcBased implements MultiinterfaceAdapter { + private static final long serialVersionUID = 1L; + @Override public String adaptToJson(UUID obj) throws Exception { return Optional.ofNullable(obj).map(UUID::toString).orElse(null); From 2d875ef2f635412cb1d33f8968f24fb68f339288 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 11:54:07 +0100 Subject: [PATCH 49/68] [#627]SuppressWarnings on checks in Enum tests Signed-off-by: Anton Pinsky --- .../yasson/adapters/model/EnumWithJsonbPropertyAdapter.java | 4 +++- .../serializers/model/EnumWithJsonbPropertyDeserializer.java | 4 +++- .../serializers/model/EnumWithJsonbPropertySerializer.java | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java index 6197b78c..32c077c5 100644 --- a/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java +++ b/src/test/java/org/eclipse/yasson/adapters/model/EnumWithJsonbPropertyAdapter.java @@ -51,9 +51,11 @@ public EnumWithJsonbPropertyAdapter() { } private Class getEnumType() { - return Class.class.cast(ParameterizedType.class.cast( + @SuppressWarnings("unchecked") + Class cast = Class.class.cast(ParameterizedType.class.cast( getClass().getGenericSuperclass()) .getActualTypeArguments()[0]); + return cast; } @Override diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java index caf0342c..39575fd8 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertyDeserializer.java @@ -52,9 +52,11 @@ public EnumWithJsonbPropertyDeserializer() { } private Class getEnumType() { - return Class.class.cast(ParameterizedType.class.cast( + @SuppressWarnings("unchecked") + Class cast = Class.class.cast(ParameterizedType.class.cast( getClass().getGenericSuperclass()) .getActualTypeArguments()[0]); + return cast; } @Override diff --git a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java index 5204bd49..595ee049 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/EnumWithJsonbPropertySerializer.java @@ -49,9 +49,11 @@ public EnumWithJsonbPropertySerializer() { } private Class getEnumType() { - return Class.class.cast(ParameterizedType.class.cast( + @SuppressWarnings("unchecked") + Class cast = Class.class.cast(ParameterizedType.class.cast( getClass().getGenericSuperclass()) .getActualTypeArguments()[0]); + return cast; } @Override public void serialize(E obj, JsonGenerator generator, SerializationContext ctx) { From ee22e55db8e759574bd47d566ee594db3131a0d7 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 11:58:52 +0100 Subject: [PATCH 50/68] [#627]Forgot the copyright Signed-off-by: Anton Pinsky --- .../java/org/eclipse/yasson/internal/model/ReverseTreeMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java b/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java index 8f40b395..db546e89 100644 --- a/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java +++ b/src/main/java/org/eclipse/yasson/internal/model/ReverseTreeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023 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 From b5be7353686c6423a5064ce7141fa3b5e30a947d Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 12:18:09 +0100 Subject: [PATCH 51/68] [#627]Some missing deprications Signed-off-by: Anton Pinsky --- .../org/eclipse/yasson/YassonProperties.java | 16 ++++++++++------ .../yasson/internal/AnnotationIntrospector.java | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/YassonProperties.java b/src/main/java/org/eclipse/yasson/YassonProperties.java index d1a98792..cb782b1b 100644 --- a/src/main/java/org/eclipse/yasson/YassonProperties.java +++ b/src/main/java/org/eclipse/yasson/YassonProperties.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2019, 2020 Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023 Payara Foundation 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 @@ -24,27 +24,31 @@ private YassonProperties() { } /** - * @deprecated + * @deprecated Use {@link YassonConfig#FAIL_ON_UNKNOWN_PROPERTIES} instead * @see YassonConfig#withFailOnUnknownProperties(boolean) */ + @Deprecated public static final String FAIL_ON_UNKNOWN_PROPERTIES = YassonConfig.FAIL_ON_UNKNOWN_PROPERTIES; /** - * @deprecated + * @deprecated Use {@link YassonConfig#USER_TYPE_MAPPING} instead * @see YassonConfig#withUserTypeMapping(java.util.Map) */ + @Deprecated public static final String USER_TYPE_MAPPING = YassonConfig.USER_TYPE_MAPPING; /** - * @deprecated + * @deprecated Use {@link YassonConfig#ZERO_TIME_PARSE_DEFAULTING} instead * @see YassonConfig#withZeroTimeParseDefaulting(boolean) */ + @Deprecated public static final String ZERO_TIME_PARSE_DEFAULTING = YassonConfig.ZERO_TIME_PARSE_DEFAULTING; /** - * @deprecated + * @deprecated Use {@link YassonConfig#NULL_ROOT_SERIALIZER} instead * @see YassonConfig#withNullRootSerializer(jakarta.json.bind.serializer.JsonbSerializer) */ + @Deprecated public static final String NULL_ROOT_SERIALIZER = YassonConfig.NULL_ROOT_SERIALIZER; } diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java index 5d9f01f8..542374a3 100644 --- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java +++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java @@ -384,7 +384,9 @@ public Optional isPropertyNillable(Property property) { return nillable.map(JsonbNillable::value); } final Optional jsonbProperty = getAnnotationFromProperty(JsonbProperty.class, property); - return jsonbProperty.map(JsonbProperty::nillable); + @SuppressWarnings("deprecation") + Optional optionalBoolean = jsonbProperty.map(JsonbProperty::nillable); + return optionalBoolean; } From 795b5db30ddb99af2cce8447da79bce3a1e914c9 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 13:00:09 +0100 Subject: [PATCH 52/68] [#627]Test classes don't need to be public - fewer warnings about modules Signed-off-by: Anton Pinsky --- src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java | 2 +- src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java | 2 +- src/test/java/org/eclipse/yasson/Issue454Test.java | 2 +- src/test/java/org/eclipse/yasson/Issue456Test.java | 2 +- src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java | 2 +- src/test/java/org/eclipse/yasson/SimpleTest.java | 2 +- src/test/java/org/eclipse/yasson/YassonConfigTest.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java b/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java index 75dda715..51480852 100644 --- a/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java +++ b/src/test/java/org/eclipse/yasson/DefaultGetterInInterface.java @@ -27,7 +27,7 @@ * * @author Maxence Laurent */ -public class DefaultGetterInInterface { +class DefaultGetterInInterface { private DefaultGetterInInterface() { } diff --git a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java index 5f8f5f01..9f8665c6 100644 --- a/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java +++ b/src/test/java/org/eclipse/yasson/FieldAccessStrategyTest.java @@ -21,7 +21,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -public class FieldAccessStrategyTest { +class FieldAccessStrategyTest { private FieldAccessStrategyTest() { } diff --git a/src/test/java/org/eclipse/yasson/Issue454Test.java b/src/test/java/org/eclipse/yasson/Issue454Test.java index 8ba0cd04..7e2dfbca 100644 --- a/src/test/java/org/eclipse/yasson/Issue454Test.java +++ b/src/test/java/org/eclipse/yasson/Issue454Test.java @@ -20,7 +20,7 @@ import jakarta.json.bind.JsonbConfig; import jakarta.json.bind.annotation.JsonbTransient; -public class Issue454Test { +class Issue454Test { private Issue454Test() { } diff --git a/src/test/java/org/eclipse/yasson/Issue456Test.java b/src/test/java/org/eclipse/yasson/Issue456Test.java index 3adc9991..62082258 100644 --- a/src/test/java/org/eclipse/yasson/Issue456Test.java +++ b/src/test/java/org/eclipse/yasson/Issue456Test.java @@ -19,7 +19,7 @@ import jakarta.json.bind.JsonbException; -public class Issue456Test { +class Issue456Test { private Issue456Test() { } diff --git a/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java b/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java index c5665c2c..72ecba0e 100644 --- a/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java +++ b/src/test/java/org/eclipse/yasson/JavaxNamingExcludedTest.java @@ -25,7 +25,7 @@ * Requires --limit-modules java.base,java.logging,java.sql (to exclude java.naming) to work. * See pom.xml surefire plugin configuration. */ -public class JavaxNamingExcludedTest { +class JavaxNamingExcludedTest { private JavaxNamingExcludedTest() { } diff --git a/src/test/java/org/eclipse/yasson/SimpleTest.java b/src/test/java/org/eclipse/yasson/SimpleTest.java index 5a4ed0b4..0b324739 100644 --- a/src/test/java/org/eclipse/yasson/SimpleTest.java +++ b/src/test/java/org/eclipse/yasson/SimpleTest.java @@ -21,7 +21,7 @@ /** * @author Roman Grigoriadi */ -public class SimpleTest { +class SimpleTest { private SimpleTest() { } diff --git a/src/test/java/org/eclipse/yasson/YassonConfigTest.java b/src/test/java/org/eclipse/yasson/YassonConfigTest.java index a6bbef60..b0ade6df 100644 --- a/src/test/java/org/eclipse/yasson/YassonConfigTest.java +++ b/src/test/java/org/eclipse/yasson/YassonConfigTest.java @@ -19,7 +19,7 @@ /** * Tests that the names of configuration fields in {@link YassonConfig} do not change. */ -public class YassonConfigTest { +class YassonConfigTest { private YassonConfigTest() {} From c4cd8d4b3a39e6036858291bee654776e899c75d Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 21:35:57 +0100 Subject: [PATCH 53/68] [#627]Made jakarta module requires transient, because they are required on the client to run this Signed-off-by: Anton Pinsky --- src/main/java/module-info.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index f6c0ace2..7900699f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023 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 @@ -14,8 +14,8 @@ * Eclipse implementation of the JSONB-API. */ module org.eclipse.yasson { - requires jakarta.json; - requires jakarta.json.bind; + requires transitive jakarta.json; + requires transitive jakarta.json.bind; requires java.logging; requires static java.xml; requires static java.naming; From 375eb1ff99b6ec8b9e296e96ec7061ecfb856279 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Wed, 8 Nov 2023 21:40:42 +0100 Subject: [PATCH 54/68] [#627]Add suppress for fallthrough warning Signed-off-by: Anton Pinsky --- .../eclipse/yasson/internal/deserializer/MapDeserializer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/MapDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/MapDeserializer.java index d366fc8f..87e265f6 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/MapDeserializer.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/MapDeserializer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -33,7 +33,7 @@ class MapDeserializer implements ModelDeserializer { this.valueDelegate = valueDelegate; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "fallthrough"}) @Override public Object deserialize(JsonParser parser, DeserializationContextImpl context) { Map map = (Map) context.getInstance(); From ac9da78322551c2605c62edbe3845a7a086483c2 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 13 Nov 2023 03:57:57 +0100 Subject: [PATCH 55/68] [#630]Fixed the state and context de-synchronisation in the YassonParser's skipXXX and streamXXX methods Signed-off-by: Anton Pinsky --- .../internal/JsonParserStreamCreator.java | 107 ++++++++++++++ .../internal/deserializer/YassonParser.java | 17 ++- .../JsonStructureToParserAdapter.java | 64 ++------- .../yasson/serializers/SerializersTest.java | 67 ++++++++- .../model/JsonParserTestDeserializers.java | 130 ++++++++++++++++++ .../serializers/model/JsonParserTestPojo.java | 74 ++++++++++ 6 files changed, 396 insertions(+), 63 deletions(-) create mode 100644 src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestPojo.java diff --git a/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java b/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java new file mode 100644 index 00000000..b95643c0 --- /dev/null +++ b/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 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 + * 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; + +import java.util.AbstractMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import jakarta.json.JsonException; +import jakarta.json.JsonValue; +import jakarta.json.stream.JsonParser; + +import org.eclipse.yasson.internal.properties.MessageKeys; +import org.eclipse.yasson.internal.properties.Messages; + +public class JsonParserStreamCreator { + + private final JsonParser parser; + private final boolean nextBeforeCreationOfValueStream; + private final Supplier canProduceArrayStream; + private final Supplier canProduceObjectStream; + private final Supplier canProduceValueStream; + + public JsonParserStreamCreator(JsonParser parser, boolean nextBeforeCreationOfValueStream, Supplier canProduceArrayStream, + Supplier canProduceObjectStream, + Supplier canProduceValueStream) { + + this.parser = Objects.requireNonNull(parser); + this.nextBeforeCreationOfValueStream = nextBeforeCreationOfValueStream; + this.canProduceArrayStream = canProduceArrayStream; + this.canProduceObjectStream = canProduceObjectStream; + this.canProduceValueStream = canProduceValueStream; + } + + /** + * Creates new {@link Stream} from values from {@link Supplier}. The stream delivers the values as long as supplier delivers non-null values + * + * @param supplier supplier of the values + * @param type of the values which are delivered by the supplier and the stream + * @return stream of values from given supplier + */ + private static Stream streamFromSupplier(Supplier supplier) { + return Stream.iterate(Objects.requireNonNull(supplier).get(), Objects::nonNull, value -> supplier.get()); + } + + public Stream getArrayStream() { + if (canProduceArrayStream.get()) { + return streamFromSupplier(() -> (parser.hasNext() && parser.next() != JsonParser.Event.END_ARRAY) ? parser.getValue() : null); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); + } + } + + public Stream> getObjectStream() { + if (canProduceObjectStream.get()) { + return streamFromSupplier(() -> { + JsonParser.Event e = parser.next(); + if (e == JsonParser.Event.END_OBJECT) { + return null; + } else if (e != JsonParser.Event.KEY_NAME) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); + } else { + String key = parser.getString(); + if (!parser.hasNext()) { + throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); + } else { + parser.next(); + return new AbstractMap.SimpleImmutableEntry<>(key, parser.getValue()); + } + } + }); + } else { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); + } + } + + public Stream getValueStream() { + if (canProduceValueStream.get()) { + if (nextBeforeCreationOfValueStream) { + parser.next(); + } + + return streamFromSupplier(() -> { + if (parser.hasNext()) { + return parser.getValue(); + } else { + return null; + } + }); + } else { + throw new IllegalStateException( + Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValueStream can be only called at the root level of JSON structure")); + } + } +} diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java index c17f6ff5..7a663e9e 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023 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 @@ -24,6 +24,7 @@ import jakarta.json.stream.JsonParser; import org.eclipse.yasson.internal.DeserializationContextImpl; +import org.eclipse.yasson.internal.JsonParserStreamCreator; /** * Yasson {@link YassonParser} parser wrapper. @@ -34,12 +35,15 @@ class YassonParser implements JsonParser { private final JsonParser delegate; private final DeserializationContextImpl context; + private final JsonParserStreamCreator streamCreator; private int level; YassonParser(JsonParser delegate, Event firstEvent, DeserializationContextImpl context) { this.delegate = delegate; this.context = context; this.level = determineLevelValue(firstEvent); + streamCreator = new JsonParserStreamCreator(this, false, () -> context.getLastValueEvent() == Event.START_ARRAY, + () -> context.getLastValueEvent() == Event.START_OBJECT, () -> level == 1 && context.getLastValueEvent() == Event.START_OBJECT); } private int determineLevelValue(Event firstEvent) { @@ -150,22 +154,19 @@ public JsonArray getArray() { @Override public Stream getArrayStream() { validate(); - level--; - return delegate.getArrayStream(); + return streamCreator.getArrayStream(); } @Override public Stream> getObjectStream() { validate(); - level--; - return delegate.getObjectStream(); + return streamCreator.getObjectStream(); } @Override public Stream getValueStream() { validate(); - level--; - return delegate.getValueStream(); + return streamCreator.getValueStream(); } @Override @@ -173,6 +174,7 @@ public void skipArray() { validate(); level--; delegate.skipArray(); + context.setLastValueEvent(Event.END_ARRAY); } @Override @@ -180,6 +182,7 @@ public void skipObject() { validate(); level--; delegate.skipObject(); + context.setLastValueEvent(Event.END_OBJECT); } @Override diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index ab8e9d86..19b05f67 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -13,7 +13,6 @@ package org.eclipse.yasson.internal.jsonstructure; import java.math.BigDecimal; -import java.util.AbstractMap; import java.util.ArrayDeque; import java.util.Deque; import java.util.EnumSet; @@ -21,11 +20,9 @@ import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Stream; import jakarta.json.JsonArray; -import jakarta.json.JsonException; import jakarta.json.JsonNumber; import jakarta.json.JsonObject; import jakarta.json.JsonStructure; @@ -35,6 +32,7 @@ import jakarta.json.stream.JsonLocation; import jakarta.json.stream.JsonParser; +import org.eclipse.yasson.internal.JsonParserStreamCreator; import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; @@ -56,6 +54,10 @@ public class JsonStructureToParserAdapter implements JsonParser { private final JsonStructure rootStructure; private final JsonProvider jsonProvider; + private final JsonParserStreamCreator streamCreator = new JsonParserStreamCreator(this, + //JsonParserImpl delivers the whole object - so we have to call next() before creation of the stream + true, () -> iterators.peek() instanceof JsonArrayIterator, () -> iterators.peek() instanceof JsonObjectIterator, iterators::isEmpty); + private Event currentEvent; /** @@ -69,17 +71,6 @@ public JsonStructureToParserAdapter(JsonStructure structure, JsonProvider jsonPr this.jsonProvider = jsonProvider; } - /** - * Creates new {@link Stream} from values from {@link Supplier}. The stream delivers the values as long as supplier delivers non-null values - * @param supplier supplier of the values - * @return stream of values from given supplier - * @param type of the values which are delivered by the supplier and the stream - */ - private static Stream streamFromSupplier(Supplier supplier){ - Objects.requireNonNull(supplier); - return Stream.iterate(supplier.get(), Objects::nonNull, value -> supplier.get()); - } - @Override public boolean hasNext() { JsonStructureIterator iterator = iterators.peek(); @@ -220,54 +211,17 @@ public JsonArray getArray() { @Override public Stream getArrayStream() { - JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonArrayIterator) { - return streamFromSupplier(() -> (hasNext() && next() != Event.END_ARRAY) ? getValue() : null); - } else { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); - } + return streamCreator.getArrayStream(); } @Override public Stream> getObjectStream() { - JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonObjectIterator) { - return streamFromSupplier(() -> { - Event e = next(); - if (e == Event.END_OBJECT) { - return null; - } else if (e != Event.KEY_NAME) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); - } else { - String key = getString(); - if (!hasNext()) { - throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object value")); - } else { - next(); - return new AbstractMap.SimpleImmutableEntry<>(key, getValue()); - } - } - }); - } else { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); - } + return streamCreator.getObjectStream(); } @Override public Stream getValueStream() { - if (iterators.isEmpty()) { - //JsonParserImpl delivers the whole object - so we have to do this the same way - JsonStructureToParserAdapter.this.next(); - return streamFromSupplier(() -> { - if (hasNext()) { - return getValue(); - } else { - return null; - } - }); - } else { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValueStream can be only called at the root level of JSON structure")); - } + return streamCreator.getValueStream(); } @Override @@ -294,4 +248,4 @@ private void skipJsonPart(Predicate predicate) { public void close() { //noop } -} +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index b384cb42..1c1ec0b0 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.SortedMap; import java.util.TimeZone; @@ -63,14 +64,18 @@ import org.eclipse.yasson.serializers.model.ExplicitJsonbSerializer; import org.eclipse.yasson.serializers.model.GenericPropertyPojo; import org.eclipse.yasson.serializers.model.ImplicitJsonbSerializer; +import org.eclipse.yasson.serializers.model.JsonParserTestDeserializers; +import org.eclipse.yasson.serializers.model.JsonParserTestPojo; import org.eclipse.yasson.serializers.model.NumberDeserializer; import org.eclipse.yasson.serializers.model.NumberSerializer; +import org.eclipse.yasson.serializers.model.TwoObjectsComparer; import org.eclipse.yasson.serializers.model.RecursiveDeserializer; import org.eclipse.yasson.serializers.model.RecursiveSerializer; import org.eclipse.yasson.serializers.model.SimpleAnnotatedSerializedArrayContainer; 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.Nested; import org.junit.jupiter.api.Test; import static java.util.Collections.singletonMap; @@ -925,4 +930,64 @@ public void testNoJsonbPropertyInEnum() { assertEquals(expected, defaultJsonb.fromJson(expectedJson, Cars.class)); } -} + @Nested + class YassonParserTests{ + @Test + public void testJsonParserFunctions() { + JsonParserTestPojo expected = new JsonParserTestPojo().init(); + + JsonParserTestDeserializers.JsonParserTestObjectDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestObjectDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + String expectedJson = new StringBuilder(jsonb.toJson(expected)) + .insert(1, "\"stringList_skip\":[\"string7\",\"string8\"],\"subPojo_skip\":{\"name\":\"subPojo_skip\"},").toString(); + + assertTrue(TwoObjectsComparer.getDifferentFieldInTwoObjects(expected, jsonb.fromJson(expectedJson, JsonParserTestPojo.class)) + .isEmpty()); + assertEquals(List.of("stringList_skip", "subPojo_skip", "bigDecimal", "integer", "longValue", "string", "stringList", + "stringList_getStream", "stringList_getValue", "string_getValue", "subPojo", "subPojo_getStream", "subPojo_getValue"), + deserializer.getKeyNames()); + + List expectedListOfEvents = List.of(JsonParser.Event.START_OBJECT, JsonParser.Event.END_ARRAY, + JsonParser.Event.END_OBJECT, JsonParser.Event.VALUE_NUMBER, JsonParser.Event.VALUE_NUMBER, JsonParser.Event.VALUE_NUMBER, + JsonParser.Event.VALUE_STRING, JsonParser.Event.END_ARRAY, JsonParser.Event.END_ARRAY, JsonParser.Event.END_ARRAY, + JsonParser.Event.VALUE_STRING, JsonParser.Event.END_OBJECT, JsonParser.Event.END_OBJECT); + + assertEquals(expectedListOfEvents, deserializer.getContextEvents()); + assertEquals("(line no=1, column no=96, offset=95)", deserializer.getLocation()); + assertTrue(deserializer.isIntegralNumber()); + }); + } + + @Test + public void testJsonParserValueStream() { + JsonParserTestPojo expected = new JsonParserTestPojo().init(); + + JsonParserTestDeserializers.JsonParserTestValueStreamDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestValueStreamDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + String expectedJson = jsonb.toJson(expected); + + assertTrue(TwoObjectsComparer.getDifferentFieldInTwoObjects(expected, jsonb.fromJson(expectedJson, JsonParserTestPojo.class)) + .isEmpty()); + }); + } + + @Test + public void testJsonParser_NoSuchElementException() { + JsonParserTestDeserializers.JsonParserTestNoSuchElementExceptionDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestNoSuchElementExceptionDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + Throwable throwable = null; + try { + jsonb.fromJson("5", JsonParserTestPojo.class); + fail("NoSuchElementException should be thrown"); + } catch (JsonbException jbe) { + throwable = jbe.getCause(); + } + + assertInstanceOf(NoSuchElementException.class, throwable); + }); + } + } +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java new file mode 100644 index 00000000..c49544af --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; + +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.json.bind.JsonbException; +import jakarta.json.bind.serializer.DeserializationContext; +import jakarta.json.bind.serializer.JsonbDeserializer; +import jakarta.json.stream.JsonParser; + +import org.eclipse.yasson.internal.DeserializationContextImpl; + +import static org.eclipse.yasson.Jsonbs.defaultJsonb; + +public class JsonParserTestDeserializers { + + public static class JsonParserTestNoSuchElementExceptionDeserializer implements JsonbDeserializer { + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + try { + parser.next(); + } catch (NoSuchElementException e) { + throw new JsonbException("Level below zero", e); + } + return new JsonParserTestPojo(); + } + } + + public static class JsonParserTestValueStreamDeserializer implements JsonbDeserializer { + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + JsonObject value = parser.getValueStream().findFirst().orElseThrow().asJsonObject(); + return defaultJsonb.fromJson(value.toString(), JsonParserTestPojo.class); + } + } + + public static class JsonParserTestObjectDeserializer implements JsonbDeserializer { + + private boolean integralNumber; + private String location; + private final List keyNames = new ArrayList<>(); + private final List contextEvents = new ArrayList<>(); + + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + JsonParserTestPojo result = new JsonParserTestPojo(); + if (ctx instanceof DeserializationContextImpl) { + DeserializationContextImpl deserializationContext = (DeserializationContextImpl) ctx; + skipKey(parser, deserializationContext); + parser.skipArray(); + skipKey(parser, deserializationContext); + parser.skipObject(); + skipKey(parser, deserializationContext); + integralNumber = parser.isIntegralNumber(); + location = parser.getLocation().toString(); + result.bigDecimal = parser.getBigDecimal(); + skipKey(parser, deserializationContext); + result.integer = parser.getInt(); + skipKey(parser, deserializationContext); + result.longValue = parser.getLong(); + skipKey(parser, deserializationContext); + result.string = parser.getString(); + skipKey(parser, deserializationContext); + result.stringList = parser.getArray().stream().map(value -> ((JsonString) value).getString()).collect(Collectors.toList()); + skipKey(parser, deserializationContext); + result.stringList_getStream = parser.getArrayStream().map(value -> ((JsonString) value).getString()).collect(Collectors.toList()); + skipKey(parser, deserializationContext); + result.stringList_getValue = + parser.getValue().asJsonArray().stream().map(value -> ((JsonString) value).getString()).collect(Collectors.toList()); + skipKey(parser, deserializationContext); + result.string_getValue = ((JsonString) parser.getValue()).getString(); + skipKey(parser, deserializationContext); + result.subPojo = new JsonParserTestPojo.JsonParserTestSubPojo(parser.getObject().getString("name")); + skipKey(parser, deserializationContext); + result.subPojo_getStream = parser.getObjectStream() + .map(o -> new JsonParserTestPojo.JsonParserTestSubPojo(((JsonString) o.getValue()).getString())) + .collect(Collectors.toList()).get(0); + //following can't be tested before Parsson bug #112 is fixed. + /*.findFirst().orElse(null); + parser.skipObject();*/ + skipKey(parser, deserializationContext); + result.subPojo_getValue = new JsonParserTestPojo.JsonParserTestSubPojo(parser.getValue().asJsonObject().getString("name")); + } + return result; + } + + private void skipKey(JsonParser parser, DeserializationContextImpl deserializationContext) { + parser.hasNext(); + contextEvents.add(deserializationContext.getLastValueEvent()); + parser.next(); + String key = parser.getString(); + keyNames.add(key); + parser.next(); + } + + public boolean isIntegralNumber() { + return integralNumber; + } + + public String getLocation() { + return location; + } + + public List getKeyNames() { + return Collections.unmodifiableList(keyNames); + } + + public List getContextEvents() { + return Collections.unmodifiableList(contextEvents); + } + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestPojo.java b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestPojo.java new file mode 100644 index 00000000..3df5484f --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestPojo.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; + +import java.math.BigDecimal; +import java.util.List; + +public class JsonParserTestPojo { + public String string; + public Integer integer; + public Long longValue; + public BigDecimal bigDecimal; + public JsonParserTestSubPojo subPojo; + public List stringList; + public JsonParserTestSubPojo subPojo_getValue; + public String string_getValue; + public List stringList_getValue; + public List stringList_getStream; + public JsonParserTestSubPojo subPojo_getStream; + + public JsonParserTestPojo() { + } + + public JsonParserTestPojo init() { + string = "string"; + integer = 1; + longValue = 2L; + bigDecimal = BigDecimal.TEN; + subPojo = new JsonParserTestSubPojo("subPojo"); + stringList = List.of("string1", "string2"); + subPojo_getValue = new JsonParserTestSubPojo("subPojo_getValue"); + string_getValue = "string_getValue"; + stringList_getValue = List.of("string3", "string4"); + stringList_getStream = List.of("string5", "string6"); + subPojo_getStream = new JsonParserTestSubPojo("subPojo_getStream"); + return this; + } + + @Override + public boolean equals(Object obj) { + return obj != null && + getClass().isAssignableFrom(obj.getClass()) && + TwoObjectsComparer.getDifferentFieldInTwoObjects(this, obj).isEmpty(); + } + + public static class JsonParserTestSubPojo { + + public String name; + + protected JsonParserTestSubPojo() { + } + + JsonParserTestSubPojo(String name) { + this.name = name; + } + + @Override + public boolean equals(Object obj) { + return obj != null && + getClass().isAssignableFrom(obj.getClass()) && + TwoObjectsComparer.getDifferentFieldInTwoObjects(this, obj).isEmpty(); + } + } +} From ef0ccddbce6be9513f7adbb907c75d13bbe4d171 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 13 Nov 2023 04:00:10 +0100 Subject: [PATCH 56/68] [#630]Forgot one class Signed-off-by: Anton Pinsky --- .../serializers/model/TwoObjectsComparer.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/org/eclipse/yasson/serializers/model/TwoObjectsComparer.java diff --git a/src/test/java/org/eclipse/yasson/serializers/model/TwoObjectsComparer.java b/src/test/java/org/eclipse/yasson/serializers/model/TwoObjectsComparer.java new file mode 100644 index 00000000..23f504ee --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/TwoObjectsComparer.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 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 + * 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.serializers.model; + +import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; + +public class TwoObjectsComparer { + public final String propertyName; + public final Object firstObjectValue; + public final Object secondObjectValue; + + public static Optional getDifferentFieldInTwoObjects(T thisObject, T otherObject) { + return otherObject == null ? Optional.empty() : Arrays.stream(thisObject.getClass().getFields()).map(f -> { + try { + return new TwoObjectsComparer(f.getName(), f.get(thisObject), f.get(otherObject)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + }).filter(o -> !Objects.equals(o.firstObjectValue, o.secondObjectValue)).findFirst(); + } + + private TwoObjectsComparer(String name, Object firstObjectValue, Object secondObjectValue) { + this.propertyName = name; + this.firstObjectValue = firstObjectValue; + this.secondObjectValue = secondObjectValue; + } + + @Override + public String toString() { + return "propertyName: " + propertyName + " firstObjectValue: " + firstObjectValue + " secondObjectValue: " + secondObjectValue; + } +} From 013237c6bcc04d3b835cc296fe8695f68df8cd53 Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Mon, 13 Nov 2023 04:04:45 +0100 Subject: [PATCH 57/68] [#611]Implemented currenEvent() in YassonParser Signed-off-by: Anton Pinsky --- .../eclipse/yasson/internal/deserializer/YassonParser.java | 5 +++++ .../org/eclipse/yasson/serializers/SerializersTest.java | 1 + .../serializers/model/JsonParserTestDeserializers.java | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java index 7a663e9e..40b04c96 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java @@ -90,6 +90,11 @@ public Event next() { return next; } + @Override + public Event currentEvent() { + return delegate.currentEvent(); + } + @Override public String getString() { return delegate.getString(); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 1c1ec0b0..044b3391 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -953,6 +953,7 @@ public void testJsonParserFunctions() { JsonParser.Event.VALUE_STRING, JsonParser.Event.END_ARRAY, JsonParser.Event.END_ARRAY, JsonParser.Event.END_ARRAY, JsonParser.Event.VALUE_STRING, JsonParser.Event.END_OBJECT, JsonParser.Event.END_OBJECT); + assertEquals(expectedListOfEvents, deserializer.getParserEvents()); assertEquals(expectedListOfEvents, deserializer.getContextEvents()); assertEquals("(line no=1, column no=96, offset=95)", deserializer.getLocation()); assertTrue(deserializer.isIntegralNumber()); diff --git a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java index c49544af..73d64a6c 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java @@ -57,6 +57,7 @@ public static class JsonParserTestObjectDeserializer implements JsonbDeserialize private boolean integralNumber; private String location; private final List keyNames = new ArrayList<>(); + private final List parserEvents = new ArrayList<>(); private final List contextEvents = new ArrayList<>(); @Override @@ -104,6 +105,7 @@ public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext private void skipKey(JsonParser parser, DeserializationContextImpl deserializationContext) { parser.hasNext(); + parserEvents.add(parser.currentEvent()); contextEvents.add(deserializationContext.getLastValueEvent()); parser.next(); String key = parser.getString(); @@ -123,6 +125,10 @@ public List getKeyNames() { return Collections.unmodifiableList(keyNames); } + public List getParserEvents() { + return Collections.unmodifiableList(parserEvents); + } + public List getContextEvents() { return Collections.unmodifiableList(contextEvents); } From e83673474aa57780d8b6258e63bf59d99851394f Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 25 Nov 2023 00:07:06 +0100 Subject: [PATCH 58/68] [#630] Backport some changes and tests from Parson stream etc. implementation; YassonParser & JsonStructureToParserAdapter fulfill more JSONP JsonParser Signed-off-by: Anton Pinsky --- pom.xml | 2 +- .../internal/JsonParserStreamCreator.java | 27 ++- .../internal/deserializer/YassonParser.java | 68 ++++-- .../JsonStructureToParserAdapter.java | 66 +++--- .../JsonStructureToParserAdapterTest.java | 224 +++++++++++------- .../yasson/serializers/SerializersTest.java | 68 ++++++ .../model/JsonParserTestDeserializers.java | 41 ++++ 7 files changed, 348 insertions(+), 148 deletions(-) diff --git a/pom.xml b/pom.xml index 0d6166a8..55a32528 100644 --- a/pom.xml +++ b/pom.xml @@ -652,7 +652,7 @@ com.puppycrawl.tools checkstyle - 10.12.4 + 10.12.5 com.sun diff --git a/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java b/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java index b95643c0..fae817ae 100644 --- a/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/JsonParserStreamCreator.java @@ -21,6 +21,7 @@ import jakarta.json.JsonException; import jakarta.json.JsonValue; import jakarta.json.stream.JsonParser; +import jakarta.json.stream.JsonParser.Event; import org.eclipse.yasson.internal.properties.MessageKeys; import org.eclipse.yasson.internal.properties.Messages; @@ -29,19 +30,16 @@ public class JsonParserStreamCreator { private final JsonParser parser; private final boolean nextBeforeCreationOfValueStream; - private final Supplier canProduceArrayStream; - private final Supplier canProduceObjectStream; + private final Supplier currenEventSupplier; private final Supplier canProduceValueStream; - public JsonParserStreamCreator(JsonParser parser, boolean nextBeforeCreationOfValueStream, Supplier canProduceArrayStream, - Supplier canProduceObjectStream, + public JsonParserStreamCreator(JsonParser parser, boolean nextBeforeCreationOfValueStream, Supplier currenEventSupplier, Supplier canProduceValueStream) { this.parser = Objects.requireNonNull(parser); this.nextBeforeCreationOfValueStream = nextBeforeCreationOfValueStream; - this.canProduceArrayStream = canProduceArrayStream; - this.canProduceObjectStream = canProduceObjectStream; - this.canProduceValueStream = canProduceValueStream; + this.currenEventSupplier = Objects.requireNonNull(currenEventSupplier); + this.canProduceValueStream = Objects.requireNonNull(canProduceValueStream); } /** @@ -56,20 +54,23 @@ private static Stream streamFromSupplier(Supplier supplier) { } public Stream getArrayStream() { - if (canProduceArrayStream.get()) { - return streamFromSupplier(() -> (parser.hasNext() && parser.next() != JsonParser.Event.END_ARRAY) ? parser.getValue() : null); + if (currenEventSupplier.get() == Event.START_ARRAY) { + return streamFromSupplier(() -> (parser.hasNext() && parser.next() != Event.END_ARRAY) ? parser.getValue() : null); } else { throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); } } public Stream> getObjectStream() { - if (canProduceObjectStream.get()) { + if (currenEventSupplier.get() == Event.START_OBJECT) { return streamFromSupplier(() -> { - JsonParser.Event e = parser.next(); - if (e == JsonParser.Event.END_OBJECT) { + if (!parser.hasNext()) { return null; - } else if (e != JsonParser.Event.KEY_NAME) { + } + Event e = parser.next(); + if (e == Event.END_OBJECT) { + return null; + } else if (e != Event.KEY_NAME) { throw new JsonException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Cannot read object key")); } else { String key = parser.getString(); diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java index 40b04c96..f5e701e8 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/YassonParser.java @@ -13,6 +13,8 @@ package org.eclipse.yasson.internal.deserializer; import java.math.BigDecimal; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Map; import java.util.NoSuchElementException; import java.util.stream.Stream; @@ -25,6 +27,8 @@ import org.eclipse.yasson.internal.DeserializationContextImpl; import org.eclipse.yasson.internal.JsonParserStreamCreator; +import org.eclipse.yasson.internal.properties.MessageKeys; +import org.eclipse.yasson.internal.properties.Messages; /** * Yasson {@link YassonParser} parser wrapper. @@ -36,23 +40,27 @@ class YassonParser implements JsonParser { private final JsonParser delegate; private final DeserializationContextImpl context; private final JsonParserStreamCreator streamCreator; - private int level; + private final Deque contextStack = new ArrayDeque<>(); YassonParser(JsonParser delegate, Event firstEvent, DeserializationContextImpl context) { this.delegate = delegate; this.context = context; - this.level = determineLevelValue(firstEvent); - streamCreator = new JsonParserStreamCreator(this, false, () -> context.getLastValueEvent() == Event.START_ARRAY, - () -> context.getLastValueEvent() == Event.START_OBJECT, () -> level == 1 && context.getLastValueEvent() == Event.START_OBJECT); + CurrentContext currentContext = determineLevelValue(firstEvent); + if (currentContext != null) { + contextStack.push(currentContext); + } + streamCreator = new JsonParserStreamCreator(this, false, context::getLastValueEvent, + () -> contextStack.size() == 1 && context.getLastValueEvent() == Event.START_OBJECT); } - private int determineLevelValue(Event firstEvent) { + private CurrentContext determineLevelValue(Event firstEvent) { switch (firstEvent) { case START_ARRAY: + return CurrentContext.ARRAY; //container start, there will be more events to come case START_OBJECT: - return 1; //container start, there will be more events to come + return CurrentContext.OBJECT; //container start, there will be more events to come default: - return 0; //just this single value, do not allow reading more + return null; //just this single value, do not allow reading more } } @@ -64,7 +72,7 @@ void skipRemaining() { @Override public boolean hasNext() { - if (level < 1) { + if (contextStack.isEmpty()) { return false; } return delegate.hasNext(); @@ -78,11 +86,14 @@ public Event next() { switch (next) { case START_OBJECT: case START_ARRAY: - level++; + CurrentContext currentContext = determineLevelValue(next); + if (currentContext != null) { + contextStack.push(currentContext); + } break; case END_OBJECT: case END_ARRAY: - level--; + contextStack.pop(); break; default: //no other changes needed @@ -127,9 +138,12 @@ public JsonLocation getLocation() { @Override public JsonObject getObject() { + if (delegate.currentEvent() != Event.START_OBJECT) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getObject() Not at the beginning of an object")); + } validate(); - level--; JsonObject jsonObject = delegate.getObject(); + contextStack.pop(); context.setLastValueEvent(Event.END_OBJECT); return jsonObject; } @@ -149,9 +163,12 @@ public JsonValue getValue() { @Override public JsonArray getArray() { + if (delegate.currentEvent() != Event.START_ARRAY) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getArray() Not at the beginning of an array")); + } validate(); - level--; JsonArray array = delegate.getArray(); + contextStack.pop(); context.setLastValueEvent(Event.END_ARRAY); return array; } @@ -176,28 +193,35 @@ public Stream getValueStream() { @Override public void skipArray() { - validate(); - level--; - delegate.skipArray(); - context.setLastValueEvent(Event.END_ARRAY); + if (contextStack.peek() == CurrentContext.ARRAY) { + delegate.skipArray(); + contextStack.pop(); + context.setLastValueEvent(Event.END_ARRAY); + } } @Override public void skipObject() { - validate(); - level--; - delegate.skipObject(); - context.setLastValueEvent(Event.END_OBJECT); + if (contextStack.peek() == CurrentContext.OBJECT) { + delegate.skipObject(); + contextStack.pop(); + context.setLastValueEvent(Event.END_OBJECT); + } } @Override public void close() { - throw new UnsupportedOperationException(); + delegate.close(); } private void validate() { - if (level < 1) { + if (contextStack.isEmpty()) { throw new NoSuchElementException("There are no more elements available!"); } } + + private enum CurrentContext { + OBJECT, + ARRAY + } } diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java index 19b05f67..b2e1a6f5 100644 --- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java +++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java @@ -15,7 +15,6 @@ import java.math.BigDecimal; import java.util.ArrayDeque; import java.util.Deque; -import java.util.EnumSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; @@ -45,18 +44,13 @@ */ public class JsonStructureToParserAdapter implements JsonParser { - private static final EnumSet GET_STRING_EVENTS = EnumSet.of(Event.KEY_NAME, Event.VALUE_STRING, Event.VALUE_NUMBER); - - private static final EnumSet NOT_GET_VALUE_EVENT_ENUM_SET = EnumSet.of(JsonParser.Event.END_OBJECT, JsonParser.Event.END_ARRAY); - private final Deque iterators = new ArrayDeque<>(); private final JsonStructure rootStructure; private final JsonProvider jsonProvider; - private final JsonParserStreamCreator streamCreator = new JsonParserStreamCreator(this, - //JsonParserImpl delivers the whole object - so we have to call next() before creation of the stream - true, () -> iterators.peek() instanceof JsonArrayIterator, () -> iterators.peek() instanceof JsonObjectIterator, iterators::isEmpty); + //JsonParserImpl delivers the whole object - so we have to call next() before creation of the stream + private final JsonParserStreamCreator streamCreator = new JsonParserStreamCreator(this, true, this::currentEvent, iterators::isEmpty); private Event currentEvent; @@ -111,12 +105,22 @@ public Event currentEvent() { @Override public String getString() { - JsonStructureIterator iterator = iterators.peek(); - if (iterator == null || !GET_STRING_EVENTS.contains(currentEvent)) { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getString() call with current event: " - + (iterator == null ? "null" : currentEvent) + "; should be in " + GET_STRING_EVENTS)); - } else { - return iterator.getString(); + if (currentEvent == null) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getString() call with current event: null")); + } + + switch (currentEvent) { + case KEY_NAME: + case VALUE_STRING: + case VALUE_NUMBER: + JsonStructureIterator iterator = iterators.peek(); + if (iterator == null) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getString() call with empty internal stack")); + } + return iterator.getString(); + default: + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getString() call with current event: " + + currentEvent + "; should be in [KEY_NAME, VALUE_STRING, VALUE_NUMBER]")); } } @@ -143,12 +147,14 @@ public BigDecimal getBigDecimal() { @Override public JsonObject getObject() { JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonObjectIterator) { + if (currentEvent == Event.START_OBJECT) { //Remove child iterator as getObject() method contract says iterators.pop(); - return current.getValue().asJsonObject(); + currentEvent = Event.END_OBJECT; + JsonValue value = current == null ? null : current.getValue(); + return value == null ? null : value.asJsonObject(); } else { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context")); + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getObject() Not at the beginning of an object")); } } @@ -171,13 +177,12 @@ public JsonLocation getLocation() { @Override public JsonValue getValue() { - if (currentEvent == null || NOT_GET_VALUE_EVENT_ENUM_SET.contains(currentEvent)) { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call with current event: " - + currentEvent + "; should not be in " + NOT_GET_VALUE_EVENT_ENUM_SET)); + if (currentEvent == null) { + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call with current event: null")); } else { JsonStructureIterator iterator = iterators.peek(); if (iterator == null) { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call on empty context")); + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call empty internal stack")); } else { switch (currentEvent) { case START_OBJECT: @@ -186,6 +191,10 @@ public JsonValue getValue() { return getArray(); case KEY_NAME: return jsonProvider.createValue(iterator.getString()); + case END_ARRAY: + case END_OBJECT: + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getValue() call with current event: " + + currentEvent + "; should not be in [END_OBJECT, END_ARRAY]")); default: return iterator.getValue(); } @@ -195,17 +204,17 @@ public JsonValue getValue() { @Override public JsonArray getArray() { - JsonStructureIterator current = iterators.peek(); - if (current instanceof JsonArrayIterator) { + if (currentEvent == Event.START_ARRAY) { //Remove child iterator as getArray() method contract says iterators.pop(); - current = iterators.peek(); + currentEvent = Event.END_ARRAY; + JsonStructureIterator current = iterators.peek(); if (current == null) { throw new NoSuchElementException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "No more elements in JSON structure")); } return current.getValue().asJsonArray(); } else { - throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of array context")); + throw new IllegalStateException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "getArray() not at the beginning of an array")); } } @@ -226,20 +235,21 @@ public Stream getValueStream() { @Override public void skipArray() { - skipJsonPart(iterator -> iterator instanceof JsonArrayIterator); + skipJsonPart(iterator -> iterator instanceof JsonArrayIterator, Event.END_ARRAY); } @Override public void skipObject() { - skipJsonPart(iterator -> iterator instanceof JsonObjectIterator); + skipJsonPart(iterator -> iterator instanceof JsonObjectIterator, Event.END_OBJECT); } - private void skipJsonPart(Predicate predicate) { + private void skipJsonPart(Predicate predicate, Event newCurrentEvent) { Objects.requireNonNull(predicate); if (!iterators.isEmpty()) { JsonStructureIterator current = iterators.peek(); if (predicate.test(current)) { iterators.pop(); + currentEvent = newCurrentEvent; } } } diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index 1614a27e..5f0e2f1d 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -23,6 +23,7 @@ import org.eclipse.yasson.TestTypeToken; import org.eclipse.yasson.YassonJsonb; +import org.junit.jupiter.api.function.Executable; import jakarta.json.Json; import jakarta.json.JsonArray; @@ -44,6 +45,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.Consumer; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -67,7 +69,7 @@ public class JsonStructureToParserAdapterTest { private static final JsonProvider jsonProvider = JsonProvider.provider(); @Test - public void testBasicJsonObject() { + void testBasicJsonObject() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); objectBuilder.add("stringProperty", "value 1"); objectBuilder.add("bigDecimalProperty", new BigDecimal("1.1")); @@ -80,7 +82,7 @@ public void testBasicJsonObject() { } @Test - public void testNullValues() { + void testNullValues() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); objectBuilder.addNull("stringProperty"); objectBuilder.addNull("bigDecimalProperty"); @@ -93,7 +95,7 @@ public void testNullValues() { } @Test - public void testInnerJsonObjectWrappedWithProperties() { + void testInnerJsonObjectWrappedWithProperties() { JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); innerBuilder.add("innerFirst", "Inner value 1"); innerBuilder.add("innerSecond", "Inner value 2"); @@ -115,7 +117,7 @@ public void testInnerJsonObjectWrappedWithProperties() { } @Test - public void testInnerJsonObjectAtEndProperty() { + void testInnerJsonObjectAtEndProperty() { JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); innerBuilder.add("innerFirst", "Inner value 1"); innerBuilder.add("innerSecond", "Inner value 2"); @@ -139,7 +141,7 @@ public void testInnerJsonObjectAtEndProperty() { } @Test - public void testEmptyJsonObject() { + void testEmptyJsonObject() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); JsonObject jsonObject = objectBuilder.build(); Pojo result = yassonJsonb.fromJsonStructure(jsonObject, Pojo.class); @@ -149,7 +151,7 @@ public void testEmptyJsonObject() { } @Test - public void testEmptyInnerJsonObject() { + void testEmptyInnerJsonObject() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); @@ -170,7 +172,7 @@ public void testEmptyInnerJsonObject() { } @Test - public void testSimpleArray() { + void testSimpleArray() { JsonArrayBuilder arrayBuilder = jsonProvider.createArrayBuilder(); arrayBuilder.add(BigDecimal.TEN).add("String value").addNull(); JsonArray jsonArray = arrayBuilder.build(); @@ -182,7 +184,7 @@ public void testSimpleArray() { } @Test - public void testArraysInsideObject() { + void testArraysInsideObject() { JsonArrayBuilder bigDecBuilder = jsonProvider.createArrayBuilder(); JsonArrayBuilder strBuilder = jsonProvider.createArrayBuilder(); JsonArrayBuilder blnBuilder = jsonProvider.createArrayBuilder(); @@ -205,7 +207,7 @@ public void testArraysInsideObject() { } @Test - public void testNestedArrays() { + void testNestedArrays() { JsonArrayBuilder arrayBuilder = jsonProvider.createArrayBuilder(); JsonArrayBuilder innerArrBuilder = jsonProvider.createArrayBuilder(); innerArrBuilder.add("first").add("second"); @@ -226,7 +228,7 @@ public void testNestedArrays() { } @Test - public void testObjectsNestedInArrays() { + void testObjectsNestedInArrays() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); objectBuilder.add("stringProperty", "value 1"); objectBuilder.add("bigDecimalProperty", new BigDecimal("1.1")); @@ -254,7 +256,7 @@ public void testObjectsNestedInArrays() { } @Test - public void testObjectsNestedInArraysRaw() { + void testObjectsNestedInArraysRaw() { JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder(); objectBuilder.add("stringProperty", "value 1"); objectBuilder.add("bigDecimalProperty", new BigDecimal("1.1")); @@ -291,7 +293,7 @@ public void testObjectsNestedInArraysRaw() { @Test - public void testCustomJsonbDeserializer() { + void testCustomJsonbDeserializer() { JsonObjectBuilder outerBuilder = jsonProvider.createObjectBuilder(); JsonObjectBuilder innerBuilder = jsonProvider.createObjectBuilder(); innerBuilder.add("first", "String value 1"); @@ -309,17 +311,22 @@ public void testCustomJsonbDeserializer() { @Nested public class DirectParserTests { + + private static void testWithParserAdapter(JsonObject jsonObject, Consumer consumer) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + consumer.accept(parser); + } + } + @Test - public void testNumbers() { - JsonObject jsonObject = jsonProvider.createObjectBuilder() + void testNumbers() { + testWithParserAdapter(jsonProvider.createObjectBuilder() .add("int", 1) .add("long", 1L) .add("double", 1d) .add("BigInteger", BigInteger.TEN) .add("BigDecimal", BigDecimal.TEN) - .build(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + .build(), parser -> { parser.next(); parser.next(); parser.getString(); @@ -350,14 +357,12 @@ public void testNumbers() { parser.next(); assertTrue(parser.isIntegralNumber()); assertEquals(BigDecimal.TEN, parser.getBigDecimal()); - } + }); } @Test - public void testParser_getString(){ - JsonObject jsonObject = TestData.createFamilyPerson(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testParser_getString(){ + testWithParserAdapter(TestData.createFamilyPerson(), parser -> { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -369,14 +374,12 @@ public void testParser_getString(){ } assertThat(values,TestData.FAMILY_MATCHER_WITH_NO_QUOTATION); - } + }); } @Test - public void testParser_getValue(){ - JsonObject jsonObject = TestData.createFamilyPerson(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testParser_getValue(){ + testWithParserAdapter(TestData.createFamilyPerson(), parser -> { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -388,14 +391,12 @@ public void testParser_getValue(){ } assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITH_QUOTATION); - } + }); } @Test - public void testSkipArray() { - JsonObject jsonObject = TestData.createObjectWithArrays(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testSkipArray() { + testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { parser.next(); parser.next(); parser.getString(); @@ -405,14 +406,12 @@ public void testSkipArray() { String key = parser.getString(); assertEquals("secondElement", key); - } + }); } @Test - public void testSkipObject() { - JsonObject jsonObject = TestData.createJsonObject(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testSkipObject() { + testWithParserAdapter(TestData.createJsonObject(), parser -> { parser.next(); parser.next(); parser.getString(); @@ -422,17 +421,77 @@ public void testSkipObject() { String key = parser.getString(); assertEquals("secondPerson", key); - } + }); + } + + private void assertThrowsIllegalStateException(Executable executable) { + assertThrows(IllegalStateException.class, executable); + } + + @Test + void testErrorGetObject() { + assertThrowsIllegalStateException(() -> testWithParserAdapter(TestData.createJsonObject(), JsonParser::getObject)); + } + + @Test + void testErrorGetArray() { + assertThrowsIllegalStateException(() -> testWithParserAdapter(TestData.createJsonObject(), parser -> { + parser.next(); + parser.getArray(); + })); + } + + @Test + void testErrorGetValueEndOfObject() { + assertThrowsIllegalStateException(() -> testWithParserAdapter(TestData.createJsonObject(), parser -> { + parser.next(); + parser.skipObject(); + parser.getValue(); + })); + } + + @Test + void testErrorGetValueEndOfArray() { + assertThrowsIllegalStateException(() -> testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { + parser.next(); + parser.next(); + parser.getString(); + parser.next(); + parser.skipArray(); + parser.getValue(); + })); + } + + @Test + void testBooleanNullandCurrentEvent() { + testWithParserAdapter(Json.createObjectBuilder() + .add("true", true) + .add("false", false) + .addNull("null") + .build(), parser -> { + parser.next(); + parser.next(); + parser.getValue(); + parser.next(); + assertEquals(JsonValue.ValueType.TRUE, parser.getValue().getValueType()); + parser.next(); + parser.getValue(); + parser.next(); + assertEquals(JsonValue.ValueType.FALSE, parser.getValue().getValueType()); + parser.next(); + parser.getValue(); + parser.next(); + assertEquals(JsonValue.ValueType.NULL, parser.getValue().getValueType()); + assertEquals(JsonParser.Event.VALUE_NULL, parser.currentEvent()); + }); } } @Nested public class StreamTests { @Test - public void testGetValueStream_GetOneElement() { - JsonObject jsonObject = TestData.createFamilyPerson(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetValueStream_GetOneElement() { + DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { JsonString name = (JsonString) parser.getValueStream() .map(JsonValue::asJsonObject) .map(JsonObject::values) @@ -444,25 +503,21 @@ public void testGetValueStream_GetOneElement() { .orElseThrow(() -> new RuntimeException("Name not found")); assertEquals("John", name.getString()); - } + }); } @Test - public void testGetValueStream_GetList() { - JsonObject jsonObject = TestData.createFamilyPerson(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetValueStream_GetList() { + DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); assertThat(values, contains(TestData.JSON_FAMILY_STRING)); - } + }); } @Test - public void testGetArrayStream_GetOneElement() { - JsonObject jsonObject = TestData.createObjectWithArrays(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetArrayStream_GetOneElement() { + DirectParserTests.testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { parser.next(); parser.next(); String key = parser.getString(); @@ -473,14 +528,12 @@ public void testGetArrayStream_GetOneElement() { assertEquals("first", element.getString()); assertEquals("firstElement", key); - } + }); } @Test - public void testGetArrayStream_GetList() { - JsonObject jsonObject = TestData.createObjectWithArrays(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetArrayStream_GetList() { + DirectParserTests.testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { parser.next(); parser.next(); String key = parser.getString(); @@ -489,14 +542,12 @@ public void testGetArrayStream_GetList() { assertThat(values, TestData.ARRAY_STREAM_MATCHER); assertEquals("firstElement", key); - } + }); } @Test - public void testGetObjectStream_GetOneElement() { - JsonObject jsonObject = TestData.createJsonObject(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetObjectStream_GetOneElement() { + DirectParserTests.testWithParserAdapter(TestData.createJsonObject(), parser -> { parser.next(); String surname = parser.getObjectStream().filter(e -> e.getKey().equals("firstPerson")) .map(Map.Entry::getValue) @@ -506,36 +557,41 @@ public void testGetObjectStream_GetOneElement() { .orElseThrow(() -> new RuntimeException("Surname not found")); assertEquals("Smith", surname); - } + }); } @Test - public void testGetObjectStream_GetList() { - JsonObject jsonObject = TestData.createFamilyPerson(); - - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + void testGetObjectStream_GetList() { + DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { parser.next(); List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITHOUT_QUOTATION); - } + }); } } @Nested public class JSONPStandardParserTests { + + private static void testWithStringParser(String json, Consumer consumer) { + try (JsonParser parser = Json.createParser(new StringReader(json))) { + consumer.accept(parser); + } + } + @Test - public void testStandardStringParser_getValueStream() { - try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + void testStandardStringParser_getValueStream() { + testWithStringParser(TestData.JSON_FAMILY_STRING, parser -> { List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); assertThat(values, contains(TestData.JSON_FAMILY_STRING)); - } + }); } @Test - public void testStandardStringParser_getArrayStream() { - try (JsonParser parser = Json.createParser(new StringReader("{\"firstElement\":[\"first\", \"second\"],\"secondElement\":[\"third\", \"fourth\"]}"))) { + void testStandardStringParser_getArrayStream() { + testWithStringParser("{\"firstElement\":[\"first\", \"second\"],\"secondElement\":[\"third\", \"fourth\"]}", parser -> { parser.next(); parser.next(); String key = parser.getString(); @@ -544,23 +600,23 @@ public void testStandardStringParser_getArrayStream() { assertThat(values, TestData.ARRAY_STREAM_MATCHER); assertEquals("firstElement", key); - } + }); } @Test - public void testStandardStringParser_getObjectStream() { - try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + void testStandardStringParser_getObjectStream() { + testWithStringParser(TestData.JSON_FAMILY_STRING, parser -> { parser.next(); List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITHOUT_QUOTATION); - } + }); } @Test - public void testStandardStringParser_getValue() { - try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + void testStandardStringParser_getValue() { + testWithStringParser(TestData.JSON_FAMILY_STRING, parser -> { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -572,12 +628,12 @@ public void testStandardStringParser_getValue() { } assertThat(values, TestData.FAMILY_MATCHER_KEYS_WITH_QUOTATION); - } + }); } @Test - public void testStandardStringParser_getString() { - try (JsonParser parser = Json.createParser(new StringReader(TestData.JSON_FAMILY_STRING))) { + void testStandardStringParser_getString() { + testWithStringParser(TestData.JSON_FAMILY_STRING, parser -> { List values = new ArrayList<>(); parser.next(); while (parser.hasNext()) { @@ -589,11 +645,11 @@ public void testStandardStringParser_getString() { } assertThat(values, TestData.FAMILY_MATCHER_WITH_NO_QUOTATION); - } + }); } @Test - public void testStandardStructureParser_getString() { + void testStandardStructureParser_getString() { JsonParserFactory factory = Json.createParserFactory(Map.of()); JsonObject jsonObject = TestData.createFamilyPerson(); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 044b3391..3bb98c31 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -990,5 +990,73 @@ public void testJsonParser_NoSuchElementException() { assertInstanceOf(NoSuchElementException.class, throwable); }); } + + @Test + public void testJsonParser_GetObject_NotAtTheStartOfObject_IllegalStateException() { + JsonParserTestDeserializers.JsonParserTestGetObjectDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestGetObjectDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + Throwable throwable = null; + try { + jsonb.fromJson("5", JsonParserTestPojo.class); + fail("IllegalStateException should be thrown"); + } catch (JsonbException jbe) { + throwable = jbe.getCause(); + } + + assertInstanceOf(IllegalStateException.class, throwable); + }); + } + + @Test + public void testJsonParser_GetArray_NotAtTheStartOfArray_IllegalStateException() { + JsonParserTestDeserializers.JsonParserTestGetArrayDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestGetArrayDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + Throwable throwable = null; + try { + jsonb.fromJson("5", JsonParserTestPojo.class); + fail("IllegalStateException should be thrown"); + } catch (JsonbException jbe) { + throwable = jbe.getCause(); + } + + assertInstanceOf(IllegalStateException.class, throwable); + }); + } + + @Test + public void testJsonParser_GetValueEndOfObject_IllegalStateException() { + JsonParserTestDeserializers.JsonParserTestEndOfObjectDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestEndOfObjectDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + Throwable throwable = null; + try { + jsonb.fromJson("{\"a\":1}", JsonParserTestPojo.class); + fail("IllegalStateException should be thrown"); + } catch (JsonbException jbe) { + throwable = jbe.getCause(); + } + + assertInstanceOf(IllegalStateException.class, throwable); + }); + } + + @Test + public void testJsonParser_GetValueEndOfArray_IllegalStateException() { + JsonParserTestDeserializers.JsonParserTestEndOfArrayDeserializer + deserializer = new JsonParserTestDeserializers.JsonParserTestEndOfArrayDeserializer(); + testWithJsonbBuilderCreate(new JsonbConfig().withDeserializers(deserializer), jsonb -> { + Throwable throwable = null; + try { + jsonb.fromJson("{\"a\":[]]}", JsonParserTestPojo.class); + fail("IllegalStateException should be thrown"); + } catch (JsonbException jbe) { + throwable = jbe.getCause(); + } + + assertInstanceOf(IllegalStateException.class, throwable); + }); + } } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java index 73d64a6c..4533f226 100644 --- a/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java +++ b/src/test/java/org/eclipse/yasson/serializers/model/JsonParserTestDeserializers.java @@ -52,6 +52,47 @@ public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext } } + public static class JsonParserTestGetObjectDeserializer implements JsonbDeserializer { + + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + parser.getObject(); + return new JsonParserTestPojo(); + } + } + + public static class JsonParserTestGetArrayDeserializer implements JsonbDeserializer { + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + parser.getArray(); + return new JsonParserTestPojo(); + } + } + + public static class JsonParserTestEndOfObjectDeserializer implements JsonbDeserializer { + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + //un-comment as soon as Parsson bug #112 is fixed +// parser.next(); + parser.skipObject(); + parser.getValue(); + return new JsonParserTestPojo(); + } + } + + public static class JsonParserTestEndOfArrayDeserializer implements JsonbDeserializer { + @Override + public JsonParserTestPojo deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + parser.next(); + parser.next(); + parser.getString(); + parser.next(); + parser.skipArray(); + parser.getValue(); + return new JsonParserTestPojo(); + } + } + public static class JsonParserTestObjectDeserializer implements JsonbDeserializer { private boolean integralNumber; From b080c99f7c803efcb6b1cdedd28863e9edd3542b Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Sat, 25 Nov 2023 00:22:30 +0100 Subject: [PATCH 59/68] =?UTF-8?q?[#630]=20Correct=20static=20error;=20some?= =?UTF-8?q?how=20works=20with=20Temurin=20=C2=AF\=5F(=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anton Pinsky --- .../JsonStructureToParserAdapterTest.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java index 5f0e2f1d..e809011b 100644 --- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java +++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java @@ -309,15 +309,15 @@ void testCustomJsonbDeserializer() { }); } - @Nested - public class DirectParserTests { - - private static void testWithParserAdapter(JsonObject jsonObject, Consumer consumer) { - try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { - consumer.accept(parser); - } + private static void testWithParserAdapter(JsonObject jsonObject, Consumer consumer) { + try (JsonStructureToParserAdapter parser = new JsonStructureToParserAdapter(jsonObject, jsonProvider)) { + consumer.accept(parser); } + } + @Nested + public class DirectParserTests { + @Test void testNumbers() { testWithParserAdapter(jsonProvider.createObjectBuilder() @@ -491,7 +491,7 @@ void testBooleanNullandCurrentEvent() { public class StreamTests { @Test void testGetValueStream_GetOneElement() { - DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { + testWithParserAdapter(TestData.createFamilyPerson(), parser -> { JsonString name = (JsonString) parser.getValueStream() .map(JsonValue::asJsonObject) .map(JsonObject::values) @@ -508,7 +508,7 @@ void testGetValueStream_GetOneElement() { @Test void testGetValueStream_GetList() { - DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { + testWithParserAdapter(TestData.createFamilyPerson(), parser -> { List values = parser.getValueStream().map(value -> Objects.toString(value, "null")).collect(Collectors.toList()); assertThat(values, contains(TestData.JSON_FAMILY_STRING)); @@ -517,7 +517,7 @@ void testGetValueStream_GetList() { @Test void testGetArrayStream_GetOneElement() { - DirectParserTests.testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { + testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { parser.next(); parser.next(); String key = parser.getString(); @@ -533,7 +533,7 @@ void testGetArrayStream_GetOneElement() { @Test void testGetArrayStream_GetList() { - DirectParserTests.testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { + testWithParserAdapter(TestData.createObjectWithArrays(), parser -> { parser.next(); parser.next(); String key = parser.getString(); @@ -547,7 +547,7 @@ void testGetArrayStream_GetList() { @Test void testGetObjectStream_GetOneElement() { - DirectParserTests.testWithParserAdapter(TestData.createJsonObject(), parser -> { + testWithParserAdapter(TestData.createJsonObject(), parser -> { parser.next(); String surname = parser.getObjectStream().filter(e -> e.getKey().equals("firstPerson")) .map(Map.Entry::getValue) @@ -562,7 +562,7 @@ void testGetObjectStream_GetOneElement() { @Test void testGetObjectStream_GetList() { - DirectParserTests.testWithParserAdapter(TestData.createFamilyPerson(), parser -> { + testWithParserAdapter(TestData.createFamilyPerson(), parser -> { parser.next(); List values = parser.getObjectStream().collect(MAP_TO_LIST_COLLECTOR); @@ -574,7 +574,7 @@ void testGetObjectStream_GetList() { @Nested public class JSONPStandardParserTests { - private static void testWithStringParser(String json, Consumer consumer) { + private void testWithStringParser(String json, Consumer consumer) { try (JsonParser parser = Json.createParser(new StringReader(json))) { consumer.accept(parser); } From ef7da0aa24bb75905203178f05ee24b91d11552f Mon Sep 17 00:00:00 2001 From: Anton Pinsky Date: Fri, 9 Feb 2024 14:59:35 +0100 Subject: [PATCH 60/68] [#617] Changed the year to meanwhile 2024; dependecies / plugins update in POM; assertInstanceOf where this is possible Signed-off-by: Anton Pinsky --- .github/workflows/maven.yml | 4 ++-- etc/checkstyle.xml | 2 +- pom.xml | 23 ++++++++++--------- src/main/java/module-info.java | 2 +- .../eclipse/yasson/FieldAccessStrategy.java | 2 +- .../eclipse/yasson/JsonBindingProvider.java | 2 +- .../java/org/eclipse/yasson/YassonConfig.java | 2 +- .../java/org/eclipse/yasson/YassonJsonb.java | 2 +- .../org/eclipse/yasson/YassonProperties.java | 4 ++-- .../internal/AnnotationIntrospector.java | 2 +- .../yasson/internal/ComponentMatcher.java | 2 +- .../eclipse/yasson/internal/JsonBinding.java | 2 +- .../internal/JsonParserStreamCreator.java | 2 +- .../yasson/internal/ReflectionUtils.java | 2 +- .../VariableTypeInheritanceSearch.java | 2 +- .../components/AbstractComponentBinding.java | 2 +- .../internal/components/AdapterBinding.java | 2 +- .../BeanManagerInstanceCreator.java | 2 +- .../components/ComponentBindings.java | 2 +- .../components/DeserializerBinding.java | 2 +- .../components/SerializerBinding.java | 2 +- .../deserializer/AdapterDeserializer.java | 2 +- .../DeserializationModelCreator.java | 2 +- .../InheritanceInstanceCreator.java | 2 +- .../deserializer/MapDeserializer.java | 2 +- .../internal/deserializer/YassonParser.java | 2 +- .../types/AbstractNumberDeserializer.java | 2 +- .../deserializer/types/EnumDeserializer.java | 2 +- .../types/TypeDeserializerBuilder.java | 2 +- .../deserializer/types/TypeDeserializers.java | 2 +- .../jsonstructure/JsonObjectIterator.java | 2 +- .../jsonstructure/JsonStructureIterator.java | 2 +- .../JsonStructureToParserAdapter.java | 2 +- .../yasson/internal/model/CreatorModel.java | 2 +- .../yasson/internal/model/PropertyModel.java | 2 +- .../yasson/internal/model/ReverseTreeMap.java | 2 +- .../ComponentBoundCustomization.java | 2 +- .../customization/CustomizationBase.java | 2 +- .../customization/PropertyCustomization.java | 2 +- .../customization/StrategiesProvider.java | 2 +- .../serializer/AdapterSerializer.java | 2 +- .../serializer/SerializationModelCreator.java | 2 +- .../serializer/types/EnumSerializer.java | 2 +- .../java/org/eclipse/yasson/Assertions.java | 2 +- .../yasson/DefaultGetterInInterface.java | 2 +- .../yasson/FieldAccessStrategyTest.java | 5 ++-- .../java/org/eclipse/yasson/Issue454Test.java | 2 +- .../java/org/eclipse/yasson/Issue456Test.java | 2 +- .../yasson/JavaxNamingExcludedTest.java | 2 +- src/test/java/org/eclipse/yasson/Jsonbs.java | 2 +- .../java/org/eclipse/yasson/SimpleTest.java | 2 +- .../org/eclipse/yasson/TestTypeToken.java | 5 ++-- .../org/eclipse/yasson/YassonConfigTest.java | 2 +- .../eclipse/yasson/adapters/AdaptersTest.java | 2 +- .../yasson/adapters/JsonbTypeAdapterTest.java | 2 +- .../model/EnumWithJsonbPropertyAdapter.java | 5 ++-- .../model/LocalPolymorphicAdapter.java | 2 +- .../model/MultilevelAdapterClass.java | 2 +- .../yasson/adapters/model/NumberAdapter.java | 2 +- .../adapters/model/UUIDMapperClsBased.java | 2 +- .../adapters/model/UUIDMapperIfcBased.java | 2 +- .../yasson/adapters/model/Vegetables.java | 2 +- .../adapters/model/VegetablesAdapter.java | 2 +- .../yasson/customization/EncodingTest.java | 2 +- .../ImplementationClassTest.java | 4 ++-- .../customization/JsonbNillableTest.java | 2 +- .../customization/JsonbPropertyTest.java | 2 +- .../JsonbPropertyVisibilityStrategyTest.java | 2 +- .../customization/PropertyOrderTest.java | 4 ++-- .../YassonSpecificConfigTests.java | 2 +- .../MultiplePolymorphicInfoTest.java | 2 +- .../PolymorphismWithJsonValuesTest.java | 2 +- .../yasson/defaultmapping/IJsonTest.java | 2 +- .../defaultmapping/SecurityManagerTest.java | 2 +- .../collections/CollectionsTest.java | 2 +- .../defaultmapping/dates/DatesTest.java | 2 +- .../defaultmapping/generics/GenericsTest.java | 8 +++---- .../model/MultipleBoundsContainer.java | 2 +- .../defaultmapping/jsonp/JsonpTest.java | 10 ++++---- .../defaultmapping/specific/OptionalTest.java | 2 +- .../UnmarshallingUnsupportedTypesTest.java | 4 ++-- .../documented/DocumentationExampleTest.java | 2 +- .../yasson/internal/JsonBindingTest.java | 2 +- .../yasson/internal/cdi/CdiInjectionTest.java | 2 +- .../internal/cdi/MockInjectionTarget.java | 2 +- .../cdi/MockInjectionTargetFactory.java | 2 +- .../yasson/internal/cdi/WeldManager.java | 2 +- .../naming/PropertyNamingStrategyTest.java | 2 +- .../JsonGeneratorToStructureAdapterTest.java | 6 ++--- .../JsonStructureToParserAdapterTest.java | 10 ++++---- .../MapToEntriesArraySerializerTest.java | 9 ++++---- .../MapToObjectSerializerTest.java | 5 ++-- .../yasson/serializers/SerializersTest.java | 22 +++++++++--------- .../yasson/serializers/model/Cars.java | 2 +- .../yasson/serializers/model/Colors.java | 2 +- .../serializers/model/ColorsDeserializer.java | 2 +- .../serializers/model/ColorsSerializer.java | 2 +- .../yasson/serializers/model/Counter.java | 2 +- .../EnumWithJsonbPropertyDeserializer.java | 5 ++-- .../EnumWithJsonbPropertySerializer.java | 5 ++-- .../model/JsonParserTestDeserializers.java | 2 +- .../serializers/model/JsonParserTestPojo.java | 2 +- .../serializers/model/NumberDeserializer.java | 2 +- .../serializers/model/NumberSerializer.java | 2 +- .../serializers/model/TwoObjectsComparer.java | 2 +- 105 files changed, 156 insertions(+), 156 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 19c25ee5..564ef3be 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,5 +1,5 @@ # -# Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021, 2024 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 @@ -27,7 +27,7 @@ jobs: - name: Set up Maven uses: stCarolas/setup-maven@v4.5 with: - maven-version: 3.9.5 + maven-version: 3.9.6 - name: Checkout for build uses: actions/checkout@v2.3.4 with: diff --git a/etc/checkstyle.xml b/etc/checkstyle.xml index c9bc6a2a..69e6f2fe 100644 --- a/etc/checkstyle.xml +++ b/etc/checkstyle.xml @@ -1,7 +1,7 @@