This is an automated email from the ASF dual-hosted git repository. rmannibucau pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/johnzon.git
commit a5044f5fbc67849e7511735ed81ddfde1e56a945 Author: Xavier Dury <[email protected]> AuthorDate: Wed Apr 3 14:31:50 2019 +0200 Fix after review --- .../main/java/org/apache/johnzon/core/Types.java | 137 +++++++-------------- .../johnzon/jsonb/JsonValueParserAdapter.java | 21 +--- .../java/org/apache/johnzon/jsonb/MoreTests.java | 50 ++++++++ .../org/apache/johnzon/mapper/MapperConfig.java | 13 +- .../apache/johnzon/mapper/MappingParserImpl.java | 7 +- .../org/apache/johnzon/mapper/ObjectConverter.java | 12 +- .../mapper/ObjectConverterWithAnnotationTest.java | 5 +- .../org/apache/johnzon/mapper/ObjectTypeTest.java | 5 +- 8 files changed, 118 insertions(+), 132 deletions(-) diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/Types.java b/johnzon-core/src/main/java/org/apache/johnzon/core/Types.java index ec1baf9..037dc93 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/Types.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/Types.java @@ -17,105 +17,68 @@ * under the License. */ package org.apache.johnzon.core; - -import java.lang.reflect.GenericArrayType; + import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; import java.util.Arrays; public class Types { - - public static class TypeVisitor<T> { - - public T visit(Class<?> type) { - throw new UnsupportedOperationException("Visiting Class not supported."); - } - - public T visit(GenericArrayType type) { - throw new UnsupportedOperationException("Visiting GenericArrayType not supported."); - } - - public T visit(ParameterizedType type) { - throw new UnsupportedOperationException("Visiting ParameterizedType not supported."); - } - - public T visit(TypeVariable<?> type) { - throw new UnsupportedOperationException("Visiting TypeVariable not supported."); + + private static Type[] resolveArgumentTypes(Class<?> type, Class<?> superType) { + if (superType.equals(type)) { + // May return Class[] instead of Type[], so copy it as a Type[] to avoid + // problems in visit(ParameterizedType) + return Arrays.copyOf(type.getTypeParameters(), superType.getTypeParameters().length, Type[].class); } - - public T visit(WildcardType type) { - throw new UnsupportedOperationException("Visiting WildcardType not supported."); + if (type.getSuperclass() != null && superType.isAssignableFrom(type.getSuperclass())) { + return resolveArgumentTypes(type.getGenericSuperclass(), superType); } - - public final T visit(Type type) { - if (type instanceof Class<?>) { - return visit((Class<?>) type); - } - if (type instanceof ParameterizedType) { - return visit((ParameterizedType) type); + Class<?>[] interfaces = type.getInterfaces(); + Type[] genericInterfaces = type.getGenericInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (superType.isAssignableFrom(interfaces[i])) { + return resolveArgumentTypes(genericInterfaces[i], superType); } - if (type instanceof WildcardType) { - return visit((WildcardType) type); - } - if (type instanceof TypeVariable<?>) { - return visit((TypeVariable<?>) type); - } - if (type instanceof GenericArrayType) { - return visit((GenericArrayType) type); - } - throw new IllegalArgumentException(String.format("Unknown type: %s", type.getClass())); } + throw new IllegalArgumentException(String.format("%s is not assignable from %s", type, superType)); } - - private static class ArgumentTypeResolver extends TypeVisitor<Type[]> { - - private final Class<?> superType; - - public ArgumentTypeResolver(Class<?> superType) { - this.superType = superType; - } - - @Override - public Type[] visit(Class<?> type) { - if (this.superType.equals(type)) { - // May return Class[] instead of Type[], so copy it as a Type[] to avoid - // problems in visit(ParameterizedType) - return Arrays.copyOf(type.getTypeParameters(), superType.getTypeParameters().length, Type[].class); - } - if (type.getSuperclass() != null && this.superType.isAssignableFrom(type.getSuperclass())) { - return visit(type.getGenericSuperclass()); - } - Class<?>[] interfaces = type.getInterfaces(); - Type[] genericInterfaces = type.getGenericInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - if (this.superType.isAssignableFrom(interfaces[i])) { - return visit(genericInterfaces[i]); + + private static Type[] resolveArgumentTypes(ParameterizedType type, Class<?> superType) { + Class<?> rawType = (Class<?>) type.getRawType(); // always a Class + TypeVariable<?>[] typeVariables = rawType.getTypeParameters(); + Type[] types = resolveArgumentTypes(rawType, superType); + for (int i = 0; i < types.length; i++) { + if (types[i] instanceof TypeVariable<?>) { + TypeVariable<?> typeVariable = (TypeVariable<?>) types[i]; + for (int j = 0; j < typeVariables.length; j++) { + if (typeVariables[j].getName().equals(typeVariable.getName())) { + types[i] = type.getActualTypeArguments()[j]; + } } } - throw new IllegalArgumentException(String.format("%s is not assignable from %s", type, this.superType)); } + return types; + } - @Override - public Type[] visit(ParameterizedType type) { - Class<?> rawType = (Class<?>) type.getRawType(); // always a Class - TypeVariable<?>[] typeVariables = rawType.getTypeParameters(); - Type[] types = visit(rawType); - for (int i = 0; i < types.length; i++) { - if (types[i] instanceof TypeVariable<?>) { - TypeVariable<?> typeVariable = (TypeVariable<?>) types[i]; - for (int j = 0; j < typeVariables.length; j++) { - if (typeVariables[j].getName().equals(typeVariable.getName())) { - types[i] = type.getActualTypeArguments()[j]; - } - } - } - } - return types; + private static Type[] resolveArgumentTypes(Type type, Class<?> superClass) { + if (type instanceof Class<?>) { + return resolveArgumentTypes((Class<?>) type, superClass); + } + if (type instanceof ParameterizedType) { + return resolveArgumentTypes((ParameterizedType) type, superClass); } + throw new IllegalArgumentException("Cannot resolve argument types from " + type.getClass().getSimpleName()); } + public static ParameterizedType findParameterizedType(Type type, Class<?> superClass) { + return new ParameterizedTypeImpl(superClass, resolveArgumentTypes(type, superClass)); + } + + private Types() { + // no-op + } + private static class ParameterizedTypeImpl implements ParameterizedType { private final Type rawType; @@ -142,16 +105,4 @@ public class Types { } } - - public static Type[] resolveArgumentTypes(Type type, Class<?> superClass) { - return new ArgumentTypeResolver(superClass).visit(type); - } - - public static ParameterizedType findParameterizedType(Type type, Class<?> superClass) { - return new ParameterizedTypeImpl(superClass, resolveArgumentTypes(type, superClass)); - } - - private Types() { - // no-op - } } diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonValueParserAdapter.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonValueParserAdapter.java index d7b9991..803f679 100644 --- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonValueParserAdapter.java +++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonValueParserAdapter.java @@ -19,15 +19,11 @@ package org.apache.johnzon.jsonb; import java.math.BigDecimal; -import java.util.EnumSet; import java.util.function.Supplier; -import javax.json.JsonArray; import javax.json.JsonNumber; -import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; -import javax.json.JsonValue.ValueType; import javax.json.stream.JsonLocation; import javax.json.stream.JsonParser; import javax.json.stream.JsonParserFactory; @@ -74,18 +70,13 @@ class JsonValueParserAdapter<T extends JsonValue> implements JsonParser { } public static JsonParser createFor(JsonValue jsonValue, Supplier<JsonParserFactory> parserFactoryProvider) { - if (jsonValue instanceof JsonObject) { - return parserFactoryProvider.get().createParser((JsonObject) jsonValue); - } else if (jsonValue instanceof JsonArray) { - return parserFactoryProvider.get().createParser((JsonArray) jsonValue); - } else if (jsonValue instanceof JsonString) { - return new JsonStringParserAdapter((JsonString) jsonValue); - } else if (jsonValue instanceof JsonNumber) { - return new JsonNumberParserAdapter((JsonNumber) jsonValue); - } else if (EnumSet.of(ValueType.FALSE, ValueType.TRUE).contains(jsonValue.getValueType())) { - return new JsonValueParserAdapter<>(jsonValue); + switch (jsonValue.getValueType()) { + case OBJECT: return parserFactoryProvider.get().createParser(jsonValue.asJsonObject()); + case ARRAY: return parserFactoryProvider.get().createParser(jsonValue.asJsonArray()); + case STRING: return new JsonStringParserAdapter((JsonString) jsonValue); + case NUMBER: return new JsonNumberParserAdapter((JsonNumber) jsonValue); + default: return new JsonValueParserAdapter<>(jsonValue); } - throw new IllegalArgumentException("Cannot create JsonParser for " + jsonValue.getValueType()); } private final T jsonValue; diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/MoreTests.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/MoreTests.java index f205ff0..f813cef 100644 --- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/MoreTests.java +++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/MoreTests.java @@ -21,7 +21,9 @@ package org.apache.johnzon.jsonb; import java.io.StringWriter; import java.lang.reflect.Type; import java.util.UUID; +import java.util.stream.Collectors; +import javax.json.JsonString; import javax.json.JsonValue; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; @@ -40,6 +42,11 @@ import org.junit.Test; public class MoreTests { + public enum Color { + + RED, GREEN, BLUE + } + // Does not seem to work with enums public static class Option { @@ -126,6 +133,39 @@ public class MoreTests { generator.write(obj.getValue()); } } + + public static class CharsDeSer implements JsonbSerializer<String>, JsonbDeserializer<String> { + + @Override + public String deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + return parser.getArrayStream().map(JsonString.class::cast).map(JsonString::getString).collect(Collectors.joining()); + } + + @Override + public void serialize(String obj, JsonGenerator generator, SerializationContext ctx) { + generator.writeStartArray(); + obj.chars().forEach(c -> generator.write(Character.toString((char) c))); + generator.writeEnd(); + } + } + + public static class ColorDeSer implements JsonbSerializer<Color>, JsonbDeserializer<Color> { + + @Override + public Color deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) { + switch (parser.getString()) { + case "R" : return Color.RED; + case "G" : return Color.GREEN; + case "B" : return Color.BLUE; + default : throw new IllegalArgumentException(); + } + } + + @Override + public void serialize(Color obj, JsonGenerator generator, SerializationContext ctx) { + generator.write(obj.name().substring(0, 1)); + } + } public static class Wrapper { @@ -143,6 +183,16 @@ public class MoreTests { @JsonbTypeSerializer(VATDeSer.class) @JsonbTypeDeserializer(VATDeSer.class) public VATNumber vatNumber = new VATNumber(42); + +// @JsonbTypeSerializer(CharsDeSer.class) +// @JsonbTypeDeserializer(CharsDeSer.class) + // TODO Not working as @JsonbTypeSerializer seems to be ignored ("hello world" instead of ["h", "e"...]) + public String hello = "hello world"; + +// @JsonbTypeSerializer(ColorDeSer.class) +// @JsonbTypeDeserializer(ColorDeSer.class) + // TODO Not working as @JsonbTypeSerializer seems to be ignored ("GREEN" instead of "G") + public Color color = Color.GREEN; } diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java index f469a2b..f6aa057 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java @@ -18,6 +18,12 @@ */ package org.apache.johnzon.mapper; +import org.apache.johnzon.mapper.access.AccessMode; +import org.apache.johnzon.mapper.converter.EnumConverter; +import org.apache.johnzon.mapper.internal.AdapterKey; +import org.apache.johnzon.mapper.internal.ConverterAdapter; + +import javax.json.JsonValue; import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.Comparator; @@ -25,13 +31,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentMap; -import javax.json.JsonValue; - -import org.apache.johnzon.mapper.access.AccessMode; -import org.apache.johnzon.mapper.converter.EnumConverter; -import org.apache.johnzon.mapper.internal.AdapterKey; -import org.apache.johnzon.mapper.internal.ConverterAdapter; - /** * Contains internal configuration for all the mapper stuff. * It needs to be immutable and 100% runtime oriented. diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java index 18b3298..198c573 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java @@ -33,7 +33,6 @@ import javax.json.JsonReader; import javax.json.JsonString; import javax.json.JsonStructure; import javax.json.JsonValue; -import javax.json.JsonValue.ValueType; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; @@ -729,12 +728,10 @@ public class MappingParserImpl implements MappingParser { if (objectConverter != null) { - if (EnumSet.of(ValueType.OBJECT, ValueType.NUMBER, ValueType.STRING, ValueType.FALSE, ValueType.TRUE).contains(jsonValue.getValueType())) { - return objectConverter.fromJson(jsonValue, type, this); - } else if (jsonValue instanceof JsonArray) { + if (jsonValue instanceof JsonArray) { return buildArray(type, jsonValue.asJsonArray(), itemConverter, objectConverter, jsonPointer, rootType); } else { - throw new UnsupportedOperationException("Array handling with ObjectConverter currently not implemented"); + return objectConverter.fromJson(jsonValue, type, this); } } diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ObjectConverter.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ObjectConverter.java index 4a5db20..a468c73 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ObjectConverter.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ObjectConverter.java @@ -18,16 +18,16 @@ */ package org.apache.johnzon.mapper; -import java.lang.reflect.Type; - import javax.json.JsonValue; +import java.lang.reflect.Type; + /** - * Convert a given Java Type a nested JSON representation. - * And the other way around. + * Convert a given Java Type a nested JSON representation. And the other way + * around. * - * An example would be to convert a custom Project POJO, like Dog.class - * to it's JSON representation + * An example would be to convert a custom Project POJO, like Dog.class to it's + * JSON representation * */ public final class ObjectConverter { diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java index 2c00f32..9c79c7e 100644 --- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import javax.json.JsonObject; import javax.json.JsonValue; import java.beans.ConstructorProperties; @@ -398,8 +397,8 @@ public class ObjectConverterWithAnnotationTest { @Override public Bike fromJson(JsonValue jsonObject, Type targetType, MappingParser parser) { - return new Bike(MANUFACTURERS.get(((JsonObject) jsonObject).getInt(MANUFACTURER_ID)), - BikeType.values()[((JsonObject) jsonObject).getInt(TYPE_INDEX)]); + return new Bike(MANUFACTURERS.get(jsonObject.asJsonObject().getInt(MANUFACTURER_ID)), + BikeType.values()[jsonObject.asJsonObject().getInt(TYPE_INDEX)]); } } } diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java index e4a56e0..785cdbf 100644 --- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java @@ -24,7 +24,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import javax.json.JsonObject; import javax.json.JsonValue; import java.lang.reflect.ParameterizedType; @@ -208,7 +207,7 @@ public class ObjectTypeTest { @Override public Dog fromJson(JsonValue jsonObject, Type targetType, MappingParser parser) { - String javaType = ((JsonObject) jsonObject).getString("//javaType"); + String javaType = jsonObject.asJsonObject().getString("//javaType"); Class targetClass = javaType != null ? getSubClass(targetType, javaType) : (Class) targetType; return parser.readObject(jsonObject, targetClass); @@ -427,7 +426,7 @@ public class ObjectTypeTest { @Override public Poodle fromJson(JsonValue jsonObject, Type targetType, MappingParser parser) { - return POODLES.get(((JsonObject) jsonObject).getString("poodleName")); + return POODLES.get(jsonObject.asJsonObject().getString("poodleName")); } }
