View Javadoc
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              // skip array start
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  }