org.eclipse.jetty.websocket.api.Callback Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.websocket.api;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* A callback object that handles success/failure events of asynchronous operations.
* NOTE: This interface is almost identical to {@code org.eclipse.jetty.util.Callback},
* which however cannot be used in the Jetty WebSocket APIs for web application classloading
* reasons.
*/
public interface Callback
{
/**
* Empty implementation.
*/
Callback NOOP = new Callback()
{
};
/**
* Creates a callback from the given success and failure lambdas.
*
* @param success the success action to invoke when the callback succeeds
* @param failure the failure consumer to invoke when the callback fails
* @return a new callback
*/
static Callback from(Runnable success, Consumer failure)
{
return new Callback()
{
@Override
public void succeed()
{
success.run();
}
@Override
public void fail(Throwable x)
{
failure.accept(x);
}
};
}
/**
* Method to invoke to succeed the callback.
*
* @see #fail(Throwable)
*/
default void succeed()
{
}
/**
* Method to invoke to fail the callback.
*
* @param x the failure
*/
default void fail(Throwable x)
{
}
/**
* Converts this callback into a {@link BiConsumer} that can be passed
* to {@link CompletableFuture#whenComplete(BiConsumer)}.
* When the {@link BiConsumer} is accepted, this callback is completed.
*
* @return a {@link BiConsumer} that completes this callback
* @see Completable#with(Consumer)
*/
default BiConsumer super Void, ? super Throwable> asBiConsumer()
{
return (r, x) ->
{
if (x == null)
succeed();
else
fail(x);
};
}
/**
* A {@link Callback} that is also a {@link CompletableFuture}.
* Applications can pass an instance of this class as a {@link Callback},
* but also use the {@link CompletableFuture} APIs.
*/
class Completable extends CompletableFuture implements Callback
{
/**
* Convenience method that creates a {@link Completable} that
* is passed to the given consumer and then returned.
* For example:
* {@code
* Completable.with(completable -> session.sendText("TEXT", completable))
* .thenRun(session::demand);
* }
*
* @param consumer the consumer that receives the completable
* @return a new completable passed to the consumer
* @see #compose(Consumer)
*/
public static Completable with(Consumer consumer)
{
Completable completable = new Completable();
consumer.accept(completable);
return completable;
}
@Override
public void succeed()
{
complete(null);
}
@Override
public void fail(Throwable x)
{
completeExceptionally(x);
}
/**
* Returns a new {@link Completable} that, when this {@link Completable}
* succeeds, is passed to the given consumer and then returned.
* If this {@link Completable} fails, the new {@link Completable} is
* also failed, and the consumer is not invoked.
* For example:
* {@code
* Callback.Completable.with(completable1 -> session.sendPartialText("hello", false, completable1))
* .compose(completable2 -> session.sendPartialText(" ", false, completable2))
* .compose(completable3 -> session.sendPartialText("world", true, completable3))
* .thenRun(session::demand);
* }
*
* @param consumer the consumer that receives the {@link Completable}
* @return a new {@link Completable} passed to the consumer
* @see #with(Consumer)
*/
public Completable compose(Consumer consumer)
{
Completable completable = new Completable();
whenComplete((r, x) ->
{
if (x == null)
consumer.accept(completable);
else
completable.fail(x);
});
return completable;
}
}
}