in odps-sdk/odps-sdk-core/src/main/java/com/aliyun/odps/data/converter/ComplexObjectConverter.java [167:296]
private JsonElement convertToJson(Object object, TypeInfo typeInfo, OdpsRecordConverter formatter) {
if (object == null) {
return JsonNull.INSTANCE;
}
switch (typeInfo.getOdpsType()) {
case ARRAY:
if (formatter.objectConverterMap.get(OdpsType.ARRAY) != ComplexObjectConverter.JSON &&
formatter.objectConverterMap.get(OdpsType.ARRAY) != ComplexObjectConverter.JSON_ALL_STR) {
// user customized converter
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
JsonArray jsonArray = new JsonArray();
ArrayTypeInfo arrayTypeInfo = (ArrayTypeInfo) typeInfo;
TypeInfo elementType = arrayTypeInfo.getElementTypeInfo();
List list = (List) object;
for (Object listItem : list) {
JsonElement element = convertToJson(listItem, elementType, formatter);
jsonArray.add((element));
}
return jsonArray;
case MAP:
if (formatter.objectConverterMap.get(OdpsType.MAP) != ComplexObjectConverter.JSON &&
formatter.objectConverterMap.get(OdpsType.MAP) != ComplexObjectConverter.JSON_ALL_STR) {
// user customized converter
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
JsonObject jsonObject = new JsonObject();
MapTypeInfo mapTypeInfo = (MapTypeInfo) typeInfo;
TypeInfo keyInfo = mapTypeInfo.getKeyTypeInfo();
TypeInfo valueInfo = mapTypeInfo.getValueTypeInfo();
Map map = (Map) object;
for (Object entryObject : map.entrySet()) {
Map.Entry entry = (Map.Entry) entryObject;
String keyString = formatter.formatObject(entry.getKey(), keyInfo);
JsonElement valString = convertToJson(entry.getValue(), valueInfo, formatter);
jsonObject.add(keyString, valString);
}
return jsonObject;
case STRUCT:
if (formatter.objectConverterMap.get(OdpsType.STRUCT) != ComplexObjectConverter.JSON &&
formatter.objectConverterMap.get(OdpsType.STRUCT) != ComplexObjectConverter.JSON_ALL_STR) {
// user customized converter
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
JsonObject jsonStruct = new JsonObject();
SimpleStruct struct = (SimpleStruct) object;
for (int i = 0; i < struct.getFieldCount(); i++) {
TypeInfo fieldType = struct.getFieldTypeInfo(i);
String key = struct.getFieldName(i);
Object value = struct.getFieldValue(i);
jsonStruct.add(key, convertToJson(value, fieldType, formatter));
}
return jsonStruct;
case BOOLEAN:
if (convertToString) {
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
return new JsonPrimitive((Boolean) object);
case TINYINT:
case SMALLINT:
case INT:
case BIGINT:
case FLOAT:
case DOUBLE:
if (convertToString) {
// GSON allow NAN INFINITY
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
return new JsonPrimitive((Number) object);
case DECIMAL:
if (convertToString) {
// GSON allow NAN INFINITY
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
}
Number n = new Number() {
@Override
public int intValue() {
return 0;
}
@Override
public long longValue() {
return 0;
}
@Override
public float floatValue() {
return 0;
}
@Override
public double doubleValue() {
return 0;
}
@Override
public String toString() {
// 3.0 => 3, same as sql
return ((BigDecimal)object).stripTrailingZeros().toPlainString();
}
};
return new JsonPrimitive(n);
case DATE:
case DATETIME:
case TIMESTAMP:
case TIMESTAMP_NTZ:
case BINARY:
case CHAR:
case VARCHAR:
case STRING:
return new JsonPrimitive(formatter.formatObject(object, typeInfo));
default:
throw new IllegalArgumentException("unsupported odpstype: " + typeInfo);
}
}