All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.caucho.v5.amp.stream.StreamBuilderImpl Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * Copyright (c) 1998-2015 Caucho Technology -- all rights reserved
 *
 * This file is part of Baratine(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 com.caucho.v5.amp.stream;

import io.baratine.function.BiConsumerAsync;
import io.baratine.function.BiConsumerSync;
import io.baratine.function.BiFunctionAsync;
import io.baratine.function.BiFunctionSync;
import io.baratine.function.BinaryOperatorAsync;
import io.baratine.function.BinaryOperatorSync;
import io.baratine.function.ConsumerAsync;
import io.baratine.function.ConsumerSync;
import io.baratine.function.FunctionAsync;
import io.baratine.function.FunctionSync;
import io.baratine.function.PredicateAsync;
import io.baratine.function.PredicateSync;
import io.baratine.function.SupplierSync;
import io.baratine.service.Cancel;
import io.baratine.service.Result;
import io.baratine.service.ServiceExceptionCancelled;
import io.baratine.service.ServiceRef;
import io.baratine.stream.ResultStream;
import io.baratine.stream.ResultStreamBuilderSync;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import com.caucho.v5.amp.ServiceRefAmp;
import com.caucho.v5.amp.message.HeadersNull;
import com.caucho.v5.amp.message.StreamCallMessage;
import com.caucho.v5.amp.spi.HeadersAmp;
import com.caucho.v5.amp.spi.OutboxAmp;
import com.caucho.v5.amp.stub.MethodAmp;

@SuppressWarnings("serial")
public class StreamBuilderImpl implements ResultStreamBuilderSync, Serializable
{
  private transient ServiceRefAmp _serviceRef;
  private transient MethodAmp _method;
  private Object[] _args;
  
  // private SupplierSync _init;
  
  // private StreamBuilderFilter _filter;
  
  // private Object _value;

  public StreamBuilderImpl(ServiceRefAmp serviceRef,
                           MethodAmp method, 
                           Object []args)
  {
    Objects.requireNonNull(serviceRef);
    Objects.requireNonNull(method);
    
    _serviceRef = serviceRef;
    _method = method;
    _args = args;
    
    // this(serviceRef, method, args, StreamBuilderFilter.identity());
  }

  /*
  private StreamBuilderImpl(ServiceRefAmp serviceRef,
                            MethodAmp method, 
                            Object []args,
                            StreamBuilderFilter filter)
  {
    Objects.requireNonNull(serviceRef);
    Objects.requireNonNull(method);
    Objects.requireNonNull(filter);
    
    _serviceRef = serviceRef;
    _method = method;
    _args = args;

    _filter = filter;
  }
  */

  private StreamBuilderImpl(StreamBuilderImpl next)
  {
    Objects.requireNonNull(next);
    
    _serviceRef = next._serviceRef;
    _method = next._method;
    _args = next._args;

    // _filter = StreamBuilderFilter.identity();
  }
  
  // 
  // builder
  //
  
  protected ResultStream build(ResultStream next)
  {
    return (ResultStream) next;
  }
  
  //
  // terminals
  //
  
  @Override
  public Cancel exec()
  {
    ResultStreamExecute resultStream = new ResultStreamExecute<>(Result.ignore());
    
    offer(resultStream);
    
    return resultStream;
  }
  
  @Override
  public void result(Result result)
  {
    ResultStream resultStream = new ResultStreamExecute(result);
    
    offer(resultStream);
    
    // return resultStream;
  }
  
  @Override
  public void to(ResultStream result)
  {
    Objects.requireNonNull(result);
    
    local().offer(result);
  }
  
  @Override
  public T result()
  {
    /*
    ResultFuture future = new ResultFuture<>();
    
    return _serviceRef.getManager().run(future, 60, TimeUnit.SECONDS, 
                                        ()->result(future));
                                        */
    //System.err.println("CURR: " + OutboxAmp.getCurrent());
    return _serviceRef.manager().run(60, TimeUnit.SECONDS, 
                                        r->result(r));
  }
  
  @Override
  public StreamBuilderImpl forEach(ConsumerSync consumer)
  {
    return new ForEachSync<>(this, consumer);
  }
  
  @Override
  public StreamBuilderImpl forEach(ConsumerAsync consumer)
  {
    return new ForEachAsync<>(this, consumer);
  }
  
  @Override
  public StreamBuilderImpl first()
  {
    return new First(this);
  }
  
  @Override
  public StreamBuilderImpl ignore()
  {
    return new Ignore(this);
  }
  
  //
  // reduce
  //

  /**
   * Reduce with a binary function
   * 
   * 
   * s = init;
   * s = op(s, t1);
   * s = op(s, t2);
   * result = s;
   * 
*/ @Override public StreamBuilderImpl reduce(T init, BinaryOperatorSync op) { return new ReduceOpInitSync<>(this, init, op); } /** * reduce((x,y)->op) with a sync binary function * *
   * s = t1;
   * s = op(s, t2);
   * s = op(s, t3);
   * result = s;
   * 
*/ @Override public StreamBuilderImpl reduce(BinaryOperatorSync op) { return new ReduceOpSync<>(this, op); } /** * Reduce with an accumulator and combiner */ @Override public StreamBuilderImpl reduce(R identity, BiFunctionSync accumulator, BinaryOperatorSync combiner) { return new ReduceAccumSync<>(this, identity, accumulator, combiner); } /** * Async Reduce with combiner */ /* @Override public StreamBuilderImpl reduce(R identity, BiFunctionAsync accumulator, BinaryOperatorAsync combiner) { return new ReduceAccumAsync<>(this, identity, accumulator, combiner); } */ @Override public StreamBuilderImpl collect(SupplierSync init, BiConsumerSync accum, BiConsumerSync combiner) { return new CollectSync<>(this, init, accum, combiner); } /* @Override public StreamBuilderImpl collect(SupplierSync init, BiConsumerAsync accum, BiConsumerAsync combiner) { return new CollectAsync<>(this, init, accum, combiner); } */ // // map // @Override public StreamBuilderImpl map(FunctionSync map) { return new MapSync(this, map); } @Override public StreamBuilderImpl map(FunctionAsync map) { return new MapAsync(this, map); } /** * chain(s->builder) - builds a ResultStream chain with custom builder */ @Override public StreamBuilderImpl custom(FunctionSync,ResultStream> builder) { return new Chain(this, builder); } /** * peek(consumer) - accepts a copy of the item and passes it on. */ @Override public StreamBuilderImpl peek(ConsumerSync consumer) { return new Peek(this, consumer); } /** * local() - switch to local (caller) methods from service (remote) methods. */ @Override public StreamBuilderImpl local() { return new Local(this); } /** * prefetch() - limit the flow prefetch credit */ // @Override public StreamBuilderImpl prefetch(int prefetch) { return new Prefetch(this, prefetch); } // // filter // /** * filter() sync */ @Override public StreamBuilderImpl filter(PredicateSync test) { return new FilterSync(this, test); } /** * filter() async */ @Override public StreamBuilderImpl filter(PredicateAsync test) { return new FilterAsync(this, test); } // // blocking versions // /** * reduce(init, (x,y)->op) sync */ /* @Override public T reduce(T init, BinaryOperatorSync op) { ResultFuture future = new ResultFuture<>(); return doFuture(future, ()->reduce(init, op, future)); } */ /* @Override public R collect(SupplierSync init, BiConsumerSync accum, BiConsumerSync combiner) { ResultFuture future = new ResultFuture<>(); return doFuture(future, ()->collect(init, accum, combiner, future)); } */ @Override public StreamBuilderImpl,U> iter() { return new Iter<>(this); /* ResultFuture> future = new ResultFuture<>(); ResultStreamIter resultIter = new ResultStreamIter<>(future); return doFuture(future, ()->offer(resultIter)); */ } @Override public StreamBuilderImpl,U> stream() { return new StreamFactory<>(this); /* ResultFuture> future = new ResultFuture<>(); ResultStreamIter resultIter = new ResultStreamIter<>(future); return doFuture(future, ()->offer(resultIter)); */ } /* @Override public V reduce(V identity, BiFunctionSync accumulator, BinaryOperatorSync combiner) { ResultFuture future = new ResultFuture<>(); return doFuture(future, ()->reduce(identity, accumulator, combiner, future)); } */ /* private R doFuture(ResultFuture future, Runnable task) { return _serviceRef.getManager().run(future, 60, TimeUnit.SECONDS, task); } */ /* private R doFuture(Consumer> task) { return _serviceRef.getManager().run(60, TimeUnit.SECONDS, task); } */ private void offer(ResultStream resultStream) { long expires = 600 * 1000L; try (OutboxAmp outbox = OutboxAmp.currentOrCreate(_serviceRef.manager())) { HeadersAmp headers = HeadersNull.NULL; ResultStream stream = build(resultStream); StreamCallMessage msg; msg = new StreamCallMessage(outbox, outbox.inbox(), headers, _serviceRef, _method, stream, expires, _args); long timeout = 10000; msg.offer(timeout); } } @Override public String toString() { return getClass().getSimpleName() + "[" + _method + "]"; } // // inner classes // abstract private static class Next extends StreamBuilderImpl { private StreamBuilderImpl _next; Next(StreamBuilderImpl next) { super(next); Objects.requireNonNull(next); _next = next; } protected StreamBuilderImpl getNext() { return _next; } } // // chain // /** * chain() builder */ private static class Chain extends Next { private FunctionSync,ResultStream> _builder; Chain(StreamBuilderImpl next, FunctionSync,ResultStream> builder) { super(next); Objects.requireNonNull(builder); _builder = builder; } @Override public ResultStream build(ResultStream result) { ResultStream chainResult = new ResultStreamChain<>(result, _builder); return getNext().build(chainResult); } } /** * chain() ResultStream */ private static class ResultStreamChain extends ResultStream.Wrapper { private ResultStream _prev; private FunctionSync,ResultStream> _builder; ResultStreamChain(ResultStream prev, FunctionSync,ResultStream> builder) { super(builder.apply((ResultStream) prev)); _prev = prev; _builder = builder; } @Override public void accept(T value) { next().accept(value); } @Override public ResultStream createJoin() { ResultStream reduce = _prev.createJoin(); return reduce; } @Override public ResultStream createFork(ResultStream resultReduce) { ResultStream prev = _prev.createFork(resultReduce); return new ResultStreamChain<>(prev, _builder); } } /** * peek() builder */ private static class Peek extends Next { private ConsumerSync _consumer; Peek(StreamBuilderImpl next, ConsumerSync consumer) { super(next); Objects.requireNonNull(consumer); _consumer = consumer; } @Override public ResultStream build(ResultStream result) { ResultStream peekResult = new ResultStreamPeek(result, _consumer); return getNext().build(peekResult); } } /** * peek() ResultStream */ private static class ResultStreamPeek extends ResultStreamServiceBase { private ConsumerSync _consumer; ResultStreamPeek(ResultStream next, ConsumerSync consumer) { super(next); _consumer = consumer; } @Override public void accept(T value) { _consumer.accept(value); next().accept(value); } @Override public ResultStream createMapSelf(ResultStream next) { return new ResultStreamPeek<>(next, _consumer); } } /** * filter() sync builder */ private static class FilterSync extends Next { private PredicateSync _test; FilterSync(StreamBuilderImpl next, PredicateSync test) { super(next); Objects.requireNonNull(test); _test = test; } @Override public ResultStream build(ResultStream result) { ResultStream filterResult = new ResultStreamFilterSync<>(result, _test); return getNext().build(filterResult); } } /** * filter() sync ResultStream */ private static class ResultStreamFilterSync extends ResultStreamServiceBase { private PredicateSync _test; ResultStreamFilterSync(ResultStream next, PredicateSync test) { super(next); _test = test; } @Override public void accept(T value) { if (_test.test(value)) { next().accept(value); } } @Override public ResultStream createMapSelf(ResultStream next) { return new ResultStreamFilterSync<>(next, _test); } } /** * filter() async builder */ private static class FilterAsync extends Next { private PredicateAsync _test; FilterAsync(StreamBuilderImpl next, PredicateAsync test) { super(next); Objects.requireNonNull(test); _test = test; } @Override public ResultStream build(ResultStream result) { ResultStream filterResult = new ResultStreamFilterAsync<>(result, _test); return getNext().build(filterResult); } } /** * filter() async ResultStream */ private static class ResultStreamFilterAsync extends ResultStreamServiceBaseAsync { private PredicateAsync _test; ResultStreamFilterAsync(ResultStream next, PredicateAsync test) { super(next); _test = test; } @Override public void accept(T value) { addPending(); _test.test(value, (x,e)->{ if (e != null) { next().fail(e); return; } if (Boolean.TRUE.equals(x)) { next().accept(value); } subPending(); }); } @Override public ResultStream createMapSelf(ResultStream next) { return new ResultStreamFilterAsync<>(next, _test); } } /** * map() sync builder */ private static class MapSync extends Next { private FunctionSync _map; MapSync(StreamBuilderImpl next, FunctionSync map) { super(next); Objects.requireNonNull(map); _map = map; } @Override public ResultStream build(ResultStream result) { ResultStream mapResult = new ResultStreamMapSync<>(result, _map); return getNext().build(mapResult); } } /** * map() sync ResultStream */ private static class ResultStreamMapSync extends ResultStreamServiceBase { private FunctionSync _map; ResultStreamMapSync(ResultStream next, FunctionSync map) { super(next); _map = map; } @Override public void accept(T value) { next().accept(_map.apply(value)); } @Override public ResultStream createMapSelf(ResultStream next) { return new ResultStreamMapSync<>(next, _map); } } /** * map() async builder */ private static class MapAsync extends Next { private FunctionAsync _map; MapAsync(StreamBuilderImpl next, FunctionAsync map) { super(next); Objects.requireNonNull(map); _map = map; } @Override public ResultStream build(ResultStream result) { ResultStream mapResult = new ResultStreamMapAsync<>(result, _map); return getNext().build(mapResult); } } /** * map() async ResultStream */ private static class ResultStreamMapAsync extends ResultStreamServiceBaseAsync { private FunctionAsync _map; ResultStreamMapAsync(ResultStream next, FunctionAsync test) { super(next); _map = test; } @Override public void accept(T value) { addPending(); _map.apply(value, Result.of(x->{ next().accept(x); subPending(); }, e->{ next().fail(e); subPending(); })); } @Override public ResultStream createMapSelf(ResultStream next) { return new ResultStreamMapAsync<>(next, _map); } } // // local() implementation classes // /** * local() StreamBuilder */ private static class Local extends Next { Local(StreamBuilderImpl next) { super(next); } @Override public ResultStream build(ResultStream result) { ResultStream chainResult = new ResultStreamLocal(result); return getNext().build(chainResult); } } /** * local() ResultStream */ private static class ResultStreamLocal extends ResultStream.Wrapper { ResultStreamLocal(ResultStream next) { super(next); } @Override public void accept(T value) { next().accept(value); } } // // first() implementation classes // /** * first() StreamBuilder */ private static class First extends Next { First(StreamBuilderImpl next) { super(next); } @Override public ResultStream build(ResultStream result) { ResultStream chainResult = new ResultStreamServiceFirst(result); return getNext().build(chainResult); } } // // ignore() implementation classes // /** * ignore() StreamBuilder */ private static class Ignore extends Next { Ignore(StreamBuilderImpl next) { super(next); } @Override public ResultStream build(ResultStream result) { ResultStream chainResult = new ResultStreamServiceIgnore(result); return getNext().build(chainResult); } } // // iter() implementation classes // /** * iter() StreamBuilder */ private static class Iter extends Next,T,U> { Iter(StreamBuilderImpl next) { super(next); } @Override public ResultStream build(ResultStream> result) { ResultStreamIter resultIter = new ResultStreamIter<>(result); return getNext().build(resultIter); } } // // stream() implementation classes // /** * stream() StreamBuilder */ private static class StreamFactory extends Next,T,U> { StreamFactory(StreamBuilderImpl next) { super(next); } @Override public ResultStream build(ResultStream> result) { ResultStreamJdkStream resultStream = new ResultStreamJdkStream<>(result); return getNext().build(resultStream); } } // // local() implementation classes /** * prefetch() StreamBuilder */ private static class Prefetch extends Next { private int _prefetch; Prefetch(StreamBuilderImpl next, int prefetch) { super(next); } @Override public ResultStream build(ResultStream result) { ResultStream prefetchResult = new ResultStreamServicePrefetch(result, _prefetch); return getNext().build(prefetchResult); } } /** * forEach() sync builder */ private static class ForEachSync extends Next { private ConsumerSync _consumer; ForEachSync(StreamBuilderImpl next, ConsumerSync consumer) { super(next); Objects.requireNonNull(consumer); _consumer = consumer; } @Override public ResultStream build(ResultStream result) { ResultStream forEachResult = new ResultStreamForEachSync<>(result, _consumer); return getNext().build(forEachResult); } } /** * forEach() async builder */ private static class ForEachAsync extends Next { private ConsumerAsync _consumer; ForEachAsync(StreamBuilderImpl next, ConsumerAsync consumer) { super(next); Objects.requireNonNull(consumer); _consumer = consumer; } @Override public ResultStream build(ResultStream result) { ResultStream forEachResult = new ResultStreamForEachAsync<>(result, _consumer); return getNext().build(forEachResult); } } /** * reduce(op) sync builder */ private static class ReduceOpSync extends Next { private BinaryOperatorSync _op; ReduceOpSync(StreamBuilderImpl next, BinaryOperatorSync op) { super(next); Objects.requireNonNull(op); _op = op; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunSync(result, _op); ResultStream resultAccum = new ResultStreamServiceFunSync(resultReduce, _op); return getNext().build(resultAccum); } } /** * reduce(op) async builder */ private static class ReduceOpAsync extends Next { private BinaryOperatorAsync _op; ReduceOpAsync(StreamBuilderImpl next, BinaryOperatorAsync op) { super(next); Objects.requireNonNull(op); _op = op; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunAsync(result, _op); ResultStream resultAccum = new ResultStreamServiceFunAsync(resultReduce, _op); return getNext().build(resultAccum); } } /** * reduce(op,init) sync builder */ private static class ReduceOpInitSync extends Next { private T _init; private BinaryOperatorSync _op; ReduceOpInitSync(StreamBuilderImpl next, T init, BinaryOperatorSync op) { super(next); _init = init; Objects.requireNonNull(op); _op = op; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunSync(result, _op); ResultStream resultAccum = new ResultStreamServiceFunInitSync(resultReduce, _init, _op); return getNext().build(resultAccum); } } /** * reduce(op,init) async builder */ private static class ReduceOpInitAsync extends Next { private T _init; private BinaryOperatorAsync _op; ReduceOpInitAsync(StreamBuilderImpl next, T init, BinaryOperatorAsync op) { super(next); _init = init; Objects.requireNonNull(op); _op = op; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunAsync(result, _op); ResultStream resultAccum = new ResultStreamServiceFunInitAsync(resultReduce, _init, _op); return getNext().build(resultAccum); } } /** * reduce(init,accum,op) sync builder */ private static class ReduceAccumSync extends Next { private R _init; private BiFunctionSync _accumulator; private BinaryOperatorSync _combiner; ReduceAccumSync(StreamBuilderImpl next, R init, BiFunctionSync accumulator, BinaryOperatorSync combiner) { super(next); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); _init = init; _accumulator = accumulator; _combiner = combiner; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunSync(result, _combiner); ResultStream resultAccum = new ResultStreamServiceFunInitSync(resultReduce, _init, _accumulator); return getNext().build(resultAccum); } } /** * reduce(init,accum,op) async builder */ private static class ReduceAccumAsync extends Next { private R _init; private BiFunctionAsync _accumulator; private BinaryOperatorAsync _combiner; ReduceAccumAsync(StreamBuilderImpl next, R init, BiFunctionAsync accumulator, BinaryOperatorAsync combiner) { super(next); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); _init = init; _accumulator = accumulator; _combiner = combiner; } @Override public ResultStream build(ResultStream result) { ResultStream resultReduce = new ResultStreamLocalFunAsync(result, _combiner); ResultStream resultAccum = new ResultStreamServiceFunInitAsync(resultReduce, _init, _accumulator); return getNext().build(resultAccum); } } /** * collect(init,accum,op) sync builder */ private static class CollectSync extends Next { private SupplierSync _init; private BiConsumerSync _accum; private BiConsumerSync _combiner; private CollectSync(StreamBuilderImpl next, SupplierSync init, BiConsumerSync accum, BiConsumerSync combiner) { super(next); Objects.requireNonNull(accum); Objects.requireNonNull(combiner); _init = init; _accum = accum; _combiner = combiner; } @Override public ResultStream build(ResultStream result) { ResultStreamLocalAccumSync reduce; reduce = new ResultStreamLocalAccumSync(result, _combiner, x->x); ResultStream resultAccum; resultAccum = new ResultStreamServiceAccumSync(reduce, _init, _accum); return getNext().build(resultAccum); } } /** * collect(init,accum,op) async builder */ private static class CollectAsync extends Next { private SupplierSync _init; private BiConsumerAsync _accum; private BiConsumerAsync _combiner; private CollectAsync(StreamBuilderImpl next, SupplierSync init, BiConsumerAsync accum, BiConsumerAsync combiner) { super(next); Objects.requireNonNull(accum); Objects.requireNonNull(combiner); _init = init; _accum = accum; _combiner = combiner; } @Override public ResultStream build(ResultStream result) { ResultStreamLocalAccumAsync reduce; reduce = new ResultStreamLocalAccumAsync(result, _combiner, x->x); ResultStream resultAccum; resultAccum = new ResultStreamServiceAccumAsync(reduce, _init, _accum); return getNext().build(resultAccum); } } static class ResultStreamExecute extends ResultStream.ResultWrapper implements Cancel { private boolean _isCancelled; private V _lastValue; ResultStreamExecute(Result result) { super(result); } @Override public void accept(V value) { _lastValue = value; } @Override public boolean isCancelled() { return _isCancelled; } @Override public void cancel() { _isCancelled = true; getNext().fail(new ServiceExceptionCancelled(getClass().getName())); } @Override public void ok() { _isCancelled = true; getNext().ok(_lastValue); } @Override public void fail(Throwable exn) { _isCancelled = true; getNext().fail(exn); } } private static class ResultStreamForEachSync extends ResultStream.Wrapper { private ConsumerSync _consumer; ResultStreamForEachSync(ResultStream result, ConsumerSync consumer) { super(result); _consumer = consumer; } @Override public void accept(V value) { _consumer.accept(value); } @Override public void ok() { super.ok(); } } private static class ResultStreamForEachAsync extends ResultStreamLocalBaseAsync { private ConsumerAsync _consumer; ResultStreamForEachAsync(ResultStream result, ConsumerAsync consumer) { super(result); _consumer = consumer; } @Override public void accept(V value) { addPending(); _consumer.accept(value, Result.of(x->{ subPending(); }, e->{ next().fail(e); subPending(); })); } } private static class ResultStreamIter extends ResultStream.Wrapper> { private ArrayList _list; ResultStreamIter(ResultStream> result) { super(result); } @Override public void start() { _list = new ArrayList(); } @Override public void accept(V value) { _list.add(value); } @Override public void ok() { next().accept(_list); next().ok(); } } private static class ResultStreamJdkStream extends ResultStream.Wrapper> { private ArrayList _list; ResultStreamJdkStream(ResultStream> result) { super(result); } @Override public void start() { _list = new ArrayList(); } @Override public void accept(V value) { _list.add(value); } @Override public void ok() { next().accept(_list.stream()); next().ok(); } } private static class ResultStreamAccumFun implements ResultStream { private ResultStream _result; private V _value; private BinaryOperatorSync _fun; ResultStreamAccumFun(ResultStream result, V initValue, BinaryOperatorSync fun) { _result = result; _value = initValue; _fun = fun; } @Override public boolean isFuture() { return _result.isFuture(); } @Override public void accept(V value) { _value = _fun.apply(_value, value); } @Override public void ok() { _result.ok(); } @Override public void fail(Throwable exn) { _result.fail(exn); } @Override public void handle(V value, Throwable exn, boolean ok) { if (ok) { ok(); } else if (exn != null) { fail(exn); } else { accept(value); } } @Override public ResultStream createJoin() { return _result.createJoin(); } @Override public ResultStream createFork(ResultStream resultReduce) { ResultStream result = _result.createFork(resultReduce); return new ResultStreamAccumFun(result, _value, _fun); } } }