Skip to content

Commit

Permalink
[eclipse-ee4j#617]User defined deserializer always should be used bef…
Browse files Browse the repository at this point in the history
…ore standard ones
  • Loading branch information
api-from-the-ion committed Oct 7, 2023
1 parent f371eb5 commit 444d929
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ private ModelDeserializer<JsonParser> deserializerChainInternal(LinkedList<Type>
models.put(cachedItem, deserializer);
return deserializer;
}

ClassCustomization classCustomization = classModel.getClassCustomization();
Optional<DeserializerBinding<?>> 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 = adapterBinding(type, (ComponentBoundCustomization) propertyCustomization);
if (adapterBinding.isPresent()) {
AdapterBinding adapter = adapterBinding.get();
Expand Down Expand Up @@ -201,14 +212,6 @@ private ModelDeserializer<JsonParser> createObjectDeserializer(LinkedList<Type>
Class<?> rawType,
CachedItem cachedItem) {
ClassCustomization classCustomization = classModel.getClassCustomization();
Optional<DeserializerBinding<?>> 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<String> params = hasCreator ? creatorParamsList(creator) : Collections.emptyList();
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
}

}
15 changes: 15 additions & 0 deletions src/test/java/org/eclipse/yasson/serializers/model/Colors.java
Original file line number Diff line number Diff line change
@@ -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
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.eclipse.yasson.serializers.model;

public class ColorsDeserializer extends EnumWithJsonbPropertyDeserializer<Colors> {

public ColorsDeserializer() {
super();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.eclipse.yasson.serializers.model;

public class ColorsSerializer extends EnumWithJsonbPropertySerializer<Colors> {
public ColorsSerializer() {
super();
}
}
Original file line number Diff line number Diff line change
@@ -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<E extends Enum<E>> implements JsonbDeserializer<E> {

private final Map<String, E> jsonToJavaMapping;

public EnumWithJsonbPropertyDeserializer() {
super();

Class<E> 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<E> 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 + "'"));
}
}
Original file line number Diff line number Diff line change
@@ -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<E extends Enum<E>> implements JsonbSerializer<E> {
private final EnumMap<E, String> javaToJsonMapping;

public EnumWithJsonbPropertySerializer() {
super();

Class<E> 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<E> 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));
}
}

0 comments on commit 444d929

Please sign in to comment.