public void setElementType(Class type, String fieldName, Class elementType) { ObjectMap<String, FieldMetadata> fields = typeToFields.get(ReflectionCache.getType(type)); if (fields == null) fields = cacheFields(ReflectionCache.getType(type)); FieldMetadata metadata = fields.get(fieldName); if (metadata == null) throw new SerializationException( "Field not found: " + fieldName + " (" + type.getName() + ")"); metadata.elementType = elementType; }
public void readFields(Object object, JsonValue jsonMap) { Type type = ReflectionCache.getType(object.getClass()); ObjectMap<String, FieldMetadata> fields = typeToFields.get(type); if (fields == null) fields = cacheFields(type); for (JsonValue child = jsonMap.child(); child != null; child = child.next()) { FieldMetadata metadata = fields.get(child.name()); if (metadata == null) { if (ignoreUnknownFields) { if (debug) System.out.println( "Ignoring unknown field: " + child.name() + " (" + type.getName() + ")"); continue; } else throw new SerializationException( "Field not found: " + child.name() + " (" + type.getName() + ")"); } Field field = metadata.field; // if (entry.value == null) continue; // I don't remember what this did. :( try { field.set(object, readValue(field.getType().getClassOfType(), metadata.elementType, child)); } catch (IllegalAccessException ex) { throw new SerializationException( "Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); } catch (SerializationException ex) { ex.addTrace(field.getName() + " (" + type.getName() + ")"); throw ex; } catch (RuntimeException runtimeEx) { SerializationException ex = new SerializationException(runtimeEx); ex.addTrace(field.getName() + " (" + type.getName() + ")"); throw ex; } } }
/** @param elementType May be null if the type is unknown. */ public void readField( Object object, String fieldName, String jsonName, Class elementType, JsonValue jsonMap) { Type type = ReflectionCache.getType(object.getClass()); ObjectMap<String, FieldMetadata> fields = typeToFields.get(type); if (fields == null) fields = cacheFields(type); FieldMetadata metadata = fields.get(fieldName); if (metadata == null) throw new SerializationException( "Field not found: " + fieldName + " (" + type.getName() + ")"); Field field = metadata.field; JsonValue jsonValue = jsonMap.get(jsonName); if (jsonValue == null) return; if (elementType == null) elementType = metadata.elementType; try { field.set(object, readValue(field.getType().getClassOfType(), elementType, jsonValue)); } catch (IllegalAccessException ex) { throw new SerializationException( "Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); } catch (SerializationException ex) { ex.addTrace(field.getName() + " (" + type.getName() + ")"); throw ex; } catch (RuntimeException runtimeEx) { SerializationException ex = new SerializationException(runtimeEx); ex.addTrace(field.getName() + " (" + type.getName() + ")"); throw ex; } }
/** @param elementType May be null if the type is unknown. */ public void writeField(Object object, String fieldName, String jsonName, Class elementType) { Type type = ReflectionCache.getType(object.getClass()); ObjectMap<String, FieldMetadata> fields = typeToFields.get(type); if (fields == null) fields = cacheFields(type); FieldMetadata metadata = fields.get(fieldName); if (metadata == null) throw new SerializationException( "Field not found: " + fieldName + " (" + type.getName() + ")"); Field field = metadata.field; if (elementType == null) elementType = metadata.elementType; try { if (debug) System.out.println("Writing field: " + field.getName() + " (" + type.getName() + ")"); writer.name(jsonName); writeValue(field.get(object), field.getType().getClassOfType(), elementType); } catch (IllegalAccessException ex) { throw new SerializationException( "Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); } catch (SerializationException ex) { ex.addTrace(field + " (" + type.getName() + ")"); throw ex; } catch (Exception runtimeEx) { SerializationException ex = new SerializationException(runtimeEx); ex.addTrace(field + " (" + type.getName() + ")"); throw ex; } }
public Type getClass(String tag) { Type type = tagToClass.get(tag); if (type != null) return type; try { return ReflectionCache.forName(tag); } catch (ClassNotFoundException ex) { throw new SerializationException(ex); } }
public void writeType(Class type) { if (typeName == null) return; String className = classToTag.get(ReflectionCache.getType(type)); if (className == null) className = type.getName(); try { writer.set(typeName, className); } catch (IOException ex) { throw new SerializationException(ex); } if (debug) System.out.println("Writing type: " + type.getName()); }
public void addChild(Actor parent, Actor child) { child.remove(); try { ReflectionCache.getType(parent.getClass()) .getMethod("setWidget", Actor.class) .invoke(parent, child); return; } catch (Exception ignored) { // FIXME this is bad Gdx.app.log("TableToolkit", "Couldn't call setWidget", ignored); } ((Group) parent).addActor(child); }
public void writeFields(Object object) { Type type = ReflectionCache.getType(object.getClass()); Object[] defaultValues = getDefaultValues(type); ObjectMap<String, FieldMetadata> fields = typeToFields.get(type); if (fields == null) fields = cacheFields(type); int i = 0; for (FieldMetadata metadata : new Values<FieldMetadata>(fields)) { Field field = metadata.field; try { Object value = field.get(object); if (defaultValues != null) { Object defaultValue = defaultValues[i++]; if (value == null && defaultValue == null) continue; if (value != null && defaultValue != null && value.equals(defaultValue)) continue; } if (debug) System.out.println("Writing field: " + field.getName() + " (" + type.getName() + ")"); writer.name(field.getName()); writeValue(value, field.getType().getClassOfType(), metadata.elementType); } catch (IllegalAccessException ex) { throw new SerializationException( "Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); } catch (SerializationException ex) { ex.addTrace(field + " (" + type.getName() + ")"); throw ex; } catch (Exception runtimeEx) { SerializationException ex = new SerializationException(runtimeEx); ex.addTrace(field + " (" + type.getName() + ")"); throw ex; } } }
/** * @param clazz May be null if the type is unknown. * @param elementType May be null if the type is unknown. * @return May be null. */ public <T> T readValue(Class<T> clazz, Class elementType, JsonValue jsonData) { if (jsonData == null) return null; Type type = ReflectionCache.getType(clazz); if (jsonData.isObject()) { String className = typeName == null ? null : jsonData.getString(typeName, null); if (className != null) { jsonData.remove(typeName); try { type = ReflectionCache.forName(className); } catch (ClassNotFoundException ex) { type = tagToClass.get(className); if (type == null) throw new SerializationException(ex); } } Object object; if (type != null) { Serializer serializer = classToSerializer.get(type); if (serializer != null) return (T) serializer.read(this, jsonData, type.getClassOfType()); object = newInstance(type); if (object instanceof Serializable) { ((Serializable) object).read(this, jsonData); return (T) object; } if (object instanceof HashMap) { HashMap result = (HashMap) object; for (JsonValue child = jsonData.child(); child != null; child = child.next()) result.put(child.name(), readValue(elementType, null, child)); return (T) result; } } else object = new OrderedMap(); if (object instanceof ObjectMap) { ObjectMap result = (ObjectMap) object; for (JsonValue child = jsonData.child(); child != null; child = child.next()) result.put(child.name(), readValue(elementType, null, child)); return (T) result; } readFields(object, jsonData); return (T) object; } if (type != null) { Serializer serializer = classToSerializer.get(type); if (serializer != null) return (T) serializer.read(this, jsonData, type.getClassOfType()); } if (jsonData.isArray()) { if (type == null || type.isAssignableFrom(ReflectionCache.getType(Array.class))) { Array newArray = new Array(); for (JsonValue child = jsonData.child(); child != null; child = child.next()) newArray.add(readValue(elementType, null, child)); return (T) newArray; } if (type.isAssignableFrom(ReflectionCache.getType(ArrayList.class))) { ArrayList newArray = new ArrayList(); for (JsonValue child = jsonData.child(); child != null; child = child.next()) newArray.add(readValue(elementType, null, child)); return (T) newArray; } if (type.isArray()) { Class componentType = type.getComponentType(); if (elementType == null) elementType = componentType; Object newArray = ReflectionCache.newArray(componentType, jsonData.size()); Type arrayType = ReflectionCache.getType(newArray.getClass()); int i = 0; for (JsonValue child = jsonData.child(); child != null; child = child.next()) arrayType.setArrayElement(newArray, i++, readValue(elementType, null, child)); return (T) newArray; } throw new SerializationException( "Unable to convert value to required type: " + jsonData + " (" + type.getName() + ")"); } Class t = type == null ? null : type.getClassOfType(); if (jsonData.isNumber()) { try { if (type == null || t == float.class || t == Float.class) return (T) (Float) jsonData.asFloat(); if (t == int.class || t == Integer.class) return (T) (Integer) jsonData.asInt(); if (t == long.class || t == Long.class) return (T) (Long) jsonData.asLong(); if (t == double.class || t == Double.class) return (T) (Double) (double) jsonData.asFloat(); if (t == String.class) return (T) Float.toString(jsonData.asFloat()); if (t == short.class || t == Short.class) return (T) (Short) (short) jsonData.asInt(); if (t == byte.class || t == Byte.class) return (T) (Byte) (byte) jsonData.asInt(); } catch (NumberFormatException ignored) { } jsonData = new JsonValue(jsonData.asString()); } if (jsonData.isBoolean()) { try { if (type == null || t == boolean.class || t == Boolean.class) return (T) (Boolean) jsonData.asBoolean(); } catch (NumberFormatException ignored) { } jsonData = new JsonValue(jsonData.asString()); } if (jsonData.isString()) { String string = jsonData.asString(); if (type == null || t == String.class) return (T) string; try { if (t == int.class || t == Integer.class) return (T) Integer.valueOf(string); if (t == float.class || t == Float.class) return (T) Float.valueOf(string); if (t == long.class || t == Long.class) return (T) Long.valueOf(string); if (t == double.class || t == Double.class) return (T) Double.valueOf(string); if (t == short.class || t == Short.class) return (T) Short.valueOf(string); if (t == byte.class || t == Byte.class) return (T) Byte.valueOf(string); } catch (NumberFormatException ignored) { } if (t == boolean.class || t == Boolean.class) return (T) Boolean.valueOf(string); if (t == char.class || t == Character.class) return (T) (Character) string.charAt(0); if (type.isEnum()) { Object[] constants = type.getEnumConstants(); for (int i = 0, n = constants.length; i < n; i++) if (string.equals(constants[i].toString())) return (T) constants[i]; } if (t == CharSequence.class) return (T) string; throw new SerializationException( "Unable to convert value to required type: " + jsonData + " (" + type.getName() + ")"); } return null; }
/** * @param value May be null. * @param knownClass May be null if the type is unknown. * @param elementType May be null if the type is unknown. */ public void writeValue(Object value, Class knownClass, Class elementType) { try { if (value == null) { writer.value(null); return; } Type knownType = ReflectionCache.getType(knownClass); Type actualType = ReflectionCache.getType(value.getClass()); if (actualType.isPrimitive() || actualType.getClassOfType() == String.class || actualType.getClassOfType() == Integer.class || actualType.getClassOfType() == Boolean.class || actualType.getClassOfType() == Float.class || actualType.getClassOfType() == Long.class || actualType.getClassOfType() == Double.class || actualType.getClassOfType() == Short.class || actualType.getClassOfType() == Byte.class || actualType.getClassOfType() == Character.class) { writer.value(value); return; } if (value instanceof Serializable) { writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); ((Serializable) value).write(this); writeObjectEnd(); return; } Serializer serializer = classToSerializer.get(actualType); if (serializer != null) { serializer.write(this, value, knownType.getClassOfType()); return; } if (value instanceof Array) { if (knownType != null && actualType != knownType) throw new SerializationException( "Serialization of an Array other than the known type is not supported.\n" + "Known type: " + knownType + "\nActual type: " + actualType); writeArrayStart(); Array array = (Array) value; for (int i = 0, n = array.size; i < n; i++) writeValue(array.get(i), elementType, null); writeArrayEnd(); return; } if (value instanceof Collection) { if (knownType != null && actualType != knownType) throw new SerializationException( "Serialization of a Collection other than the known type is not supported.\n" + "Known type: " + knownType + "\nActual type: " + actualType); writeArrayStart(); for (Object item : (Collection) value) writeValue(item, elementType, null); writeArrayEnd(); return; } if (actualType.isArray()) { if (elementType == null) elementType = actualType.getComponentType(); int length = actualType.getArrayLength(value); writeArrayStart(); for (int i = 0; i < length; i++) writeValue(actualType.getArrayElement(value, i), elementType, null); writeArrayEnd(); return; } if (value instanceof OrderedMap) { if (knownType == null) knownType = ReflectionCache.getType(OrderedMap.class); writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); OrderedMap map = (OrderedMap) value; for (Object key : map.orderedKeys()) { writer.name(convertToString(key)); writeValue(map.get(key), elementType, null); } writeObjectEnd(); return; } if (value instanceof ArrayMap) { if (knownType == null) knownType = ReflectionCache.getType(ArrayMap.class); writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); ArrayMap map = (ArrayMap) value; for (int i = 0, n = map.size; i < n; i++) { writer.name(convertToString(map.keys[i])); writeValue(map.values[i], elementType, null); } writeObjectEnd(); return; } if (value instanceof ObjectMap) { if (knownType == null) knownType = ReflectionCache.getType(OrderedMap.class); writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); for (Entry entry : ((ObjectMap<?, ?>) value).entries()) { writer.name(convertToString(entry.key)); writeValue(entry.value, elementType, null); } writeObjectEnd(); return; } if (value instanceof Map) { if (knownType == null) knownType = ReflectionCache.getType(HashMap.class); writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); for (Map.Entry entry : ((Map<?, ?>) value).entrySet()) { writer.name(convertToString(entry.getKey())); writeValue(entry.getValue(), elementType, null); } writeObjectEnd(); return; } if (actualType.isEnum()) { writer.value(value); return; } writeObjectStart(actualType.getClassOfType(), knownType.getClassOfType()); writeFields(value); writeObjectEnd(); } catch (IOException ex) { throw new SerializationException(ex); } }
public <T> Serializer<T> getSerializer(Class<T> type) { return (Serializer<T>) classToSerializer.get(ReflectionCache.getType(type)); }
public <T> void setSerializer(Class<T> type, Serializer<T> serializer) { classToSerializer.put(ReflectionCache.getType(type), serializer); }