io.vertx.up.unity.Fluctuate Maven / Gradle / Ivy
package io.vertx.up.unity;
import io.reactivex.Observable;
import io.vertx.core.AsyncResult;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.up.exception.WebException;
import io.vertx.up.exception.web._500InternalServerException;
import io.vertx.up.util.Ut;
import java.util.*;
import java.util.function.*;
@SuppressWarnings("unchecked")
class Fluctuate {
/**
* Source -> List -> List>
*/
static Future> thenParallel(
final Future> source,
final Function> generateFun,
final BiFunction mergeFun
) {
return source.compose(first -> {
final List secondFutures = new ArrayList<>();
Observable.fromIterable(first)
.map(generateFun::apply)
.filter(Objects::nonNull)
.subscribe(secondFutures::add)
.dispose();
final Future> result = Future.future();
CompositeFuture.all(secondFutures).setHandler(res -> {
final List secondary = res.result().list();
// Zipper Operation, the base list is first.
final List completed = Ut.elementZip(first, secondary, mergeFun);
result.complete(completed);
});
return result;
});
}
static Future thenScatterJson(
final Future source,
final Function> generateFun,
final BiFunction mergeFun
) {
return source.compose(first -> {
final List secondFutures = new ArrayList<>();
Observable.fromIterable(first)
.map(item -> (JsonObject) item)
.map(generateFun::apply)
.subscribe(secondFutures::add)
.dispose();
final Future result = Future.future();
CompositeFuture.all(secondFutures).setHandler(res -> {
final List secondary = res.result().list();
// Zipper Operation, the base list is first
final List completed = Ut.elementZip(first.getList(), secondary, mergeFun);
result.complete(new JsonArray(completed));
});
return result;
});
}
static Future thenParallelArray(
final Future source,
final Function> generateFun,
final BinaryOperator operatorFun
) {
return source.compose(first -> {
final List secondFutures = new ArrayList<>();
Observable.fromIterable(first)
.map(item -> (JsonObject) item)
.map(generateFun::apply)
.subscribe(secondFutures::add)
.dispose();
final Future result = Future.future();
CompositeFuture.all(secondFutures).setHandler(res -> {
final List secondary = res.result().list();
// Zipper Operation, the base list is first
final List completed = Ut.elementZip(first.getList(), secondary, operatorFun);
result.complete(new JsonArray(completed));
});
return result;
});
}
static Future thenParallelArray(
final Future... futures
) {
final Future result = Future.future();
CompositeFuture.all(Arrays.asList(futures)).setHandler(res -> {
final JsonObject resultMap = new JsonObject();
Ut.itList(res.result().list(), (item, index) -> resultMap.put(index.toString(), item));
result.complete(resultMap);
});
return result;
}
static Future thenParallelJson(
final Future... futures
) {
final Future result = Future.future();
// thenResponse
CompositeFuture.all(Arrays.asList(futures)).setHandler(thenResponse(result, (finished) -> {
final JsonObject resultMap = new JsonObject();
if (null != finished) {
Ut.itList(finished.list(), (item, index) -> resultMap.put(index.toString(), item));
}
return resultMap;
}));
return result;
}
static Future thenParallelJson(
final Future source,
final Function> generateFun,
final BiConsumer... operatorFun
) {
return source.compose(first -> {
final List secondFutures = generateFun.apply(first);
final Future result = Future.future();
// thenResponse
CompositeFuture.all(secondFutures).setHandler(thenResponse(result, (finished) -> {
if (null != finished) {
final List secondary = finished.list();
// Zipper Operation, the base list is first
Ut.itList(secondary, (item, index) -> operatorFun[index].accept(first, item));
}
return first;
}));
return result;
});
}
/**
* Source ->
* Target1
* Target2
*/
static Future thenComposite(
final Future source,
final BiFunction, T> mergeFun,
final Supplier>... suppliers) {
return source.compose(first -> {
final List secondFutures = new ArrayList<>();
Observable.fromArray(suppliers)
.map(Supplier::get)
.subscribe(secondFutures::add)
.dispose();
// thenResponse
return thenResponse(secondFutures, first, mergeFun);
});
}
static Future thenComposite(
final List> futures
) {
final Future result = Future.future();
final List converted = new ArrayList<>(futures);
// thenResponse
CompositeFuture.all(converted).setHandler(thenResponse(result, (finished) ->
null == finished ? new JsonArray() : new JsonArray(finished.list())
));
return result;
}
static Future thenComposite(
final Future source,
final BiFunction, T> mergeFun,
final Function>... functions) {
return source.compose(first -> {
final List secondFutures = new ArrayList<>();
Observable.fromArray(functions)
.map(item -> item.apply(first))
.subscribe(secondFutures::add)
.dispose();
// thenResponse
return thenResponse(secondFutures, first, mergeFun);
});
}
static Future thenOtherwise(
final Future conditionFuture,
final Supplier> supplierTrue, final Function trueFun,
final Supplier> supplierFalse, final Function falseFun
) {
final Future future = Future.future();
conditionFuture.setHandler(handler -> {
if (handler.succeeded() && handler.result()) {
// Success & Boolean
final Future trueFuture = supplierTrue.get();
trueFuture.setHandler(trueRes -> future.complete(trueFun.apply(trueRes.result())));
} else {
// Failed & Boolean = false;
final Future falseFuture = supplierFalse.get();
falseFuture.setHandler(falseRes -> future.complete(falseFun.apply(falseRes.result())));
}
});
return future;
}
static Future thenOtherwise(
final Future conditionFuture,
final Supplier> supplierTrue, final Function trueFun,
final Class extends WebException> clazz, final Object... args
) {
final Future future = Future.future();
conditionFuture.setHandler(handler -> {
if (handler.succeeded() && handler.result()) {
// Success & Boolean
final Future trueFuture = supplierTrue.get();
trueFuture.setHandler(trueRes -> future.complete(trueFun.apply(trueRes.result())));
} else {
// Failed & Boolean = false;
if (null == clazz) {
future.complete();
} else {
// Error existing
final WebException error = Ut.instance(clazz, args);
future.fail(error);
}
}
});
return future;
}
static Future thenError(
final Class extends WebException> clazz,
final Object... args
) {
final WebException error = To.toError(clazz, args);
return Future.failedFuture(error);
}
private static Future thenResponse(
final List secondFutures,
final F first,
final BiFunction, T> mergeFun) {
final Future result = Future.future();
CompositeFuture.all(secondFutures).setHandler(
thenResponse(result, (finished) -> null == finished ? null : mergeFun.apply(first, finished.list())));
return result;
}
static Future> thenSet(
final List data,
final Function> fun
) {
final Future> results = Future.future();
final List futures = new ArrayList<>();
data.stream().map(fun).forEach(futures::add);
CompositeFuture.all(futures).setHandler(thenResponse(results, finished -> {
if (null == finished) {
return new HashSet<>();
} else {
final List extracted = finished.list();
return new HashSet<>(extracted);
}
}));
return results;
}
private static Handler> thenResponse(
final Future future,
final Function fun) {
return res -> {
if (res.succeeded()) {
final T callback = fun.apply(res.result());
future.complete(callback);
} else {
if (null != res.cause()) {
res.cause().printStackTrace();
future.fail(res.cause());
} else {
future.fail(new _500InternalServerException(Fluctuate.class, null));
}
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy