I have a method like this:
private CompletionStage<Void> example(final Resource resource) {
return firstMatcher.match(resource)
.whenComplete((op, t) -> {
if (t != null || !op.isPresent()) {
LOGGER.debug("resource doesn't match");
}
})
.thenAccept(optMatch -> optMatch.ifPresent(match -> {
LOGGER.debug("resource matches");
// DONE
}));
// OR ELSE (Not sure how to chain this piece)
return secondMatcher.match(resource)
.whenComplete((op, t) -> {
if (t != null || !op.isPresent()) {
LOGGER.debug("resource doesn't match");
}
})
.thenAccept(optMatch -> optMatch.ifPresent(match -> {
LOGGER.debug("resource matches");
// DONE
}));
I would like to return a method that first matches my resource with the firstMatcher. If a match is found, it ends there. But if a match is not found, then it relies on the secondMatcher. Is it possible to chain this into a single method?
CodePudding user response:
You need something like this:
private CompletionStage<Void> example(final Resource resource) {
return firstMatcher
.match( resource )
.thenCompose( firstMatch -> {
if ( firstMatch.isPresent() ) {
LOGGER.debug( "resource matches first" );
return CompletableFuture.completedFuture( null );
}
LOGGER.debug("resource doesn't match first");
return secondMatcher
.match( resource )
.thenCompose( secondMatch -> {
if ( secondMatch.isPresent() ) {
LOGGER.debug( "resource matches second" );
return CompletableFuture.completedFuture( null );
}
LOGGER.debug("resource doesn't match second");
// I'm returning a failed CompletionStage
// but you can add a third matcher or return something else.
// It depends on your requirements
return CompletableFuture.failed(new MatchNotFoundException());
});
} );
}
Note that I've removed the whenComplete
because they make the example more verbose, but you can add them back if you need to.
A possible refactoring:
private CompletionStage<Void> example(final Resource resource) {
return matches( firstMatcher.match( resource ), () -> matches( secondMatcher.match( resource ), () -> CompletionStages.failedFuture( new MatchNotFoundException() ) ) );
}
private static CompletionStage<Void> matches(CompletionStage<Optional<Object>> matcher, Supplier<CompletionStage<Void>> alternative) {
return matcher
.thenCompose( opt -> {
if ( opt.isPresent() ) {
LOGGER.debug( "resource matches" );
return CompletableFuture.completedFuture( null );
}
return alternative.get();
} );
}