Ejemplo n.º 1
0
  /**
   * @param value May be null.
   * @param knownType May be null if the type is unknown.
   * @param elementType May be null if the type is unknown.
   */
  public void writeValue(Object value, Class knownType, Class elementType) {
    try {
      if (value == null) {
        writer.value(null);
        return;
      }

      Class actualType = value.getClass();

      if (actualType.isPrimitive()
          || actualType == String.class
          || actualType == Integer.class
          || actualType == Boolean.class
          || actualType == Float.class
          || actualType == Long.class
          || actualType == Double.class
          || actualType == Short.class
          || actualType == Byte.class
          || actualType == Character.class) {
        writer.value(value);
        return;
      }

      if (value instanceof Serializable) {
        writeObjectStart(actualType, knownType);
        ((Serializable) value).write(this);
        writeObjectEnd();
        return;
      }

      Serializer serializer = classToSerializer.get(actualType);
      if (serializer != null) {
        serializer.write(this, value, knownType);
        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 && actualType != ArrayList.class)
          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 = java.lang.reflect.Array.getLength(value);
        writeArrayStart();
        for (int i = 0; i < length; i++)
          writeValue(java.lang.reflect.Array.get(value, i), elementType, null);
        writeArrayEnd();
        return;
      }

      if (value instanceof OrderedMap) {
        if (knownType == null) knownType = OrderedMap.class;
        writeObjectStart(actualType, knownType);
        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 = ArrayMap.class;
        writeObjectStart(actualType, knownType);
        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 = OrderedMap.class;
        writeObjectStart(actualType, knownType);
        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 = OrderedMap.class;
        writeObjectStart(actualType, knownType);
        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, knownType);
      writeFields(value);
      writeObjectEnd();
    } catch (IOException ex) {
      throw new SerializationException(ex);
    }
  }
Ejemplo n.º 2
0
  /**
   * @param type 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> type, Class elementType, Object jsonData) {
    if (jsonData == null) return null;

    if (jsonData instanceof OrderedMap) {
      OrderedMap<String, Object> jsonMap = (OrderedMap) jsonData;

      String className = typeName == null ? null : (String) jsonMap.remove(typeName);
      if (className != null) {
        try {
          type = (Class<T>) Class.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, jsonMap, type);

        object = newInstance(type);

        if (object instanceof Serializable) {
          ((Serializable) object).read(this, jsonMap);
          return (T) object;
        }

        if (object instanceof HashMap) {
          HashMap result = (HashMap) object;
          for (Entry entry : jsonMap.entries())
            result.put(entry.key, readValue(elementType, null, entry.value));
          return (T) result;
        }
      } else object = new OrderedMap();

      if (object instanceof ObjectMap) {
        ObjectMap result = (ObjectMap) object;
        for (String key : jsonMap.orderedKeys())
          result.put(key, readValue(elementType, null, jsonMap.get(key)));
        return (T) result;
      }

      readFields(object, jsonMap);
      return (T) object;
    }

    if (type != null) {
      Serializer serializer = classToSerializer.get(type);
      if (serializer != null) return (T) serializer.read(this, jsonData, type);
    }

    if (jsonData instanceof Array) {
      Array array = (Array) jsonData;
      if (type == null || Array.class.isAssignableFrom(type)) {
        Array newArray = type == null ? new Array() : (Array) newInstance(type);
        newArray.ensureCapacity(array.size);
        for (int i = 0, n = array.size; i < n; i++)
          newArray.add(readValue(elementType, null, array.get(i)));
        return (T) newArray;
      }
      if (ArrayList.class.isAssignableFrom(type)) {
        ArrayList newArray = type == null ? new ArrayList() : (ArrayList) newInstance(type);
        newArray.ensureCapacity(array.size);
        for (int i = 0, n = array.size; i < n; i++)
          newArray.add(readValue(elementType, null, array.get(i)));
        return (T) newArray;
      }
      if (type.isArray()) {
        Class componentType = type.getComponentType();
        if (elementType == null) elementType = componentType;
        Object newArray = java.lang.reflect.Array.newInstance(componentType, array.size);
        for (int i = 0, n = array.size; i < n; i++)
          java.lang.reflect.Array.set(newArray, i, readValue(elementType, null, array.get(i)));
        return (T) newArray;
      }
      throw new SerializationException(
          "Unable to convert value to required type: " + jsonData + " (" + type.getName() + ")");
    }

    if (jsonData instanceof Float) {
      Float floatValue = (Float) jsonData;
      try {
        if (type == null || type == float.class || type == Float.class)
          return (T) (Float) floatValue;
        if (type == int.class || type == Integer.class) return (T) (Integer) floatValue.intValue();
        if (type == long.class || type == Long.class) return (T) (Long) floatValue.longValue();
        if (type == double.class || type == Double.class)
          return (T) (Double) floatValue.doubleValue();
        if (type == short.class || type == Short.class) return (T) (Short) floatValue.shortValue();
        if (type == byte.class || type == Byte.class) return (T) (Byte) floatValue.byteValue();
      } catch (NumberFormatException ignored) {
      }
      jsonData = String.valueOf(jsonData);
    }

    if (jsonData instanceof Boolean) jsonData = String.valueOf(jsonData);

    if (jsonData instanceof String) {
      String string = (String) jsonData;
      if (type == null || type == String.class) return (T) jsonData;
      try {
        if (type == int.class || type == Integer.class) return (T) Integer.valueOf(string);
        if (type == float.class || type == Float.class) return (T) Float.valueOf(string);
        if (type == long.class || type == Long.class) return (T) Long.valueOf(string);
        if (type == double.class || type == Double.class) return (T) Double.valueOf(string);
        if (type == short.class || type == Short.class) return (T) Short.valueOf(string);
        if (type == byte.class || type == Byte.class) return (T) Byte.valueOf(string);
      } catch (NumberFormatException ignored) {
      }
      if (type == boolean.class || type == Boolean.class) return (T) Boolean.valueOf(string);
      if (type == char.class || type == 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 (type == CharSequence.class) return (T) string;
      throw new SerializationException(
          "Unable to convert value to required type: " + jsonData + " (" + type.getName() + ")");
    }

    return null;
  }
Ejemplo n.º 3
0
 private void prettyPrint(Object object, StringBuilder buffer, int indent, int singleLineColumns) {
   if (object instanceof OrderedMap) {
     OrderedMap<String, ?> map = (OrderedMap) object;
     if (map.size == 0) {
       buffer.append("{}");
     } else {
       boolean newLines = !isFlat(map);
       int start = buffer.length();
       outer:
       while (true) {
         buffer.append(newLines ? "{\n" : "{ ");
         int i = 0;
         for (String key : map.orderedKeys()) {
           if (newLines) indent(indent, buffer);
           buffer.append(outputType.quoteName(key));
           buffer.append(": ");
           prettyPrint(map.get(key), buffer, indent + 1, singleLineColumns);
           if (i++ < map.size - 1) buffer.append(",");
           buffer.append(newLines ? '\n' : ' ');
           if (!newLines && buffer.length() - start > singleLineColumns) {
             buffer.setLength(start);
             newLines = true;
             continue outer;
           }
         }
         break;
       }
       if (newLines) indent(indent - 1, buffer);
       buffer.append('}');
     }
   } else if (object instanceof Array) {
     Array array = (Array) object;
     if (array.size == 0) {
       buffer.append("[]");
     } else {
       boolean newLines = !isFlat(array);
       int start = buffer.length();
       outer:
       while (true) {
         buffer.append(newLines ? "[\n" : "[ ");
         for (int i = 0, n = array.size; i < n; i++) {
           if (newLines) indent(indent, buffer);
           prettyPrint(array.get(i), buffer, indent + 1, singleLineColumns);
           if (i < array.size - 1) buffer.append(",");
           buffer.append(newLines ? '\n' : ' ');
           if (!newLines && buffer.length() - start > singleLineColumns) {
             buffer.setLength(start);
             newLines = true;
             continue outer;
           }
         }
         break;
       }
       if (newLines) indent(indent - 1, buffer);
       buffer.append(']');
     }
   } else if (object instanceof String) {
     buffer.append(outputType.quoteValue((String) object));
   } else if (object instanceof Float) {
     Float floatValue = (Float) object;
     int intValue = floatValue.intValue();
     buffer.append(floatValue - intValue == 0 ? intValue : object);
   } else if (object instanceof Boolean) {
     buffer.append(object);
   } else if (object == null) {
     buffer.append("null");
   } else throw new SerializationException("Unknown object type: " + object.getClass());
 }