package org.jdbi.v3.core.argument;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jdbi.v3.core.argument.internal.ObjectPropertyNamedArgumentFinder;
import org.jdbi.v3.core.argument.internal.TypedValue;
import org.jdbi.v3.core.config.JdbiCache;
import org.jdbi.v3.core.config.JdbiCaches;
import org.jdbi.v3.core.qualifier.QualifiedType;
import org.jdbi.v3.core.qualifier.Qualifiers;
import org.jdbi.v3.core.statement.StatementContext;
import org.jdbi.v3.core.statement.UnableToCreateStatementException;
public class ObjectFieldArguments extends ObjectPropertyNamedArgumentFinder {
private static final JdbiCache<Class<?>, Map<String, Field>> FIELD_CACHE =
JdbiCaches.declare(beanClass ->
Stream.of(beanClass.getFields())
.collect(Collectors.toMap(Field::getName, Function.identity())));
private final Class<?> beanClass;
public ObjectFieldArguments(String prefix, Object bean) {
super(prefix, bean);
this.beanClass = bean.getClass();
}
@Override
protected Optional<TypedValue> getValue(String name, StatementContext ctx) {
Field field = FIELD_CACHE.get(beanClass, ctx).get(name);
if (field == null) {
return Optional.empty();
}
try {
QualifiedType<?> type = QualifiedType.of(field.getGenericType())
.withAnnotations(ctx.getConfig(Qualifiers.class).findFor(field));
Object value = field.get(obj);
return Optional.of(new TypedValue(type, value));
} catch (IllegalAccessException e) {
throw new UnableToCreateStatementException(String.format("Access exception getting field for "
+ "bean property [%s] on [%s]",
name, obj), e, ctx);
}
}
@Override
protected NamedArgumentFinder getNestedArgumentFinder(Object obj) {
return new ObjectFieldArguments(null, obj);
}
@Override
public String toString() {
return "{lazy bean field arguments \"" + obj + "\"";
}
}