1 package org.davidmoten.kool.json;
2
3 import java.io.IOException;
4 import java.io.UncheckedIOException;
5 import java.util.function.Supplier;
6
7 import org.davidmoten.kool.Stream;
8
9 import com.fasterxml.jackson.core.JsonParser;
10 import com.fasterxml.jackson.core.JsonToken;
11 import com.fasterxml.jackson.core.TreeNode;
12 import com.fasterxml.jackson.databind.JsonNode;
13 import com.fasterxml.jackson.databind.ObjectMapper;
14 import com.fasterxml.jackson.databind.node.ArrayNode;
15
16 public final class LazyArrayNode implements Supplier<ArrayNode> {
17
18 private final JsonParser parser;
19 private final ObjectMapper mapper;
20
21 LazyArrayNode(JsonParser parser, ObjectMapper mapper) {
22 this.parser = parser;
23 this.mapper = mapper;
24 }
25
26 @Override
27 public ArrayNode get() {
28 try {
29 return (ArrayNode) mapper.readTree(parser);
30 } catch (IOException e) {
31 throw new UncheckedIOException(e);
32 }
33 }
34
35 public Stream<JsonNode> values() {
36 return Stream.<JsonNode>defer(() ->
37 Stream.generate(emitter -> {
38 JsonToken token = parser.nextToken();
39 if (token.equals(JsonToken.END_ARRAY)) {
40 emitter.onComplete();
41 } else {
42 TreeNode v = mapper.readTree(parser);
43 emitter.onNext((JsonNode) v);
44 }
45 })).doOnDispose(() -> parser.close());
46 }
47
48 public <T> Stream<T> values(Class<T> cls) {
49 return Stream.<T>defer(() -> {
50
51 parser.nextToken();
52 return Stream.generate(emitter -> {
53 if (parser.isClosed()) {
54 emitter.onComplete();
55 } else {
56 T v = mapper.readValue(parser, cls);
57 if (v == null) {
58 emitter.onComplete();
59 } else {
60 emitter.onNext(v);
61 }
62 }
63 });
64 }).doOnDispose(() -> parser.close());
65 }
66
67 }