public <E> E getGenericProperty(final String key, final E def) { if (def == null || Clazz.isPrimitive(def.getClass())) { return storage.get(key, def); } else { System.out.println("Read " + path + "." + key + (plain ? ".json" : ".ejs")); return JSonStorage.restoreFromFile( new File(path + "." + key + (plain ? ".json" : ".ejs")), def); } }
@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; }