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 e582a7412..0ac3f980a 100644 --- a/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.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 @@ -269,9 +269,10 @@ private ModelDeserializer createCollectionDeserializer(CachedItem ca ? ((ParameterizedType) type).getActualTypeArguments()[0] : Object.class; colType = ReflectionUtils.resolveType(chain, colType); + ClassModel classModel = jsonbContext.getMappingContext().getOrCreateClassModel(ReflectionUtils.getRawType(colType)); ModelDeserializer typeProcessor = typeProcessor(chain, colType, - propertyCustomization, + classModel.getClassCustomization(), JustReturn.instance()); CollectionDeserializer collectionDeserializer = new CollectionDeserializer(typeProcessor); CollectionInstanceCreator instanceDeserializer = new CollectionInstanceCreator(collectionDeserializer, type); 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 de8942e1f..315fe4a85 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/SerializationModelCreator.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 @@ -286,7 +286,10 @@ private ModelSerializer createCollectionSerializer(LinkedList chain, Type colType = type instanceof ParameterizedType ? ((ParameterizedType) type).getActualTypeArguments()[0] : Object.class; - ModelSerializer typeSerializer = memberSerializer(chain, colType, customization, false); + Type resolvedKey = ReflectionUtils.resolveType(chain, colType); + Class rawClass = ReflectionUtils.getRawType(resolvedKey); + ClassModel classModel = jsonbContext.getMappingContext().getOrCreateClassModel(rawClass); + ModelSerializer typeSerializer = memberSerializer(chain, colType, classModel.getClassCustomization(), false); CollectionSerializer collectionSerializer = new CollectionSerializer(typeSerializer); KeyWriter keyWriter = new KeyWriter(collectionSerializer); NullVisibilitySwitcher nullVisibilitySwitcher = new NullVisibilitySwitcher(true, keyWriter); diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java index 8557f7615..db0efdf18 100644 --- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java +++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 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 @@ -51,6 +51,8 @@ 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.Containee; +import org.eclipse.yasson.serializers.model.Container; import org.eclipse.yasson.serializers.model.Crate; import org.eclipse.yasson.serializers.model.CrateDeserializer; import org.eclipse.yasson.serializers.model.CrateDeserializerWithConversion; @@ -797,4 +799,17 @@ public void testBoxToArray() { assertThat(jsonb.toJson(box), is(expected)); } + @Test + public void testCustomSerializersInContainer(){ + Jsonb jsonb = JsonbBuilder.create(); + + Container expected = new Container(List.of(new Containee("k", "v"))); + + String expectedJson = jsonb.toJson(expected); + System.out.println(expectedJson); + + assertEquals(expected, jsonb.fromJson(expectedJson, Container.class)); + + } + } diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Containee.java b/src/test/java/org/eclipse/yasson/serializers/model/Containee.java new file mode 100644 index 000000000..ada2d4668 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/Containee.java @@ -0,0 +1,47 @@ +/* + * 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.Objects; + +import jakarta.json.bind.annotation.JsonbTypeDeserializer; +import jakarta.json.bind.annotation.JsonbTypeSerializer; + +@JsonbTypeDeserializer(ContaineeDeserializer.class) +@JsonbTypeSerializer(ContaineeSerializer.class) +public class Containee { + final String key; + final String value; + + public Containee(String key, String value) { + this.key = key; + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Containee containee = (Containee) o; + return Objects.equals(key, containee.key) && Objects.equals(value, containee.value); + } + + @Override + public int hashCode() { + return Objects.hash(key, value); + } +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ContaineeDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ContaineeDeserializer.java new file mode 100644 index 000000000..232738057 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/ContaineeDeserializer.java @@ -0,0 +1,41 @@ +/* + * 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 jakarta.json.bind.serializer.DeserializationContext; +import jakarta.json.bind.serializer.JsonbDeserializer; +import jakarta.json.stream.JsonParser; + +public class ContaineeDeserializer implements JsonbDeserializer { + + @Override + public Containee deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + String key = null; + String value = ""; + while (parser.hasNext()) { + var event = parser.next(); + if (event == JsonParser.Event.KEY_NAME && parser.getString().equals("key")) { + parser.next(); // move to VALUE + key = parser.getString(); + } else if (event == JsonParser.Event.KEY_NAME && parser.getString().equals("value")) { + parser.next(); // move to VALUE + value = parser.getString(); + } + } + assert key != null; + return new Containee(key, value); + } + +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/ContaineeSerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/ContaineeSerializer.java new file mode 100644 index 000000000..152e9ab5d --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/ContaineeSerializer.java @@ -0,0 +1,29 @@ +/* + * 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.serializer.JsonbSerializer; +import jakarta.json.bind.serializer.SerializationContext; +import jakarta.json.stream.JsonGenerator; + +public class ContaineeSerializer implements JsonbSerializer { + + @Override + public void serialize(Containee obj, JsonGenerator generator, SerializationContext ctx) { + generator.writeStartObject(); + generator.write("key", obj.key); + generator.write("value", obj.value); + generator.writeEnd(); + } + +} diff --git a/src/test/java/org/eclipse/yasson/serializers/model/Container.java b/src/test/java/org/eclipse/yasson/serializers/model/Container.java new file mode 100644 index 000000000..8c732fba7 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/model/Container.java @@ -0,0 +1,55 @@ +/* + * 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.ArrayList; +import java.util.List; +import java.util.Objects; + +public class Container { + + private List containees; + + public Container() { + containees = new ArrayList<>(); + } + + public Container(List containees) { + this.containees = containees; + } + + public void setContainees(List containees) { + this.containees = containees; + } + + public List getContainees() { + return containees; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Container container = (Container) o; + return Objects.equals(containees, container.containees); + } + + @Override + public int hashCode() { + return Objects.hash(containees); + } +}