All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.team33.patterns.arbitrary.mimas.Supplying Maven / Gradle / Ivy

Go to download

Provides classes that support the generation of arbitrary values of virtually any type.

The newest version!
package de.team33.patterns.arbitrary.mimas;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

@SuppressWarnings("PackageVisibleField")
class Supplying {

    private static final Map, List> SUPPLIERS = new ConcurrentHashMap<>(0);
    private static final String METHOD_NOT_APPLICABLE = Util.load(Supplying.class, "supplierMethodNotApplicable.txt");

    final S source;
    final Class sourceType;
    final Set ignorable;
    final Predicate desired;

    private final List suppliers;

    Supplying(final S source, final Collection ignore) {
        this.source = source;
        this.sourceType = source.getClass();
        this.suppliers = SUPPLIERS.computeIfAbsent(sourceType, Supplying::suppliers);
        this.ignorable = new HashSet<>(ignore);
        this.desired = nameFilter(ignorable).negate();
    }

    private static Predicate nameFilter(final Set names) {
        return method -> names.contains(method.getName());
    }

    private static List suppliers(final Class sourceType) {
        return Methods.publicGetters(sourceType)
                      .collect(Collectors.toList());
    }

    private Supplier supplier(final Method method) {
        return () -> {
            try {
                return method.invoke(source);
            } catch (final IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
                throw new UnfitConditionException(String.format(METHOD_NOT_APPLICABLE,
                                                                sourceType,
                                                                method.toGenericString(),
                                                                method.getName()), e);
            }
        };
    }

    final Supplier desiredSupplier(final Type resultType, final BinaryOperator preference) {
        return suppliers.stream()
                        .filter(supplier -> Types.isMatching(resultType, supplier.getGenericReturnType()))
                        .filter(desired)
                        .reduce(preference)
                        .map(this::supplier)
                        .orElse(null);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy