ClassValueConverter.java
package com.surrealdb;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
class ClassValueConverter<T> {
private final Class<T> clazz;
ClassValueConverter(Class<T> clazz) {
this.clazz = clazz;
}
private static java.lang.Object convertSingleValue(final Value value) {
if (value.isBoolean()) {
return value.getBoolean();
} else if (value.isDouble()) {
return value.getDouble();
} else if (value.isLong()) {
return value.getLong();
} else if (value.isString()) {
return value.getString();
} else if (value.isThing()) {
return value.getThing();
} else if (value.isGeometry()) {
return value.getGeometry();
} else if (value.isBigdecimal()) {
return value.getBigDecimal();
} else if (value.isBytes()) {
return value.getBytes();
} else if (value.isUuid()) {
return value.getUuid();
}
throw new SurrealDBException("Unsupported value: " + value);
}
private static java.lang.Object convertArrayValue(final Field field, final Value value) throws ReflectiveOperationException {
if (value.isObject()) {
final Class<?> subType = getGenericType(field);
if (subType == null) {
throw new SurrealDBException("Unsupported field type: " + field);
}
return convertObject(subType, value.getObject());
} else if (value.isArray()) {
final List<java.lang.Object> arrayList = new ArrayList<>();
for (final Value elementValue : value.getArray()) {
arrayList.add(convertArrayValue(field, elementValue));
}
return arrayList;
} else {
return convertSingleValue(value);
}
}
private static <T> T convertObject(Class<T> clazz, Object source) throws ReflectiveOperationException {
final T target = clazz.getConstructor().newInstance();
for (final Entry entry : source) {
final Field field = clazz.getDeclaredField(entry.getKey());
final Value value = entry.getValue();
field.setAccessible(true);
if (value.isArray()) {
final List<java.lang.Object> arrayList = new ArrayList<>();
for (final Value elementValue : value.getArray()) {
arrayList.add(convertArrayValue(field, elementValue));
}
field.set(target, arrayList);
} else if (value.isObject()) {
java.lang.Object o = convertObject(field.getType(), value.getObject());
field.set(target, o);
} else {
field.set(target, convertSingleValue(value));
}
}
return target;
}
private static Class<?> getGenericType(final Field field) {
// Check if the field is parameterized
if (field.getGenericType() instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
// Get the actual type arguments (generics)
final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
if (actualTypeArguments.length > 0) {
// Return the first type argument
return (Class<?>) actualTypeArguments[0];
}
}
return null;
}
final T convertObject(final Value value) {
try {
return convertObject(clazz, value.getObject());
} catch (ReflectiveOperationException e) {
throw new SurrealDBException("Failed to create instance of " + clazz.getName(), e);
}
}
}