
io.baratine.service.Result Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of api Show documentation
Show all versions of api Show documentation
A reactive Java web server.
The newest version!
/*
* Copyright (c) 1998-2015 Caucho Technology -- all rights reserved
*
* This file is part of Baratine(TM)(TM)
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Baratine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Baratine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Baratine; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package io.baratine.service;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import io.baratine.function.TriConsumer;
import io.baratine.service.ResultImpl.AdapterMake;
import io.baratine.service.ResultImpl.ResultJoinBuilder;
/**
* Result is a continuation callback for async service calls with a primary
* result filled by * ok(value)
oran exception return filled by
* fail(exception)
*
* Since Result is designed as a lambda @FunctionalInterface interface,
* clients can use simple lambda expressions to process the results.
*
* For services that call other services, Results can be chained to simplify
* return value processing.
*
*
* Sample client usage:
*
* Services services = Services.newManager().get();
*
* MyService service = manager.service(new MyServiceImpl())
* .as(MyService.class);
*
* // JDK8 lambda for handle callback
* service.hello((x,e)->System.out.println("Result: " + x));
*
* // JDK8 lambda with builder
* service.hello(Result.onFail(e->System.out.println("Exception: " + e))
* .onOk(x->System.out.println("Result: " + x));
* // Explicit result
* service.hello(new MyHelloResult());
*
* // result chaining with function
* service.hello(result.then(x->"[" + x + "]"));
*
* // result chaining with consumer
* service.hello(result.then((x,r)->r.ok("[" + x + "]")));
*
* // result fork/join
* Result.Fork<String,String> fork = result.fork();
* service1.hello(fork.branch());
* service2.hello(fork.branch());
* fork.onFail((x,e,r)->r.ok("fork-fail: " + x + " " + e));
* fork.join((x,r)->r.ok("fork-result: " + x));
* ...
* public class MyResultHandler implements Result<MyDomainObject> {
* ...
* @Override
* public void handle(MyDomainObject value, Throwable exn)
{
if (exn != null) {
exn.printStackTrace();
return;
}
* map.put(value.name, value.value);
*
* store.add(value);
* }
*
*
* Sample service usage:
*
* void hello(Result<String> result)
* {
* result.ok("Hello, world");
* }
*
*
* Chaining:
*
* void doRouter(Result<String> result)
* {
* HelloService hello = ...;
*
* hello.hello(result.then(x->"Hello: " + x));
* }
*
*
*/
@FunctionalInterface
public interface Result extends ResultChain
{
/**
* Client handler for result values. The result will either contain
* a value or a failure exception, but not both.
*
* The service will call ok
or fail
. The client
* will receive a handle callback.
*
* Service:
*
* void hello(Result<String> result)
* {
* result.ok("Hello, world");
* }
*
*
* Client:
*
* hello.hello((x,e)->System.out.println("Hello: " + x + " " + e));
*
*
* @param value the result value
* @param fail the result failure exception
*/
void handle(T value, Throwable fail)
throws Exception;
/**
* Completes the Result with its value. Services call complete to finish
* the response.
*
* Service:
*
* void hello(Result<String> result)
* {
* result.ok("Hello, world");
* }
*
*
* Client:
*
* hello.hello((x,e)->System.out.println("Hello: " + x));
*
*
* @param result the result value
*/
@Override
default void ok(T result)
{
try {
handle(result, null);
} catch (Exception e) {
fail(e);
}
}
/**
* Fails the Result with an exception. The exception will be passed to
* the calling client.
*
* @param exn the exception
*/
@Override
default void fail(Throwable exn)
{
try {
handle(null, exn);
} catch (Exception e) {
throw new ServiceExceptionExecution(e);
}
}
/**
* Returns a copied transfer object based on the value.
*
* Shim preserves encapsulation by isolating service objects from
* the outside callers.
*/
default void okShim(Object value)
{
throw new UnsupportedOperationException(getClass().getName());
}
/**
* Create an empty Result that ignores the ok
.
*/
static Result ignore()
{
return ResultImpl.Ignore.create();
}
/**
* Creates a chained result for calling an internal
* service from another service. The lambda expression will complete
* the original result.
*
*
* void myMiddle(Result<String> result)
* {
* MyLeafService leaf = ...;
*
* leaf.myLeaf(result.then((v,r)->r.ok("Leaf: " + v)));
* }
*
*/
default Result then(BiConsumer> consumer)
{
return ResultChain.then(this, consumer);
}
/**
* Creates a Result as a pair of lambda consumers, one to process normal
* results, and one to handle exceptions.
*
*
* hello.hello(Result.of(e->System.out.println("exception: " + e))
* .onOk(x->System.out.println("result: " + x));
*
*
*
* @param result a consumer to handle a normal result value.
* @param exn a consumer to handle an exception result
*
* @return the constructed Result
*/
static Result of(Consumer result, Consumer exn)
{
return new AdapterMake(result, exn);
}
static Result of(Consumer consumer)
{
Objects.requireNonNull(consumer);
return new ResultImpl.ResultBuilder<>(consumer, null);
}
interface Builder
{
Result onOk(Consumer consumer);
}
/**
*
* Result.Fork<String,String> fork = result.fork();
*
* service1.hello(fork.branch());
* service2.hello(fork.branch());
*
* fork.join(x->System.out.println("Fork: " + x));
*
*
* @return fork/join builder
*/
default Fork fork()
{
return new ResultJoinBuilder<>(this);
}
//
// internal methods for managing future results
//
public interface Fork
{
Result branch();
Fork fail(TriConsumer,List,Result> fails);
void join(Function,T> combiner);
void join(BiConsumer,Result> combiner);
}
abstract public static class Wrapper extends WrapperChain>
{
protected Wrapper(ResultChain delegate)
{
super(delegate);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy