001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3; 018 019import java.util.Collection; 020import java.util.Map; 021import java.util.Objects; 022import java.util.concurrent.atomic.AtomicInteger; 023import java.util.function.Supplier; 024import java.util.regex.Pattern; 025 026/** 027 * This class assists in validating arguments. The validation methods are 028 * based along the following principles: 029 * <ul> 030 * <li>An invalid {@code null} argument causes a {@link NullPointerException}.</li> 031 * <li>A non-{@code null} argument causes an {@link IllegalArgumentException}.</li> 032 * <li>An invalid index into an array/collection/map/string causes an {@link IndexOutOfBoundsException}.</li> 033 * </ul> 034 * 035 * <p>All exceptions messages are 036 * <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax">format strings</a> 037 * as defined by the Java platform. For example: 038 * 039 * <pre> 040 * Validate.isTrue(i > 0, "The value must be greater than zero: %d", i); 041 * Validate.notNull(surname, "The surname must not be %s", null); 042 * </pre> 043 * 044 * <p>#ThreadSafe#</p> 045 * @see String#format(String, Object...) 046 * @since 2.0 047 */ 048public class Validate { 049 050 private static final String DEFAULT_NOT_NAN_EX_MESSAGE = 051 "The validated value is not a number"; 052 private static final String DEFAULT_FINITE_EX_MESSAGE = 053 "The value is invalid: %f"; 054 private static final String DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE = 055 "The value %s is not in the specified exclusive range of %s to %s"; 056 private static final String DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE = 057 "The value %s is not in the specified inclusive range of %s to %s"; 058 private static final String DEFAULT_MATCHES_PATTERN_EX = "The string %s does not match the pattern %s"; 059 private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null"; 060 private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false"; 061 private static final String DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE = 062 "The validated array contains null element at index: %d"; 063 private static final String DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE = 064 "The validated collection contains null element at index: %d"; 065 private static final String DEFAULT_NOT_BLANK_EX_MESSAGE = "The validated character sequence is blank"; 066 private static final String DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE = "The validated array is empty"; 067 private static final String DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE = 068 "The validated character sequence is empty"; 069 private static final String DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE = "The validated collection is empty"; 070 private static final String DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE = "The validated map is empty"; 071 private static final String DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE = "The validated array index is invalid: %d"; 072 private static final String DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE = 073 "The validated character sequence index is invalid: %d"; 074 private static final String DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE = 075 "The validated collection index is invalid: %d"; 076 private static final String DEFAULT_VALID_STATE_EX_MESSAGE = "The validated state is false"; 077 private static final String DEFAULT_IS_ASSIGNABLE_EX_MESSAGE = "Cannot assign a %s to a %s"; 078 private static final String DEFAULT_IS_INSTANCE_OF_EX_MESSAGE = "Expected type: %s, actual: %s"; 079 080 /** 081 * Validate that the specified primitive value falls between the two 082 * exclusive values specified; otherwise, throws an exception. 083 * 084 * <pre>Validate.exclusiveBetween(0.1, 2.1, 1.1);</pre> 085 * 086 * @param start the exclusive start value 087 * @param end the exclusive end value 088 * @param value the value to validate 089 * @throws IllegalArgumentException if the value falls out of the boundaries 090 * @since 3.3 091 */ 092 @SuppressWarnings("boxing") 093 public static void exclusiveBetween(final double start, final double end, final double value) { 094 // TODO when breaking BC, consider returning value 095 if (value <= start || value >= end) { 096 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 097 } 098 } 099 100 /** 101 * Validate that the specified primitive value falls between the two 102 * exclusive values specified; otherwise, throws an exception with the 103 * specified message. 104 * 105 * <pre>Validate.exclusiveBetween(0.1, 2.1, 1.1, "Not in range");</pre> 106 * 107 * @param start the exclusive start value 108 * @param end the exclusive end value 109 * @param value the value to validate 110 * @param message the exception message if invalid, not null 111 * @throws IllegalArgumentException if the value falls outside the boundaries 112 * @since 3.3 113 */ 114 public static void exclusiveBetween(final double start, final double end, final double value, final String message) { 115 // TODO when breaking BC, consider returning value 116 if (value <= start || value >= end) { 117 throw new IllegalArgumentException(message); 118 } 119 } 120 121 /** 122 * Validate that the specified primitive value falls between the two 123 * exclusive values specified; otherwise, throws an exception. 124 * 125 * <pre>Validate.exclusiveBetween(0, 2, 1);</pre> 126 * 127 * @param start the exclusive start value 128 * @param end the exclusive end value 129 * @param value the value to validate 130 * @throws IllegalArgumentException if the value falls out of the boundaries 131 * @since 3.3 132 */ 133 @SuppressWarnings("boxing") 134 public static void exclusiveBetween(final long start, final long end, final long value) { 135 // TODO when breaking BC, consider returning value 136 if (value <= start || value >= end) { 137 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 138 } 139 } 140 141 /** 142 * Validate that the specified primitive value falls between the two 143 * exclusive values specified; otherwise, throws an exception with the 144 * specified message. 145 * 146 * <pre>Validate.exclusiveBetween(0, 2, 1, "Not in range");</pre> 147 * 148 * @param start the exclusive start value 149 * @param end the exclusive end value 150 * @param value the value to validate 151 * @param message the exception message if invalid, not null 152 * @throws IllegalArgumentException if the value falls outside the boundaries 153 * @since 3.3 154 */ 155 public static void exclusiveBetween(final long start, final long end, final long value, final String message) { 156 // TODO when breaking BC, consider returning value 157 if (value <= start || value >= end) { 158 throw new IllegalArgumentException(message); 159 } 160 } 161 162 /** 163 * Validate that the specified argument object fall between the two 164 * exclusive values specified; otherwise, throws an exception. 165 * 166 * <pre>Validate.exclusiveBetween(0, 2, 1);</pre> 167 * 168 * @param <T> the type of the argument object 169 * @param start the exclusive start value, not null 170 * @param end the exclusive end value, not null 171 * @param value the object to validate, not null 172 * @throws IllegalArgumentException if the value falls outside the boundaries 173 * @see #exclusiveBetween(Object, Object, Comparable, String, Object...) 174 * @since 3.0 175 */ 176 public static <T> void exclusiveBetween(final T start, final T end, final Comparable<T> value) { 177 // TODO when breaking BC, consider returning value 178 if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) { 179 throw new IllegalArgumentException(String.format(DEFAULT_EXCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 180 } 181 } 182 183 /** 184 * Validate that the specified argument object fall between the two 185 * exclusive values specified; otherwise, throws an exception with the 186 * specified message. 187 * 188 * <pre>Validate.exclusiveBetween(0, 2, 1, "Not in boundaries");</pre> 189 * 190 * @param <T> the type of the argument object 191 * @param start the exclusive start value, not null 192 * @param end the exclusive end value, not null 193 * @param value the object to validate, not null 194 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 195 * @param values the optional values for the formatted exception message, null array not recommended 196 * @throws IllegalArgumentException if the value falls outside the boundaries 197 * @see #exclusiveBetween(Object, Object, Comparable) 198 * @since 3.0 199 */ 200 public static <T> void exclusiveBetween(final T start, final T end, final Comparable<T> value, final String message, final Object... values) { 201 // TODO when breaking BC, consider returning value 202 if (value.compareTo(start) <= 0 || value.compareTo(end) >= 0) { 203 throw new IllegalArgumentException(getMessage(message, values)); 204 } 205 } 206 207 /** 208 * Validates that the specified argument is not infinite or Not-a-Number (NaN); 209 * otherwise throwing an exception. 210 * 211 * <pre>Validate.finite(myDouble);</pre> 212 * 213 * <p>The message of the exception is "The value is invalid: %f".</p> 214 * 215 * @param value the value to validate 216 * @throws IllegalArgumentException if the value is infinite or Not-a-Number (NaN) 217 * @see #finite(double, String, Object...) 218 * @since 3.5 219 */ 220 public static void finite(final double value) { 221 finite(value, DEFAULT_FINITE_EX_MESSAGE, value); 222 } 223 224 /** 225 * Validates that the specified argument is not infinite or Not-a-Number (NaN); 226 * otherwise throwing an exception with the specified message. 227 * 228 * <pre>Validate.finite(myDouble, "The argument must contain a numeric value");</pre> 229 * 230 * @param value the value to validate 231 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 232 * @param values the optional values for the formatted exception message 233 * @throws IllegalArgumentException if the value is infinite or Not-a-Number (NaN) 234 * @see #finite(double) 235 * @since 3.5 236 */ 237 public static void finite(final double value, final String message, final Object... values) { 238 if (Double.isNaN(value) || Double.isInfinite(value)) { 239 throw new IllegalArgumentException(getMessage(message, values)); 240 } 241 } 242 243 /** 244 * Gets the message using {@link String#format(String, Object...) String.format(message, values)} 245 * if the values are not empty, otherwise return the message unformatted. 246 * This method exists to allow validation methods declaring a String message and varargs parameters 247 * to be used without any message parameters when the message contains special characters, 248 * e.g. {@code Validate.isTrue(false, "%Failed%")}. 249 * 250 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 251 * @param values the optional values for the formatted message 252 * @return formatted message using {@link String#format(String, Object...) String.format(message, values)} 253 * if the values are not empty, otherwise return the unformatted message. 254 */ 255 private static String getMessage(final String message, final Object... values) { 256 return ArrayUtils.isEmpty(values) ? message : String.format(message, values); 257 } 258 259 /** 260 * Validate that the specified primitive value falls between the two 261 * inclusive values specified; otherwise, throws an exception. 262 * 263 * <pre>Validate.inclusiveBetween(0.1, 2.1, 1.1);</pre> 264 * 265 * @param start the inclusive start value 266 * @param end the inclusive end value 267 * @param value the value to validate 268 * @throws IllegalArgumentException if the value falls outside the boundaries (inclusive) 269 * @since 3.3 270 */ 271 @SuppressWarnings("boxing") 272 public static void inclusiveBetween(final double start, final double end, final double value) { 273 // TODO when breaking BC, consider returning value 274 if (value < start || value > end) { 275 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 276 } 277 } 278 279 /** 280 * Validate that the specified primitive value falls between the two 281 * inclusive values specified; otherwise, throws an exception with the 282 * specified message. 283 * 284 * <pre>Validate.inclusiveBetween(0.1, 2.1, 1.1, "Not in range");</pre> 285 * 286 * @param start the inclusive start value 287 * @param end the inclusive end value 288 * @param value the value to validate 289 * @param message the exception message if invalid, not null 290 * @throws IllegalArgumentException if the value falls outside the boundaries 291 * @since 3.3 292 */ 293 public static void inclusiveBetween(final double start, final double end, final double value, final String message) { 294 // TODO when breaking BC, consider returning value 295 if (value < start || value > end) { 296 throw new IllegalArgumentException(message); 297 } 298 } 299 300 /** 301 * Validate that the specified primitive value falls between the two 302 * inclusive values specified; otherwise, throws an exception. 303 * 304 * <pre>Validate.inclusiveBetween(0, 2, 1);</pre> 305 * 306 * @param start the inclusive start value 307 * @param end the inclusive end value 308 * @param value the value to validate 309 * @throws IllegalArgumentException if the value falls outside the boundaries (inclusive) 310 * @since 3.3 311 */ 312 @SuppressWarnings("boxing") 313 public static void inclusiveBetween(final long start, final long end, final long value) { 314 // TODO when breaking BC, consider returning value 315 if (value < start || value > end) { 316 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 317 } 318 } 319 320 /** 321 * Validate that the specified primitive value falls between the two 322 * inclusive values specified; otherwise, throws an exception with the 323 * specified message. 324 * 325 * <pre>Validate.inclusiveBetween(0, 2, 1, "Not in range");</pre> 326 * 327 * @param start the inclusive start value 328 * @param end the inclusive end value 329 * @param value the value to validate 330 * @param message the exception message if invalid, not null 331 * @throws IllegalArgumentException if the value falls outside the boundaries 332 * @since 3.3 333 */ 334 public static void inclusiveBetween(final long start, final long end, final long value, final String message) { 335 // TODO when breaking BC, consider returning value 336 if (value < start || value > end) { 337 throw new IllegalArgumentException(message); 338 } 339 } 340 341 /** 342 * Validate that the specified argument object fall between the two 343 * inclusive values specified; otherwise, throws an exception. 344 * 345 * <pre>Validate.inclusiveBetween(0, 2, 1);</pre> 346 * 347 * @param <T> the type of the argument object 348 * @param start the inclusive start value, not null 349 * @param end the inclusive end value, not null 350 * @param value the object to validate, not null 351 * @throws IllegalArgumentException if the value falls outside the boundaries 352 * @see #inclusiveBetween(Object, Object, Comparable, String, Object...) 353 * @since 3.0 354 */ 355 public static <T> void inclusiveBetween(final T start, final T end, final Comparable<T> value) { 356 // TODO when breaking BC, consider returning value 357 if (value.compareTo(start) < 0 || value.compareTo(end) > 0) { 358 throw new IllegalArgumentException(String.format(DEFAULT_INCLUSIVE_BETWEEN_EX_MESSAGE, value, start, end)); 359 } 360 } 361 362 /** 363 * Validate that the specified argument object fall between the two 364 * inclusive values specified; otherwise, throws an exception with the 365 * specified message. 366 * 367 * <pre>Validate.inclusiveBetween(0, 2, 1, "Not in boundaries");</pre> 368 * 369 * @param <T> the type of the argument object 370 * @param start the inclusive start value, not null 371 * @param end the inclusive end value, not null 372 * @param value the object to validate, not null 373 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 374 * @param values the optional values for the formatted exception message, null array not recommended 375 * @throws IllegalArgumentException if the value falls outside the boundaries 376 * @see #inclusiveBetween(Object, Object, Comparable) 377 * @since 3.0 378 */ 379 public static <T> void inclusiveBetween(final T start, final T end, final Comparable<T> value, final String message, final Object... values) { 380 // TODO when breaking BC, consider returning value 381 if (value.compareTo(start) < 0 || value.compareTo(end) > 0) { 382 throw new IllegalArgumentException(getMessage(message, values)); 383 } 384 } 385 386 /** 387 * Validates that the argument can be converted to the specified class, if not, throws an exception. 388 * 389 * <p>This method is useful when validating that there will be no casting errors.</p> 390 * 391 * <pre>Validate.isAssignableFrom(SuperClass.class, object.getClass());</pre> 392 * 393 * <p>The message format of the exception is "Cannot assign {type} to {superType}"</p> 394 * 395 * @param superType the class must be validated against, not null 396 * @param type the class to check, not null 397 * @throws IllegalArgumentException if type argument is not assignable to the specified superType 398 * @see #isAssignableFrom(Class, Class, String, Object...) 399 * @since 3.0 400 */ 401 public static void isAssignableFrom(final Class<?> superType, final Class<?> type) { 402 // TODO when breaking BC, consider returning type 403 if (type == null || superType == null || !superType.isAssignableFrom(type)) { 404 throw new IllegalArgumentException( 405 String.format(DEFAULT_IS_ASSIGNABLE_EX_MESSAGE, ClassUtils.getName(type, "null type"), ClassUtils.getName(superType, "null type"))); 406 } 407 } 408 409 /** 410 * Validates that the argument can be converted to the specified class, if not throws an exception. 411 * 412 * <p>This method is useful when validating if there will be no casting errors.</p> 413 * 414 * <pre>Validate.isAssignableFrom(SuperClass.class, object.getClass());</pre> 415 * 416 * <p>The message of the exception is "The validated object cannot be converted to the" 417 * followed by the name of the class and "class"</p> 418 * 419 * @param superType the class must be validated against, not null 420 * @param type the class to check, not null 421 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 422 * @param values the optional values for the formatted exception message, null array not recommended 423 * @throws IllegalArgumentException if argument cannot be converted to the specified class 424 * @see #isAssignableFrom(Class, Class) 425 */ 426 public static void isAssignableFrom(final Class<?> superType, final Class<?> type, final String message, final Object... values) { 427 // TODO when breaking BC, consider returning type 428 if (!superType.isAssignableFrom(type)) { 429 throw new IllegalArgumentException(getMessage(message, values)); 430 } 431 } 432 433 /** 434 * Validates that the argument is an instance of the specified class, if not throws an exception. 435 * 436 * <p>This method is useful when validating according to an arbitrary class</p> 437 * 438 * <pre>Validate.isInstanceOf(OkClass.class, object);</pre> 439 * 440 * <p>The message of the exception is "Expected type: {type}, actual: {obj_type}"</p> 441 * 442 * @param type the class the object must be validated against, not null 443 * @param obj the object to check, null throws an exception 444 * @throws IllegalArgumentException if argument is not of specified class 445 * @see #isInstanceOf(Class, Object, String, Object...) 446 * @since 3.0 447 */ 448 public static void isInstanceOf(final Class<?> type, final Object obj) { 449 // TODO when breaking BC, consider returning obj 450 if (!type.isInstance(obj)) { 451 throw new IllegalArgumentException(String.format(DEFAULT_IS_INSTANCE_OF_EX_MESSAGE, type.getName(), ClassUtils.getName(obj, "null"))); 452 } 453 } 454 455 /** 456 * Validate that the argument is an instance of the specified class; otherwise 457 * throwing an exception with the specified message. This method is useful when 458 * validating according to an arbitrary class 459 * 460 * <pre>Validate.isInstanceOf(OkClass.class, object, "Wrong class, object is of class %s", 461 * object.getClass().getName());</pre> 462 * 463 * @param type the class the object must be validated against, not null 464 * @param obj the object to check, null throws an exception 465 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 466 * @param values the optional values for the formatted exception message, null array not recommended 467 * @throws IllegalArgumentException if argument is not of specified class 468 * @see #isInstanceOf(Class, Object) 469 * @since 3.0 470 */ 471 public static void isInstanceOf(final Class<?> type, final Object obj, final String message, final Object... values) { 472 // TODO when breaking BC, consider returning obj 473 if (!type.isInstance(obj)) { 474 throw new IllegalArgumentException(getMessage(message, values)); 475 } 476 } 477 478 /** 479 * Validate that the argument condition is {@code true}; otherwise 480 * throwing an exception. This method is useful when validating according 481 * to an arbitrary boolean expression, such as validating a 482 * primitive number or using your own custom validation expression. 483 * 484 * <pre> 485 * Validate.isTrue(i > 0); 486 * Validate.isTrue(myObject.isOk());</pre> 487 * 488 * <p>The message of the exception is "The validated expression is 489 * false".</p> 490 * 491 * @param expression the boolean expression to check 492 * @throws IllegalArgumentException if expression is {@code false} 493 * @see #isTrue(boolean, String, long) 494 * @see #isTrue(boolean, String, double) 495 * @see #isTrue(boolean, String, Object...) 496 * @see #isTrue(boolean, Supplier) 497 */ 498 public static void isTrue(final boolean expression) { 499 if (!expression) { 500 throw new IllegalArgumentException(DEFAULT_IS_TRUE_EX_MESSAGE); 501 } 502 } 503 504 /** 505 * Validate that the argument condition is {@code true}; otherwise 506 * throwing an exception with the specified message. This method is useful when 507 * validating according to an arbitrary boolean expression, such as validating a 508 * primitive number or using your own custom validation expression. 509 * 510 * <pre>Validate.isTrue(d > 0.0, "The value must be greater than zero: %s", d);</pre> 511 * 512 * <p>For performance reasons, the double value is passed as a separate parameter and 513 * appended to the exception message only in the case of an error.</p> 514 * 515 * @param expression the boolean expression to check 516 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 517 * @param value the value to append to the message when invalid 518 * @throws IllegalArgumentException if expression is {@code false} 519 * @see #isTrue(boolean) 520 * @see #isTrue(boolean, String, long) 521 * @see #isTrue(boolean, String, Object...) 522 * @see #isTrue(boolean, Supplier) 523 */ 524 public static void isTrue(final boolean expression, final String message, final double value) { 525 if (!expression) { 526 throw new IllegalArgumentException(String.format(message, Double.valueOf(value))); 527 } 528 } 529 530 /** 531 * Validate that the argument condition is {@code true}; otherwise 532 * throwing an exception with the specified message. This method is useful when 533 * validating according to an arbitrary boolean expression, such as validating a 534 * primitive number or using your own custom validation expression. 535 * 536 * <pre>Validate.isTrue(i > 0.0, "The value must be greater than zero: %d", i);</pre> 537 * 538 * <p>For performance reasons, the long value is passed as a separate parameter and 539 * appended to the exception message only in the case of an error.</p> 540 * 541 * @param expression the boolean expression to check 542 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 543 * @param value the value to append to the message when invalid 544 * @throws IllegalArgumentException if expression is {@code false} 545 * @see #isTrue(boolean) 546 * @see #isTrue(boolean, String, double) 547 * @see #isTrue(boolean, String, Object...) 548 * @see #isTrue(boolean, Supplier) 549 */ 550 public static void isTrue(final boolean expression, final String message, final long value) { 551 if (!expression) { 552 throw new IllegalArgumentException(String.format(message, Long.valueOf(value))); 553 } 554 } 555 556 /** 557 * Validate that the argument condition is {@code true}; otherwise 558 * throwing an exception with the specified message. This method is useful when 559 * validating according to an arbitrary boolean expression, such as validating a 560 * primitive number or using your own custom validation expression. 561 * 562 * <pre>{@code 563 * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);}</pre> 564 * 565 * @param expression the boolean expression to check 566 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 567 * @param values the optional values for the formatted exception message, null array not recommended 568 * @throws IllegalArgumentException if expression is {@code false} 569 * @see #isTrue(boolean) 570 * @see #isTrue(boolean, String, long) 571 * @see #isTrue(boolean, String, double) 572 * @see #isTrue(boolean, Supplier) 573 */ 574 public static void isTrue(final boolean expression, final String message, final Object... values) { 575 if (!expression) { 576 throw new IllegalArgumentException(getMessage(message, values)); 577 } 578 } 579 580 /** 581 * Validate that the argument condition is {@code true}; otherwise throwing an exception with the specified message. This method is useful when validating 582 * according to an arbitrary boolean expression, such as validating a primitive number or using your own custom validation expression. 583 * 584 * <pre>{@code 585 * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max); 586 * }</pre> 587 * 588 * @param expression the boolean expression to check 589 * @param messageSupplier the exception message supplier 590 * @throws IllegalArgumentException if expression is {@code false} 591 * @see #isTrue(boolean) 592 * @see #isTrue(boolean, String, long) 593 * @see #isTrue(boolean, String, double) 594 * @since 3.18.0 595 */ 596 public static void isTrue(final boolean expression, final Supplier<String> messageSupplier) { 597 if (!expression) { 598 throw new IllegalArgumentException(messageSupplier.get()); 599 } 600 } 601 602 /** 603 * Validate that the specified argument character sequence matches the specified regular 604 * expression pattern; otherwise throwing an exception. 605 * 606 * <pre>Validate.matchesPattern("hi", "[a-z]*");</pre> 607 * 608 * <p>The syntax of the pattern is the one used in the {@link Pattern} class.</p> 609 * 610 * @param input the character sequence to validate, not null 611 * @param pattern the regular expression pattern, not null 612 * @throws IllegalArgumentException if the character sequence does not match the pattern 613 * @see #matchesPattern(CharSequence, String, String, Object...) 614 * @since 3.0 615 */ 616 public static void matchesPattern(final CharSequence input, final String pattern) { 617 // TODO when breaking BC, consider returning input 618 if (!Pattern.matches(pattern, input)) { 619 throw new IllegalArgumentException(String.format(DEFAULT_MATCHES_PATTERN_EX, input, pattern)); 620 } 621 } 622 623 /** 624 * Validate that the specified argument character sequence matches the specified regular 625 * expression pattern; otherwise throwing an exception with the specified message. 626 * 627 * <pre>Validate.matchesPattern("hi", "[a-z]*", "%s does not match %s", "hi" "[a-z]*");</pre> 628 * 629 * <p>The syntax of the pattern is the one used in the {@link Pattern} class.</p> 630 * 631 * @param input the character sequence to validate, not null 632 * @param pattern the regular expression pattern, not null 633 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 634 * @param values the optional values for the formatted exception message, null array not recommended 635 * @throws IllegalArgumentException if the character sequence does not match the pattern 636 * @see #matchesPattern(CharSequence, String) 637 * @since 3.0 638 */ 639 public static void matchesPattern(final CharSequence input, final String pattern, final String message, final Object... values) { 640 // TODO when breaking BC, consider returning input 641 if (!Pattern.matches(pattern, input)) { 642 throw new IllegalArgumentException(getMessage(message, values)); 643 } 644 } 645 646 /** 647 * Validate that the specified argument iterable is neither 648 * {@code null} nor contains any elements that are {@code null}; 649 * otherwise throwing an exception. 650 * 651 * <pre>Validate.noNullElements(myCollection);</pre> 652 * 653 * <p>If the iterable is {@code null}, then the message in the exception 654 * is "The validated object is null". 655 * 656 * <p>If the array has a {@code null} element, then the message in the 657 * exception is "The validated iterable contains null element at index: 658 * " followed by the index.</p> 659 * 660 * @param <T> the iterable type 661 * @param iterable the iterable to check, validated not null by this method 662 * @return the validated iterable (never {@code null} method for chaining) 663 * @throws NullPointerException if the array is {@code null} 664 * @throws IllegalArgumentException if an element is {@code null} 665 * @see #noNullElements(Iterable, String, Object...) 666 */ 667 public static <T extends Iterable<?>> T noNullElements(final T iterable) { 668 return noNullElements(iterable, DEFAULT_NO_NULL_ELEMENTS_COLLECTION_EX_MESSAGE); 669 } 670 671 /** 672 * Validate that the specified argument iterable is neither 673 * {@code null} nor contains any elements that are {@code null}; 674 * otherwise throwing an exception with the specified message. 675 * 676 * <pre>Validate.noNullElements(myCollection, "The collection contains null at position %d");</pre> 677 * 678 * <p>If the iterable is {@code null}, then the message in the exception 679 * is "The validated object is null". 680 * 681 * <p>If the iterable has a {@code null} element, then the iteration 682 * index of the invalid element is appended to the {@code values} 683 * argument.</p> 684 * 685 * @param <T> the iterable type 686 * @param iterable the iterable to check, validated not null by this method 687 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 688 * @param values the optional values for the formatted exception message, null array not recommended 689 * @return the validated iterable (never {@code null} method for chaining) 690 * @throws NullPointerException if the array is {@code null} 691 * @throws IllegalArgumentException if an element is {@code null} 692 * @see #noNullElements(Iterable) 693 */ 694 public static <T extends Iterable<?>> T noNullElements(final T iterable, final String message, final Object... values) { 695 Objects.requireNonNull(iterable, "iterable"); 696 final AtomicInteger ai = new AtomicInteger(); 697 iterable.forEach(e -> { 698 if (e == null) { 699 throw new IllegalArgumentException(getMessage(message, ArrayUtils.addAll(values, ai.getAndIncrement()))); 700 } 701 }); 702 return iterable; 703 } 704 705 /** 706 * Validate that the specified argument array is neither 707 * {@code null} nor contains any elements that are {@code null}; 708 * otherwise throwing an exception. 709 * 710 * <pre>Validate.noNullElements(myArray);</pre> 711 * 712 * <p>If the array is {@code null}, then the message in the exception 713 * is "The validated object is null".</p> 714 * 715 * <p>If the array has a {@code null} element, then the message in the 716 * exception is "The validated array contains null element at index: 717 * " followed by the index.</p> 718 * 719 * @param <T> the array type 720 * @param array the array to check, validated not null by this method 721 * @return the validated array (never {@code null} method for chaining) 722 * @throws NullPointerException if the array is {@code null} 723 * @throws IllegalArgumentException if an element is {@code null} 724 * @see #noNullElements(Object[], String, Object...) 725 */ 726 public static <T> T[] noNullElements(final T[] array) { 727 return noNullElements(array, DEFAULT_NO_NULL_ELEMENTS_ARRAY_EX_MESSAGE); 728 } 729 730 /** 731 * Validate that the specified argument array is neither 732 * {@code null} nor contains any elements that are {@code null}; 733 * otherwise throwing an exception with the specified message. 734 * 735 * <pre>Validate.noNullElements(myArray, "The array contain null at position %d");</pre> 736 * 737 * <p>If the array is {@code null}, then the message in the exception 738 * is "The validated object is null". 739 * 740 * <p>If the array has a {@code null} element, then the iteration 741 * index of the invalid element is appended to the {@code values} 742 * argument.</p> 743 * 744 * @param <T> the array type 745 * @param array the array to check, validated not null by this method 746 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 747 * @param values the optional values for the formatted exception message, null array not recommended 748 * @return the validated array (never {@code null} method for chaining) 749 * @throws NullPointerException if the array is {@code null} 750 * @throws IllegalArgumentException if an element is {@code null} 751 * @see #noNullElements(Object[]) 752 */ 753 public static <T> T[] noNullElements(final T[] array, final String message, final Object... values) { 754 Objects.requireNonNull(array, "array"); 755 for (int i = 0; i < array.length; i++) { 756 if (array[i] == null) { 757 final Object[] values2 = ArrayUtils.add(values, Integer.valueOf(i)); 758 throw new IllegalArgumentException(getMessage(message, values2)); 759 } 760 } 761 return array; 762 } 763 764 /** 765 * <p>Validates that the specified argument character sequence is 766 * neither {@code null}, a length of zero (no characters), empty 767 * nor whitespace; otherwise throwing an exception. 768 * 769 * <pre>Validate.notBlank(myString);</pre> 770 * 771 * <p>The message in the exception is "The validated character 772 * sequence is blank". 773 * 774 * @param <T> the character sequence type 775 * @param chars the character sequence to check, validated not null by this method 776 * @return the validated character sequence (never {@code null} method for chaining) 777 * @throws NullPointerException if the character sequence is {@code null} 778 * @throws IllegalArgumentException if the character sequence is blank 779 * @see #notBlank(CharSequence, String, Object...) 780 * @since 3.0 781 */ 782 public static <T extends CharSequence> T notBlank(final T chars) { 783 return notBlank(chars, DEFAULT_NOT_BLANK_EX_MESSAGE); 784 } 785 786 /** 787 * Validates that the specified argument character sequence is not {@link StringUtils#isBlank(CharSequence) blank} (whitespaces, empty ({@code ""}) or 788 * {@code null}); otherwise throwing an exception with the specified message. 789 * 790 * <pre> 791 * Validate.notBlank(myString, "The string must not be blank"); 792 * </pre> 793 * 794 * @param <T> the character sequence type 795 * @param chars the character sequence to check, validated not null by this method 796 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 797 * @param values the optional values for the formatted exception message, null array not recommended 798 * @return the validated character sequence (never {@code null} method for chaining) 799 * @throws NullPointerException if the character sequence is {@code null} 800 * @throws IllegalArgumentException if the character sequence is blank 801 * @see #notBlank(CharSequence) 802 * @see StringUtils#isBlank(CharSequence) 803 * @since 3.0 804 */ 805 public static <T extends CharSequence> T notBlank(final T chars, final String message, final Object... values) { 806 Objects.requireNonNull(chars, toSupplier(message, values)); 807 if (StringUtils.isBlank(chars)) { 808 throw new IllegalArgumentException(getMessage(message, values)); 809 } 810 return chars; 811 } 812 813 /** 814 * <p>Validates that the specified argument collection is neither {@code null} 815 * nor a size of zero (no elements); otherwise throwing an exception. 816 * 817 * <pre>Validate.notEmpty(myCollection);</pre> 818 * 819 * <p>The message in the exception is "The validated collection is 820 * empty". 821 * 822 * @param <T> the collection type 823 * @param collection the collection to check, validated not null by this method 824 * @return the validated collection (never {@code null} method for chaining) 825 * @throws NullPointerException if the collection is {@code null} 826 * @throws IllegalArgumentException if the collection is empty 827 * @see #notEmpty(Collection, String, Object...) 828 */ 829 public static <T extends Collection<?>> T notEmpty(final T collection) { 830 return notEmpty(collection, DEFAULT_NOT_EMPTY_COLLECTION_EX_MESSAGE); 831 } 832 833 /** 834 * <p>Validates that the specified argument map is neither {@code null} 835 * nor a size of zero (no elements); otherwise throwing an exception. 836 * 837 * <pre>Validate.notEmpty(myMap);</pre> 838 * 839 * <p>The message in the exception is "The validated map is 840 * empty". 841 * 842 * @param <T> the map type 843 * @param map the map to check, validated not null by this method 844 * @return the validated map (never {@code null} method for chaining) 845 * @throws NullPointerException if the map is {@code null} 846 * @throws IllegalArgumentException if the map is empty 847 * @see #notEmpty(Map, String, Object...) 848 */ 849 public static <T extends Map<?, ?>> T notEmpty(final T map) { 850 return notEmpty(map, DEFAULT_NOT_EMPTY_MAP_EX_MESSAGE); 851 } 852 853 /** 854 * <p>Validates that the specified argument character sequence is 855 * neither {@code null} nor a length of zero (no characters); 856 * otherwise throwing an exception with the specified message. 857 * 858 * <pre>Validate.notEmpty(myString);</pre> 859 * 860 * <p>The message in the exception is "The validated 861 * character sequence is empty". 862 * 863 * @param <T> the character sequence type 864 * @param chars the character sequence to check, validated not null by this method 865 * @return the validated character sequence (never {@code null} method for chaining) 866 * @throws NullPointerException if the character sequence is {@code null} 867 * @throws IllegalArgumentException if the character sequence is empty 868 * @see #notEmpty(CharSequence, String, Object...) 869 */ 870 public static <T extends CharSequence> T notEmpty(final T chars) { 871 return notEmpty(chars, DEFAULT_NOT_EMPTY_CHAR_SEQUENCE_EX_MESSAGE); 872 } 873 874 /** 875 * <p>Validates that the specified argument collection is neither {@code null} 876 * nor a size of zero (no elements); otherwise throwing an exception 877 * with the specified message. 878 * 879 * <pre>Validate.notEmpty(myCollection, "The collection must not be empty");</pre> 880 * 881 * @param <T> the collection type 882 * @param collection the collection to check, validated not null by this method 883 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 884 * @param values the optional values for the formatted exception message, null array not recommended 885 * @return the validated collection (never {@code null} method for chaining) 886 * @throws NullPointerException if the collection is {@code null} 887 * @throws IllegalArgumentException if the collection is empty 888 * @see #notEmpty(Object[]) 889 */ 890 public static <T extends Collection<?>> T notEmpty(final T collection, final String message, final Object... values) { 891 Objects.requireNonNull(collection, toSupplier(message, values)); 892 if (collection.isEmpty()) { 893 throw new IllegalArgumentException(getMessage(message, values)); 894 } 895 return collection; 896 } 897 898 /** 899 * Validate that the specified argument map is neither {@code null} 900 * nor a size of zero (no elements); otherwise throwing an exception 901 * with the specified message. 902 * 903 * <pre>Validate.notEmpty(myMap, "The map must not be empty");</pre> 904 * 905 * @param <T> the map type 906 * @param map the map to check, validated not null by this method 907 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 908 * @param values the optional values for the formatted exception message, null array not recommended 909 * @return the validated map (never {@code null} method for chaining) 910 * @throws NullPointerException if the map is {@code null} 911 * @throws IllegalArgumentException if the map is empty 912 * @see #notEmpty(Object[]) 913 */ 914 public static <T extends Map<?, ?>> T notEmpty(final T map, final String message, final Object... values) { 915 Objects.requireNonNull(map, toSupplier(message, values)); 916 if (map.isEmpty()) { 917 throw new IllegalArgumentException(getMessage(message, values)); 918 } 919 return map; 920 } 921 922 /** 923 * Validate that the specified argument character sequence is 924 * neither {@code null} nor a length of zero (no characters); 925 * otherwise throwing an exception with the specified message. 926 * 927 * <pre>Validate.notEmpty(myString, "The string must not be empty");</pre> 928 * 929 * @param <T> the character sequence type 930 * @param chars the character sequence to check, validated not null by this method 931 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 932 * @param values the optional values for the formatted exception message, null array not recommended 933 * @return the validated character sequence (never {@code null} method for chaining) 934 * @throws NullPointerException if the character sequence is {@code null} 935 * @throws IllegalArgumentException if the character sequence is empty 936 * @see #notEmpty(CharSequence) 937 */ 938 public static <T extends CharSequence> T notEmpty(final T chars, final String message, final Object... values) { 939 Objects.requireNonNull(chars, toSupplier(message, values)); 940 if (chars.length() == 0) { 941 throw new IllegalArgumentException(getMessage(message, values)); 942 } 943 return chars; 944 } 945 946 /** 947 * <p>Validates that the specified argument array is neither {@code null} 948 * nor a length of zero (no elements); otherwise throwing an exception. 949 * 950 * <pre>Validate.notEmpty(myArray);</pre> 951 * 952 * <p>The message in the exception is "The validated array is 953 * empty". 954 * 955 * @param <T> the array type 956 * @param array the array to check, validated not null by this method 957 * @return the validated array (never {@code null} method for chaining) 958 * @throws NullPointerException if the array is {@code null} 959 * @throws IllegalArgumentException if the array is empty 960 * @see #notEmpty(Object[], String, Object...) 961 */ 962 public static <T> T[] notEmpty(final T[] array) { 963 return notEmpty(array, DEFAULT_NOT_EMPTY_ARRAY_EX_MESSAGE); 964 } 965 966 /** 967 * <p>Validates that the specified argument array is neither {@code null} 968 * nor a length of zero (no elements); otherwise throwing an exception 969 * with the specified message. 970 * 971 * <pre>Validate.notEmpty(myArray, "The array must not be empty");</pre> 972 * 973 * @param <T> the array type 974 * @param array the array to check, validated not null by this method 975 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 976 * @param values the optional values for the formatted exception message, null array not recommended 977 * @return the validated array (never {@code null} method for chaining) 978 * @throws NullPointerException if the array is {@code null} 979 * @throws IllegalArgumentException if the array is empty 980 * @see #notEmpty(Object[]) 981 */ 982 public static <T> T[] notEmpty(final T[] array, final String message, final Object... values) { 983 Objects.requireNonNull(array, toSupplier(message, values)); 984 if (array.length == 0) { 985 throw new IllegalArgumentException(getMessage(message, values)); 986 } 987 return array; 988 } 989 990 /** 991 * Validates that the specified argument is not Not-a-Number (NaN); otherwise 992 * throwing an exception. 993 * 994 * <pre>Validate.notNaN(myDouble);</pre> 995 * 996 * <p>The message of the exception is "The validated value is not a 997 * number".</p> 998 * 999 * @param value the value to validate 1000 * @throws IllegalArgumentException if the value is not a number 1001 * @see #notNaN(double, String, Object...) 1002 * @since 3.5 1003 */ 1004 public static void notNaN(final double value) { 1005 notNaN(value, DEFAULT_NOT_NAN_EX_MESSAGE); 1006 } 1007 1008 /** 1009 * Validates that the specified argument is not Not-a-Number (NaN); otherwise 1010 * throwing an exception with the specified message. 1011 * 1012 * <pre>Validate.notNaN(myDouble, "The value must be a number");</pre> 1013 * 1014 * @param value the value to validate 1015 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1016 * @param values the optional values for the formatted exception message 1017 * @throws IllegalArgumentException if the value is not a number 1018 * @see #notNaN(double) 1019 * @since 3.5 1020 */ 1021 public static void notNaN(final double value, final String message, final Object... values) { 1022 if (Double.isNaN(value)) { 1023 throw new IllegalArgumentException(getMessage(message, values)); 1024 } 1025 } 1026 1027 /** 1028 * Validate that the specified argument is not {@code null}; 1029 * otherwise throwing an exception. 1030 * 1031 * <pre>Validate.notNull(myObject, "The object must not be null");</pre> 1032 * 1033 * <p>The message of the exception is "The validated object is 1034 * null". 1035 * 1036 * @param <T> the object type 1037 * @param object the object to check 1038 * @return the validated object (never {@code null} for method chaining) 1039 * @throws NullPointerException if the object is {@code null} 1040 * @see #notNull(Object, String, Object...) 1041 * @deprecated Use {@link Objects#requireNonNull(Object)}. 1042 */ 1043 @Deprecated 1044 public static <T> T notNull(final T object) { 1045 return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE); 1046 } 1047 1048 /** 1049 * Validate that the specified argument is not {@code null}; 1050 * otherwise throwing an exception with the specified message. 1051 * 1052 * <pre>Validate.notNull(myObject, "The object must not be null");</pre> 1053 * 1054 * @param <T> the object type 1055 * @param object the object to check 1056 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1057 * @param values the optional values for the formatted exception message 1058 * @return the validated object (never {@code null} for method chaining) 1059 * @throws NullPointerException if the object is {@code null} 1060 * @see Objects#requireNonNull(Object) 1061 */ 1062 public static <T> T notNull(final T object, final String message, final Object... values) { 1063 return Objects.requireNonNull(object, toSupplier(message, values)); 1064 } 1065 1066 private static Supplier<String> toSupplier(final String message, final Object... values) { 1067 return () -> getMessage(message, values); 1068 } 1069 1070 /** 1071 * Validates that the index is within the bounds of the argument 1072 * collection; otherwise throwing an exception. 1073 * 1074 * <pre>Validate.validIndex(myCollection, 2);</pre> 1075 * 1076 * <p>If the index is invalid, then the message of the exception 1077 * is "The validated collection index is invalid: " 1078 * followed by the index.</p> 1079 * 1080 * @param <T> the collection type 1081 * @param collection the collection to check, validated not null by this method 1082 * @param index the index to check 1083 * @return the validated collection (never {@code null} for method chaining) 1084 * @throws NullPointerException if the collection is {@code null} 1085 * @throws IndexOutOfBoundsException if the index is invalid 1086 * @see #validIndex(Collection, int, String, Object...) 1087 * @since 3.0 1088 */ 1089 public static <T extends Collection<?>> T validIndex(final T collection, final int index) { 1090 return validIndex(collection, index, DEFAULT_VALID_INDEX_COLLECTION_EX_MESSAGE, Integer.valueOf(index)); 1091 } 1092 1093 /** 1094 * Validates that the index is within the bounds of the argument 1095 * character sequence; otherwise throwing an exception. 1096 * 1097 * <pre>Validate.validIndex(myStr, 2);</pre> 1098 * 1099 * <p>If the character sequence is {@code null}, then the message 1100 * of the exception is "The validated object is 1101 * null".</p> 1102 * 1103 * <p>If the index is invalid, then the message of the exception 1104 * is "The validated character sequence index is invalid: " 1105 * followed by the index.</p> 1106 * 1107 * @param <T> the character sequence type 1108 * @param chars the character sequence to check, validated not null by this method 1109 * @param index the index to check 1110 * @return the validated character sequence (never {@code null} for method chaining) 1111 * @throws NullPointerException if the character sequence is {@code null} 1112 * @throws IndexOutOfBoundsException if the index is invalid 1113 * @see #validIndex(CharSequence, int, String, Object...) 1114 * @since 3.0 1115 */ 1116 public static <T extends CharSequence> T validIndex(final T chars, final int index) { 1117 return validIndex(chars, index, DEFAULT_VALID_INDEX_CHAR_SEQUENCE_EX_MESSAGE, Integer.valueOf(index)); 1118 } 1119 1120 /** 1121 * Validates that the index is within the bounds of the argument 1122 * collection; otherwise throwing an exception with the specified message. 1123 * 1124 * <pre>Validate.validIndex(myCollection, 2, "The collection index is invalid: ");</pre> 1125 * 1126 * <p>If the collection is {@code null}, then the message of the 1127 * exception is "The validated object is null".</p> 1128 * 1129 * @param <T> the collection type 1130 * @param collection the collection to check, validated not null by this method 1131 * @param index the index to check 1132 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1133 * @param values the optional values for the formatted exception message, null array not recommended 1134 * @return the validated collection (never {@code null} for chaining) 1135 * @throws NullPointerException if the collection is {@code null} 1136 * @throws IndexOutOfBoundsException if the index is invalid 1137 * @see #validIndex(Collection, int) 1138 * @since 3.0 1139 */ 1140 public static <T extends Collection<?>> T validIndex(final T collection, final int index, final String message, final Object... values) { 1141 Objects.requireNonNull(collection, "collection"); 1142 if (index < 0 || index >= collection.size()) { 1143 throw new IndexOutOfBoundsException(getMessage(message, values)); 1144 } 1145 return collection; 1146 } 1147 1148 /** 1149 * Validates that the index is within the bounds of the argument 1150 * character sequence; otherwise throwing an exception with the 1151 * specified message. 1152 * 1153 * <pre>Validate.validIndex(myStr, 2, "The string index is invalid: ");</pre> 1154 * 1155 * <p>If the character sequence is {@code null}, then the message 1156 * of the exception is "The validated object is null".</p> 1157 * 1158 * @param <T> the character sequence type 1159 * @param chars the character sequence to check, validated not null by this method 1160 * @param index the index to check 1161 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1162 * @param values the optional values for the formatted exception message, null array not recommended 1163 * @return the validated character sequence (never {@code null} for method chaining) 1164 * @throws NullPointerException if the character sequence is {@code null} 1165 * @throws IndexOutOfBoundsException if the index is invalid 1166 * @see #validIndex(CharSequence, int) 1167 * @since 3.0 1168 */ 1169 public static <T extends CharSequence> T validIndex(final T chars, final int index, final String message, final Object... values) { 1170 Objects.requireNonNull(chars, "chars"); 1171 if (index < 0 || index >= chars.length()) { 1172 throw new IndexOutOfBoundsException(getMessage(message, values)); 1173 } 1174 return chars; 1175 } 1176 1177 /** 1178 * Validates that the index is within the bounds of the argument 1179 * array; otherwise throwing an exception. 1180 * 1181 * <pre>Validate.validIndex(myArray, 2);</pre> 1182 * 1183 * <p>If the array is {@code null}, then the message of the exception 1184 * is "The validated object is null".</p> 1185 * 1186 * <p>If the index is invalid, then the message of the exception is 1187 * "The validated array index is invalid: " followed by the 1188 * index.</p> 1189 * 1190 * @param <T> the array type 1191 * @param array the array to check, validated not null by this method 1192 * @param index the index to check 1193 * @return the validated array (never {@code null} for method chaining) 1194 * @throws NullPointerException if the array is {@code null} 1195 * @throws IndexOutOfBoundsException if the index is invalid 1196 * @see #validIndex(Object[], int, String, Object...) 1197 * @since 3.0 1198 */ 1199 public static <T> T[] validIndex(final T[] array, final int index) { 1200 return validIndex(array, index, DEFAULT_VALID_INDEX_ARRAY_EX_MESSAGE, Integer.valueOf(index)); 1201 } 1202 1203 /** 1204 * Validates that the index is within the bounds of the argument 1205 * array; otherwise throwing an exception with the specified message. 1206 * 1207 * <pre>Validate.validIndex(myArray, 2, "The array index is invalid: ");</pre> 1208 * 1209 * <p>If the array is {@code null}, then the message of the exception 1210 * is "The validated object is null".</p> 1211 * 1212 * @param <T> the array type 1213 * @param array the array to check, validated not null by this method 1214 * @param index the index to check 1215 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1216 * @param values the optional values for the formatted exception message, null array not recommended 1217 * @return the validated array (never {@code null} for method chaining) 1218 * @throws NullPointerException if the array is {@code null} 1219 * @throws IndexOutOfBoundsException if the index is invalid 1220 * @see #validIndex(Object[], int) 1221 * @since 3.0 1222 */ 1223 public static <T> T[] validIndex(final T[] array, final int index, final String message, final Object... values) { 1224 Objects.requireNonNull(array, "array"); 1225 if (index < 0 || index >= array.length) { 1226 throw new IndexOutOfBoundsException(getMessage(message, values)); 1227 } 1228 return array; 1229 } 1230 1231 /** 1232 * Validate that the stateful condition is {@code true}; otherwise 1233 * throwing an exception. This method is useful when validating according 1234 * to an arbitrary boolean expression, such as validating a 1235 * primitive number or using your own custom validation expression. 1236 * 1237 * <pre> 1238 * Validate.validState(field > 0); 1239 * Validate.validState(this.isOk());</pre> 1240 * 1241 * <p>The message of the exception is "The validated state is 1242 * false".</p> 1243 * 1244 * @param expression the boolean expression to check 1245 * @throws IllegalStateException if expression is {@code false} 1246 * @see #validState(boolean, String, Object...) 1247 * @since 3.0 1248 */ 1249 public static void validState(final boolean expression) { 1250 if (!expression) { 1251 throw new IllegalStateException(DEFAULT_VALID_STATE_EX_MESSAGE); 1252 } 1253 } 1254 1255 /** 1256 * Validate that the stateful condition is {@code true}; otherwise 1257 * throwing an exception with the specified message. This method is useful when 1258 * validating according to an arbitrary boolean expression, such as validating a 1259 * primitive number or using your own custom validation expression. 1260 * 1261 * <pre>Validate.validState(this.isOk(), "The state is not OK: %s", myObject);</pre> 1262 * 1263 * @param expression the boolean expression to check 1264 * @param message the {@link String#format(String, Object...)} exception message if invalid, not null 1265 * @param values the optional values for the formatted exception message, null array not recommended 1266 * @throws IllegalStateException if expression is {@code false} 1267 * @see #validState(boolean) 1268 * @since 3.0 1269 */ 1270 public static void validState(final boolean expression, final String message, final Object... values) { 1271 if (!expression) { 1272 throw new IllegalStateException(getMessage(message, values)); 1273 } 1274 } 1275 1276 /** 1277 * Constructs a new instance. This class should not normally be instantiated. 1278 */ 1279 public Validate() { 1280 } 1281}