public Type getType() { return qualifiedType.getType(); }
/** * Creates a {@code QualifiedType<T>} for a {@code Class<T>} with no qualifiers. * @param clazz the unqualified type * @return the unqualified QualifiedType * @see #with(Annotation...) to then qualify your type */ public static <T> QualifiedType<T> of(Class<T> clazz) { return new QualifiedType<>(clazz, emptySet()); }
private UnsupportedOperationException factoryNotFound(QualifiedType<?> qualifiedType, Object value) { Type type = qualifiedType.getType(); if (type instanceof Class<?>) { // not a ParameterizedType final TypeVariable<?>[] params = ((Class<?>) type).getTypeParameters(); if (params.length > 0) { return new UnsupportedOperationException("No type parameters found for erased type '" + type + Arrays.toString(params) + "' with qualifiers '" + qualifiedType.getQualifiers() + "'. To bind a generic type, prefer using bindByType."); } } return new UnsupportedOperationException("No argument factory registered for '" + value + "' of qualified type " + qualifiedType); }
private static <T> Optional<EnumStrategy> doFindStrategy(QualifiedType<T> type) { boolean hasByName = type.hasQualifier(EnumByName.class); boolean hasByOrdinal = type.hasQualifier(EnumByOrdinal.class); if (hasByName && hasByOrdinal) { throw new IllegalArgumentException(String.format( "%s is both %s and %s", type.getType(), EnumByName.class.getSimpleName(), EnumByOrdinal.class.getSimpleName() )); } if (hasByName) { return Optional.of(EnumStrategy.BY_NAME); } else if (hasByOrdinal) { return Optional.of(EnumStrategy.BY_ORDINAL); } else { return Optional.empty(); } }
/** * Obtain a column mapper for the given type. * * @param type the target type to map to * @return a ColumnMapper for the given type, or empty if no column mapper is registered for the given type. */ public Optional<ColumnMapper<?>> findFor(Type type) { return findFor(QualifiedType.of(type)).map(m -> (ColumnMapper<?>) m); }
/** * 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()); }
/** * Returns a QualifiedType that has the same type as this instance, but with the given qualifiers. * * @param qualifiers the qualifiers for the new qualified type. * @return the QualifiedType */ public QualifiedType<T> with(Annotation... qualifiers) { return with(Arrays.asList(qualifiers)); }
@Override public Optional<ColumnMapper<?>> build(QualifiedType<?> type, ConfigRegistry config) { return maps.equals(type) ? Optional.of(mapper) : Optional.empty(); } }
/** * Creates a {@code QualifiedType<T>} for a {@code GenericType<T>} with no qualifiers. * @param type the unqualified type * @return the unqualified QualifiedType * @see #with(Annotation...) to then qualify your type */ @SuppressWarnings("unchecked") public static <T> QualifiedType<T> of(GenericType<T> type) { return (QualifiedType<T>) of(type.getType()); }
/** * Returns a QualifiedType that has the same type as this instance, but with the given qualifiers. * * @param qualifiers the qualifiers for the new qualified type. * @throws IllegalArgumentException if any of the given qualifier types have annotation attributes. * @return the QualifiedType */ @SafeVarargs public final QualifiedType<T> with(Class<? extends Annotation>... qualifiers) { return with(Arrays.stream(qualifiers).map(AnnotationFactory::create).collect(toList())); }
/** * Adapts a {@link ColumnMapperFactory} into a QualifiedColumnMapperFactory. The returned * factory only matches qualified types with zero qualifiers. * * @param factory the factory to adapt */ static QualifiedColumnMapperFactory adapt(ColumnMapperFactory factory) { Set<Annotation> qualifiers = getQualifiers(factory.getClass()); return (type, config) -> type.getQualifiers().equals(qualifiers) ? factory.build(type.getType(), config) : Optional.empty(); }
/** * Create a QualifiedColumnMapperFactory from a given {@link ColumnMapper} that matches * a single {@link QualifiedType} exactly. * * @param type the mapped type * @param mapper the mapper * @param <T> the mapped type * @return */ static <T> QualifiedColumnMapperFactory of(QualifiedType<T> type, ColumnMapper<T> mapper) { return (t, config) -> t.equals(type) ? Optional.of(mapper) : Optional.empty(); } }
ConsumerResultReturner(Method method, int consumerIndex) { this.consumerIndex = consumerIndex; Type parameterType = method.getGenericParameterTypes()[consumerIndex]; this.elementType = QualifiedType.of( GenericTypes.findGenericParameter(parameterType, Consumer.class) .orElseThrow(() -> new IllegalStateException( "Cannot reflect Consumer<T> element type T in method consumer parameter " + parameterType))) .with(getQualifiers(method.getParameters()[consumerIndex])); }
/** * Obtain an argument for given value in the given context * * @param type the type of the argument. * @param value the argument value. * @return an Argument for the given value. */ public Optional<Argument> findFor(Type type, Object value) { return findFor(QualifiedType.of(type), value); }
@Override public Optional<ColumnMapper<?>> build(QualifiedType<?> givenType, ConfigRegistry config) { return Optional.of(givenType.getType()) .map(GenericTypes::getErasedType) .filter(Class::isEnum) .flatMap(clazz -> makeEnumArgument((QualifiedType<Enum>) givenType, (Class<Enum>) clazz, config)); }
/** * Adapts an {@link ArgumentFactory} into a QualifiedArgumentFactory. The returned factory only * matches qualified types with zero qualifiers. * * @param factory the factory to adapt */ static QualifiedArgumentFactory adapt(ArgumentFactory factory) { Set<Annotation> qualifiers = getQualifiers(factory.getClass()); return (type, value, config) -> type.getQualifiers().equals(qualifiers) ? factory.build(type.getType(), value, config) : Optional.empty(); } }
/** * Creates a wildcard {@code QualifiedType<?>} for a {@link Type} with no qualifiers. * @param type the unqualified type * @return the unqualified QualifiedType * @see #with(Annotation...) to then qualify your type */ public static QualifiedType<?> of(Type type) { return new QualifiedType<>(type, emptySet()); }
JpaMember(Class<?> clazz, Column column, Field field) { this.clazz = requireNonNull(clazz); this.columnName = nameOf(column, field.getName()); this.qualifiedType = QualifiedType.of(field.getGenericType()).with(getQualifiers(field)); field.setAccessible(true); this.accessor = field::get; this.mutator = field::set; }
/** * Maps this result set to a {@link ResultIterable} of the given element type. * * @param type the type to map the result set rows to * @return a {@link ResultIterable} of the given type. * @see Configurable#registerRowMapper(RowMapper) * @see Configurable#registerRowMapper(org.jdbi.v3.core.mapper.RowMapperFactory) * @see Configurable#registerColumnMapper(org.jdbi.v3.core.mapper.ColumnMapperFactory) * @see Configurable#registerColumnMapper(ColumnMapper) */ default ResultIterable<?> mapTo(Type type) { return mapTo(QualifiedType.of(type)); }