net.javacrumbs.futureconverter.java8common.Java8FutureUtils Maven / Gradle / Ivy
/*
* Copyright © 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.javacrumbs.futureconverter.java8common;
import net.javacrumbs.futureconverter.common.internal.ValueSource;
import net.javacrumbs.futureconverter.common.internal.ValueSourceFuture;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public class Java8FutureUtils {
public static CompletableFuture createCompletableFuture(ValueSource valueSource) {
if (valueSource instanceof CompletableFuturebackedValueSource) {
return ((CompletableFuturebackedValueSource) valueSource).getWrappedFuture();
} else {
return new ValueSourcebackedCompletableFuture(valueSource);
}
}
public static ValueSourceFuture createValueSourceFuture(CompletableFuture completableFuture) {
if (completableFuture instanceof ValueSourcebackedCompletableFuture &&
((ValueSourcebackedCompletableFuture) completableFuture).getValueSource() instanceof ValueSourceFuture) {
return (ValueSourceFuture) ((ValueSourcebackedCompletableFuture) completableFuture).getValueSource();
} else {
return new CompletableFuturebackedValueSource<>(completableFuture);
}
}
public static ValueSource createValueSource(CompletableFuture completableFuture) {
if (completableFuture instanceof ValueSourcebackedCompletableFuture) {
return ((ValueSourcebackedCompletableFuture) completableFuture).getValueSource();
} else {
return new CompletableFuturebackedValueSource<>(completableFuture);
}
}
/**
* CompletableFuture that takes values from the ValueSource. CompletableFuture is a class, not
* an interface so we can not just forward events from the ValueSource, we to always instantiate the class.
*/
private static final class ValueSourcebackedCompletableFuture extends CompletableFuture {
private final ValueSource valueSource;
private ValueSourcebackedCompletableFuture(ValueSource valueSource) {
this.valueSource = valueSource;
valueSource.addCallbacks(this::complete, this::completeExceptionally);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (isDone()) {
return false;
}
boolean result = valueSource.cancel(mayInterruptIfRunning);
super.cancel(mayInterruptIfRunning);
return result;
}
private ValueSource getValueSource() {
return valueSource;
}
}
private static final class CompletableFuturebackedValueSource extends ValueSourceFuture {
private CompletableFuturebackedValueSource(CompletableFuture completableFuture) {
super(completableFuture);
}
@Override
public void addCallbacks(Consumer successCallback, Consumer failureCallback) {
getWrappedFuture().whenComplete((v, t) -> {
if (t == null) {
successCallback.accept(v);
} else {
failureCallback.accept(t);
}
});
}
@Override
protected CompletableFuture getWrappedFuture() {
return (CompletableFuture) super.getWrappedFuture();
}
}
}