Skip to main content

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

  • From: Tatu Saloranta < >
  • To:
  • Subject: [json-processing-spec users] Re: How to create JsonNumber, JsonString instances?
  • Date: Mon, 4 Mar 2013 20:15:42 -0800

On Mon, Mar 4, 2013 at 8:14 PM, Jitendra Kotamraju
< >
 wrote:
> On 03/01/2013 08:27 AM, Tatu Saloranta wrote:
>>
>> On Thu, Feb 28, 2013 at 10:35 PM, Jitendra Kotamraju
>> < >
>>  wrote:
>>>
>>> On 2/28/13 7:16 PM, Tatu Saloranta wrote:
>>>>
>>>> I have played a bit with API, to create basic converters to/from
>>>> JsonValues, and things mostly work as expected.
>>>> But one thing I bumped into is this: how does one create JsonNumber or
>>>> JsonString instances? Arrays and Objects can be built, and other
>>>> values are singletons (null, true, false). But I am somehow missing
>>>> methods for asking implementation to provide number and string values.
>>>> Is this omission intentional?
>>>
>>> That was intentional.
>>>
>>>> For most use cases I can indirectly create these by adding into arrays
>>>
>>> Yes, builders create JsonNumber, JsonString instances behind the scenes
>>> using primitive and String types.  Builders can also reuse if there are
>>> any
>>> of those instances from other array and objects. So we haven't provided a
>>> way for developers to create those instances from scratch (unless
>>> creating
>>> custom implementations for those interfaces).
>>>
>>>> and objects, but it complicates building process slightly, so I am
>>>
>>> Can you elaborate your usecase. Is the building process using builders or
>>> do
>>> you require them for some other usecase ?
>>
>> In general this simplifies building tree nodes (JsonValues) from any
>> source. My particular use case is reading JsonValues using Jackson
>> streaming parser. It is a straight-forward recursive-descent approach,
>> where ability to parse individual values (not just arrays, objects,
>> but scalars) makes code very simple.
>>
>> Ideally something like:
>>
>> ----
>>
>>      public JsonValue deserialize(JsonParser jp, DeserializationContext
>> ctxt)
>>              throws IOException, JsonProcessingException
>>      {
>>          switch (jp.getCurrentToken()) {
>>          case START_OBJECT:
>>            {
>>              JsonObjectBuilder b = _builderFactory.createObjectBuilder();
>>              while (jp.nextToken() != JsonToken.END_OBJECT) {
>>                 String name = jp.getCurrentName();
>>                 jp.nextToken();
>>                 b.add(name, deserialize(jp, ctxt));
>>              }
>>              return b.build();
>>          case START_ARRAY:
>>              {
>>                JsonArrayBuilder b = _builderFactory.createArrayBuilder();
>>                while (jp.nextToken() != JsonToken.END_ARRAY) {
>>                  b.add(deserialize(jp, ctxt));
>>                }
>>              }
>>              return _deserializeArray(jp, ctxt);
>>          case VALUE_NUMBER_INT: // etc
>>              // This is missing!
>>              return provider.createNumber(jp.getIntValue();
>
> True, or your impl could return a custom JsonNumber impl.
>
>>          default:
>>              return _deserializeScalar(jp, ctxt);
>>          }
>>
>> ---
>>
>> Now, in absence of a factory method (or if JsonValue types were final,
>> having them as interfaces adds complexity here), I have to either
>> duplicate code for Array and Object case; or use contrived work-around
>> to add number to an array, return it:
>>
>>                  JsonArrayBuilder b =
>> _builderFactory.createArrayBuilder();
>>                  return b.add(jp.getLongValue()).build().get(0);
>
> Yes, that's one way, but may not be efficient. The API doesn't have much
> support to get scalars.

Right.

>> Hope this helps!
>>
>> Aside from this, the only other minor problem I found was lack of
>> methods to detect underlying number type (which was discussed
>> earlier).
>>
>> On plus side, I was able to create this:
>>
>https://github.com/FasterXML/jackson-datatype-jsr353
>
> This is interesting. This works with *any* 353 provider.

Yes that's the idea.

>> rather easily, so that one can use Jackson streaming readers to read
>> JsonValues and streaming generators to write them out. Which means
>> that it's technically easy to make Tree Model part of JSR-353 to
>> interoperate with Jackson at least.
>
> Looks like there are more options here :
> - One way is to bypass the builders, and just implement the JsonValue types.
> It is only 4 classes: Array, Object, Number and String.
>
> - Other option is that existing Jackson tree model can directly implement
> the types, but
> doesn't have to implement other classes like builders etc.
> - Also, if Jackson implements 353 provider, then it has all the necessary
> classes.
> - There are other options
>
> I don't know which one is going to be better. Some of the things that come
> up during
> these projects can be considered for next version.

Right. It's not a big deal, just leads to bit of code duplication. I
went ahead and used builder add methods, except for root value, where
a work-around is needed. I wish I had noticed this before
specification was finalized; Provider would have been simple and
natural place to add these.

-+ Tatu +-


[json-processing-spec users] How to create JsonNumber, JsonString instances?

Tatu Saloranta 03/01/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

David Schlosnagle 03/01/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

Tatu Saloranta 03/01/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

Jitendra Kotamraju 03/01/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

Tatu Saloranta 03/01/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

Jitendra Kotamraju 03/05/2013

[json-processing-spec users] Re: How to create JsonNumber, JsonString instances?

Tatu Saloranta 03/05/2013
 
 
Close
loading
Please Confirm
Close