package org.jdbi.v3.core.argument;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import org.jdbi.v3.core.argument.internal.StatementBinder;
import org.jdbi.v3.core.argument.internal.strategies.LoggableBinderArgument;
import org.jdbi.v3.core.config.ConfigRegistry;
import static org.jdbi.v3.core.generic.GenericTypes.getErasedType;
abstract class DelegatingArgumentFactory implements ArgumentFactory.Preparable {
private final Map<Class<?>, Function<Object, Argument>> builders = new IdentityHashMap<>();
@Override
public Optional<Function<Object, Argument>> prepare(Type type, ConfigRegistry config) {
return Optional.ofNullable(builders.get(getErasedType(type)));
}
@Override
public Optional<Argument> build(Type expectedType, Object value, ConfigRegistry config) {
Class<?> expectedClass = getErasedType(expectedType);
if (value != null && expectedClass == Object.class) {
expectedClass = value.getClass();
}
return Optional.ofNullable(builders.get(expectedClass)).map(r -> r.apply(value));
}
@Override
public Collection<? extends Type> prePreparedTypes() {
return builders.keySet();
}
@SuppressWarnings("unchecked")
<T> void register(Class<T> klass, int sqlType, StatementBinder<T> binder) {
builders.put(klass,
value -> value == null
? new NullArgument(sqlType)
: new LoggableBinderArgument<>((T) value, binder));
}
}