Repository: johnzon
Updated Branches:
  refs/heads/master 6fc58b4c8 -> e2562bf73


aligning code from AccessMode and Generics to avoid duplication


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/e2562bf7
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/e2562bf7
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/e2562bf7

Branch: refs/heads/master
Commit: e2562bf73ca323cb1fb889c89e1b19875db4a6fd
Parents: 6fc58b4
Author: Romain Manni-Bucau <rmannibu...@apache.org>
Authored: Sun Feb 4 18:02:34 2018 +0100
Committer: Romain Manni-Bucau <rmannibu...@apache.org>
Committed: Sun Feb 4 18:02:34 2018 +0100

----------------------------------------------------------------------
 .../johnzon/mapper/MappingParserImpl.java       | 54 ++++++-----
 .../org/apache/johnzon/mapper/Mappings.java     | 10 +-
 .../johnzon/mapper/access/BaseAccessMode.java   | 96 ++------------------
 .../johnzon/mapper/access/FieldAccessMode.java  | 16 ++--
 .../johnzon/mapper/access/MethodAccessMode.java | 18 ++--
 .../johnzon/mapper/reflection/Generics.java     | 31 +++----
 6 files changed, 76 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
----------------------------------------------------------------------
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 538b737..18af2ec 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
@@ -172,23 +172,23 @@ public class MappingParserImpl implements MappingParser {
             if (Class.class.isInstance(targetType) && ((Class) 
targetType).isArray()) {
                 final Class componentType = ((Class) 
targetType).getComponentType();
                 return (T) buildArrayWithComponentType(jsonArray, 
componentType, config.findAdapter(componentType),
-                        isDeduplicateObjects ? new JsonPointerTracker(null, 
"/") : null);
+                        isDeduplicateObjects ? new JsonPointerTracker(null, 
"/") : null, Object.class);
             }
             if (ParameterizedType.class.isInstance(targetType)) {
 
                 final ParameterizedType pt = (ParameterizedType) targetType;
-                final Mappings.CollectionMapping mapping = 
mappings.findCollectionMapping(pt);
+                final Mappings.CollectionMapping mapping = 
mappings.findCollectionMapping(pt, Object.class);
                 if (mapping == null) {
                     throw new UnsupportedOperationException("type " + 
targetType + " not supported");
                 }
 
                 final Type arg = pt.getActualTypeArguments()[0];
                 return (T) mapCollection(mapping, jsonArray, 
Class.class.isInstance(arg) ? config.findAdapter(Class.class.cast(arg)) : null,
-                        null, isDeduplicateObjects ? new 
JsonPointerTracker(null, "/") : null);
+                        null, isDeduplicateObjects ? new 
JsonPointerTracker(null, "/") : null, Object.class);
             }
             if (Object.class == targetType) {
                 return (T) new 
ArrayList(asList(Object[].class.cast(buildArrayWithComponentType(jsonArray, 
Object.class, null,
-                        isDeduplicateObjects ? new JsonPointerTracker(null, 
"/") : null))));
+                        isDeduplicateObjects ? new JsonPointerTracker(null, 
"/") : null, Object.class))));
             }
         }
         if (JsonValue.NULL.equals(jsonValue)) {
@@ -263,7 +263,7 @@ public class MappingParserImpl implements MappingParser {
                             } else if (JsonString.class.isInstance(jsonValue) 
&& any) {
                                 map.put(value.getKey(), 
JsonString.class.cast(jsonValue).getString());
                             } else {
-                                map.put(convertTo(keyType, value.getKey()), 
toObject(null, jsonValue, fieldArgTypes[1], null, jsonPointer));
+                                map.put(convertTo(keyType, value.getKey()), 
toObject(null, jsonValue, fieldArgTypes[1], null, jsonPointer, Object.class));
                             }
                         }
                         return map;
@@ -272,7 +272,7 @@ public class MappingParserImpl implements MappingParser {
             } else if (Map.class == type || HashMap.class == type || 
LinkedHashMap.class == type) {
                 final LinkedHashMap<String, Object> map = new 
LinkedHashMap<String, Object>();
                 for (final Map.Entry<String, JsonValue> value : 
object.entrySet()) {
-                    map.put(value.getKey(), toObject(null, value.getValue(), 
Object.class, null, jsonPointer));
+                    map.put(value.getKey(), toObject(null, value.getValue(), 
Object.class, null, jsonPointer, Object.class));
                 }
                 return map;
             }
@@ -340,7 +340,7 @@ public class MappingParserImpl implements MappingParser {
                     }
                 }
                 final Object convertedValue = toValue(existingInstance, 
jsonValue, value.converter, value.itemConverter, value.paramType, 
value.objectConverter,
-                        new JsonPointerTracker(jsonPointer, setter.getKey()));
+                        new JsonPointerTracker(jsonPointer, setter.getKey()), 
inType);
                 if (convertedValue != null) {
                     setterMethod.write(t, convertedValue);
                 }
@@ -352,7 +352,7 @@ public class MappingParserImpl implements MappingParser {
                 if (!classMapping.setters.containsKey(key)) {
                     try {
                         classMapping.anySetter.invoke(t, key, toValue(null, 
entry.getValue(), null, null, Object.class, null,
-                                isDeduplicateObjects ? new 
JsonPointerTracker(jsonPointer, entry.getKey()) : null));
+                                isDeduplicateObjects ? new 
JsonPointerTracker(jsonPointer, entry.getKey()) : null, type));
                     } catch (final IllegalAccessException e) {
                         throw new IllegalStateException(e);
                     } catch (final InvocationTargetException e) {
@@ -465,7 +465,8 @@ public class MappingParserImpl implements MappingParser {
 
 
     private Object toObject(final Object baseInstance, final JsonValue 
jsonValue,
-                            final Type type, final Adapter itemConverter, 
JsonPointerTracker jsonPointer) {
+                            final Type type, final Adapter itemConverter, 
final JsonPointerTracker jsonPointer,
+                            final Type rootType) {
         if (jsonValue == null || JsonValue.NULL.equals(jsonValue)) {
             return null;
         }
@@ -515,7 +516,7 @@ public class MappingParserImpl implements MappingParser {
             if (JsonArray.class == type || JsonStructure.class == type) {
                 return jsonValue;
             }
-            return buildArray(type, JsonArray.class.cast(jsonValue), 
itemConverter, null, jsonPointer);
+            return buildArray(type, JsonArray.class.cast(jsonValue), 
itemConverter, null, jsonPointer, rootType);
         } else if (JsonNumber.class.isInstance(jsonValue)) {
             if (JsonNumber.class == type) {
                 return jsonValue;
@@ -577,43 +578,46 @@ public class MappingParserImpl implements MappingParser {
         throw new MapperException("Unable to parse " + jsonValue + " to " + 
type);
     }
 
-    private Object buildArray(final Type type, final JsonArray jsonArray, 
final Adapter itemConverter, ObjectConverter.Reader objectConverter,
-                              final JsonPointerTracker jsonPointer) {
+    private Object buildArray(final Type type, final JsonArray jsonArray, 
final Adapter itemConverter,
+                              final ObjectConverter.Reader objectConverter,
+                              final JsonPointerTracker jsonPointer, final Type 
rootType) {
         if (Class.class.isInstance(type)) {
             final Class clazz = Class.class.cast(type);
             if (clazz.isArray()) {
                 final Class<?> componentType = clazz.getComponentType();
-                return buildArrayWithComponentType(jsonArray, componentType, 
itemConverter, jsonPointer);
+                return buildArrayWithComponentType(jsonArray, componentType, 
itemConverter, jsonPointer, rootType);
             }
         }
 
         if (ParameterizedType.class.isInstance(type)) {
-            final Mappings.CollectionMapping mapping = 
mappings.findCollectionMapping(ParameterizedType.class.cast(type));
+            final Mappings.CollectionMapping mapping = 
mappings.findCollectionMapping(ParameterizedType.class.cast(type), rootType);
             if (mapping != null) {
-                return mapCollection(mapping, jsonArray, itemConverter, 
objectConverter, jsonPointer);
+                return mapCollection(mapping, jsonArray, itemConverter, 
objectConverter, jsonPointer, rootType);
             }
         }
 
         if (Object.class == type) {
-            return buildArray(ANY_LIST, jsonArray, null, null, jsonPointer);
+            return buildArray(ANY_LIST, jsonArray, null, null, jsonPointer, 
rootType);
         }
 
         throw new UnsupportedOperationException("type " + type + " not 
supported");
     }
 
-    private Object buildArrayWithComponentType(final JsonArray jsonArray, 
final Class<?> componentType, final Adapter itemConverter, JsonPointerTracker 
jsonPointer) {
+    private Object buildArrayWithComponentType(final JsonArray jsonArray, 
final Class<?> componentType, final Adapter itemConverter,
+                                               final JsonPointerTracker 
jsonPointer, final Type rootType) {
         final Object array = Array.newInstance(componentType, 
jsonArray.size());
         int i = 0;
         for (final JsonValue value : jsonArray) {
             Array.set(array, i, toObject(null, value, componentType, 
itemConverter,
-                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
i) : null));
+                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
i) : null, rootType));
             i++;
         }
         return array;
     }
 
     private <T> Collection<T> mapCollection(final Mappings.CollectionMapping 
mapping, final JsonArray jsonArray,
-                                            final Adapter itemConverter, 
ObjectConverter.Reader objectConverter, JsonPointerTracker jsonPointer) {
+                                            final Adapter itemConverter, 
ObjectConverter.Reader objectConverter,
+                                            final JsonPointerTracker 
jsonPointer, final Type rootType) {
         final Collection collection;
 
         if (SortedSet.class == mapping.raw || NavigableSet.class == 
mapping.raw || TreeSet.class == mapping.raw) {
@@ -639,7 +643,7 @@ public class MappingParserImpl implements MappingParser {
             collection.add(JsonValue.NULL.equals(value)
                     ? null
                     : toValue(null, value, null, itemConverter, mapping.arg, 
objectConverter,
-                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
i) : null));
+                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
i) : null, rootType));
             i++;
         }
 
@@ -671,27 +675,29 @@ public class MappingParserImpl implements MappingParser {
                     mapping.factory.getParameterItemConverter()[i],
                     mapping.factory.getParameterTypes()[i],
                     mapping.factory.getObjectConverter()[i],
-                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
paramName) : null); //X TODO ObjectConverter in @JOhnzonConverter with 
Constructors!
+                    isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, 
paramName) : null,
+                    mapping.clazz); //X TODO ObjectConverter in 
@JohnzonConverter with Constructors!
         }
 
         return objects;
     }
 
     private Object toValue(final Object baseInstance, final JsonValue 
jsonValue, final Adapter converter,
-                           final Adapter itemConverter, final Type type, final 
ObjectConverter.Reader objectConverter, JsonPointerTracker jsonPointer) {
+                           final Adapter itemConverter, final Type type, final 
ObjectConverter.Reader objectConverter,
+                           final JsonPointerTracker jsonPointer, final Type 
rootType) {
 
         if (objectConverter != null) {
 
             if (jsonValue instanceof JsonObject) {
                 return objectConverter.fromJson((JsonObject) jsonValue, type, 
this);
             } else if (jsonValue instanceof JsonArray) {
-                return buildArray(type, jsonValue.asJsonArray(), 
itemConverter, objectConverter, jsonPointer);
+                return buildArray(type, jsonValue.asJsonArray(), 
itemConverter, objectConverter, jsonPointer, rootType);
             } else {
                 throw new UnsupportedOperationException("Array handling with 
ObjectConverter currently not implemented");
             }
         }
 
-        return converter == null ? toObject(baseInstance, jsonValue, type, 
itemConverter, jsonPointer)
+        return converter == null ? toObject(baseInstance, jsonValue, type, 
itemConverter, jsonPointer, rootType)
                 : jsonValue.getValueType() == JsonValue.ValueType.STRING ? 
converter.to(JsonString.class.cast(jsonValue).getString())
                 : convertTo(converter, jsonValue, jsonPointer);
     }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
index 8a04515..a722602 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
@@ -24,6 +24,7 @@ import 
org.apache.johnzon.mapper.converter.DateWithCopyConverter;
 import org.apache.johnzon.mapper.converter.EnumConverter;
 import org.apache.johnzon.mapper.internal.AdapterKey;
 import org.apache.johnzon.mapper.internal.ConverterAdapter;
+import org.apache.johnzon.mapper.reflection.Generics;
 import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
 
 import java.lang.annotation.Annotation;
@@ -258,10 +259,10 @@ public class Mappings {
         this.config = config;
     }
 
-    public CollectionMapping findCollectionMapping(final ParameterizedType 
genericType) {
+    public CollectionMapping findCollectionMapping(final ParameterizedType 
genericType, final Type enclosingType) {
         CollectionMapping collectionMapping = collections.get(genericType);
         if (collectionMapping == null) {
-            collectionMapping = createCollectionMapping(genericType);
+            collectionMapping = createCollectionMapping(genericType, 
enclosingType);
             if (collectionMapping == null) {
                 return null;
             }
@@ -273,7 +274,7 @@ public class Mappings {
         return collectionMapping;
     }
 
-    private <T> CollectionMapping createCollectionMapping(final 
ParameterizedType aType) {
+    private <T> CollectionMapping createCollectionMapping(final 
ParameterizedType aType, final Type root) {
         final Type[] fieldArgTypes = aType.getActualTypeArguments();
         final Type raw = aType.getRawType();
         if (fieldArgTypes.length == 1 && Class.class.isInstance(raw)) {
@@ -295,7 +296,8 @@ public class Mappings {
                 return null;
             }
 
-            final CollectionMapping mapping = new 
CollectionMapping(isPrimitive(fieldArgTypes[0]), collectionType, 
fieldArgTypes[0]);
+            final CollectionMapping mapping = new 
CollectionMapping(isPrimitive(fieldArgTypes[0]), collectionType,
+                    Generics.resolve(fieldArgTypes[0], 
Class.class.isInstance(root) ? Class.class.cast(root) : null));
             collections.putIfAbsent(aType, mapping);
             return mapping;
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
index 36200ad..5661ee2 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
@@ -18,32 +18,26 @@
  */
 package org.apache.johnzon.mapper.access;
 
-import org.apache.johnzon.mapper.Adapter;
-import org.apache.johnzon.mapper.JohnzonAny;
-import org.apache.johnzon.mapper.Converter;
-import org.apache.johnzon.mapper.JohnzonConverter;
-import org.apache.johnzon.mapper.MapperConverter;
-import org.apache.johnzon.mapper.ObjectConverter;
-import org.apache.johnzon.mapper.internal.ConverterAdapter;
-import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
+import static org.apache.johnzon.mapper.reflection.Converters.matches;
 
 import java.beans.ConstructorProperties;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.GenericDeclaration;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
-import static java.util.Arrays.asList;
-import static org.apache.johnzon.mapper.reflection.Converters.matches;
+import org.apache.johnzon.mapper.Adapter;
+import org.apache.johnzon.mapper.Converter;
+import org.apache.johnzon.mapper.JohnzonAny;
+import org.apache.johnzon.mapper.JohnzonConverter;
+import org.apache.johnzon.mapper.MapperConverter;
+import org.apache.johnzon.mapper.ObjectConverter;
+import org.apache.johnzon.mapper.internal.ConverterAdapter;
 
 // handle some specific types
 public abstract class BaseAccessMode implements AccessMode {
@@ -271,78 +265,4 @@ public abstract class BaseAccessMode implements AccessMode 
{
         }
         return delegate;
     }
-
-    protected Type fixType(final Class<?> clazz, final Type type) { // to 
enhance
-        if (TypeVariable.class.isInstance(type)) { // we need to handle it on 
deserialization side, not needed on serialization side
-            return fixTypeVariable(clazz, type);
-        }
-        if (ParameterizedType.class.isInstance(type)) {
-            final ParameterizedType pt = ParameterizedType.class.cast(type);
-            final Type[] actualTypeArguments = pt.getActualTypeArguments();
-            if (actualTypeArguments.length == 1 && 
Class.class.isInstance(pt.getRawType())
-                && 
Collection.class.isAssignableFrom(Class.class.cast(pt.getRawType()))
-                && 
Class.class.cast(pt.getRawType()).getName().startsWith("java.util.")
-                && TypeVariable.class.isInstance(actualTypeArguments[0])) {
-                return new JohnzonParameterizedType(pt.getRawType(), 
fixTypeVariable(clazz, actualTypeArguments[0]));
-            } else if (actualTypeArguments.length == 2 && 
Class.class.isInstance(pt.getRawType())
-                && 
Map.class.isAssignableFrom(Class.class.cast(pt.getRawType()))
-                && 
Class.class.cast(pt.getRawType()).getName().startsWith("java.util.")
-                && TypeVariable.class.isInstance(actualTypeArguments[1])) {
-                return new JohnzonParameterizedType(pt.getRawType(), 
actualTypeArguments[0], fixTypeVariable(clazz, actualTypeArguments[1]));
-            }
-        }
-        return type;
-    }
-
-    private Type fixTypeVariable(final Class<?> clazz, final Type type) {
-        final TypeVariable typeVariable = TypeVariable.class.cast(type);
-        final Class<?> classWithDeclaration = findClass(clazz.getSuperclass(), 
typeVariable.getGenericDeclaration());
-
-        if (classWithDeclaration != null) {
-            // try to match generic
-            final TypeVariable<? extends Class<?>>[] typeParameters = 
classWithDeclaration.getTypeParameters();
-            final int idx = asList(typeParameters).indexOf(typeVariable);
-            if (idx >= 0) {
-
-                ParameterizedType pt = findParameterizedType(clazz, 
classWithDeclaration);
-                if (pt != null) {
-                    if (pt.getActualTypeArguments().length == 
typeParameters.length) {
-                        return pt.getActualTypeArguments()[idx];
-                    }
-                }
-            }
-        }
-        return type;
-    }
-
-    private Class<?> findClass(final Class<?> clazz, final GenericDeclaration 
genericDeclaration) {
-
-        if (clazz == null || clazz == genericDeclaration) {
-            return clazz;
-        }
-
-        final Class<?> superclass = clazz.getSuperclass();
-        if (superclass != null && superclass != Object.class) {
-            return findClass(superclass, genericDeclaration);
-        }
-
-        return null;
-    }
-
-    private ParameterizedType findParameterizedType(Class<?> clazz, Class<?> 
classWithDeclaration) {
-
-        if (clazz == Object.class) {
-            return null;
-        }
-
-        Type genericSuperclass = clazz.getGenericSuperclass();
-
-        if (genericSuperclass instanceof ParameterizedType &&
-            ((ParameterizedType) genericSuperclass).getRawType() == 
classWithDeclaration) {
-
-                return (ParameterizedType) genericSuperclass;
-        }
-
-        return findParameterizedType(clazz.getSuperclass(), 
classWithDeclaration);
-    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
index f2cec48..831f895 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
@@ -18,12 +18,6 @@
  */
 package org.apache.johnzon.mapper.access;
 
-import org.apache.johnzon.mapper.Adapter;
-import org.apache.johnzon.mapper.JohnzonAny;
-import org.apache.johnzon.mapper.JohnzonProperty;
-import org.apache.johnzon.mapper.MapperException;
-import org.apache.johnzon.mapper.ObjectConverter;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -31,6 +25,12 @@ import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.johnzon.mapper.Adapter;
+import org.apache.johnzon.mapper.JohnzonAny;
+import org.apache.johnzon.mapper.JohnzonProperty;
+import org.apache.johnzon.mapper.MapperException;
+import org.apache.johnzon.mapper.ObjectConverter;
+
 public class FieldAccessMode extends BaseAccessMode {
     public FieldAccessMode(final boolean useConstructor, final boolean 
acceptHiddenConstructor) {
         super(useConstructor, acceptHiddenConstructor);
@@ -46,7 +46,7 @@ public class FieldAccessMode extends BaseAccessMode {
             }
 
             final Field field = f.getValue();
-            readers.put(extractKey(field, key), new FieldReader(field, 
fixType(clazz, field.getGenericType())));
+            readers.put(extractKey(field, key), new FieldReader(field, 
field.getGenericType()));
         }
         return readers;
     }
@@ -61,7 +61,7 @@ public class FieldAccessMode extends BaseAccessMode {
             }
 
             final Field field = f.getValue();
-            writers.put(extractKey(field, key), new FieldWriter(field, 
fixType(clazz, field.getGenericType())));
+            writers.put(extractKey(field, key), new FieldWriter(field, 
field.getGenericType()));
         }
         return writers;
     }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/MethodAccessMode.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/MethodAccessMode.java
 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/MethodAccessMode.java
index c81c070..b694bd2 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/MethodAccessMode.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/MethodAccessMode.java
@@ -18,12 +18,6 @@
  */
 package org.apache.johnzon.mapper.access;
 
-import org.apache.johnzon.mapper.Adapter;
-import org.apache.johnzon.mapper.JohnzonAny;
-import org.apache.johnzon.mapper.JohnzonProperty;
-import org.apache.johnzon.mapper.MapperException;
-import org.apache.johnzon.mapper.ObjectConverter;
-
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
@@ -34,6 +28,12 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.johnzon.mapper.Adapter;
+import org.apache.johnzon.mapper.JohnzonAny;
+import org.apache.johnzon.mapper.JohnzonProperty;
+import org.apache.johnzon.mapper.MapperException;
+import org.apache.johnzon.mapper.ObjectConverter;
+
 public class MethodAccessMode extends BaseAccessMode {
     private final boolean supportGetterAsWritter;
 
@@ -52,7 +52,7 @@ public class MethodAccessMode extends BaseAccessMode {
                 if (isIgnored(descriptor.getName()) || 
Meta.getAnnotation(readMethod, JohnzonAny.class) != null) {
                     continue;
                 }
-                readers.put(extractKey(descriptor.getName(), readMethod, 
null), new MethodReader(readMethod, fixType(clazz, 
readMethod.getGenericReturnType())));
+                readers.put(extractKey(descriptor.getName(), readMethod, 
null), new MethodReader(readMethod, readMethod.getGenericReturnType()));
             }
         }
         return readers;
@@ -69,12 +69,12 @@ public class MethodAccessMode extends BaseAccessMode {
             final Method writeMethod = descriptor.getWriteMethod();
             if (writeMethod != null) {
                 writers.put(extractKey(descriptor.getName(), writeMethod, 
descriptor.getReadMethod()),
-                        new MethodWriter(writeMethod, fixType(clazz, 
writeMethod.getGenericParameterTypes()[0])));
+                        new MethodWriter(writeMethod, 
writeMethod.getGenericParameterTypes()[0]));
             } else if (supportGetterAsWritter
                     && 
Collection.class.isAssignableFrom(descriptor.getPropertyType())
                     && descriptor.getReadMethod() != null) {
                 final Method readMethod = descriptor.getReadMethod();
-                writers.put(extractKey(descriptor.getName(), readMethod, 
null), new MethodGetterAsWriter(readMethod, fixType(clazz, 
readMethod.getGenericReturnType())));
+                writers.put(extractKey(descriptor.getName(), readMethod, 
null), new MethodGetterAsWriter(readMethod, readMethod.getGenericReturnType()));
             }
         }
         return writers;

http://git-wip-us.apache.org/repos/asf/johnzon/blob/e2562bf7/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Generics.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Generics.java
 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Generics.java
index 31ad7f2..8e06529 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Generics.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Generics.java
@@ -56,12 +56,12 @@ public final class Generics {
                 if (args == null) {
                     args = new ArrayList<>();
                     if (index > 0) {
-                        
args.addAll(asList(parameterizedType.getActualTypeArguments()).subList(0, index 
+ 1));
+                        
args.addAll(asList(parameterizedType.getActualTypeArguments()).subList(0, 
index));
                     }
                 }
             }
             if (args != null) {
-                args.add(arg);
+                args.add(type);
             }
             index++;
         }
@@ -74,23 +74,22 @@ public final class Generics {
     // for now the level is hardcoded to 2 with generic > concrete
     private static Type resolveTypeVariable(final Type value, final Class<?> 
rootClass) {
         final TypeVariable<?> tv = TypeVariable.class.cast(value);
-        final Type parent = rootClass.getGenericSuperclass();
+        Type parent = rootClass == null ? null : 
rootClass.getGenericSuperclass();
+        while (Class.class.isInstance(parent)) {
+            parent = Class.class.cast(parent).getGenericSuperclass();
+        }
+        while (ParameterizedType.class.isInstance(parent) && 
ParameterizedType.class.cast(parent).getRawType() != 
tv.getGenericDeclaration()) {
+            parent = 
Class.class.cast(ParameterizedType.class.cast(parent).getRawType()).getGenericSuperclass();
+        }
         if (ParameterizedType.class.isInstance(parent)) {
             final ParameterizedType parentPt = 
ParameterizedType.class.cast(parent);
-            if (Class.class.isInstance(parentPt.getRawType())) {
-                final Type grandParent = 
Class.class.cast(parentPt.getRawType()).getGenericSuperclass();
-                if (ParameterizedType.class.isInstance(grandParent)) {
-                    final ParameterizedType grandParentPt = 
ParameterizedType.class.cast(grandParent);
-                    final Type[] grandParentArgs = 
grandParentPt.getActualTypeArguments();
-                    int index = 0;
-                    final String name = tv.getName();
-                    for (final Type t : grandParentArgs) {
-                        if (TypeVariable.class.isInstance(t) && 
TypeVariable.class.cast(t).getName().equals(name)) {
-                            return parentPt.getActualTypeArguments()[index];
-                        }
-                        index++;
-                    }
+            final int argIndex = 
asList(Class.class.cast(parentPt.getRawType()).getTypeParameters()).indexOf(tv);
+            if (argIndex >= 0) {
+                final Type type = parentPt.getActualTypeArguments()[argIndex];
+                if (TypeVariable.class.isInstance(type)) {
+                    return resolveTypeVariable(type, rootClass);
                 }
+                return type;
             }
         }
         return value;

Reply via email to