[JSON_PROCESSING_SPEC-9] Adding methods to JsonParser to get objects Created: 14/Jun/12  Updated: 20/Sep/14

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Something like the following, that gives the objects from the parser

/**

  • getJsonValue(JsonObject.class) is valid in START_OBJECT state,
  • moves cursor to END_OBJECT
    *
  • getJsonValue(JsonArray.class) is valid in START_ARRAY state
  • moves cursor to END_ARRAY
    *
  • getJsonValue(JsonString.class) is valid in VALUE_STRING state
    *
  • getJsonValue(JsonNumber.class) is valid in VALUE_NUMBER state
    */
    public <T extends JsonValue> T getJsonValue(Class<T> clazz) { return null; }


 Comments   
Comment by kchung [ 20/Sep/14 ]

This issue, together with issue 29, would be useful for processing big JSON data. It is important to be able to load the JSON values are of interest and skip those that are not.

However, it is most likely that the criteria for getting or skipping JSON values lies within the values themselves. For instance, say we have an array of objects representing the contacts, and we are only interested in getting the contacts who are females that live in New York city. We'll need to process some parts of the object to determine if it should be loaded or skipped, and we cannot make that decision at the beginning of an object. How to factor that into the API is the challenge.





[JSON_PROCESSING_SPEC-62] Allow builder object to be reused for DRY creation of Json Created: 26/Aug/14  Updated: 02/Sep/14

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: tirams Assignee: jitu
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: builder, json

 Description   

The current builder object is not reusable once build() is called the map is cleared
Want to be able to do something like:

//a base builder
JsonObjectBuilder builder = Json.createObjectBuilder().
                            add("name", "Peter").
                            add("required", false).
                            add("unique", true);
boolean keepSettings = true;
JsonObject baseObj = builder.build(keepSettings);
//note: if you add a new keepSettings parameter to build method to optionally 
// retain the current elements in the current map we can we extend the base 
// properties and add some more to the internal map, keepSettings for build 
// tells it to not clear out the map (as it does now) so we can go on using the 
// same builder to construct with.

//now we can tweak the current builder by adding a new property or overriding one
builder.add("addedField", "extra");

// and make a object from the current base and tweaked map of prop/vals.
JsonObject builtOnObj = builder.build();

Current implementation doesn't allow for reuse of a built builder you'd have to create another object and copy / paste everything set that was set above

— OR —

Another option to implement this need would be to be able to construct a new builder by passing in an existing one so that the map values can be reused for example:

//start with a base object
JsonObjectBuilder baseBuilder = Json.createObjectBuilder().
                            add("name", "Peter").
                            add("required", false).
                            add("unique", true);

//pass the base object into the constructor of a new builder object 
JsonObjectBuilder specialBuilder = Json.createObjectBuilder(*baseBuilder*).
                           add("addedMember", "addtionInfoOnBase").
                           add("moreStuff", "alsoThis");

// again pass on the starting elements for the map of this builder
JsonObjectBuilder extraSpecialBuilder = Json.createObjectBuilder(specialBuilder).
                           add("supa", "awesome");

//then we can create the objects , without having to copy/paste all the prior settings
// for each ones builder
JsonObject baseObject = baseBuilder.build();
JsonObject specialObject = specialBuilder.build();
JsonObject extraSpecialObject  = extraSpecialBuilder.build();



 Comments   
Comment by kchung [ 02/Sep/14 ]

Thanks for the suggestion. However, I must say it does not agree with the basic builder pattern used by the current API. Extending the life span of a builder may lead to memory leaks, and sharing implementations in two builders may cause confusion.

Currently, there are some efforts to add editing operations (including appending to an array) to immutable JSON structures after they are built. The idea is similar to your 2nd suggesting. It goes like this.

  JsonArray orig = Json.createJsonArrayBuilder(). ... .build();
  // create a new builder based on the original array
  JsonArrayBuilder ab = Json.createJsonArrayBuilder(orig);
  // do some editing and get a new array
  JsonArray new = ab.add(...).build();

Of course the operations on ab are not restricted to append, but can include insert, replace, and remove.

Of course this change can only happen in the next release of the API, so nothing has been committed.





[JSON_PROCESSING_SPEC-63] Add support for non-blocking IO when reading and writing JSON Created: 28/Sep/14  Updated: 19/Feb/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Ed Burns Assignee: jitu
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Add support for non-blocking IO when reading and writing JSON.



 Comments   
Comment by salyh [ 19/Feb/15 ]

what about adding java.nio support to JSR 374?





[JSON_PROCESSING_SPEC-70] Add Support for processing big JSON data Created: 23/Apr/15  Updated: 23/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

For our purpose, big JSON data are those whose object model are too big to fit the available memory. Currently, most of JSONP API's (e.g. JsonArray) requires that whole JSON object model be in memory. The only available API for processing big JSON seems to be JsonParser, but that is too low level to be useful.

Since Java stream operations is a useful tool to use for querying, filtering and processing JSON data, we should explore ways for constructing streams from JsonParse events. Of course the objects in the stream should be high level enough to be useful, like elements of an array or object. Streams should also be implemented in such a way that only the elements that take part in the stream operations need to be in memory. For instance, those elements that are filtered out can be discarded.

Not sure at this stage if it's best to add API's to JsonParser to create stremas, or we'll need new classes/interfaces that works with JsonParser. In any case, we probably need to add some features in JsonParser (e.g. skip to the end of an array) that will be useful when processing big JSON.






[JSON_PROCESSING_SPEC-65] Support for RFC 7159 Created: 09/Dec/14  Updated: 20/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

RFC 7159 replaces RFC 4627 and is the current spec on JSON.

The most significant change is that a JSON text, the top level object in a JSON tree, can be any JSON value, and not restricted to a JSON object or array anymore. So we'll need to modify the JSON-P API accordingly.



 Comments   
Comment by kchung [ 18/Feb/15 ]

Serveral APIs need to be added or updated.

  1. Building object model.
    We use JsonArrayBuilder and JsonObjectBuilder to create a JSON array and a Json Object in memory. We need new API to create a JsonNumber or JsonString. The only way this can be done is to use the our factory class Json (which uses JsonProvider). Propose to add
    Json.createValue(String);
    Json.createValue(int);
    Json.createValue(double);
    etc
    
  2. JsonReader
    There is no API for reading a JSON string, Json number, TRUE, FALSE, or NULL as the top level object in a JSON text.
    The current JsonReader has three read methods:
    JsonArray readArray()
    JsonObject readObject()
    JsonStructure read()
    

    Ideally, read() should return a JsonValue instead of a JsonStructure. Unfortunately, we cannot change the API, so we'll add a

    JsonValue readValue()

    .

  3. JsonGenerator
    We can reuse the JsonGenerator#write methods that are used for writing a JSON value in an array to also writing a JSON value at the top level, but the javadocs need to be modified. For instance, the javadocs for the method
    JsonGenerator write(java.math.BigDecimal value)

    says

    Writes the specified value as a JSON number value within the current array context.

    and will be modified to say

    Writes the specified value as a JSON number value within the current array or root context
  4. JsonWriter
    JsonWriter has three write methods
    write(JsonStructure value)
    writeArray(JsonArray array)
    writerObject(JsonObject object)
    

    We can overload the first method with a

    write(JsonValue value)

    to write a JsonString, JsonNumber, TRUE, etc.

Comment by salyh [ 19/Feb/15 ]

There is also another minor change that maybe is relevant for the new spec:
"8.1 Implementations MUST NOT add a byte order mark", so at least we have to document this somewhere in the docs to make it clear to implementators

Comment by asotobu [ 20/Feb/15 ]

I have found this document that may be useful http://stamm-wilbrandt.de/en/blog/diff.rfc4627-rfc7159.txt

Comment by eugen.cepoi [ 22/Feb/15 ]

1 and 4 are related. You have to add those newInstance methods for JsonValues in order to be able to pass them in JsonWriter.write(value).
It just makes the end user write more code. The only direct advantage I see here is that it might be more symmetric with parsing...

About 2, having readJsonValue seems ok, but might be a bit confusing. Do you think it would be such a big deal breaking compatibility (as anyway we break java version compatibility with adding support for stream ops)? Plus I find this JsonStructure useless...lets just remove this interface and make JsonObject/Array impl. JsonValue.

JsonValue could have some methods to cast to sub types.

Comment by asotobu [ 22/Feb/15 ]

About second point I agree with Eugene. Maybe it would be better break compatibility and make JsonObject/Array implement JsonValue it seems a natural solution, but if we cannot break the compatibility then readJsonValue is not a bad solution at all.

Comment by kchung [ 23/Feb/15 ]

Yea, it is usually a big deal to break backward compatibility. We can deprecate features, but we must not break BC unless absolutely necessary. To me, allowing top level JSON be any value is not that important a feature (I wouldn't change the API to support it if it were not in the spec) and not worth breaking BC.

Requiring a newer Java version is not breaking BC, because old applications can still be compiled and run with newer Java. Every new EE usually requires a new SE version for it.

Yea, we should have methods in JsonValue for getting subtypes, as least for JsonArray and JsonObject. How about

  default JsonArray asJsonArray() {
      return JsonArray.class.cast(this);
  }
  default JsonObject asJsonObject() {
      return JsonObject.class.cast(this);
  }

? They need to be default methods because we cannot add new methods to the JsonValue interface without breaking BC. Another reason why we need JDK 8.

Comment by asotobu [ 23/Feb/15 ]

Let's do it as you mention and not breaking BC. Let's see how the overall API looks like and we can decide to change the approach and break BC lately. We always have time to break it.





[JSON_PROCESSING_SPEC-67] Add Edit/Transform operations to JsonObject and JsonArray Created: 18/Feb/15  Updated: 12/Mar/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In the current JSON object model, JsonArray and JsonObject are immutable. While the advantage of immutability is well-known, it is also sometimes restrictive.

I propose adding operations to transform an immutable JsonArray or JsonObject into another immutable JsonArray or JsonObject. I also propose using the builder pattern for doing the transform operations. We already have JsonArrayBuilder and JsonObjectBuilder, we just need to add new APIs. Here's my concrete proposal.

  1. Add Json.createArrayBuilder(JsonArray initArray) to create a JsonArrayBuilder with an initial JsonArray.
  2. Add JsonArrayBuilder.add(int i, JsonValue value) to insert a value at index i.
  3. Add JsonArrayBuilder.remove(int i) to remove value at index i.
  4. Add JsonArrayBuilder.set(int i) to replace the value at index i.
  5. The method JsonArrayBuilder.build() can be used to return an immtable transformed JsonArray

Similar APIs can to added to handle JsonObject transformations.



 Comments   
Comment by asotobu [ 19/Feb/15 ]

I think that these operations may be really useful in some areas where currently you need to deep copy the objects manually. But we must be aware of memory usage of these operations and we should warn the users.

For example calling Json.createArrayBuilder(JsonArray initArray) means that the array with all elements inside the array (sub-arrays, objects, ...) should be cloned as well to maintain the immutability. Obviously depending on the size of the document it could be a big usage of memory.

Also I will purpose add a method called deepCopy (or something like this) to JsonObject so every object is responsible to cloning himself.

Comment by salyh [ 19/Feb/15 ]

Maybe we can combine this with Json Pointer/Merge? I would like to see a solution where i can edit a hole json object/array graph in a handy way.
So i suggest something like a MutableJsonObject/MutableJsonArray (containing other MutableJsonObjects/MutableJsonArrays) where it it possible to append, set and remove elements (denoted by a Json path?) and then "build()" it to a immutable version. To do it only on the builder level does not really add any value cause you never had a chance to mutate a complete graph (if i understand it correctly). I know this has some disadvantages related to threading etc. but lets discuss it at least.

BTW: I think point 4. should be "Add JsonArrayBUILDER.set(int i) to replace the value at index i."

Comment by kchung [ 19/Feb/15 ]

Since the elements of an array are all immutable, I don't think we need to clone them in Json.createArrayBuilder(JsonArray initArray) and a shallow copy will suffice. The problem is with all of the references to this array: they must all be modified to refer to the new transformed array, which may triggers more transformations. An example would make this clear.

Supposed we have a JSON path "a/b/c/d" that refers to an array "d" in a JSON text. If "d" is transformed to "dt", then "c" also needs to be transformed to refer to "dt", and so on. Any transformation on an internal node in the JSON tree will require transformations on all its parent nodes. This is exactly what we'll need to do for JSON patch.

I don't see a need for a deepCopy inJsonObject or JsonArray, because they are already immutable. What's the use case for two identical immutable JSON objects? It might make sense if deepCopy returns a mutable copy, but currently there is no such thing in the API.

Obviously if the size of the array is huge, it'll take a lot of memory and these operations will roughly double the size (one for original, and another for the result). That is not so bad.

Comment by kchung [ 19/Feb/15 ]

@salyh: We'll have an API for the patch/merge, but I think it can build on these basic operations.

I've edited point 4 to fix the typo. Thanks.

Introducing MutableJsonArray and MutableJsonObject will open up a can of worms. Where do they fit in our class hierarchy? They cannot be derived from JsonStructure because JsonStructure is immutable. Also they cannot be passed to methods that expect the immutable versions as arguments, and the best we can do is to overload the method to take both. It gets messy pretty fast. I've thought about it before and didn't see any simple solution.

Comment by salyh [ 20/Feb/15 ]

Yeah, seems there is no simple solution here but on staying on the builder level is IMHO no "real mutability", but this might be a individual opinion only

Comment by eugen.cepoi [ 22/Feb/15 ]

The concrete proposal looks good to me, I was suggesting something similar in the first version of the jsr.

Even if I am usually proning immutability, I wonder if we should not consider making the dom structure mutable... I am asking my self this question for some time

Might be worth considering at least...

Comment by eugen.cepoi [ 22/Feb/15 ]

And JsonObject/Array already extend Map/List...who provide mutation methods.
Deep cloning could be an alternative. When someone wants an instance that is not mutated somewhere else, then he can clone it. And to prevent someone to mutate an instance when he shouldn't then we could use a flag propagated recursivelly in the children nodes that throws some exception when the methods are called (like now).

Comment by kchung [ 23/Feb/15 ]

I think we should at least do what I've proposed, since it is conceptually simple, and adds some new functionalities. We just need to be careful that it can be implemented and not too slow. We need to make sure that JSON patch can be implemented efficiently. This is approach A.

We can also explore if it is feasible to have deep copy operations that return mutable copies of JsonObject/Array. I am against having new classes/interface such as MutableJsonArray, but we can have the deep copy returns a Map or List. We just need operations to turn them back into immutable JsonArrar/Object. This is approach B.

Neither approach has an inherent advantage over the other. If the operations only touches a small portion of the JSON tree, then approach A would be faster. If there are lots of operations that touch a major portion of the JSON tree, then approach B may be faster.

I've did some work on approach A, so I can check in what I've done to let people play with it Anyone interested in investigating approach B?

Comment by salyh [ 24/Feb/15 ]

I can make a proposal for approach B.

But i am currently unsure where to put code proposal into? Seems there is currently no branch for JSONP 1.1 in jsonp git repo.
Can i push personal branches in there or do we submit patches?

Comment by salyh [ 24/Feb/15 ]

pushed to https://github.com/json-processing-inofficial/jsonp/commit/a3221bea7f6814c196164ae0242bae931f39501a

Comment by kchung [ 24/Feb/15 ]

@salyh Why is the deep copy defensive clones? I thought you only need to make defensive clones of mutable objects, and not immutable ones like we have here. And we are not making clones to be defensive, we do that so we can modify the JSON object model.

The name toMutableList is misleading. Does it return a mutable list that may contain, for instance, an immutable JsonObject ? I am sure you meant that what it return does not include anything (at least nothing from JSONP) immutable. It is not clear from the javadocs.

It also cannot be List<JsonValue>, because a JsonValue is immutable.

Comment by salyh [ 25/Feb/15 ]

you're right, "defensive" is superfluous here

With toMutableList()/toMutableMap() i meant the List/Map itself is mutable (so you can add, remove, ...) and the containing JsonValue objects are still immutable but can be "converted" to mutable by calling toMutableList()/toMutableMap() on them respectively. It really not ideal but without introducing new interfaces/classes the only other option i see to make toMutableList()/toMutableMap() return List<Object>/Map<String, Object> where Object is either a List<Object>, Map<String, Object>, Boolean, String, Number, null but thats also not really handy (and in addition we need to handle RFC 7159 as well)

Comment by kchung [ 26/Feb/15 ]

OK, but then you would doing pretty much approach A.

Approach A codes checked in branch editOps.

Comment by salyh [ 26/Feb/15 ]

exactly, and thats why i suggest to introduce new classes/interfaces, pls see mailinglist ...

Comment by kchung [ 27/Feb/15 ]

@salyh I thought you are proposing to do Approach B!

Comment by salyh [ 01/Mar/15 ]

Here are the (second) proposal for approach B with introducing one new interface javax/json/MutableJsonStructure.
It contains also a almost complete (but not performance optimized) implementation and test cases.
The proposal integrated with JSON pointer (i added a dummy class for this until JSON_PROCESSING_SPEC-60 is ready).
I have included a quick and dirty implementation of JSON patch (RFC 6902 variant) just to show how the proposal can be used to implement it.

https://github.com/json-processing-inofficial/jsonp/commit/33a9e5c10611c595fadb2eb606758bd1b318fe7c

The relevant API components are

  • new interface javax/json/MutableJsonStructure (with inner interface Ancestor)
  • new method added to javax/json/JsonStructure
  • dummy class javax/json/JsonPointer until JSON_PROCESSING_SPEC-60 is ready

Implementation:

  • org/glassfish/json/JsonPatcherImpl shows how MutableJsonStructure could be used to implement JSON patch
  • glassfish/json/AbstractMutableJsonStructure implements MutableJsonStructure
  • org/glassfish/json/AncestorImpl implements MutableJsonStructure.Ancestor
  • org/glassfish/json/GenericJsonValue helper
  • org/glassfish/json/JsonArrayBuilderImpl implements MutableJsonStructure
  • org/glassfish/json/JsonObjectBuilderImpl implements MutableJsonStructure

Unittests

  • org/glassfish/json/tests/MutableJsonStructureTest
  • Tests for JsonPatcherImpl not pushed because it uses third party tests (ASL2 license) and to be safe i will not check in this for now
Comment by keilw [ 12/Mar/15 ]

Would be great to actually link JSON_PROCESSING_SPEC-60 here as a blocker or related ticket. I can't do this, seems only the Spec Lead or maybe creator of the entry can do ;-|





[JSON_PROCESSING_SPEC-66] Umbrella feaature list Created: 13/Feb/15  Updated: 23/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: Task Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Tentative new features.

  1. Support rfc 7159.
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-65
  2. Support Json Pointer.
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-60
  3. Support Json Patch.
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-61
  4. Add Editing/Transformation operations to JsonArray and JsonObject
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-67
  5. Support queries on JSON, using JDK 8 streams.
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-68
  6. Support for processing big JSON, e.g. add filters to Json parsing.
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-70
  7. Utilities
    https://java.net/jira/browse/JSON_PROCESSING_SPEC-69


 Comments   
Comment by asotobu [ 18/Feb/15 ]

Point 5 it could be a bit problematic in the sense that if we decide to be only compatible to Java 8 and beyond then no problem, but this will exclude Java 7 users. Moreover now I am not aware if Java EE 8 will be only compatible with Java 8 and beyond or Java 7 will be supported as well.

Maybe I will add something related with Json Patch that is called Json Diff. This operation receive two json documents (or nodes), one origin and the other is the target and returns a Json Patch document with the changes that it should occurs to origin so it becomes a target node. This operation is really useful when you are in a high concurrent environment where it can be collisions because of concurrent modifications of same document and you want to expose the differences and give to the final user the choice to apply the whole change or not or choose individually which change to apply. Implementing this feature with Json Diff and Json Patch this is pretty simple.

There is no Json Diff rfc so we can implement the diff for Json Patch and for Json Merge.

Comment by kchung [ 18/Feb/15 ]

Java EE 8 will require Java SE 8. By the time this JSR is released (some time in 2016), SE 9 will be ready to go, and most user will be on SE 8. It does not make sense to not use Lambdas provided in SE 8, and I don't know of any better ways of doing JSON queries without using Lambdas.

Comment by eugen.cepoi [ 22/Feb/15 ]

2 and 5 have some points in common, in fact Json Pointer is a subset of querying a json document. Maybe json pointer could be a more high level layer using 5 and allowing people to mix both.

Comment by kchung [ 23/Feb/15 ]

@eugen, I have some specific ideas about 5, and is less ambitious. Let's come back to this later after we discuss Json pointer and queries.

Comment by salyh [ 24/Feb/15 ]

+1 for dropping Java 7 support (Java 7 EOPU is likely in two month, see http://www.oracle.com/technetwork/java/eol-135779.html)





[JSON_PROCESSING_SPEC-64] Implement visitor pattern for JSON traversal Created: 08/Oct/14  Updated: 20/Feb/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: salyh Assignee: jitu
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Implement visitor pattern for easier and more convenient JSON traversal/introspection

Here is a first sketch:

New method for JsonValue to make it visitable

public void accept(JsonValueVisitor visitor);

Give the json constants a type

package javax.json;

//tagging interface for null, true, false
public interface JsonConstant extends JsonValue{

}

And finally the visitor interface

package javax.json;

public interface JsonValueVisitor {

    public void visit(JsonArray array);
    public void visit(JsonObject object);
    public void visit(JsonNumber number);
    public void visit(JsonString string);
    public void visit(JsonConstant constant); //true, false, null

}


 Comments   
Comment by kchung [ 10/Oct/14 ]

I've actually implemented a Visitor for JSON. It is similar to what's proposed here. The main differences are:

  1. Mine has visitors for array elements and name/value pairs
  2. Minie has no need for a JsonConstant, since constants are part of the above

For future reference, here's what I have

Visitor.java
package javax.json;

import java.util.Map;

public class Visitor {

    public void visit(String key, JsonObject obj) {
        visit(obj);
    }

    public void visit(String key, JsonArray array) {
        visit(array);
    }

    public void visit(String key, String string) {
    }

    public void visit(String key, JsonNumber number) {
    }

    public void visit(String key, boolean test) {
    }

    public void visit(String key) {
    }

    public void visit(int i, JsonObject obj) {
        visit(obj);
    }

    public void visit(int i, JsonArray array) {
        visit(array);
    }

    public void visit(int i, String string) {
    }

    public void visit(int i, JsonNumber number) {
    }

    public void visit(int i, boolean test) {
    }

    public void visit(int i) {
    }


    public void visit(JsonObject object) {
        for (Map.Entry<String, JsonValue> entry: object.entrySet()) {
            String key = entry.getKey();
            JsonValue value = entry.getValue();
            switch (value.getValueType()) {
                case OBJECT:
                    visit(key, (JsonObject)value);
                    break;
                case ARRAY:
                    visit(key, (JsonArray)value);
                    break;
                case NUMBER:
                    visit(key, object.getJsonNumber(key));
                    break;
                case TRUE:
                case FALSE:
                    visit(key, object.getBoolean(key));
                    break;
                case STRING:
                    visit(key, object.getString(key));
                    break;
                case NULL:
                    visit(key);
                    break;
            }
        }
    }

    public void visit(JsonArray array) {
        for (int i = 0; i < array.size(); i++) {
            switch (array.get(i).getValueType()) {
                case OBJECT:
                    visit(i, array.getJsonObject(i));
                    break;
                case ARRAY:
                    visit(i, array.getJsonArray(i));
                    break;
                case NUMBER:
                    visit(i, array.getJsonNumber(i));
                    break;
                case TRUE:
                case FALSE:
                    visit(i, array.getBoolean(i));
                    break;
                case STRING:
                    visit(i, array.getString(i));
                    break;
                case NULL:
                    visit(i);
                    break;
             }
        }
    }
}
Comment by kchung [ 10/Oct/14 ]

However, I don't think visitors are useful. They are most useful in cases where context is not needed, like output the words in a dictionary, or compute the average age of all people. It becomes awkward when context is needed, like computing the average age of males who live in California. I have yet to come with an example where the use of visitors is compelling.

I think it would be more useful to look into using JDK's stream operations for JSON queries.

Comment by salyh [ 19/Feb/15 ]

Do we want to discuss JDK's streams within JSR 374?

Comment by kchung [ 20/Feb/15 ]

Yes, we'll look into applying JDK's streams on JSON objects. I'll open another jira to discuss it.





[JSON_PROCESSING_SPEC-68] Support JSON queries using JDK's stream operations Created: 06/Mar/15  Updated: 04/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

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.



 Comments   
Comment by kchung [ 04/Apr/15 ]

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




[JSON_PROCESSING_SPEC-69] Add ultility to construct JsonStructure from raw JSON string Created: 04/Apr/15  Updated: 06/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.1

Type: New Feature Priority: Major
Reporter: kchung Assignee: kchung
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, JsonArrayBuilder and JsonObjectBuilder can be used to create JSON object models from scratch. However, the process is cumbersome and verbose. There should be an easier way for doing this.

I am proposing something like the following:

JsonArray a = JsonUtil.getArray(
    "[{'abc': 'xyz', 'ss': 1234}, {'m\\'n': 'l\"m'}]");

Note that I'm using single quotes for JSON strings, otherwise I'll have lots of \" as required in Java. I am not proposing allowing single quotes for JSON string (which is not allowed in JSON) in general. This utility will need to convert ' to " before sending it to JsonReader.

Note also \ is used to allow ' or " inside the JSON string, but this is just some details that we should not worry for now.

Such utility will be very useful in writing JSON tests. But it should be useful to JSON users.



 Comments   
Comment by mitemitreski [ 04/Apr/15 ]

Single quotes are great idea but we need to make sure somehow that it is clear that this is intended as a helper only and not standards derailing.

Is JavaDoc enough for this ?

Comment by kchung [ 06/Apr/15 ]

We need to be clear that single quotes can only be used in this method. We'll have to do our best in the javadocs, since it the only thing we have for the spec.





[JSON_PROCESSING_SPEC-60] Support for JSON Pointer Created: 28/Oct/13  Updated: 28/Mar/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Consider adding support for JSON Pointer. The RFC is at http://tools.ietf.org/html/rfc6901



 Comments   
Comment by asotobu [ 18/Feb/15 ]

JSON Pointer is really a must for next release of JSR 374 because without them it is going to be pretty hard for example implementing JSON Patch feature. In fact because JSON Pointer is required for implementing Json Patch we should discuss this first.

I have collaborated with Jackson guys implementing Json Pointer support so it can be used in Json Patch implementation. Although now I am going to mention something of low level implementation I prefer to note now so I don't miss it later.

Json Pointer allows developers to get some part of a json document (something like x-path for xml). But you also need some operations to manage json pointers themselves. In this sense next management operations are required for json patch implementation.

  • last() -> Returns the leaf of current JSON Pointer expression. Leaf is the last non-null segment of current JSON Pointer.
  • tail() -> Accessor for getting a "sub-pointer", instance where current segment has been removed and pointer includes rest of segments. For matching state, will return null.
  • head() -> Accessor for getting a pointer instance that is identical to this instance except that the last segment has been dropped. For example, for JSON Point "/root/branch/leaf", this method would return pointer "/root/branch" (compared to tail() that would return "/branch/leaf").

Of course we would need other operations which will involve the json document and the json pointer, but last, tail and head are operations that only affects the json pointer expression.

Comment by kchung [ 21/Feb/15 ]

Let's up level the api design for Json Pointer a bit. There are a number of issues to consider.

  1. Should JsonPointer be an interface or a concrete class? I guess the answer depends on whether we need to create an instance of it from the factory (SPI), like how it is now for JsonParser etc. I think it would be simpler if we can just do a new JsonPointer("q/b/c/d") to create one.
  2. Since a Json Pointer refers to a Json Text, should the text be part of JsonPointer? If not, the text will need to be applied when we do operations with the pointer. In other words, which of the following two scenarios is better:
      JsonObject target = ... ; # the target Json text
      JsonPointer pointer = new JsonPointer("a/b/c/d");
      JsonValue value = pointer.get(target); # get the value referenced

    or

      JsonObject target = ...; # the target Json text
      JsonPointer pointer = new JsonPointer(target, "a/b/c/d");
      JsonValue value = pointer.get(); # get the value referenced

    One might argument the the first is better since the same pointer can be applied to other text. but I am not sure if that is useful in practice.

  3. What other operations can we do with a pointer? To support Json Patch, we should have at least the following:
    1. get the value at the reference location
    2. add a new value to the reference location
    3. remove the value at the reference location
    4. replace the value at the reference location with another value
Comment by asotobu [ 21/Feb/15 ]
  • Point 1) I think JsonPointer could be a concrete class, it is much simpler and I think JsonPointer is generic enough to be provided from spec.
  • Point 2) First approach feels more natural to me and less restrictive in the sense that if devs want they can reuse a JsonPointer object to be used on other json objects, as noted maybe it is not useful but if we use the second one then we are not giving this freedom to developers, so I vote for the first one approach.

Only to considerations. The first one is that I think it could be better to no offer the constructor to devs but an static method. I said this because there is some rules a json pointer should follow (for example it should start with a '/') and also the first thing to do in a JsonPointer is evaluating and decoding and escaped char. It may look strange to do all this kind of stuff in a contructor, so I think that an static method that uses at the end a protected constructor may be better.
something like:

JsonPointer.compile("/a/b/c");

and/or

JsonPointer.valueOf("/a/b/c");

And the second point is should be the operation of get/add/remove/... be a part of the JsonPointer or a part of JsonObject.


JsonObject target = ... ; # the target Json text
JsonPointer pointer = new JsonPointer("a/b/c/d");
JsonValue value = pointer.get(target); # get the value referenced


or


JsonObject node = ... ; # the target Json text
JsonPointer pointer = new JsonPointer("a/b/c/d");
JsonValue value = node.get(pointer); # get the value referenced


I think both are valid and I have used both approaches one in Jackson and another one in one project that implemented Json Pointer before it was done in Jackson. For me and it is something personal I feel more comfortable of having operations on node instead of pointer. node.get(pointer). But it is something personal.

Comment by eugen.cepoi [ 22/Feb/15 ]

About last/tail/head, I think the names might be confusing. Peoples are used to them in the context of collections.

1) I agree, I would prefer to see json pointer implemented in the spec.

2) I also prefer option 1, but would like to see shortcut methods on json value. So people can do stuff like
JsonObject person = ...
person.at("address/street").asString()

How do you plan to handle incomplete paths (when some element in the path matches a null object)?

3) In case of mutation, I guess it would return a new instance of the root object on which the operation was applied?
As for 2) would be nice to have shortcuts at node level.

Comment by asotobu [ 22/Feb/15 ]

Well yes about giving a shortcut to users so you can do something like:

person.at("")

About incomplete paths, the RFC mention that there is no "explicit" paths as described here.

Look section 3 of RFC:

The ABNF syntax of a JSON Pointer is:

      json-pointer    = *( "/" reference-token )
      reference-token = *( unescaped / escaped )
      unescaped       = %x00-2E / %x30-7D / %x7F-10FFFF
         ; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'
      escaped         = "~" ( "0" / "1" )
        ; representing '~' and '/', respectively

   It is an error condition if a JSON Pointer value does not conform to
   this syntax (see Section 7).

See that a pointer must start with '/'. So the example you mention above should be:

person.at("/address/street").asString()
Comment by eugen.cepoi [ 22/Feb/15 ]

Sorry I was unclear with "How do you plan to handle incomplete paths (when some element in the path matches a null object)?"

What I mean is not, how we handle a malformed path it self, but what will be the result of a json pointer expression when it encounters a null/missing value when evaluating the path? Note that null and missing could have different semantics. Would we return null? Optional? Or do something else?

Comment by asotobu [ 23/Feb/15 ]

I have read what Jackson-Utils JsonPointer and Jackson-databind JsonPointer solves this problem.

The first one returns a Null which as you said it may be incorrect because a value can be null as well.

The second one returns an special JsonObject which has a method called isMissingNode() that returns true in this case, meaning that there is no node there.

If you see javadoc JsonValue class has a NULL constant (JsonValue.NULL) https://json-processing-spec.java.net/nonav/releases/1.0/pfd-draft/javadocs/javax/json/JsonValue.html so what we can do is if returns a Java null means missing value and if it returns a JsonValue.NULL means the value Null.

Comment by kchung [ 23/Feb/15 ]

Yes, a Json pointer should begin with a '/'. My bad.

@asotobu I still like constructors better, because it is what most people would expect to use, and using static method to instantiate is less intuitive. There is nothing wrong with doing some processing in constructors. They can also be processed lazily.

Agreed that the operations starting from the target

person.get(pointer)

can be an alternate syntax. The short cut

person.get("/address/street")

also makes sense.

Here is the question. If we can use this short cut all the time, do we still need the class JsonPointer? Here are exaples for each of the 4 operations, just to see how they look like:

  JsonValue value = person.get("/address/street");
  JsonObject p = person.replace("/address/street". "Main Street"); // return the transformed person
  JsonObject p = person.remove("/phones/office");
  JsonObject p = person.add("/phones/mobil", "1234-567");

This way, the Json pointer will be completely removed from the API and is hidden in the implementation. Are there things that can be done with the two step approach (first create a JsonPointer, then apply to a target) but not with the short-cut?

Regarding the question about what should be returned when pointer specifies a non-existing entry, I think spec says an error should be raised. See http://tools.ietf.org/html/rfc6901#section-7

Comment by mitemitreski [ 23/Feb/15 ]

+1 on hiding the implementation details since really I don't see the need to know that part.

The shortcut also looks cleaner then the 2-step approach.

Just wondering how would we retrieve a collection of values from a collection of pointers applied on a object?

Or specifically how would a collection of operations would be applied to an object dynamically without knowing the order of the operations.
I am asking this since this would be needed in https://tools.ietf.org/html/rfc6902

Comment by asotobu [ 24/Feb/15 ]

@kchung and @mitemitreski From my point of view I would maintain the JsonPointer class in spec. Let me show why. A JsonPointer expression requires two things when it is created/used; the first one is escaping special characters and the second one (and this is an implementation details but all implementations I have worked of JsonPointer uses) it is that a json pointer expression is tokenized (or segmented) so in this way it is easier to implement the JsonPointer logic and also some operations required by Json Patch.

So let's suppose next scenario. I have 2000 request per minute which every request uses the same JsonPointer. This means that every minute you will execute 2000 times the escaping the same chunk of string and tokenize the expression. Although these are not an expensive operations it is unnecessary to execute them each time if the business logic is exactly the same.

So if spec allows to pass a JsonPointer then you will be able to create an static JsonPointer expression and call person.get(staticJsonPointer);

Of course we can still offer the string method which internally creates a new JsonPointer object, but at least we give to users the option to create only once the expression.

Comment by kchung [ 24/Feb/15 ]

@asotobu I don't get your argument about extra processing are need for a Json pointer. Isn't that true anyway? This is just an implementation detail, right?

I still don't know how often a Json pointer is reused. In your example, if the Json pointer is part of the request (maybe part of a Json patch). You'll need to do a comparison to determine if two pointers are same. To me it almost looks like you need a cache of JsonPointer. Note also the same optimization can be realized for the short-cut, because it can also look up the cache to reuse a previous JsonPointer.

I am not ruling out JsonPointer. I am just exploring what a JSON Pointer API we need to have. If we can make it simpler, the better.

We don't need to make decisions right now. We should have better ideas when we discuss/implement JSON patch.

Comment by asotobu [ 25/Feb/15 ]

Well let me explain with code. If you look here https://github.com/FasterXML/jackson-core/blob/master/src/main/java/com/fasterxml/jackson/core/JsonPointer.java#L114 you will see the process that requires creating a JsonPointer instance in Jackson. But I have used other Java libraries that implements JsonPointer and it is pretty similar. So as you can see there is some logic like escaping characters and creating segments for each sub-expression.

This is not good or bad it is simply an implementation details I know but let's suppose next code:

JsonObject[] persons = new JsonObject[5000];
//fill persons
JsonObject[] addresses = new JsonObject[5000]; 

for(int i=0;i<persons.length;i++) {
  addresses[i] = persons[i].get("/personalinformation/address");
}

In that code the escaping characters and segmentation of json pointer expression will be evaluated 5000 times.

But if I could do something like:

JsonObject[] persons = new JsonObject[5000];
//fill persons
JsonObject[] addresses = new JsonObject[5000]; 

JsonPointer addressPointer = new JsonPointer("/personalinformation/address");
for(int i=0;i<persons.length;i++) {
  addresses[i] = persons[i].get(addressPointer);
}

Then construction would be only one.

Because we don't know exactly if reusing a jsonpointer would be a requirement or not, I think that would have sense to implement both operations:

  • get("/a/b")
  • get(new JsonPointer("/a/b");

Basically because we are getting the best of both worlds with minimal requirement. The only requirement is that JsonPointer becomes an interface of the spec.

Comment by kchung [ 25/Feb/15 ]

OK. Let's keep both for now. I'll summarize what we have.

  1. JsonPointer is a non-abstract class with a constructor
    public JsonPointer(String pointer);
  2. The syntax for applying a JsonPointer to a JsonValue is
    JsonValue value;
    JsonPointer pointer = new JsonPointer("/a/b/c");
    value.get(pointer);
    
  3. The JsonValue operations should be overloaded to take the raw Json pointer String as a short cut
    value.get("/a/b/c");
    
  4. Add 4 operaions to JsonValue:
    1. getValue # there is already a get in JsonObject
    2. remove
    3. replace
    4. add
  5. An error is raised if the pointer reference a non-existing value.

Do we still need the alternate syntax

pointer.get(value)

?

I'll writeup the javadocs for JsonPointer and we can talk more.

Comment by asotobu [ 25/Feb/15 ]

jsonPointer could be an interface as well, so implementors Can decide how to implement json pointer resolution and how to create. WDYT ?

Comment by kchung [ 27/Feb/15 ]

@asotobu I thought you were against using SPI to instantiate a JsonPointer, and now you have reversed your position? Just to be clear, you prefer

 JsonPointer pointer = Json.createJsonPointer("/a/b/c");

to

 JsonPointer pointer = new JsonPointer("/a/b/c");

But be aware that there has been complaints about the use of SPI interfaces in JSON-P, and one of our task is to simplify the API and avoid using the SPI.

Personally, either would work for me. We can assume one and proceed to firm up the API for JsonPointer. Are there methods, other than the 4 I proposed, that should be added to JsonPointer? Once we have JsonPointer API, we can move on to Json Patch.

Comment by asotobu [ 28/Feb/15 ]

Hi, well I was not against something I was only mention other options to have different options, but both can work and I feel comfortable.
But today I have started to prototyping something and probably you are right that creating JsonPointer as SPI it can be a headache, and if our task is simplify the API for implementators then I am going to start working for JsonPointer as a class and not an interface.

About if I prefer first or second option, I like the first one but the second one works as well. If JsonPointer is a class then we can implement in both ways, because it seems that the majority thinks that it is better as a constructor I am going to implement as is.

If you agree my next steps are going to be cloning the project, create a branch and implement JsonPointer class (with some inner classes) and adding the operations to JsonObject for getting a node. All with their tests. Then if it looks ok let's implement the rest of the operations described here.

WDYT?

Comment by kchung [ 03/Mar/15 ]

@asotobu Go ahead with a branch for JsonPointer. We can assume the first option for now. It wouldn't be to hard to switch later if necessary.

To implement JsonPointer, you'll need my proposed API for transforming a JsonArray and JsonObject. Maybe I should merge it into the master branch first. For now let's first work on getting the API right.

Comment by kchung [ 05/Mar/15 ]

asotobu proposed:

/* 
* Accessor for getting a "sub-pointer", representing the rest of segments of a pointer.
* For example /person/address/street if current segment is address it will return /street json pointer
*/
public JsonPointer tail();

/**
* Accessor for getting a pointer instance that is identical to this
* instance except that the last segment has been dropped.
* For example, for JSON Point "/root/branch/leaf", this method would
* return pointer "/root/branch" (compared to {@link #tail()} that
* would return "/branch/leaf").
*/
public JsonPointer head();

/**
* Returns the leaf of current JSON Pointer expression.
* Leaf is the last non-null segment of current JSON Pointer.
*/
public JsonPointer last();

/**
* Method that may be called to see if the pointer would match property
* of a JSON Object.
* 
*/
public boolean matchesProperty(String name);
public JsonPointer matchProperty(String name);

/**
* Method that may be called to see if the pointer would match
* array element with given index.
* 
*/
public boolean matchesElement(int index);

Almost all of these methods were implemented by me in Jackson but we can change the names to something better (I am pretty bad given name to things) feel free to adapt it.

Comment by kchung [ 05/Mar/15 ]

@asotobu: All the methods seems to me too low level to be exposed in an API. What can an use do with a JsonPointer? I think the answer is that he/she wants to use it on some JSON structure. Here is my proposal, coming from that perspective.

    /**
     * Return the value at the referenced location
     * in the specified {@code JsonStructure}
     *
     * @param target the {@code JsonStructure} referenced by this {@code JsonPointer}
     *
     * @return the {@code JsonValue} referenced by this {@code JsonPointer}
     */
    public JsonValue getValue(JsonStructure target);

    /**
     * Add or replace a value at the referenced location
     * in the specified {@code JsonStructure}.
     * <ol>
     * <li>If the reference is the target {@code JsonStructure},
     * the value, which must be the same type as the target,
     * is returned.</li>
     * <li>If the reference is an index to an array, the value is inserted
     * into the array at the index.  If the index is specified with a "-",
     * or if the index is equal to the size of the array,
     * the value is appended to the array.</li>
     * <li>If the reference is a name of a {@code JsonObject}, and the
     * referenced value exists, the value is replaced by the specified value.
     * If it does not exists, a new name/value pair is added to the object.
     * </li>
     * </ol>
     *
     * @param target the target {@code JsonStructure}
     * @param value the value to be added
     * @return the resultant JsonStructure
     * @throws IndexOutOfBoundsException if the index to the array is out of range
     */
    public JsonStructure add(JsonStructure target, JsonValue value);

    /**
     * Replace the value at the referenced location
     * in the specified {@code JsonStructure} with the specified value.
     *
     * @param target the target {@code JsonStructure}
     * @param value the value to be stored at the referenced location
     * @return the resultant JsonStructure
     * @throws JsonException if the value does not exists,
     *    or if the reference is the target.
     */
    public JsonStructure replace(JsonStructure target, JsonValue value);

    /**
     * Remove the value at the reference location
     * in the specified {@code JsonStructure}
     *
     * @param target the target {@code JsonStructure}
     * @return the resultant JsonStructure
     * @throws JsonException if the referenced value does not exists,
     *    or if the reference is the target.
     */
    public JsonStructure remove(JsonStructure target);

We should probably overload these methods to return JsonArray or JsonObject, if the target is a JsonArray or JsonObject.

Comment by asotobu [ 05/Mar/15 ]

Yes I agree that my approach exposes maybe too much the internals, but my approach (and probably wrong) was to not expose JsonStructure inside JsonPointer. But probably as you said for an API it would be better your approach.

Only I have next question should we add remove, replace, add... methods here? I said that because JsonPointer doesn't talk about replacing or removing elements but only as getting elements. Of course we need these operations for json patch but should be this place to implement them or they should be used in upper level let's say in json patch implementation? So they only call jsonpointer.get(path) and with returned JsonStructure they call let's say the remove method.

From my point of view JsonPointer should only provide get (that is the main purpose of the json pointer spec) and because add, remove, replace operations are also implemented in JsonObject, then the json patch API should use both classes to do the operations.

What do you think? The API would be more focused on Json Pointer and also simpler.

Comment by kchung [ 06/Mar/15 ]

I think your methods are not what JSON users would want or need to do with JSON Pointers. Of course if you have valid use cases, I can change my mind.

You are right that RFC 6901 only talks about get, and not add, remove, and replace. But all of them are needed by Patch, and they are useful outside of Patch (think of the scenario where you want to do a minor modification and don't want to create a JSON Patch for it). We just need a way to refer to a node in the JSON tree, and the spec provides us with the syntax. If there is not a spec for it, we may have to invent something.

I also think that it is good to keep all Pointer operations in one place. It would be confusing if we have only get in JsonPointer and others in other places.

There is not much anyone can do with a JsonPointer unless its operations are applied to a JSON structure. I have wondered before if we even need a JsonPointer, but you have convinced me that we do. If we have operations in JsonPointer, other places that use a JSON Pointer (e.g JsonPatch, JsonMergePatch, or even JsonObject etc) can just refer to them in JsonPointer. Architecturally, this approach is good.

Comment by asotobu [ 07/Mar/15 ]

Ok from this point of view I agree that JsonPointer can agglutinate all these kind of operations so it can be used standalone by developers or in json patch, json merge, ....

So what I am going to implement if I understand correctly is a class (not interface) that implements all these operations using the operations you implemented for transformations, isn't it?

Only one question and I think the answer is yes, when you do a replace, add or remove to a JsonStructure, does the returned structure be another JsonStructure with the change? I think that the answer is yes because if not then the JsonStructure was not immutable.

That's all if you agree I will clone the current master and I will start working on that.

Alex.

Comment by kchung [ 08/Mar/15 ]

Alex, +1.

Comment by asotobu [ 09/Mar/15 ]

Hi, I have implemented initial version of JsonPointer. For now only getValue operation is implemented to see if I have understood correctly where to put JsonPointer class and the tests and so on. (https://github.com/lordofthejars/jsr374-unofficial/blob/master/tests/src/test/java/org/glassfish/json/tests/JsonPointerTest.java)

There are some things that need to be implemented like the remaining operations, extract some constants like (~, 0 or 1) and add javadoc.

Well let's review first the work that I have done and if it all is ok then I will finish the whole implementation.

Thank you so much.
Alex.

Comment by asotobu [ 15/Mar/15 ]

I have just implemented the remove operation with one minor change API. Basically that remove now returns a JsonValue instead of JsonStructure, but with this change I can reuse methods from getValue and add.

Then it is time for replace. I have seen that there is no replace operation in JsonArrayBuilder class. Should we add it or we can assume that a replace is a remove + add? In case of JsonObjectArray it is already implemented in add method.

That's all after this implementation I will need to refactor some parts, write more tests and start using JsonExpcetion in some places and that's all. I think that next week I will have JsonPointer implemented.

The implementation is at: https://github.com/lordofthejars/jsr374-unofficial/blob/master/api/src/main/java/javax/json/JsonPointer.java

Comment by kchung [ 16/Mar/15 ]

@asotobu Some general comments first.

  1. You should merge the latest source for JsonPointer into you codes, including all the javadocs. It makes it easier for anyone to review you codes.
  2. You should implement what we have agreed on the API, and not modify it to suit your implementation. If you think the API should be changed, we should discuss it with other EG.
  3. You should be careful about following the javadocs. For instance, we know that a null JSON Pointer string is not allowed, so you don't need to test for null in add. Also, when the javadocs says JsonException should be raised, you should wrap an IllegalArgumentException in a JsoException.

OK, let's discuss the design of implementation of JsonPointer. Say we have a pointer "/a/b/c/d" on target t and we want to do an operation add, remove, replace (we won't discuss getValue, since it is easy). We just need to take the tokens in the reverse order and apply the operations to the last two nodes, and apply the replace operations as we move up the tree:

    c' = c.{add,remove,replace}(d)
    b' = b.replace(c')
    a' = a.replace(b')
    t' = t.replace(a')

So if we do it right, we should handle all of these operations the same ways. To me it seems to be straight forward to remember the nodes a, b, c, and d in t, either using an array or recursion .

Maybe it is useful to abstract the execution of an operation op on a node n with a value v (n.op(v)) with an interface and use a JsonArray or JsonObject implementation, depending on the node type. That way we don't need to do a lot of type testing on the node. I'll think about this more.

Comment by asotobu [ 17/Mar/15 ]

Hi,
about points 1, 2 and 3 I really understand what you mean and for this reason I decided to put the project in my github so I could use as sandbox not as final solution, then I can implement globally without worrying much in code conventions and so on, try things that I can share with all of you and then with something "running" we can take decisions on how API should be. Maybe I am too visual guy (I mean I can think better if I have something real to iterate). For this reason I said on my previous comment that I was totally aware that I was not following exactly the API defined in root (for example some return type or throwing IllegalArgumentException), but I think that in this way it is easier to purpose changes to the API, but in any case my intention was to change anything of the official API without consensus. I wanted to show only how using current API can be implemented the operations and see if it fits well or we can find another way that fits better (for example returning JSonValue instead of JsonStructure so we can reuse internal methods), of course if the change was an strong change then I would have updated to latest sources for sure. Note that because of this PoC of JSonPointer now we have some questions that we need to fix and that was exactly my main intention in this case. For example there are some add operations that are not implemented yet because they are pretty simple when you have the most generic one.

But also I understand that I need to change something on how I work because probably with an small more effort I can make PoC and having always the updated API.

Saying that let's see next discussion:

Yes this is exactly how I am doing by applying the operation and then replacing (which is a copy operation of previous nodes) you can see the call here https://github.com/lordofthejars/jsr374-unofficial/blob/master/api/src/main/java/javax/json/JsonPointer.java#L95. I think that using Lambdas we can make the algorithm even more generic but for now I think it is ok.

As you suggested the implementation may reacall on an if to know if it is a JsonArray or JsonObject and depending on that do one change or another.

Maybe we could create an interface that has the add and remove operations (replace can be done by removing and adding), so I can remove the next ifs

if (currentNode.getValueType() == ValueType.OBJECT)
if (currentNode.getValueType() == ValueType.ARRAY)

The only problem I see in this approach is that the interface must be common so for example it could looks like:

JsonStructure add(String name, JsonValue value);
void remove(String name);

The problem that I see is that meanwhile in case of objects the name is really the name of the property you want to add or remove, in case of arrays we must ensure to clarify to the implementators that this string is going to be a position that will need to be translated. I would try to avoid using two different interfaces one for objects and another for arrays because then we will still have the same problem of having to "cast" the instances.

Comment by kchung [ 17/Mar/15 ]

First, let me point out that there is a replace operation in JsonArrayBuilder, and that is "set".

The reason we have an "add" method that takes a JsonValue as a parameter and returns a JsonValue is to allow cases where the target is not a JsonArray or JsonObject (allowed now by rfc 7159) and the Json Pointer is empty. Strangely, RFC 6902 only allow empty pointer for add. I think we should add an "add" method that take a JsonStructure and returns a JsonStructure, just like other methods, and special case empty json pointer.

I think your code is fine, but can be simplified. Instead of having copyJsonValue (shouldn't it be addJsonValue instead?), traverseAndCopyJsonObject, removeJsonValue, traversetAndRemoveJsonValue, traverseAndReplace, they can be combined into one or two more generate methods, because they all similar, except for the operation on the last node.

What we need is the abstraction that encapsulates the reference of a JsonStructure with a member, and in which we can apply the operations. I have in mind something like,

  interface NodeRef {
      JsonStructure add(JsonValue v);
      JsonStructure remove();
      JsonStructure replace(JsonValue v);
}
public class ArrayRef implements NodeRef {
    ArrayRef(JsonArray a, int index){ 
    ...
}
public class ObjectRef implements NodeRef {
    ObjectRef(JsonObject obj, string name)
}

So the operations would be handled in implementation classes.

Comment by asotobu [ 18/Mar/15 ]

Well if we create an add method that returns a JsonStructure then we will need some instanceof code because Builders works with JsonValue but well there is no problem in doing in this way.

About the NodeRef interface I don't catch you sorry. I mean how current JsonStructure interface meets NodeRef interface and how it can be used from the point of view of JsonPointer. I mean JsonStructure is something that it is not dynamic in the sense that it is provided by users. But on the other side we have NodeRef which is dynamic and depends on the evaluation of the JsonPointer expression. So in this case I am not sure to understand exactly how to work with these classes.

Comment by kchung [ 18/Mar/15 ]

Instead of explaining how NodeRef works, it would be easier to show you the codes. Therefore I've checked in a NodeReference.java. Essentially it encapsulate all the operations you want to do with a JsonStructure member.

I've also implement some operations in JsonPointer, using NodeReference. I've reuse your codes that parases the escaped reference tokens.

The codes compiles, but not tested yet. Please go over the codes, and let me know if you have questions. Also let me know if you spot errors and/or improvements.

There are still some more works to do to finish JsonPointer, and you are welcome to do that. But I think we should start on JSON patch and JSON merge patch, which build on top of JsonPointer.

Comment by asotobu [ 19/Mar/15 ]

Ok now I understand what you mean, first I was thinking that JsonStructure should implements NodeRef for this reason I didn't catch you, now I see that what you mean was an aggregation so all operations are inside a class and not in JsonPointer, really good idea.

Ok from my part this weekend I am going to complete this class, run all the tests I have on my project (I need to refactor some of them but overall they are good and so exhaustive), fix any error I can find (if any) and then push the code to master.

Now I am going to start a conversation in PATCH issue so we can start discussing the API and then I think that implementation will be pretty easy.

Thank you so much for your reviews

Comment by asotobu [ 21/Mar/15 ]

I have just pushed my latest work on jsonpointer. I am using the mirrored github repo (https://github.com/json-processing-inofficial/jsonp) and you can see the PR here https://github.com/json-processing-inofficial/jsonp/pull/1/files I think that when the change is accepted it will be automatically synchronized with java-net repo.

Things that I have modified:

  • equals and hash methods to be a real implementation. (Should we do the same for toString()?)
  • in getValue in case a non JsonStructure is passed a JsonException is thrown because it has no sense (I think after reviewing the spec) to apply a json pointer to a single value but I may be wrong.
  • in getValue there was a bug in case pointer points to a non existing element. Instead of returning null now it returns a JsonException.
  • finished add(JsonValue, JsonValue) method following similar approach as getValue. I think it has no sense to apply an add operation to a single value.
  • in NodeReference implementations there were two bugs on array remove and replace operations, in case of using "-" char in expression an ArrayIndexOutOfBounds was thrown instead of JsonException.
  • Added tests for all operations, more tests can be done but for now it is a good start.
Comment by kchung [ 24/Mar/15 ]

Line 112 - 123: can be replace with

return jsonPointer.equals(other.jsonPointer); 

since jsonPointer cannot be null (see javadocs for the constructor)

hascode(): why not just return jsonPointer.hashCode();

After reading the spec again, it does seems to say that the target must be a JsonStructure. If so, we should remove the method

public JsonValue add(JsonValue target, JsonValue value)

and replace

public JsonValue getValue(JsonValue target)

with

public JsonValue getValue(JsonStructure target)

According to the spec, we should throw JsonException when value is non-existing (including array index out of bounds). We should push the checking to NodeReference

Comment by asotobu [ 25/Mar/15 ]

Yes I read it before the PR again and I arrived to same conclusion, for this reason I didn't implement JsonValue but casting to JsonStructure or throwing an exception. We can remove methods without much problem.

Comment by kchung [ 25/Mar/15 ]

@Alex I committed and pushed the changes we discussed. Please review and test. You can also check in the tests, if they pass.

Comment by asotobu [ 26/Mar/15 ]

Good this weekend I will incorporate the tests I have already written and start working on JsonPatch as we discussed in the issue.

Comment by asotobu [ 28/Mar/15 ]

@Kin-man while writing tests for JsonPatch I have found some issues regarding to JsonPointer/NodeReference. For example being target an array and the json pointer something like /~1 which is translated to "/" and not to the number 1 it throws a NumberFormatException. What I have done is catching the NumberFormatException and throw a JsonException wrapping the NumberFormatException. I think this is the correct way to procedure, WDYT?

And it happens the same when you try to put a value on an index array out of bounds.





[JSON_PROCESSING_SPEC-61] Support for JSON Patch Created: 02/Dec/13  Updated: 03/Apr/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.1

Type: New Feature Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Consider adding support for JSON Patch. The RFC is at http://tools.ietf.org/html/rfc6902

Perhaps, it can be used for transforming one JsonObject/JsonArray to another (works well since JsonObject/JsonArray are immutable)



 Comments   
Comment by kchung [ 09/Dec/14 ]

Note there is another alternate spec for patching a JSON document: Json Merge Patch, rfc 7396

This uses a diff patching, and is less verbose. There are some short-comings:

  1. It uses null for delete, so you cannot replace a value with null.
  2. It does not patch array entries, so you'll need to replace the whole array.

Maybe we should consider supporting both.

Comment by mitemitreski [ 17/Feb/15 ]

@kchung as you said https://tools.ietf.org/html/rfc7396 is the one that is a lot less verbose and it is more practical.
In my book, this one should be given a higher priority.

On the other hand, if we already have a JSON-Pointer as part of the spec they both make sense.

Comment by asotobu [ 18/Feb/15 ]

As @mitemitreski said, having json pointer implemented, the hard work is done and we can offer support for both of them, maybe we can start with merge patch and then if we are on time we can implement patch as well, or we can define both at first.

Comment by kchung [ 18/Feb/15 ]

Agreed that we should do both, at least we should not exclude either at first.

In terms of implementation order, I also agree that JSON Pointer should be done first. In fact I believe we should tackle the editing or transformation operations first, because they are lower level operations that both JSON Pointer and JSON can build on. See https://java.net/jira/browse/JSON_PROCESSING_SPEC-67 for more details.

Agreed also that JSON patch should include a diff function.

Comment by asotobu [ 19/Mar/15 ]

I send you my first purpose for Json Patch API:

/**
* <p>{@code Patch} interface represents a common interface for applying patches on a {@link JsonStructure}.<p>
* <p>A patch is a {@code JsonStructure} for expressing operations or modifications to a given JSON document.</p>
**/
public interface Patch {

  /**
  * <p>Apply this patch to a {@code JsonStructure}.</p>
  * @param target to apply the patch to.
  * @return the patched {@code JsonStructure}. Since a {@code JsonObject} or {@code JsonArray} is immutable,
  *         these operation returns a new JSON Object or array.
  */
  JsonStructure apply(JsonStructure target);

}

/**
* <p>Implementation of JSON Patch described at <a href="https://tools.ietf.org/html/rfc6902">rfc 6902</a></p>
* <p>JSON Patch is a format (identified by the media type "application/json-patch+json") for expressing a sequence of operations to apply to a target JSON document;
* it is suitable for use with the HTTP PATCH method.</p>
* <p>A JSON Patch document is a JSON document that represents an array of objects.
* Each object represents a single operation to be applied to the target JSON document.</p>
* <p>The following is an example JSON Patch document:</p>
* <pre>
*
* [
*  { "op": "test", "path": "/a/b/c", "value": "foo" },
*  { "op": "remove", "path": "/a/b/c" },
*  { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
*  { "op": "replace", "path": "/a/b/c", "value": 42 },
*  { "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
*  { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
* ]
* </pre>
* <p> Operations are applied sequentially in the order they
* appear in the array.  Each operation in the sequence is applied to
* the target document; the resulting document becomes the target of the
* next operation.  Evaluation continues until all operations are
* successfully applied or until an error condition is encountered.
* </p>
**/
public JsonPatch implements Patch {

  /**
  * <p>Creates a {@code JsonPatch} object.</p>
  * @param jsonPatch array structure expressing a sequence of operations to apply to a JSON document.
  *        This document follows <a href="https://tools.ietf.org/html/rfc6902">rfc6902</a> notation defined at <a href="https://tools.ietf.org/html/rfc6902#section-3">Section 3 Document Structure</a>.</p>
  **/
  public JsonPatch(JsonArray jsonPatch) {

  }

  /**
  * <p>Apply this json patch document to a {@code JsonStructure}.</p>
  * @param target to apply the patch to.
  * @return the patched {@code JsonStructure}. Since a {@code JsonObject} or {@code JsonArray} is immutable, these operation returns a new JSON Object or array.
  */
  public JsonStructure apply(JsonStructure target) {

  }

}

/**
* <p>Implementation of JSON Merge Patch described at <a href="http://tools.ietf.org/html/rfc7386">rfc 7386</a></p>
* <p>A JSON merge patch document describes changes to be made to a target
* JSON document using a syntax that closely mimics the document being
* modified.  Recipients of a merge patch document determine the exact
* set of changes being requested by comparing the content of the
* provided patch against the current content of the target document.
* If the provided merge patch contains members that do not appear
* within the target, those members are added.  If the target does
* contain the member, the value is replaced.  Null values in the merge
* patch are given special meaning to indicate the removal of existing
* values in the target.
* </p>
**/
public JsonMergePatch implements Patch {

  /**
  * <p>Creates a {@code JsonMergePatch} object</p>
  * @param jsonMergePatch JSON document that describes changes to be made to a target using syntax defined in <a href="http://tools.ietf.org/html/rfc7386">rfc7386.
  **/
  public JsonMergePatch(JsonObject jsonMergePatch) {

  }

  //...
}
Comment by kchung [ 20/Mar/15 ]

@Alex Thanks. Several quick comments.

  1. Why do we need the interface Patch? Since 6902 and 7963 are totally different, there is nothing common except in names. It does not really make much sense to combine JsonPatch and JsonMergePatch into one interface.
  2. How about just have two concrete classes: JsonPatch and JsonMergePatch.
  3. We should include overloaded "apply" method for JsonArray and JsonObject.
  4. Maybe a static generatePatch (or just diff) method?
Comment by asotobu [ 21/Mar/15 ]

1. Probably you were right, I was thinking more in creating a factory of merge methods (path or merge patch) but as I said we can remove it.
2. Agreed
3. Don't understand this. Why apply should be in JsonArray or JsonObject? I was having in mind using JsonPointer operations. For example in pseudocode:

JsonArray patchOperations = ...
target = ...
foreach(JsonObject patch:patchOperations) {
  JsonPointer pointer = new JsonPointer(patch.get("path"));
  if(patch.get("op") is "add") {
    target = pointer.add(target, patch.get("value");
  }
}

4. Probably it is true but maybe we could wait for next iteration.

Comment by kchung [ 23/Mar/15 ]

Regarding 3, what I meant was:

public class JsonPatch {
    JsonStructure apply(JsonStructure target);
    JsonArray apply(JsonArray target);
    JsonObject apply(JsonObject target);
}

So that you can write

JsonArray result = jsonPatch.apply(target);

If target is known to be a JsonArray, without having to use cast on the result.

Comment by asotobu [ 24/Mar/15 ]

Understood yes it has a lot of sense. I am going to merge the PR about JsonPointer and start working on that.

Comment by asotobu [ 30/Mar/15 ]

I have written several tests for checking and I have found some issues that I think it may be changed, I am going to mention here and if you agree I can fix:

  • In case you refer an array position with a char instead a number a NumberFormatException is thrown. I think it should throw a JsonException.
  • In case you refer an array position with an integer but out of bounds of the array a IndexArrayOutOfBounds is thrown. I think it should throw a JsonException.

In next test cases json patch is not applied because it says that from patch contains the path path expression:

        {
            "op": { "op": "move", "from": "/x/a", "path": "/x/a" },
            "target": { "x": { "a": "helo" } },
            "expected": { "x": { "a": "helo" } }
        },
        {
            "op": { "op": "move", "from": "/0", "path": "/0/x" },
            "target": [ "victim", {}, {} ],
            "expected": [ { "x": "victim" }, {} ]
        } 

I think that this check is not necessary, I have read the spec and I have not seen anything about this limitation.

And then the other thing I have noticed is this case:

{
            "op": { "op": "replace", "path": "", "value": false },
            "target": { "x": { "a": "b", "y": {} } },
            "expected": false
        }

Which basically replaces a document to a value. If new spec supports adding simple values in root part, it seems that this exception should not be thrown, isn't it?

Alex.

Comment by kchung [ 30/Mar/15 ]

Agreed that JsonException should be thrown instead of NumberFormatException and ArrayIndexOutofBoundsException.

Regarding the check for overlaps in move, the spec says

The "from" location MUST NOT be a proper prefix of the "path" location; i.e., a location cannot be moved into one of its children.

So there should be a check for overlaps. However, the check is not entirely correct and your example should be allowed. In other words, move from "/x/a" to /x/a" is allowed, but not from "/x" to "/x/a".

I think we should disallow "replace" with "" JSON Pointer, because the spec seems to only allow "add" with "". However, you may be right in that any Jsonvalue should be allowed. So, should "add" return a JsonValue instead of a JsonStructure? I don't like this, as it would screw up our nice API. Let me think about this more.

Comment by asotobu [ 31/Mar/15 ]

Yes in move operation it says what you mention but I have found the same in copy operation. For example:

       {
            "op": { "op": "copy", "from": "/0", "path": "/0" },
            "node": [ true ],
            "expected": [ true, true ]
        }

it fails with same error, and in case of copy operation there is no reference in rfc about prefixing from and path elements. So for what I understand copy operation should accept prefixing from field from path.

Comment by kchung [ 31/Mar/15 ]

Yes, the spec does not say this is disallowed, so I'll probably remove the check for copy. I still think it does not make sense to copy from /a to /a/b, for instance, but we'll allow it. BTW, move from /a to /a is a nop.

Thinking about whether "add" should return a JsonValue instead of a JsonStructure, I noticed that RFC 6902 refers to 4627 (instead of 7159). I think this is because it was published before 7159. Until 6902 is updated for 7159, we will stick with the original intend and enforce the rule that the root of a JSON tree can only be replaced with a JsonStructure.

I'll fix the code to fix the issues you raised. Thanks.

Comment by kchung [ 31/Mar/15 ]

I've committed the fix. However, I cannot cause ArrayIndexOutOfBoundsException to happen. I thought NodeReference take care of it already.

Comment by asotobu [ 01/Apr/15 ]

Cool, I have a use case where this ArrayIndexOutOfBounds occurs. I will update the code and run the test suite again and if the problem still happens I will fix it and push the changes. I remember that the exception occurs in JsonPointer class and not in NodeReference but I will take a look.

Also I am going to implement the diff operation during next week.

Alex.

Comment by asotobu [ 02/Apr/15 ]

Hi I have found that this operation:

{
            "op": { "op": "replace", "path": "", "value": false },
            "target": { "x": { "a": "b", "y": {} } },
            "expected": false
}

Throws that a value cannot add to root element, only object and array. In previous comment you mention (or I understood) that this was fixed. Do you think that replace should be have the same behavior as add? If you think so I can fix it or if you want you can fix it as well.

Alex.

Comment by kchung [ 02/Apr/15 ]

@Alex Please read my comments (4 before this). I think value can only be JsonStructure in this case.

The spec says

This operation is functionally identical to a "remove" operation for a value, followed immediately by an "add" operation at the same location with the replacement value.

Since we disallow JSON root for remove, we should also disallow it for replace.

Comment by asotobu [ 03/Apr/15 ]

Sorry yes this is true I had in mind the #6 comment above that you mention that you will think about it , and don't ask me why but my brain was still thinking on this and not that you already taken a decision. Sorry





[JSON_PROCESSING_SPEC-58] Add Support for JSON Queries Created: 28/May/13  Updated: 23/Feb/15

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.1
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: reza_rahman Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I received feedback that JSON-P should add support for being able to query JSON objects (a la XPath). I am aware that this is an immature field with some competing approaches but think this is very valid feedback particularly in making JSON-P more compelling vis-à-vis existing JSON processing solutions.

Do let me know if anything needs to be explained further - I am happy to help.

Please note that these are purely my personal views and certainly not of Oracle's as a company.



 Comments   
Comment by kchung [ 06/May/14 ]

There is currently no standard for JSON queries, so it would be premature to put query into JSON APIs.

Since JsonObject is a Map, and JsonArray a List, some querying should be possible using the Lambda expression in JDK 8. For instance,

  contacts.stream()
    .filter(p->p.getString("city").equals("Santa Clara"))
    .forEach(p->System.out.println(p.getString("firstName") + " " + p.getString("lastName"));)

would print out the names of your contacts residing in Santa Clara. With a little more work, it should be possible to return a JSON document of the query results.

Maybe the spec should look into providing better support for doing queries in Lambda?

Comment by mitemitreski [ 23/Feb/15 ]

Would filtering or transformations using JSON pointer make sense?





[JSON_PROCESSING_SPEC-22] Injection support for JsonParserFactory/JsonGeneratorFactory Created: 29/Oct/12  Updated: 07/Jan/13

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-next
Fix Version/s: 1.0-next

Type: New Feature Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

http://java.net/projects/json-processing-spec/lists/users/archive/2012-10/message/112

This can be considered for later releases






[JSON_PROCESSING_SPEC-32] matchName(String) methods on JsonParser Created: 03/Dec/12  Updated: 03/Dec/12

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JsonParser#matchName(String) kind of methods are required for performance.
http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/40






[JSON_PROCESSING_SPEC-31] Incremental processing of large strings Created: 03/Dec/12  Updated: 03/Dec/12

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Provide way to parse/process large string values incrementally in parser






[JSON_PROCESSING_SPEC-29] JsonParser#skipValue() Created: 03/Dec/12  Updated: 03/Dec/12

Status: Open
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jitu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

skipValue() discussion is at
http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/64






Generated at Fri Aug 28 23:20:51 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.