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

com.fluxtion.runtime.dataflow.helpers.Predicates Maven / Gradle / Ivy

package com.fluxtion.runtime.dataflow.helpers;

import com.fluxtion.runtime.annotations.Initialise;
import com.fluxtion.runtime.annotations.OnParentUpdate;
import com.fluxtion.runtime.annotations.OnTrigger;
import com.fluxtion.runtime.annotations.builder.AssignToField;
import com.fluxtion.runtime.dataflow.Stateful;
import com.fluxtion.runtime.partition.LambdaReflection;
import lombok.Value;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.fluxtion.runtime.partition.LambdaReflection.*;

public interface Predicates {

    static boolean greaterThanInt(int a, int b) {
        return a > b;
    }

    static boolean greaterThanDouble(double a, double b) {
        return a > b;
    }

    static boolean greaterThanLong(long a, long b) {
        return a > b;
    }

    static boolean alwaysTrue() {
        return true;
    }

    static boolean alwaysFalse() {
        return true;
    }

    static boolean isInteger(String in) {
        try {
            Integer.parseInt(in);
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    static boolean isDouble(String in) {
        try {
            Double.parseDouble(in);
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    static boolean isLong(String in) {
        try {
            Long.parseLong(in);
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    static  LambdaReflection.SerializableFunction hasChangedFilter() {
        return new HasChanged()::objChanged;
    }

    static  SerializableFunction, Boolean> hasMapChanged() {
        return new MapHasChanged()::checkMapChanged;
    }

    static SerializableIntFunction hasIntChanged() {
        return new HasChanged()::intChanged;
    }

    static SerializableDoubleFunction hasDoubleChanged() {
        return new HasChanged()::doubleChanged;
    }

    static SerializableLongFunction hasLongChanged() {
        return new HasChanged()::longChanged;
    }

    static SerializableIntFunction gt(int limit) {
        return new GreaterThan(limit, Double.NaN)::check;
    }

    static SerializableFunction greaterThanBoxed(Integer limit) {
        return new GreaterThan(limit, Double.NaN)::checkBoxedInteger;
    }

    static SerializableFunction greaterThanBoxed(Long limit) {
        return new GreaterThan(limit, Double.NaN)::checkBoxedLong;
    }

    static SerializableLongFunction gt(long limit) {
        return new GreaterThan(limit, Double.NaN)::check;
    }

    static SerializableDoubleFunction gt(double limit) {
        return new GreaterThan(Long.MAX_VALUE, limit)::check;
    }


    static SerializableIntFunction lt(int limit) {
        return new LessThan(limit, Double.NaN)::check;
    }

    static SerializableLongFunction lt(long limit) {
        return new LessThan(limit, Double.NaN)::check;
    }

    static SerializableDoubleFunction lt(double limit) {
        return new LessThan(Long.MAX_VALUE, limit)::check;
    }

    class HasChanged {
        long longPrevious;
        double doublePrevious;
        int previousInt;
        Object previousObject;

        public boolean intChanged(int newValue) {
            boolean changed = newValue != previousInt;
            previousInt = newValue;
            return changed;
        }

        public boolean longChanged(long newValue) {
            boolean changed = newValue != longPrevious;
            longPrevious = newValue;
            return changed;
        }


        public boolean doubleChanged(double newValue) {
            if (Double.isNaN(newValue) && Double.isNaN(doublePrevious)) {
                return false;
            }
            boolean changed = newValue != doublePrevious;
            doublePrevious = newValue;
            return changed;
        }

        public  boolean objChanged(T newValue) {
            boolean changed = !newValue.equals(previousObject);
            previousObject = newValue;
            return changed;
        }
    }

    class MapHasChanged {
        private final Map oldMap = new HashMap<>();

        public  Boolean checkMapChanged(Map map) {
            boolean changed = !map.equals(oldMap);
            oldMap.clear();
            oldMap.putAll(map);
            return changed;
        }
    }

    @Value
    class GreaterThan {
        long limit;
        double doubleLimit;

        public boolean check(int input) {
            return input > limit;
        }

        public boolean check(double input) {
            return input > doubleLimit;
        }

        public boolean check(long input) {
            return input > limit;
        }

        public boolean checkBoxedInteger(Integer input) {
            return check(input);
        }

        public boolean checkBoxedLong(Long input) {
            return check(input);
        }
    }

    @Value
    class LessThan {
        long limit;
        double doubleLimit;

        public boolean check(int input) {
            return input < limit;
        }

        public boolean check(double input) {
            return input < doubleLimit;
        }

        public boolean check(long input) {
            return input < limit;
        }
    }

    class AllUpdatedPredicate extends Stateful.StatefulWrapper {

        private final List monitored = new ArrayList<>();
        private final transient Map updateMap = new HashMap<>();
        private boolean allUpdated;

        public AllUpdatedPredicate(
                @AssignToField("monitored") List monitored,
                @AssignToField("resetTrigger") Object resetKey) {
            super(resetKey);
            this.monitored.addAll(monitored);
        }

        public AllUpdatedPredicate(List monitored) {
            this(monitored, null);
        }

        @OnParentUpdate("monitored")
        public void parentUpdated(Object parent) {
            if (!allUpdated) {
                updateMap.put(parent, true);
                allUpdated = updateMap.values().stream().allMatch(v -> v);
            }
        }

        @OnTrigger
        public boolean propagateEvent() {
            return allUpdated;
        }

        @Initialise
        public void init() {
            allUpdated = false;
            updateMap.clear();
            monitored.forEach(p -> updateMap.put(p, false));
        }

        @Override
        public void reset() {
            init();
        }
    }

    class AnyUpdatedPredicate {

        private final List monitored = new ArrayList<>();

        public AnyUpdatedPredicate(@AssignToField("monitored") List monitored) {
            this.monitored.addAll(monitored);
        }

        @OnTrigger
        public boolean propagateEvent() {
            return true;
        }
    }

    @Value
    class PredicateWrapper {
        SerializableSupplier predicate;

        public boolean test(Object o) {
            return predicate.get();
        }
    }
}