One of the fundamental pieces of an asynchronous programming model
is the mechanism by which clients retrieve the result of the asynchronous
task. Since Java 5, there has been a
java.util.concurrent.Future
interface available in the Java
class libraries, which means that it is the de facto
API in Java for handling the result of an asynchronous task. Futures have
some limitations however in that they have no mechanism for registering
callbacks. Java 8 introduces the class
java.util.concurrent.CompletableFuture
which addresses this
but it is a complex API.
This specification defines a Promises API which is independent of all other OSGi specifications including the OSGi Framework and thus can be easily used outside of the OSGi environment.
A Promise object holds the result of a potentially asynchronous task. The receiver of a Promise object can register callbacks on the Promise to be notified when the result is available or can block on the result becoming available. Promises can be chained together in powerful ways to handle asynchronous work flows and recovery.
Promises capture the effects of latency and errors by making these explicit in the API signatures. Latency is represented by callbacks which will eventually be called. Errors are represented by the failure member. In essence, this is what sets Promises apart from things such as RPC calls where such effects are not explicitly captured but rather attempted to be transparently handled.
-
Common concepts - The API is inspired by the Promises work in JavaScript and uses the same basic concepts. See [2] JavaScript Promises.
-
Independent - The design is independent of all other OSGi specifications and can be used outside of an OSGi environment.
-
Asynchronous - The design supports asynchronous tasks.
-
Small - The API and implementation are very compact.
-
Complete - The design provides a very complete set of operations for Promise which are primitives that can be used to address most use cases.
-
Monad - The design supports monadic programming. See [4] Monad.
-
Resolution - A Promise can be resolved successfully with a value or unsuccessfully with an exception.
-
Generified - Generics are used to promote type safety.
-
Promise - A Promise object holds the eventual result of a potentially asynchronous task.
-
Callback - The receiver of a Promise can register callbacks on the Promise to be notified when the task is completed.
-
Deferred - A Deferred object represents the potentially asynchronous task and is used to resolve the Promise.
A Promise object holds the eventual result of a potentially
asynchronous task. A Promise is either unresolved or resolved. An
unresolved Promise does not have the result of the
associated task available while a resolved Promise
has the result of the associated task available. The isDone()
method must return true
if the Promise is resolved and
false
if the Promise is unresolved. A Promise must only be
resolved once.
A resolved Promise can be either resolved with a value, which means
the associated task completed successfully and
supplied a result, or resolved with a failure, which means the associated
task completed unsuccessfully and supplied an
exception. The getFailure() method can be called to determine if the resolved
Promise completed successfully with a value or unsuccessfully with a
failure. If the getFailure() method returns a Throwable
, the
Promise resolved unsuccessfully with a failure. If the getFailure() method returns null
, the Promise
resolved successfully with a value that can be obtained from getValue().
If the Promise is unresolved, then calling getFailure() or getValue() must block until the Promise is resolved. In general, these two methods should not be used outside of a callback. Use callbacks to be notified when the Promise is resolved. See Callbacks.
Promise is an interface which can allow for many Promise implementations. This API contains the Deferred class which provides access to the standard Promise implementation. A Deferred object can be created by calling the deferred() method on a PromiseFactory object.
A PromiseFactory object is created with a specified callback
executor and a specified scheduled executor to use for created Promise
objects and the Promise objects associated with created Deferred objects.
If the callback executor or the scheduled executor is not specified or is
specified as null
, then implementation default executors will
be used. The Deferred() constructor will create a Deferred whose
associated Promise uses the implementation default executors. All Promise
objects created by a Promise must use the same executors as the creating
Promise. Callbacks must be called using the callback executor. The
scheduled executor must be used by the timeout(long) and delay(long) operations. The inlineExecutor() method can be used to obtain an executor which
runs callbacks immediately on the thread calling the
Executor.execute
method. This behavior is similar to how
callbacks were executed in the default Promise implementation of Promise
1.0 specification.
The Promise associated with a Deferred object can be obtained using getPromise(). This Promise can then be supplied to other parties who can use it to be notified of and obtain the eventual result.
public Promise<String> getTimeConsumingAnswer() {
Deferred<String> deferred = factory.deferred();
asynchronously(() -> doTask(deferred));
return deferred.getPromise();
}
A Deferred object can later be used to resolve the associated Promise successfully by calling resolve(T) or unsuccessfully by calling fail(Throwable).
private void doTask(Deferred<String> deferred) {
try {
String answer = computeTimeConsumingAnswer();
deferred.resolve(answer); // successfully resolve with value
} catch (Exception e) {
deferred.fail(e); // unsuccessfully resolve with exception
}
}
A Deferred object can also be used to resolve the associated Promise with the eventual result of another Promise by calling resolveWith(Promise) or the result of a CompletionStage by calling resolveWith(CompletionStage).
private void doTask(Deferred<String> deferred) {
try {
Promise<String> promise = getPromiseWithTheAnswer();
deferred.resolveWith(promise); // resolve with another Promise
} catch (Exception e) {
deferred.fail(e); // unsuccessfully resolve with exception
}
}
If resolve(T) or fail(Throwable) is called when the Promise associated with the Deferred is already resolved, then an Illegal State Exception must be thrown.
Care must be taken in sharing a Deferred object with other parties since the other parties can resolve the associated Promise. A Deferred object should be made available only to the party that will responsible for resolving the associated Promise.
To be notified when a Promise has been resolved, callbacks are used.
The Promise API provides two forms of callbacks: the basic
Runnable
and Consumer callbacks and the more specialized Success and Failure
callbacks.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the callback is called.
Resolving a Promise happens-before any
registered callback is called. That is, for the resolved Promise, in a
registered callback isDone() must return true
and getValue()
and getFailure() must not block.
Callbacks may be registered at any time including before and after a Promise has been resolved. If a callback is registered before the Promise is resolved, it will be called later when the Promise is resolved. If a callback is registered on an already resolved Promise, it will be called right away.
The onResolve(Runnable) method is used to register a
Runnable
with the Promise which must be called when the
Promise is resolved either successfully with a value or unsuccessfully
with a failure. The resolved Promise is not passed to the Runnable, so
if the Runnable implementation needs access to the resolved Promise, it
must take care to ensure it has access.
final Promise<String> answer = getTimeConsumingAnswer();
answer.onResolve(() -> doSomethingWithAnswer(answer));
The onResolve(Runnable) method returns the Promise object upon which it is called.
The thenAccept(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved successfully with a value. The value of the resolved Promise is passed to the Consumer.
final Promise<String> answer = getTimeConsumingAnswer().thenAccept(s ->
doSomethingWithAnswer(s)
);
The thenAccept(Consumer) method returns a new Promise which will be resolved with either the exception thrown from the Consumer, if one is thrown, or with the Promise.
The onSuccess(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved successfully with a value. The value of the resolved Promise is passed to the Consumer. The onSuccess(Consumer) method returns the Promise object upon which it is called.
The onFailure(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved unsuccessfully with a failure. The failure of the resolved Promise is passed to the Consumer. The onFailure(Consumer) method returns the Promise object upon which it is called.
The then(Success) and then(Success,Failure) methods can be used to register the more specialized Success and Failure callbacks. The Success callback is only called if the Promise is successfully resolved with a value. The Failure callback is only called if the Promise is unsuccessfully resolved with a failure.
Promise<String> answer = getTimeConsumingAnswer();
answer.then(p -> processResult(p.getValue()), p -> handleFailure(p.getFailure()));
The then
methods return a new Promise which can be
used to chain Promises together.
The then(Success), then(Success,Failure), and thenAccept(Consumer) methods also provide a means to chain Promises
together. These methods return a new Promise which is chained to the
original Promise upon which the method was called. The returned Promise
must be resolved when the original Promise is resolved after the specified
Success, Failure, or Consumer callback is executed. The result of the
executed callback must be used to resolve the returned Promise. A sequence
of calls to the then
methods can be used to create a chain of
promises which are resolved in sequence.
For the then(Success) or then(Success,Failure) methods, if the original Promise is successfully resolved, the Success callback is executed and the Promise returned by the Success callback, if any, or thrown exception is used to resolve the Promise returned from the method. If the original Promise is resolved with a failure, the Failure callback is executed and the Promise returned from the method is resolved with a failure.
For the thenAccept(Consumer) method, if the original Promise is successfully resolved, the Consumer callback is executed and the value of the original Promise or thrown exception is used to resolve the Promise returned from the method. If the original Promise is resolved with a failure, the Consumer callback is not executed and the Promise returned from the method is resolved with the failure of the original Promise.
In the following example, a Promise which will supply the name of the file to download is chained to a Promise which will return a mirror URL to use to download the file which is then further chained to a Promise which will return an Input Stream from which to read the download file.
Promise<String> name = getDownloadName();
Promise<URL> mirror = name.then(p -> getMirror(p.getValue()));
Promise<InputStream> in = mirror.then(p -> getStream(p.getValue()));
Since we probably do not need the intermediate Promises, we can collapse the chain into a single statement.
Promise<InputStream> in = getDownloadName().then(p -> getMirror(p.getValue()))
.then(p -> getStream(p.getValue()));
The chain of Promises will also propagate any exceptions that occur to resolve the last Promise in the chain which means we do not need to do any exception handling in the intermediate tasks. Promises can also be chained by using the monadic programming methods in Monad.
The Promise API supports monadic programming. See [4] Monad. The Promise interface
defines a number of interesting methods including map
,
flatMap
and filter
.
-
filter(Predicate) - Filter the value of the Promise.
If the Promise is successfully resolved, the predicate argument is called with the value of the Promise. If the predicate accepts the value, then the value is used to successfully resolve the Promise returned by the filter method. If the predicate does not accept the value, the Promise returned by the filter method is unsuccessfully resolved with a No Such Element Exception. If the predicate throws an exception, the Promise returned by the filter method is unsuccessfully resolved with that exception.
If the Promise is unsuccessfully resolved, the predicate argument is not called and the Promise returned by the filter method is unsuccessfully resolved with the failure of the Promise.
-
map(Function) - Map the value of the Promise.
If the Promise is successfully resolved, the function argument is called with the value of the Promise. The value returned by the function is used to successfully resolve the Promise returned by the map method. If the function throws an exception, the Promise returned by the map method is unsuccessfully resolved with that exception.
If the Promise is unsuccessfully resolved, the function argument is not called and the Promise returned by the map method is unsuccessfully resolved with the failure of the Promise.
-
flatMap(Function) - FlatMap the value of the Promise.
If the Promise is successfully resolved, the function argument is called with the value of the Promise. The Promise returned by the function is used to resolve the Promise returned by the flatMap method. If the function throws an exception, the Promise returned by the flatMap method is unsuccessfully resolved with that exception.
If the Promise is unsuccessfully resolved, the function argument is not called and the Promise returned by the flatMap method is unsuccessfully resolved with the failure of the Promise.
-
recover(Function) - Recover from the unsuccessful resolution of the Promise with a recovery value.
If the Promise is successfully resolved, the function argument is not called and the Promise returned by the recover method is resolved with the value of the Promise.
If the Promise is unsuccessfully resolved, the function argument is called with the Promise to supply a recovery value. If the recovery value is not
null
, the Promise returned by the recover method is successfully resolved with the recovery value. If the recovery value isnull
, the Promise returned by the recover method is unsuccessfully resolved with the failure of the Promise. If the function throws an exception, the Promise returned by the recover method is unsuccessfully resolved with that exception. -
recoverWith(Function) - Recover from the unsuccessful resolution of the Promise with a recovery Promise.
If the Promise is successfully resolved, the function argument is not called and the Promise returned by the recover method is resolved with the value of the Promise.
If the Promise is unsuccessfully resolved, the function argument is called with the Promise to supply a recovery Promise. If the recovery Promise is not
null
, the Promise returned by the recover method is resolved with the recovery Promise. If the recovery Promise isnull
, the Promise returned by the recover method is unsuccessfully resolved with the failure of the Promise. If the function throws an exception, the Promise returned by the recover method is unsuccessfully resolved with that exception. -
fallbackTo(Promise) - Fall back to the value of the Promise argument if the Promise unsuccessfully resolves.
If the Promise is successfully resolved, the Promise argument is not used and the Promise returned by the fallbackTo method is resolved with the value of the Promise.
If the Promise is unsuccessfully resolved, the Promise argument is used to provide a fallback value when it becomes resolved. If the Promise argument is successfully resolved, the Promise returned by the fallbackTo method is resolved with the value of the Promise argument. If the Promise argument is unsuccessfully resolved, the Promise returned by the fallbackTo method is unsuccessfully resolved with the failure of the Promise.
These functions can be used to build pipelines of chained Promises that are processed in sequence. For example, in the following chain, the value of the original promise, once resolved, is filtered for acceptable values. If the filter says the value is not acceptable, the recover method will be used to replace it with a default value.
return promise.filter(v -> isValueOk(v)).recover(p -> getDefaultValue())
With these chains, one can write powerful programs without the need to resort to complex if/else and try/catch logic.
The Promise API provides methods to affect the timing of resolving Promises.
-
timeout(long) - Time out the resolution of the Promise.
If the Promise is successfully resolved before the timeout, the returned Promise is resolved with the value of the Promise. If the Promise is resolved with a failure before the timeout, the returned Promise is resolved with the failure of the Promise. If the timeout is reached before the Promise is resolved, the returned Promise is failed with a TimeoutException.
-
delay(long) - Delay after the resolution of the Promise.
Once the Promise is resolved, resolve the returned Promise with the Promise after the specified delay.
In Java 8, the concept of Functional Interfaces is introduced. See [5] Function Interfaces. Functional interfaces are types with a single abstract method. Instances of functional interfaces can be created with lambda expressions, method references, or constructor references. Many methods on Promise take functional interface arguments and so are suitable for use with lambda expressions and method references in Java 8.
Four of these functional interfaces are Function, Predicate, Supplier, and
Consumer.
These are equivalent to functional interfaces which are part of the
java.util.function
package introduced in Java 8 with
additional static methods to support interoperation. OSGi defines these
interfaces to allow throwing checked exceptions which can be propagated in
a chain of Promises.
The API also provides several useful utility methods when working with Promises.
Often, you may need to create an already resolved Promise to return or chain with another Promise. The resolved(T) method can be used to create a new Promise already successfully resolved with the specified value. The failed(Throwable) method can be used to create a new Promise already unsuccessfully resolved with the specified exception. These methods also exists as static methods on the Promises class returning Promises which use the implementation default executors.
return getTimeConsumingAnswer().fallbackTo(factory.resolved("Fallback Value"));
The resolvedWith(Promise) method can be used to return a new Promise that will be resolved with the specified Promise.
The submit(Callable) method can be used to return a new Promise that will hold the result of the specified task. The task will be executed on the callback executor.
The all(Collection) method returns a Promise that is a latch on the
specified Promises. The returned Promise must resolve only when all of the
specified Promises have resolved. The toPromise() method returns a Collector
which can
be used on a Stream
of Promises to collect the results of the
Promises into a latch using the all(Collection) method as the finisher. The all
method also exists as a static method on the Promises class
returning a Promise which uses the implementation default
executors.
Interoperation with CompletionStage is supported. The resolvedWith(CompletionStage) method returns a Promise that is resolved by the specified CompletionStage. The toCompletionStage() method returns a CompletionStage that is resolved by the receiving Promise.
The Promise API does not define any OSGi services nor does the API perform any privileged actions. Therefore, it has no security considerations.
Promise Package Version 1.2.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest.
Example import for consumers using the API in this package:
Import-Package: org.osgi.util.promise; version="[1.2,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.util.promise; version="[1.2,1.3)"
-
Deferred
- A Deferred Promise resolution. -
FailedPromisesException
- Promise failure exception for a collection of failed Promises. -
Failure
- Failure callback for a Promise. -
Promise
- A Promise of a value. -
PromiseFactory
- Promise factory to create Deferred and Promise objects. -
PromiseFactory.Option
- Defines the options for a Promise factory. -
Success
- Success callback for a Promise. -
TimeoutException
- Timeout exception for a Promise.
The value type associated with the created Promise.
A Deferred Promise resolution.
Instances of this class can be used to create a Promise that can be resolved in the future. The associated Promise can be successfully resolved with resolve(Object) or resolved with a failure with fail(Throwable). It can also be resolved with the resolution of another promise using resolveWith(Promise).
The associated Promise can be provided to any one, but the Deferred object should be made available only to the party that will responsible for resolving the Promise.
Immutable
Consumers of this API must not implement this type
Create a new Deferred.
The associated promise will use the default callback executor and default scheduled executor.
The failure of the resolved Promise. Must not be
null
.
Fail the Promise associated with this Deferred.
After the associated Promise is resolved with the specified failure, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the associated Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
IllegalStateException
– If the associated Promise was already
resolved.
Returns the Promise associated with this Deferred.
All Promise objects created by the associated Promise will use the executors of the associated Promise.
The Promise associated with this Deferred.
The value of the resolved Promise.
Successfully resolve the Promise associated with this Deferred.
After the associated Promise is resolved with the specified value, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the associated Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
IllegalStateException
– If the associated Promise was already
resolved.
A Promise whose value or failure must be used to resolve the
associated Promise. Must not be null
.
Resolve the Promise associated with this Deferred with the specified Promise.
If the specified Promise is successfully resolved, the associated Promise is resolved with the value of the specified Promise. If the specified Promise is resolved with a failure, the associated Promise is resolved with the failure of the specified Promise.
After the associated Promise is resolved with the specified Promise, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the associated Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
A Promise that is resolved only when the associated Promise is
resolved by the specified Promise. The returned Promise must be
successfully resolved with the value null
, if the
associated Promise was resolved by the specified Promise. The
returned Promise must be resolved with a failure of
IllegalStateException, if the associated Promise was
already resolved when the specified Promise was resolved.
A CompletionStage whose result must be used to resolve the
associated Promise. Must not be null
.
Resolve the Promise associated with this Deferred with the specified CompletionStage.
If the specified CompletionStage is completed normally, the associated Promise is resolved with the value of the specified CompletionStage. If the specified CompletionStage is completed exceptionally, the associated Promise is resolved with the failure of the specified CompletionStage.
After the associated Promise is resolved with the specified CompletionStage, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the associated Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
A Promise that is resolved only when the associated Promise is
resolved by the specified CompletionStage. The returned Promise
must be successfully resolved with the value null
, if the
associated Promise was resolved by the specified CompletionStage.
The returned Promise must be resolved with a failure of
IllegalStateException, if the associated Promise was
already resolved when the specified CompletionStage was
completed.
1.2
Promise failure exception for a collection of failed Promises.
A collection of Promises that have been resolved with a
failure. Must not be null
, must not be empty and all of
the elements in the collection must not be null
.
The cause of this exception. This is typically the failure of the first Promise in the specified collection.
Create a new FailedPromisesException with the specified Promises.
Failure callback for a Promise.
A Failure callback is registered with a Promise using the Promise.then(Success, Failure) method and is called if the Promise is resolved with a failure.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
Thread-safe
The failed resolved Promise.
Failure callback for a Promise.
This method is called if the Promise with which it is registered resolves with a failure.
In the remainder of this description we will refer to the Promise returned by Promise.then(Success, Failure) when this Failure callback was registered as the chained Promise.
If this methods completes normally, the chained Promise must be failed with the same exception which failed the resolved Promise. If this method throws an exception, the chained Promise must be failed with the thrown exception.
Exception
– The chained Promise must be failed with the thrown
exception.
The value type associated with this Promise.
A Promise of a value.
A Promise represents a future value. It handles the interactions for asynchronous processing. A Deferred object can be used to create a Promise and later resolve the Promise. A Promise is used by the caller of an asynchronous function to get the result or handle the error. The caller can either get a callback when the Promise is resolved with a value or an error, or the Promise can be used in chaining. In chaining, callbacks are provided that receive the resolved Promise, and a new Promise is generated that resolves based upon the result of a callback.
Both callbacks and chaining can be repeated any number of times, even after the Promise has been resolved.
Example callback usage:
Promise<String> foo = foo();
foo.onResolve(() -> System.out.println("resolved"));
Example chaining usage;
Success<String,String> doubler = p -> Promises
.resolved(p.getValue() + p.getValue());
Promise<String> foo = foo().then(doubler).then(doubler);
Thread-safe
Consumers of this API must not implement this type
The time to delay in milliseconds. Zero and negative time is treated as no delay.
Delay after the resolution of this Promise.
Once this Promise is resolved, resolve the returned Promise with this Promise after the specified delay.
A Promise that is resolved with this Promise after this Promise is resolved and the specified delay has elapsed.
1.1
The Promise whose value must be used to resolve the
returned Promise if this Promise resolves with a failure. Must not
be null
.
Fall back to the value of the specified Promise if this Promise fails.
If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.
If this Promise is resolved with a failure, the successful result of the specified Promise is used to resolve the returned Promise. If the specified Promise is resolved with a failure, the returned Promise must be failed with the failure of this Promise rather than the failure of the specified Promise.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that returns the value of this Promise or falls back to the value of the specified Promise.
The Predicate to evaluate the value of this Promise.
Must not be null
.
Filter the value of this Promise.
If this Promise is successfully resolved, the returned Promise must
either be resolved with the value of this Promise, if the specified
Predicate accepts that value, or failed with a
NoSuchElementException
, if the specified Predicate does not
accept that value. If the specified Predicate throws an exception, the
returned Promise must be failed with the exception.
If this Promise is resolved with a failure, the returned Promise must be failed with that failure.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that filters the value of this Promise.
<R>
The value type associated with the returned Promise.
The Function that must flatMap the value of this Promise to
a Promise that must be used to resolve the returned Promise. Must
not be null
.
FlatMap the value of this Promise.
If this Promise is successfully resolved, the returned Promise must be resolved with the Promise from the specified Function as applied to the value of this Promise. If the specified Function throws an exception, the returned Promise must be failed with the exception.
If this Promise is resolved with a failure, the returned Promise must be failed with that failure.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that returns the value of this Promise as mapped by the specified Function.
Returns the failure of this Promise.
If this Promise is not resolved, this method must block and wait for this Promise to be resolved before completing.
If this Promise was resolved with a failure, this method returns with the
failure of this Promise. If this Promise was successfully resolved, this
method must return null
.
The failure of this resolved Promise or null
if this
Promise was successfully resolved.
InterruptedException
– If the current thread was interrupted while
waiting.
Returns the value of this Promise.
If this Promise is not resolved, this method must block and wait for this Promise to be resolved before completing.
If this Promise was successfully resolved, this method returns with the
value of this Promise. If this Promise was resolved with a failure, this
method must throw an InvocationTargetException
with the
failure exception as the cause.
The value of this resolved Promise.
InvocationTargetException
– If this Promise was resolved with a
failure. The cause of the InvocationTargetException
is
the failure exception.
InterruptedException
– If the current thread was interrupted while
waiting.
Returns whether this Promise has been resolved.
This Promise may be successfully resolved or resolved with a failure.
true
if this Promise was resolved either successfully or
with a failure; false
if this Promise is unresolved.
<R>
The value type associated with the returned Promise.
The Function that must map the value of this Promise to the
value that must be used to resolve the returned Promise. Must not
be null
.
Map the value of this Promise.
If this Promise is successfully resolved, the returned Promise must be resolved with the value of specified Function as applied to the value of this Promise. If the specified Function throws an exception, the returned Promise must be failed with the exception.
If this Promise is resolved with a failure, the returned Promise must be failed with that failure.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that returns the value of this Promise as mapped by the specified Function.
The Consumer callback that receives the failure of this
Promise. Must not be null
.
Register a callback to be called with the failure for this Promise when this Promise is resolved with a failure. The callback will not be called if this Promise is resolved successfully.
This method may be called at any time including before and after this Promise has been resolved.
Resolving this Promise happens-before any registered callback is
called. That is, in a registered callback, isDone() must return
true
and getValue() and getFailure() must not
block.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.
This Promise.
1.1
The callback to be called when this Promise is resolved.
Must not be null
.
Register a callback to be called when this Promise is resolved.
The specified callback is called when this Promise is resolved either successfully or with a failure.
This method may be called at any time including before and after this Promise has been resolved.
Resolving this Promise happens-before any registered callback is
called. That is, in a registered callback, isDone() must return
true
and getValue() and getFailure() must not
block.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.
This Promise.
The Consumer callback that receives the value of this
Promise. Must not be null
.
Register a callback to be called with the result of this Promise when this Promise is resolved successfully. The callback will not be called if this Promise is resolved with a failure.
This method may be called at any time including before and after this Promise has been resolved.
Resolving this Promise happens-before any registered callback is
called. That is, in a registered callback, isDone() must return
true
and getValue() and getFailure() must not
block.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.
This Promise.
1.1
If this Promise resolves with a failure, the specified
Function is called to produce a recovery value to be used to
resolve the returned Promise. Must not be null
.
Recover from a failure of this Promise with a recovery value.
If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.
If this Promise is resolved with a failure, the specified Function is applied to this Promise to produce a recovery value.
-
If the recovery value is not
null
, the returned Promise must be resolved with the recovery value. -
If the recovery value is
null
, the returned Promise must be failed with the failure of this Promise. -
If the specified Function throws an exception, the returned Promise must be failed with that exception.
To recover from a failure of this Promise with a recovery value of
null
, the recoverWith(Function) method must be used. The
specified Function for recoverWith(Function) can return
Promises.resolved(null)
to supply the desired null
value.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that resolves with the value of this Promise or recovers from the failure of this Promise.
If this Promise resolves with a failure, the specified
Function is called to produce a recovery Promise to be used to
resolve the returned Promise. Must not be null
.
Recover from a failure of this Promise with a recovery Promise.
If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.
If this Promise is resolved with a failure, the specified Function is applied to this Promise to produce a recovery Promise.
-
If the recovery Promise is not
null
, the returned Promise must be resolved with the recovery Promise. -
If the recovery Promise is
null
, the returned Promise must be failed with the failure of this Promise. -
If the specified Function throws an exception, the returned Promise must be failed with that exception.
This method may be called at any time including before and after this Promise has been resolved.
A Promise that resolves with the value of this Promise or recovers from the failure of this Promise.
<R>
The value type associated with the returned Promise.
The Success callback to be called when this Promise is
successfully resolved. May be null
if no Success
callback is required. In this case, the returned Promise must
be resolved with the value null
when this Promise is
successfully resolved.
The Failure callback to be called when this Promise is
resolved with a failure. May be null
if no Failure
callback is required.
Chain a new Promise to this Promise with Success and Failure callbacks.
The specified Success callback is called when this Promise is successfully resolved and the specified Failure callback is called when this Promise is resolved with a failure.
This method returns a new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success or Failure callback is executed. The result of the executed callback must be used to resolve the returned Promise. Multiple calls to this method can be used to create a chain of promises which are resolved in sequence.
If this Promise is successfully resolved, the Success callback is executed and the result Promise, if any, or thrown exception is used to resolve the returned Promise from this method. If this Promise is resolved with a failure, the Failure callback is executed and the returned Promise from this method is failed.
This method may be called at any time including before and after this Promise has been resolved.
Resolving this Promise happens-before any registered callback is
called. That is, in a registered callback, isDone() must return
true
and getValue() and getFailure() must not
block.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.
A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success or Failure callback, if any, is executed.
<R>
The value type associated with the returned Promise.
The Success callback to be called when this Promise is
successfully resolved. May be null
if no Success
callback is required. In this case, the returned Promise must
be resolved with the value null
when this Promise is
successfully resolved.
Chain a new Promise to this Promise with a Success callback.
This method performs the same function as calling
then(Success, Failure) with the specified Success callback and
null
for the Failure callback.
A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success, if any, is executed.
The Consumer callback that receives the value of this
Promise. Must not be null
.
Chain a new Promise to this Promise with a Consumer callback that receives the value of this Promise when it is successfully resolved.
The specified Consumer is called when this Promise is resolved successfully.
This method returns a new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified callback is executed. If the callback throws an exception, the returned Promise is failed with that exception. Otherwise the returned Promise is resolved with the success value from this Promise.
This method may be called at any time including before and after this Promise has been resolved.
Resolving this Promise happens-before any registered callback is
called. That is, in a registered callback, isDone() must return
true
and getValue() and getFailure() must not
block.
A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.
A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Consumer is executed.
1.1
The time to wait in milliseconds. Zero and negative time is treated as an immediate timeout.
Time out the resolution of this Promise.
If this Promise is successfully resolved before the timeout, the returned Promise is resolved with the value of this Promise. If this Promise is resolved with a failure before the timeout, the returned Promise is resolved with the failure of this Promise. If the timeout is reached before this Promise is resolved, the returned Promise is failed with a TimeoutException.
A Promise that is resolved when either this Promise is resolved or the specified timeout is reached.
1.1
Promise factory to create Deferred and Promise objects.
Instances of this class can be used to create Deferred and Promise objects which use the executors used to construct this object for any callback or scheduled operation execution.
1.1
Immutable
The executor to use for callbacks. null
can be specified for the default callback executor.
Create a new PromiseFactory with the specified callback executor.
The default scheduled executor and default options will be used.
The executor to use for callbacks. null
can be specified for the default callback executor.
The scheduled executor for use for scheduled
operations. null
can be specified for the default
scheduled executor.
Create a new PromiseFactory with the specified callback executor and specified scheduled executor.
The default options will be used.
The executor to use for callbacks. null
can be specified for the default callback executor.
The scheduled executor for use for scheduled
operations. null
can be specified for the default
scheduled executor.
Options for PromiseFactory.
Create a new PromiseFactory with the specified callback executor, specified scheduled executor, and specified options.
1.2
<T, S extends T>
The value type of the List value associated with the returned Promise.
The value type of the specified Promises.
The Promises which must be resolved before the returned
Promise must be resolved. Must not be null
and all of
the elements in the collection must not be null
.
Returns a new Promise that is a latch on the resolution of the specified Promises.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
The returned Promise acts as a gate and must be resolved after all of the specified Promises are resolved.
A Promise that must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.
<T>
The value type associated with the returned Deferred.
Create a new Deferred with the callback executor and scheduled executor of this PromiseFactory object.
Use this method instead of Deferred.Deferred() to create a new Deferred whose associated Promise uses executors other than the default executors.
A new Deferred with the callback and scheduled executors of this PromiseFactory object
Returns the executor to use for callbacks.
The executor to use for callbacks. This will be the default
callback executor if null
was specified for the callback
executor when this PromiseFactory was created.
<T>
The value type associated with the returned Promise.
The failure of the resolved Promise. Must not be
null
.
Returns a new Promise that has been resolved with the specified failure.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
Use this method instead of Promises.failed(Throwable) to create a Promise which uses executors other than the default executors.
A new Promise that has been resolved with the specified failure.
Returns an Executor implementation that executes tasks immediately on the
thread calling the Executor.execute
method.
An Executor implementation that executes tasks immediately on the
thread calling the Executor.execute
method.
<T>
The value type associated with the returned Promise.
The value of the resolved Promise.
Returns a new Promise that has been resolved with the specified value.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
Use this method instead of Promises.resolved(Object) to create a Promise which uses executors other than the default executors.
A new Promise that has been resolved with the specified value.
<T>
The value type associated with the returned Promise.
A CompletionStage whose result will be used to resolve the
returned Promise. Must not be null
.
Returns a new Promise that will be resolved with the result of the specified CompletionStage.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
If the specified CompletionStage is completed normally, the returned Promise is resolved with the value of the specified CompletionStage. If the specified CompletionStage is completed exceptionally, the returned Promise is resolved with the exception of the specified CompletionStage.
After the returned Promise is resolved with the specified CompletionStage, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the returned Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
A new Promise that will be resolved with the result of the specified CompletionStage.
1.2
<T>
The value type associated with the returned Promise.
A Promise whose value or failure must be used to resolve the
returned Promise. Must not be null
.
Returns a new Promise that will be resolved with the specified Promise.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
If the specified Promise is successfully resolved, the returned Promise is resolved with the value of the specified Promise. If the specified Promise is resolved with a failure, the returned Promise is resolved with the failure of the specified Promise.
After the returned Promise is resolved with the specified Promise, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.
Resolving the returned Promise happens-before any registered
callback is called. That is, in a registered callback,
Promise.isDone() must return true
and
Promise.getValue() and Promise.getFailure() must not
block.
A new Promise that is resolved with the specified Promise.
1.2
Returns the scheduled executor to use for scheduled operations.
The scheduled executor to use for scheduled operations. This will
be the default scheduled executor if null
was specified
for the scheduled executor when this PromiseFactory was created.
<T>
The value type associated with the returned Promise.
The task whose result will be available from the returned Promise.
Returns a new Promise that will hold the result of the specified task.
The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.
The specified task will be executed on the callback executor.
A new Promise that will hold the result of the specified task.
<T, S extends T>
The value type of the List value result of the collected all(Collection) Promise.
The value type of the input Promises.
Returns a Collector
that accumulates the results of the input
Promises into a new all(Collection) Promise.
A Collector
which accumulates the results of all the
input Promises into a new all(Collection) Promise.
1.2
Defines the options for a Promise factory.
The default options are no options unless the boolean system property
org.osgi.util.promise.allowCurrentThread
is set to false
.
When this is the case, the option Option.CALLBACKS_EXECUTOR_THREAD
is a default option.
1.2
Run callbacks on an executor thread. If this option is not set, callbacks added to a resolved Promise may be immediately called on the caller's thread to avoid a thread context switch.
Static helper methods for Promises.
These methods return Promises which use the default callback executor and default scheduled executor. See PromiseFactory for similar methods which use executors other than the default executors.
Thread-safe
<T, S extends T>
The value type of the List value associated with the returned Promise.
A subtype of the value type of the List value associated with the returned Promise.
The Promises which must be resolved before the returned
Promise must be resolved. Must not be null
and all of
the elements in the collection must not be null
.
Returns a new Promise that is a latch on the resolution of the specified Promises.
The returned Promise acts as a gate and must be resolved after all of the specified Promises are resolved.
A Promise which uses the default callback executor and default scheduled executor that is resolved only when all the specified Promises are resolved. The returned Promise must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.
<T>
The value type associated with the specified Promises.
The Promises which must be resolved before the returned
Promise must be resolved. Must not be null
and all of
the arguments must not be null
.
Returns a new Promise that is a latch on the resolution of the specified Promises.
The new Promise acts as a gate and must be resolved after all of the specified Promises are resolved.
A Promise which uses the default callback executor and scheduled executor that is resolved only when all the specified Promises are resolved. The returned Promise must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.
<T>
The value type associated with the returned Promise.
The failure of the resolved Promise. Must not be
null
.
Returns a new Promise that has been resolved with the specified failure.
A new Promise which uses the default callback executor and default scheduled executor that has been resolved with the specified failure.
<T>
The value type associated with the returned Promise.
The value of the resolved Promise.
Returns a new Promise that has been resolved with the specified value.
A new Promise which uses the default callback executor and default scheduled executor that has been resolved with the specified value.
The value type of the resolved Promise passed as input to this callback.
The value type of the returned Promise from this callback.
Success callback for a Promise.
A Success callback is registered with a Promise using the Promise.then(Success) method and is called if the Promise is resolved successfully.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
Thread-safe
The successfully resolved Promise.
Success callback for a Promise.
This method is called if the Promise with which it is registered resolves successfully.
In the remainder of this description we will refer to the Promise returned by this method as the returned Promise and the Promise returned by Promise.then(Success) when this Success callback was registered as the chained Promise.
If the returned Promise is null
then the chained Promise must
resolve immediately with a successful value of null
. If the
returned Promise is not null
then the chained Promise must be
resolved when the returned Promise is resolved.
The Promise to use to resolve the chained Promise, or
null
if the chained Promise is to be resolved immediately
with the value null
.
Exception
– The chained Promise must be failed with the thrown
exception.
Function Package Version 1.2.
Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest.
Example import for consumers using the API in this package:
Import-Package: org.osgi.util.function; version="[1.2,2.0)"
Example import for providers implementing the API in this package:
Import-Package: org.osgi.util.function; version="[1.2,1.3)"
The type of the function input.
A function that accepts a single argument and produces no result.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
1.1
Thread-safe
The input to this function.
Applies this function to the specified argument.
Exception
– An exception thrown by the method.
The Consumer
to be called after this
Consumer
is called. Must not be null
.
Compose the specified Consumer
to be called after this
Consumer
.
A Consumer
composed of this Consumer
and the
specified Consumer
.
<T>
The type of the function input.
The java.util.function.Consumer
to wrap. Must not
be null
.
Returns a Consumer
which wraps a
java.util.function.Consumer
.
A Consumer
which wraps the specified
java.util.function.Consumer
.
<T>
The type of the function input.
The Consumer
to wrap. Must not be null
.
Returns a java.util.function.Consumer
which wraps the specified
Consumer
and throws any thrown exceptions.
The returned java.util.function.Consumer
will throw any exception
thrown by the wrapped Consumer
.
A java.util.function.Consumer
which wraps the specified
Consumer
.
<T>
The type of the function input.
The Consumer
to wrap. Must not be null
.
Returns a java.util.function.Consumer
which wraps the specified
Consumer
and discards any thrown Exception
s.
The returned java.util.function.Consumer
will discard any
Exception
thrown by the wrapped Consumer
.
A java.util.function.Consumer
which wraps the specified
Consumer
.
The type of the function input.
The type of the function output.
A function that accepts a single argument and produces a result.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
Thread-safe
<S>
The type of the value supplied by the specified
Function
.
The Function
to be called on the value returned by
this Function
. Must not be null
.
Compose the specified Function
to be called on the value returned
by this Function
.
A Function
composed of this Function
and the
specified Function
.
The input to this function.
Applies this function to the specified argument.
The output of this function.
Exception
– An exception thrown by the method.
<T, R>
The type of the function input.
The type of the function output.
The java.util.function.Function
to wrap. Must not
be null
.
Returns a Function
which wraps the specified
java.util.function.Function
.
A Function
which wraps the specified
java.util.function.Function
.
<T, R>
The type of the function input.
The type of the function output.
The Function
to wrap. Must not be null
.
Returns a java.util.function.Function
which wraps the specified
Function
and throws any thrown exceptions.
The returned java.util.function.Function
will throw any exception
thrown by the wrapped Function
.
A java.util.function.Function
which wraps the specified
Function
.
<T, R>
The type of the function input.
The type of the function output.
The Function
to wrap. Must not be null
.
The value to return if the specified Function
throws an Exception
.
Returns a java.util.function.Function
which wraps the specified
Function
and the specified value.
If the the specified Function
throws an Exception
, the
the specified value is returned.
A java.util.function.Function
which wraps the specified
Function
and the specified value.
<T, R>
The type of the function input.
The type of the function output.
The Function
to wrap. Must not be null
.
The java.util.function.Supplier
to call for a
return value if the specified Function
throws an
Exception
.
Returns a java.util.function.Function
which wraps the specified
Function
and the specified java.util.function.Supplier
.
If the the specified Function
throws an Exception
, the
value returned by the specified java.util.function.Supplier
is
returned.
A java.util.function.Function
which wraps the specified
Function
and the specified
java.util.function.Supplier
.
<S>
The type of the value consumed the specified Function
.
The Function
to be called to supply a value to be
consumed by this Function
. Must not be null
.
Compose the specified Function
to be called to supply a value to
be consumed by this Function
.
A Function
composed of this Function
and the
specified Function
.
The type of the predicate input.
A predicate that accepts a single argument and produces a boolean result.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
Thread-safe
The Predicate
to be called after this
Predicate
is called. Must not be null
.
Compose this Predicate
logical-AND the specified
Predicate
.
Short-circuiting is used, so the specified Predicate
is not
called if this Predicate
returns false
.
A Predicate
composed of this Predicate
and the
specified Predicate
using logical-AND.
<T>
The type of the predicate input.
The Predicate
to wrap. Must not be null
.
Returns a java.util.function.Predicate
which wraps the specified
Predicate
and throws any thrown exceptions.
The returned java.util.function.Predicate
will throw any
exception thrown by the wrapped Predicate
.
A java.util.function.Predicate
which wraps the specified
Predicate
.
<T>
The type of the predicate input.
The Predicate
to wrap. Must not be null
.
The value to return if the specified Predicate
throws an Exception
.
Returns a java.util.function.Predicate
which wraps the specified
Predicate
and the specified value.
If the the specified Predicate
throws an Exception
, the
the specified value is returned.
A java.util.function.Predicate
which wraps the specified
Predicate
and the specified value.
<T>
The type of the predicate input.
The Predicate
to wrap. Must not be null
.
The java.util.function.BooleanSupplier
to call
for a return value if the specified Predicate
throws
an Exception
.
Returns a java.util.function.Predicate
which wraps the specified
Predicate
and the specified
java.util.function.BooleanSupplier
.
If the the specified Predicate
throws an Exception
, the
value returned by the specified
java.util.function.BooleanSupplier
is returned.
A java.util.function.Predicate
which wraps the specified
Predicate
and the specified
java.util.function.BooleanSupplier
.
<T>
The type of the predicate input.
The java.util.function.Predicate
to wrap. Must not
be null
.
Returns a Predicate
which wraps the specified
java.util.function.Predicate
.
A Predicate
which wraps the specified
java.util.function.Predicate
.
Return a Predicate
which is the negation of this
Predicate
.
A Predicate
which is the negation of this
Predicate
.
The Predicate
to be called after this Predicate
is called. Must not be null
.
Compose this Predicate
logical-OR the specified
Predicate
.
Short-circuiting is used, so the specified Predicate
is not
called if this Predicate
returns true
.
A Predicate
composed of this Predicate
and the
specified Predicate
using logical-OR.
The type of the function output.
A function that produces a result.
This is a functional interface and can be used as the assignment target for a lambda expression or method reference.
Thread-safe
<T>
The type of the function output.
The Supplier
to wrap. Must not be null
.
Returns a java.util.function.Supplier
which wraps the specified
Supplier
and throws any thrown exceptions.
The returned java.util.function.Supplier
will throw any exception
thrown by the wrapped Supplier
.
A java.util.function.Supplier
which wraps the specified
Supplier
.
<T>
The type of the function output.
The Supplier
to wrap. Must not be null
.
The value to return if the specified Supplier
throws an Exception
.
Returns a java.util.function.Supplier
which wraps the specified
Supplier
and the specified value.
If the the specified Supplier
throws an Exception
, the
the specified value is returned.
A java.util.function.Supplier
which wraps the specified
Supplier
and the specified value.
<T>
The type of the function output.
The Supplier
to wrap. Must not be null
.
The java.util.function.Supplier
to call for a
return value if the specified Supplier
throws an
Exception
.
Returns a java.util.function.Supplier
which wraps the specified
Supplier
and the specified java.util.function.Supplier
.
If the the specified Supplier
throws an Exception
, the
value returned by the specified java.util.function.Supplier
is
returned.
A java.util.function.Supplier
which wraps the specified
Supplier
and the specified
java.util.function.Supplier
.
<T>
The type of the function output.
The java.util.function.Supplier
to wrap. Must not
be null
.
Returns a Supplier
which wraps the specified
java.util.function.Supplier
.
A Supplier
which wraps the specified
java.util.Supplier.Function
.
[1]JavaScript Promiseshttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[2]JavaScript Promiseshttps://web.dev/promises/
[3]ECMAScript® 2022 Language Specificationhttps://tc39.es/ecma262/#sec-promise-objects
[5]Function Interfaceshttps://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8
-
Added support for resolving a Promise with a CompletionStage, resolvedWith(CompletionStage) and resolveWith(CompletionStage), and creating a CompletionStage resolved by a Promise, toCompletionStage().
-
The PromiseFactory class has a new constructor, PromiseFactory(Executor,ScheduledExecutorService,Option...), which allows the caller to specify PromiseFactory.Options. The option CALLBACKS_EXECUTOR_THREAD specifies to run callbacks on an executor thread. If this option is not set, callbacks added to a resolved promise may be immediately called on the caller's thread to avoid a thread context switch.
-
Added the resolvedWith(Promise) method which can be used to return a new Promise that will be resolved with a specified promise.
-
Added the toPromise() method which returns a
Collector
which can be used on aStream
of Promises to collect the results of the Promises into a latch using the all(Collection) method as the finisher. -
Updated org.osgi.util.function package to add Supplier interface as well as a number of static methods to support interoperation with the
java.util.function
equivalents.