Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reading a json array directly to a Java stream #825

Open
SingingBush opened this issue May 16, 2022 · 1 comment
Open

Support reading a json array directly to a Java stream #825

SingingBush opened this issue May 16, 2022 · 1 comment

Comments

@SingingBush
Copy link
Contributor

Currently we have to get a collection then convert it to a stream:

final List<String> list = reader.read("$.store.book.[*].title", List.class);

final Stream<String> stream = list.stream();

it would be convenient to be able to do this directly:

final Stream<String> stream = reader.read("$.store.book.[*].title", Stream.class);
@SingingBush
Copy link
Contributor Author

The solution in pull #829 seems reasonable to cover this requirement in a way that can be done across the different providers. I had a look at changing the GsonMappingProvider to achieve it by adding a TypeAdapter to the Gson config. As json-path doesn't expose a way to add an adapter I had to change the line where it instantiates Gson (return new Gson();) to instead be

final GsonBuilder builder = new GsonBuilder();

builder.registerTypeHierarchyAdapter(Stream.class, new TypeAdapter<Stream>() {
    @Override
    public void write(JsonWriter out, Stream value) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Stream read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }

        final List list = new ArrayList();

        in.beginArray();
        while (in.hasNext()) {
            switch (in.peek()) {
                case STRING:
                    list.add(in.nextString());
                    break;
                case NUMBER:
                    list.add(in.nextDouble());
                    break;
                case BOOLEAN:
                    list.add(in.nextBoolean());
                    break;
                case NULL:
                    in.nextNull();
                    break;
            }
        }
        in.endArray();

        return list.stream();
    }
});

return builder.create();

but this is still rather limited and I've still not looked at doing the same for Jackson. I opened #931 as it'll make it easier for the end user to implement something like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant