package org.jdbi.v3.json.internal;
import java.lang.reflect.Type;
import java.util.Optional;
import org.jdbi.v3.core.config.ConfigRegistry;
import org.jdbi.v3.core.internal.JdbiOptionals;
import org.jdbi.v3.core.mapper.ColumnMapper;
import org.jdbi.v3.core.mapper.ColumnMapperFactory;
import org.jdbi.v3.core.mapper.ColumnMappers;
import org.jdbi.v3.core.qualifier.QualifiedType;
import org.jdbi.v3.core.result.UnableToProduceResultException;
import org.jdbi.v3.json.Json;
import org.jdbi.v3.json.JsonConfig;
import org.jdbi.v3.json.JsonMapper;
@Json
public class JsonColumnMapperFactory implements ColumnMapperFactory {
private static final String JSON_NOT_RETRIEVABLE = String.format(
"No column mapper found for '@%s String', or 'String'",
Json.class.getSimpleName()
);
@Override
public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) {
if (String.class.equals(type)) {
return Optional.empty();
}
ColumnMappers cm = config.get(ColumnMappers.class);
ColumnMapper<String> jsonStringMapper = JdbiOptionals.findFirstPresent(
() -> cm.findFor(QualifiedType.of(String.class).with(Json.class)),
() -> cm.findFor(String.class))
.orElseThrow(() -> new UnableToProduceResultException(JSON_NOT_RETRIEVABLE));
final JsonMapper mapper = config.get(JsonConfig.class).getJsonMapper();
return Optional.of((rs, i, ctx) ->
mapper.fromJson(
type,
Optional.ofNullable(jsonStringMapper.map(rs, i, ctx))
.orElse("null"),
config));
}
}