001package com.thetransactioncompany.jsonrpc2.util; 002 003 004import java.util.List; 005import java.util.Map; 006 007import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; 008 009 010/** 011 * Utility class for retrieving JSON-RPC 2.0 positional parameters (packed into 012 * a JSON Array). 013 * 014 * <p>Provides a set of getter methods according to the expected parameter type 015 * (number, string, etc.) and whether the parameter is mandatory or optional: 016 * 017 * <ul> 018 * <li>{@code getXXX(param_pos)} for mandatory parameters, where 019 * {@code XXX} is the expected parameter type. 020 * <li>{@code getOptXXX(param_pos, default_value)} for optional parameters, 021 * specifying a default value. 022 * </ul> 023 * 024 * <p>There are also generic getter methods that let you do the type conversion 025 * yourself. 026 * 027 * <p>If a parameter cannot be retrieved, e.g. due to a missing mandatory 028 * parameter or bad type, a 029 * {@link com.thetransactioncompany.jsonrpc2.JSONRPC2Error#INVALID_PARAMS} 030 * exception is thrown. 031 * 032 * <p>Example: suppose you have a method with 3 positional parameters where the 033 * first two are mandatory and the last is optional and has a default value of 034 * {@code true}. 035 * 036 * <pre> 037 * // Parse received request string 038 * JSONRPC2Request request = null; 039 * 040 * try { 041 * request = JSONRPC2Request.parse(jsonString); 042 * } catch (JSONRPC2ParseException e) { 043 * // handle exception... 044 * } 045 * 046 * // Create a new retriever for positional parameters 047 * List params = (List)request.getParams(); 048 * PositionalParamsRetriever r = new PositionalParamsRetriever(params); 049 * 050 * try { 051 * // Extract first mandatory string parameter 052 * String param1 = r.getString(0); 053 * 054 * // Extract second integer parameter 055 * int param2 = r.getInt(1); 056 * 057 * // Extract third optional boolean parameter which defaults to true 058 * boolean param3 = r.getOptBoolean(2, true); 059 * 060 * } catch (JSONRPC2Error e) { 061 * // A JSONRPC2Error.INVALID_PARAMS will be thrown to indicate 062 * // an unexpected parameter type or a missing mandatory parameter. 063 * // You can use it straight away to create the appropriate 064 * // JSON-RPC 2.0 error response. 065 * JSONRPC2Response response = new JSONRPC2Response(e, null); 066 * } 067 * </pre> 068 * 069 * @author Vladimir Dzhuvinov 070 */ 071public class PositionalParamsRetriever 072 extends ParamsRetriever { 073 074 075 /** 076 * The positional parameters interface. 077 */ 078 private List<Object> params; 079 080 081 /** 082 * Throws a JSON-RPC 2.0 error indicating a missing positional 083 * parameter. 084 * 085 * @param position The parameter position. Should be non-negative. 086 * 087 * @throws JSONRPC2Error Formatted JSON-RPC 2.0 error. 088 */ 089 private static void throwMissingParameterException(final int position) 090 throws JSONRPC2Error { 091 092 throw JSONRPC2Error.INVALID_PARAMS. 093 appendMessage(": Missing parameter at position " + position); 094 } 095 096 097 /** 098 * Throws a JSON-RPC 2.0 error indicating a positional parameter with 099 * unexpected {@code null} value. 100 * 101 * @param position The parameter position. Should be non-negative. 102 * 103 * @throws JSONRPC2Error Formatted JSON-RPC 2.0 error. 104 */ 105 private static void throwNullParameterException(final int position) 106 throws JSONRPC2Error { 107 108 throw JSONRPC2Error.INVALID_PARAMS. 109 appendMessage(": Parameter at position " + position + " must not be null"); 110 } 111 112 113 /** 114 * Throws a JSON-RPC 2.0 error indicating a positional parameter with 115 * an unexpected enumerated value. 116 * 117 * @param position The parameter position. Should be non-negative. 118 * @param enumStrings The acceptable string values. Must not be 119 * {@code null}. 120 * 121 * @throws JSONRPC2Error Formatted JSON-RPC 2.0 error. 122 */ 123 private static void throwEnumParameterException(final int position, 124 final String[] enumStrings) 125 throws JSONRPC2Error { 126 127 StringBuilder msg = new StringBuilder(": Enumerated parameter at position " + 128 position + "\" must have values "); 129 130 for (int i=0; i < enumStrings.length; i++) { 131 132 if (i > 0 && i == enumStrings.length - 1) 133 msg.append(" or "); 134 135 else if (i > 0) 136 msg.append(", "); 137 138 msg.append('"'); 139 msg.append(enumStrings[i]); 140 msg.append('"'); 141 } 142 143 throw JSONRPC2Error.INVALID_PARAMS.appendMessage(msg.toString()); 144 } 145 146 147 /** 148 * Throws a JSON-RPC 2.0 error indicating a positional parameter with 149 * an unexpected enumerated value. 150 * 151 * @param position The parameter position. Should be non-negative. 152 * @param enumClass The enumeration class specifying the acceptable 153 * string values. Must not be {@code null}. 154 * 155 * @throws JSONRPC2Error Formatted JSON-RPC 2.0 error. 156 */ 157 private static <T extends Enum<T>> void throwEnumParameterException(final int position, 158 final Class<T> enumClass) 159 throws JSONRPC2Error { 160 161 StringBuilder msg = new StringBuilder(": Enumerated parameter at position " + 162 position + " must have values "); 163 164 T[] constants = enumClass.getEnumConstants(); 165 166 for (int i = 0; i < constants.length; i++) { 167 168 if (i > 0 && i == constants.length - 1) 169 msg.append(" or "); 170 171 else if (i > 0) 172 msg.append(", "); 173 174 msg.append('"'); 175 msg.append(constants[i].toString()); 176 msg.append('"'); 177 } 178 179 throw JSONRPC2Error.INVALID_PARAMS.appendMessage(msg.toString()); 180 } 181 182 183 /** 184 * Creates a JSON-RPC 2.0 error indicating a positional parameter with 185 * an unexpected JSON type. 186 * 187 * @param position The parameter position. Should be non-negative. 188 * 189 * @return Formatted JSON-RPC 2.0 error. 190 */ 191 private static JSONRPC2Error newUnexpectedParameterTypeException(final int position) { 192 193 return JSONRPC2Error.INVALID_PARAMS. 194 appendMessage(": Parameter at position " + position + " has an unexpected JSON type"); 195 } 196 197 198 /** 199 * Creates a JSON-RPC 2.0 error indicating an array exception. 200 * 201 * @param position The parameter position. Should be non-negative. 202 * 203 * @return Formatted JSON-RPC 2.0 error. 204 */ 205 private static JSONRPC2Error newArrayException(final int position) { 206 207 return JSONRPC2Error.INVALID_PARAMS. 208 appendMessage(": Parameter at position " + position + " caused an array exception"); 209 } 210 211 212 /** 213 * Creates a new positional parameters retriever from the specified 214 * value list. 215 * 216 * @param params The positional parameters list. Must not be 217 * {@code null}. 218 */ 219 public PositionalParamsRetriever(final List<Object> params) { 220 221 if (params == null) 222 throw new IllegalArgumentException("The parameters list must not be null"); 223 224 this.params = params; 225 } 226 227 228 /** 229 * Gets the positional parameters for this retriever. 230 * 231 * @return The positional parameters. 232 */ 233 public List<Object> getParams() { 234 235 return params; 236 } 237 238 239 @Override 240 public int size() { 241 242 return params.size(); 243 } 244 245 246 /** 247 * Returns {@code true} a parameter at the specified position exists, 248 * else {@code false}. 249 * 250 * @param position The parameter position. 251 * 252 * @return {@code true} if the parameter exists, else {@code false}. 253 */ 254 public boolean hasParam(final int position) { 255 256 return position < params.size(); 257 } 258 259 260 /** 261 * Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if there is 262 * no parameter at the specified position. 263 * 264 * <p>You may use this method to fire the proper JSON-RPC 2.0 error 265 * on a missing mandatory parameter. 266 * 267 * @param position The parameter position, starting with zero for the 268 * first. 269 * 270 * @throws JSONRPC2Error On a missing parameter 271 * ({@link JSONRPC2Error#INVALID_PARAMS}). 272 */ 273 public void ensureParam(final int position) 274 throws JSONRPC2Error { 275 276 if (position >= params.size() ) 277 throwMissingParameterException(position); 278 } 279 280 281 /** 282 * Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if there is 283 * no parameter at the specified position, its value is {@code null}, 284 * or its type doesn't map to the specified. 285 * 286 * <p>You may use this method to fire the proper JSON-RPC 2.0 error 287 * on a missing or badly-typed mandatory parameter. 288 * 289 * @param position The parameter position. 290 * @param clazz The corresponding Java class that the parameter 291 * should map to (any one of the return types of the 292 * {@code getXXX()} getter methods. Set to 293 * {@code Object.class} to allow any type. Must not be 294 * {@code null}. 295 * 296 * @throws JSONRPC2Error On a missing parameter, {@code null} value or 297 * bad type ({@link JSONRPC2Error#INVALID_PARAMS}). 298 */ 299 public <T> void ensureParam(final int position, final Class<T> clazz) 300 throws JSONRPC2Error { 301 302 ensureParam(position, clazz, false); 303 } 304 305 306 /** 307 * Throws a {@code JSONRPC2Error.INVALID_PARAMS} exception if there is 308 * no parameter at the specified position or its type doesn't map to 309 * the specified. 310 * 311 * <p>You may use this method to fire the proper JSON-RPC 2.0 error 312 * on a missing or badly-typed mandatory parameter. 313 * 314 * @param position The parameter position. 315 * @param clazz The corresponding Java class that the parameter 316 * should map to (any one of the return types of the 317 * {@code getXXX()} getter methods. Set to 318 * {@code Object.class} to allow any type. Must not be 319 * {@code null}. 320 * @param allowNull If {@code true} allows a {@code null} parameter 321 * value. 322 * 323 * @throws JSONRPC2Error On a missing parameter or bad type 324 * ({@link JSONRPC2Error#INVALID_PARAMS}). 325 */ 326 public <T> void ensureParam(final int position, 327 final Class<T> clazz, 328 final boolean allowNull) 329 throws JSONRPC2Error { 330 331 // First, check existence only 332 ensureParam(position); 333 334 // Now check type 335 Object value = params.get(position); 336 337 if (value == null) { 338 339 if (allowNull) 340 return; // ok 341 else 342 throwNullParameterException(position); 343 } 344 345 if (! clazz.isAssignableFrom(value.getClass())) 346 throw newUnexpectedParameterTypeException(position); 347 } 348 349 350 /** 351 * Retrieves the specified parameter which can be of any type. Use this 352 * generic getter if you want to cast the value yourself. Otherwise 353 * look at the typed {@code get*} methods. 354 * 355 * @param position The parameter position. 356 * 357 * @return The parameter value. 358 * 359 * @throws JSONRPC2Error On a missing parameter 360 * ({@link JSONRPC2Error#INVALID_PARAMS}). 361 */ 362 public Object get(final int position) 363 throws JSONRPC2Error { 364 365 ensureParam(position); 366 367 return params.get(position); 368 } 369 370 371 /** 372 * Retrieves the specified parameter which must map to the provided 373 * class (use the appropriate wrapper class for primitive types). 374 * 375 * @param position The parameter position. 376 * @param clazz The corresponding Java class that the parameter 377 * should map to (any one of the return types of the 378 * {@code getXXX()} getter methods. Set to 379 * {@code Object.class} to allow any type. Must not be 380 * {@code null}. 381 * 382 * @return The parameter value. 383 * 384 * @throws JSONRPC2Error On a missing parameter, {@code null} value or 385 * bad type ({@link JSONRPC2Error#INVALID_PARAMS}). 386 */ 387 public <T> T get(final int position, final Class<T> clazz) 388 throws JSONRPC2Error { 389 390 return get(position, clazz, false); 391 } 392 393 394 /** 395 * Retrieves the specified parameter which must map to the provided 396 * class (use the appropriate wrapper class for primitive types). 397 * 398 * @param position The parameter position. 399 * @param clazz The corresponding Java class that the parameter 400 * should map to (any one of the return types of the 401 * {@code getXXX()} getter methods. Set to 402 * {@code Object.class} to allow any type. Must not be 403 * {@code null}. 404 * @param allowNull If {@code true} allows a {@code null} parameter 405 * value. 406 * 407 * @return The parameter value. 408 * 409 * @throws JSONRPC2Error On a missing parameter or bad type 410 * ({@link JSONRPC2Error#INVALID_PARAMS}). 411 */ 412 @SuppressWarnings("unchecked") 413 public <T> T get(final int position, final Class<T> clazz, final boolean allowNull) 414 throws JSONRPC2Error { 415 416 ensureParam(position, clazz, allowNull); 417 418 try { 419 return (T)params.get(position); 420 421 } catch (ClassCastException e) { 422 423 throw newUnexpectedParameterTypeException(position); 424 } 425 } 426 427 428 /** 429 * Retrieves the specified optional parameter which must map to the 430 * provided class (use the appropriate wrapper class for primitive 431 * types). If the parameter doesn't exist the method returns the 432 * specified default value. 433 * 434 * @param position The parameter position. 435 * @param clazz The corresponding Java class that the parameter 436 * should map to (any one of the return types of 437 * the {@code getXXX()} getter methods. Set to 438 * {@code Object.class} to allow any type. Must not 439 * be {@code null}. 440 * @param defaultValue The default return value if the parameter 441 * doesn't exist. May be {@code null}. 442 * 443 * @return The parameter value. 444 * 445 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 446 * ({@link JSONRPC2Error#INVALID_PARAMS}). 447 */ 448 public <T> T getOpt(final int position, final Class<T> clazz, final T defaultValue) 449 throws JSONRPC2Error { 450 451 return getOpt(position, clazz, false, defaultValue); 452 } 453 454 455 /** 456 * Retrieves the specified optional parameter which must map to the 457 * provided class (use the appropriate wrapper class for primitive 458 * types). If the parameter doesn't exist the method returns the 459 * specified default value. 460 * 461 * @param position The parameter position. 462 * @param clazz The corresponding Java class that the parameter 463 * should map to (any one of the return types of 464 * the {@code getXXX()} getter methods. Set to 465 * {@code Object.class} to allow any type. Must not 466 * be {@code null}. 467 * @param allowNull If {@code true} allows a {@code null} parameter 468 * value. 469 * @param defaultValue The default return value if the parameter 470 * doesn't exist. May be {@code null}. 471 * 472 * @return The parameter value. 473 * 474 * @throws JSONRPC2Error On a bad parameter type 475 * ({@link JSONRPC2Error#INVALID_PARAMS}). 476 */ 477 @SuppressWarnings("unchecked") 478 public <T> T getOpt(final int position, 479 final Class<T> clazz, 480 final boolean allowNull, 481 final T defaultValue) 482 throws JSONRPC2Error { 483 484 if (! hasParam(position)) 485 return defaultValue; 486 487 ensureParam(position, clazz, allowNull); 488 489 try { 490 return (T)params.get(position); 491 492 } catch (ClassCastException e) { 493 494 throw newUnexpectedParameterTypeException(position); 495 } 496 } 497 498 499 /** 500 * Retrieves the specified string parameter. 501 * 502 * @param position The parameter position. 503 * 504 * @return The parameter value as a string. 505 * 506 * @throws JSONRPC2Error On a missing parameter, bad type or 507 * {@code null} value 508 * ({@link JSONRPC2Error#INVALID_PARAMS}). 509 */ 510 public String getString(final int position) 511 throws JSONRPC2Error { 512 513 return getString(position, false); 514 } 515 516 517 /** 518 * Retrieves the specified string parameter. 519 * 520 * @param position The parameter position. 521 * @param allowNull If {@code true} allows a {@code null} value. 522 * 523 * @return The parameter value as a string. 524 * 525 * @throws JSONRPC2Error On a missing parameter or bad type 526 * ({@link JSONRPC2Error#INVALID_PARAMS}). 527 */ 528 public String getString(final int position, final boolean allowNull) 529 throws JSONRPC2Error { 530 531 return get(position, String.class, allowNull); 532 } 533 534 535 /** 536 * Retrieves the specified optional string parameter. If it doesn't 537 * exist the method will return the specified default value. 538 * 539 * @param position The parameter position. 540 * @param defaultValue The default return value if the parameter 541 * doesn't exist. May be {@code null}. 542 * 543 * @return The parameter value as a string. 544 * 545 * @throws JSONRPC2Error On a bad type or {@code null} value 546 * ({@link JSONRPC2Error#INVALID_PARAMS}). 547 */ 548 public String getOptString(final int position, final String defaultValue) 549 throws JSONRPC2Error { 550 551 return getOptString(position, false, defaultValue); 552 } 553 554 555 /** 556 * Retrieves the specified optional string parameter. If it doesn't 557 * exist the method will return the specified default value. 558 * 559 * @param position The parameter position. 560 * @param allowNull If {@code true} allows a {@code null} value. 561 * @param defaultValue The default return value if the parameter 562 * doesn't exist. May be {@code null}. 563 * 564 * @return The parameter value as a string. 565 * 566 * @throws JSONRPC2Error On a bad type ({@link JSONRPC2Error#INVALID_PARAMS}). 567 */ 568 public String getOptString(final int position, final boolean allowNull, final String defaultValue) 569 throws JSONRPC2Error { 570 571 return getOpt(position, String.class, allowNull, defaultValue); 572 } 573 574 575 /** 576 * Retrieves the specified enumerated string parameter. 577 * 578 * @param position The parameter position. 579 * @param enumStrings The acceptable string values. Must not be 580 * {@code null}. 581 * 582 * @return The parameter value as a string. 583 * 584 * @throws JSONRPC2Error On a missing parameter, bad type or 585 * bad enumeration value 586 * ({@link JSONRPC2Error#INVALID_PARAMS}). 587 */ 588 public String getEnumString(final int position, final String[] enumStrings) 589 throws JSONRPC2Error { 590 591 return getEnumString(position, enumStrings, false); 592 } 593 594 595 /** 596 * Retrieves the specified enumerated string parameter, allowing for a 597 * case-insensitive match. 598 * 599 * @param position The parameter position. 600 * @param enumStrings The acceptable string values. Must not be 601 * {@code null}. 602 * @param ignoreCase {@code true} for a case insensitive match. 603 * 604 * @return The matching parameter value as a string. 605 * 606 * @throws JSONRPC2Error On a missing parameter, bad type or 607 * bad enumeration value 608 * ({@link JSONRPC2Error#INVALID_PARAMS}). 609 */ 610 public String getEnumString(final int position, 611 final String[] enumStrings, 612 final boolean ignoreCase) 613 throws JSONRPC2Error { 614 615 String value = get(position, String.class); 616 617 String match = getEnumStringMatch(value, enumStrings, ignoreCase); 618 619 if (match == null) 620 throwEnumParameterException(position, enumStrings); 621 622 return match; 623 } 624 625 626 /** 627 * Retrieves the specified optional enumerated string parameter. If it 628 * doesn't exist the method will return the specified default value. 629 * 630 * @param position The parameter position. 631 * @param enumStrings The acceptable string values. Must not be 632 * {@code null}. 633 * @param defaultValue The default return value if the parameter 634 * doesn't exist. May be {@code null}. 635 * 636 * @return The parameter value as a string. 637 * 638 * @throws JSONRPC2Error On a bad type or bad enumeration value 639 * ({@link JSONRPC2Error#INVALID_PARAMS}). 640 */ 641 public String getOptEnumString(final int position, 642 final String[] enumStrings, 643 final String defaultValue) 644 throws JSONRPC2Error { 645 646 return getOptEnumString(position, enumStrings, defaultValue, false); 647 } 648 649 650 /** 651 * Retrieves the specified optional enumerated string parameter, 652 * allowing for a case insenstive match. If it doesn't exist the method 653 * will return the specified default value. 654 * 655 * @param position The parameter position. 656 * @param enumStrings The acceptable string values. Must not be 657 * {@code null}. 658 * @param defaultValue The default return value if the parameter 659 * doesn't exist. May be {@code null}. 660 * @param ignoreCase {@code true} for a case insensitive match. 661 * 662 * @return The parameter value as a string. 663 * 664 * @throws JSONRPC2Error On a bad type or bad enumeration value 665 * ({@link JSONRPC2Error#INVALID_PARAMS}). 666 */ 667 public String getOptEnumString(final int position, 668 final String[] enumStrings, 669 final String defaultValue, 670 final boolean ignoreCase) 671 throws JSONRPC2Error { 672 673 String value = getOpt(position, String.class, defaultValue); 674 675 if (defaultValue == null && value == null) 676 return null; 677 678 String match = getEnumStringMatch(value, enumStrings, ignoreCase); 679 680 if (match == null) 681 throwEnumParameterException(position, enumStrings); 682 683 return match; 684 } 685 686 687 /** 688 * Retrieves the specified enumerated parameter (from a JSON string 689 * that has a predefined set of possible values). 690 * 691 * @param position The parameter position. 692 * @param enumClass An enumeration type with constant names 693 * representing the acceptable string values. Must not 694 * be {@code null}. 695 * 696 * @return The matching enumeration constant. 697 * 698 * @throws JSONRPC2Error On a missing parameter, bad type or 699 * bad enumeration value 700 * ({@link JSONRPC2Error#INVALID_PARAMS}). 701 */ 702 public <T extends Enum<T>> T getEnum(final int position, final Class<T> enumClass) 703 throws JSONRPC2Error { 704 705 return getEnum(position, enumClass, false); 706 } 707 708 709 /** 710 * Retrieves the specified enumerated parameter (from a JSON string 711 * that has a predefined set of possible values), allowing for a case 712 * -insensitive match. 713 * 714 * @param position The parameter position. 715 * @param enumClass An enumeration type with constant names 716 * representing the acceptable string values. Must 717 * not be {@code null}. 718 * @param ignoreCase If {@code true} a case insensitive match against 719 * the acceptable constant names is performed. 720 * 721 * @return The matching enumeration constant. 722 * 723 * @throws JSONRPC2Error On a missing parameter, bad type or 724 * bad enumeration value 725 * ({@link JSONRPC2Error#INVALID_PARAMS}). 726 */ 727 public <T extends Enum<T>> T getEnum(final int position, 728 final Class<T> enumClass, 729 final boolean ignoreCase) 730 throws JSONRPC2Error { 731 732 String value = get(position, String.class); 733 734 T match = getEnumStringMatch(value, enumClass, ignoreCase); 735 736 if (match == null) 737 throwEnumParameterException(position, enumClass); 738 739 return match; 740 } 741 742 743 /** 744 * Retrieves the specified optional enumerated parameter (from a JSON 745 * string that has a predefined set of possible values). If it doesn't 746 * exist the method will return the specified default value. 747 * 748 * @param position The parameter position. 749 * @param enumClass An enumeration type with constant names 750 * representing the acceptable string values. Must 751 * not be {@code null}. 752 * @param defaultValue The default return value if the parameter 753 * doesn't exist. May be {@code null}. 754 * 755 * @return The matching enumeration constant. 756 * 757 * @throws JSONRPC2Error On a bad type or bad enumeration value 758 * ({@link JSONRPC2Error#INVALID_PARAMS}). 759 */ 760 public <T extends Enum<T>> T getOptEnum(final int position, 761 final Class<T> enumClass, 762 final String defaultValue) 763 throws JSONRPC2Error { 764 765 return getOptEnum(position, enumClass, defaultValue, false); 766 } 767 768 769 /** 770 * Retrieves the specified optional enumerated parameter (from a JSON 771 * string that has a predefined set of possible values), allowing for a 772 * case insenstive match. If it doesn't exist the method will return 773 * the specified default value. 774 * 775 * @param position The parameter position. 776 * @param enumClass An enumeration type with constant names 777 * representing the acceptable string values. Must 778 * not be {@code null}. 779 * @param defaultValue The default return value if the parameter 780 * doesn't exist. May be {@code null}. 781 * @param ignoreCase If {@code true} a case-insensitive match against 782 * the acceptable constant names is performed. 783 * 784 * @return The matching enumeration constant. 785 * 786 * @throws JSONRPC2Error On a bad type or bad enumeration value 787 * ({@link JSONRPC2Error#INVALID_PARAMS}). 788 */ 789 public <T extends Enum<T>> T getOptEnum(final int position, 790 final Class<T> enumClass, 791 final String defaultValue, 792 final boolean ignoreCase) 793 throws JSONRPC2Error { 794 795 String value = getOpt(position, String.class, defaultValue); 796 797 if (defaultValue == null && value == null) 798 return null; 799 800 T match = getEnumStringMatch(value, enumClass, ignoreCase); 801 802 if (match == null) 803 throwEnumParameterException(position, enumClass); 804 805 return match; 806 } 807 808 809 /** 810 * Retrieves the specified boolean (maps from JSON true/false) 811 * parameter. 812 * 813 * @param position The parameter position. 814 * 815 * @return The parameter value as a {@code boolean}. 816 * 817 * @throws JSONRPC2Error On a missing parameter, bad type or 818 * {@code null} value 819 * ({@link JSONRPC2Error#INVALID_PARAMS}). 820 */ 821 public boolean getBoolean(final int position) 822 throws JSONRPC2Error { 823 824 return get(position, Boolean.class); 825 } 826 827 828 /** 829 * Retrieves the specified optional boolean (maps from JSON true/false) 830 * parameter. If it doesn't exist the method will return the specified 831 * default value. 832 * 833 * @param position The parameter position. 834 * @param defaultValue The default return value if the parameter 835 * doesn't exist. 836 * 837 * @return The parameter value as a {@code boolean}. 838 * 839 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 840 * ({@link JSONRPC2Error#INVALID_PARAMS}). 841 */ 842 public boolean getOptBoolean(final int position, final boolean defaultValue) 843 throws JSONRPC2Error { 844 845 return getOpt(position, Boolean.class, defaultValue); 846 } 847 848 849 /** 850 * Retrieves the specified numeric parameter as an {@code int}. 851 * 852 * @param position The parameter position. 853 * 854 * @return The parameter value as an {@code int}. 855 * 856 * @throws JSONRPC2Error On a missing parameter, bad type or 857 * {@code null} value 858 * ({@link JSONRPC2Error#INVALID_PARAMS}). 859 */ 860 public int getInt(final int position) 861 throws JSONRPC2Error { 862 863 Number number = get(position, Number.class); 864 return number.intValue(); 865 } 866 867 868 /** 869 * Retrieves the specified optional numeric parameter as an 870 * {@code int}. If it doesn't exist the method will return the 871 * specified default value. 872 * 873 * @param position The parameter position. 874 * @param defaultValue The default return value if the parameter 875 * doesn't exist. 876 * 877 * @return The parameter value as an {@code int}. 878 * 879 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 880 * ({@link JSONRPC2Error#INVALID_PARAMS}). 881 */ 882 public int getOptInt(final int position, final int defaultValue) 883 throws JSONRPC2Error { 884 885 Number number = getOpt(position, Number.class, defaultValue); 886 return number.intValue(); 887 } 888 889 890 /** 891 * Retrieves the specified numeric parameter as a {@code long}. 892 * 893 * @param position The parameter position. 894 * 895 * @return The parameter value as a {@code long}. 896 * 897 * @throws JSONRPC2Error On a missing parameter, bad type or 898 * {@code null} value 899 * ({@link JSONRPC2Error#INVALID_PARAMS}). 900 */ 901 public long getLong(final int position) 902 throws JSONRPC2Error { 903 904 Number number = get(position, Number.class); 905 return number.longValue(); 906 } 907 908 909 /** 910 * Retrieves the specified optional numeric parameter as a 911 * {@code long}. If it doesn't exist the method will return the 912 * specified default value. 913 * 914 * @param position The parameter position. 915 * @param defaultValue The default return value if the parameter 916 * doesn't exist. 917 * 918 * @return The parameter value as a {@code long}. 919 * 920 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 921 * ({@link JSONRPC2Error#INVALID_PARAMS}). 922 */ 923 public long getOptLong(final int position, final long defaultValue) 924 throws JSONRPC2Error { 925 926 Number number = getOpt(position, Number.class, defaultValue); 927 return number.longValue(); 928 } 929 930 931 /** 932 * Retrieves the specified numeric parameter as a {@code float}. 933 * 934 * @param position The parameter position. 935 * 936 * @return The parameter value as a {@code float}. 937 * 938 * @throws JSONRPC2Error On a missing parameter, bad type or 939 * {@code null} value 940 * ({@link JSONRPC2Error#INVALID_PARAMS}). 941 */ 942 public float getFloat(final int position) 943 throws JSONRPC2Error { 944 945 Number number = get(position, Number.class); 946 return number.floatValue(); 947 } 948 949 950 /** 951 * Retrieves the specified optional numeric parameter as a 952 * {@code float}. If it doesn't exist the method will return the 953 * specified default value. 954 * 955 * @param position The parameter position. 956 * @param defaultValue The default return value if the parameter 957 * doesn't exist. 958 * 959 * @return The parameter value as a {@code float}. 960 * 961 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 962 * ({@link JSONRPC2Error#INVALID_PARAMS}). 963 */ 964 public float getOptFloat(final int position, final float defaultValue) 965 throws JSONRPC2Error { 966 967 Number number = getOpt(position, Number.class, defaultValue); 968 return number.floatValue(); 969 } 970 971 972 /** 973 * Retrieves the specified numeric parameter as a {@code double}. 974 * 975 * @param position The parameter position. 976 * 977 * @return The parameter value as a {@code double}. 978 * 979 * @throws JSONRPC2Error On a missing parameter, bad type or 980 * {@code null} value 981 * ({@link JSONRPC2Error#INVALID_PARAMS}). 982 */ 983 public double getDouble(final int position) 984 throws JSONRPC2Error { 985 986 Number number = get(position, Number.class); 987 return number.doubleValue(); 988 } 989 990 991 /** 992 * Retrieves the specified optional numeric parameter as a 993 * {@code double}. If it doesn't exist the method will return the 994 * specified default value. 995 * 996 * @param position The parameter position. 997 * @param defaultValue The default return value if the parameter 998 * doesn't exist. 999 * 1000 * @return The parameter value as a {@code double}. 1001 * 1002 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 1003 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1004 */ 1005 public double getOptDouble(final int position, final double defaultValue) 1006 throws JSONRPC2Error { 1007 1008 Number number = getOpt(position, Number.class, defaultValue); 1009 return number.doubleValue(); 1010 } 1011 1012 1013 /** 1014 * Retrieves the specified list (maps from JSON array) parameter. 1015 * 1016 * @param position The parameter position. 1017 * 1018 * @return The parameter value as a list. 1019 * 1020 * @throws JSONRPC2Error On a missing parameter, bad type or 1021 * {@code null} value 1022 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1023 */ 1024 public List<Object> getList(final int position) 1025 throws JSONRPC2Error { 1026 1027 final boolean allowNull = false; 1028 1029 return getList(position, allowNull); 1030 } 1031 1032 1033 /** 1034 * Retrieves the specified list (maps from JSON array) parameter. 1035 * 1036 * @param position The parameter position. 1037 * @param allowNull If {@code true} allows a {@code null} value. 1038 * 1039 * @return The parameter value as a list. 1040 * 1041 * @throws JSONRPC2Error On a missing parameter or bad type 1042 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1043 */ 1044 @SuppressWarnings("unchecked") 1045 public List<Object> getList(final int position, final boolean allowNull) 1046 throws JSONRPC2Error { 1047 1048 return (List<Object>)get(position, List.class, allowNull); 1049 } 1050 1051 1052 /** 1053 * Retrieves the specified optional list (maps from JSON array) 1054 * parameter. If it doesn't exist the method will return the specified 1055 * default value. 1056 * 1057 * @param position The parameter position. 1058 * @param defaultValue The default return value if the parameter 1059 * doesn't exist. May be {@code null}. 1060 * 1061 * @return The parameter value as a list. 1062 * 1063 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 1064 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1065 */ 1066 public List<Object> getOptList(final int position, final List<Object> defaultValue) 1067 throws JSONRPC2Error { 1068 1069 final boolean allowNull = false; 1070 1071 return getOptList(position, allowNull, defaultValue); 1072 } 1073 1074 1075 /** 1076 * Retrieves the specified optional list (maps from JSON array) 1077 * parameter. If it doesn't exist the method will return the specified 1078 * default value. 1079 * 1080 * @param position The parameter position. 1081 * @param allowNull If {@code true} allows a {@code null} value. 1082 * @param defaultValue The default return value if the parameter 1083 * doesn't exist. May be {@code null}. 1084 * 1085 * @return The parameter value as a list. 1086 * 1087 * @throws JSONRPC2Error On a bad parameter type 1088 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1089 */ 1090 @SuppressWarnings("unchecked") 1091 public List<Object> getOptList(final int position, 1092 final boolean allowNull, 1093 final List<Object> defaultValue) 1094 throws JSONRPC2Error { 1095 1096 return (List<Object>)getOpt(position, List.class, allowNull, defaultValue); 1097 } 1098 1099 1100 /** 1101 * Retrieves the specified string array (maps from JSON array of 1102 * strings) parameter. 1103 * 1104 * @param position The parameter position. 1105 * 1106 * @return The parameter value as a string array. 1107 * 1108 * @throws JSONRPC2Error On a missing parameter, bad type or 1109 * {@code null} value 1110 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1111 */ 1112 public String[] getStringArray(final int position) 1113 throws JSONRPC2Error { 1114 1115 final boolean allowNull = false; 1116 1117 return getStringArray(position, allowNull); 1118 } 1119 1120 1121 /** 1122 * Retrieves the specified string array (maps from JSON array of 1123 * strings) parameter. 1124 * 1125 * @param position The parameter position. 1126 * @param allowNull If {@code true} allows a {@code null} value. 1127 * 1128 * @return The parameter value as a string array. 1129 * 1130 * @throws JSONRPC2Error On a missing parameter or bad type 1131 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1132 */ 1133 @SuppressWarnings("unchecked") 1134 public String[] getStringArray(final int position, final boolean allowNull) 1135 throws JSONRPC2Error { 1136 1137 List<Object> list = getList(position, allowNull); 1138 1139 if (list == null) 1140 return null; 1141 1142 try { 1143 return list.toArray(new String[0]); 1144 1145 } catch (ArrayStoreException e) { 1146 1147 throw newArrayException(position); 1148 } 1149 } 1150 1151 1152 /** 1153 * Retrieves the specified optional string array (maps from JSON array 1154 * of strings) parameter. If it doesn't exist the method will return 1155 * the specified default value. 1156 * 1157 * @param position The parameter position. 1158 * @param defaultValue The default return value if the parameter 1159 * doesn't exist. May be {@code null}. 1160 * 1161 * @return The parameter value as a string array. 1162 * 1163 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 1164 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1165 */ 1166 public String[] getOptStringArray(final int position, final String[] defaultValue) 1167 throws JSONRPC2Error { 1168 1169 final boolean allowNull = false; 1170 1171 return getOptStringArray(position, allowNull, defaultValue); 1172 } 1173 1174 1175 /** 1176 * Retrieves the specified optional string array (maps from JSON array 1177 * of strings) parameter. If it doesn't exist the method will return 1178 * the specified default value. 1179 * 1180 * @param position The parameter position. 1181 * @param allowNull If {@code true} allows a {@code null} value. 1182 * @param defaultValue The default return value if the parameter 1183 * doesn't exist. May be {@code null}. 1184 * 1185 * @return The parameter value as a string array. 1186 * 1187 * @throws JSONRPC2Error On a bad parameter type 1188 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1189 */ 1190 public String[] getOptStringArray(final int position, 1191 final boolean allowNull, 1192 final String[] defaultValue) 1193 throws JSONRPC2Error { 1194 1195 if (! hasParam(position)) 1196 return defaultValue; 1197 1198 return getStringArray(position, allowNull); 1199 } 1200 1201 1202 /** 1203 * Retrieves the specified map (maps from JSON object) parameter. 1204 * 1205 * @param position The parameter position. 1206 * 1207 * @return The parameter value as a map. 1208 * 1209 * @throws JSONRPC2Error On a missing parameter, bad type or 1210 * {@code null} value 1211 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1212 */ 1213 public Map<String,Object> getMap(final int position) 1214 throws JSONRPC2Error { 1215 1216 return getMap(position, false); 1217 } 1218 1219 1220 /** 1221 * Retrieves the specified map (maps from JSON object) parameter. 1222 * 1223 * @param position The parameter position. 1224 * @param allowNull If {@code true} allows a {@code null} value. 1225 * 1226 * @return The parameter value as a map. 1227 * 1228 * @throws JSONRPC2Error On a missing parameter or bad type 1229 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1230 */ 1231 @SuppressWarnings("unchecked") 1232 public Map<String,Object> getMap(final int position, final boolean allowNull) 1233 throws JSONRPC2Error { 1234 1235 try { 1236 return (Map<String,Object>)get(position, Map.class, allowNull); 1237 1238 } catch (ClassCastException e) { 1239 1240 throw newUnexpectedParameterTypeException(position); 1241 } 1242 } 1243 1244 1245 /** 1246 * Retrieves the specified optional map (maps from JSON object) 1247 * parameter. If it doesn't exist the method will return the specified 1248 * default value. 1249 * 1250 * @param position The parameter position. 1251 * @param defaultValue The default return value if the parameter 1252 * doesn't exist. May be {@code null}. 1253 * 1254 * @return The parameter value as a map. 1255 * 1256 * @throws JSONRPC2Error On a bad parameter type or {@code null} value 1257 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1258 */ 1259 public Map<String,Object> getOptMap(final int position, final Map<String,Object> defaultValue) 1260 throws JSONRPC2Error { 1261 1262 return getOptMap(position, false, defaultValue); 1263 } 1264 1265 1266 /** 1267 * Retrieves the specified optional map (maps from JSON object) 1268 * parameter. If it doesn't exist the method will return the specified 1269 * default value. 1270 * 1271 * @param position The parameter position. 1272 * @param allowNull If {@code true} allows a {@code null} value. 1273 * @param defaultValue The default return value if the parameter 1274 * doesn't exist. May be {@code null}. 1275 * 1276 * @return The parameter value as a map. 1277 * 1278 * @throws JSONRPC2Error On a bad parameter type 1279 * ({@link JSONRPC2Error#INVALID_PARAMS}). 1280 */ 1281 @SuppressWarnings("unchecked") 1282 public Map<String,Object> getOptMap(final int position, 1283 final boolean allowNull, 1284 final Map<String,Object> defaultValue) 1285 throws JSONRPC2Error { 1286 1287 try { 1288 return (Map<String,Object>)getOpt(position, Map.class, allowNull, defaultValue); 1289 1290 } catch (ClassCastException e) { 1291 1292 throw newUnexpectedParameterTypeException(position); 1293 } 1294 } 1295}