1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.util; 18 19 import android.annotation.IntRange; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.os.Build; 24 import android.text.TextUtils; 25 26 import com.google.errorprone.annotations.CompileTimeConstant; 27 28 import java.util.Arrays; 29 import java.util.Collection; 30 import java.util.Objects; 31 32 /** 33 * Simple static methods to be called at the start of your own methods to verify 34 * correct arguments and state. 35 */ 36 public class Preconditions { 37 38 /** 39 * Ensures that an expression checking an argument is true. 40 * 41 * @param expression the expression to check 42 * @throws IllegalArgumentException if {@code expression} is false 43 */ 44 @UnsupportedAppUsage checkArgument(boolean expression)45 public static void checkArgument(boolean expression) { 46 if (!expression) { 47 throw new IllegalArgumentException(); 48 } 49 } 50 51 /** 52 * Ensures that an expression checking an argument is true. 53 * 54 * @param expression the expression to check 55 * @param errorMessage the exception message to use if the check fails; will 56 * be converted to a string using {@link String#valueOf(Object)} 57 * @throws IllegalArgumentException if {@code expression} is false 58 */ 59 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) checkArgument( boolean expression, final @CompileTimeConstant Object errorMessage)60 public static void checkArgument( 61 boolean expression, 62 final @CompileTimeConstant Object errorMessage) { 63 if (!expression) { 64 throw new IllegalArgumentException(String.valueOf(errorMessage)); 65 } 66 } 67 68 /** 69 * Ensures that an expression checking an argument is true. 70 * 71 * @param expression the expression to check 72 * @param messageTemplate a printf-style message template to use if the check fails; will 73 * be converted to a string using {@link String#format(String, Object...)} 74 * @param messageArgs arguments for {@code messageTemplate} 75 * @throws IllegalArgumentException if {@code expression} is false 76 */ checkArgument( final boolean expression, final @CompileTimeConstant @NonNull String messageTemplate, final Object... messageArgs)77 public static void checkArgument( 78 final boolean expression, 79 final @CompileTimeConstant @NonNull String messageTemplate, 80 final Object... messageArgs) { 81 if (!expression) { 82 throw new IllegalArgumentException(String.format(messageTemplate, messageArgs)); 83 } 84 } 85 86 /** 87 * Ensures that an string reference passed as a parameter to the calling 88 * method is not empty. 89 * 90 * @param string an string reference 91 * @return the string reference that was validated 92 * @throws IllegalArgumentException if {@code string} is empty 93 */ checkStringNotEmpty(final T string)94 public static @NonNull <T extends CharSequence> T checkStringNotEmpty(final T string) { 95 if (TextUtils.isEmpty(string)) { 96 throw new IllegalArgumentException(); 97 } 98 return string; 99 } 100 101 /** 102 * Ensures that an string reference passed as a parameter to the calling 103 * method is not empty. 104 * 105 * @param string an string reference 106 * @param errorMessage the exception message to use if the check fails; will 107 * be converted to a string using {@link String#valueOf(Object)} 108 * @return the string reference that was validated 109 * @throws IllegalArgumentException if {@code string} is empty 110 */ checkStringNotEmpty(final T string, final @CompileTimeConstant Object errorMessage)111 public static @NonNull <T extends CharSequence> T checkStringNotEmpty(final T string, 112 final @CompileTimeConstant Object errorMessage) { 113 if (TextUtils.isEmpty(string)) { 114 throw new IllegalArgumentException(String.valueOf(errorMessage)); 115 } 116 return string; 117 } 118 119 /** 120 * Ensures that an string reference passed as a parameter to the calling method is not empty. 121 * 122 * @param string an string reference 123 * @param messageTemplate a printf-style message template to use if the check fails; will be 124 * converted to a string using {@link String#format(String, Object...)} 125 * @param messageArgs arguments for {@code messageTemplate} 126 * @return the string reference that was validated 127 * @throws IllegalArgumentException if {@code string} is empty 128 */ checkStringNotEmpty( final T string, final @NonNull @CompileTimeConstant String messageTemplate, final Object... messageArgs)129 public static @NonNull <T extends CharSequence> T checkStringNotEmpty( 130 final T string, 131 final @NonNull @CompileTimeConstant String messageTemplate, 132 final Object... messageArgs) { 133 if (TextUtils.isEmpty(string)) { 134 throw new IllegalArgumentException(String.format(messageTemplate, messageArgs)); 135 } 136 return string; 137 } 138 139 /** 140 * Ensures that an object reference passed as a parameter to the calling 141 * method is not null. 142 * 143 * @param reference an object reference 144 * @return the non-null reference that was validated 145 * @throws NullPointerException if {@code reference} is null 146 * @deprecated - use {@link java.util.Objects.requireNonNull} instead. 147 */ 148 @Deprecated 149 @UnsupportedAppUsage checkNotNull(final T reference)150 public static @NonNull <T> T checkNotNull(final T reference) { 151 if (reference == null) { 152 throw new NullPointerException(); 153 } 154 return reference; 155 } 156 157 /** 158 * Ensures that an object reference passed as a parameter to the calling 159 * method is not null. 160 * 161 * @param reference an object reference 162 * @param errorMessage the exception message to use if the check fails; will 163 * be converted to a string using {@link String#valueOf(Object)} 164 * @return the non-null reference that was validated 165 * @throws NullPointerException if {@code reference} is null 166 * @deprecated - use {@link java.util.Objects#requireNonNull} instead. 167 */ 168 @Deprecated 169 @UnsupportedAppUsage checkNotNull( final T reference, final @CompileTimeConstant Object errorMessage)170 public static @NonNull <T> T checkNotNull( 171 final T reference, 172 final @CompileTimeConstant Object errorMessage) { 173 if (reference == null) { 174 throw new NullPointerException(String.valueOf(errorMessage)); 175 } 176 return reference; 177 } 178 179 /** 180 * Ensures that an object reference passed as a parameter to the calling 181 * method is not null. 182 * 183 * @param messageTemplate a printf-style message template to use if the check fails; will 184 * be converted to a string using {@link String#format(String, Object...)} 185 * @param messageArgs arguments for {@code messageTemplate} 186 * @throws NullPointerException if {@code reference} is null 187 */ checkNotNull( final T reference, final @NonNull @CompileTimeConstant String messageTemplate, final Object... messageArgs)188 public static @NonNull <T> T checkNotNull( 189 final T reference, 190 final @NonNull @CompileTimeConstant String messageTemplate, 191 final Object... messageArgs) { 192 if (reference == null) { 193 throw new NullPointerException(String.format(messageTemplate, messageArgs)); 194 } 195 return reference; 196 } 197 198 /** 199 * Ensures the truth of an expression involving the state of the calling 200 * instance, but not involving any parameters to the calling method. 201 * 202 * @param expression a boolean expression 203 * @throws IllegalStateException if {@code expression} is false 204 */ 205 @UnsupportedAppUsage checkState(final boolean expression)206 public static void checkState(final boolean expression) { 207 checkState(expression, null); 208 } 209 210 /** 211 * Ensures the truth of an expression involving the state of the calling 212 * instance, but not involving any parameters to the calling method. 213 * 214 * @param expression a boolean expression 215 * @param errorMessage the exception message to use if the check fails; will 216 * be converted to a string using {@link String#valueOf(Object)} 217 * @throws IllegalStateException if {@code expression} is false 218 */ 219 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) checkState(final boolean expression, String errorMessage)220 public static void checkState(final boolean expression, String errorMessage) { 221 if (!expression) { 222 throw new IllegalStateException(errorMessage); 223 } 224 } 225 226 /** 227 * Ensures the truth of an expression involving the state of the calling 228 * instance, but not involving any parameters to the calling method. 229 * 230 * @param expression a boolean expression 231 * @param messageTemplate a printf-style message template to use if the check fails; will 232 * be converted to a string using {@link String#format(String, Object...)} 233 * @param messageArgs arguments for {@code messageTemplate} 234 * @throws IllegalStateException if {@code expression} is false 235 */ checkState( final boolean expression, final @NonNull @CompileTimeConstant String messageTemplate, final Object... messageArgs)236 public static void checkState( 237 final boolean expression, 238 final @NonNull @CompileTimeConstant String messageTemplate, 239 final Object... messageArgs) { 240 if (!expression) { 241 throw new IllegalStateException(String.format(messageTemplate, messageArgs)); 242 } 243 } 244 245 /** 246 * Ensures the truth of an expression involving whether the calling identity is authorized to 247 * call the calling method. 248 * 249 * @param expression a boolean expression 250 * @throws SecurityException if {@code expression} is false 251 */ checkCallAuthorization(final boolean expression)252 public static void checkCallAuthorization(final boolean expression) { 253 if (!expression) { 254 throw new SecurityException("Calling identity is not authorized"); 255 } 256 } 257 258 /** 259 * Ensures the truth of an expression involving whether the calling identity is authorized to 260 * call the calling method. 261 * 262 * @param expression a boolean expression 263 * @param message the message of the security exception to be thrown 264 * @throws SecurityException if {@code expression} is false 265 */ checkCallAuthorization(final boolean expression, final String message)266 public static void checkCallAuthorization(final boolean expression, final String message) { 267 if (!expression) { 268 throw new SecurityException(message); 269 } 270 } 271 272 /** 273 * Ensures the truth of an expression involving whether the calling identity is authorized to 274 * call the calling method. 275 * 276 * @param expression a boolean expression 277 * @param messageTemplate a printf-style message template to use if the check fails; will 278 * be converted to a string using {@link String#format(String, Object...)} 279 * @param messageArgs arguments for {@code messageTemplate} 280 * @throws SecurityException if {@code expression} is false 281 */ checkCallAuthorization( final boolean expression, final @NonNull @CompileTimeConstant String messageTemplate, final Object... messageArgs)282 public static void checkCallAuthorization( 283 final boolean expression, 284 final @NonNull @CompileTimeConstant String messageTemplate, 285 final Object... messageArgs) { 286 if (!expression) { 287 throw new SecurityException(String.format(messageTemplate, messageArgs)); 288 } 289 } 290 291 /** 292 * Ensures the truth of an expression involving whether the calling user is authorized to 293 * call the calling method. 294 * 295 * @param expression a boolean expression 296 * @throws SecurityException if {@code expression} is false 297 */ checkCallingUser(final boolean expression)298 public static void checkCallingUser(final boolean expression) { 299 if (!expression) { 300 throw new SecurityException("Calling user is not authorized"); 301 } 302 } 303 304 /** 305 * Check the requested flags, throwing if any requested flags are outside 306 * the allowed set. 307 * 308 * @return the validated requested flags. 309 */ checkFlagsArgument(final int requestedFlags, final int allowedFlags)310 public static int checkFlagsArgument(final int requestedFlags, final int allowedFlags) { 311 if ((requestedFlags & allowedFlags) != requestedFlags) { 312 throw new IllegalArgumentException("Requested flags 0x" 313 + Integer.toHexString(requestedFlags) + ", but only 0x" 314 + Integer.toHexString(allowedFlags) + " are allowed"); 315 } 316 317 return requestedFlags; 318 } 319 320 /** 321 * Ensures that that the argument numeric value is non-negative (greater than or equal to 0). 322 * 323 * @param value a numeric int value 324 * @param errorMessage the exception message to use if the check fails 325 * @return the validated numeric value 326 * @throws IllegalArgumentException if {@code value} was negative 327 */ checkArgumentNonnegative(final int value, final String errorMessage)328 public static @IntRange(from = 0) int checkArgumentNonnegative(final int value, 329 final String errorMessage) { 330 if (value < 0) { 331 throw new IllegalArgumentException(errorMessage); 332 } 333 334 return value; 335 } 336 337 /** 338 * Ensures that that the argument numeric value is non-negative (greater than or equal to 0). 339 * 340 * @param value a numeric int value 341 * 342 * @return the validated numeric value 343 * @throws IllegalArgumentException if {@code value} was negative 344 */ checkArgumentNonnegative(final int value)345 public static @IntRange(from = 0) int checkArgumentNonnegative(final int value) { 346 if (value < 0) { 347 throw new IllegalArgumentException(); 348 } 349 350 return value; 351 } 352 353 /** 354 * Ensures that that the argument numeric value is non-negative (greater than or equal to 0). 355 * 356 * @param value a numeric long value 357 * @return the validated numeric value 358 * @throws IllegalArgumentException if {@code value} was negative 359 */ checkArgumentNonnegative(final long value)360 public static long checkArgumentNonnegative(final long value) { 361 if (value < 0) { 362 throw new IllegalArgumentException(); 363 } 364 365 return value; 366 } 367 368 /** 369 * Ensures that that the argument numeric value is non-negative (greater than or equal to 0). 370 * 371 * @param value a numeric long value 372 * @param errorMessage the exception message to use if the check fails 373 * @return the validated numeric value 374 * @throws IllegalArgumentException if {@code value} was negative 375 */ checkArgumentNonnegative(final long value, final String errorMessage)376 public static long checkArgumentNonnegative(final long value, final String errorMessage) { 377 if (value < 0) { 378 throw new IllegalArgumentException(errorMessage); 379 } 380 381 return value; 382 } 383 384 /** 385 * Ensures that that the argument numeric value is positive (greater than 0). 386 * 387 * @param value a numeric int value 388 * @param errorMessage the exception message to use if the check fails 389 * @return the validated numeric value 390 * @throws IllegalArgumentException if {@code value} was not positive 391 */ checkArgumentPositive(final int value, final String errorMessage)392 public static int checkArgumentPositive(final int value, final String errorMessage) { 393 if (value <= 0) { 394 throw new IllegalArgumentException(errorMessage); 395 } 396 397 return value; 398 } 399 400 /** 401 * Ensures that the argument floating point value is non-negative (greater than or equal to 0). 402 * @param value a floating point value 403 * @param errorMessage the exteption message to use if the check fails 404 * @return the validated numeric value 405 * @throws IllegalArgumentException if {@code value} was negative 406 */ checkArgumentNonNegative(final float value, final String errorMessage)407 public static float checkArgumentNonNegative(final float value, final String errorMessage) { 408 if (value < 0) { 409 throw new IllegalArgumentException(errorMessage); 410 } 411 412 return value; 413 } 414 415 /** 416 * Ensures that the argument floating point value is positive (greater than 0). 417 * @param value a floating point value 418 * @param errorMessage the exteption message to use if the check fails 419 * @return the validated numeric value 420 * @throws IllegalArgumentException if {@code value} was not positive 421 */ checkArgumentPositive(final float value, final String errorMessage)422 public static float checkArgumentPositive(final float value, final String errorMessage) { 423 if (value <= 0) { 424 throw new IllegalArgumentException(errorMessage); 425 } 426 427 return value; 428 } 429 430 /** 431 * Ensures that the argument floating point value is a finite number. 432 * 433 * <p>A finite number is defined to be both representable (that is, not NaN) and 434 * not infinite (that is neither positive or negative infinity).</p> 435 * 436 * @param value a floating point value 437 * @param valueName the name of the argument to use if the check fails 438 * 439 * @return the validated floating point value 440 * 441 * @throws IllegalArgumentException if {@code value} was not finite 442 */ checkArgumentFinite(final float value, final String valueName)443 public static float checkArgumentFinite(final float value, final String valueName) { 444 if (Float.isNaN(value)) { 445 throw new IllegalArgumentException(valueName + " must not be NaN"); 446 } else if (Float.isInfinite(value)) { 447 throw new IllegalArgumentException(valueName + " must not be infinite"); 448 } 449 450 return value; 451 } 452 453 /** 454 * Ensures that the argument floating point value is within the inclusive range. 455 * 456 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers 457 * will always be out of range.</p> 458 * 459 * @param value a floating point value 460 * @param lower the lower endpoint of the inclusive range 461 * @param upper the upper endpoint of the inclusive range 462 * @param valueName the name of the argument to use if the check fails 463 * 464 * @return the validated floating point value 465 * 466 * @throws IllegalArgumentException if {@code value} was not within the range 467 */ checkArgumentInRange(float value, float lower, float upper, String valueName)468 public static float checkArgumentInRange(float value, float lower, float upper, 469 String valueName) { 470 if (Float.isNaN(value)) { 471 throw new IllegalArgumentException(valueName + " must not be NaN"); 472 } else if (value < lower) { 473 throw new IllegalArgumentException( 474 String.format( 475 "%s is out of range of [%f, %f] (too low)", valueName, lower, upper)); 476 } else if (value > upper) { 477 throw new IllegalArgumentException( 478 String.format( 479 "%s is out of range of [%f, %f] (too high)", valueName, lower, upper)); 480 } 481 482 return value; 483 } 484 485 /** 486 * Ensures that the argument floating point value is within the inclusive range. 487 * 488 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers 489 * will always be out of range.</p> 490 * 491 * @param value a floating point value 492 * @param lower the lower endpoint of the inclusive range 493 * @param upper the upper endpoint of the inclusive range 494 * @param valueName the name of the argument to use if the check fails 495 * 496 * @return the validated floating point value 497 * 498 * @throws IllegalArgumentException if {@code value} was not within the range 499 */ checkArgumentInRange(double value, double lower, double upper, String valueName)500 public static double checkArgumentInRange(double value, double lower, double upper, 501 String valueName) { 502 if (Double.isNaN(value)) { 503 throw new IllegalArgumentException(valueName + " must not be NaN"); 504 } else if (value < lower) { 505 throw new IllegalArgumentException( 506 String.format( 507 "%s is out of range of [%f, %f] (too low)", valueName, lower, upper)); 508 } else if (value > upper) { 509 throw new IllegalArgumentException( 510 String.format( 511 "%s is out of range of [%f, %f] (too high)", valueName, lower, upper)); 512 } 513 514 return value; 515 } 516 517 /** 518 * Ensures that the argument int value is within the inclusive range. 519 * 520 * @param value a int value 521 * @param lower the lower endpoint of the inclusive range 522 * @param upper the upper endpoint of the inclusive range 523 * @param valueName the name of the argument to use if the check fails 524 * 525 * @return the validated int value 526 * 527 * @throws IllegalArgumentException if {@code value} was not within the range 528 */ 529 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) checkArgumentInRange(int value, int lower, int upper, String valueName)530 public static int checkArgumentInRange(int value, int lower, int upper, 531 String valueName) { 532 if (value < lower) { 533 throw new IllegalArgumentException( 534 String.format( 535 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper)); 536 } else if (value > upper) { 537 throw new IllegalArgumentException( 538 String.format( 539 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper)); 540 } 541 542 return value; 543 } 544 545 /** 546 * Ensures that the argument long value is within the inclusive range. 547 * 548 * @param value a long value 549 * @param lower the lower endpoint of the inclusive range 550 * @param upper the upper endpoint of the inclusive range 551 * @param valueName the name of the argument to use if the check fails 552 * 553 * @return the validated long value 554 * 555 * @throws IllegalArgumentException if {@code value} was not within the range 556 */ checkArgumentInRange(long value, long lower, long upper, String valueName)557 public static long checkArgumentInRange(long value, long lower, long upper, 558 String valueName) { 559 if (value < lower) { 560 throw new IllegalArgumentException( 561 String.format( 562 "%s is out of range of [%d, %d] (too low)", valueName, lower, upper)); 563 } else if (value > upper) { 564 throw new IllegalArgumentException( 565 String.format( 566 "%s is out of range of [%d, %d] (too high)", valueName, lower, upper)); 567 } 568 569 return value; 570 } 571 572 /** 573 * Ensures that the array is not {@code null}, and none of its elements are {@code null}. 574 * 575 * @param value an array of boxed objects 576 * @param valueName the name of the argument to use if the check fails 577 * 578 * @return the validated array 579 * 580 * @throws NullPointerException if the {@code value} or any of its elements were {@code null} 581 */ checkArrayElementsNotNull(final T[] value, final String valueName)582 public static <T> T[] checkArrayElementsNotNull(final T[] value, final String valueName) { 583 if (value == null) { 584 throw new NullPointerException(valueName + " must not be null"); 585 } 586 587 for (int i = 0; i < value.length; ++i) { 588 if (value[i] == null) { 589 throw new NullPointerException( 590 String.format("%s[%d] must not be null", valueName, i)); 591 } 592 } 593 594 return value; 595 } 596 597 /** 598 * Ensures that the {@link Collection} is not {@code null}, and none of its elements are 599 * {@code null}. 600 * 601 * @param value a {@link Collection} of boxed objects 602 * @param valueName the name of the argument to use if the check fails 603 * 604 * @return the validated {@link Collection} 605 * 606 * @throws NullPointerException if the {@code value} or any of its elements were {@code null} 607 */ checkCollectionElementsNotNull( final C value, final String valueName)608 public static @NonNull <C extends Collection<T>, T> C checkCollectionElementsNotNull( 609 final C value, final String valueName) { 610 if (value == null) { 611 throw new NullPointerException(valueName + " must not be null"); 612 } 613 614 long ctr = 0; 615 for (T elem : value) { 616 if (elem == null) { 617 throw new NullPointerException( 618 String.format("%s[%d] must not be null", valueName, ctr)); 619 } 620 ++ctr; 621 } 622 623 return value; 624 } 625 626 /** 627 * Ensures that the {@link Collection} is not {@code null}, and contains at least one element. 628 * 629 * @param value a {@link Collection} of boxed elements. 630 * @param valueName the name of the argument to use if the check fails. 631 632 * @return the validated {@link Collection} 633 * 634 * @throws NullPointerException if the {@code value} was {@code null} 635 * @throws IllegalArgumentException if the {@code value} was empty 636 */ checkCollectionNotEmpty(final Collection<T> value, final String valueName)637 public static <T> Collection<T> checkCollectionNotEmpty(final Collection<T> value, 638 final String valueName) { 639 if (value == null) { 640 throw new NullPointerException(valueName + " must not be null"); 641 } 642 if (value.isEmpty()) { 643 throw new IllegalArgumentException(valueName + " is empty"); 644 } 645 return value; 646 } 647 648 /** 649 * Ensures that the given byte array is not {@code null}, and contains at least one element. 650 * 651 * @param value an array of elements. 652 * @param valueName the name of the argument to use if the check fails. 653 654 * @return the validated array 655 * 656 * @throws NullPointerException if the {@code value} was {@code null} 657 * @throws IllegalArgumentException if the {@code value} was empty 658 */ 659 @NonNull checkByteArrayNotEmpty(final byte[] value, final String valueName)660 public static byte[] checkByteArrayNotEmpty(final byte[] value, final String valueName) { 661 if (value == null) { 662 throw new NullPointerException(valueName + " must not be null"); 663 } 664 if (value.length == 0) { 665 throw new IllegalArgumentException(valueName + " is empty"); 666 } 667 return value; 668 } 669 670 /** 671 * Ensures that argument {@code value} is one of {@code supportedValues}. 672 * 673 * @param supportedValues an array of string values 674 * @param value a string value 675 * 676 * @return the validated value 677 * 678 * @throws NullPointerException if either {@code value} or {@code supportedValues} is null 679 * @throws IllegalArgumentException if the {@code value} is not in {@code supportedValues} 680 */ 681 @NonNull checkArgumentIsSupported(final String[] supportedValues, final String value)682 public static String checkArgumentIsSupported(final String[] supportedValues, 683 final String value) { 684 checkNotNull(value); 685 checkNotNull(supportedValues); 686 687 if (!contains(supportedValues, value)) { 688 throw new IllegalArgumentException(value + "is not supported " 689 + Arrays.toString(supportedValues)); 690 } 691 return value; 692 } 693 contains(String[] values, String value)694 private static boolean contains(String[] values, String value) { 695 if (values == null) { 696 return false; 697 } 698 for (int i = 0; i < values.length; ++i) { 699 if (Objects.equals(value, values[i])) { 700 return true; 701 } 702 } 703 return false; 704 } 705 706 /** 707 * Ensures that all elements in the argument floating point array are within the inclusive range 708 * 709 * <p>While this can be used to range check against +/- infinity, note that all NaN numbers 710 * will always be out of range.</p> 711 * 712 * @param value a floating point array of values 713 * @param lower the lower endpoint of the inclusive range 714 * @param upper the upper endpoint of the inclusive range 715 * @param valueName the name of the argument to use if the check fails 716 * 717 * @return the validated floating point value 718 * 719 * @throws IllegalArgumentException if any of the elements in {@code value} were out of range 720 * @throws NullPointerException if the {@code value} was {@code null} 721 */ checkArrayElementsInRange(float[] value, float lower, float upper, String valueName)722 public static float[] checkArrayElementsInRange(float[] value, float lower, float upper, 723 String valueName) { 724 checkNotNull(value, "%s must not be null", valueName); 725 726 for (int i = 0; i < value.length; ++i) { 727 float v = value[i]; 728 729 if (Float.isNaN(v)) { 730 throw new IllegalArgumentException(valueName + "[" + i + "] must not be NaN"); 731 } else if (v < lower) { 732 throw new IllegalArgumentException( 733 String.format("%s[%d] is out of range of [%f, %f] (too low)", 734 valueName, i, lower, upper)); 735 } else if (v > upper) { 736 throw new IllegalArgumentException( 737 String.format("%s[%d] is out of range of [%f, %f] (too high)", 738 valueName, i, lower, upper)); 739 } 740 } 741 742 return value; 743 } 744 745 /** 746 * Ensures that all elements in the argument integer array are within the inclusive range 747 * 748 * @param value an integer array of values 749 * @param lower the lower endpoint of the inclusive range 750 * @param upper the upper endpoint of the inclusive range 751 * @param valueName the name of the argument to use if the check fails 752 * 753 * @return the validated integer array 754 * 755 * @throws IllegalArgumentException if any of the elements in {@code value} were out of range 756 * @throws NullPointerException if the {@code value} was {@code null} 757 */ checkArrayElementsInRange(int[] value, int lower, int upper, String valueName)758 public static int[] checkArrayElementsInRange(int[] value, int lower, int upper, 759 String valueName) { 760 checkNotNull(value, "%s must not be null", valueName); 761 762 for (int i = 0; i < value.length; ++i) { 763 int v = value[i]; 764 765 if (v < lower) { 766 throw new IllegalArgumentException( 767 String.format("%s[%d] is out of range of [%d, %d] (too low)", 768 valueName, i, lower, upper)); 769 } else if (v > upper) { 770 throw new IllegalArgumentException( 771 String.format("%s[%d] is out of range of [%d, %d] (too high)", 772 valueName, i, lower, upper)); 773 } 774 } 775 776 return value; 777 } 778 779 /** 780 * Throws an exception that guides developers to configure a {@code RavenwoodRule} when the 781 * given argument is {@code null}. 782 */ requireNonNullViaRavenwoodRule(@ullable T t)783 public static <T> @NonNull T requireNonNullViaRavenwoodRule(@Nullable T t) { 784 if (t == null) { 785 throw new IllegalStateException("This operation requires that a RavenwoodRule be " 786 + "configured to accurately define the expected test environment"); 787 } else { 788 return t; 789 } 790 } 791 } 792