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

dev.gradleplugins.runnerkit.providers.AbstractGradleExecutionProvider Maven / Gradle / Ivy

There is a newer version: 0.0.148
Show newest version
package dev.gradleplugins.runnerkit.providers;

import dev.gradleplugins.runnerkit.GradleExecutionContext;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

@ToString
@EqualsAndHashCode
abstract class AbstractGradleExecutionProvider implements GradleExecutionProviderInternal {
    private static final ThreadLocal> NEXT_PARAMETER = new ThreadLocal<>();
    private final GradleExecutionProvider value;

    @SuppressWarnings("unchecked")
    protected AbstractGradleExecutionProvider() {
        this.value = (GradleExecutionProvider) NEXT_PARAMETER.get();
        NEXT_PARAMETER.remove();
    }

    public T get() {
        return value.get();
    }

    public T orElse(T other) {
        return value.orElse(other);
    }

    public T orElseGet(Supplier supplier) {
        return value.orElseGet(supplier);
    }

    public boolean isPresent() {
        return value.isPresent();
    }

    public  Optional map(Function mapper) {
        return value.map(mapper);
    }

    public void calculateValue(GradleExecutionContext context) {
        if (value instanceof CalculatedValueProvider) {
            ((CalculatedValueProvider) value).calculateValue(context);
        }
    }

    protected static > T noValue(Class type) {
        NEXT_PARAMETER.set(new NoValueProvider<>(type));
        try {
            return type.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e); // TODO:
        }
    }

    protected static , S> T fixed(Class type, S value) {
        NEXT_PARAMETER.set(new FixedValueProvider(value));
        try {
            return type.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e); // TODO:
        }
    }

    protected static , S> T supplied(Class type, Supplier value) {
        NEXT_PARAMETER.set(new SuppliedValueProvider(value));
        try {
            return type.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e); // TODO:
        }
    }

    protected static , S> T calculated(Class type, Function value) {
        NEXT_PARAMETER.set(new CalculatedValueProvider<>(value));
        try {
            return type.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e); // TODO:
        }
    }

    @EqualsAndHashCode
    private static final class NoValueProvider implements GradleExecutionProvider {
        @EqualsAndHashCode.Exclude private final Class type;

        public NoValueProvider(Class type) {
            this.type = type;
        }

        @Override
        public T get() {
            throw new UnsupportedOperationException(String.format("Cannot get value for '%s'.", type.getSimpleName()));
        }

        @Override
        public T orElse(T other) {
            return other;
        }

        @Override
        public T orElseGet(Supplier supplier) {
            return supplier.get();
        }

        @Override
        public boolean isPresent() {
            return false;
        }

        @Override
        public  Optional map(Function mapper) {
            return Optional.empty();
        }

        @Override
        public String toString() {
            return "no value";
        }
    }

    @EqualsAndHashCode
    private static class FixedValueProvider implements GradleExecutionProvider {
        private final T value;

        FixedValueProvider(T value) {
            this.value = value;
        }

        @Override
        public T get() {
            return value;
        }

        @Override
        public T orElse(T other) {
            return value;
        }

        @Override
        public T orElseGet(Supplier supplier) {
            return value;
        }

        @Override
        public boolean isPresent() {
            return true;
        }

        @Override
        public  Optional map(Function mapper) {
            return Optional.of(value).map(mapper);
        }

        @Override
        public String toString() {
            return "fixed(" + value + ")";
        }
    }

    @EqualsAndHashCode
    private static class SuppliedValueProvider implements GradleExecutionProvider {
        private final Supplier value;

        SuppliedValueProvider(Supplier value) {
            this.value = value;
        }

        @Override
        public T get() {
            return value.get();
        }

        @Override
        public T orElse(T other) {
            return value.get();
        }

        @Override
        public T orElseGet(Supplier supplier) {
            return value.get();
        }

        @Override
        public boolean isPresent() {
            return true;
        }

        @Override
        public  Optional map(Function mapper) {
            return Optional.of(value.get()).map(mapper);
        }

        @Override
        public String toString() {
            return "supplied(" + value + ")";
        }
    }

    @EqualsAndHashCode
    private static class CalculatedValueProvider implements GradleExecutionProvider {
        private final Function generator;
        private T value;

        CalculatedValueProvider(Function generator) {
            this.generator = generator;
        }

        @Override
        public T get() {
            assertValueCalculated();
            return value;
        }

        @Override
        public T orElse(T other) {
            assertValueCalculated();
            return value;
        }

        @Override
        public T orElseGet(Supplier supplier) {
            assertValueCalculated();
            return value;
        }

        @Override
        public boolean isPresent() {
            return true;
        }

        @Override
        public  Optional map(Function mapper) {
            assertValueCalculated();
            return Optional.of(value).map(mapper);
        }

        private void assertValueCalculated() {
            if (value == null) {
                throw new RuntimeException("value not calculated");
            }
        }

        public void calculateValue(GradleExecutionContext context) {
            value = generator.apply(context);
        }

        @Override
        public String toString() {
            return "calculated(" + value + ")";
        }
    }
}