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 javax.json.JsonValue.ValueType.*; 008import static Torello.JSON.RJInternal.*; 009import static Torello.JSON.JFlag.*; 010 011import javax.json.JsonObject; 012import javax.json.JsonArray; 013import javax.json.JsonString; 014import javax.json.JsonNumber; 015import javax.json.JsonValue; 016 017import java.math.BigDecimal; 018 019import java.util.function.Function; 020 021/** 022 * Builds on the J2EE Standard Release JSON Parsing Tools by providing additional 023 * help with converting JSON Data into <B STYLE='color: red'>Java Boxed-Primitive Types</B> 024 * 025 * <EMBED CLASS='external-html' DATA-FILE-ID=ALL_CLASSES_NOTE> 026 * <EMBED CLASS='external-html' DATA-FILE-ID=READ_BOXED_JSON> 027 * <EMBED CLASS='external-html' DATA-FILE-ID=READ_BOXED_PTABLE> 028 * <EMBED CLASS='external-html' DATA-CH='java.lang.Character' DATA-FILE-ID=JAVA_LANG_CHAR> 029 * 030 * @see JsonObject 031 * @see JsonArray 032 */ 033@Torello.JavaDoc.Annotations.StaticFunctional 034public class ReadBoxedJSON 035{ 036 // This is a static class. Has no program state. 037 private ReadBoxedJSON() { } 038 039 040 // ******************************************************************************************** 041 // ******************************************************************************************** 042 // From JsonArray, No Error Control Flags 043 // ******************************************************************************************** 044 // ******************************************************************************************** 045 046 047 /** 048 * <EMBED CLASS='external-html' DATA-TYPE=Integer DATA-FILE-ID=READ_BOXED_NF_JA> 049 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 050 * @see JsonNumber#intValueExact() 051 */ 052 @IntoHTMLTable( 053 title="Retrieve a JsonArray element, and transform it to a Java Boxed Integer", 054 background=BlueDither 055 ) 056 public static Integer getInteger(final JsonArray ja, final int index) 057 { return GET_NO_FLAGS(ja, index, JsonNumber::intValueExact, Integer.class); } 058 059 /** 060 * <EMBED CLASS='external-html' DATA-TYPE=Long DATA-FILE-ID=READ_BOXED_NF_JA> 061 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 062 * @see JsonNumber#longValueExact() 063 */ 064 @IntoHTMLTable( 065 title="Retrieve a JsonArray element, and transform it to a Boxed Long Integer", 066 background=GreenDither 067 ) 068 public static Long getLong(final JsonArray ja, final int index) 069 { return GET_NO_FLAGS(ja, index, JsonNumber::longValueExact, Long.class); } 070 071 /** 072 * <EMBED CLASS='external-html' DATA-TYPE=Long DATA-FILE-ID=READ_BOXED_NF_JA> 073 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 074 * @see JsonNumber#bigDecimalValue() 075 */ 076 @IntoHTMLTable( 077 title="Retrieve a JsonArray element, and transform it to a Boxed Short Integer", 078 background=BlueDither 079 ) 080 public static Short getShort(final JsonArray ja, final int index) 081 { return GET_NO_FLAGS(ja, index, jn -> jn.bigDecimalValue().shortValueExact(), Short.class); } 082 083 /** 084 * <EMBED CLASS='external-html' DATA-TYPE=Byte DATA-FILE-ID=READ_BOXED_NF_JA> 085 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 086 * @see JsonNumber#bigDecimalValue() 087 */ 088 @IntoHTMLTable( 089 title="Retrieve a JsonArray element, and transform it to a Java Boxed Byte", 090 background=GreenDither 091 ) 092 public static Byte getByte(final JsonArray ja, final int index) 093 { return GET_NO_FLAGS(ja, index, jn -> jn.bigDecimalValue().byteValueExact(), Byte.class); } 094 095 /** 096 * <EMBED CLASS='external-html' DATA-TYPE=Double DATA-FILE-ID=READ_BOXED_NF_JA> 097 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 098 * @see RJInternal#DOUBLE_WITH_CHECK(JsonNumber) 099 */ 100 @IntoHTMLTable( 101 title="Retrieve a JsonArray element, and transform it to a Java Boxed Double", 102 background=BlueDither 103 ) 104 public static Double getDouble(final JsonArray ja, final int index) 105 { return GET_NO_FLAGS(ja, index, RJInternal::DOUBLE_WITH_CHECK, Double.class); } 106 107 /** 108 * <EMBED CLASS='external-html' DATA-TYPE=Float DATA-FILE-ID=READ_BOXED_NF_JA> 109 * @see #GET_NO_FLAGS(JsonArray, int, Function, Class) 110 * @see RJInternal#FLOAT_WITH_CHECK(JsonNumber) 111 */ 112 @IntoHTMLTable( 113 title="Retrieve a JsonArray element, and transform it to a Java Boxed Float", 114 background=GreenDither 115 ) 116 public static Float getFloat(final JsonArray ja, final int index) 117 { return GET_NO_FLAGS(ja, index, RJInternal::FLOAT_WITH_CHECK, Float.class); } 118 119 /** 120 * <EMBED CLASS='external-html' DATA-TYPE=Boolean DATA-FILE-ID=READ_BOXED_NF_JA> 121 * @see JsonValue#getValueType() 122 * @see JsonValue.ValueType#TRUE 123 * @see JsonValue.ValueType#FALSE 124 * @see JsonValue#TRUE 125 * @see JsonValue#FALSE 126 */ 127 @IntoHTMLTable( 128 title="Retrieve a JsonArray element, and transform it to a Java Boxed Boolean", 129 background=BlueDither 130 ) 131 public static Boolean getBoolean(final JsonArray ja, final int index) 132 { 133 final JsonValue jv = ja.get(index); 134 135 switch (jv.getValueType()) 136 { 137 case NULL: return null; 138 case TRUE: return true; 139 case FALSE: return false; 140 default: throw new JsonTypeArrException(ja, index, TRUE, jv, Boolean.class); 141 } 142 } 143 144 145 // ******************************************************************************************** 146 // ******************************************************************************************** 147 // From JsonObject, No Error Control Flags 148 // ******************************************************************************************** 149 // ******************************************************************************************** 150 151 152 /** 153 * <EMBED CLASS='external-html' DATA-TYPE=Integer DATA-FILE-ID=READ_BOXED_NF_JO> 154 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 155 * @see JsonNumber#intValueExact() 156 */ 157 @IntoHTMLTable( 158 title="Retrieve a JsonObject property, and transform it to a Java Boxed Integer", 159 background=GreenDither 160 ) 161 public static Integer getInteger( 162 final JsonObject jo, 163 final String propertyName, 164 final boolean isOptional 165 ) 166 { 167 return GET_NO_FLAGS 168 (jo, propertyName, isOptional, JsonNumber::intValueExact, Integer.class); 169 } 170 171 /** 172 * <EMBED CLASS='external-html' DATA-TYPE=Long DATA-FILE-ID=READ_BOXED_NF_JO> 173 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 174 * @see JsonNumber#longValueExact() 175 */ 176 @IntoHTMLTable( 177 title="Retrieve a JsonObject property, and transform it to a Boxed Long Integer", 178 background=BlueDither 179 ) 180 public static Long getLong( 181 final JsonObject jo, 182 final String propertyName, 183 final boolean isOptional 184 ) 185 { 186 return GET_NO_FLAGS 187 (jo, propertyName, isOptional, JsonNumber::longValueExact, Long.class); 188 } 189 190 /** 191 * <EMBED CLASS='external-html' DATA-TYPE=Short DATA-FILE-ID=READ_BOXED_NF_JO> 192 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 193 * @see JsonNumber#bigDecimalValue() 194 */ 195 @IntoHTMLTable( 196 title="Retrieve a JsonObject property, and transform it to a Boxed Short Integer", 197 background=GreenDither 198 ) 199 public static Short getShort( 200 final JsonObject jo, 201 final String propertyName, 202 final boolean isOptional 203 ) 204 { 205 return GET_NO_FLAGS( 206 jo, propertyName, isOptional, 207 jn -> jn.bigDecimalValue().shortValueExact(), 208 Short.class 209 ); 210 } 211 212 /** 213 * <EMBED CLASS='external-html' DATA-TYPE=Byte DATA-FILE-ID=READ_BOXED_NF_JO> 214 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 215 * @see JsonNumber#bigDecimalValue() 216 */ 217 @IntoHTMLTable( 218 title="Retrieve a JsonObject property, and transform it to a Java Boxed Byte", 219 background=BlueDither 220 ) 221 public static Byte getByte( 222 final JsonObject jo, 223 final String propertyName, 224 final boolean isOptional 225 ) 226 { 227 return GET_NO_FLAGS( 228 jo, propertyName, isOptional, 229 jn -> jn.bigDecimalValue().byteValueExact(), 230 Byte.class 231 ); 232 } 233 234 /** 235 * <EMBED CLASS='external-html' DATA-TYPE=Double DATA-FILE-ID=READ_BOXED_NF_JO> 236 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 237 * @see RJInternal#DOUBLE_WITH_CHECK(JsonNumber) 238 */ 239 @IntoHTMLTable( 240 title="Retrieve a JsonObject property, and transform it to a Java Boxed Double", 241 background=GreenDither 242 ) 243 public static Double getDouble( 244 final JsonObject jo, 245 final String propertyName, 246 final boolean isOptional 247 ) 248 { 249 return GET_NO_FLAGS 250 (jo, propertyName, isOptional, RJInternal::DOUBLE_WITH_CHECK, Double.class); 251 } 252 253 /** 254 * <EMBED CLASS='external-html' DATA-TYPE=Float DATA-FILE-ID=READ_BOXED_NF_JO> 255 * @see #GET_NO_FLAGS(JsonObject, String, boolean, Function, Class) 256 * @see RJInternal#FLOAT_WITH_CHECK(JsonNumber) 257 */ 258 @IntoHTMLTable( 259 title="Retrieve a JsonObject property, and transform it to a Java Boxed Float", 260 background=BlueDither 261 ) 262 public static Float getFloat( 263 final JsonObject jo, 264 final String propertyName, 265 final boolean isOptional 266 ) 267 { 268 return GET_NO_FLAGS 269 (jo, propertyName, isOptional, RJInternal::FLOAT_WITH_CHECK, Float.class); 270 } 271 272 /** 273 * <EMBED CLASS='external-html' DATA-TYPE=Boolean DATA-FILE-ID=READ_BOXED_NF_JO> 274 * @see JsonValue#getValueType() 275 * @see JsonValue.ValueType#TRUE 276 * @see JsonValue.ValueType#FALSE 277 * @see JsonValue#TRUE 278 * @see JsonValue#FALSE 279 */ 280 @IntoHTMLTable( 281 title="Retrieve a JsonObject property, and transform it to a Java Boxed Boolean", 282 background=GreenDither 283 ) 284 public static Boolean getBoolean( 285 final JsonObject jo, 286 final String propertyName, 287 final boolean isOptional 288 ) 289 { 290 if (! jo.containsKey(propertyName)) 291 { 292 if (isOptional) return null; 293 throw new JsonPropMissingException(jo, propertyName, TRUE, Boolean.class); 294 } 295 296 final JsonValue jv = jo.get(propertyName); 297 298 switch (jv.getValueType()) 299 { 300 case NULL: return null; 301 case TRUE: return true; 302 case FALSE: return false; 303 default: throw new JsonTypeObjException(jo, propertyName, TRUE, jv, Boolean.class); 304 } 305 } 306 307 308 // ******************************************************************************************** 309 // ******************************************************************************************** 310 // From JsonArray, WITH FLAGS 311 // ******************************************************************************************** 312 // ******************************************************************************************** 313 314 315 /** 316 * <EMBED CLASS='external-html' DATA-TYPE=Integer DATA-FILE-ID=READ_BOXED_WF_JA> 317 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 318 * @see JsonNumber#intValueExact() 319 * @see JsonNumber#intValue() 320 */ 321 @IntoHTMLTable( 322 title="Retrieve a JsonArray element, and transform it to a Java Boxed Integer", 323 background=BlueDither 324 ) 325 public static Integer getInteger( 326 final JsonArray ja, 327 final int index, 328 final int FLAGS, 329 final int defaultValue 330 ) 331 { 332 return GET( 333 ja, index, FLAGS, defaultValue, 334 Integer.class, JsonNumber::intValueExact, JsonNumber::intValue 335 ); 336 } 337 338 /** 339 * <EMBED CLASS='external-html' DATA-TYPE=Long DATA-FILE-ID=READ_BOXED_WF_JA> 340 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 341 * @see JsonNumber#longValueExact() 342 * @see JsonNumber#longValue() 343 */ 344 @IntoHTMLTable( 345 title="Retrieve a JsonArray element, and transform it to a Boxed Long Integer", 346 background=GreenDither 347 ) 348 public static Long getLong( 349 final JsonArray ja, 350 final int index, 351 final int FLAGS, 352 final long defaultValue 353 ) 354 { 355 return GET( 356 ja, index, FLAGS, defaultValue, 357 Long.class, JsonNumber::longValueExact, JsonNumber::longValue 358 ); 359 } 360 361 /** 362 * <EMBED CLASS='external-html' DATA-TYPE=Short DATA-FILE-ID=READ_BOXED_WF_JA> 363 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 364 * @see JsonNumber#bigDecimalValue() 365 */ 366 @IntoHTMLTable( 367 title="Retrieve a JsonArray element, and transform it to a Boxed Short Integer", 368 background=BlueDither 369 ) 370 public static Short getShort( 371 final JsonArray ja, 372 final int index, 373 final int FLAGS, 374 final short defaultValue 375 ) 376 { 377 return GET( 378 ja, index, FLAGS, defaultValue, Short.class, 379 jn -> jn.bigDecimalValue().shortValueExact(), 380 jn -> jn.bigDecimalValue().shortValue() 381 ); 382 } 383 384 /** 385 * <EMBED CLASS='external-html' DATA-TYPE=Byte DATA-FILE-ID=READ_BOXED_WF_JA> 386 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 387 * @see JsonNumber#bigDecimalValue() 388 */ 389 @IntoHTMLTable( 390 title="Retrieve a JsonArray element, and transform it to a Java Boxed Byte", 391 background=GreenDither 392 ) 393 public static Byte getByte( 394 final JsonArray ja, 395 final int index, 396 final int FLAGS, 397 final byte defaultValue 398 ) 399 { 400 return GET( 401 ja, index, FLAGS, defaultValue, Byte.class, 402 jn -> jn.bigDecimalValue().byteValueExact(), 403 jn -> jn.bigDecimalValue().byteValue() 404 ); 405 } 406 407 /** 408 * <EMBED CLASS='external-html' DATA-TYPE=Double DATA-FILE-ID=READ_BOXED_WF_JA> 409 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 410 * @see RJInternal#DOUBLE_WITH_CHECK(JsonNumber) 411 * @see JsonNumber#bigDecimalValue() 412 */ 413 @IntoHTMLTable( 414 title="Retrieve a JsonArray element, and transform it to a Java Boxed Double", 415 background=BlueDither 416 ) 417 public static Double getDouble( 418 final JsonArray ja, 419 final int index, 420 final int FLAGS, 421 final double defaultValue 422 ) 423 { 424 return GET( 425 ja, index, FLAGS, defaultValue, Double.class, 426 RJInternal::DOUBLE_WITH_CHECK, 427 jn -> jn.bigDecimalValue().doubleValue() 428 ); 429 } 430 431 /** 432 * <EMBED CLASS='external-html' DATA-TYPE=Float DATA-FILE-ID=READ_BOXED_WF_JA> 433 * @see #GET(JsonArray, int, int, Number, Class, Function, Function) 434 * @see RJInternal#FLOAT_WITH_CHECK(JsonNumber) 435 * @see JsonNumber#bigDecimalValue() 436 */ 437 @IntoHTMLTable( 438 title="Retrieve a JsonArray element, and transform it to a Java Boxed Float", 439 background=GreenDither 440 ) 441 public static Float getFloat( 442 final JsonArray ja, 443 final int index, 444 final int FLAGS, 445 final float defaultValue 446 ) 447 { 448 return GET( 449 ja, index, FLAGS, defaultValue, Float.class, 450 RJInternal::FLOAT_WITH_CHECK, 451 jn -> jn.bigDecimalValue().floatValue() 452 ); 453 } 454 455 /** 456 * <EMBED CLASS='external-html' DATA-TYPE=Boolean DATA-FILE-ID=READ_BOXED_WF_JA> 457 * @see JsonValue#getValueType() 458 * @see JsonValue.ValueType#TRUE 459 * @see JsonValue.ValueType#FALSE 460 * @see JsonValue#TRUE 461 * @see JsonValue#FALSE 462 */ 463 @IntoHTMLTable( 464 title="Retrieve a JsonArray element, and transform it to a Java Boxed Boolean", 465 background=BlueDither 466 ) 467 public static Boolean getBoolean( 468 final JsonArray ja, 469 final int index, 470 final int FLAGS, 471 final boolean defaultValue 472 ) 473 { 474 if (index >= ja.size()) return IOOBEX(ja, index, defaultValue, FLAGS); 475 476 final JsonValue jv = ja.get(index); // Throw an IndexOutOfBoundsException 477 478 switch (jv.getValueType()) 479 { 480 case NULL: return JNAEX(ja, index, defaultValue, FLAGS, TRUE, Boolean.class); 481 case TRUE: return true; 482 case FALSE: return false; 483 default: return JTAEX(ja, index, defaultValue, FLAGS, TRUE, jv, Boolean.class); 484 } 485 } 486 487 488 // ******************************************************************************************** 489 // ******************************************************************************************** 490 // From JsonObject, WITH FLAGS 491 // ******************************************************************************************** 492 // ******************************************************************************************** 493 494 495 /** 496 * <EMBED CLASS='external-html' DATA-TYPE=Integer DATA-FILE-ID=READ_BOXED_WF_JO> 497 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 498 * @see JsonNumber#intValueExact() 499 * @see JsonNumber#intValue() 500 */ 501 @IntoHTMLTable( 502 title="Retrieve a JsonObject property, and transform it to a Java Boxed Integer", 503 background=GreenDither 504 ) 505 public static Integer getInteger( 506 final JsonObject jo, 507 final String propertyName, 508 final int FLAGS, 509 final int defaultValue 510 ) 511 { 512 return GET( 513 jo, propertyName, FLAGS, defaultValue, 514 Integer.class, JsonNumber::intValueExact, JsonNumber::intValue 515 ); 516 } 517 518 /** 519 * <EMBED CLASS='external-html' DATA-TYPE=Long DATA-FILE-ID=READ_BOXED_WF_JO> 520 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 521 * @see JsonNumber#longValueExact() 522 * @see JsonNumber#longValue() 523 */ 524 @IntoHTMLTable( 525 title="Retrieve a JsonObject property, and transform it to a Boxed Long Integer", 526 background=BlueDither 527 ) 528 public static Long getLong( 529 final JsonObject jo, 530 final String propertyName, 531 final int FLAGS, 532 final long defaultValue 533 ) 534 { 535 return GET( 536 jo, propertyName, FLAGS, defaultValue, 537 Long.class, JsonNumber::longValueExact, JsonNumber::longValue 538 ); 539 } 540 541 /** 542 * <EMBED CLASS='external-html' DATA-TYPE=Short DATA-FILE-ID=READ_BOXED_WF_JO> 543 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 544 * @see JsonNumber#bigDecimalValue() 545 */ 546 @IntoHTMLTable( 547 title="Retrieve a JsonObject property, and transform it to a Boxed Short Integer", 548 background=GreenDither 549 ) 550 public static Short getShort( 551 final JsonObject jo, 552 final String propertyName, 553 final int FLAGS, 554 final short defaultValue 555 ) 556 { 557 return GET( 558 jo, propertyName, FLAGS, defaultValue, 559 Short.class, 560 jn -> jn.bigDecimalValue().shortValueExact(), 561 jn -> jn.bigDecimalValue().shortValue() 562 ); 563 } 564 565 /** 566 * <EMBED CLASS='external-html' DATA-TYPE=Byte DATA-FILE-ID=READ_BOXED_WF_JO> 567 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 568 * @see JsonNumber#bigDecimalValue() 569 */ 570 @IntoHTMLTable( 571 title="Retrieve a JsonObject property, and transform it to a Java Boxed Byte", 572 background=BlueDither 573 ) 574 public static Byte getByte( 575 final JsonObject jo, 576 final String propertyName, 577 final int FLAGS, 578 final byte defaultValue 579 ) 580 { 581 return GET( 582 jo, propertyName, FLAGS, defaultValue, 583 Byte.class, 584 jn -> jn.bigDecimalValue().byteValueExact(), 585 jn -> jn.bigDecimalValue().byteValue() 586 ); 587 } 588 589 /** 590 * <EMBED CLASS='external-html' DATA-TYPE=Double DATA-FILE-ID=READ_BOXED_WF_JO> 591 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 592 * @see RJInternal#DOUBLE_WITH_CHECK(JsonNumber) 593 * @see JsonNumber#bigDecimalValue() 594 */ 595 @IntoHTMLTable( 596 title="Retrieve a JsonObject property, and transform it to a Java Boxed Double", 597 background=GreenDither 598 ) 599 public static Double getDouble( 600 final JsonObject jo, 601 final String propertyName, 602 final int FLAGS, 603 final double defaultValue 604 ) 605 { 606 return GET( 607 jo, propertyName, FLAGS, defaultValue, 608 Double.class, 609 RJInternal::DOUBLE_WITH_CHECK, 610 jn -> jn.bigDecimalValue().doubleValue() 611 ); 612 } 613 614 /** 615 * <EMBED CLASS='external-html' DATA-TYPE=Float DATA-FILE-ID=READ_BOXED_WF_JO> 616 * @see #GET(JsonObject, String, int, Number, Class, Function, Function) 617 * @see RJInternal#FLOAT_WITH_CHECK(JsonNumber) 618 * @see JsonNumber#bigDecimalValue() 619 */ 620 @IntoHTMLTable( 621 title="Retrieve a JsonObject property, and transform it to a Java Boxed Float", 622 background=BlueDither 623 ) 624 public static Float getFloat( 625 final JsonObject jo, 626 final String propertyName, 627 final int FLAGS, 628 final float defaultValue 629 ) 630 { 631 return GET( 632 jo, propertyName, FLAGS, defaultValue, 633 Float.class, 634 RJInternal::FLOAT_WITH_CHECK, 635 jn -> jn.bigDecimalValue().floatValue() 636 ); 637 } 638 639 /** 640 * <EMBED CLASS='external-html' DATA-TYPE=Boolean DATA-FILE-ID=READ_BOXED_WF_JO> 641 * @see JsonValue#getValueType() 642 * @see JsonValue.ValueType#TRUE 643 * @see JsonValue.ValueType#FALSE 644 * @see JsonValue#TRUE 645 * @see JsonValue#FALSE 646 */ 647 @IntoHTMLTable( 648 title="Retrieve a JsonObject property, and transform it to a Java Boxed Boolean", 649 background=GreenDither 650 ) 651 public static Boolean getBoolean( 652 final JsonObject jo, 653 final String propertyName, 654 final int FLAGS, 655 final boolean defaultValue 656 ) 657 { 658 final JsonValue jv = jo.get(propertyName); 659 660 if (jv == null) return JPMEX(jo, propertyName, defaultValue, FLAGS, TRUE, Boolean.class); 661 662 switch (jv.getValueType()) 663 { 664 case NULL: return JNOEX(jo, propertyName, defaultValue, FLAGS, TRUE, Boolean.class); 665 case TRUE: return true; 666 case FALSE: return false; 667 668 default: 669 return JTOEX(jo, propertyName, defaultValue, FLAGS, TRUE, jv, Boolean.class); 670 } 671 } 672 673 674 // ******************************************************************************************** 675 // ******************************************************************************************** 676 // PROTECTED, INTERNAL METHODS FOR NUMBERS 677 // ******************************************************************************************** 678 // ******************************************************************************************** 679 680 681 /** 682 * This is an internal helper method for retrieving an element from a {@link JsonArray}, 683 * and converting it to one of the standard <B STYLE='color: red;'>Java Types</B>. 684 * 685 * @param <T> Numeric Boxed-Type, as an instance of {@code java.lang.Class} 686 * @param ja Any instance of {@link JsonArray} 687 * @param index A valid index into {@code 'ja'} 688 * @param jsonTypeToJavaType <EMBED CLASS='external-html' DATA-FILE-ID=READ_BOXED_JTTJT> 689 * 690 * @return The converted number, as an instance Generic-Parameter {@code 'T'} 691 * 692 * @throws JsonTypeArrException If array index specified does not contain a {@link JsonNumber} 693 * @throws JsonArithmeticArrException If there any arithmetic problems during the conversion 694 * @throws IndexOutOfBoundsException If {@code 'index'} is out of the bounds of {@code 'ja'} 695 * 696 * @see #getInteger(JsonArray, int) 697 * @see #getLong(JsonArray, int) 698 * @see #getShort(JsonArray, int) 699 * @see #getByte(JsonArray, int) 700 * @see #getDouble(JsonArray, int) 701 * @see #getFloat(JsonArray, int) 702 */ 703 protected static <T extends java.lang.Number> T GET_NO_FLAGS( 704 final JsonArray ja, 705 final int index, 706 final Function<JsonNumber, T> jsonTypeToJavaType, 707 final Class<T> returnClass 708 ) 709 { 710 // This will throw an IndexOutOfBoundsException if the index is out of bounds. 711 // Since this *IS NOT* a method with FLAGS, the user has no way to avoid this exception 712 // throw if, indeed, the index really is out of bounds! 713 // 714 // Using one of the 'FLAGS' variants of the 'GET' array-index, a user may request that 715 // either null or a default-value be returned. Not with this version-of 'GET', though. 716 717 final JsonValue jv = ja.get(index); 718 719 switch (jv.getValueType()) 720 { 721 // This method allows for null-returns. If Json-Null, return Java-Null. 722 case NULL: return null; 723 724 // This will throw ArithmeticException if it cannot be converted 725 case NUMBER: 726 727 // REMEMBER: The primary reason for this class is that MEANINGFUL ERROR MESSAGES 728 // make Json-Binding a lot easer... "JsonArithmeticException" has just 729 // about everything that you need to know when debugging this stuff 730 731 try 732 { return jsonTypeToJavaType.apply((JsonNumber) jv); } 733 734 catch (ArithmeticException ae) 735 { 736 throw new JsonArithmeticArrException 737 (ae, ja, index, NUMBER, jv, returnClass); 738 } 739 740 // The JsonValue at the specified array-index does not contain an JsonNumber. 741 default: throw new JsonTypeArrException 742 (ja, index, NUMBER, jv, returnClass); 743 } 744 } 745 746 /** 747 * This is an internal helper method for retrieving a property from a {@link JsonObject}, 748 * and converting it to one of the standard <B STYLE='color: red;'>Java Types</B>. 749 * 750 * @param <T> Numeric Boxed-Type, as an instance of {@code java.lang.Class} 751 * @param jo Any instance of {@link JsonObject} 752 * @param propertyName Any property name contained by {@code 'jo'} 753 * @param isOptional <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_IS_OPTIONAL> 754 * @param jsonTypeToJavaType <EMBED CLASS='external-html' DATA-FILE-ID=READ_BOXED_JTTJT> 755 * 756 * @return The converted number, as an instance of Generic-Parameter {@code 'T'} 757 * 758 * @throws JsonPropMissingException If the property is missing, and {@code 'isOptional'} 759 * is {@code FALSE}. 760 * @throws JsonTypeObjException If the property specified does not contain a {@link JsonNumber} 761 * @throws JsonArithmeticObjException If there any arithmetic problems during the conversion 762 * 763 * @see #getInteger(JsonObject, String, boolean) 764 * @see #getLong(JsonObject, String, boolean) 765 * @see #getShort(JsonObject, String, boolean) 766 * @see #getByte(JsonObject, String, boolean) 767 * @see #getDouble(JsonObject, String, boolean) 768 * @see #getFloat(JsonObject, String, boolean) 769 */ 770 protected static <T extends java.lang.Number> T GET_NO_FLAGS( 771 final JsonObject jo, 772 final String propertyName, 773 final boolean isOptional, 774 final Function<JsonNumber, T> jsonTypeToJavaType, 775 final Class<T> returnClass 776 ) 777 { 778 // Here, a 'get' request was made for a property that isn't actually listed among the 779 // properties in the provided JsonObject. If 'isOptional' return null, otherwise throw 780 781 if (! jo.containsKey(propertyName)) 782 { 783 if (isOptional) return null; 784 785 throw new JsonPropMissingException 786 (jo, propertyName, NUMBER, returnClass); 787 } 788 789 final JsonValue jv = jo.get(propertyName); 790 791 switch (jv.getValueType()) 792 { 793 // This method allows for null-returns. If Json-Null, return Java-Null. 794 case NULL: return null; 795 796 // This will throw ArithmeticException if this isn't a proper Java int 797 case NUMBER: 798 799 800 // REMEMBER: The primary reason for this class is that MEANINGFUL ERROR MESSAGES 801 // make Json-Binding a lot easer... "JsonArithmeticException" has just 802 // about everything that you need to know when debugging this stuff 803 804 try 805 { return jsonTypeToJavaType.apply((JsonNumber) jv); } 806 807 catch (ArithmeticException ae) 808 { 809 throw new JsonArithmeticObjException 810 (ae, jo, propertyName, NUMBER, jv, returnClass); 811 } 812 813 // The JsonObject property does not contain a JsonNumber. 814 default: throw new JsonTypeObjException 815 (jo, propertyName, NUMBER, jv, returnClass); 816 } 817 } 818 819 820 // ******************************************************************************************** 821 // ******************************************************************************************** 822 // GET: USES-FLAG METHODS 823 // ******************************************************************************************** 824 // ******************************************************************************************** 825 826 827 /** 828 * This is an internal helper method for retrieving an element from a {@link JsonArray}, 829 * and converting it to a <B STYLE='color: red;'>Java Type</B>. 830 * <EMBED CLASS=defs DATA-TYPE=number DATA-JTYPE=JsonNumber> 831 * 832 * @param <T> Numeric Boxed-Type, as an instance of {@code java.lang.Class} 833 * @param ja Any instance of {@link JsonArray} 834 * @param index A valid index into {@code 'ja'} 835 * @param FLAGS Error-Control / Throw flag constants, defined in {@link JFlag} 836 * @param defaultValue <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_DEF_VAL> 837 * 838 * @return On success, this method returns the converted number (of type {@code 'T'}). 839 * 840 * @throws IndexOutOfBoundsException <EMBED CLASS='external-html' DATA-FILE-ID=IOOBEX> 841 * @throws JsonArithmeticArrException <EMBED CLASS='external-html' DATA-FILE-ID=JAEX> 842 * @throws JsonNullArrException <EMBED CLASS='external-html' DATA-FILE-ID=JNAEX> 843 * @throws JsonTypeArrException <EMBED CLASS='external-html' DATA-FILE-ID=JTAEX> 844 * 845 * @see #getInteger(JsonArray, int, int, int) 846 * @see #getLong(JsonArray, int, int, long) 847 * @see #getShort(JsonArray, int, int, short) 848 * @see #getByte(JsonArray, int, int, byte) 849 * @see #getDouble(JsonArray, int, int, double) 850 * @see #getFloat(JsonArray, int, int, float) 851 * @see ReadNumberJSON#get(JsonArray, int, int, Number) 852 * 853 * @see RJInternal#IOOBEX(JsonArray, int, Object, int) 854 * @see RJInternal#JNAEX(JsonArray, int, Object, int, JsonValue.ValueType, Class) 855 * @see RJInternal#JTAEX(JsonArray, int, Object, int, JsonValue.ValueType, JsonValue, Class) 856 */ 857 protected static <T extends java.lang.Number> T GET( 858 final JsonArray ja, 859 final int index, 860 final int FLAGS, 861 final T defaultValue, 862 final Class<T> returnClass, 863 final Function<JsonNumber, T> jsonTypeToJavaType, 864 final Function<JsonNumber, T> typeToType2 865 ) 866 { 867 // When TRUE, the index provided turned out to be outside of the bounds of the array. The 868 // IndexOutOfBounds "handler" (the method called here) will check the FLAGS, and: 869 // 870 // 1) return the defaultValue (if Requested by 'FLAGS' for IOOBEX) 871 // 2) return null (if Requested by 'FLAGS' for IOOBEX) 872 // 3) throw IndexOutOfBoundsException 873 // 874 // NOTE: It is probably a "little less efficient" to turn this into a method call, 875 // since there are all these parameters that have to be passed, but this is 876 // trading "readability" (less head-aches) in exchange for efficiency. 877 // 878 // This point applies to all of the "Exception Flag Handlers" used here 879 880 if (index >= ja.size()) return IOOBEX(ja, index, defaultValue, FLAGS); 881 882 final JsonValue jv = ja.get(index); 883 884 switch (jv.getValueType()) 885 { 886 // When a 'NULL' (Json-Null) JsonValue is present, the JsonNullArrException 'handler' 887 // will do one of the following: 888 // 889 // 1) return the defaultValue (if Requested by 'FLAGS' for JNAEX) 890 // 2) return null (if Requested by 'FLAGS' for JNAEX) 891 // 3) throw JsonNullArrException 892 893 case NULL: return JNAEX(ja, index, defaultValue, FLAGS, NUMBER, returnClass); 894 895 case NUMBER: 896 897 // Temp Variable, Used Twice (Just a Cast) 898 final JsonNumber n = (JsonNumber) jv; 899 900 try 901 { return jsonTypeToJavaType.apply(n); } 902 903 904 // Because 905 // 906 // 1) A method for this code would only be invoked here, and... 907 // 2) And because there would be 9 parameters to pass, 908 // 3) the 'inline' version of "Flag Handler" is left here! 909 // 910 // NOTE: All four "JsonArithmetic Arr/Obj Exception" exception throws 911 // are different for each of the 4 methods where they are used. 912 913 catch (ArithmeticException ae) 914 { 915 if ((FLAGS & RETURN_NULL_ON_AEX) != 0) return null; 916 if ((FLAGS & RETURN_DEFVAL_ON_AEX) != 0) return defaultValue; 917 if ((FLAGS & RETURN_JAPPROX_ON_AEX) != 0) return typeToType2.apply(n); 918 if ((FLAGS & RETURN_NULL_ON_ANY_ALL) != 0) return null; 919 if ((FLAGS & RETURN_DEFVAL_ON_ANY_ALL) != 0) return defaultValue; 920 921 throw new JsonArithmeticArrException 922 (ae, ja, index, NUMBER, jv, returnClass); 923 } 924 925 926 // The JsonValue at the specified array-index does not contain an JsonNumber. 927 // The "JsonTypeArrException Handler" will do one of these: 928 // 929 // 1) return the defaultValue (if Requested by 'FLAGS' for JTAEX) 930 // 2) return null (if Requested by 'FLAGS' for JTAEX) 931 // 3) throw JsonTypeArrException 932 933 default: return JTAEX(ja, index, defaultValue, FLAGS, NUMBER, jv, returnClass); 934 } 935 } 936 937 /** 938 * This is an internal helper method for retrieving a property from a {@link JsonObject}, 939 * and converting it to a <B STYLE='color: red;'>Java Type</B>. 940 * <EMBED CLASS=defs DATA-TYPE=number DATA-JTYPE=JsonNumber> 941 * 942 * @param jo Any instance of {@link JsonObject} 943 * @param propertyName Any property name contained by {@code 'jo'} 944 * @param FLAGS Error-Control / Throw flag constants, defined in {@link JFlag} 945 * @param defaultValue <EMBED CLASS='external-html' DATA-FILE-ID=COMMON_DEF_VAL> 946 * 947 * @return On success, this method returns the converted number (of type {@code 'T'}). 948 * 949 * @throws JsonPropMissingException <EMBED CLASS='external-html' DATA-FILE-ID=JPMEX> 950 * @throws JsonArithmeticObjException <EMBED CLASS='external-html' DATA-FILE-ID=JAEX> 951 * @throws JsonNullObjException <EMBED CLASS='external-html' DATA-FILE-ID=JNOEX> 952 * @throws JsonTypeObjException <EMBED CLASS='external-html' DATA-FILE-ID=JTOEX> 953 * 954 * @see #getInteger(JsonObject, String, int, int) 955 * @see #getLong(JsonObject, String, int, long) 956 * @see #getShort(JsonObject, String, int, short) 957 * @see #getByte(JsonObject, String, int, byte) 958 * @see #getDouble(JsonObject, String, int, double) 959 * @see #getFloat(JsonObject, String, int, float) 960 * @see ReadNumberJSON#get(JsonObject, String, int, Number) 961 * 962 * @see RJInternal#JPMEX(JsonObject, String, Object, int, JsonValue.ValueType, Class) 963 * @see RJInternal#JNOEX(JsonObject, String, Object, int, JsonValue.ValueType, Class) 964 * @see RJInternal#JTOEX(JsonObject, String, Object, int, JsonValue.ValueType, JsonValue, Class) 965 */ 966 protected static <T extends java.lang.Number> T GET( 967 final JsonObject jo, 968 final String propertyName, 969 final int FLAGS, 970 final T defaultValue, 971 final Class<T> returnClass, 972 final Function<JsonNumber, T> jsonTypeToJavaType, 973 final Function<JsonNumber, T> typeToType2 974 ) 975 { 976 final JsonValue jv = jo.get(propertyName); 977 978 979 // When TRUE, the user-specified 'property' (named by 'propertyName') isn't actually one 980 // of the listed properties inside the JsonObject. The JsonPropMissingException "handler" 981 // (the method called here) will check the FLAGS, and: 982 // 983 // 1) return the defaultValue (if Requested by 'FLAGS' for JPMEX) 984 // 2) return null (if Requested by 'FLAGS' for JPMEX) 985 // 3) throw JsonPropMissingException 986 // 987 // NOTE: It is probably a "little less efficient" to turn this into a method call, 988 // since there are all these parameters that have to be passed, but this is 989 // trading "readability" (less head-aches) in exchange for efficiency. 990 // 991 // This point applies to all of the "Exception Flag Handlers" used here 992 993 if (jv == null) return JPMEX(jo, propertyName, defaultValue, FLAGS, NUMBER, returnClass); 994 995 switch (jv.getValueType()) 996 { 997 // When a 'NULL' (Json-Null) JsonValue is present, the JsonNullObjException 'handler' 998 // will do one of the following: 999 // 1000 // 1) return the defaultValue (if Requested by 'FLAGS' for JNOEX) 1001 // 2) return null (if Requested by 'FLAGS' for JNOEX) 1002 // 3) throw JsonNullArrException 1003 1004 case NULL: return JNOEX(jo, propertyName, defaultValue, FLAGS, NUMBER, returnClass); 1005 1006 case NUMBER: 1007 1008 // Temp Variable, Used Twice (Just a Cast) 1009 final JsonNumber n = (JsonNumber) jv; 1010 1011 try 1012 { return jsonTypeToJavaType.apply(n); } 1013 1014 1015 // Because 1016 // 1017 // 1) A method for this code would only be invoked here, and... 1018 // 2) And because there would be 9 parameters to pass, 1019 // 3) the 'inline' version of "Flag Handler" is left here! 1020 // 1021 // NOTE: All four "JsonArithmetic Arr/Obj Exception" exception throws 1022 // are different for each of the 4 methods where they are used. 1023 1024 catch (ArithmeticException ae) 1025 { 1026 if ((FLAGS & RETURN_NULL_ON_AEX) != 0) return null; 1027 if ((FLAGS & RETURN_DEFVAL_ON_AEX) != 0) return defaultValue; 1028 if ((FLAGS & RETURN_JAPPROX_ON_AEX) != 0) return typeToType2.apply(n); 1029 if ((FLAGS & RETURN_NULL_ON_ANY_ALL) != 0) return null; 1030 if ((FLAGS & RETURN_DEFVAL_ON_ANY_ALL) != 0) return defaultValue; 1031 1032 throw new JsonArithmeticObjException 1033 (ae, jo, propertyName, NUMBER, jv, returnClass); 1034 } 1035 1036 1037 // The JsonValue of 'propertyName' does not contain an JsonNumber. 1038 // The "JsonTypeObjException Handler" will do one of these: 1039 // 1040 // 1) return the defaultValue (if Requested by 'FLAGS' for JTOEX) 1041 // 2) return null (if Requested by 'FLAGS' for JTOEX) 1042 // 3) throw JsonTypeObjException 1043 1044 default: return JTOEX(jo, propertyName, defaultValue, FLAGS, NUMBER, jv, returnClass); 1045 } 1046 } 1047 1048} 1049