javaee / json-processing-spec

Legacy JSON Processing spec. Please use the link below to find the current JSON P project
https://github.com/jakartaee/jsonp-api
Other
8 stars 3 forks source link

Support JSON queries using JDK's stream operations #68

Closed glassfishrobot closed 7 years ago

glassfishrobot commented 9 years ago

Currently, there is no standard on JSON queries. It is not our goal to propose any such standard. Rather, our goal is to encourage using JDK's stream operations for JSON queries, and to provide help to make it easier to write Java codes for the query, and to return JSON arrays or objects.

Consider the simple query: find the books titles whose price is greater $30, in sorted order. One can write now:

JsonArray books = ... ;
    JsonArray result = books.getValuesAs(JsonObject.class)
            .filter(b->b.getJsonNumber("price").doubleValue() > 30)
            .map(b->b.getString("title"))
            .sorted()
            .collect(Collector.of(
             Json::createArrayBuilder,
             JsonArrayBuilder::add,
             (b1, b2)->b1,
             JsonArrayBuilder::build));

Surely we can help to make this easier.

Affected Versions

[1.1]

glassfishrobot commented 9 years ago

Reported by kchung

glassfishrobot commented 9 years ago

kchung said: Checked in javax.json.stream.JsonCollectors.java that includes the following Collectors

  1. toJsonArray
  2. toJsonObject
  3. groupBy with a downstream Collector
  4. groupBy with JsonArray
glassfishrobot commented 7 years ago

kratz said: Collector downstream prototype in

public static Collector<JsonValue, Map<String, JsonArrayBuilder>, JsonObject> groupingBy(
    Function<JsonValue, String> classifier,
    Collector<JsonValue, JsonArrayBuilder, JsonArray> downstream
)

seems to be too strict. I would prefer

Collector<JsonValue, ?, JsonArray> downstream

here or just some subset of JsonArrayBuilder interface with required methods only.

Why? Because when I was writting my own sample with JsonArray collector which sorts stream entries by some JsonObject attribute:

/** Builder to create sorted JsonArray with ordering by {@code "name"} attribute of {@code JsonObject}. */
    private class ValueBuilder implements JsonArrayBuilder {

        /** Sorted collection of values. */
        private final TreeSet<JsonValue> values;

        private ValueBuilder() {
            values = new TreeSet<>(
    (JsonValue v1, JsonValue v2) -> {
        if (v1.getValueType() == JsonValue.ValueType.OBJECT && v1.getValueType() == JsonValue.ValueType.OBJECT) {
            return v1.asJsonObject().getString("name").compareTo(v2.asJsonObject().getString("name"));
        }
        throw new IllegalStateException("Values must be JsonObject");
    }
            );
        }

        /**
         * Builder accumulator method.
         * @param value Value to be added to {@code JsonArray}.
         * @return This builder instance.
         */
        @Override
        public JsonArrayBuilder add(JsonValue value) {
            values.add(value);
            return this;
        }

        /**
         * Builder combiner method.
         * @param builder Builder containing values to be added to {@code JsonArray}.
         * @return This builder instance.
         */
        public ValueBuilder addAll(ValueBuilder builder) {
            values.addAll(builder.values);
            return this;
        }

        /**
         * Builder finisher method.
         * @return {@code JsonArray} from current builder content.
         */
        @Override
        public JsonArray build() {
            JsonArrayBuilder builder = Json.createArrayBuilder();
            for (JsonValue value : values) {
builder.add(value);
            }
            return builder.build();
        }

        @Override
        public JsonArrayBuilder add(String value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(BigDecimal value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(BigInteger value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(int value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(long value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(double value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(boolean value) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder addNull() {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(JsonObjectBuilder builder) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public JsonArrayBuilder add(JsonArrayBuilder builder) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

    }

I had to implement full JsonArrayBuilder interface because of this but for my use-case

Collector<JsonValue,JsonArrayBuilder,JsonArray> toArray = Collector.of(
ValueBuilder::new, JsonArrayBuilder::add, JsonArrayBuilder::addAll, JsonArrayBuilder::build
        );

only three methods from this interface are required.

glassfishrobot commented 7 years ago

@lukasj said: https://java.net/projects/jsonp/sources/git/revision/7a40191

glassfishrobot commented 9 years ago

Issue-Links: blocks JSON_PROCESSING_SPEC-66

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA JSON_PROCESSING_SPEC-68

glassfishrobot commented 7 years ago

Marked as fixed on Thursday, March 9th 2017, 9:12:13 am