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

org.rx.core.Extends Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package org.rx.core;

import lombok.NonNull;
import lombok.SneakyThrows;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.rx.annotation.ErrorCode;
import org.rx.annotation.Metadata;
import org.rx.exception.ApplicationException;
import org.rx.exception.InvalidException;
import org.rx.exception.TraceHandler;
import org.rx.util.function.Action;
import org.rx.util.function.BiAction;
import org.rx.util.function.BiFunc;
import org.rx.util.function.Func;

import java.io.Serializable;
import java.lang.reflect.AnnotatedElement;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;

@SuppressWarnings(Constants.NON_UNCHECKED)
public interface Extends extends Serializable {
    //region extend
    static  List newConcurrentList(boolean readMore) {
        return readMore ? new CopyOnWriteArrayList<>() : new Vector<>();
    }

    static  List newConcurrentList(int initialCapacity) {
        return newConcurrentList(initialCapacity, false);
    }

    static  List newConcurrentList(int initialCapacity, boolean readMore) {
        return readMore ? new CopyOnWriteArrayList<>() : new Vector<>(initialCapacity);
    }

    static  T require(T arg) {
        if (arg == null) {
            throw new IllegalArgumentException("The object requires non null");
        }
        return arg;
    }

    @ErrorCode("test")
    static  void require(T arg, boolean testResult) {
        require(arg);
        if (!testResult) {
            throw new ApplicationException("test", values(arg));
        }
    }

    static boolean quietly(@NonNull Action fn) {
        try {
            fn.invoke();
            return true;
        } catch (Throwable e) {
            TraceHandler.INSTANCE.log("quietly {}", fn, e);
        }
        return false;
    }

    static  T quietly(Func fn) {
        return quietly(fn, null);
    }

    static  T quietly(@NonNull Func fn, Func defaultValue) {
        try {
            return fn.invoke();
        } catch (Throwable e) {
            TraceHandler.INSTANCE.log("quietly {}", fn, e);
        }
        if (defaultValue != null) {
            return defaultValue.get();
        }
        return null;
    }

    static  BiFunc quietlyRecover() {
        return e -> {
            TraceHandler.INSTANCE.log("quietlyRecover", e);
            return null;
        };
    }

    static boolean retry(Action fn, int maxAttempts) {
        return retry(fn, maxAttempts, 0, 0, 0, null);
    }

    static boolean retry(Action fn, int maxAttempts, BiFunc recover) {
        return retry(fn, maxAttempts, 0, 0, 0, recover);
    }

    @SneakyThrows
    static boolean retry(@NonNull Action fn, int maxAttempts, long backoffDelay, long backoffMaxDelay, double backoffMultipler, BiFunc recover) {
        Throwable last = null;
        long slept = backoffDelay;
        boolean exponential = backoffMultipler > 0;
        boolean exponentialMax = backoffMaxDelay > 0;
        for (int i = 0; i < maxAttempts; i++) {
            try {
                fn.invoke();
                return true;
            } catch (Throwable e) {
                last = e;
            }
            if (exponential) {
                slept *= backoffMultipler;
            }
            if (exponentialMax && slept > backoffMaxDelay) {
                break;
            }
            Thread.sleep(slept);
        }
        if (last != null) {
            if (recover == null) {
                throw last;
            }
            return ifNull(recover.invoke(last), false);
        }
        return false;
    }

    static  T retry(@NonNull Func fn, int maxAttempts) {
        return retry(fn, maxAttempts, 0, 0, 0, null);
    }

    static  T retry(@NonNull Func fn, int maxAttempts, BiFunc recover) {
        return retry(fn, maxAttempts, 0, 0, 0, recover);
    }

    @SneakyThrows
    static  T retry(@NonNull Func fn, int maxAttempts, long backoffDelay, long backoffMaxDelay, double backoffMultipler, BiFunc recover) {
        Throwable last = null;
        long slept = backoffDelay;
        boolean exponential = backoffMultipler > 0;
        boolean exponentialMax = backoffMaxDelay > 0;
        for (int i = 0; i < maxAttempts; i++) {
            try {
                return fn.invoke();
            } catch (Throwable e) {
                last = e;
            }
            if (exponential) {
                slept *= backoffMultipler;
            }
            if (exponentialMax && slept > backoffMaxDelay) {
                break;
            }
            Thread.sleep(slept);
        }
        if (last != null) {
            if (recover == null) {
                throw last;
            }
            return recover.invoke(last);
        }
        return null;
    }

    //region each
    static  void eachQuietly(Object array, BiAction fn) {
        eachQuietly(Linq.fromIterable(array), fn);
    }

    static  void eachQuietly(Iterable iterable, BiAction fn) {
        each(iterable, fn, false, Constants.TIMEOUT_INFINITE);
    }

    static  void eachQuietly(Iterable iterable, BiAction fn, long interruptedFlag) {
        each(iterable, fn, false, interruptedFlag);
    }

    static  void each(Object array, BiAction fn) {
        each(Linq.fromIterable(array), fn);
    }

    static  void each(Iterable iterable, BiAction fn) {
        each(iterable, fn, true, Constants.TIMEOUT_INFINITE);
    }

    static  void each(Iterable iterable, BiAction fn, boolean throwOnNext, long interruptedFlag) {
        if (iterable == null || fn == null) {
            return;
        }

        for (T t : iterable) {
            try {
                fn.invoke(t);
            } catch (Throwable e) {
                if (throwOnNext) {
                    throw InvalidException.sneaky(e);
                }
                TraceHandler.INSTANCE.log("each", e);
            }
            if (!ThreadPool.asyncContinueFlag(true)) {
                break;
            }
            if (interruptedFlag < 0) {
                if (Thread.interrupted()) {
                    break;
                }
            } else {
                try {
                    Thread.sleep(interruptedFlag);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }

    //CircuitBreakingException
    static void circuitContinue(boolean flag) {
        ThreadPool.ASYNC_CONTINUE.set(flag);
    }

    @SneakyThrows
    static void sleep(long millis) {
        Thread.sleep(millis);
    }
    //endregion

    static boolean tryClose(Object obj) {
        return tryAs(obj, AutoCloseable.class, p -> quietly(p::close));
    }

    static boolean tryClose(AutoCloseable obj) {
        if (obj == null) {
            return false;
        }
        quietly(obj::close);
        return true;
    }

    static  boolean tryAs(Object obj, Class type) {
        return tryAs(obj, type, null);
    }

    @SneakyThrows
    static  boolean tryAs(Object obj, Class type, BiAction fn) {
        T t = as(obj, type);
        if (t == null) {
            return false;
        }
        if (fn != null) {
            fn.invoke(t);
        }
        return true;
    }

    static String metadata(@NonNull AnnotatedElement annotatedElement) {
        Metadata m = annotatedElement.getAnnotation(Metadata.class);
        if (m == null) {
            return null;
        }
        return m.value();
    }

    static Object[] values(Object... args) {
        return args;
    }

    static  T ifNull(T value, T defaultVal) {
        return value != null ? value : defaultVal;
    }

    @SneakyThrows
    static  T ifNull(T value, Func fn) {
        if (value == null) {
            if (fn != null) {
                value = fn.invoke();
            }
        }
        return value;
    }

    static  T as(Object obj, Class type) {
        if (!TypeUtils.isInstance(obj, type)) {
            return null;
        }
        return (T) obj;
    }

    static  boolean eq(T a, T b) {
        //Objects.equals() poisonous
        return a == b || (a != null && a.equals(b));
    }
    //endregion

    default  TV attr(TK key) {
        return IOC.weakMap(this, false).get(key);
    }

    default  void attr(TK key, TV value) {
        Map map = IOC.weakMap(this, false);
        if (value == null) {
            map.remove(key);
        } else {
            map.put(key, value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy