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

com.slimgears.apt.util.VisitorUtils Maven / Gradle / Ivy

There is a newer version: 0.7.58
Show newest version
/**
 *
 */
package com.slimgears.apt.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class VisitorUtils {
    public static > List findAllOf(Class cls, T element, Supplier builderSupplier) {
        List elements = new ArrayList<>();
        //noinspection unchecked
        builderSupplier.get()
                .onAny((T el) -> {
                    if (cls.isInstance(el)) {
                        elements.add(cls.cast(el));
                    }
                })
                .visit(element, null);
        return elements;
    }

    public static  BiFunction doNothing() {
        return (e, p) -> null;
    }

    public static  BinaryOperator takeFirstNonNull() {
        return (a, b) -> Optional.ofNullable(a).orElse(b);
    }

    public static  BinaryOperator takeLastNonNull() {
        return (a, b) -> Optional.ofNullable(b).orElse(a);
    }

    public static  BinaryOperator takeFirst() {
        return (a, b) -> a;
    }

    public static  BinaryOperator takeFirstOrDefault(T defaultVal) {
        return (a, b) -> Optional.ofNullable(a).orElse(defaultVal);
    }

    public static  BinaryOperator takeLast() {
        return (a, b) -> b;
    }

    public static  BinaryOperator takeLastOrDefault(T defaultVal) {
        return (a, b) -> Optional.ofNullable(b).orElse(defaultVal);
    }

    static abstract class AbstractBuilder> {
        private final BinaryOperator resultCombiner;
        protected BiPredicate filter = (e, p) -> true;
        protected BiFunction onAny = doNothing();
        protected Map, BiFunction> listeners = new HashMap<>();

        protected AbstractBuilder(BinaryOperator resultCombiner) {
            this.resultCombiner = resultCombiner;
        }

        protected abstract B self();

        public B filter(BiPredicate predicate) {
            this.filter = this.filter.and(predicate);
            return self();
        }

        @SuppressWarnings("unchecked")
        public  B on(Class elementClass, BiFunction listener) {
            BiFunction newListener = Optional
                    .ofNullable(listeners.get(elementClass))
                    .map(l -> combine((BiFunction) l, listener))
                    .orElse(listener);
            listeners.put(elementClass, newListener);
            return self();
        }

        public  B on(Class elementClass, Function consumer) {
            return on(elementClass, ignoreParam(consumer));
        }

        public  B on(Class elementClass, Consumer consumer) {
            return on(elementClass, ignoreParam(consumer));
        }

        public B onAny(BiFunction consumer) {
            this.onAny = combine(this.onAny, consumer);
            return self();
        }

        public B onAny(Function consumer) {
            return onAny(ignoreParam(consumer));
        }

        public B onAny(Consumer consumer) {
            return onAny(ignoreParam(consumer));
        }

        protected  BiFunction combine(BiFunction a, BiFunction b) {
            return (e, p) -> resultCombiner.apply(a.apply(e, p), b.apply(e, p));
        }

        protected   BiFunction ignoreParam(Function func) {
            return (e, p) -> func.apply(e);
        }

        protected   BiFunction ignoreParam(Consumer consumer) {
            return ignoreParam(e -> {
                consumer.accept(e);
                return null;
            });
        }

        @SafeVarargs
        protected final R aggregate(R... results) {
            return Stream.of(results)
                    .filter(Objects::nonNull)
                    .reduce(resultCombiner)
                    .orElse(null);
        }

        protected final R aggregate(R first, Stream others) {
            return Stream.concat(Stream.of(first), others)
                    .filter(Objects::nonNull)
                    .reduce(resultCombiner)
                    .orElse(null);
        }

        @SuppressWarnings("unchecked")
        protected  BiFunction listenerOf(Class cls) {
            return Optional
                    .ofNullable(listeners.get(cls))
                    .map(l -> (BiFunction)l)
                    .orElseGet(VisitorUtils::doNothing);
        }

        public abstract V build();
        protected abstract R accept(T element, V visitor, P param);

        public void visit(T element, P param) {
            accept(element, build(), param);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy