private static <E extends Enum<E>> E getValueByName(Class<E> enumClass, String name, StatementContext ctx) { return JdbiOptionals.findFirstPresent( () -> Arrays.stream(enumClass.getEnumConstants()).filter(e -> e.name().equals(name)).findFirst(), () -> Arrays.stream(enumClass.getEnumConstants()).filter(e -> e.name().equalsIgnoreCase(name)).findFirst() ) .orElseThrow(() -> new UnableToProduceResultException( String.format("no %s value could be matched to the name %s", enumClass.getSimpleName(), name), ctx)); } }
return JdbiOptionals.findFirstPresent( () -> Optional.ofNullable(method.getAnnotation(SqlBatch.class)) .map(SqlBatch::value)
/** * Register bean arguments and row mapping for an {@code Immutable*} value class, expecting the default generated class and builder names. * @param spec the specification interface or abstract class * @param <S> the specification class * @return a plugin that configures type mapping for the given class */ public <S> JdbiImmutables registerImmutable(Class<S> spec) { final Class<? extends S> impl = classByPrefix("Immutable", spec); return registerImmutable(spec, impl, JdbiOptionals.findFirstPresent( () -> nullaryMethodOf(spec, "builder"), () -> nullaryMethodOf(impl, "builder")) .orElseThrow(() -> new IllegalArgumentException("Neither " + spec + " nor " + impl + " have a 'builder' method"))); }
@Override public Optional<Argument> build(Type type, Object value, ConfigRegistry config) { if (String.class.equals(type)) { return Optional.empty(); } String json = value == null ? null : config.get(JsonConfig.class).getJsonMapper().toJson(type, value, config); Arguments a = config.get(Arguments.class); // look for specialized json support first, revert to simple String binding if absent return Optional.of(JdbiOptionals.findFirstPresent( () -> a.findFor(QualifiedType.of(String.class).with(Json.class), json), () -> a.findFor(String.class, json)) .orElseThrow(() -> new UnableToCreateStatementException(JSON_NOT_STORABLE))); } }
@Override public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) { if (String.class.equals(type)) { return Optional.empty(); } ColumnMappers cm = config.get(ColumnMappers.class); // look for specialized json support first, revert to simple String mapping if absent 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) -> { String json = jsonStringMapper.map(rs, i, ctx); return json == null ? null : mapper.fromJson(type, json, config); }); } }
/** * Determines which strategy is to be used for a given {@link QualifiedType}, falling back to * reading strategy annotations on the source class and/or using the configured default. * * @param <E> the {@link Enum} type * @param type qualified type to derive a strategy from * @return the strategy by which this enum should be handled */ public <E extends Enum<E>> EnumStrategy findStrategy(QualifiedType<E> type) { Class<?> erasedType = getErasedType(type.getType()); return JdbiOptionals.findFirstPresent( () -> doFindStrategy(type), () -> doFindStrategy(QualifiedType.of(erasedType).with(getQualifiers(erasedType))) ).orElseGet(() -> registry.get(Enums.class).getDefaultStrategy()); }
/** * Obtain a row mapper for the given type in the given context. * * @param type the target type to map to * @return a RowMapper for the given type, or empty if no row mapper is registered for the given type. */ public Optional<RowMapper<?>> findFor(Type type) { // ConcurrentHashMap can enter an infinite loop on nested computeIfAbsent calls. // Since row mappers can decorate other row mappers, we have to populate the cache the old fashioned way. // See https://bugs.openjdk.java.net/browse/JDK-8062841, https://bugs.openjdk.java.net/browse/JDK-8142175 RowMapper<?> cached = cache.get(type); if (cached != null) { return Optional.of(cached); } Optional<RowMapper<?>> mapper = findFirstPresent( () -> factories.stream() .flatMap(factory -> toStream(factory.build(type, registry))) .findFirst(), () -> registry.get(ColumnMappers.class).findFor(type) .map(SingleColumnMapper::new)); mapper.ifPresent(m -> cache.put(type, m)); return mapper; }
@Override public Optional<Argument> build(Type type, Object value, ConfigRegistry config) { if (String.class.equals(type)) { return Optional.empty(); } return Optional.of((pos, stmt, ctx) -> { String json = value == null ? null : ctx.getConfig(JsonConfig.class).getJsonMapper().toJson(type, value, ctx); // look for specialized json support first, revert to simple String binding if absent Argument stringBinder = JdbiOptionals.findFirstPresent( () -> ctx.findArgumentFor(QualifiedType.of(String.class).with(Json.class), json), () -> ctx.findArgumentFor(String.class, json)) .orElseThrow(() -> new UnableToCreateStatementException(JSON_NOT_STORABLE)); stringBinder.apply(pos, stmt, ctx); }); } }
@Override public Optional<ColumnMapper<?>> build(Type type, ConfigRegistry config) { if (String.class.equals(type)) { return Optional.empty(); } return Optional.of((rs, i, ctx) -> { // look for specialized json support first, revert to simple String mapping if absent ColumnMapper<String> jsonStringMapper = JdbiOptionals.findFirstPresent( () -> ctx.findColumnMapperFor(QualifiedType.of(String.class).with(Json.class)), () -> ctx.findColumnMapperFor(String.class)) .orElseThrow(() -> new UnableToProduceResultException(JSON_NOT_RETRIEVABLE, ctx)); String json = jsonStringMapper.map(rs, i, ctx); return json == null ? null : ctx.getConfig(JsonConfig.class).getJsonMapper().fromJson(type, json, ctx); }); } }