001package Torello.JSON;
002
003import Torello.JavaDoc.Annotations.IntoHTMLTable;
004import static Torello.JavaDoc.Annotations.IntoHTMLTable.Background.BlueDither;
005import static Torello.JavaDoc.Annotations.IntoHTMLTable.Background.GreenDither;
006
007import static Torello.JSON.JFlag.*;
008
009import javax.json.*;
010
011import java.lang.reflect.Constructor;
012import java.lang.reflect.Modifier;
013
014import java.util.Objects;
015import java.util.function.Function;
016
017import static javax.json.JsonValue.ValueType.*;
018
019/**
020 * Builds on the J2EE Standard Release JSON Parsing Tools by providing additional
021 * help with converting JSON Data into Java Object-Data.
022 * 
023 * <EMBED CLASS='external-html' DATA-FILE-ID=ALL_CLASSES_NOTE>
024 * <EMBED CLASS='external-html' DATA-FILE-ID=READ_JSON>
025 * <EMBED CLASS='external-html' DATA-FILE-ID=JO_DESERIALIZE>
026 * 
027 * @see Json
028 * @see JsonObject
029 * @see JsonArray
030 */
031@Torello.JavaDoc.Annotations.StaticFunctional
032public class ReadJSON
033{
034    // This is a static class.  Has no program state.
035    private ReadJSON() { }
036
037
038    // ********************************************************************************************
039    // ********************************************************************************************
040    // Object, Class<T>
041    // ********************************************************************************************
042    // ********************************************************************************************
043
044
045    /**
046     * Retrieve a {@link JsonArray} element, and transform it to a Java {@code Object} (POJO).
047     * <EMBED CLASS='external-HTML' DATA-FILE-ID=READ_POJO_NOTE>
048     * <EMBED CLASS=defs DATA-JTYPE=JsonObject DATA-TYPE='Type Parameter T'>
049     * 
050     * @param <T>           <EMBED CLASS='external-html' DATA-FILE-ID=READ_TYPE_PARAM_T>
051     * @param ja            Any instance of {@link JsonArray}
052     * @param index         A valid index into {@code 'ja'}
053     * @param c             <EMBED CLASS='external-html' DATA-FILE-ID=READ_C>
054     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JA>
055     * @return              <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_RET_TON_JA>
056     * 
057     * @throws IndexOutOfBoundsException    If {@code 'index'} is out of bounds of {@code 'ja'}
058     * @throws NullPointerException         If either {@code 'c'} or {@code 'ja'} are passed null
059     * @throws InvalidClassException        <EMBED CLASS='external-html' DATA-FILE-ID=INV_CLASS_EX>
060     * @throws JsonTypeArrException         <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTAEX>
061     * @throws JsonNullArrException         <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNAEX>
062     * @throws JsonBuildPOJOArrException    <EMBED CLASS='external-html' DATA-FILE-ID=READ_JBPAEX>
063     */
064    public static <T> T getObject(
065            final JsonArray ja,
066            final int       index,
067            final Class<T>  c,
068            final boolean   throwOnNull
069        )
070    {
071        final JsonValue         jv      = NPE_CHECK_JA(ja).get(index);
072        final Constructor<T>    ctor    = InvalidClassException.check(c);
073
074        switch (jv.getValueType())
075        {
076            case NULL:
077                // This is simple-stuff (not rocket-science).  "Type Mapping" Code has to worry
078                // about what the meaning of "null" should be.
079
080                if (throwOnNull)    throw new JsonNullArrException(ja, index, OBJECT, c);
081                else                return null;
082
083            case OBJECT:
084                try 
085                    { return ctor.newInstance((JsonObject) jv); }
086
087                catch (Exception e)
088                    { throw new JsonBuildPOJOArrException(e, ja, index, (JsonObject) jv, c); }
089
090            // The JsonValue at the specified array-index does not contain a JsonObject.
091            default: throw new JsonTypeArrException(ja, index, OBJECT, jv, c);
092        }
093    }
094
095    /**
096     * Extract a {@link JsonObject} property, and transform it to a Java {@code Object} (POJO).
097     * <EMBED CLASS='external-HTML' DATA-FILE-ID=READ_POJO_NOTE>
098     * <EMBED CLASS=defs DATA-TYPE='Type Parameter T' DATA-JTYPE=JsonObject>
099     * 
100     * @param <T>           <EMBED CLASS='external-html' DATA-FILE-ID=READ_TYPE_PARAM_T>
101     * @param jo            Any instance of {@link JsonObject}.
102     * @param propertyName  Any property name contained by {@code 'jo'}
103     * @param isOptional    <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_IS_OPTIONAL>
104     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JO>
105     * @return              <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_RET_TON_JO>
106     * 
107     * @throws JsonPropMissingException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JPMEX>
108     * @throws NullPointerException         If {@code 'jo', 'propertyName'} or {@code 'c'} are null
109     * @throws InvalidClassException        <EMBED CLASS='external-html' DATA-FILE-ID=INV_CLASS_EX>
110     * @throws JsonTypeObjException         <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTOEX>
111     * @throws JsonNullObjException         <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNOEX>
112     * @throws JsonBuildPOJOObjException    <EMBED CLASS='external-html' DATA-FILE-ID=READ_JBPOEX>
113     */
114    public static <T> T getObject(
115            final JsonObject    jo,
116            final String        propertyName, 
117            final Class<T>      c,
118            final boolean       isOptional,
119            final boolean       throwOnNull
120        )
121    {
122        final JsonValue         jv      = NPE_CHECK_JO(jo, propertyName);
123        final Constructor<T>    ctor    = InvalidClassException.check(c);
124
125        if (jv == null)
126        {
127            if (isOptional) return null;
128            throw new JsonPropMissingException(jo, propertyName, OBJECT, c);
129        }
130
131        switch (jv.getValueType())
132        {
133            case NULL:
134
135                // This is simple-stuff (not rocket-science).  "Type Mapping" Code has to
136                // worry about what the meaning of "null" should be.
137
138                if (throwOnNull)    throw new JsonNullObjException(jo, propertyName, OBJECT, c);
139                else                return null;
140
141            case OBJECT:
142                try 
143                    { return ctor.newInstance(jo); }
144
145                catch (Exception e)
146                {
147                    throw new JsonBuildPOJOObjException
148                        (e, jo, propertyName, (JsonObject) jv, c);
149                }
150
151                // The JsonObject propertydoes not contain a JsonObject.
152            default: throw new JsonTypeObjException(jo, propertyName, OBJECT, jv, c);
153        }
154    }
155
156
157    // ********************************************************************************************
158    // ********************************************************************************************
159    // Object, Function<JsonObject, T>
160    // ********************************************************************************************
161    // ********************************************************************************************
162
163
164    /** <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_GETOBJ_JA2> */
165    @IntoHTMLTable(
166        title=
167            "Reads one JsonObject from a JsonArray, and uses a Generator Function to build " +
168            "a POJO",
169        background=BlueDither
170    )
171    public static <T> T getObject(
172            final JsonArray                         ja,
173            final int                               index,
174            final Function<JsonObject, ? extends T> builderFunction,
175            final Class<T>                          c,
176            final boolean                           throwOnNull
177        )
178    {
179        final JsonValue jv = NPE_CHECK_JA(ja).get(index);
180
181        switch (jv.getValueType())
182        {
183            case NULL:
184                if (throwOnNull)    throw new JsonNullArrException(ja, index, OBJECT, c);
185                else                return null;
186
187            case OBJECT:
188                try 
189                    { return builderFunction.apply((JsonObject) jv); }
190
191                catch (Exception e)
192                    { throw new JsonBuildPOJOArrException(e, ja, index, (JsonObject) jv, c); }
193
194            default: throw new JsonTypeArrException(ja, index, OBJECT, jv, c);
195        }
196    }
197
198    /** <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_GETOBJ_JO2> */
199    @IntoHTMLTable(
200        title=
201            "Reads one JsonObject from a JsonArray, and uses a Generator Function to build " +
202            "a POJO",
203        background=GreenDither
204    )
205    public static <T> T getObject(
206            final JsonObject                        jo,
207            final String                            propertyName,
208            final Function<JsonObject, ? extends T> builderFunction,
209            final Class<T>                          c,
210            final boolean                           isOptional,
211            final boolean                           throwOnNull
212        )
213    {
214        final JsonValue jv = NPE_CHECK_JO(jo, propertyName);
215
216        if (jv == null)
217        {
218            if (isOptional) return null;
219            throw new JsonPropMissingException(jo, propertyName, OBJECT, c);
220        }
221
222        switch (jv.getValueType())
223        {
224            case NULL:
225                if (throwOnNull)    throw new JsonNullObjException(jo, propertyName, OBJECT, c);
226                else                return null;
227
228            case OBJECT:
229                try 
230                    { return builderFunction.apply((JsonObject) jv); }
231
232                catch (Exception e)
233                {
234                    throw new JsonBuildPOJOObjException
235                        (e, jo, propertyName, (JsonObject) jv, c);
236                }
237
238            default: throw new JsonTypeObjException(jo, propertyName, OBJECT, jv, c);
239        }
240    }
241
242    /**
243     * This class contains a lot of the reason / impetus for writing {@code 'ReadJSON'}.  This
244     * does converts a {@link JsonObject} into a Java-Object.  The actual binding must be
245     * implemented by the programmer - because the class-type that is passed to this method
246     * (parameter {@code 'c'}) must have a constructor accepting this {@code JsonObject}.
247     * 
248     * <EMBED CLASS='external-html' DATA-FILE-ID=READ_POJO_NOTE>
249     * 
250     * @param <T>   <EMBED CLASS='external-html' DATA-FILE-ID=READ_TYPE_PARAM_T>
251     * @param jo    This may be any {@link JsonObject} which can be bound to {@code 'c'}.
252     * @param c     <EMBED CLASS='external-html' DATA-FILE-ID=READ_C>
253     * @return      An instance of the class {@code 'T'}, which is specified by {@code 'c'}
254     * 
255     * @throws JsonException        <EMBED CLASS='external-html' DATA-FILE-ID=READ_JEX_REFL>
256     * @throws NullPointerException If {@code 'jo'} or {@code 'c'} are passed null
257     * 
258     * @throws InvalidClassException Throws if a valid, single-argument, {@code 'JsonObject'}
259     * constructor is not present or is not accessible within {@code 'c'}
260     */
261    public static <T> T getObject(JsonObject jo, Class<T> c)
262    { 
263        Objects.requireNonNull(jo, "You have passed null to Class Parameter 'jo'");
264        Objects.requireNonNull(c, "You have passed null to Class Parameter 'c'");
265
266        final Constructor<T> ctor = InvalidClassException.check(c);
267
268        try
269            { return ctor.newInstance(jo); }
270
271        catch (Exception e)
272        {
273            // *MANY* possible Exception's may be thrown, and *ALL* are checked exceptions
274            throw new JsonException(
275                "Unable to instantiate class: [" + c.getName() + "] using provided " +
276                    "Java-Object\n" +
277                "See Exception.getCause() for details.",
278                e
279            );
280        }
281    }
282
283
284    // ********************************************************************************************
285    // ********************************************************************************************
286    // String
287    // ********************************************************************************************
288    // ********************************************************************************************
289
290
291    /**
292     * Retrieve a {@link JsonArray} element, and transform it to a {@code java.lang.String}.
293     * <EMBED CLASS=defs DATA-JTYPE=JsonString DATA-TYPE='java.lang.String'>
294     * 
295     * @param ja            Any instance of {@link JsonArray}
296     * @param index         A valid index into {@code 'ja'}
297     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JA>
298     * @return              <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_RET_TON_JA>
299     * 
300     * @throws IndexOutOfBoundsException If {@code 'index'} is out of the bounds of {@code 'ja'}
301     * @throws JsonTypeArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTAEX>
302     * @throws JsonNullArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNAEX>
303     * @throws NullPointerException      If {@code 'ja'} is passed null.
304     * 
305     * @see JsonValue#getValueType()
306     * @see JsonValue.ValueType#STRING
307     */
308    public static String getString(JsonArray ja, int index, boolean throwOnNull)
309    {
310        // This will also throw an IndexOutOfBoundsException if the index is out of bounds.
311        final JsonValue jv = NPE_CHECK_JA(ja).get(index);
312
313        switch (jv.getValueType())
314        {
315            case NULL:
316
317                // This is simple-stuff (not rocket-science).  "Type Mapping" Code has to worry
318                // about what the meaning of "null" should be.
319
320                if (throwOnNull) throw new JsonNullArrException(ja, index, STRING, String.class);
321                else return null;
322
323            case STRING: return ((JsonString) jv).getString();
324
325            // The JsonValue at the specified array-index does not contain a JsonString.
326            default: throw new JsonTypeArrException(ja, index, STRING, jv, String.class);
327        }
328    }
329
330    /**
331     * Extract a {@link JsonObject} property, and transform it to a {@code java.lang.String}.
332     * <EMBED CLASS=defs DATA-TYPE='java.lang.String' DATA-JTYPE=JsonString>
333     * 
334     * @param jo            Any instance of {@link JsonObject}.
335     * @param propertyName  Any property name contained by {@code 'jo'}
336     * @param isOptional    <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_IS_OPTIONAL>
337     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JO>
338     * @return              <EMBED CLASS='external-html' DATA-FILE-ID=READJSON_RET_TON_JO>
339     * 
340     * @throws JsonPropMissingException <EMBED CLASS='external-html' DATA-FILE-ID=READ_JPMEX>
341     * @throws JsonTypeObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTOEX>
342     * @throws JsonNullObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNOEX>
343     * @throws NullPointerException     if either {@code 'jo'} or {@code 'propertyName'} are null
344     * 
345     * @see JsonValue#getValueType()
346     * @see JsonValue.ValueType#STRING
347     */
348    public static String getString
349        (JsonObject jo, String propertyName, boolean isOptional, boolean throwOnNull)
350    {
351        final JsonValue jv = NPE_CHECK_JO(jo, propertyName);
352
353        if (jv == null)
354        {
355            if (isOptional) return null;
356            throw new JsonPropMissingException(jo, propertyName, STRING, String.class);
357        }
358
359        switch (jv.getValueType())
360        {
361            case NULL:
362
363                // This is simple-stuff (not rocket-science).  "Type Mapping" Code has to worry
364                // about what the meaning of "null" should be.
365
366                if (throwOnNull) throw new JsonNullObjException
367                    (jo, propertyName, STRING, String.class);
368
369                else return null;
370
371            case STRING: return ((JsonString) jv).getString();
372
373            // The JsonObject propertydoes not contain a JsonString.
374            default: throw new JsonTypeObjException(jo, propertyName, STRING, jv, String.class);
375        }
376    }
377
378
379    // ********************************************************************************************
380    // ********************************************************************************************
381    // JsonObject
382    // ********************************************************************************************
383    // ********************************************************************************************
384
385
386    /**
387     * Extract an instance of {@link JsonObject} from an instance of {@link JsonArray}.
388     * 
389     * <EMBED CLASS=defs DATA-JTYPE=JsonObject DATA-TYPE=JsonObject>
390     * @param ja            Any instance of {@link JsonArray}
391     * @param index         A valid index into {@code 'ja'}
392     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JA>
393     * 
394     * @return The requested {@link JsonObject}, or null (only if null's have been permitted).
395     * @throws IndexOutOfBoundsException If {@code 'index'} is out of bounds of {@code 'ja'}
396     * @throws JsonTypeArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTAEX>
397     * @throws JsonNullArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNAEX>
398     * @throws NullPointerException      If {@code 'ja'} is passed null
399     * 
400     * @see JsonValue#getValueType()
401     * @see JsonValue.ValueType#OBJECT
402     */
403    public static JsonObject getJsonObject(JsonArray ja, int index, boolean throwOnNull)
404    {
405        // This will also throw an IndexOutOfBoundsException if the index is out of bounds.
406        final JsonValue jv = NPE_CHECK_JA(ja).get(index);
407
408        switch (jv.getValueType())
409        {
410            case NULL:
411                if (throwOnNull)
412                    throw new JsonNullArrException(ja, index, OBJECT, JsonObject.class);
413                else
414                    return null;
415
416            case OBJECT: return (JsonObject) jv;
417
418            // The JsonValue at the specified array-index does not contain a JsonObject.
419            default: throw new JsonTypeArrException(ja, index, OBJECT, jv, JsonObject.class);
420        }
421    }
422
423    /**
424     * Extract an instance of {@link JsonObject} from an instance of {@link JsonObject}.
425     *  
426     * <EMBED CLASS=defs DATA-JTYPE=JsonObject DATA-TYPE=JsonObject>
427     * @param jo            Any instance of {@link JsonObject}.
428     * @param propertyName  Name of the JSON property that should be contained within {@code 'jo'}
429     * @param isOptional    <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_IS_OPTIONAL>
430     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JO>
431     * 
432     * @return The requested {@link JsonObject}, or null (only if null's have been permitted).
433     * @throws JsonPropMissingException <EMBED CLASS='external-html' DATA-FILE-ID=READ_JPMEX>
434     * @throws JsonTypeObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTOEX>
435     * @throws JsonNullObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNOEX>
436     * @throws NullPointerException     if either {@code 'jo'} or {@code 'propertyName'} are null
437     * 
438     * @see JsonValue#getValueType()
439     * @see JsonValue.ValueType#OBJECT
440     */
441    public static JsonObject getJsonObject
442        (JsonObject jo, String propertyName, boolean isOptional, boolean throwOnNull)
443    {
444        final JsonValue jv = NPE_CHECK_JO(jo, propertyName);
445
446        if (jv == null)
447        {
448            if (isOptional) return null;
449            throw new JsonPropMissingException(jo, propertyName, OBJECT, JsonObject.class);
450        }
451
452        switch (jv.getValueType())
453        {
454            case NULL:
455                if (throwOnNull)
456                    throw new JsonNullObjException(jo, propertyName, OBJECT, JsonObject.class);
457                else
458                    return null;
459
460            case OBJECT: return (JsonObject) jv;
461
462            // The JsonValue at the specified property does not contain a JsonObject.
463            default:
464                throw new JsonTypeObjException(jo, propertyName, OBJECT, jv, JsonObject.class);
465        }
466    }
467
468
469    // ********************************************************************************************
470    // ********************************************************************************************
471    // JsonArray
472    // ********************************************************************************************
473    // ********************************************************************************************
474
475
476    /**
477     * Extract an instance of {@link JsonArray} from an instance of {@link JsonArray}.
478     * 
479     * <EMBED CLASS=defs DATA-JTYPE=JsonArray DATA-TYPE=JsonArray>
480     * @param ja            Any instance of {@link JsonArray}
481     * @param index         A valid index into {@code 'ja'}
482     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JA>
483     * 
484     * @return The requested {@link JsonArray}, or null (only if null's have been permitted).
485     * @throws IndexOutOfBoundsException If {@code 'index'} is out of bounds of {@code 'ja'}
486     * @throws JsonTypeArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTAEX>
487     * @throws JsonNullArrException      <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNAEX>
488     * @throws NullPointerException     if {@code 'ja'} is passed null
489     * 
490     * @see JsonValue#getValueType()
491     * @see JsonValue.ValueType#ARRAY
492     */
493    public static JsonArray getJsonArray(JsonArray ja, int index, boolean throwOnNull)
494    {
495        // This will also throw an IndexOutOfBoundsException if the index is out of bounds.
496        final JsonValue jv = NPE_CHECK_JA(ja).get(index);
497
498        switch (jv.getValueType())
499        {
500            case NULL:
501                if (throwOnNull)
502                    throw new JsonNullArrException(ja, index, ARRAY, JsonArray.class);
503                else
504                    return null;
505
506            case ARRAY: return (JsonArray) jv;
507
508            // The JsonValue at the specified property does not contain a JsonArray.
509            default: throw new JsonTypeArrException(ja, index, ARRAY, jv, JsonArray.class);
510        }
511    }
512
513    /**
514     * Extract an instance of {@link JsonArray} from an instance of {@link JsonObject}.
515     *  
516     * <EMBED CLASS=defs DATA-JTYPE=JsonArray DATA-TYPE=JsonArray>
517     * @param jo            Any instance of {@link JsonObject}.
518     * @param propertyName  Name of the JSON property that should be contained within {@code 'jo'}
519     * @param isOptional    <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_IS_OPTIONAL>
520     * @param throwOnNull   <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_THROW_ON_JO>
521     * 
522     * @return The requested {@link JsonArray}, or null (only if null's have been permitted).
523     * @throws JsonPropMissingException <EMBED CLASS='external-html' DATA-FILE-ID=READ_JPMEX>
524     * @throws JsonTypeObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JTOEX>
525     * @throws JsonNullObjException     <EMBED CLASS='external-html' DATA-FILE-ID=READ_JNOEX>
526     * @throws NullPointerException     if either {@code 'jo'} or {@code 'propertyName'} are null
527     * 
528     * @see JsonValue#getValueType()
529     * @see JsonValue.ValueType#ARRAY
530     */
531    public static JsonArray getJsonArray
532        (JsonObject jo, String propertyName, boolean isOptional, boolean throwOnNull)
533    {
534        final JsonValue jv = NPE_CHECK_JO(jo, propertyName);
535
536        if (jv == null)
537        {
538            if (isOptional) return null;
539            throw new JsonPropMissingException(jo, propertyName, ARRAY, JsonArray.class);
540        }
541
542        switch (jv.getValueType())
543        {
544            case NULL:
545                if (throwOnNull)
546                    throw new JsonNullObjException(jo, propertyName, ARRAY, JsonArray.class);
547                else
548                    return null;
549
550            case ARRAY: return (JsonArray) jv;
551
552            // The JsonValue at the specified property does not contain a JsonArray.
553            default:
554                throw new JsonTypeObjException(jo, propertyName, ARRAY, jv, JsonArray.class);
555        }
556    }
557
558    // ********************************************************************************************
559    // ********************************************************************************************
560    // Internal Methods
561    // ********************************************************************************************
562    // ********************************************************************************************
563
564
565    private static JsonArray NPE_CHECK_JA(JsonArray ja)
566    {
567        Objects.requireNonNull(ja, "You have passed null to JsonArray Parameter 'ja'");
568        return ja;
569    }
570
571    private static JsonValue NPE_CHECK_JO(JsonObject jo, String property)
572    {
573        Objects.requireNonNull(jo, "You have passed null to JsonObject Parameter 'jo'");
574        Objects.requireNonNull(property, "You have passed null to String Parameter 'property'");
575        return jo.get(property);
576    }
577
578    private static JsonObject NPE_CHECK_JO(JsonObject jo)
579    {
580        Objects.requireNonNull(jo, "You have passed null to JsonObject Parameter 'jo'");
581        return jo;
582    }
583}