org.rx.core.Extends Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxlib Show documentation
Show all versions of rxlib Show documentation
A set of utilities for Java
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);
}
}
}