You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by st...@apache.org on 2016/04/06 22:42:55 UTC

[1/6] incubator-johnzon git commit: JOHNZON-71 copied logic from mapper to MappingParser

Repository: incubator-johnzon
Updated Branches:
  refs/heads/master 8bca6082c -> e917e77d6


JOHNZON-71 copied logic from mapper to MappingParser


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

Branch: refs/heads/master
Commit: 253d6fafab4be03353c5275f0494650b250ae411
Parents: 8bca608
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Tue Apr 5 23:20:11 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Tue Apr 5 23:20:11 2016 +0200

----------------------------------------------------------------------
 .../java/org/apache/johnzon/mapper/Mapper.java  |   9 +
 .../apache/johnzon/mapper/MappingParser.java    |  15 -
 .../johnzon/mapper/MappingParserImpl.java       | 524 ++++++++++++++++++-
 .../apache/johnzon/mapper/ObjectConverter.java  |   3 +-
 .../apache/johnzon/mapper/ObjectTypeTest.java   |   6 +-
 5 files changed, 520 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/253d6faf/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index 4d6e803..fa9bfd2 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -245,7 +245,16 @@ public class Mapper implements Closeable {
         return mapObject(clazz, readerFactory.createReader(stream(stream)));
     }
 
+
     private <T> T mapObject(final Type clazz, final JsonReader reader) {
+        return new MappingParserImpl(config, mappings, reader).readObject(clazz);
+    }
+
+
+    /**
+     * @deprecated just for refactoring
+     */
+    private <T> T mapObjectOld(final Type clazz, final JsonReader reader) {
         try {
             final JsonValue object = readerHandler.read(reader);
             if (JsonStructure.class == clazz || JsonObject.class == clazz || JsonValue.class == clazz) {

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/253d6faf/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParser.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParser.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParser.java
index 615dfaf..cee68d8 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParser.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParser.java
@@ -20,29 +20,14 @@ package org.apache.johnzon.mapper;
 
 import java.lang.reflect.Type;
 
-import javax.json.JsonReader;
 import javax.json.JsonValue;
-import javax.json.stream.JsonParser;
 
 /**
  * Handles reading Json for Objects.
- * Internally it uses a {@link JsonParser} to write JSON
- *
- * To write JSON-P structure elements you can use the {@link #getJsonParser()} ()} method.
  *
  */
 public interface MappingParser {
 
-    /**
-     * @return the {@link JsonParser} used internally to read the JSON input.
-     */
-    JsonParser getJsonParser();
-
-    /**
-     * @return the {@link JsonReader} to read in full {@link javax.json.JsonValue}s from the {@link #getJsonParser()}
-     */
-    JsonReader getJsonReader();
-
     <T> T readObject(Type targetType);
 
     <T> T readObject(JsonValue jsonValue, Type targetType);

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/253d6faf/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 369b9b8..3c455a6 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
@@ -18,46 +18,534 @@
  */
 package org.apache.johnzon.mapper;
 
+import org.apache.johnzon.core.JsonLongImpl;
+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 org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
 import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
 import javax.json.JsonValue;
-import javax.json.stream.JsonParser;
-
-import org.apache.johnzon.core.JsonReaderImpl;
+import javax.xml.bind.DatatypeConverter;
 
 /**
  * This class is not concurrently usable as it contains state.
  */
 public class MappingParserImpl implements MappingParser {
-    private final JsonParser jsonParser;
 
-    private JsonReader jsonReader = null;
+    private static final Adapter<Object, String> FALLBACK_CONVERTER = new ConverterAdapter<Object>(new FallbackConverter());
+    private static final JohnzonParameterizedType ANY_LIST = new JohnzonParameterizedType(List.class, Object.class);
+
+
+    protected final ConcurrentMap<Adapter<?, ?>, AdapterKey> reverseAdaptersRegistry;
+
+    private final MapperConfig config;
+    private final Mappings mappings;
+
+    private final JsonReader jsonReader;
+
+
 
-    public MappingParserImpl(JsonParser jsonParser) {
-        this.jsonParser = jsonParser;
+    public MappingParserImpl(MapperConfig config, Mappings mappings, JsonReader jsonReader) {
+        this.config = config;
+        this.mappings = mappings;
+
+        this.jsonReader = jsonReader;
+
+        reverseAdaptersRegistry = new ConcurrentHashMap<Adapter<?, ?>, AdapterKey>(config.getAdapters().size());
     }
 
+
     @Override
-    public JsonParser getJsonParser() {
-        return jsonParser;
+    public <T> T readObject(Type targetType) {
+
+        try {
+            return readObject(jsonReader.read(), targetType);
+        } finally {
+            if (config.isClose()) {
+                jsonReader.close();
+            }
+        }
     }
 
     @Override
-    public JsonReader getJsonReader() {
-        if (jsonReader == null) {
-            jsonReader = new JsonReaderImpl(jsonParser);
+    public <T> T readObject(JsonValue jsonValue, Type targetType) {
+        if (JsonStructure.class == targetType || JsonObject.class == targetType || JsonValue.class == targetType) {
+            return (T) jsonValue;
         }
-        return jsonReader;
+        if (JsonObject.class.isInstance(jsonValue)) {
+            return (T) buildObject(targetType, JsonObject.class.cast(jsonValue));
+        }
+        if (JsonString.class.isInstance(jsonValue) && targetType == String.class) {
+            return (T) JsonString.class.cast(jsonValue).getString();
+        }
+        if (JsonNumber.class.isInstance(jsonValue)) {
+            final JsonNumber number = JsonNumber.class.cast(jsonValue);
+            if (targetType == int.class || targetType == Integer.class) {
+                return (T) Integer.valueOf(number.intValue());
+            }
+            if (targetType == long.class || targetType == Long.class) {
+                return (T) Long.valueOf(number.longValue());
+            }
+            if (targetType == double.class || targetType == Double.class) {
+                return (T) Double.valueOf(number.doubleValue());
+            }
+            if (targetType == BigDecimal.class) {
+                return (T) number.bigDecimalValue();
+            }
+            if (targetType == BigInteger.class) {
+                return (T) number.bigIntegerValue();
+            }
+        }
+        if (JsonValue.NULL == jsonValue) {
+            return null;
+        }
+        if (JsonValue.TRUE == jsonValue && (Boolean.class == targetType || boolean.class == targetType)) {
+            return (T) Boolean.TRUE;
+        }
+        if (JsonValue.FALSE == jsonValue && (Boolean.class == targetType || boolean.class == targetType)) {
+            return (T) Boolean.FALSE;
+        }
+        throw new IllegalArgumentException("Unsupported " + jsonValue + " for type " + targetType);
     }
 
-    @Override
-    public <T> T readObject(Type targetType) {
-        return null;
+
+    private Object buildObject(final Type inType, final JsonObject object) {
+        Type type = inType;
+        if (inType == Object.class) {
+            type = new JohnzonParameterizedType(Map.class, String.class, Object.class);
+        }
+
+        final Mappings.ClassMapping classMapping = mappings.findOrCreateClassMapping(type);
+
+        if (classMapping == null) {
+            if (ParameterizedType.class.isInstance(type)) {
+                final ParameterizedType aType = ParameterizedType.class.cast(type);
+                final Type[] fieldArgTypes = aType.getActualTypeArguments();
+                if (fieldArgTypes.length >= 2) {
+                    final Class<?> raw = Class.class.cast(aType.getRawType());
+
+                    final Map map;
+                    if (LinkedHashMap.class == raw) {
+                        map = new LinkedHashMap();
+                    } else if (SortedMap.class.isAssignableFrom(raw) || NavigableMap.class == raw || TreeMap.class == raw) {
+                        map = new TreeMap();
+                    } else if (ConcurrentMap.class.isAssignableFrom(raw)) {
+                        map = new ConcurrentHashMap(object.size());
+                    } else if (EnumMap.class.isAssignableFrom(raw)) {
+                        map = new EnumMap(Class.class.cast(fieldArgTypes[0]));
+                    } else if (Map.class.isAssignableFrom(raw)) {
+                        map = new HashMap(object.size());
+                    } else {
+                        map = null;
+                    }
+
+                    if (map != null) {
+
+                        Type keyType;
+                        if (ParameterizedType.class.isInstance(fieldArgTypes[0])) {
+                            keyType = fieldArgTypes[0];
+                        } else {
+                            keyType = fieldArgTypes[0];
+                        }
+
+                        final boolean any = fieldArgTypes.length < 2 || fieldArgTypes[1] == Object.class;
+                        for (final Map.Entry<String, JsonValue> value : object.entrySet()) {
+                            final JsonValue jsonValue = value.getValue();
+                            if (JsonNumber.class.isInstance(jsonValue) && any) {
+                                final JsonNumber number = JsonNumber.class.cast(jsonValue);
+                                if (JsonLongImpl.class.isInstance(number)) {
+                                    final int integer = number.intValue();
+                                    final long asLong = number.longValue();
+                                    if (integer == asLong) {
+                                        map.put(value.getKey(), integer);
+                                    } else {
+                                        map.put(value.getKey(), asLong);
+                                    }
+                                } else {
+                                    map.put(value.getKey(), !number.isIntegral() ? number.bigDecimalValue() : number.intValue());
+                                }
+                            } 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));
+                            }
+                        }
+                        return map;
+                    }
+                }
+            } 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));
+                }
+                return map;
+            }
+        }
+        if (classMapping == null) {
+            throw new MapperException("Can't map " + type);
+        }
+
+        if (classMapping.factory == null) {
+            throw new IllegalArgumentException(classMapping.clazz + " not instantiable");
+        }
+
+        final Object t = classMapping.factory.getParameterTypes().length == 0 ?
+                classMapping.factory.create(null) : classMapping.factory.create(createParameters(classMapping, object));
+        for (final Map.Entry<String, Mappings.Setter> setter : classMapping.setters.entrySet()) {
+            final JsonValue jsonValue = object.get(setter.getKey());
+            final Mappings.Setter value = setter.getValue();
+            if (JsonValue.class == value.paramType) {
+                setter.getValue().writer.write(t, jsonValue);
+                continue;
+            }
+            if (jsonValue == null) {
+                continue;
+            }
+
+            final AccessMode.Writer setterMethod = value.writer;
+            if (jsonValue == JsonValue.NULL) { // forced
+                setterMethod.write(t, null);
+            } else {
+                Object existingInstance = null;
+                if (config.isReadAttributeBeforeWrite()) {
+                    final Mappings.Getter getter = classMapping.getters.get(setter.getKey());
+                    if (getter != null) {
+                        try {
+                            existingInstance = getter.reader.read(t);
+                        } catch (final RuntimeException re) {
+                            // backward compatibility
+                        }
+                    }
+                }
+                final Object convertedValue = toValue(existingInstance, jsonValue, value.converter, value.itemConverter, value.paramType);
+                if (convertedValue != null) {
+                    setterMethod.write(t, convertedValue);
+                }
+            }
+        }
+
+        return t;
     }
 
-    @Override
-    public <T> T readObject(JsonValue jsonValue, Type targetType) {
+    private Object convertTo(final Adapter converter, final JsonValue jsonValue) {
+        if (jsonValue.getValueType() == JsonValue.ValueType.OBJECT) {
+
+            //X TODO maybe we can put this into MapperConfig?
+            //X      config.getAdapter(AdapterKey)
+            //X      config.getAdapterKey(Adapter)
+            AdapterKey adapterKey = reverseAdaptersRegistry.get(converter);
+            if (adapterKey == null) {
+                for (final Map.Entry<AdapterKey, Adapter<?, ?>> entry : config.getAdapters().entrySet()) {
+                    if (entry.getValue() == converter) {
+                        adapterKey = entry.getKey();
+                        reverseAdaptersRegistry.put(converter, adapterKey);
+                        break;
+                    }
+                }
+            }
+
+            final Object param;
+            try {
+                param = buildObject(adapterKey.getTo(), JsonObject.class.cast(jsonValue));
+            } catch (final Exception e) {
+                throw new MapperException(e);
+            }
+            return converter.to(param);
+        }
+        return converter.to(jsonValue.toString());
+    }
+
+
+
+    private Object toObject(final Object baseInstance, final JsonValue jsonValue,
+                            final Type type, final Adapter itemConverter) {
+        if (jsonValue == null || JsonValue.NULL == jsonValue) {
+            return null;
+        }
+
+        if (type == Boolean.class || type == boolean.class) {
+            if (jsonValue == JsonValue.TRUE) {
+                return true;
+            }
+            if (jsonValue == JsonValue.FALSE) {
+                return false;
+            }
+            throw new MapperException("Unable to parse " + jsonValue + " to boolean");
+        }
+
+        if(config.isTreatByteArrayAsBase64() && jsonValue.getValueType() == JsonValue.ValueType.STRING && (type == byte[].class /*|| type == Byte[].class*/)) {
+            return DatatypeConverter.parseBase64Binary(((JsonString)jsonValue).getString());
+        }
+
+        if (Object.class == type) { // handling specific types here to keep exception in standard handling
+            if (jsonValue == JsonValue.TRUE) {
+                return true;
+            }
+            if (jsonValue == JsonValue.FALSE) {
+                return false;
+            }
+            if (JsonNumber.class.isInstance(jsonValue)) {
+                final JsonNumber jsonNumber = JsonNumber.class.cast(jsonValue);
+                if(jsonNumber.isIntegral()) {
+                    return jsonNumber.intValue();
+                }
+                return jsonNumber.doubleValue();
+            }
+        }
+
+        if (type == Character.class || type == char.class) {
+            return convertTo(Class.class.cast(type), (JsonString.class.cast(jsonValue).getString()));
+        }
+
+        if (JsonObject.class.isInstance(jsonValue)) {
+            if (JsonObject.class == type || JsonStructure.class == type) {
+                return jsonValue;
+            }
+            final boolean typedAdapter = TypeAwareAdapter.class.isInstance(itemConverter);
+            final Object object = buildObject(
+                    baseInstance != null ? baseInstance.getClass() : (
+                            typedAdapter ? TypeAwareAdapter.class.cast(itemConverter).getTo() : type),
+                    JsonObject.class.cast(jsonValue));
+            return typedAdapter ? itemConverter.to(object) : object;
+        } else if (JsonArray.class.isInstance(jsonValue)) {
+            if (JsonArray.class == type || JsonStructure.class == type) {
+                return jsonValue;
+            }
+            return buildArray(type, JsonArray.class.cast(jsonValue), itemConverter);
+        } else if (JsonNumber.class.isInstance(jsonValue)) {
+            if (JsonNumber.class == type) {
+                return jsonValue;
+            }
+
+            final JsonNumber number = JsonNumber.class.cast(jsonValue);
+
+            if (type == Integer.class || type == int.class) {
+                return number.intValue();
+            }
+
+            if (type == Long.class || type == long.class) {
+                return number.longValue();
+            }
+
+            if (type == Short.class || type == short.class) {
+                return (short) number.intValue();
+            }
+
+            if (type == Byte.class || type == byte.class) {
+                return (byte) number.intValue();
+            }
+
+            if (type == Float.class || type == float.class) {
+                return (float) number.doubleValue();
+            }
+
+            if (type == Double.class || type == double.class) {
+                return number.doubleValue();
+            }
+
+            if (type == BigInteger.class) {
+                return number.bigIntegerValue();
+            }
+
+            if (type == BigDecimal.class) {
+                return number.bigDecimalValue();
+            }
+        } else if (JsonString.class.isInstance(jsonValue)) {
+            if (JsonString.class == type) {
+                return jsonValue;
+            }
+
+            final String string = JsonString.class.cast(jsonValue).getString();
+            if (itemConverter == null) {
+                return convertTo(Class.class.cast(type), string);
+            } else {
+                return itemConverter.to(string);
+            }
+        }
+
+        throw new MapperException("Unable to parse " + jsonValue + " to " + type);
+    }
+
+    private Object buildArray(final Type type, final JsonArray jsonArray, final Adapter itemConverter) {
+        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);
+            }
+        }
+
+        if (ParameterizedType.class.isInstance(type)) {
+            final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(ParameterizedType.class.cast(type));
+            if (mapping != null) {
+                return mapCollection(mapping, jsonArray, itemConverter);
+            }
+        }
+
+        if (Object.class == type) {
+            return buildArray(ANY_LIST, jsonArray, null);
+        }
+
+        throw new UnsupportedOperationException("type " + type + " not supported");
+    }
+
+    private Object buildArrayWithComponentType(final JsonArray jsonArray, final Class<?> componentType, final Adapter itemConverter) {
+        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));
+        }
+        return array;
+    }
+
+    private <T> Collection<T> mapCollection(final Mappings.CollectionMapping mapping, final JsonArray jsonArray,
+                                            final Adapter itemConverter) {
+        final Collection collection;
+
+        if (SortedSet.class == mapping.raw || NavigableSet.class == mapping.raw || TreeSet.class == mapping.raw) {
+            collection = new TreeSet<T>();
+        } else if (Set.class == mapping.raw || HashSet.class == mapping.raw) {
+            collection = new HashSet<T>(jsonArray.size());
+        } else if (Queue.class == mapping.raw || ArrayBlockingQueue.class == mapping.raw) {
+            collection = new ArrayBlockingQueue<T>(jsonArray.size());
+        } else if (List.class == mapping.raw || Collection.class == mapping.raw || ArrayList.class == mapping.raw || EnumSet.class == mapping.raw) {
+            collection = new ArrayList<T>(jsonArray.size());
+        } else if (LinkedHashSet.class == mapping.raw) {
+            collection = new LinkedHashSet<T>(jsonArray.size());
+        } else if (Deque.class == mapping.raw || ArrayDeque.class == mapping.raw) {
+            collection = new ArrayDeque(jsonArray.size());
+        } else if (Queue.class == mapping.raw || PriorityQueue.class == mapping.raw) {
+            collection = new PriorityQueue(jsonArray.size());
+        } else {
+            throw new IllegalStateException("not supported collection type: " + mapping.raw.getName());
+        }
+
+        for (final JsonValue value : jsonArray) {
+            collection.add(value == JsonValue.NULL ? null : toObject(null, value, mapping.arg, itemConverter));
+        }
+
+        if (EnumSet.class == mapping.raw) {
+            if (collection.isEmpty()) {
+                return EnumSet.noneOf(Class.class.cast(mapping.arg));
+            } else if (collection.size() == 1) {
+                return Collection.class.cast(EnumSet.of(Enum.class.cast(collection.iterator().next())));
+            } else {
+                final List<Enum<?>> list = List.class.cast(collection);
+                return Collection.class.cast(EnumSet.of(list.get(0), list.subList(1, list.size()).toArray(new Enum[list.size() - 1])));
+            }
+        }
+
+        return collection;
+    }
+
+
+    private Object[] createParameters(final Mappings.ClassMapping mapping, final JsonObject object) {
+        final int length = mapping.factory.getParameterTypes().length;
+        final Object[] objects = new Object[length];
+
+        for (int i = 0; i < length; i++) {
+
+            objects[i] = toValue(null,
+                                 object.get(mapping.factory.getParameterNames()[i]),
+                                 mapping.factory.getParameterConverter()[i],
+                                 mapping.factory.getParameterItemConverter()[i],
+                                 mapping.factory.getParameterTypes()[i]);
+        }
+
+        return objects;
+    }
+
+    private Object toValue(final Object baseInstance, final JsonValue jsonValue, final Adapter converter,
+                           final Adapter itemConverter, final Type type) {
+        return converter == null ? toObject(baseInstance, jsonValue, type, itemConverter)
+                                 : jsonValue.getValueType() == JsonValue.ValueType.STRING ? converter.to(JsonString.class.cast(jsonValue).getString())
+                                                                                          : convertTo(converter, jsonValue);
+    }
+
+
+    /**
+     * @deprecated see MapperConfig
+     */
+    private Object convertTo(final Type aClass, final String text) {
+        if (Object.class == aClass || String.class == aClass) {
+            return text;
+        }
+        final Adapter converter = findAdapter(aClass);
+        if (converter == null) {
+            config.getAdapters().putIfAbsent(new AdapterKey(String.class, aClass), FALLBACK_CONVERTER);
+            return FALLBACK_CONVERTER.to(text);
+        }
+        return converter.to(text);
+    }
+
+    /**
+     * @deprecated see MapperConfig
+     */
+    private Adapter findAdapter(final Type aClass) {
+        final Adapter<?, ?> converter = config.getAdapters().get(new AdapterKey(aClass, String.class));
+        if (converter != null) {
+            return converter;
+        }
+        if (Class.class.isInstance(aClass)) {
+            final Class<?> clazz = Class.class.cast(aClass);
+            if (clazz.isEnum()) {
+                final Adapter<?, ?> enumConverter = new ConverterAdapter(new EnumConverter(clazz));
+                config.getAdapters().putIfAbsent(new AdapterKey(String.class, aClass), enumConverter);
+                return enumConverter;
+            }
+        }
         return null;
     }
+
+
+    private static class FallbackConverter implements Converter<Object> {
+        @Override
+        public String toString(final Object instance) {
+            return instance.toString();
+        }
+
+        @Override
+        public Object fromString(final String text) {
+            throw new MapperException("Using fallback converter, " +
+                                      "this only works in write mode but not in read. Please register a custom converter to do so.");
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/253d6faf/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ObjectConverter.java
----------------------------------------------------------------------
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 1b5ff5f..5869f4d 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,6 +18,7 @@
  */
 package org.apache.johnzon.mapper;
 
+import javax.json.JsonObject;
 import java.lang.reflect.Type;
 
 /**
@@ -32,5 +33,5 @@ import java.lang.reflect.Type;
 public interface ObjectConverter<T> extends MapperConverter {
     void writeJson(T instance, MappingGenerator jsonbGenerator);
 
-    T fromJson(MappingParser jsonbParser, Type targetType);
+    T fromJson(JsonObject jsonObject, Type targetType, MappingParser parser);
 }

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/253d6faf/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java
----------------------------------------------------------------------
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 c999c0f..2abb617 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
@@ -86,15 +86,15 @@ public class ObjectTypeTest {
         }
 
         @Override
-        public Dog fromJson(MappingParser mappingParser, Type targetType) {
-            JsonObject jsonObject = mappingParser.getJsonReader().readObject();
+        public Dog fromJson(JsonObject jsonObject, Type targetType, MappingParser parser) {
             String javaType = jsonObject.getString("//javaType");
             Class targetClass = javaType != null ? getSubClass(targetType, javaType) : (Class) targetType;
 
-            return mappingParser.readObject(jsonObject, targetClass);
+            return parser.readObject(jsonObject, targetClass);
         }
 
 
+
         /**
          * Helper method to check that javaType is really a subclass of targetType.
          * Might get moved to a utility class


[4/6] incubator-johnzon git commit: JOHNZON-71 Mapper cleanup, removed unused code

Posted by st...@apache.org.
JOHNZON-71 Mapper cleanup, removed unused code


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

Branch: refs/heads/master
Commit: 9bcba149bc2fa0cf8f25415547a8d6ce9b3b9a3b
Parents: 65e84ca
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Wed Apr 6 00:22:31 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Wed Apr 6 00:22:31 2016 +0200

----------------------------------------------------------------------
 .../java/org/apache/johnzon/mapper/Mapper.java  | 478 +------------------
 1 file changed, 2 insertions(+), 476 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/9bcba149/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index df0aa37..7854d3b 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -18,25 +18,14 @@
  */
 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 org.apache.johnzon.mapper.reflection.JohnzonCollectionType;
-import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
 import javax.json.JsonReader;
 import javax.json.JsonReaderFactory;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
 import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
 import javax.json.stream.JsonGenerator;
 import javax.json.stream.JsonGeneratorFactory;
-import javax.xml.bind.DatatypeConverter;
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
@@ -49,31 +38,9 @@ import java.io.Writer;
 import java.lang.reflect.Array;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
-import java.util.Deque;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -81,8 +48,6 @@ import static java.util.Arrays.asList;
 import static org.apache.johnzon.mapper.internal.Streams.noClose;
 
 public class Mapper implements Closeable {
-    private static final Adapter<Object, String> FALLBACK_CONVERTER = new ConverterAdapter<Object>(new FallbackConverter());
-    private static final JohnzonParameterizedType ANY_LIST = new JohnzonParameterizedType(List.class, Object.class);
 
     protected final MapperConfig config;
     protected final Mappings mappings;
@@ -103,39 +68,6 @@ public class Mapper implements Closeable {
         this.closeables = closeables;
     }
 
-    /**
-     * @deprecated see MapperConfig
-     */
-    private Adapter findAdapter(final Type aClass) {
-        final Adapter<?, ?> converter = config.getAdapters().get(new AdapterKey(aClass, String.class));
-        if (converter != null) {
-            return converter;
-        }
-        if (Class.class.isInstance(aClass)) {
-            final Class<?> clazz = Class.class.cast(aClass);
-            if (clazz.isEnum()) {
-                final Adapter<?, ?> enumConverter = new ConverterAdapter(new EnumConverter(clazz));
-                config.getAdapters().putIfAbsent(new AdapterKey(String.class, aClass), enumConverter);
-                return enumConverter;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @deprecated see MapperConfig
-     */
-    private Object convertTo(final Type aClass, final String text) {
-        if (Object.class == aClass || String.class == aClass) {
-            return text;
-        }
-        final Adapter converter = findAdapter(aClass);
-        if (converter == null) {
-            config.getAdapters().putIfAbsent(new AdapterKey(String.class, aClass), FALLBACK_CONVERTER);
-            return FALLBACK_CONVERTER.to(text);
-        }
-        return converter.to(text);
-    }
 
     public <T> void writeArray(final Object object, final OutputStream stream) {
         writeObject(asList((T[]) object), stream);
@@ -245,64 +177,6 @@ public class Mapper implements Closeable {
         return mapObject(clazz, readerFactory.createReader(stream(stream)));
     }
 
-
-    private <T> T mapObject(final Type clazz, final JsonReader reader) {
-        return new MappingParserImpl(config, mappings, reader).readObject(clazz);
-    }
-
-
-    /**
-     * @deprecated just for refactoring
-     */
-    private <T> T mapObjectOld(final Type clazz, final JsonReader reader) {
-        try {
-            final JsonValue object = readerHandler.read(reader);
-            if (JsonStructure.class == clazz || JsonObject.class == clazz || JsonValue.class == clazz) {
-                return (T) object;
-            }
-            if (JsonObject.class.isInstance(object)) {
-                return (T) buildObject(clazz, JsonObject.class.cast(object));
-            }
-            if (JsonString.class.isInstance(object) && clazz == String.class) {
-                return (T) JsonString.class.cast(object).getString();
-            }
-            if (JsonNumber.class.isInstance(object)) {
-                final JsonNumber number = JsonNumber.class.cast(object);
-                if (clazz == int.class || clazz == Integer.class) {
-                    return (T) Integer.valueOf(number.intValue());
-                }
-                if (clazz == long.class || clazz == Long.class) {
-                    return (T) Long.valueOf(number.longValue());
-                }
-                if (clazz == double.class || clazz == Double.class) {
-                    return (T) Double.valueOf(number.doubleValue());
-                }
-                if (clazz == BigDecimal.class) {
-                    return (T) number.bigDecimalValue();
-                }
-                if (clazz == BigInteger.class) {
-                    return (T) number.bigIntegerValue();
-                }
-            }
-            if (JsonValue.NULL == object) {
-                return null;
-            }
-            if (JsonValue.TRUE == object && (Boolean.class == clazz || boolean.class == clazz)) {
-                return (T) Boolean.TRUE;
-            }
-            if (JsonValue.FALSE == object && (Boolean.class == clazz || boolean.class == clazz)) {
-                return (T) Boolean.FALSE;
-            }
-            throw new IllegalArgumentException("Unsupported " + object + " for type " + clazz);
-        } catch (final Exception e) {
-            throw new MapperException(e);
-        } finally {
-            if (config.isClose()) {
-                reader.close();
-            }
-        }
-    }
-
     public <T> Collection<T> readCollection(final InputStream stream, final ParameterizedType genericType) {
         return mapObject(genericType, readerFactory.createReader(stream(stream)));
     }
@@ -343,347 +217,11 @@ public class Mapper implements Closeable {
         return mapObject(Array.newInstance(clazz, 0).getClass(), reader);
     }
 
-    private Object buildObject(final Type inType, final JsonObject object) throws Exception {
-        Type type = inType;
-        if (inType == Object.class) {
-            type = new JohnzonParameterizedType(Map.class, String.class, Object.class);
-        }
-
-        final Mappings.ClassMapping classMapping = mappings.findOrCreateClassMapping(type);
-
-        if (classMapping == null) {
-            if (ParameterizedType.class.isInstance(type)) {
-                final ParameterizedType aType = ParameterizedType.class.cast(type);
-                final Type[] fieldArgTypes = aType.getActualTypeArguments();
-                if (fieldArgTypes.length >= 2) {
-                    final Class<?> raw = Class.class.cast(aType.getRawType());
-
-                    final Map map;
-                    if (LinkedHashMap.class == raw) {
-                        map = new LinkedHashMap();
-                    } else if (SortedMap.class.isAssignableFrom(raw) || NavigableMap.class == raw || TreeMap.class == raw) {
-                        map = new TreeMap();
-                    } else if (ConcurrentMap.class.isAssignableFrom(raw)) {
-                        map = new ConcurrentHashMap(object.size());
-                    } else if (EnumMap.class.isAssignableFrom(raw)) {
-                        map = new EnumMap(Class.class.cast(fieldArgTypes[0]));
-                    } else if (Map.class.isAssignableFrom(raw)) {
-                        map = new HashMap(object.size());
-                    } else {
-                        map = null;
-                    }
-
-                    if (map != null) {
-
-                        Type keyType;
-                        if (ParameterizedType.class.isInstance(fieldArgTypes[0])) {
-                            keyType = fieldArgTypes[0];
-                        } else {
-                            keyType = fieldArgTypes[0];
-                        }
-
-                        final boolean any = fieldArgTypes.length < 2 || fieldArgTypes[1] == Object.class;
-                        for (final Map.Entry<String, JsonValue> value : object.entrySet()) {
-                            final JsonValue jsonValue = value.getValue();
-                            if (JsonNumber.class.isInstance(jsonValue) && any) {
-                                final JsonNumber number = JsonNumber.class.cast(jsonValue);
-                                if (readerHandler.isJsonLong(number)) {
-                                    final int integer = number.intValue();
-                                    final long asLong = number.longValue();
-                                    if (integer == asLong) {
-                                        map.put(value.getKey(), integer);
-                                    } else {
-                                        map.put(value.getKey(), asLong);
-                                    }
-                                } else {
-                                    map.put(value.getKey(), !number.isIntegral() ? number.bigDecimalValue() : number.intValue());
-                                }
-                            } 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));
-                            }
-                        }
-                        return map;
-                    }
-                }
-            } 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));
-                }
-                return map;
-            }
-        }
-        if (classMapping == null) {
-            throw new MapperException("Can't map " + type);
-        }
-
-        if (classMapping.factory == null) {
-            throw new IllegalArgumentException(classMapping.clazz + " not instantiable");
-        }
-
-        final Object t = classMapping.factory.getParameterTypes().length == 0 ?
-                classMapping.factory.create(null) : classMapping.factory.create(createParameters(classMapping, object));
-        for (final Map.Entry<String, Mappings.Setter> setter : classMapping.setters.entrySet()) {
-            final JsonValue jsonValue = object.get(setter.getKey());
-            final Mappings.Setter value = setter.getValue();
-            if (JsonValue.class == value.paramType) {
-                setter.getValue().writer.write(t, jsonValue);
-                continue;
-            }
-            if (jsonValue == null) {
-                continue;
-            }
-
-            final AccessMode.Writer setterMethod = value.writer;
-            if (jsonValue == JsonValue.NULL) { // forced
-                setterMethod.write(t, null);
-            } else {
-                Object existingInstance = null;
-                if (config.isReadAttributeBeforeWrite()) {
-                    final Mappings.Getter getter = classMapping.getters.get(setter.getKey());
-                    if (getter != null) {
-                        try {
-                            existingInstance = getter.reader.read(t);
-                        } catch (final RuntimeException re) {
-                            // backward compatibility
-                        }
-                    }
-                }
-                final Object convertedValue = toValue(existingInstance, jsonValue, value.converter, value.itemConverter, value.paramType);
-                if (convertedValue != null) {
-                    setterMethod.write(t, convertedValue);
-                }
-            }
-        }
-
-        return t;
-    }
-
-    private Object toValue(final Object baseInstance, final JsonValue jsonValue, final Adapter converter,
-                           final Adapter itemConverter, final Type type) throws Exception {
-        return converter == null ?
-                toObject(baseInstance, jsonValue, type, itemConverter) : jsonValue.getValueType() == ValueType.STRING ?
-                converter.to(JsonString.class.cast(jsonValue).getString()) :
-                convertTo(converter, jsonValue);
-    }
 
-    private Object convertTo(final Adapter converter, final JsonValue jsonValue) {
-        if (jsonValue.getValueType() == ValueType.OBJECT) {
-            AdapterKey adapterKey = reverseAdaptersRegistry.get(converter);
-            if (adapterKey == null) {
-                for (final Map.Entry<AdapterKey, Adapter<?, ?>> entry : config.getAdapters().entrySet()) {
-                    if (entry.getValue() == converter) {
-                        adapterKey = entry.getKey();
-                        reverseAdaptersRegistry.put(converter, adapterKey);
-                        break;
-                    }
-                }
-            }
-            final Object param;
-            try {
-                param = buildObject(adapterKey.getTo(), JsonObject.class.cast(jsonValue));
-            } catch (final Exception e) {
-                throw new MapperException(e);
-            }
-            return converter.to(param);
-        }
-        return converter.to(jsonValue.toString());
-    }
-
-    private Object[] createParameters(final Mappings.ClassMapping mapping, final JsonObject object) throws Exception {
-        final int length = mapping.factory.getParameterTypes().length;
-        final Object[] objects = new Object[length];
-        for (int i = 0; i < length; i++) {
-            objects[i] = toValue(
-                    null,
-                    object.get(mapping.factory.getParameterNames()[i]), mapping.factory.getParameterConverter()[i],
-                    mapping.factory.getParameterItemConverter()[i], mapping.factory.getParameterTypes()[i]);
-        }
-        return objects;
-    }
-
-    private Object toObject(final Object baseInstance, final JsonValue jsonValue,
-                            final Type type, final Adapter itemConverter) throws Exception {
-        if (jsonValue == null || JsonValue.NULL == jsonValue) {
-            return null;
-        }
-
-        if (type == Boolean.class || type == boolean.class) {
-            if (jsonValue == JsonValue.TRUE) {
-                return true;
-            }
-            if (jsonValue == JsonValue.FALSE) {
-                return false;
-            }
-            throw new MapperException("Unable to parse " + jsonValue + " to boolean");
-        }
-
-        if(config.isTreatByteArrayAsBase64() && jsonValue.getValueType() == ValueType.STRING && (type == byte[].class /*|| type == Byte[].class*/)) {
-            return DatatypeConverter.parseBase64Binary(((JsonString)jsonValue).getString());
-        }
-
-        if (Object.class == type) { // handling specific types here to keep exception in standard handling
-            if (jsonValue == JsonValue.TRUE) {
-                return true;
-            }
-            if (jsonValue == JsonValue.FALSE) {
-                return false;
-            }
-            if (JsonNumber.class.isInstance(jsonValue)) {
-                final JsonNumber jsonNumber = JsonNumber.class.cast(jsonValue);
-                if(jsonNumber.isIntegral()) {
-                    return jsonNumber.intValue();
-                }
-                return jsonNumber.doubleValue();
-            }
-        }
-
-        if (type == Character.class || type == char.class) {
-            return convertTo(Class.class.cast(type), (JsonString.class.cast(jsonValue).getString()));
-        }
-
-        if (JsonObject.class.isInstance(jsonValue)) {
-            if (JsonObject.class == type || JsonStructure.class == type) {
-                return jsonValue;
-            }
-            final boolean typedAdapter = TypeAwareAdapter.class.isInstance(itemConverter);
-            final Object object = buildObject(
-                    baseInstance != null ? baseInstance.getClass() : (
-                            typedAdapter ? TypeAwareAdapter.class.cast(itemConverter).getTo() : type),
-                    JsonObject.class.cast(jsonValue));
-            return typedAdapter ? itemConverter.to(object) : object;
-        } else if (JsonArray.class.isInstance(jsonValue)) {
-            if (JsonArray.class == type || JsonStructure.class == type) {
-                return jsonValue;
-            }
-            return buildArray(type, JsonArray.class.cast(jsonValue), itemConverter);
-        } else if (JsonNumber.class.isInstance(jsonValue)) {
-            if (JsonNumber.class == type) {
-                return jsonValue;
-            }
-
-            final JsonNumber number = JsonNumber.class.cast(jsonValue);
-
-            if (type == Integer.class || type == int.class) {
-                return number.intValue();
-            }
-
-            if (type == Long.class || type == long.class) {
-                return number.longValue();
-            }
-
-            if (type == Short.class || type == short.class) {
-                return (short) number.intValue();
-            }
-
-            if (type == Byte.class || type == byte.class) {
-                return (byte) number.intValue();
-            }
-
-            if (type == Float.class || type == float.class) {
-                return (float) number.doubleValue();
-            }
-
-            if (type == Double.class || type == double.class) {
-                return number.doubleValue();
-            }
-
-            if (type == BigInteger.class) {
-                return number.bigIntegerValue();
-            }
-
-            if (type == BigDecimal.class) {
-                return number.bigDecimalValue();
-            }
-        } else if (JsonString.class.isInstance(jsonValue)) {
-            if (JsonString.class == type) {
-                return jsonValue;
-            }
-
-            final String string = JsonString.class.cast(jsonValue).getString();
-            if (itemConverter == null) {
-                return convertTo(Class.class.cast(type), string);
-            } else {
-                return itemConverter.to(string);
-            }
-        }
-
-        throw new MapperException("Unable to parse " + jsonValue + " to " + type);
-    }
-
-    private Object buildArray(final Type type, final JsonArray jsonArray, final Adapter itemConverter) throws Exception {
-        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);
-            }
-        }
-
-        if (ParameterizedType.class.isInstance(type)) {
-            final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(ParameterizedType.class.cast(type));
-            if (mapping != null) {
-                return mapCollection(mapping, jsonArray, itemConverter);
-            }
-        }
-
-        if (Object.class == type) {
-            return buildArray(ANY_LIST, jsonArray, null);
-        }
-
-        throw new UnsupportedOperationException("type " + type + " not supported");
-    }
-
-    private <T> Collection<T> mapCollection(final Mappings.CollectionMapping mapping, final JsonArray jsonArray,
-                                            final Adapter itemConverter) throws Exception {
-        final Collection collection;
-
-        if (SortedSet.class == mapping.raw || NavigableSet.class == mapping.raw || TreeSet.class == mapping.raw) {
-            collection = new TreeSet<T>();
-        } else if (Set.class == mapping.raw || HashSet.class == mapping.raw) {
-            collection = new HashSet<T>(jsonArray.size());
-        } else if (Queue.class == mapping.raw || ArrayBlockingQueue.class == mapping.raw) {
-            collection = new ArrayBlockingQueue<T>(jsonArray.size());
-        } else if (List.class == mapping.raw || Collection.class == mapping.raw || ArrayList.class == mapping.raw || EnumSet.class == mapping.raw) {
-            collection = new ArrayList<T>(jsonArray.size());
-        } else if (LinkedHashSet.class == mapping.raw) {
-            collection = new LinkedHashSet<T>(jsonArray.size());
-        } else if (Deque.class == mapping.raw || ArrayDeque.class == mapping.raw) {
-            collection = new ArrayDeque(jsonArray.size());
-        } else if (Queue.class == mapping.raw || PriorityQueue.class == mapping.raw) {
-            collection = new PriorityQueue(jsonArray.size());
-        } else {
-            throw new IllegalStateException("not supported collection type: " + mapping.raw.getName());
-        }
-
-        for (final JsonValue value : jsonArray) {
-            collection.add(value == JsonValue.NULL ? null : toObject(null, value, mapping.arg, itemConverter));
-        }
-
-        if (EnumSet.class == mapping.raw) {
-            if (collection.isEmpty()) {
-                return EnumSet.noneOf(Class.class.cast(mapping.arg));
-            } else if (collection.size() == 1) {
-                return Collection.class.cast(EnumSet.of(Enum.class.cast(collection.iterator().next())));
-            } else {
-                final List<Enum<?>> list = List.class.cast(collection);
-                return Collection.class.cast(EnumSet.of(list.get(0), list.subList(1, list.size()).toArray(new Enum[list.size() - 1])));
-            }
-        }
-
-        return collection;
+    private <T> T mapObject(final Type clazz, final JsonReader reader) {
+        return new MappingParserImpl(config, mappings, reader).readObject(clazz);
     }
 
-    private Object buildArrayWithComponentType(final JsonArray jsonArray, final Class<?> componentType, final Adapter itemConverter) throws Exception {
-        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));
-        }
-        return array;
-    }
 
     private Reader stream(final Reader stream) {
         return !config.isClose() ? noClose(stream) : stream;
@@ -720,16 +258,4 @@ public class Mapper implements Closeable {
         }
     }
 
-    private static class FallbackConverter implements Converter<Object> {
-        @Override
-        public String toString(final Object instance) {
-            return instance.toString();
-        }
-
-        @Override
-        public Object fromString(final String text) {
-            throw new UnsupportedOperationException("Using fallback converter, " +
-                    "this only works in write mode but not in read. Please register a custom converter to do so.");
-        }
-    }
 }


[3/6] incubator-johnzon git commit: JOHNZON-71 move collection logic to MappingParser

Posted by st...@apache.org.
JOHNZON-71 move collection logic to MappingParser


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

Branch: refs/heads/master
Commit: 65e84ca0b5e02d816709aa547bc48cd1c5827dac
Parents: d7f4a86
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Wed Apr 6 00:11:55 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Wed Apr 6 00:11:55 2016 +0200

----------------------------------------------------------------------
 .../java/org/apache/johnzon/mapper/Mapper.java  | 30 ++------------------
 .../johnzon/mapper/MappingParserImpl.java       | 18 ++++++++++--
 2 files changed, 18 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/65e84ca0/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index 917aee5..df0aa37 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -304,20 +304,7 @@ public class Mapper implements Closeable {
     }
 
     public <T> Collection<T> readCollection(final InputStream stream, final ParameterizedType genericType) {
-        final JsonReader reader = readerFactory.createReader(stream(stream));
-        final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(genericType);
-        if (mapping == null) {
-            throw new UnsupportedOperationException("type " + genericType + " not supported");
-        }
-        try {
-            return mapCollection(mapping, reader.readArray(), null);
-        } catch (final Exception e) {
-            throw new MapperException(e);
-        } finally {
-            if (config.isClose()) {
-                reader.close();
-            }
-        }
+        return mapObject(genericType, readerFactory.createReader(stream(stream)));
     }
 
     public <T> T readJohnzonCollection(final InputStream stream, final JohnzonCollectionType<T> genericType) {
@@ -329,20 +316,7 @@ public class Mapper implements Closeable {
     }
 
     public <T> Collection<T> readCollection(final Reader stream, final ParameterizedType genericType) {
-        final JsonReader reader = readerFactory.createReader(stream(stream));
-        final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(genericType);
-        if (mapping == null) {
-            throw new UnsupportedOperationException("type " + genericType + " not supported");
-        }
-        try {
-            return mapCollection(mapping, reader.readArray(), null);
-        } catch (final Exception e) {
-            throw new MapperException(e);
-        } finally {
-            if (config.isClose()) {
-                reader.close();
-            }
-        }
+        return mapObject(genericType, readerFactory.createReader(stream(stream)));
     }
 
     public <T> T[] readArray(final Reader stream, final Class<T> clazz) {

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/65e84ca0/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 140d203..b0239d6 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
@@ -133,9 +133,23 @@ public class MappingParserImpl implements MappingParser {
                 return (T) number.bigIntegerValue();
             }
         }
-        if (JsonArray.class.isInstance(jsonValue) && Class.class.isInstance(targetType) && ((Class) targetType).isArray()) {
-            return (T) buildArrayWithComponentType((JsonArray) jsonValue, ((Class) targetType).getComponentType(), null);
+        if (JsonArray.class.isInstance(jsonValue)) {
 
+            JsonArray jsonArray = (JsonArray) jsonValue;
+
+            if (Class.class.isInstance(targetType) && ((Class) targetType).isArray()) {
+                return (T) buildArrayWithComponentType(jsonArray, ((Class) targetType).getComponentType(), null);
+            }
+            if (ParameterizedType.class.isInstance(targetType)) {
+
+                final Mappings.CollectionMapping mapping = mappings.findCollectionMapping((ParameterizedType) targetType);
+                if (mapping == null) {
+                    throw new UnsupportedOperationException("type " + targetType + " not supported");
+                }
+
+                return (T) mapCollection(mapping, jsonArray, null);
+
+            }
         }
         if (JsonValue.NULL == jsonValue) {
             return null;


[5/6] incubator-johnzon git commit: JOHNZON-71 json-p 1.1 handling optional

Posted by st...@apache.org.
JOHNZON-71 json-p 1.1 handling optional


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

Branch: refs/heads/master
Commit: 97fea634ae2ec186f40b740f7294a5a461948ee1
Parents: 9bcba14
Author: Mark Struberg <st...@apache.org>
Authored: Wed Apr 6 22:11:38 2016 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Wed Apr 6 22:11:38 2016 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/johnzon/mapper/MappingParserImpl.java | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/97fea634/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 b0239d6..9a7dcfa 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
@@ -19,6 +19,7 @@
 package org.apache.johnzon.mapper;
 
 import org.apache.johnzon.core.JsonLongImpl;
+import org.apache.johnzon.core.JsonReaderImpl;
 import org.apache.johnzon.mapper.access.AccessMode;
 import org.apache.johnzon.mapper.converter.EnumConverter;
 import org.apache.johnzon.mapper.internal.AdapterKey;
@@ -96,6 +97,11 @@ public class MappingParserImpl implements MappingParser {
     public <T> T readObject(Type targetType) {
 
         try {
+            if (jsonReader instanceof JsonReaderImpl) {
+                // later in JSON-P 1.1 we can remove this hack again
+                return readObject(((JsonReaderImpl) jsonReader).readValue(), targetType);
+            }
+
             return readObject(jsonReader.read(), targetType);
         } finally {
             if (config.isClose()) {


[6/6] incubator-johnzon git commit: JOHNZON-71 replaced IllegalArgumentException with MapperException

Posted by st...@apache.org.
JOHNZON-71 replaced IllegalArgumentException with MapperException


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

Branch: refs/heads/master
Commit: e917e77d62a9dc19fbf7c9362de70dc8f34bd23c
Parents: 97fea63
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Wed Apr 6 22:34:10 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Wed Apr 6 22:34:10 2016 +0200

----------------------------------------------------------------------
 .../src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/e917e77d/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 9a7dcfa..e13778d 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
@@ -247,7 +247,7 @@ public class MappingParserImpl implements MappingParser {
         }
 
         if (classMapping.factory == null) {
-            throw new IllegalArgumentException(classMapping.clazz + " not instantiable");
+            throw new MapperException(classMapping.clazz + " not instantiable");
         }
 
         final Object t = classMapping.factory.getParameterTypes().length == 0 ?


[2/6] incubator-johnzon git commit: JOHNZON-71 move array logic to MappingParser

Posted by st...@apache.org.
JOHNZON-71 move array logic to MappingParser


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

Branch: refs/heads/master
Commit: d7f4a866ee38d754aaa5c6a426a2be5dec90b264
Parents: 253d6fa
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Tue Apr 5 23:52:40 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Tue Apr 5 23:52:40 2016 +0200

----------------------------------------------------------------------
 .../src/main/java/org/apache/johnzon/mapper/Mapper.java   | 10 +---------
 .../java/org/apache/johnzon/mapper/MappingParserImpl.java |  4 ++++
 2 files changed, 5 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/d7f4a866/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index fa9bfd2..917aee5 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -366,15 +366,7 @@ public class Mapper implements Closeable {
     }
 
     private Object mapArray(final Class<?> clazz, final JsonReader reader) {
-        try {
-            return buildArrayWithComponentType(reader.readArray(), clazz, null);
-        } catch (final Exception e) {
-            throw new MapperException(e);
-        } finally {
-            if (config.isClose()) {
-                reader.close();
-            }
-        }
+        return mapObject(Array.newInstance(clazz, 0).getClass(), reader);
     }
 
     private Object buildObject(final Type inType, final JsonObject object) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/d7f4a866/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 3c455a6..140d203 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
@@ -133,6 +133,10 @@ public class MappingParserImpl implements MappingParser {
                 return (T) number.bigIntegerValue();
             }
         }
+        if (JsonArray.class.isInstance(jsonValue) && Class.class.isInstance(targetType) && ((Class) targetType).isArray()) {
+            return (T) buildArrayWithComponentType((JsonArray) jsonValue, ((Class) targetType).getComponentType(), null);
+
+        }
         if (JsonValue.NULL == jsonValue) {
             return null;
         }