@SuppressWarnings({"unchecked", "rawtypes"}) public Object jsonToObject(final JSonNode json, Type type) throws MapperException { final ClassCache cc; try { Class<?> clazz = null; if (type instanceof ParameterizedType) { Type typ = ((ParameterizedType) type).getRawType(); if (typ instanceof Class) { clazz = (Class<?>) typ; } } else if (type instanceof Class) { clazz = (Class) type; } else if (type instanceof GenericArrayType) { // this is for 1.6 // for 1.7 we do not get GenericArrayTypeImpl here but the // actual array class type = clazz = Array.newInstance((Class<?>) ((GenericArrayType) type).getGenericComponentType(), 0) .getClass(); } if (clazz == null || clazz == Object.class) { if (json instanceof JSonArray) { type = clazz = LinkedList.class; } else if (json instanceof JSonObject) { type = clazz = HashMap.class; } else if (json instanceof JSonValue) { switch (((JSonValue) json).getType()) { case BOOLEAN: type = clazz = boolean.class; break; case DOUBLE: type = clazz = double.class; break; case LONG: type = clazz = long.class; break; case NULL: case STRING: type = clazz = String.class; } } } final TypeMapper<?> tm = typeMapper.get(clazz); if (tm != null) { return tm.reverseMap(json); } if (json instanceof JSonValue) { if (!Clazz.isPrimitive(type) && !Clazz.isString(type) && type != Object.class && ((JSonValue) json).getValue() != null && !Clazz.isEnum(type)) { // throw new MapperException(json + " cannot be mapped to " + type); } switch (((JSonValue) json).getType()) { case BOOLEAN: case DOUBLE: case LONG: if (type instanceof Class) { return JSonMapper.cast(((JSonValue) json).getValue(), (Class) type); } else { return ((JSonValue) json).getValue(); } case STRING: if (type instanceof Class && ((Class<?>) type).isEnum()) { try { return Enum.valueOf((Class<Enum>) type, ((JSonValue) json).getValue() + ""); } catch (final IllegalArgumentException e) { if (isIgnoreIllegalArgumentMappings() || isIgnoreIllegalEnumMappings()) { return null; } throw e; } } else { return ((JSonValue) json).getValue(); } case NULL: return null; } } if (type instanceof ParameterizedType) { final ParameterizedType pType = (ParameterizedType) type; Type raw = pType.getRawType(); if (raw instanceof Class && Collection.class.isAssignableFrom((Class) raw)) { final Collection<Object> inst = (Collection<Object>) mapClasses((Class) raw).newInstance(); final JSonArray obj = (JSonArray) json; for (final JSonNode n : obj) { inst.add(this.jsonToObject(n, pType.getActualTypeArguments()[0])); } return inst; } else if (raw instanceof Class && Map.class.isAssignableFrom((Class) raw)) { final Map<String, Object> inst = (Map<String, Object>) mapClasses((Class) raw).newInstance(); final JSonObject obj = (JSonObject) json; Entry<String, JSonNode> next; for (final Iterator<Entry<String, JSonNode>> it = obj.entrySet().iterator(); it.hasNext(); ) { next = it.next(); inst.put( next.getKey(), this.jsonToObject(next.getValue(), pType.getActualTypeArguments()[1])); } return inst; } } if (clazz != null) { if (clazz == Object.class) { // guess type if (json instanceof JSonArray) { type = LinkedList.class; } else if (json instanceof JSonObject) { type = HashMap.class; } } if (Collection.class.isAssignableFrom(clazz)) { final Collection<Object> inst = (Collection<Object>) mapClasses(clazz).newInstance(); final JSonArray obj = (JSonArray) json; final Type gs = clazz.getGenericSuperclass(); final Type gType; if (gs instanceof ParameterizedType) { gType = ((ParameterizedType) gs).getActualTypeArguments()[0]; } else { gType = void.class; } for (final JSonNode n : obj) { inst.add(this.jsonToObject(n, gType)); } return inst; } else if (Map.class.isAssignableFrom(clazz)) { final Map<String, Object> inst = (Map<String, Object>) mapClasses(clazz).newInstance(); final JSonObject obj = (JSonObject) json; final Type gs = clazz.getGenericSuperclass(); final Type gType; if (gs instanceof ParameterizedType) { gType = ((ParameterizedType) gs).getActualTypeArguments()[1]; } else { gType = void.class; } Entry<String, JSonNode> next; for (final Iterator<Entry<String, JSonNode>> it = obj.entrySet().iterator(); it.hasNext(); ) { next = it.next(); inst.put(next.getKey(), this.jsonToObject(next.getValue(), gType)); } return inst; } else if (clazz.isArray()) { final JSonArray obj = (JSonArray) json; final Object arr = Array.newInstance(mapClasses(clazz.getComponentType()), obj.size()); for (int i = 0; i < obj.size(); i++) { final Object v = this.jsonToObject(obj.get(i), clazz.getComponentType()); Array.set(arr, i, v); } return arr; } else { if (json instanceof JSonArray) { final java.util.List<Object> inst = new ArrayList<Object>(); final JSonArray obj = (JSonArray) json; final Type gs = clazz.getGenericSuperclass(); final Type gType; if (gs instanceof ParameterizedType) { gType = ((ParameterizedType) gs).getActualTypeArguments()[0]; } else { gType = Object.class; } for (final JSonNode n : obj) { inst.add(this.jsonToObject(n, gType)); } return inst; } else { final JSonObject obj = (JSonObject) json; if (Clazz.isPrimitive(clazz)) { // if (isIgnoreIllegalArgumentMappings()) { return null; } else { throw new IllegalArgumentException("Cannot Map " + obj + " to " + clazz); } } cc = ClassCache.getClassCache(clazz); final Object inst = cc.getInstance(); JSonNode value; Object v; for (final Setter s : cc.getSetter()) { value = obj.get(s.getKey()); if (value == null) { continue; } // Type fieldType = s.getType(); // special handling for generic fields if (fieldType instanceof TypeVariable) { final Type[] actualTypes = ((ParameterizedType) type).getActualTypeArguments(); final TypeVariable<?>[] genericTypes = clazz.getTypeParameters(); for (int i = 0; i < genericTypes.length; i++) { if (StringUtils.equals( ((TypeVariable) fieldType).getName(), genericTypes[i].getName())) { fieldType = actualTypes[i]; break; } } } v = this.jsonToObject(value, fieldType); try { s.setValue(inst, v); } catch (final IllegalArgumentException e) { if (isIgnoreIllegalArgumentMappings()) { continue; } else if (v == null && isIgnorePrimitiveNullMapping()) { continue; } throw e; } } return inst; } } } else { System.err.println("TYPE?!"); } } catch (final SecurityException e) { e.printStackTrace(); } catch (final NoSuchMethodException e) { e.printStackTrace(); } catch (final IllegalArgumentException e) { e.printStackTrace(); } catch (final InstantiationException e) { e.printStackTrace(); } catch (final IllegalAccessException e) { e.printStackTrace(); } catch (final InvocationTargetException e) { e.printStackTrace(); } return null; }
/** * @param obj * @return * @throws MapperException */ @SuppressWarnings("unchecked") public JSonNode create(final Object obj) throws MapperException { try { if (obj == null) { return new JSonValue(null); } final Class<? extends Object> clazz = obj.getClass(); TypeMapper<?> mapper; if (clazz.isPrimitive()) { if (clazz == boolean.class) { return new JSonValue((Boolean) obj); } else if (clazz == char.class) { return new JSonValue(0 + ((Character) obj).charValue()); } else if (clazz == byte.class) { return new JSonValue(((Byte) obj).longValue()); } else if (clazz == short.class) { return new JSonValue(((Short) obj).longValue()); } else if (clazz == int.class) { return new JSonValue(((Integer) obj).longValue()); } else if (clazz == long.class) { return new JSonValue(((Long) obj).longValue()); } else if (clazz == float.class) { return new JSonValue(((Float) obj).doubleValue()); } else if (clazz == double.class) { return new JSonValue(((Double) obj).doubleValue()); } } else if (clazz.isEnum()) { return new JSonValue(obj + ""); } else if (obj instanceof Boolean) { return new JSonValue(((Boolean) obj).booleanValue()); } else if (obj instanceof Character) { return new JSonValue(0 + ((Character) obj).charValue()); } else if (obj instanceof Byte) { return new JSonValue(((Byte) obj).longValue()); } else if (obj instanceof Short) { return new JSonValue(((Short) obj).longValue()); } else if (obj instanceof Integer) { return new JSonValue(((Integer) obj).longValue()); } else if (obj instanceof Long) { return new JSonValue(((Long) obj).longValue()); } else if (obj instanceof Float) { return new JSonValue(((Float) obj).doubleValue()); } else if (obj instanceof Double) { return new JSonValue(((Double) obj).doubleValue()); } else if (obj instanceof String) { return new JSonValue((String) obj); } else if (obj instanceof Map) { final JSonObject ret = new JSonObject(); Entry<Object, Object> next; for (final Iterator<Entry<Object, Object>> it = ((Map<Object, Object>) obj).entrySet().iterator(); it.hasNext(); ) { next = it.next(); if (!(next.getKey() instanceof String)) { throw new MapperException( "Map keys have to be Strings: " + clazz + " Keyclass:" + (next.getKey() == null ? "<null>" : next.getKey().getClass())); } ret.put(next.getKey().toString(), create(next.getValue())); } return ret; } else if (obj instanceof Collection) { final JSonArray ret = new JSonArray(); for (final Object o : (Collection<?>) obj) { ret.add(create(o)); } return ret; } else if (clazz.isArray()) { final JSonArray ret = new JSonArray(); for (int i = 0; i < Array.getLength(obj); i++) { ret.add(create(Array.get(obj, i))); } return ret; } else if (obj instanceof Class) { return new JSonValue(((Class<?>) obj).getName()); } else if ((mapper = typeMapper.get(clazz)) != null) { return mapper.map(obj); } else /* if (obj instanceof Storable) */ { final ClassCache cc = ClassCache.getClassCache(clazz); final JSonObject ret = new JSonObject(); for (final Getter g : cc.getGetter()) { ret.put(g.getKey(), create(g.getValue(obj))); } return ret; } } catch (final IllegalArgumentException e) { e.printStackTrace(); } catch (final IllegalAccessException e) { e.printStackTrace(); } catch (final InvocationTargetException e) { e.printStackTrace(); } catch (final SecurityException e) { e.printStackTrace(); } catch (final NoSuchMethodException e) { e.printStackTrace(); } return null; }