/** * Returns an instantiator that uses given constructor and given types to create instances, or * empty if there are no conversions that can be made to instantiate the type. */ @NotNull private <T> Optional<Instantiator<T>> implicitInstantiatorFrom( @NotNull Constructor<T> constructor, @NotNull NamedTypeList types) { if (!isPublic(constructor.getModifiers())) return Optional.empty(); List<String> columnNames = types.getNames(); return findTargetTypes(constructor, columnNames) .flatMap( targetTypes -> resolveConversions(types, targetTypes) .map( conversions -> new ReflectionInstantiator<>( constructor, conversions, createPropertyAccessorsForValuesNotCoveredByConstructor( constructor, columnNames)))); }
@NotNull private Optional<Instantiator<?>> findExplicitInstantiatorFor( Class<?> cl, @NotNull NamedTypeList types) throws InstantiationFailureException { Constructor<?> constructor = dalesbredConstructor(cl).orElse(null); if (constructor == null) return Optional.empty(); try { ReflectionUtils.makeAccessible(constructor); } catch (SecurityException e) { throw new InstantiationFailureException( "Cannot instantiate " + constructor.getDeclaringClass().getName() + " using non-public constructor due to Security exception", e); } List<String> columnNames = types.getNames(); List<Type> constructorParameterTypes = asList(constructor.getGenericParameterTypes()); if (constructorParameterTypes.size() != columnNames.size()) throw new InstantiationFailureException( String.format( "Cannot instantiate %s, constructor takes %d arguments, but result set has %d", constructor.getDeclaringClass().getName(), constructorParameterTypes.size(), columnNames.size())); ReflectionInstantiator<?> instantiator = resolveConversions(types, constructorParameterTypes) .map( conversions -> new ReflectionInstantiator<>(constructor, conversions, Collections.emptyList())) .orElseThrow( () -> new InstantiationFailureException( "could not find a way to instantiate " + constructor.getDeclaringClass().getName() + " with parameters " + types)); return Optional.of(instantiator); }