001package Torello.JSON;
002
003import Torello.Java.StringParse;
004import Torello.Java.UnreachableError;
005
006import Torello.Java.Function.IntTFunction;
007import Torello.Java.Function.IntIntTFunc;
008
009import Torello.Java.Additional.Counter;
010
011import java.util.function.Function;
012import java.util.function.Predicate;
013
014import java.math.BigDecimal;
015import java.math.BigInteger;
016
017import javax.json.JsonNumber;
018import javax.json.JsonObject;
019import javax.json.JsonArray;
020
021
022// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
023// This class provides LAMBDA'S / FUNCTION-POINTERS / FUNCTIONAL-INTERFACES
024// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
025// 
026// OK, This Class provides the Vast-Majority of the Lambda / Functional-Interfaces that can be 
027// associated with the Standard Java Primitive-Types which are handled by this Json-Package.  This 
028// Package handle 7 of 8 standard Java-Types, but leaves out the 'char' Primitive-Type, because 
029// Json doesn't have much of anything resembling a 'char' type, and the concept just seemed 
030// generally, completely unnecessary.
031// 
032// This class also has a configuration-record for the types: String, Number & even Object.
033// 
034//
035// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
036// WHAT TO KNOW ABOUT THESE LAMBDA'S
037// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
038// 
039// The Lambda's which are "stored" or "saved" in all of the builder methods here are exactly the 
040// Lambda's which *DO NOT REQUIRE USER-INPUT* in order to generate.  This is "as opposed to" the
041// Functional-Interfaces which are produced by the Class 'TempFlags'.
042// 
043// In class "TempFlags", the Lambda-Functions that are generated / selected / produced there are
044// in *STRICT ADHERENCE* with the choices that the user has made using the "JFlags" parameter - the
045// Flag-Mask that allows a user to confgure specific behavior of the Json-Parser.
046// 
047// To summarize - *AGAIN* - the Lambda's / Functional-Interfaces / a.k.a. "Method Pointers" which 
048// are declared inside this class are all of the ones which are associated with the **SPECIFIC 
049// TYPE** that was decided-upon, based on the RJArr Method that he has invoked.  These Lambda's
050// are constant, and would never change based on user-preference.  Though they could be eliminated
051// or ignored, it isn't possible for them to "Modified by User-Preferences", etc...
052// 
053// Class 'TempFlags' has a giant dispatch engine that dispatches based on flags the user has
054// provided
055// 
056// 
057// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
058// The "Funtion-Pointer" Reminder
059// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
060// 
061// It is important to remember that everything that is done inside the Json-Array Processing 
062// Classes (Specifically, those which begin with "RJArr") - is done by a single "Processing Loop"
063// Main-Class.  Please review the contents of the "ProcessJsonArray" class to see how any 
064// invocation of either the RJArr: Stream, Consumer or Array Classes all use the "ProcessJsonArray"
065// class to perform their parse.
066// 
067// This is acheived by wrapping the dozens of User-Choices, Configurations, Preferences & 
068// Selections into a suite of Functional-Interfaces (Function-Pointers) and saving them inide of 
069// a giant "SettingsRec".  The Java Byte-Code Optimizer is likely capable of doing enough 
070// optimizations to ensure that all of the Pointer-Reference "De-Referencing" that is going on 
071// is done efficiently.  More testing needs to be done to check this out...
072
073public class BASIC_TYPES<T>
074{
075    // ********************************************************************************************
076    // ********************************************************************************************
077    // Main Fields  (These are used to FURTHER help configure class "SettingsRec")
078    // ********************************************************************************************
079    // ********************************************************************************************
080
081
082    // Used by the Multi-Dimensional Array Processor only
083    // final Function<JsonArray, U> array1DGenerator;
084
085    final byte whichType;
086
087    // Essentially: Not STRING, BOOLEAN or OBJECT
088    final boolean isNumberType;
089
090    // same as primitive or boxed (I think)
091    final boolean referenceOrPrimitive;
092
093    // Class of the Stream.Builder "accept" Parameter
094    final Class<T> CLASS;
095
096    // Number size tester
097    final Predicate<JsonNumber> jsonNumWillFit;
098
099    // String-tester (for parsing number-strings)
100    final Predicate<String> validStrTester;
101
102    // default-parser (number-string to Integer)
103    final Function<String, T> defaultParser;
104
105    // numberConverter (JAPPROX_ON_AEX *AND* usual-ans)
106    final Function<Number, T> numberConverter;
107
108    // Generates AEX on fail
109    final Function<BigDecimal, T> numberConverterExThrow;
110
111
112    // ********************************************************************************************
113    // ********************************************************************************************
114    // Exported (and also internally used) Static Constants
115    // ********************************************************************************************
116    // ********************************************************************************************
117
118
119    static final boolean REFERENCE  = true;
120    static final boolean BOXED      = true;
121    static final boolean PRIMITIVE  = false;
122
123    static final byte INTEGER = 0;
124    static final byte SHORT   = 1;
125    static final byte BYTE    = 2;
126    static final byte LONG    = 3;
127    static final byte DOUBLE  = 4;
128    static final byte FLOAT   = 5;
129
130    static final byte BOOLEAN = 6;
131    static final byte NUMBER  = 7;
132    static final byte STRING  = 8;
133
134    static final byte JSON_OBJECT   = 9;
135    static final byte JSON_ARRAY    = 10;
136
137    static final byte EXTENDED_OBJ  = 11;
138
139
140    // ********************************************************************************************
141    // ********************************************************************************************
142    // Internal, Private, Static Singleton-Instances THAT ARE INITIALLY NULL AND ARE LAZILY-LOADED!
143    // ********************************************************************************************
144    // ********************************************************************************************
145
146
147    // Rather than generating 18 Records, 16 or 17 of which will likely never be used throughout 
148    // the life-cycle of the program, this set of fields are all assigned null, and are not
149    // instantiated until they are requested by the user.
150    // 
151    // These are, indeed, all singleton instances that contain CONSTANT-DATA which is re-used for 
152    // each and every call for a request of the configurations that are present inside this data
153    // class.
154
155    private static BASIC_TYPES<Integer>     BOXED_INTEGER       = null;
156    private static BASIC_TYPES<Integer>     PRIMITIVE_INTEGER   = null;
157
158    private static BASIC_TYPES<Short>       BOXED_SHORT         = null;
159    private static BASIC_TYPES<Short>       PRIMITIVE_SHORT     = null;
160
161    private static BASIC_TYPES<Byte>        BOXED_BYTE          = null;
162    private static BASIC_TYPES<Byte>        PRIMITIVE_BYTE      = null;
163
164    private static BASIC_TYPES<Long>        BOXED_LONG          = null;
165    private static BASIC_TYPES<Long>        PRIMITIVE_LONG      = null;
166
167    private static BASIC_TYPES<Double>      BOXED_DOUBLE        = null;
168    private static BASIC_TYPES<Double>      PRIMITIVE_DOUBLE    = null;
169
170    private static BASIC_TYPES<Float>       BOXED_FLOAT         = null;
171    private static BASIC_TYPES<Float>       PRIMITIVE_FLOAT     = null;
172
173    private static BASIC_TYPES<Boolean>     BOXED_BOOLEAN       = null;
174    private static BASIC_TYPES<Boolean>     PRIMITIVE_BOOLEAN   = null;
175
176    private static BASIC_TYPES<String>      STRING_REC          = null;
177    private static BASIC_TYPES<Number>      NUMBER_REC          = null;
178
179    private static BASIC_TYPES<JsonObject>  JSON_OBJECT_REC     = null;
180    private static BASIC_TYPES<JsonArray>   JSON_ARRAY_REC      = null;
181
182
183    // ********************************************************************************************
184    // ********************************************************************************************
185    // The Lazy-Loading Methods / Getters (These methods do both at the same time)
186    // ********************************************************************************************
187    // ********************************************************************************************
188
189
190    // These are nothing more than "getters" for the above Data-Field Singleton-Instances.  These 
191    // 18 methods are simply designed to return the same constant singleton instance each and every
192    // time that any of these methods are invoked.
193    // 
194    // Most important, notice that on the very first call to these methods, the value assigned to 
195    // these fields will always be null (after being loaded by the class-loader).  These methods 
196    // will call the constructor for these fields the first time they are called, and then from
197    // point forward, the same singleton will be returned each and ever time
198
199    static BASIC_TYPES<Integer> BOXED_INTEGER()
200    { return (BOXED_INTEGER !=null) ? BOXED_INTEGER : (BOXED_INTEGER = INTEGER(BOXED)); }
201
202    static BASIC_TYPES<Integer> PRIMITIVE_INTEGER()
203    {
204        return (PRIMITIVE_INTEGER !=null)
205            ? PRIMITIVE_INTEGER
206            : (PRIMITIVE_INTEGER = INTEGER(PRIMITIVE));
207    }
208
209
210    static BASIC_TYPES<Short> BOXED_SHORT()
211    { return (BOXED_SHORT !=null) ? BOXED_SHORT : (BOXED_SHORT = SHORT(BOXED)); }
212
213    static BASIC_TYPES<Short> PRIMITIVE_SHORT()
214    { return (PRIMITIVE_SHORT !=null) ? PRIMITIVE_SHORT : (PRIMITIVE_SHORT = SHORT(PRIMITIVE)); }
215
216
217    static BASIC_TYPES<Byte> BOXED_BYTE()
218    { return (BOXED_BYTE !=null) ? BOXED_BYTE : (BOXED_BYTE = BYTE(BOXED)); }
219
220    static BASIC_TYPES<Byte> PRIMITIVE_BYTE()
221    { return (PRIMITIVE_BYTE !=null) ? PRIMITIVE_BYTE : (PRIMITIVE_BYTE = BYTE(PRIMITIVE)); }
222
223
224    static BASIC_TYPES<Long> BOXED_LONG()
225    { return (BOXED_LONG !=null) ? BOXED_LONG : (BOXED_LONG = LONG(BOXED)); }
226
227    static BASIC_TYPES<Long> PRIMITIVE_LONG()
228    { return (PRIMITIVE_LONG !=null) ? PRIMITIVE_LONG : (PRIMITIVE_LONG = LONG(PRIMITIVE)); }
229
230
231    static BASIC_TYPES<Double> BOXED_DOUBLE()
232    { return (BOXED_DOUBLE !=null) ? BOXED_DOUBLE : (BOXED_DOUBLE = DOUBLE(BOXED)); }
233
234    static BASIC_TYPES<Double> PRIMITIVE_DOUBLE()
235    {
236        return (PRIMITIVE_DOUBLE !=null)
237            ? PRIMITIVE_DOUBLE
238            : (PRIMITIVE_DOUBLE = DOUBLE(PRIMITIVE));
239    }
240
241
242    static BASIC_TYPES<Float> BOXED_FLOAT()
243    { return (BOXED_FLOAT !=null) ? BOXED_FLOAT : (BOXED_FLOAT = FLOAT(BOXED)); }
244
245    static BASIC_TYPES<Float> PRIMITIVE_FLOAT()
246    { return (PRIMITIVE_FLOAT !=null) ? PRIMITIVE_FLOAT : (PRIMITIVE_FLOAT = FLOAT(PRIMITIVE)); }
247
248
249    static BASIC_TYPES<Boolean> BOXED_BOOLEAN()
250    { return (BOXED_BOOLEAN !=null) ? BOXED_BOOLEAN : (BOXED_BOOLEAN = BOOLEAN(BOXED)); }
251
252    static BASIC_TYPES<Boolean> PRIMITIVE_BOOLEAN()
253    {
254        return (PRIMITIVE_BOOLEAN !=null)
255            ? PRIMITIVE_BOOLEAN
256            : (PRIMITIVE_BOOLEAN = BOOLEAN(PRIMITIVE));
257    }
258
259
260    static BASIC_TYPES<Number> NUMBER_REC()
261    { return (NUMBER_REC !=null) ? NUMBER_REC : (NUMBER_REC = NUMBER()); }
262
263    static BASIC_TYPES<String> STRING_REC()
264    { return (STRING_REC !=null) ? STRING_REC : (STRING_REC = STRING()); }
265
266    static BASIC_TYPES<JsonObject> JSON_OBJECT_REC()
267    { return (JSON_OBJECT_REC !=null) ? JSON_OBJECT_REC : (JSON_OBJECT_REC = JO()); }
268
269    static BASIC_TYPES<JsonArray> JSON_ARRAY_REC()
270    { return (JSON_ARRAY_REC !=null) ? JSON_ARRAY_REC : (JSON_ARRAY_REC = JA()); }
271
272
273    // ********************************************************************************************
274    // ********************************************************************************************
275    // Constructor
276    // ********************************************************************************************
277    // ********************************************************************************************
278
279
280    private BASIC_TYPES(
281            final byte                      whichType,
282            final boolean                   referenceOrPrimitive,
283            final Class<T>                  CLASS,
284            final Predicate<JsonNumber>     jsonNumWillFit,
285            final Predicate<String>         validStrTester,
286            final Function<String, T>       defaultParser,
287            final Function<Number, T>       numberConverter,
288            final Function<BigDecimal, T>   numberConverterExThrow
289        )
290    {
291        this.whichType              = whichType;
292        this.referenceOrPrimitive   = referenceOrPrimitive;
293        this.CLASS                  = CLASS;   
294        this.jsonNumWillFit         = jsonNumWillFit;
295        this.validStrTester         = validStrTester;
296        this.defaultParser          = defaultParser;
297        this.numberConverter        = numberConverter;
298        this.numberConverterExThrow = numberConverterExThrow;
299
300        this.isNumberType =
301                (this.whichType != STRING)
302            &&  (this.whichType != BOOLEAN)
303            &&  (this.whichType != JSON_OBJECT)
304            &&  (this.whichType != JSON_ARRAY);
305
306
307        // This constructor is private, and cannot be used by the "EXTENDED_TYPES" subclass.
308        // Leave this here, because is serves (sort of) as a comment, and a reminder.
309
310        if (this.whichType == EXTENDED_OBJ) throw new UnreachableError();
311    }
312
313
314    // This is a specialize constructor which is being added to allow for providing an
315    // "Object-Builder" variant of the "objArr".  What that means, in English, is that a new 
316    // version of the method for reading an Array of Objects is being added.  The original version
317    // of "Object Array Handler" required that the Object have a constructor which accepts a 
318    // Json-Object as Input in order to produce an instance of the Object.
319    // 
320    // This new variant of "Basic Type" will allow the user to provide any old lambda function,
321    // whatsoever, to produce / build / construct an instance of the Object that has been retrieved
322    // from the Json-Array of Objects.  This feature was added in April 2025.  It is needed for the
323    // Java-Doc Frames & Package-Summary Sorter "Feature."  The user provides a Json based 
324    // Configuration-File, and that Configuration-File contains an array of objects.
325    // 
326    // The Code looks much nicer when there is a "B1" Builder and a "D1" Data-Record, than when
327    // there is just one giant "D1" Data-Record with a large constructor shoved inside of it.  
328    // By adding this new "Basic-Type" thing-y, I can separate the two!
329
330    // Here is the original constructor.  Since there is only one method that invokes this
331    // constructor there is, therefore, no need to accept all of these parameters, and they can be
332    // automatically hard-wired to accept null.
333
334    BASIC_TYPES(final Class<T> CLASS)
335    {
336        this.whichType              = EXTENDED_OBJ;
337        this.referenceOrPrimitive   = true;
338        this.CLASS                  = CLASS;   
339        this.jsonNumWillFit         = null;
340        this.validStrTester         = null;
341        this.defaultParser          = null;
342        this.numberConverter        = null;
343        this.numberConverterExThrow = null;
344        this.isNumberType           = false;
345    }
346
347
348    // ********************************************************************************************
349    // ********************************************************************************************
350    // All of the actual Configurations themselves - as "private static builder methods"
351    // ********************************************************************************************
352    // ********************************************************************************************
353
354
355    private static BASIC_TYPES<Integer> INTEGER(final boolean boxedOrPrimitive)
356    {
357        return new BASIC_TYPES<>(
358            INTEGER,                    // final byte       whichType
359            boxedOrPrimitive,           // final boolean    referenceOrPrimitive
360
361            // final Class<T> CLASS
362            boxedOrPrimitive ? Integer.class : int.class,
363
364            // final Predicate<JsonNumber> jsonNumWillFit
365            (JsonNumber jn) -> jn.numberValue().getClass() == Integer.class,
366
367            StringParse::isInteger,     // final Predicate<String>          validStrTester
368            Integer::parseInt,          // final Function<String, T>        defaultParser
369            Number::intValue,           // final Function<Number, T>        numberConverter
370            BigDecimal::intValueExact   // final Function<BigDecimal, T>    numberConverterExThrow
371        );
372    }
373
374    private static BASIC_TYPES<Short> SHORT(final boolean boxedOrPrimitive)
375    {
376        return new BASIC_TYPES<>(
377            SHORT,                      // final byte       whichType
378            boxedOrPrimitive,           // final boolean    referenceOrPrimitive
379
380            // final Class<T> CLASS
381            boxedOrPrimitive ? Short.class : short.class,
382
383            BASIC_TYPES::shortTypePred, // final Predicate<JsonNumber>      jsonNumWillFit
384            StringParse::isShort,       // final Predicate<String>          validStrTester
385            Short::parseShort,          // final Function<String, T>        defaultParser
386            Number::shortValue,         // final Function<Number, T>        numberConverter
387            BigDecimal::shortValueExact // final Function<BigDecimal, T>    numberConverterExThrow
388        );
389    }
390
391    private static BASIC_TYPES<Byte> BYTE(final boolean boxedOrPrimitive)
392    {
393        return new BASIC_TYPES<>(
394            BYTE,                       // final byte       whichType
395            boxedOrPrimitive,           // final boolean    referenceOrPrimitive
396
397            // final Class<T> CLASS
398            boxedOrPrimitive ? Byte.class : byte.class,
399
400            BASIC_TYPES::byteTypePred,  // final Predicate<JsonNumber>      jsonNumWillFit
401            StringParse::isByte,        // final Predicate<String>          validStrTester
402            Byte::parseByte,            // final Function<String, T>        defaultParser
403            Number::byteValue,          // final Function<Number, T>        numberConverter
404            BigDecimal::byteValueExact  // final Function<BigDecimal, T>    numberConverterExThrow
405        );
406    }
407
408    private static BASIC_TYPES<Long> LONG(final boolean boxedOrPrimitive)
409    {
410        return new BASIC_TYPES<>(
411            LONG,                       // final byte       whichType
412            boxedOrPrimitive,           // final boolean    referenceOrPrimitive
413
414            // final Class<T> CLASS
415            boxedOrPrimitive ? Long.class : long.class,
416
417            BASIC_TYPES::longTypePred,  // final Predicate<JsonNumber>      jsonNumWillFit
418            StringParse::isLong,        // final Predicate<String>          validStrTester
419            Long::parseLong,            // final Function<String, T>        defaultParser
420            Number::longValue,          // final Function<Number, T>        numberConverter
421            BigDecimal::longValueExact  // final Function<BigDecimal, T>    numberConverterExThrow
422        );
423    }
424
425    private static BASIC_TYPES<Double> DOUBLE(final boolean boxedOrPrimitive)
426    {
427        return new BASIC_TYPES<>(
428            DOUBLE,                     // final byte       whichType
429            boxedOrPrimitive,           // final boolean    referenceOrPrimitive
430
431            // final Class<T> CLASS
432            boxedOrPrimitive ? Double.class : double.class,
433
434            // final Predicate<JsonNumber> jsonNumWillFit, doubleTypePred doesn't exist
435            null,
436
437            StringParse::isDouble,      // final Predicate<String>      validStrTester
438            Double::parseDouble,        // final Function<String, T>    defaultParser
439            Number::doubleValue,        // final Function<Number, T>    numberConverter
440
441            // final Function<BigDecimal, T> numberConverterExThrow
442            (BigDecimal bd) -> { throw new ArithmeticException("Invalid Input"); }
443        );
444    }
445
446    private static BASIC_TYPES<Float> FLOAT(final boolean boxedOrPrimitive)
447    {
448        return new BASIC_TYPES<>(
449            FLOAT,                      // final byte whichType 
450            boxedOrPrimitive,           // final boolean referenceOrPrimitive
451
452            // final Class<T> CLASS
453            boxedOrPrimitive ? Float.class : float.class,
454
455            // final Predicate<JsonNumber> jsonNumWillFit, floatTypePred doesn't exist
456            null,
457
458            StringParse::isDouble,      // final Predicate<String> validStrTester
459                                        //      StringParse doesn't have an "isFloat"
460            Float::parseFloat,          // final Function<String, T> defaultParser
461            Number::floatValue,         // final Function<Number, T> numberConverter
462
463            // final Function<BigDecimal, T> numberConverterExThrow
464            (BigDecimal bd) -> { throw new ArithmeticException("Invalid Input"); }
465        );
466    }
467
468    private static BASIC_TYPES<Boolean> BOOLEAN(final boolean boxedOrPrimitive)
469    {
470        return new BASIC_TYPES<>(
471            BOOLEAN,                // final byte whichType 
472            boxedOrPrimitive,       // final boolean referenceOrPrimitive
473
474            // final Class<T> CLASS
475            boxedOrPrimitive ? Boolean.class : boolean.class,
476
477            // final Predicate<JsonNumber> jsonNumWillFit - Boolean is not a JsonNumber!
478            null,
479
480            s -> true,              // final Predicate<String> validStrTester
481                                    //      String-tester (for parsing number-strings)
482            Boolean::parseBoolean,  // final Function<String, T> defaultParser
483            null,                   // numberConverter (JAPPROX_ON_AEX *AND* usual-ans)
484            null                    // The Arithmetic-Exception thing
485        );
486    }
487
488    private static BASIC_TYPES<Number> NUMBER()
489    {
490        // It's been 2.5 years since I originally wrote this, and I really don't remember
491        // how this one works...
492
493        return new BASIC_TYPES<Number>(
494            NUMBER,                     // final byte                   whichType,
495            BOXED,                      // final boolean                referenceOrPrimitive,
496            Number.class,               // final Class<T>               CLASS,
497            (JsonNumber jn) -> true,    // final Predicate<JsonNumber>  jsonNumWillFit,
498
499
500            // These are all Hard-Coded into the "SettingsRec"
501            // There is a special case when this.whiteType == BASIC_TYPES.NUMBER
502
503            null,   // final Predicate<String>          validStrTester,
504            null,   // final Function<String, T>        defaultParser,
505            null,   // final Function<Number, T>        numberConverter,
506            null    // final Function<BigDecimal, T>    numberConverterExThrow
507        );
508    }
509
510    // None of these little configurtion-lambdas are needed because 'String' is not a number
511    private static BASIC_TYPES<String> STRING()
512    {
513        return new BASIC_TYPES<>(
514            STRING,         // final byte                      whichType,
515            true,           // final boolean                   referenceOrPrimitive,
516            String.class,   // final Class<T>                  CLASS,
517            null,           // final Predicate<JsonNumber>     jsonNumWillFit,
518            null,           // final Predicate<String>         validStrTester,
519            null,           // final Function<String, T>       defaultParser,
520            null,           // final Function<Number, T>       numberConverter w/Approx,
521            null            // final Function<BigDecimal, T>   numberConverter w/AEX
522        );
523    }
524
525    // None of these little configurtion-lambdas are needed because 'JsonObject' is not a number
526    private static BASIC_TYPES<JsonObject> JO()
527    {
528        return new BASIC_TYPES<>(
529            JSON_OBJECT,        // final byte                      whichType,
530            true,               // final boolean                   referenceOrPrimitive,
531            JsonObject.class,   // final Class<T>                  CLASS,
532            null,               // final Predicate<JsonNumber>     jsonNumWillFit,
533            null,               // final Predicate<String>         validStrTester,
534            null,               // final Function<String, T>       defaultParser,
535            null,               // final Function<Number, T>       numberConverter w/Approx,
536            null                // final Function<BigDecimal, T>   numberConverter w/AEX
537        );
538    }
539
540    // None of these little configurtion-lambdas are needed because 'JsonObject' is not a number
541    private static BASIC_TYPES<JsonArray> JA()
542    {
543        return new BASIC_TYPES<>(
544            JSON_ARRAY,         // final byte                      whichType,
545            true,               // final boolean                   referenceOrPrimitive,
546            JsonArray.class,    // final Class<T>                  CLASS,
547            null,               // final Predicate<JsonNumber>     jsonNumWillFit,
548            null,               // final Predicate<String>         validStrTester,
549            null,               // final Function<String, T>       defaultParser,
550            null,               // final Function<Number, T>       numberConverter w/Approx,
551            null                // final Function<BigDecimal, T>   numberConverter w/AEX
552        );
553    }
554
555
556    // ********************************************************************************************
557    // ********************************************************************************************
558    // Three Minor Helper Predicates
559    // ********************************************************************************************
560    // ********************************************************************************************
561
562
563    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
564    // Long-Type Test-Predicate
565    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
566
567    private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
568    private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);
569
570    private static boolean longTypePred(JsonNumber jn)
571    {
572        if (! jn.isIntegral()) return false;
573
574        BigInteger  bi      = jn.bigIntegerValue();
575        int         signum  = bi.signum();
576
577        return  ((signum > 0) && (bi.compareTo(LONG_MAX) <= 0))
578            ||  ((signum < 0) && (bi.compareTo(LONG_MIN) >= 0))
579            ||  (signum == 0);
580    }
581
582
583    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
584    // Short-Type Test-Predicate
585    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
586
587    private static final BigInteger SHORT_MAX   = BigInteger.valueOf(Short.MAX_VALUE);
588    private static final BigInteger SHORT_MIN   = BigInteger.valueOf(Short.MIN_VALUE);
589
590    private static boolean shortTypePred(JsonNumber jn)
591    {
592        if (! jn.isIntegral()) return false;
593
594        BigInteger  bi      = jn.bigIntegerValue();
595        int         signum  = bi.signum();
596
597        return  ((signum > 0) && (bi.compareTo(SHORT_MAX) <= 0))
598            ||  ((signum < 0) && (bi.compareTo(SHORT_MIN) >= 0))
599            ||  (signum == 0);
600    }
601
602
603    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
604    // Byte-Type Test-Predicate
605    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
606
607    private static final BigInteger BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE);
608    private static final BigInteger BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE);
609
610    private static boolean byteTypePred(JsonNumber jn)
611    {
612        if (! jn.isIntegral()) return false;
613
614        BigInteger  bi      = jn.bigIntegerValue();
615        int         signum  = bi.signum();
616
617        return  ((signum > 0) && (bi.compareTo(BYTE_MAX) <= 0))
618            ||  ((signum < 0) && (bi.compareTo(BYTE_MIN) >= 0))
619            ||  (signum == 0);
620    }
621}