/** * Return a ConstructorMapper for the given type and prefix. * * @param <T> the type to map * @param type the mapped type * @param prefix the column name prefix * @return the mapper */ public static <T> RowMapper<T> of(Class<T> type, String prefix) { return new ConstructorMapper<>(findFactoryFor(type), prefix); }
/** * Find an invokable constructor. Prefer an {@link JdbiConstructor} annotated * one if present. Throws if multiple or zero candidates are found. * * @param <T> the type to inspect * @param type the type to inspect * @return the preferred constructor */ public static <T> Constructor<T> findConstructorFor(Class<T> type) { @SuppressWarnings("unchecked") final Constructor<T>[] constructors = (Constructor<T>[]) type.getDeclaredConstructors(); List<Constructor<T>> annotatedConstructors = Stream.of(constructors) .filter(c -> c.isAnnotationPresent(JdbiConstructor.class)) .collect(Collectors.toList()); if (annotatedConstructors.size() > 1) { throw new IllegalArgumentException(type + " may have at most one constructor annotated @JdbiConstructor"); } else if (annotatedConstructors.size() == 1) { return annotatedConstructors.get(0); } return findImplicitConstructorFor(type); }
/** * Return a ConstructorMapper for the given type. * * @param <T> the type to map * @param type the mapped type * @return the mapper */ public static <T> RowMapper<T> of(Class<T> type) { return ConstructorMapper.of(findConstructorFor(type)); }
/** * Return a ConstructorMapper for the given type and prefix. * * @param <T> the type to map * @param type the mapped type * @param prefix the column name prefix * @return the mapper */ public static <T> RowMapper<T> of(Class<T> type, String prefix) { return ConstructorMapper.of(findConstructorFor(type), prefix); }
new ConstructorMapper<>(findFactoryFor(p.getType()), nestedPrefix)) .specialize0(ctx, columnNames, columnNameMatchers, unmatchedColumns);
/** * Find an invokable instance factory, such as a constructor or a static factory method. * Prefer an {@link JdbiConstructor} annotated constructor or static factory method if * one is present. Throws if multiple or zero candidates are found. * * @param <T> the type to inspect * @param type the type to inspect * @return the preferred constructor or static factory method */ static <T> InstanceFactory<T> findFactoryFor(Class<T> type) { @SuppressWarnings("unchecked") final Constructor<T>[] constructors = (Constructor<T>[]) type.getDeclaredConstructors(); List<Constructor<T>> explicitConstructors = Stream.of(constructors) .filter(constructor -> constructor.isAnnotationPresent(JdbiConstructor.class)) .collect(Collectors.toList()); List<Method> explicitFactoryMethods = Stream.of(type.getDeclaredMethods()) .filter(method -> method.isAnnotationPresent(JdbiConstructor.class)) .collect(Collectors.toList()); if (explicitConstructors.size() + explicitFactoryMethods.size() > 1) { throw new IllegalArgumentException(type + " may have at most one constructor or static factory method annotated @JdbiConstructor"); } if (explicitConstructors.size() == 1) { return new ConstructorInstanceFactory<>(explicitConstructors.get(0)); } if (explicitFactoryMethods.size() == 1) { return new StaticMethodInstanceFactory<>(type, explicitFactoryMethods.get(0)); } return new ConstructorInstanceFactory<>(findImplicitConstructorFor(type)); }