@NotNull public Instantiator<?> findInstantiator(@NotNull Type type, @NotNull NamedTypeList types) { // First check if we have an immediate conversion registered. If so, we'll just use that. if (types.size() == 1) { TypeConversion conversion = findConversionFromDbValue(types.getType(0), type).orElse(null); if (conversion != null) return args -> conversion.convert(args.getSingleValue()); } Class<?> cl = rawType(type); Instantiator<?> instantiator = findExplicitInstantiatorFor(cl, types).orElse(null); if (instantiator != null) return instantiator; if (!isPublic(cl.getModifiers())) throw new InstantiationFailureException( type + " can't be instantiated reflectively because it is not public or missing a @DalesbredConstructor-annotation"); return candidateConstructorsSortedByDescendingParameterCount(cl) .map(ctor -> implicitInstantiatorFrom(ctor, types).orElse(null)) .filter(Objects::nonNull) .findFirst() .orElseThrow( () -> new InstantiationFailureException( "could not find a way to instantiate " + type + " with parameters " + types)); }
@Nullable public Object valueToDatabase(@Nullable Object value) { if (value == null) return null; TypeConversion conversion = typeConversionRegistry.findConversionToDb(value.getClass()).orElse(null); if (conversion != null) return conversion.convert(value); else if (value instanceof Enum<?>) return dialect.valueToDatabase(((Enum<?>) value).name()); else return dialect.valueToDatabase(value); }
@NotNull private static Optional<TypeConversion> findEnumConversion(@NotNull Type target) { if (isEnum(target)) { @SuppressWarnings("rawtypes") Class<? extends Enum> cl = rawType(target).asSubclass(Enum.class); return Optional.ofNullable( TypeConversion.fromNonNullFunction(value -> Enum.valueOf(cl, value.toString()))); } return Optional.empty(); }
/** * Returns conversion for converting value of source to target, or returns null if there's no such * conversion. */ @NotNull private Optional<TypeConversion> findConversionFromDbValue( @NotNull Type source, @NotNull Type target) { if (isAssignable(target, source)) return Optional.of(TypeConversion.identity()); Optional<TypeConversion> directConversion = typeConversionRegistry.findConversionFromDbValue(source, target); if (directConversion.isPresent()) return directConversion; Optional<TypeConversion> arrayConversion = findArrayConversion(source, target); if (arrayConversion.isPresent()) return arrayConversion; Optional<TypeConversion> optionalConversion = findOptionalConversion(source, target); if (optionalConversion.isPresent()) return optionalConversion; Optional<TypeConversion> enumConversion = findEnumConversion(target); if (enumConversion.isPresent()) return enumConversion; return Optional.empty(); }