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 69ea3926c00d4e4cffa86ae0ebdcc2b8185bad31
Author: Xavier Dury <[email protected]>
AuthorDate: Tue Apr 2 19:58:45 2019 +0200

    Fixed deserialization of primitives
    Serializers, Deserializers and Adapters ParameterizedTypes can be
    retrieved on super-classes/interfaces
---
 .../main/java/org/apache/johnzon/core/Types.java   | 157 +++++++++++++++++++++
 .../java/org/apache/johnzon/core/TypesTest.java    |  48 +++++++
 .../org/apache/johnzon/jsonb/JohnzonBuilder.java   |  21 +--
 .../johnzon/jsonb/JsonValueParserAdapter.java      | 146 +++++++++++++++++++
 .../org/apache/johnzon/jsonb/JsonbAccessMode.java  |  25 +---
 .../johnzon/jsonb/JohnzonConverterInJsonbTest.java |   5 +-
 .../java/org/apache/johnzon/jsonb/MoreTests.java   | 156 ++++++++++++++++++++
 .../org/apache/johnzon/mapper/MapperConfig.java    |  15 +-
 .../apache/johnzon/mapper/MappingParserImpl.java   |   7 +-
 .../org/apache/johnzon/mapper/ObjectConverter.java |   5 +-
 .../apache/johnzon/mapper/MapperConfigTest.java    |   7 +-
 .../mapper/ObjectConverterWithAnnotationTest.java  |   8 +-
 .../org/apache/johnzon/mapper/ObjectTypeTest.java  |  10 +-
 13 files changed, 551 insertions(+), 59 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
new file mode 100644
index 0000000..ec1baf9
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/Types.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * 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.");
+        }
+
+        public T visit(WildcardType type) {
+            throw new UnsupportedOperationException("Visiting WildcardType not 
supported.");
+        }
+
+        public final T visit(Type type) {
+            if (type instanceof Class<?>) {
+                return visit((Class<?>) type);
+            }
+            if (type instanceof ParameterizedType) {
+                return visit((ParameterizedType) type);
+            }
+            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()));
+        }
+    }
+
+    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]);
+                }
+            }
+            throw new IllegalArgumentException(String.format("%s is not 
assignable from %s", type, this.superType));
+        }
+
+        @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 class ParameterizedTypeImpl implements ParameterizedType {
+
+        private final Type rawType;
+        private final Type[] arguments;
+
+        public ParameterizedTypeImpl(Type rawType, Type... arguments) {
+            this.rawType = rawType;
+            this.arguments = arguments;
+        }
+
+        @Override
+        public Type getRawType() {
+            return rawType;
+        }
+
+        @Override
+        public Type getOwnerType() {
+            return null;
+        }
+
+        @Override
+        public Type[] getActualTypeArguments() {
+            return arguments;
+        }
+
+    }
+
+    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-core/src/test/java/org/apache/johnzon/core/TypesTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/TypesTest.java
new file mode 100644
index 0000000..8e1fc20
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/TypesTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.core;
+
+import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TypesTest {
+    
+    interface GenericInterface<X, Y> {}
+    
+    interface PartialInterface<X> extends Serializable, 
GenericInterface<Integer, X> {}
+    
+    static abstract class AbstractClass<Z, Y> implements PartialInterface<Y> {}
+    
+    static class ConcreteClass extends AbstractClass<String, Boolean> {}
+    
+    @Test
+    public void test() {
+        ParameterizedType parameterizedType = 
Types.findParameterizedType(ConcreteClass.class, GenericInterface.class);
+        
+        
Assert.assertTrue(Arrays.deepEquals(parameterizedType.getActualTypeArguments(), 
new Type[] {
+                Integer.class,
+                Boolean.class
+        }));
+    }
+}
diff --git 
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java 
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index d146d79..7189a5d 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -84,6 +84,7 @@ import javax.json.stream.JsonParserFactory;
 import org.apache.johnzon.core.AbstractJsonFactory;
 import org.apache.johnzon.core.JsonGeneratorFactoryImpl;
 import org.apache.johnzon.core.JsonParserFactoryImpl;
+import org.apache.johnzon.core.Types;
 import org.apache.johnzon.jsonb.cdi.CDIs;
 import org.apache.johnzon.jsonb.converter.JohnzonJsonbAdapter;
 import org.apache.johnzon.jsonb.factory.SimpleJohnzonAdapterFactory;
@@ -274,10 +275,7 @@ public class JohnzonBuilder implements JsonbBuilder {
 
         
config.getProperty(JsonbConfig.SERIALIZERS).map(JsonbSerializer[].class::cast).ifPresent(serializers
 -> {
             Stream.of(serializers).forEach(s -> {
-                final ParameterizedType pt = findPT(s, JsonbSerializer.class);
-                if (pt == null) {
-                    throw new IllegalArgumentException(s + " doesn't implement 
JsonbSerializer");
-                }
+                final ParameterizedType pt = 
Types.findParameterizedType(s.getClass(), JsonbSerializer.class);
                 final Type[] args = pt.getActualTypeArguments();
                 // TODO: support PT in ObjectConverter (list)
                 if (args.length != 1 || !Class.class.isInstance(args[0])) {
@@ -292,10 +290,7 @@ public class JohnzonBuilder implements JsonbBuilder {
         });
         
config.getProperty(JsonbConfig.DESERIALIZERS).map(JsonbDeserializer[].class::cast).ifPresent(deserializers
 -> {
             Stream.of(deserializers).forEach(d -> {
-                final ParameterizedType pt = findPT(d, 
JsonbDeserializer.class);
-                if (pt == null) {
-                    throw new IllegalArgumentException(d + " doesn't implement 
JsonbDeserializer");
-                }
+                final ParameterizedType pt = 
Types.findParameterizedType(d.getClass(), JsonbDeserializer.class);
                 final Type[] args = pt.getActualTypeArguments();
                 if (args.length != 1 || !Class.class.isInstance(args[0])) {
                     throw new IllegalArgumentException("We only support 
deserializer on Class for now");
@@ -304,7 +299,7 @@ public class JohnzonBuilder implements JsonbBuilder {
                 builder.addObjectConverter(
                         Class.class.cast(args[0]), (ObjectConverter.Reader)
                                 (jsonObject, targetType, parser) -> 
d.deserialize(
-                                        
parserFactoryProvider.get().createParser(jsonObject), new 
JohnzonDeserializationContext(parser), targetType));
+                                        
JsonValueParserAdapter.createFor(jsonObject, parserFactoryProvider), new 
JohnzonDeserializationContext(parser), targetType));
             });
         });
 
@@ -331,6 +326,7 @@ public class JohnzonBuilder implements JsonbBuilder {
             }
         } : new JohnzonJsonb(mapper);
     }
+    
 
     private AccessMode toAccessMode(final Object s) {
         if (String.class.isInstance(s)) {
@@ -368,13 +364,6 @@ public class JohnzonBuilder implements JsonbBuilder {
         };
     }
 
-    private ParameterizedType findPT(final Object s, final Class<?> type) {
-        return ParameterizedType.class.cast(
-                Stream.of(s.getClass().getGenericInterfaces())
-                        .filter(i -> ParameterizedType.class.isInstance(i) && 
ParameterizedType.class.cast(i).getRawType() == type)
-                        .findFirst().orElse(null));
-    }
-
     private Object getBeanManager() {
         if (beanManager == null) {
             try { // don't trigger CDI if not there
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
new file mode 100644
index 0000000..d7b9991
--- /dev/null
+++ 
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonValueParserAdapter.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+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;
+
+class JsonValueParserAdapter<T extends JsonValue> implements JsonParser {
+    
+    private static class JsonStringParserAdapter extends 
JsonValueParserAdapter<JsonString> {
+
+        public JsonStringParserAdapter(JsonString jsonValue) {
+            super(jsonValue);
+        }
+        
+        @Override
+        public String getString() {
+            return getValue().getString();
+        }
+    }
+    
+    private static class JsonNumberParserAdapter extends 
JsonValueParserAdapter<JsonNumber> {
+        
+        public JsonNumberParserAdapter(JsonNumber jsonValue) {
+            super(jsonValue);
+        }
+
+        @Override
+        public boolean isIntegralNumber() {
+            return getValue().isIntegral();
+        }
+
+        @Override
+        public int getInt() {
+            return getValue().intValueExact();
+        }
+
+        @Override
+        public long getLong() {
+            return getValue().longValueExact();
+        }
+
+        @Override
+        public BigDecimal getBigDecimal() {
+            return getValue().bigDecimalValue();
+        }
+    }
+    
+    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);
+        }
+        throw new IllegalArgumentException("Cannot create JsonParser for " + 
jsonValue.getValueType());
+    }
+    
+    private final T jsonValue;
+    
+    JsonValueParserAdapter(T jsonValue) {
+        this.jsonValue = jsonValue;
+    }
+
+    @Override
+    public boolean hasNext() {
+        return false;
+    }
+
+    @Override
+    public Event next() {
+        throw new UnsupportedOperationException("next() no supported for " + 
jsonValue.getValueType());
+    }
+
+    @Override
+    public String getString() {
+        throw new UnsupportedOperationException("next() no supported for " + 
jsonValue.getValueType());
+    }
+
+    @Override
+    public boolean isIntegralNumber() {
+        throw new UnsupportedOperationException("isIntegralNumber() not 
supported for " + jsonValue.getValueType());
+    }
+
+    @Override
+    public int getInt() {
+        throw new UnsupportedOperationException("getInt() not supported for " 
+ jsonValue.getValueType());
+    }
+
+    @Override
+    public long getLong() {
+        throw new UnsupportedOperationException("getLong() not supported for " 
+ jsonValue.getValueType());
+    }
+
+    @Override
+    public BigDecimal getBigDecimal() {
+        throw new UnsupportedOperationException("getBigDecimal() not supported 
for " + jsonValue.getValueType());
+    }
+
+    @Override
+    public JsonLocation getLocation() {
+        throw new UnsupportedOperationException("getLocation() not supported 
for " + jsonValue.getValueType());
+    }
+
+    @Override
+    public void close() {
+        // no-op
+    }
+    
+    @Override
+    public T getValue() {
+        return jsonValue;
+    }
+}
diff --git 
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java 
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
index e5718fb..c0fcd33 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
@@ -18,6 +18,7 @@
  */
 package org.apache.johnzon.jsonb;
 
+import org.apache.johnzon.core.Types;
 import org.apache.johnzon.jsonb.converter.JohnzonJsonbAdapter;
 import org.apache.johnzon.jsonb.converter.JsonbDateConverter;
 import org.apache.johnzon.jsonb.converter.JsonbLocalDateConverter;
@@ -63,6 +64,7 @@ import javax.json.bind.config.PropertyVisibilityStrategy;
 import javax.json.bind.serializer.JsonbDeserializer;
 import javax.json.bind.serializer.JsonbSerializer;
 import javax.json.stream.JsonParserFactory;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
@@ -335,10 +337,7 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
         final Adapter converter;
         if (adapter != null) {
             final Class<? extends JsonbAdapter> value = adapter.value();
-            final ParameterizedType pt = findPt(value, JsonbAdapter.class);
-            if (pt == null) {
-                throw new IllegalArgumentException(value + " doesn't implement 
JsonbAdapter");
-            }
+            final ParameterizedType pt = Types.findParameterizedType(value, 
JsonbAdapter.class);
             final JohnzonAdapterFactory.Instance<? extends JsonbAdapter> 
instance = newInstance(value);
             toRelease.add(instance);
             final Type[] actualTypeArguments = pt.getActualTypeArguments();
@@ -363,12 +362,6 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
         return converter;
     }
 
-    private ParameterizedType findPt(final Class<?> value, final Class<?> 
type) {
-        return ParameterizedType.class.cast(
-                Stream.of(value.getGenericInterfaces())
-                        .filter(i -> ParameterizedType.class.isInstance(i) && 
ParameterizedType.class.cast(i).getRawType() == type).findFirst().orElse(null));
-    }
-
     private JohnzonAdapterFactory.Instance newInstance(final Class<?> value) {
         return factory.create(value);
     }
@@ -736,14 +729,11 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
 
             if (deserializer != null) {
                 final Class<? extends JsonbDeserializer> value = 
deserializer.value();
-                final ParameterizedType pt = findPt(value, 
JsonbDeserializer.class);
-                if (pt == null) {
-                    throw new IllegalArgumentException(value + " doesn't 
implement JsonbDeserializer");
-                }
+                final ParameterizedType pt = 
Types.findParameterizedType(value, JsonbDeserializer.class);
                 final JohnzonAdapterFactory.Instance<? extends 
JsonbDeserializer> instance = newInstance(value);
                 toRelease.add(instance);
                 reader = (jsonObject, targetType, parser) ->
-                        
instance.getValue().deserialize(parserFactory.get().createParser(jsonObject), 
new JohnzonDeserializationContext(parser), targetType);
+                        
instance.getValue().deserialize(JsonValueParserAdapter.createFor(jsonObject, 
parserFactory), new JohnzonDeserializationContext(parser), targetType);
             } else if (johnzonConverter != null) {
                 try {
                     MapperConverter mapperConverter = 
johnzonConverter.value().newInstance();
@@ -781,10 +771,7 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
 
             if (serializer != null) {
                 final Class<? extends JsonbSerializer> value = 
serializer.value();
-                final ParameterizedType pt = findPt(value, 
JsonbSerializer.class);
-                if (pt == null) {
-                    throw new IllegalArgumentException(value + " doesn't 
implement JsonbSerializer");
-                }
+                final ParameterizedType pt = 
Types.findParameterizedType(value, JsonbSerializer.class);
                 final JohnzonAdapterFactory.Instance<? extends 
JsonbSerializer> instance = newInstance(value);
                 toRelease.add(instance);
                 writer = (instance1, jsonbGenerator) ->
diff --git 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JohnzonConverterInJsonbTest.java
 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JohnzonConverterInJsonbTest.java
index f9de06a..c72cac5 100644
--- 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JohnzonConverterInJsonbTest.java
+++ 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JohnzonConverterInJsonbTest.java
@@ -24,6 +24,7 @@ import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 
 import javax.json.JsonObject;
+import javax.json.JsonValue;
 import javax.json.bind.Jsonb;
 import javax.json.bind.spi.JsonbProvider;
 
@@ -92,9 +93,9 @@ public class JohnzonConverterInJsonbTest {
         }
 
         @Override
-        public TestDTO fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
+        public TestDTO fromJson(JsonValue jsonValue, Type targetType, 
MappingParser parser) {
             TestDTO dto = new TestDTO();
-            dto.instant = 
ZonedDateTime.parse(jsonObject.getString(TIMESTAMP_JSON_KEY)).toInstant();
+            dto.instant = ZonedDateTime.parse(((JsonObject) 
jsonValue).getString(TIMESTAMP_JSON_KEY)).toInstant();
             return dto;
         }
     }
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
new file mode 100644
index 0000000..f205ff0
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/MoreTests.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.jsonb;
+
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.util.UUID;
+
+import javax.json.JsonValue;
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.adapter.JsonbAdapter;
+import javax.json.bind.annotation.JsonbTypeAdapter;
+import javax.json.bind.annotation.JsonbTypeDeserializer;
+import javax.json.bind.annotation.JsonbTypeSerializer;
+import javax.json.bind.serializer.DeserializationContext;
+import javax.json.bind.serializer.JsonbDeserializer;
+import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.bind.serializer.SerializationContext;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonParser;
+
+import org.junit.Test;
+
+public class MoreTests {
+    
+    // Does not seem to work with enums
+    public static class Option {
+        
+        public static final Option YES = new Option(true);
+        public static final Option NO = new Option(false);
+        
+        private final boolean value;
+        
+        private Option(boolean value) {
+            this.value = value;
+        }
+
+        public boolean asBoolean() {
+            return value;
+        }
+        
+        public static Option of(boolean value) {
+            return value ? YES : NO;
+        }
+    }
+    
+    public static class VATNumber {
+        
+        private final long value;
+
+        public VATNumber(long value) {
+            this.value = value;
+        }
+        
+        public long getValue() {
+            return value;
+        }
+    }
+    
+    public interface Composite<T, X> extends JsonbSerializer<T>, 
JsonbDeserializer<T>, JsonbAdapter<T, X> {}
+    
+    public static abstract class AbstractComposite<T, X> implements 
Composite<T, X> {}
+    
+    public static abstract class StringValueComposite<T> extends 
AbstractComposite<T, String> {}
+    
+    public static class UUIDComposite extends StringValueComposite<UUID> {
+        
+        public void serialize(UUID obj, JsonGenerator generator, 
SerializationContext ctx) {
+            generator.write(obj.toString());
+        }
+        
+        public UUID deserialize(JsonParser parser, DeserializationContext ctx, 
Type rtType) {
+            return UUID.fromString(parser.getString());
+        }
+
+        @Override
+        public UUID adaptFromJson(String obj) throws Exception {
+            return UUID.fromString(obj);
+        }
+        
+        @Override
+        public String adaptToJson(UUID obj) throws Exception {
+            return obj.toString();
+        }
+    }
+    
+    public static class OptionDeSer implements JsonbSerializer<Option>, 
JsonbDeserializer<Option> {
+
+        @Override
+        public Option deserialize(JsonParser parser, DeserializationContext 
ctx, Type rtType) {
+            return Option.of(parser.getValue().equals(JsonValue.TRUE));
+        }
+
+        @Override
+        public void serialize(Option obj, JsonGenerator generator, 
SerializationContext ctx) {
+            generator.write(obj.asBoolean());
+        }
+    }
+    
+    public static class VATDeSer implements JsonbSerializer<VATNumber>, 
JsonbDeserializer<VATNumber> {
+
+        @Override
+        public VATNumber deserialize(JsonParser parser, DeserializationContext 
ctx, Type rtType) {
+            return new VATNumber(parser.getLong());
+        }
+
+        @Override
+        public void serialize(VATNumber obj, JsonGenerator generator, 
SerializationContext ctx) {
+            generator.write(obj.getValue());
+        }
+    }
+
+    public static class Wrapper {
+        
+        @JsonbTypeSerializer(UUIDComposite.class)
+        @JsonbTypeDeserializer(UUIDComposite.class)
+        public UUID uuid = UUID.randomUUID();
+
+        @JsonbTypeAdapter(UUIDComposite.class)
+        public UUID uuid2 = UUID.randomUUID();
+        
+        @JsonbTypeSerializer(OptionDeSer.class)
+        @JsonbTypeDeserializer(OptionDeSer.class)
+        public Option option = Option.YES;
+        
+        @JsonbTypeSerializer(VATDeSer.class)
+        @JsonbTypeDeserializer(VATDeSer.class)
+        public VATNumber vatNumber = new VATNumber(42);
+        
+    }
+
+    @Test
+    public void testIt() {
+        Jsonb jsonb = JsonbBuilder.create();
+        StringWriter w = new StringWriter();
+        jsonb.toJson(new Wrapper(), w);
+        jsonb.fromJson(w.toString(), Wrapper.class);
+    }
+}
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 fd7d9db..f469a2b 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,12 +18,6 @@
  */
 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.JsonObject;
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
 import java.util.Comparator;
@@ -31,6 +25,13 @@ 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.
@@ -44,7 +45,7 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig 
implements Cloneable {
         }
 
         @Override
-        public Object fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
+        public Object fromJson(JsonValue jsonObject, Type targetType, 
MappingParser parser) {
             return null;
         }
     };
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 4ad1633..18b3298 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,6 +33,7 @@ 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;
@@ -727,9 +728,9 @@ public class MappingParserImpl implements MappingParser {
                            final JsonPointerTracker jsonPointer, final Type 
rootType) {
 
         if (objectConverter != null) {
-
-            if (jsonValue instanceof JsonObject) {
-                return objectConverter.fromJson((JsonObject) jsonValue, type, 
this);
+            
+            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) {
                 return buildArray(type, jsonValue.asJsonArray(), 
itemConverter, objectConverter, jsonPointer, rootType);
             } else {
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 03ce47e..4a5db20 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,9 +18,10 @@
  */
 package org.apache.johnzon.mapper;
 
-import javax.json.JsonObject;
 import java.lang.reflect.Type;
 
+import javax.json.JsonValue;
+
 /**
  * Convert a given Java Type a nested JSON representation.
  * And the other way around.
@@ -39,7 +40,7 @@ public final class ObjectConverter {
     }
 
     public interface Reader<T> extends MapperConverter {
-        T fromJson(JsonObject jsonObject, Type targetType, MappingParser 
parser);
+        T fromJson(JsonValue jsonValue, Type targetType, MappingParser parser);
     }
 
     public interface Codec<T> extends ObjectConverter.Writer<T>, 
ObjectConverter.Reader<T> {
diff --git 
a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java 
b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
index f1348fb..c447606 100644
--- 
a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
+++ 
b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
@@ -25,7 +25,8 @@ import org.apache.johnzon.mapper.internal.AdapterKey;
 import org.junit.Assert;
 import org.junit.Test;
 
-import javax.json.JsonObject;
+import javax.json.JsonValue;
+
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
 import java.util.Collections;
@@ -191,7 +192,7 @@ public class MapperConfigTest {
         }
 
         @Override
-        public T fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
+        public T fromJson(JsonValue jsonObject, Type targetType, MappingParser 
parser) {
             // dummy
             return null;
         }
@@ -204,7 +205,7 @@ public class MapperConfigTest {
         }
 
         @Override
-        public T fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
+        public T fromJson(JsonValue jsonObject, Type targetType, MappingParser 
parser) {
             // dummy
             return null;
         }
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 c465f8b..2c00f32 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
@@ -24,6 +24,8 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import javax.json.JsonObject;
+import javax.json.JsonValue;
+
 import java.beans.ConstructorProperties;
 import java.lang.reflect.Type;
 import java.util.Arrays;
@@ -395,9 +397,9 @@ public class ObjectConverterWithAnnotationTest {
         }
 
         @Override
-        public Bike fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
-            return new 
Bike(MANUFACTURERS.get(jsonObject.getInt(MANUFACTURER_ID)),
-                            BikeType.values()[jsonObject.getInt(TYPE_INDEX)]);
+        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)]);
         }
     }
 }
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 adfe0e5..e4a56e0 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
@@ -25,6 +25,8 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import javax.json.JsonObject;
+import javax.json.JsonValue;
+
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -205,8 +207,8 @@ public class ObjectTypeTest {
         }
 
         @Override
-        public Dog fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
-            String javaType = jsonObject.getString("//javaType");
+        public Dog fromJson(JsonValue jsonObject, Type targetType, 
MappingParser parser) {
+            String javaType = ((JsonObject) 
jsonObject).getString("//javaType");
             Class targetClass = javaType != null ? getSubClass(targetType, 
javaType) : (Class) targetType;
 
             return parser.readObject(jsonObject, targetClass);
@@ -424,8 +426,8 @@ public class ObjectTypeTest {
         }
 
         @Override
-        public Poodle fromJson(JsonObject jsonObject, Type targetType, 
MappingParser parser) {
-            return POODLES.get(jsonObject.getString("poodleName"));
+        public Poodle fromJson(JsonValue jsonObject, Type targetType, 
MappingParser parser) {
+            return POODLES.get(((JsonObject) 
jsonObject).getString("poodleName"));
         }
     }
 

Reply via email to