1 package org.davidmoten.kool.internal.operators.stream;
2
3 import java.util.concurrent.Callable;
4
5 import org.davidmoten.kool.Stream;
6 import org.davidmoten.kool.StreamIterator;
7 import org.davidmoten.kool.internal.util.Exceptions;
8
9 import com.github.davidmoten.guavamini.Preconditions;
10
11 public final class SwitchOnEmpty<T> implements Stream<T> {
12
13 private final Stream<T> stream;
14 private Callable<? extends Stream<T>> factory;
15
16 public SwitchOnEmpty(Stream<T> stream, Callable<? extends Stream<T>> factory) {
17 this.stream = stream;
18 this.factory = factory;
19 }
20
21 @Override
22 public StreamIterator<T> iterator() {
23 return new StreamIterator<T>() {
24
25 StreamIterator<T> it = stream.iterator();
26
27 boolean checkedForEmpty;
28
29 @Override
30 public boolean hasNext() {
31 check();
32 return it.hasNext();
33 }
34
35 @Override
36 public T next() {
37 check();
38 return it.nextNullChecked();
39 }
40
41 @Override
42 public void dispose() {
43 if (it != null) {
44 it.dispose();
45 it = null;
46 }
47 }
48
49 private void check() {
50 if (!checkedForEmpty) {
51 checkedForEmpty = true;
52 if (!it.hasNext()) {
53 it.dispose();
54 try {
55 it = Preconditions.checkNotNull(factory.call().iterator());
56 } catch (Exception e) {
57 Exceptions.rethrow(e);
58 return;
59 }
60 }
61 }
62 }
63
64 };
65 }
66
67 }