[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-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-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-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-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-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-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-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-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-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-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-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-59] JavaDoc problems when building with JDK 8 Created: 18/Jul/13  Updated: 06/May/14  Resolved: 06/May/14

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

Type: Bug Priority: Minor
Reporter: heliofrota Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

gnu-linux manjaro distribution x86 jdk8-b7


Tags: adoptajsr

 Description   

Build error due javadoc problems when building with jdk8 b97

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.8.1:jar (attach-javadocs) on project javax.json-api: MavenReportException: Error while creating archive:
[ERROR] Exit code: 1 - javadoc: warning - Error fetching URL: http://docs.oracle.com/javase/6/docs/api
[ERROR] /home/hf/Desktop/cejug/adopt_a_jsr/jsonp~git/api/src/main/java/javax/json/JsonArray.java:177: warning: no @param for <T>
[ERROR] <T extends JsonValue> List<T> getValuesAs(Class<T> clazz);
[ERROR] ^
[ERROR] /home/hf/Desktop/cejug/adopt_a_jsr/jsonp~git/api/src/main/java/javax/json/JsonArray.java:201: warning: no @param for defaultValue
[ERROR] String getString(int index, String defaultValue);
[ERROR] ^

Full logs on JSR mailing list.



 Comments   
Comment by heliofrota [ 23/Jul/13 ]

Maybe this is issue from maven javadoc plugin and this line:
[ERROR] Exit code: 1 - javadoc: warning - Error fetching URL: http://docs.oracle.com/javase/6/docs/api

I going to investigate this.

Comment by kchung [ 06/May/14 ]

Fixed.





[JSON_PROCESSING_SPEC-56] Use long instead of int for JsonLocation's line no, column no, stream offset Created: 11/Mar/13  Updated: 14/Mar/13  Resolved: 14/Mar/13

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

Type: Bug Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See the discussion thread
http://java.net/projects/json-processing-spec/lists/users/archive/2013-03/message/8






[JSON_PROCESSING_SPEC-57] NPE for null name or null key in object builder Created: 12/Mar/13  Updated: 14/Mar/13  Resolved: 14/Mar/13

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

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


 Description   

JsonObjectBuilder and JsonArrayBuilder don't allow null for a name or a value. Add it to the javadoc.






[JSON_PROCESSING_SPEC-51] JsonNumber equals()/hashCode() semantics Created: 01/Feb/13  Updated: 12/Feb/13  Due: 07/Feb/13  Resolved: 12/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

Type: Improvement Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The discussion is at http://java.net/projects/json-processing-spec/lists/users/archive/2013-01/message/88

Instead of using BigDecimal.equals(), Jonathan suggesting to use BigDecimal.compareTo().






[JSON_PROCESSING_SPEC-55] Remove JsonNumber.NumberType Created: 12/Feb/13  Updated: 12/Feb/13  Resolved: 12/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

The discussion is at:
http://java.net/projects/json-processing-spec/lists/users/archive/2013-02/message/25



 Comments   
Comment by jitu [ 12/Feb/13 ]

Resolved as suggested in the discussion.





[JSON_PROCESSING_SPEC-54] Shorten getter method names; make chained getters read well when used together Created: 06/Feb/13  Updated: 10/Feb/13  Resolved: 10/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pfd

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


 Description   

The idea here is to make the following two changes, which work well together:

1. Remove 'value' from most getter names
2. Use the same method naming convention on JsonNumber as is used on java.lang.Number

The result is that repetitive-looking use cases like jsonObject.getNumberValue("num").getDoubleValue() turn into this non-repetitive arrangement: jsonObject.getNumber("num").doubleValue().

This suggestion, along with JSON_PROCESSING_SPEC-53, has been implemented here:

https://github.com/jfuerth/javax-json/commit/shorter-method-names



 Comments   
Comment by jitu [ 08/Feb/13 ]
  • Your changes have this : JsonParser#getInt(), JsonNumber#intValue(), JsonObject#getInt()

Should we use one scheme here: getInt() even in JsonNumber ? Then, s/getIntValueExact()/getIntExact()

Comment by jfuerth [ 09/Feb/13 ]

Good point. I thought about that too when I was making the method name changes.

The conclusion I arrived at was that JsonParser#getInt() makes somewhat more sense than JsonParser#intValue(). It matches JsonArray#getInt(int) and JsonObject#getInt(String). Only JsonNumber differs, and for these two reasons:

1. JsonNumber serves a similar purpose to java.lang.Number, and to me this is a strong case for staying with the familiar/expected naming scheme
2. When the JsonObject or JsonArray getter method names match the JsonNumber getter method name, chained calls like jsonObject.getNumber("key").getDouble() don't read as well as jsonObject.getNumber("key").doubleValue().

So my preference is still to stay with getXXX() method names across the whole javax.json API, but go with the very well established java.lang.Number method names on JsonNumber.

Comment by jitu [ 10/Feb/13 ]

Fixing it as suggested.





[JSON_PROCESSING_SPEC-53] Replace generic get methods in JsonArray & JsonObject with specific getters for object, array & number Created: 04/Feb/13  Updated: 10/Feb/13  Due: 08/Feb/13  Resolved: 10/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pfd

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


 Description   

Example of how this change affects a typical task such as pulling a numeric value out of a nested object:

Given a JSON data structure:

    {
        "id": 1234,
        "location": {
            "lat": 39.12333432,
            "long": -79.12344534
        }
    }

fetch the latitude from the nested "location" object.

BEFORE:

    JsonObject jo = ...;
    double lat = jo.get("location", JsonObject.class).get("lat", JsonNumber.class).getDoubleValue();

AFTER:

    JsonObject jo = ...;
    double lat = jo.getObject("location").getNumber("lat").doubleValue();

I've implemented this together with shortening of getter names (drop 'Value' from getter method names; adjusted JsonNumber to use the familiar java.lang.Number method naming convention)

You can play with it by pulling from here:

https://github.com/jfuerth/javax-json/commit/c88ec370a78154fa348758b9edbf022cf746d301



 Comments   
Comment by jitu [ 06/Feb/13 ]

I think JsonNumber names should be in a separate issue. We have the same names in other places, for e.g JsonParser#getIntValue()

Comment by jfuerth [ 06/Feb/13 ]

Oh, good catch! I thought I had found all of them. I'll open a separate issue.

Comment by jfuerth [ 06/Feb/13 ]

I removed 'Value' from the method names in JsonParser. The commit is available for review on the same branch at:

https://github.com/jfuerth/javax-json/commit/shorter-method-names

Comment by jitu [ 09/Feb/13 ]
  • You noted earlier, one thing unsettling is getObject/getArray/getNumber return JsonXXX, where as getString return String
  • Should we use getJsonObject/getJsonArray etc? It is bit long.
double lat = jo.get("location", JsonObject.class).get("lat", JsonNumber.class).getDoubleValue();

would be

double lat = jo.getJsonObject("location").getJsonNumber("lat").getDouble();
  • Since there are accessor methods for string, int (perhaps the common cases), should we just add array and object accessor methods.
Comment by jfuerth [ 09/Feb/13 ]

That sounds like a reasonable solution to me. Adding "Json" to the names of methods that return JsonValues eliminates the potential confusion.

Closely related issue:

In the change I made for review, I eliminated the JsonObject#get(String,Class) and JsonArray#get(int,Class). This means that it's no longer possible to retrieve a JsonString instance from an object or an array (you can only get the java.lang.String that the JsonString wraps). I didn't add a special method for obtaining the JsonString mostly because the getString() that returns java.lang.String was in the way. It doesn't seem like a big problem to me.

I can only see one potential use case for getting the JsonString wrapper held by a JsonObject or JsonArray: when copying a bunch of string values from a JsonObject to a JsonObjectBuilder, passing the unwrapped strings to the builder will require new JsonString wrapper instances to be created, whereas this could be avoided by passing the JsonString wrapper that the JsonObject was already using. The same does not go for arrays, because we can use JsonArray#asList(JsonString.class) to get at the wrappers.

What do you think? If we rename getObject -> getJsonObject, getArray -> getJsonArray(), getNumber() -> getJsonNumber(), should we also add a getJsonString()?

Comment by jitu [ 09/Feb/13 ]

I was planning to add a method for JsonString. But anyway, developers can always use get(string/index) and cast it.
I will do the changes and you can take a look at it.

Comment by jitu [ 10/Feb/13 ]

Removed
getValue(..., ...)

Added
JsonArray getJsonArray(...)
JsonObject getJsonObject(...)
JsonNumber getJsonNumber(...)
JsonString getJsonString(...)
boolean isNull(...)





[JSON_PROCESSING_SPEC-48] Add accessor method to consume same type of objects in JsonArray Created: 25/Jan/13  Updated: 08/Feb/13  Due: 07/Feb/13  Resolved: 08/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

Jonathan suggests that API add the following method to consume same type of objects in JsonArray

<T extends JsonValue> List<T> JsonArray#getValuesAs(Class<T>) or
<T extends JsonValue> Iterable<T> JsonArray#getValuesAs(Class<T>)

see the discussion

http://java.net/projects/json-processing-spec/lists/users/archive/2013-01/message/0



 Comments   
Comment by jitu [ 08/Feb/13 ]

Added an accessor method that provides a list view of the specified type





[JSON_PROCESSING_SPEC-52] Make parsing location available to application code Created: 04/Feb/13  Updated: 08/Feb/13  Due: 08/Feb/13  Resolved: 08/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

The public review draft of the javax.json API does not make the parse location available to application code. Several members of the Toronto JUG indicated that this would be critically important to their adoption of the API.

It was suggested to create a Location type, and make location information available on request from JsonParser.getLocation(), and as a property of JsonParsingException.

Jitu pointed out that this was previously discussed on the mailing list. Here is that thread: http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/61



 Comments   
Comment by jitu [ 05/Feb/13 ]

StAX had Location, but all the information is optional as per javadoc.

Are there any real usecases for JsonParser.getLocation() ?

One proposal could be to add only to JsonParsingException (not for JsonParser):

interface JsonLocation

{ int getLineNumber(); int getColumnNumber(); int getStreamOffset(); }

-------
JsonParsingException(String message, JsonLocation location)
JsonParsingException(String message, Throwable cause, JsonLocation location)
JsonLocation getLocation()

Comment by jfuerth [ 05/Feb/13 ]

The JsonLocation interface you've proposed looks good.

I actually did ask one of the people who brought this up if it would be sufficient to put location information on the parsing exception only. He said no; he uses location information during his streaming XML parse, even when there are no syntax errors in the XML.

I don't know exactly what his use case is, but I can certainly imagine creating a system that throws an error when the data is semantically wrong. For example:

{ "id": 1234, "firstName": "Alice", "lastName": [1, 2, 3] }

although the above is a structurally valid JSON message, an application would likely want to reject it because lastName should be a string, but we were given an array. The application's own error message would be much better if it could include location information.

One final thought: unfortunately, we'll have to make location information optional too: when we are streaming a tree of JsonValues through JsonParser, there won't be an underlying character-oriented stream to calculate a line and column number from.

We could still require implementations to provide location information when the underlying data is coming from a string.

Comment by jitu [ 08/Feb/13 ]

Added JsonLocation as discussed





[JSON_PROCESSING_SPEC-30] Exposing Location in JsonParser and JsonParsingException Created: 03/Dec/12  Updated: 05/Feb/13  Resolved: 05/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

Location discussion is at
http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/70






[JSON_PROCESSING_SPEC-40] JsonBuilder and JsonReader should be interfaces Created: 11/Dec/12  Updated: 04/Feb/13  Resolved: 04/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

The current design limits possible performance improvements that could be obtained by custom parser implementations. A cleaner design would let the implementation provide both parser and object model implementations that are better integrated and higher performing.

If we implement http://java.net/jira/browse/JSON_PROCESSING_SPEC-9 a json structure could consist of a mix between implementations from the api package and implementation defined classes.

Builders would be created by static methods of the Json class or a JsonBuilderFactory created via the Json class.
JsonReader would require a JsonReaderFactory with similar methods to JsonParserFactory.

Discussion at http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/9 and http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/54



 Comments   
Comment by jitu [ 12/Dec/12 ]

Since JsonParser/JsonGenerator are already used by JsonReader/JsonGenerator, most of the performance improvements are available from a provider. Perhpas, the remaining improvements for JsonString/JsonNumber impl may not be much.

The high-level API should more usable than the low-level API, i.e new JsonArrayBuilder() etc is more user friendly.

Otherwise, a possible approach is to introduce
JsonReaderFactory, JsonWriterFactory, JsonBuilderFactory, and all possible methods on Json. That seem bit heavy-weight to me and not justify the performance benefits.

Comment by wenshao [ 13/Dec/12 ]

i can not understand why not be interfaces?

not just these two, should be interfaces include following:
JsonReader
JsonWriter
JsonArrayBuilder
JsonObjectBuilder

Comment by jhorstmann [ 07/Jan/13 ]

The current design, with only JsonParser as an implementation provided class, also seems to have performance problems of its own due to repeated ServiceLoader lookup. With JsonReader as an interface and a threadsafe JsonReaderFactory these lookups can be avoided.

Discussion at http://java.net/projects/json-processing-spec/lists/users/archive/2013-01/message/2

Comment by jitu [ 09/Jan/13 ]

One suggestion was to cache the provider so that there won't be service lookup costs for each JsonReader/JsonWriter. The cache strategy that is suggested is:
"The cache should be a ThreadLocal, and the cached value should include
a reference to the class loader that was used to look up the provider,
presumably the thread-context class loader. Use the cached provider only
when the saved class loader matches the one that you'd use if you were
going to look it up again."

Comment by jitu [ 04/Feb/13 ]

Made JsonReader, JsonWriter, JsonArrayWriter, JsonObjectWriter as interfaces.
Added JsonReaderFactor, JsonWriterFactory, JsonBuilderFactory interfaces to create these objects.

Added methods to create these objects as well as the factory classes.





[JSON_PROCESSING_SPEC-42] Add overview to the javadoc Created: 07/Jan/13  Updated: 04/Feb/13  Resolved: 04/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

Add a overview to javadoc so that the main page (http://json-processing-spec.java.net/nonav/releases/1.0/pr-draft/javadocs/index.html) will have scope and high-level description etc.



 Comments   
Comment by jitu [ 04/Feb/13 ]

Added the javadoc overview page





[JSON_PROCESSING_SPEC-49] Rename JsonString#getValue() to getStringValue() Created: 25/Jan/13  Updated: 04/Feb/13  Resolved: 04/Feb/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

It has two methods to get string data. getStringValue()/asString() would be more appropriate.



 Comments   
Comment by jitu [ 04/Feb/13 ]

Fixed as suggested





[JSON_PROCESSING_SPEC-50] Error in JavaDoc for JSONObjectBuilder Created: 31/Jan/13  Updated: 31/Jan/13  Resolved: 31/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pfd

Type: Improvement Priority: Major
Reporter: srivastava.apoorvkumar Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The JavaDoc has a sample JSONString

{
"firstName": "John", "lastName": "Smith", "age": 25,
"address" :

{ "streetAddress", "21 2nd Street", "city", "New York", "state", "NY", "postalCode", "10021" }

,
"phoneNumber": [

{ "type": "home", "number": "212 555-1234" }

,

{ "type": "fax", "number": "646 555-4567" }

]
}

Here the the value for key "address" is erroneous. It should either be an array or it should be converted in list of json key value pair using ' : ' .



 Comments   
Comment by jitu [ 31/Jan/13 ]

Fixing the typo as indicated in the issue

------------
[master 982aeae] JSON_PROCESSING_SPEC-50 Fixing typo in JSON text





[JSON_PROCESSING_SPEC-45] JsonObject/JsonArray accessor methods that take default values Created: 11/Jan/13  Updated: 31/Jan/13  Resolved: 31/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

See the discussion
http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/120
http://java.net/projects/json-processing-spec/lists/users/archive/2013-01/message/17



 Comments   
Comment by jitu [ 31/Jan/13 ]

Added the methods that take default values in both JsonArray and JsonObject





[JSON_PROCESSING_SPEC-43] JsonObject#getIntValue() javadoc says it would return null Created: 07/Jan/13  Updated: 30/Jan/13  Resolved: 30/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

Type: Bug Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JsonObject#getIntValue() javadoc says it would return null if there is no mapping. It should throw NPE if there is no mapping. Similarly, getStringValue() should throw NPE if there is no mapping.



 Comments   
Comment by jitu [ 30/Jan/13 ]

Resolving the issue as indicated in the description.





[JSON_PROCESSING_SPEC-47] Remove exception constructors Created: 25/Jan/13  Updated: 30/Jan/13  Resolved: 30/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

Feedback from exception handling section in http://crazyjavahacking.org/jsonProcessingReview.pdf

Remove
JsonException()
JsonException(Throwable)

JsonGenerationException()
JsonGenerationException(Throwable)

JsonParsingException()
JsonParsingException(Throwable)



 Comments   
Comment by jitu [ 30/Jan/13 ]

Fixing this as suggested in the issue.





[JSON_PROCESSING_SPEC-46] Missing constructor JsonReader(InputStream, Map<String, ?> Created: 24/Jan/13  Updated: 24/Jan/13  Resolved: 24/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

Type: Bug Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

JsonReader(InputStream, Map<String, ?>) constructor is missing. I think we should add that.



 Comments   
Comment by jitu [ 24/Jan/13 ]

Added the missing constructor





[JSON_PROCESSING_SPEC-44] Replace JsonFeature/JsonConfiguration with Properties Created: 11/Jan/13  Updated: 24/Jan/13  Resolved: 24/Jan/13

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pfd

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


 Description   

Brian Goetz's feedback

"I think JsonFeature is a mistake. You'll be playing whack-a-mole forever, and the spec will lag behind implementations with respect to features. Trying to capture all these strongly typed in the API is a recipe for chasing our tail."



 Comments   
Comment by jitu [ 24/Jan/13 ]

Removed JsonConfiguration/JsonFeature

Added Map<String, ?> as configuration as per discussion.





[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-6] Better name for JsonNumber#getNumberType() Created: 13/Jun/12  Updated: 14/Dec/12  Resolved: 14/Dec/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

Need a better name for JsonNumber#getNumberType(). The method is really returns just the smallest numeric type that can be used with that value.



 Comments   
Comment by jitu [ 14/Dec/12 ]

Got resolved with JSON_PROCESSING_SPEC-41. NumberType just gives INTEGER or DECIMAL





[JSON_PROCESSING_SPEC-41] Remove NumberType.LONG and rename NumberType.BigDecimal Created: 11/Dec/12  Updated: 14/Dec/12  Resolved: 14/Dec/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

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


 Description   

NumberType would be less confusing if it just stated the distinction whether a number has a fractional part.

A NumberType of INTEGER would guarantee that calling getBigIntegerValue does not throw an ArithmeticException. The NumberType would be independent of the actual magnitude of the number, thus calling getIntValueExact might still throw an Exception if the number is smaller than Integer.MIN_VALUE of larger than Integer.MAX_VALUE.

The current NumberType BIG_DECIMAL should be renamed to just DECIMAL or REAL (see http://en.wikipedia.org/wiki/Real_number) and would indicate that the number has a fractional part and calling get(Int|Long|BigInteger)ValueExact might throw an ArithmeticException.

The algorithm for distinguishing these two types should be based on whether BigDecimal#scale() is 0.

Discussion at http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/43



 Comments   
Comment by jhorstmann [ 11/Dec/12 ]

On a Jave ME profile of this JSON API, the methods getBigIntegerValue(Exact) and getBigDecimalValue would be excluded, NumberType should be INTEGER if the number can be exactly represented as a long, which is the largest integral type on such platforms.

Comment by jitu [ 11/Dec/12 ]

The current number type is the minimum holding number type. For 1.23e2, it gives INT.

This proposal is primarily removing "minimum holding" number type. So API doesn't provide a way if the integral number fits into int, long, BigInteger, and it becomes an application responsibility.

If applications don't require to know about this minimum holding number type, then I am fine with the proposal. I will see if there any comments internally.

Comment by keilw [ 12/Dec/12 ]

>The algorithm for distinguishing these two types should be based on whether >BigDecimal#scale() is 0.

What would it be on ME, as BigDecimal and BigInteger would not be there?

Aside from that, I fully agree with renaming BIG_DECIMAL to something like DECIMAL, REAL or FLOATING, which covers all numbers with decimal value.

And keep INTEGER or rename INT, ideally dropping the LONG.

An alternative could again be the JSON spec which knows
int

  • digit
  • digit1-9 digits
    • digit
    • digit1-9 digits

frac

  • . digits

exp

  • e digits

see http://json.org/

If there are sufficient algorithms to tell FRAC (which is quite similar to FLOATING or DECIMAL) from EXP, this may be closest to JSON design.

Werner

Comment by jitu [ 13/Dec/12 ]

ME could use a similar algo what scale() is doing to determine if the number has a fractional part or not.

I am thinking of rolling the following:

    /**
     * JSON number type that is used to find out if a number is numerically
     * integer or a decimal.
     */
    enum NumberType {
        /**
         * Represents a number that is numerically integer.
         * The value can be accessed as int, long, or BigInteger using
         * different JsonNumber accessor methods.
         */
        INTEGER,

        /**
         * Represents a number that is numerically decimal. The value can
         * be accessed as double, or BigDecimal using different JsonNumber
         * accessor methods.
         */
        DECIMAL
    }

    /**
     * Returns a JSON number type for this number.
     * A {@link BigDecimal} may be used to store the numeric value internally
     * and the semantics of this method is defined using
     * {@link BigDecimal#scale()}.
     * If the scale of a value is zero, then its number type is
     * {@link NumberType#INTEGER INTEGER} else {@link NumberType#DECIMAL DECIMAL}.
     *
     * <p>
     * The number type can be used to invoke appropriate accessor methods to get
     * numeric value for the number.
     * <p>
     * <b>For example:</b>
     * <code>
     * <pre>
     * switch(getNumberType()) {
     *     case INTEGER :
     *         long l = getLongValue(); break;
     *     case DECIMAL :
     *         BigDecimal bd = getBigDecimalValue(); break;
     * }
     * </pre>
     * </code>
     *
     * @return a number type
     */
    NumberType getNumberType();
Comment by jhorstmann [ 13/Dec/12 ]

A ME profile would probably store the number in a double, which has no concept similar to BigDecimal#scale(). It could return type INTEGER if getDoubleValue() == Math.floor(getDoubleValue());, but this would return different results than an implementation based on BigDecimal for numbers like "1.0".

The equivalent code with BigDecimal would be:

try {
    bd.setScale(0, RoundingMode.UNNECESSARY);
    return NumberType.INTEGER;
} catch (ArithmeticException ex) {
    return NumberType.DECIMAL;
}

If we can not decide on the correct semantics, then it would probably be better to remove the NumberType distinction completely or defer it to a future version.

Comment by jitu [ 13/Dec/12 ]

Let me commit the proposal in this issue. I don't think we need to define what ME is going to do here now. Anyway, ME needs to define semantics for other methods like equals(), hashCode() etc.

Comment by jitu [ 14/Dec/12 ]

Resolving with the proposal in this issue





[JSON_PROCESSING_SPEC-39] JSON API renaming: s/JsonArray/JsonList and s/JsonObject/JsonMap Created: 11/Dec/12  Updated: 13/Dec/12  Resolved: 13/Dec/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Mark Reinhold's feedback
-------------------------
Looking at this API in depth for the first time, I kept getting confused
by the name "JsonObject".

In Java terms, what JSON calls an "Object" is just a map, from strings to
JSON values. Java already uses "Object" as the unifying supertype of all
types, so I'd expect "JsonObject" to unify (some set of) JSON-specific
value types.

This suggests a renaming along these lines:

JsonObject --> JsonMap
JsonObjectBuilder --> JsonMapBuilder
JsonStructure --> JsonObject

I think Java developers would find this more natural, since most will
never read the actual JSON specification.

Remember that this API is for Java developers, not readers of the JSON
specification.
-------------



 Comments   
Comment by jitu [ 11/Dec/12 ]

I received the same feedback from Brian Goetz earlier. But some libraries are already using JsonObject and JsonArray, so we continued that naming. But this API is for Java developers, so we should follow what is suggested by Mark and Brian.

This would also mean we need to change in other places

JsonArray --> JsonList
JsonArrayBuilder --> JsonListBuilder

  • JsonReader and JsonWriter changes
    s/readArray/readList
    s/readObject/readMap

s/writeArray/writeList
s/writeObject/writeMap

  • JsonGenerator
    s/writeStartArray/writeStartList
    s/writeStartObject/writeStartMap
  • We have events (like START_ARRAY etc) in the JsonParser. Those need to be changed to START_LIST etc
  • ValueType has ARRAY and OBJECT, those will be changed to LIST and MAP.
Comment by jitu [ 13/Dec/12 ]

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

Based on the discussion, resolving this one with no action.





[JSON_PROCESSING_SPEC-35] Add ability to read/writer numeric types as String Created: 07/Dec/12  Updated: 12/Dec/12  Resolved: 12/Dec/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: blaise_doughan Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Allow Strings to be written to and read from JSON numeric types.

Relevant Use Cases:

  • Ensure I can get a value represented as 1.23e10 (JSON allows this representation)
  • If I have a form that is being using to collection data, this data can be written to JSON without first having to convert it to a numeric type.
  • Make it easier to port data from XML to JSON, again no need to first convert it to a numeric type.


 Comments   
Comment by jitu [ 07/Dec/12 ]

Suggest the following methods in JsonGenerator.

JsonGenerator writeNumber(String name, String number)
JsonGenerator writeNumber(String number)

The number string value needs to be validated as per JSON grammar.

Comment by jitu [ 12/Dec/12 ]

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

Based on the discussion, resolving with no action.





[JSON_PROCESSING_SPEC-2] A reader.readObject() call that reads JsonObject stream with duplicate keys should throw exception Created: 03/May/12  Updated: 12/Dec/12  Resolved: 12/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

Type: Bug Priority: Minor
Reporter: adf59 Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

reader = new JsonReader(new StringReader("

{\"foo\":\"bar\",\"foo\":\"foo\"}

"));
JsonValue jv = reader.readObject();

It seems that the above readObject() should throw an exception if duplicate keys exist within an object.



 Comments   
Comment by jitu [ 12/Dec/12 ]

It just overwrites the mapping with new values(similar to Map)





[JSON_PROCESSING_SPEC-12] JsonObjectBuilder should throw exception for duplicate keys Created: 16/Oct/12  Updated: 12/Dec/12  Resolved: 12/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

JsonObjectBuilder should throw exception for duplicate keys while buiding JSON Objects



 Comments   
Comment by jitu [ 03/Dec/12 ]

Should we throw exception or overwrite the existing mapping ?

Comment by jitu [ 12/Dec/12 ]

If there already exists a mapping for key, it just replaces the old value with the new one(similar to Map).





[JSON_PROCESSING_SPEC-38] Extend JsonArray with List<JsonValue> and JsonObject with Map<String, JsonValue> Created: 09/Dec/12  Updated: 11/Dec/12  Resolved: 11/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

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


 Description   

Mark Reinhold's feedback:
----------
Is there a reason that JsonObject
(current name) doesn't implement java.util.Map<String,JsonValue>
directly? It seems awkward to have to invoke a getValues() method
in order to get an actual Map.
------------
My hesistation is Map has mutable methods. He still considers there
is value by implementing these collections. He says:
------------
The mutating methods in the Map interface are all optional; you can just
have them throw UnsupportedOperationException.

Along similar lines, JsonList should implement java.util.List<JsonValue>.

These two changes will make it much easier to leverage the existing
collections framework as well as all the Lambda goodness coming in SE 8.
----------------



 Comments   
Comment by jitu [ 11/Dec/12 ]

Fixing it as specified in the issue: JsonArray extends List<JsonValue> and JsonObject extends Map<String, JsonValue>





[JSON_PROCESSING_SPEC-36] JSON builder improvements Created: 07/Dec/12  Updated: 10/Dec/12  Resolved: 10/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

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


 Description   

Feedback from Mark Reinhold
--------------------------------------
The EDR javadoc for JsonObject contains this builder-pattern example:

    JsonObject object = new JsonBuilder()
        .beginObject()
            .add("firstName", "John")
            .add("lastName", "Smith")
            .add("age", 25)
            .beginObject("address")
                .add("streetAddress", "21 2nd Street")
                .add("city", "New York")
                .add("state", "NY")
                .add("postalCode", "10021")
            .endObject()
            .beginArray("phoneNumber")
                .beginObject()
                    .add("type", "home")
                    .add("number", "212 555-1234")
                .endObject()
                .beginObject()
                    .add("type", "home")
                    .add("number", "646 555-4567")
                .endObject()
            .endArray()
        .endObject()
    .build();

One problem with this style is that the structure of the object being
constructed is not reflected in the syntax of the expression. A reader
must visually scan for "begin" and "end" methods in order to understand
the resulting object structure, or even just to indent the code.

Here's a variant of the above example written against a (hypothetical)
alternative API:

    JsonObject value = new JsonObjectBuilder()
        .add("firstName", "John")
        .add("lastName", "Smith")
        .add("age", 25)
        .add("address", new JsonObjectBuilder()
             .add("streetAddress", "21 2nd Street")
             .add("city", "New York")
             .add("state", "NY")
             .add("postalCode", "10021"))
        .add("phoneNumber", new JsonArrayBuilder()
             .add(new JsonObjectBuilder()
                  .add("type", "home")
                  .add("number", "212 555-1234"))
             .add(new JsonObjectBuilder()
                  .add("type", "home")
                  .add("number", "646 555-4567")))
        .build();

Note how the structure of the resulting object is obvious from the
structure of the expression, which (by the way) is indented correctly
(at least by Emacs) without any manual effort at all. You also don't
need the "end" methods.

Have you considered a design that would support this style? I think
it's much more readable.
--------------------------



 Comments   
Comment by jitu [ 07/Dec/12 ]

The current design was used by JsonBuilder as well as JsonGenerator, and it is more suitable from streaming generation. Now JsonGenerator is moved to its own abstraction, this proposal is appealing.

Here are some observations:

  • proposal seems to be simpler
  • here one has to start with JsonObjectBuilder and JsonArrayBuilder. In the current design, one just starts with JsonBuilder always.
  • uses two classes, instead of all the other baggage like JsonBuildable, JsonBuilder
  • avoids the generics trick which end() method is doing.
  • end() is not required
  • The earlier design also works for generating JSON in a streaming fashion. Now(after EDR) JsonGenerator uses its own abstraction, so this seems more suitable now.
  • I think this is also guarantees compile-time safety to the building objects similar to the current one i.e one cannot add JSON array values in objects (name/value pairs)
  • I think we can still add existing JsonArray/JsonObject

I would like to incorporate the Marc's proposal.

Comment by jitu [ 10/Dec/12 ]

Incorporating the suggested proposal.





[JSON_PROCESSING_SPEC-24] Provide write() methods for Map<String,Object> and List in JsonWriter Created: 27/Nov/12  Updated: 09/Dec/12  Resolved: 09/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: Sutanu Ghosh Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The JsonWriter can have two additional write() methods to serialize a Map<String,Object> and a List.

JsonWriter {
write(Map<String,Object> jsonObject)
write(List jsonArray)
}

Map<String,Object> --> JSON object
List --> JSON array
The element objects in the Map or List can be any valid Java-JSON types or a Map or a List.

This will avoid the need to convert a Map<String,Object> or a List object to a JsonObject or JsonArray respectively before serializing via JsonWriter.



 Comments   
Comment by jitu [ 09/Dec/12 ]

Will consider JsonArray to implement List<JsonValue> and
JsonObject to implement Map<String, JsonValue>

Other than that we don't provide support any Object





[JSON_PROCESSING_SPEC-26] Provide read() methods to return Map<String,Object> and List in JsonReader Created: 27/Nov/12  Updated: 09/Dec/12  Resolved: 09/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: Sutanu Ghosh Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The JsonReader can have two additional read() methods to de-serialize a JSON object or array.

JsonReader {
Map<String,Object> readObjectAsMap( )
List readArrayAsList( )
}

Map<String,Object> --> JSON object
List --> JSON array
The element objects in the Map or List can be any valid Java-JSON types or a Map or a List.

This will avoid the need to convert a JsonObject or JsonArray to a Map<String,Object> or a List object respectively after de-serializing via JsonReader.



 Comments   
Comment by jitu [ 09/Dec/12 ]

Will consider JsonArray to implement List<JsonValue>
and JsonObject to implement Map<String, JsonValue>





[JSON_PROCESSING_SPEC-21] Add toString() to JsonObject/JsonArray Created: 25/Oct/12  Updated: 09/Dec/12  Resolved: 09/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

toString() should give the JSON representation



 Comments   
Comment by jitu [ 25/Oct/12 ]

Adding JsonValue#toString() method

Comment by jitu [ 03/Dec/12 ]

Closing the issue

Comment by jitu [ 09/Dec/12 ]

Need to mark the Fix version

Comment by jitu [ 09/Dec/12 ]

Marking the fix version





[JSON_PROCESSING_SPEC-37] Json has too many methods Created: 08/Dec/12  Updated: 08/Dec/12  Resolved: 08/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed 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-12/message/19

Keep only commonly created parser, generator methods. Other variations can be got from their factories.



 Comments   
Comment by jitu [ 08/Dec/12 ]

Fixing it as suggested in the thread
http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/31





[JSON_PROCESSING_SPEC-34] Consistent inner class names : s/JsonValueType/ValueType s/JsonNumberType/NumberType Created: 06/Dec/12  Updated: 08/Dec/12  Resolved: 08/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed 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/jsr353-experts/archive/2012-12/message/36



 Comments   
Comment by jitu [ 08/Dec/12 ]

Done the specified change





[JSON_PROCESSING_SPEC-33] Make Json class constructor private Created: 05/Dec/12  Updated: 05/Dec/12  Resolved: 05/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Bug Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed 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/jsr353-experts/archive/2012-12/message/24



 Comments   
Comment by jitu [ 05/Dec/12 ]

Making Json class constructor private





[JSON_PROCESSING_SPEC-19] Add JsonParsingException, JsonGenerationException Created: 24/Oct/12  Updated: 05/Dec/12  Resolved: 05/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

The following thread has exception discussion
http://java.net/projects/json-processing-spec/lists/users/archive/2012-10/message/27



 Comments   
Comment by jitu [ 05/Dec/12 ]

Added JsonParsingException and JsonGenerationException as per discussion. They are used primarily to catch incorrect JSON while parsing and generating





[JSON_PROCESSING_SPEC-5] Super type for JsonArray and JsonObject Created: 13/Jun/12  Updated: 03/Dec/12  Resolved: 01/Aug/12

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

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


 Description   

Need a common supertype for JsonArray and JsonObject. Otherwise, the object model API
has two "top level" types and that looks odd. A common type would make it easy to pass
JSON text around. The changes would be:

public interface JsonText {
}

public interface JsonArray extends JsonValue, JsonText {
}

public interface JsonObject extends JsonValue, JsonText {
}

public class JsonBuilder {

public static interface JsonBuildable<T extends JsonText>

{ ..}

...
}

public class JsonWriter implements Closeable {
public void write(JsonText value)

{ ... }
}

public class JsonReader implements Closeable {
public JsonText read() { ... }

}

Can also use JsonDocument instead of JsonText, but JsonText is preferred as it is
used by grammar.

Perhaps, we also need to add START_TEXT, END_TEXT parser events.



 Comments   
Comment by jhorstmann [ 13/Jun/12 ]

Isn't JsonValue already the common supertype?

From the grammar in the rfc, json text would be the serialized form of an object or array. I think this distinction between serialized form and object model should be made clear in the api, as that is not always the case with other json libs.

The only common property of object and array would perhaps be a 'size' property. If you think another interface would be useful then I would suggest a name like JsonContainer or JsonStructure. The term structure also appears in the rfc, but might be mistaken for a C struct, which is more like a json object.

Comment by jitu [ 13/Jun/12 ]

JsonValue is a supertype of JsonArray/JsonObject but that also includes other values like JsonString, JsonNumber etc. Hence the new type.

Your have a point about serialized form and the use of JsonText etc. Simiarly, some suggested to use JsonMap/JsonList instead of JsonObject/JsonArray(when I experimented with this, this renaming is not coming out well).

Comment by jitu [ 01/Aug/12 ]

Let me use JsonStructure for now. If we find a better name, we will use it.





[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






[JSON_PROCESSING_SPEC-17] JsonParser shouldn't extend Iterable Created: 24/Oct/12  Updated: 03/Dec/12  Resolved: 24/Oct/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed 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-04/message/72



 Comments   
Comment by jitu [ 24/Oct/12 ]

Checked with SE team regarding Iterable. Here is a comment

"While the specifications do not require that an Iterable can be iterated repeatedly/consistently, many users expect this and are likely to be confused if they cannot.

If you do not intend iterator() to return a fresh "rewound" view every time, then you should probably follow the convention set by Socket.getInputStream(), which returns the same stream on every call.

You definitely don't want to implement Iterator; a parser is-not-a Iterator. One option would be to have an iterator() method but not implement Iterable, where the iterator() method was spec'ed to behave as above – just return the same Iterator object every time. All you lose there is the foreach loop support – no big deal.

Overall I think you sow more confusion than benefit by implementing Iterable.

When you get to EE 8 you can implement Streamable too!"

Based on this, added iterator() method.





[JSON_PROCESSING_SPEC-18] Add convenient accessor methods for string, int values on JsonArray and JsonObject Created: 24/Oct/12  Updated: 03/Dec/12  Resolved: 25/Oct/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

Type: Bug Priority: Major
Reporter: jitu Assignee: jitu
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Instead of calling JsonArray.getValue(0, JsonString.class).getValue(), provide
a convenient method JsonArray.getStringValue(0). Similarly they should be
added for JsonObject as well.



 Comments   
Comment by jitu [ 25/Oct/12 ]

Adding the following methods:
JsonArray.java
+ public String getStringValue(int index);
+ public int getIntValue(int index);

JsonObject.java
+ public String getStringValue(String name);
+ public int getIntValue(String name);





[JSON_PROCESSING_SPEC-27] Remove JsonParser#iterator() method Created: 27/Nov/12  Updated: 03/Dec/12  Resolved: 03/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

Remove JsonParser#iterator() method and replace with hasNext() and next(). The problem with iterator is not returning self-contained events. One has to go back forth between iterator and parser objects. One proposal was to use advance() (instead of hasNext()) and getEvent() (instead of next()), but most users preferred hasNext()/next().

Some of the discussion is at:
http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/63



 Comments   
Comment by jitu [ 03/Dec/12 ]

Replaced iterator() method with hasNext()/next() methods.





[JSON_PROCESSING_SPEC-23] JsonBuilder method names:s/begin/start Created: 20/Nov/12  Updated: 03/Dec/12  Resolved: 03/Dec/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

s/beginArray/startArray
s/beingObject/startObject
s/endObject/end
s/endArray/end

This would reflect JsonParser events. JsonGenerator also uses "writeStartXXX"



 Comments   
Comment by jitu [ 03/Dec/12 ]

changed method names





[JSON_PROCESSING_SPEC-20] remove JsonValue Created: 25/Oct/12  Updated: 30/Nov/12  Resolved: 30/Nov/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

Type: Improvement Priority: Major
Reporter: wenshao Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It is difficult to use.

JsonArray & JsonObject should direct support primitive type, include:

Byte, Short, Integer, Long, BigInteger, BigDecimal, Float, Double
Boolean, String
null

JsonArray & JsonObject should include pirimitive operation, like:
class JsonObject {
int getIntValue(String name, int defaultValue);
Integer getInt(String name);
long getLongValue(String name, int defaultValue);
Long getLong(String name);
... ...

JsonArray getJsonArray(String name);
JsonObject getJsonObject(String name);
}

class JsonArray {
int getIntValue(int index, int defaultValue);
Integer getInt(int index);
long getLongValue(int index, int defaultValue);
Long getLong(int index);
... ...

JsonArray getJsonArray(int index);
JsonObject getJsonObject(int index);
}



 Comments   
Comment by jitu [ 25/Oct/12 ]

I have already added few methods in JsonObject and JsonArray for common cases. They are convenience methods(still use JsonValue), see http://java.net/jira/browse/JSON_PROCESSING_SPEC-18

You are raising bigger question which is to not use JsonString, JsonNumber. Instead, use existing types.
There are few use cases:

  • For example, if the JSON string data is huge, we cannot map to String. But JsonString could be used (perhaps backed up by a file)
  • Number has two many types. And if a number needs to be represented as String, it would be a problem since string is used for JSON string.
  • Having a common type helps, but if it is too difficult to use, then we should consider again. Other option is to mix and match primitives and JsonValue types. But that would be too messy.

Let us take the discussion to users mailing list.

Comment by jitu [ 30/Nov/12 ]

There was quite a bit of discussion on the mailing list and also with JDK architects.

Closing this one without any fix.





[JSON_PROCESSING_SPEC-1] Do not require that all content end up in String or char[] Created: 04/Feb/12  Updated: 30/Nov/12  Resolved: 30/Nov/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

Type: New Feature Priority: Major
Reporter: headius Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In my work on the JRuby project, it has become painfully obvious that many Java APIs lose performance out of the gate because of the cost of decoding all incoming bytes to char[] before processing them. This also makes it difficult for JVM languages that use a different String representation to use those APIs.

I propose that the JSON processing API for Java should not impose String or char[] on consumers unnecessarily. In the style of the "spymemcached" library, it should be possible to register a factor that can create strings of other forms directly from the incoming bytes, allowing for parsing and processing JSON without ever decoding. This would make it possible (and may be necessary) to match the performance of C-based libraries, and allows consumers that do not want decoded characters/strings to use the raw bytes directly.

I will be monitoring this JSR once activity begins and discussions are made public.



 Comments   
Comment by headius [ 04/Feb/12 ]

My description should read "register a factory" instead of "register a factor".

Comment by jitu [ 13/Jun/12 ]

Updating the issue with some related discussion:

http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/0
http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/2
http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/22
http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/23
http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/25

Comment by jitu [ 21/Nov/12 ]

We are supporting byte streams, but we are not exposing byte[] in parser or JsonString. I think that would be less useful for developers. Moreover, one needs to encoding of the underlying stream to use it.

Comment by headius [ 26/Nov/12 ]

I hope you can elaborate on that a bit. Supporting byte streams but still transcoding everything to UTF-16 char strings would defeat all the gains of being able to work directly with bytes.

The factory suggestion still seems like the cleanest way. In an ideal world, we'd be able to register a factory that receives the incoming byte[] + offsets and we can then construct whatever string-like structure we want from that. It would avoid unnecessary transcoding for languages and libraries that can work directly with bytes, and it would eliminate lots of transient objects and overhead from going to String eagerly.

I'd like to understand better what you mean by "supporting byte streams".

Comment by jitu [ 26/Nov/12 ]

We are supporting creation of parser objects using byte streams like InputStream (rather than character streams like Reader). Some of the provider impl take advantage of working with byte streams for certain encodings and don't convert to characters internally.

At the application level, most users would be consuming them as String and the provider impls produce the String when it is asked. The pull parser is lazy in that sense. You are suggesting to add something like the following approaches:

1) A way to register/use factory
JsonParser

{ void setFactory(SomeFactory<T> f) // valid in VALUE_STRING, KEY_NAME states // go through SomeFactory to create T T getStringObject(byte[] buf, int offset, int len) }

or

2) one other alternative using already existing JsonString interface

JsonParser

{ + JsonString getString(); }

// May be existing JsonString is good enough(no need to add additional methods like getBytes etc)
JsonString

{ .. + byte[] getBytes(); + Charset getCharset(); }

I think exposing bytes doesn't work well at the application level for various reasons. One of the reasons is escaping of characters and one cannot expose the internal buffer directly as it is. I think a custom provider and a subtype of JsonParser would be good for this case.

I will start a thread on the users list. Please follow there.

Comment by jitu [ 30/Nov/12 ]

Resolving without any action as per the discussion
http://java.net/projects/json-processing-spec/lists/users/archive/2012-11/message/81





[JSON_PROCESSING_SPEC-28] JsonString#getChars() that return CharSequence Created: 30/Nov/12  Updated: 30/Nov/12  Resolved: 30/Nov/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

JsonString#getChars() that returns a CharSequence would be useful so that a big string need not be created



 Comments   
Comment by jitu [ 30/Nov/12 ]

Added the method

/**

  • Returns the char sequence for the JSON String value
    *
  • @return a char sequence for JSON String value
    */
    CharSequence getChars();




[JSON_PROCESSING_SPEC-14] equals()/hashcCode() for object model Created: 19/Oct/12  Updated: 29/Nov/12  Resolved: 29/Nov/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

Define equals()/hashCode() semantics



 Comments   
Comment by jitu [ 29/Nov/12 ]

equals()/hashCode() is defined as follows:

JsonNumber

  • BigDecimal getBigDecimal(). BigDecimal is used for equals()/hashCode()

JsonObject

  • Map<String, JsonValue> getValues(). Map is used for equals()/hashCode()

JsonArray

  • List<JsonValue> getValues(). List is used for equals()/hashCode()

JsonString

  • String getString(). String is used for equals()/hashCode()

JsonTrue/JsonFalse/JsonNull

  • JsonValueType getValueType(). The corresponding enum is used for equals()/hashCode()




[JSON_PROCESSING_SPEC-10] Clarify default provider class loading semantics Created: 07/Sep/12  Updated: 27/Nov/12  Resolved: 27/Nov/12

Status: Closed
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

If a OSGi bundle includes both api+impl without META-INF/services entry, the default impl won't be loaded by TCC(since TCC may be webapp classloader)



 Comments   
Comment by jitu [ 27/Nov/12 ]

Not specifying how a default provider is loaded.

  • Also considered specifying a system property for a provider name. The order considered was:
    1) system property
    2) ServiceLoader
    3) default provider

That doesn't work well when a webapp bundles its own provider in a war file (if a system property is already defined).

  • If we define the order to be
    1) ServiceLoader
    2) System property
    3) default provider

then system property doesn't work well(since one of the providers are picked up using ServiceLoader).

so not specifying system property as it is of limited use.





[JSON_PROCESSING_SPEC-13] JsonParser/JsonGenerator/JsonReader/JsonWriter close() need to close underlying source Created: 16/Oct/12  Updated: 27/Nov/12  Resolved: 27/Nov/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0-pr

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


 Description   

close() need to call close on the underlying source as that seems like more common usage. So make this as default. Some more discussion is at:
http://java.net/projects/json-processing-spec/lists/users/archive/2012-10/message/11



 Comments   
Comment by jitu [ 27/Nov/12 ]

Javadoc is updated to close the underlying source by default.





[JSON_PROCESSING_SPEC-11] Flushable for JsonGenerator Created: 15/Oct/12  Updated: 27/Nov/12  Resolved: 27/Nov/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.0-pr

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


 Description   

See the thread
http://java.net/projects/json-processing-spec/lists/users/archive/2012-10/message/17



 Comments   
Comment by jitu [ 27/Nov/12 ]

Reworked JsonGenerator and it implements Flushable now.





[JSON_PROCESSING_SPEC-25] Provide read() methods to retrun Map<String,Object> and List in JsonReader Created: 27/Nov/12  Updated: 27/Nov/12  Resolved: 27/Nov/12

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

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


 Description   

The JsonWriter can have two additional write() methods to serialize a Map<String,Object> and a List.

JsonWriter {
write(Map<String,Object> jsonObject)
write(List jsonArray)
}

Map<String,Object> --> JSON object
List --> JSON array
The element objects in the Map or List can be any valid Java-JSON types or a Map or a List.

This will avoid the need to convert a Map<String,Object> or a List object to a JsonObject or JsonArray respectively before serializing via JsonWriter.



 Comments   
Comment by Sutanu Ghosh [ 27/Nov/12 ]

Please close. Bad description when I cloned another one.

Comment by jitu [ 27/Nov/12 ]

Closing a per the user request





[JSON_PROCESSING_SPEC-15] Use Charset instead of string in methods Created: 23/Oct/12  Updated: 29/Oct/12  Resolved: 24/Oct/12

Status: Resolved
Project: json-processing-spec
Component/s: None
Affects Version/s: 1.0-pr
Fix Version/s: 1.0-pr

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


 Description   

For e.g.:
s/JsonReader(InputStream in, String encoding)/JsonReader(InputStream,
CharSet)
JDK 7 defined constants for standard charsets in StandardCharsets. For e.g
StandardCharsets.UTF_8
Applications take advantage of those constants when they use JDK 7. That
also means that API doesn't have to specify
of wrapping UnsupportedEncodingException in many places. Infact, it seems to
be that some places UnsupportedCharsetException/IllegalCharsetNameException
would be more appropriate than UnsupportedEncodingException.



 Comments   
Comment by jitu [ 24/Oct/12 ]

Added Charset instead of String while creating JsonParser/JsonGenerator/JsonReader/JsonWriter.





[JSON_PROCESSING_SPEC-16] java bean direct to json string Created: 24/Oct/12  Updated: 25/Oct/12  Resolved: 25/Oct/12

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

Type: New Feature Priority: Major
Reporter: wenshao Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

now jsonp only support:
json object -> json string
json string -> json object

it should support:
javabean -> json string
json string -> java bean

it's simple use, and good performance.

like fastjson's api:

com.alibaba.fastjson.JSON.toJSONString(Object)

demo:
https://github.com/AlibabaTech/fastjson/blob/master/src/test/java/com/alibaba/json/demo/Demo2.java



 Comments   
Comment by wenshao [ 24/Oct/12 ]

json string -> java bean :

VO vo = JSON.parseObject("...json string...", VO.class);

Comment by wenshao [ 24/Oct/12 ]

in the china, fastjson is very popular. it's really fast.

https://github.com/eishay/jvm-serializers/wiki/Staging-Results

6 times performance to gson, 2 times performance to jackson, 50 times performance to json-lib.

it's simple to use:
String jsonString = JSON.toJSONString(javaBean);
VO vo = JSON.parseObject("...json string ...", VO.class);

Comment by jitu [ 24/Oct/12 ]

This is outside of the current JSR scope. There will be JSON-Binding JSR that would address this usecase

Comment by jitu [ 25/Oct/12 ]

Resolving this one as this is outside the JSR scope





[JSON_PROCESSING_SPEC-8] Factory to create JsonParser, JsonGenerator instances Created: 13/Jun/12  Updated: 15/Oct/12  Resolved: 15/Oct/12

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

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


 Description   

The following user thread has all the discussion:
http://java.net/projects/json-processing-spec/lists/users/archive/2012-04/message/41



 Comments   
Comment by jitu [ 15/Oct/12 ]

Factory classes are already added





[JSON_PROCESSING_SPEC-7] Don't extend JsonArray with Iterable<JsonValue> Created: 13/Jun/12  Updated: 25/Jun/12  Resolved: 25/Jun/12

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

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


 Description   

May be JsonArray shouldn't extend with Iterable<JsonValue>. By extending, it is committing to the particular type and hard to change later. Also, collections are going through major changes w.r.t lambdafication. There is already a method to get List<JsonValue> which is Iterable<JsonValue> and if required we add an additional method.



 Comments   
Comment by jitu [ 25/Jun/12 ]

Resolving it: JsonArray doesn't extend Iterable<JsonValue> anymore





[JSON_PROCESSING_SPEC-3] addArray methods in Builder Created: 21/May/12  Updated: 18/Jun/12  Resolved: 18/Jun/12

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

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


 Description   

Feedback on addArray methods: "API already has beginArray() for starting a new array, better to turn this into addAll(Iterable<JsonValue>) which would add all the elements of the iterable at the current point. That way addAll() can do double-duty both to bulk-add into the currently built array, or you can do .beginArray().addAll(iterable).endArray() to add a nested array."



 Comments   
Comment by jitu [ 21/May/12 ]

Proposed changes are:

Remove
JsonArrayBuilder#addArray(Iterable<JsonValue>)
JsonObjectBuilder#addArray(String, Iterable<JsonValue>)

and add
JsonArrayBuilder#addAll(Iterable<JsonValue>)

Comment by illsleydc [ 26/May/12 ]

I definitely agree with the need for an addAll to JsonArrayBuilder, but I think it's worth exploring further and adding a few... (I don't know where a developer would normally be getting the Iterable<JsonValue> from?)

addAll(Iterable<String>), addAll(Iterable<Integer>), addAll(Iterable<Double>)

The obvious inefficiency here is for people with int[] or double[]. For them, addAll(int...) etc would be better. That could get to be a lot of methods, but with consistent naming, it might not feel too overwhelming.

Comment by jitu [ 14/Jun/12 ]

> I definitely agree with the need for an addAll to JsonArrayBuilder, but I think it's worth exploring further and adding a few... (I don't know where a developer would normally be getting the Iterable<JsonValue> from?)

The developer may get Iterable<JsonValue> from an existing JsonArray, say JsonArray#getValues().

>addAll(Iterable<String>), addAll(Iterable<Integer>), addAll(Iterable<Double>)
>The obvious inefficiency here is for people with int[] or double[]. For them, addAll(int...) etc would be better. That could get to be a lot of methods, but with consistent naming, it might not feel too overwhelming.

We already have methods to add one JsonValue, int, String etc. Perhaps, we just remove the current addArray() methods and not add any new addAll methods. A developer can add them using the existing methods in a loop. If the addAll methods really needed, we can add them later.

Comment by jitu [ 18/Jun/12 ]

Removing the addArray methods on the builders.





[JSON_PROCESSING_SPEC-4] Need a method to get the number of values in JsonArray Created: 23/May/12  Updated: 12/Jun/12  Resolved: 12/Jun/12

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

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


 Description   

Feedback: "If there is going to be indexed access there needs to be a way to
obtain the length in JsonArray"



 Comments   
Comment by jitu [ 23/May/12 ]

Proposed solution is to add the following method to JsonArray that gives the number of values in a JSON array

int size()

Comment by illsleydc [ 26/May/12 ]

Makes sense to me.





Generated at Thu Jul 30 04:33:06 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.