se.fortnox.reactivewizard.db.deserializing.DeserializerUtil Maven / Gradle / Ivy
package se.fortnox.reactivewizard.db.deserializing;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.fortnox.reactivewizard.json.JsonDeserializerFactory;
import se.fortnox.reactivewizard.util.CamelSnakeConverter;
import se.fortnox.reactivewizard.util.PropertyResolver;
import se.fortnox.reactivewizard.util.ReflectionUtil;
import java.lang.reflect.Type;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
class DeserializerUtil {
private static final Logger LOG = LoggerFactory.getLogger(DeserializerUtil.class);
private static final JsonDeserializerFactory JSON_DESERIALIZER_FACTORY = new JsonDeserializerFactory();
static Map createPropertyDeserializers(Class cls, ResultSetMetaData metaData,
BiFunction, Deserializer, T> deserializerFactory
) throws SQLException {
Map propertyDeserializers = new LinkedHashMap<>();
String[] columns = extractColumnLabels(metaData);
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
String propertyName = CamelSnakeConverter.snakeToCamel(column);
String[] propertyPath = propertyName.split("\\.");
Optional propertyResolver = ReflectionUtil.getPropertyResolver(cls, propertyPath);
if (propertyResolver.isPresent()) {
T propertyDeserializer = createPropertyDeserializer((PropertyResolver) propertyResolver.get(), metaData, i + 1, deserializerFactory);
propertyDeserializers.put(propertyPath, propertyDeserializer);
} else {
LOG.warn("Tried to deserialize column " + column + ", but found no matching property named " + propertyName + " in " + cls.getSimpleName());
}
}
return Collections.unmodifiableMap(propertyDeserializers);
}
private static T createPropertyDeserializer(PropertyResolver propertyResolver, ResultSetMetaData metaData,
int columnIndex, BiFunction, Deserializer, T> deserializerFactory
) throws SQLException {
Class> type = propertyResolver.getPropertyType();
int columnType = metaData.getColumnType(columnIndex);
Deserializer simpleProp = ColumnDeserializerFactory.getColumnDeserializer(type, columnType, columnIndex);
if (simpleProp == null) {
return jsonPropertyDeserializer(propertyResolver, columnIndex, deserializerFactory);
}
return deserializerFactory.apply(propertyResolver, simpleProp);
}
private static T jsonPropertyDeserializer(PropertyResolver propertyResolver,
int columnIndex,
BiFunction, Deserializer, T> deserializerFactory
) {
Type propertyGenericType = propertyResolver.getPropertyGenericType();
Function deserializer = JSON_DESERIALIZER_FACTORY.createDeserializer(propertyGenericType);
return deserializerFactory.apply(propertyResolver, (rs) -> {
String columnValue = rs.getString(columnIndex);
if (columnValue == null) {
return Optional.empty();
}
Object value = deserializer.apply(columnValue);
return Optional.ofNullable(value);
});
}
private static String[] extractColumnLabels(ResultSetMetaData metaData) throws SQLException {
String[] columnLabels = new String[metaData.getColumnCount()];
for (int i = 0; i < columnLabels.length; i++) {
columnLabels[i] = metaData.getColumnLabel(i + 1);
}
return columnLabels;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy