com.slimgears.apt.util.VisitorUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apt-utils Show documentation
Show all versions of apt-utils Show documentation
General purpose utils / module: apt-utils
/**
*
*/
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 extends B> 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 extends T, P, R>> 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