All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wl4g.component.common.lang.Assert2 Maven / Gradle / Ivy

/*
 * Copyright 2017 ~ 2025 the original author or authors. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wl4g.component.common.lang;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

import javax.annotation.Nullable;
import com.wl4g.component.common.reflect.ObjectInstantiators;

import static com.wl4g.component.common.lang.StringUtils2.*;
import static java.lang.Math.max;
import static java.lang.String.format;

/**
 * Assertion utility class that assists in validating arguments.
 *
 * 

* Useful for identifying programmer errors early and clearly at runtime. * *

* For example, if the contract of a public method states it does not allow * {@code null} arguments, {@code Assert} can be used to validate that contract. * Doing this clearly indicates a contract violation when it occurs and protects * the class's invariants. * *

* Typically used to validate method arguments rather than configuration * properties, to check for cases that are usually programmer errors rather than * configuration errors. In contrast to configuration initialization code, there * is usually no point in falling back to defaults in such methods. * *

* This class is similar to JUnit's assertion library. If an argument value is * deemed invalid, an {@link IllegalArgumentException} is thrown (typically). * For example: * *

 * Assert2.notNull(clazz, "The class must not be null");
 * Assert2.isTrue(i > 0, "The value must be greater than zero");
 * 
* *

* Mainly for internal use within the framework; consider * Apache's Commons * Lang for a more comprehensive suite of {@code String} utilities. * * @author Keith Donald * @author Juergen Hoeller * @author Sam Brannen * @author Colin Sampaleanu * @author Rob Harrop * @since 1.1.2 */ public abstract class Assert2 { /** * Assert a boolean expression, throwing an {@code IllegalStateException} if * the expression evaluates to {@code false}. *

* Call {@link #isTrue} if you wish to throw an * {@code IllegalArgumentException} on an assertion failure. * *

	 * Assert2.state(id == null, "The id property must not already be initialized");
	 * 
* * @param expression * a boolean expression * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalStateException * if {@code expression} is {@code false} */ public static void state(boolean expression, String fmtMessage, Object... args) { if (!expression) { throw new IllegalStateException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } } /** * Assert a boolean expression, throwing an {@code IllegalStateException} if * the expression evaluates to {@code false}. * * @param expression * a boolean expression * @param argName */ public static void stateOf(boolean expression, String argName) { state(expression, argName + " condition miss"); } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * *
	 * Assert2.isTrue(i > 0, "The value must be greater than zero");
	 * 
* * @param expression * a boolean expression * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if {@code expression} is {@code false} */ public static void isTrue(boolean expression, String fmtMessage, Object... args) { if (!expression) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * *
	 * Assert2.isTrue(i > 0, "The value must be greater than zero");
	 * 
* * @param expression * a boolean expression * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if {@code expression} is {@code false} */ public static void isTrue(boolean expression, Supplier messageSupplier) { if (!expression) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(nullSafeGet(messageSupplier))); } } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * *
	 * Assert2.isTrue(i > 0, "The value must be greater than zero");
	 * 
* * @param expression * a boolean expression * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if {@code expression} is {@code false} */ public static void isTrue(boolean expression, Class exceptionClass, String fmtMessage, Object... args) { if (!expression) { doWrapException(exceptionClass, fmtMessage, args); } } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * *
	 * Assert2.isTrue(i > 0, "The value must be greater than zero");
	 * 
* * @param expression * a boolean expression * @param exceptionClass * Throwable class * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if {@code expression} is {@code false} */ public static void isTrue(boolean expression, Class exceptionClass, Supplier messageSupplier) { if (!expression) { doWrapException(exceptionClass, nullSafeGet(messageSupplier)); } } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * * @param expression * a boolean expression * @param argName */ public static void isTrueOf(boolean expression, String argName) { isTrue(expression, argName + " condition miss"); } /** * Assert a boolean expression, throwing an {@code IllegalArgumentException} * if the expression evaluates to {@code false}. * * @param expression * a boolean expression * @param exceptionClass * @param argName */ public static void isTrueOf(boolean expression, Class exceptionClass, String argName) { isTrue(expression, exceptionClass, argName + " condition must be true"); } /** * Assert that an object is {@code null}. * *
	 * Assert2.isNull(value, "The value must be null");
	 * 
* * @param object * the object to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object is not {@code null} */ public static void isNull(Object object, String fmtMessage, Object... args) { if (object != null) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } } /** * Assert that an object is {@code null}. * *
	 * Assert2.isNull(value, "The value must be null");
	 * 
* * @param object * the object to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object is {@code null} */ @SuppressWarnings("unchecked") public static T isNull(Object object, Class exceptionClass, String fmtMessage, Object... args) { if (object != null) { doWrapException(exceptionClass, fmtMessage, args); } return (T) object; } /** * Assert that an object is {@code null}. * * @param object * the object to check * @param argName */ public static void isNullOf(Object object, String argName) { isNull(object, argName + " must be null"); } /** * Assert that an object is not {@code null}. * *
	 * Assert2.notNull(clazz, "The class must not be null");
	 * 
* * @param object * the object to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object is {@code null} */ @SuppressWarnings("unchecked") public static T notNull(Object object, String fmtMessage, Object... args) { if (object == null) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX + doFormat(fmtMessage, args)); } return (T) object; } /** * Assert that an object is not {@code null}. * *
	 * Assert2.notNull(clazz, "The class must not be null");
	 * 
* * @param object * the object to check * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object is {@code null} */ @SuppressWarnings("unchecked") public static T notNull(Object object, Supplier messageSupplier) { if (object == null) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(nullSafeGet(messageSupplier))); } return (T) object; } /** * Assert that an object is not {@code null}. * *
	 * Assert2.notNull(clazz, "The class must not be null");
	 * 
* * @param object * the object to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object is {@code null} */ @SuppressWarnings("unchecked") public static T notNull(Object object, Class exceptionClass, String fmtMessage, Object... args) { if (object == null) { doWrapException(exceptionClass, fmtMessage, args); } return (T) object; } /** * Assert that an object is not {@code null}. * *
	 * Assert2.notNull(clazz, "The class must not be null");
	 * 
* * @param object * the object to check * @param exceptionClass * Throwable class * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object is {@code null} */ @SuppressWarnings("unchecked") public static T notNull(Object object, Class exceptionClass, Supplier messageSupplier) { if (object == null) { doWrapException(exceptionClass, nullSafeGet(messageSupplier)); } return (T) object; } /** * Assert that an object is not {@code null}. * * @param object * the object to check * @param argName */ @SuppressWarnings("unchecked") public static T notNullOf(Object object, String argName) { notNull(object, argName + " is required"); return (T) object; } /** * Assert that an object is not {@code null}. * * @param object * the object to check * @param exceptionClass * @param argName */ @SuppressWarnings("unchecked") public static T notNullOf(Object object, Class exceptionClass, String argName) { notNull(object, exceptionClass, argName + " is required"); return (T) object; } /** * Assert that the given String is not empty; that is, it must not be * {@code null} and not the empty String. * *
	 * Assert2.hasLength(name, "Name must not be empty");
	 * 
* * @param text * the String to check * @param fmtMessage * the exception message to use if the assertion fails * @see StringUtils#hasLength * @throws IllegalArgumentException * if the text is empty */ public static void hasLength(String text, String fmtMessage, Object... args) { if (!isNotBlank(text)) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } } /** * Assert that the given String is not empty; that is, it must not be * {@code null} and not the empty String. * * @param text * the String to check * @param argName */ public static void hasLengthOf(String text, String argName) { hasLength(text, argName + " must have length; it must not be null or empty"); } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * *
	 * Assert2.hasText(name, "'name' must not be empty");
	 * 
* * @param text * the String to check * @param fmtMessage * the exception message to use if the assertion fails * @see StringUtils#hasText * @throws IllegalArgumentException * if the text does not contain valid text content */ @SuppressWarnings("unchecked") public static T hasText(String text, String fmtMessage, Object... args) { if (!isNotBlank(text)) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } return (T) text; } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * *
	 * Assert2.hasText(name, "'name' must not be empty");
	 * 
* * @param text * the String to check * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @see StringUtils#hasText * @throws IllegalArgumentException * if the text does not contain valid text content */ @SuppressWarnings("unchecked") public static T hasText(String text, Supplier messageSupplier) { if (!isNotBlank(text)) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(nullSafeGet(messageSupplier))); } return (T) text; } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * *
	 * Assert2.hasText(name, "'name' must not be empty");
	 * 
* * @param text * the String to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @see StringUtils#hasText * @throws IllegalArgumentException * if the text does not contain valid text content */ @SuppressWarnings("unchecked") public static T hasText(String text, Class exceptionClass, String fmtMessage, Object... args) { if (!isNotBlank(text)) { doWrapException(exceptionClass, fmtMessage, args); } return (T) text; } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * *
	 * Assert2.hasText(name, "'name' must not be empty");
	 * 
* * @param text * the String to check * @param exceptionClass * Throwable class * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @see StringUtils#hasText * @throws IllegalArgumentException * if the text does not contain valid text content */ @SuppressWarnings("unchecked") public static T hasText(String text, Class exceptionClass, Supplier messageSupplier) { if (!isNotBlank(text)) { doWrapException(exceptionClass, nullSafeGet(messageSupplier)); } return (T) text; } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * * @param text * the String to check * @param argName */ @SuppressWarnings("unchecked") public static T hasTextOf(String text, String argName) { hasText(text, argName + " is required"); return (T) text; } /** * Assert that the given String contains valid text content; that is, it * must not be {@code null} and must contain at least one non-whitespace * character. * * @param text * the String to check * @param exceptionClass * @param argName */ @SuppressWarnings("unchecked") public static T hasTextOf(String text, Class exceptionClass, String argName) { hasText(text, exceptionClass, argName + " is required"); return (T) text; } /** * Assert that the given text does not contain the given substring. * *
	 * Assert2.doesNotContain(name, "rod", "Name must not contain 'rod'");
	 * 
* * @param textToSearch * the text to search * @param substring * the substring to find within the text * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the text contains the substring */ public static void doesNotContain(String textToSearch, String substring, String fmtMessage, Object... args) { if (isNotBlank(textToSearch) && isNotBlank(substring) && textToSearch.contains(substring)) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX + doFormat(fmtMessage, args)); } } /** * Assert that the given text does not contain the given substring. * * @param textToSearch * the text to search * @param substring * the substring to find within the text * @param argName */ public static void doesNotContainOf(String textToSearch, String substring, String argName) { doesNotContain(textToSearch, substring, argName + " must not contain the substring [" + substring + "]"); } /** * Assert that an array contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(array, "The array must contain elements");
	 * 
* * @param array * the array to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object array is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Object[] array, String fmtMessage, Object... args) { if (array == null || array.length == 0) { throw new IllegalArgumentException(doFormat(fmtMessage, args)); } return (T) array; } /** * Assert that an array contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(array, "The array must contain elements");
	 * 
* * @param array * the array to check * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object array is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Object[] array, Supplier messageSupplier) { if (array == null || array.length == 0) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(nullSafeGet(messageSupplier))); } return (T) array; } /** * Assert that an array contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(array, "The array must contain elements");
	 * 
* * @param array * the array to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object array is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Object[] array, Class exceptionClass, String fmtMessage, Object... args) { if (array == null || array.length == 0) { doWrapException(exceptionClass, fmtMessage, args); } return (T) array; } /** * Assert that an array contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(array, "The array must contain elements");
	 * 
* * @param array * the array to check * @param exceptionClass * Throwable class * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object array is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Object[] array, Class exceptionClass, Supplier messageSupplier) { if (array == null || array.length == 0) { doWrapException(exceptionClass, nullSafeGet(messageSupplier)); } return (T) array; } /** * Assert that an array contains elements; that is, it must not be * {@code null} * * @param array * the array to check * @param argName */ @SuppressWarnings("unchecked") public static T notEmptyOf(Object[] array, String argName) { notEmpty(array, argName + " must not be empty: it must contain at least 1 element"); return (T) array; } /** * Assert that an array contains elements; that is, it must not be * {@code null} * * @param array * the array to check * @param exceptionClass * @param argName */ @SuppressWarnings("unchecked") public static T notEmptyOf(Object[] array, Class exceptionClass, String argName) { notEmpty(array, exceptionClass, argName + " must not be empty: it must contain at least 1 element"); return (T) array; } /** * Assert that an array contains no {@code null} elements. *

* Note: Does not complain if the array is empty! * *

	 * Assert2.noNullElements(array, "The array must contain non-null elements");
	 * 
* * @param array * the array to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object array contains a {@code null} element */ public static void noNullElements(Object[] array, String fmtMessage, Object... args) { if (array != null) { for (Object element : array) { if (element == null) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } } } } /** * Assert that an array contains no {@code null} elements. *

* Note: Does not complain if the array is empty! * *

	 * Assert2.noNullElements(array, "The array must contain non-null elements");
	 * 
* * @param array * the array to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the object array contains a {@code null} element */ public static void noNullElements(Object[] array, Class exceptionClass, String fmtMessage, Object... args) { if (array != null) { for (Object element : array) { if (element == null) { doWrapException(exceptionClass, fmtMessage, args); } } } } /** * Assert that an array contains no {@code null} elements. * * @param array * the array to check * @param argName */ public static void noNullElementsOf(Object[] array, String argName) { noNullElements(array, argName + " must not contain any null elements"); } /** * Assert that a collection contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(collection, "Collection must contain elements");
	 * 
* * @param collection * the collection to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the collection is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Collection collection, String fmtMessage, Object... args) { if (collection == null || collection.isEmpty()) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } return (T) collection; } /** * Assert that a collection contains elements; that is, it must not be * {@code null} and must contain at least one element. * *
	 * Assert2.notEmpty(collection, "Collection must contain elements");
	 * 
* * @param collection * the collection to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the collection is {@code null} or contains no elements */ @SuppressWarnings("unchecked") public static T notEmpty(Collection collection, Class exceptionClass, String fmtMessage, Object... args) { if (collection == null || collection.isEmpty()) { doWrapException(exceptionClass, fmtMessage, args); } return (T) collection; } /** * Assert that a collection contains elements; that is, it must not be * {@code null} and must contain at least one element. * * @param collection * the collection to check * @param argName */ @SuppressWarnings("unchecked") public static T notEmptyOf(Collection collection, String argName) { notEmpty(collection, argName + " must not be empty: it must contain at least 1 element"); return (T) collection; } /** * Assert that a Map contains entries; that is, it must not be {@code null} * and must contain at least one entry. * *
	 * Assert2.notEmpty(map, "Map must contain entries");
	 * 
* * @param map * the map to check * @param exceptionClass * Throwable class * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the map is {@code null} or contains no entries */ @SuppressWarnings("unchecked") public static T notEmpty(Map map, Class exceptionClass, String fmtMessage, Object... args) { if (map == null || map.isEmpty()) { doWrapException(exceptionClass, fmtMessage, args); } return (T) map; } /** * Assert that a Map contains entries; that is, it must not be {@code null} * and must contain at least one entry. * *
	 * Assert2.notEmpty(map, "Map must contain entries");
	 * 
* * @param map * the map to check * @param fmtMessage * the exception message to use if the assertion fails * @throws IllegalArgumentException * if the map is {@code null} or contains no entries */ @SuppressWarnings("unchecked") public static T notEmpty(Map map, String fmtMessage, Object... args) { if (map == null || map.isEmpty()) { throw new IllegalArgumentException(ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } return (T) map; } /** * Assert that a Map contains entries; that is, it must not be {@code null} * and must contain at least one entry. * * @param map * the map to check * @param argName */ @SuppressWarnings("unchecked") public static T notEmptyOf(Map map, String argName) { notEmpty(map, argName + " must not be empty; it must contain at least one entry"); return (T) map; } /** * Assert that a Map contains entries; that is, it must not be {@code null} * and must contain at least one entry. * * @param map * the map to check * @param exceptionClass * @param argName */ @SuppressWarnings("unchecked") public static T notEmptyOf(Map map, Class exceptionClass, String argName) { notEmpty(map, exceptionClass, argName + " must not be empty; it must contain at least one entry"); return (T) map; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.mustAssignableFrom(Parent.class, Sub.class);
	 * 
* * @param parentType * the parent type class * @param type * the target type class * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending object's type will be appended. In any * other case, a ":" with a space and the name of the offending * object's type will be appended. * @throws ClassCastException */ public static Class mustAssignableFrom(Class parentType, Class type) { return mustAssignableFrom(parentType, type, "Type '%s' must be extension compatible from parentType '%s'", parentType, type); } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.mustAssignableFrom(Parent.class, Sub.class, "Unexpected compatible type");
	 * 
* * @param parentType * the parent type class * @param type * the target type class * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending object's type will be appended. In any * other case, a ":" with a space and the name of the offending * object's type will be appended. * @throws ClassCastException */ public static Class mustAssignableFrom(Class parentType, Class type, String fmtMessage, Object... args) { notNull(parentType, "ParentType to check against must not be null"); notNull(type, "Type to check against must not be null"); if (!parentType.isAssignableFrom(type)) { doWrapException(ClassCastException.class, fmtMessage, args); } return type; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.instanceOf(Foo.class, foo, "Foo expected");
	 * 
* * @param type * the type to check against * @param obj * the object to check * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending object's type will be appended. In any * other case, a ":" with a space and the name of the offending * object's type will be appended. * @throws IllegalArgumentException * if the object is not an instance of type */ @SuppressWarnings("unchecked") public static T isInstanceOf(Class type, Object obj, String fmtMessage, Object... args) { notNull(type, "Type to check against must not be null"); if (!type.isInstance(obj)) { instanceCheckFailed(type, obj, IllegalArgumentException.class, doFormat(fmtMessage, args)); } return (T) obj; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.instanceOf(Foo.class, foo, "Foo expected");
	 * 
* * @param type * the type to check against * @param obj * the object to check * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object is not an instance of type */ @SuppressWarnings("unchecked") public static T isInstanceOf(Class type, Object obj, Supplier messageSupplier) { notNull(type, "Type to check against must not be null"); if (!type.isInstance(obj)) { instanceCheckFailed(type, obj, IllegalArgumentException.class, ASSERT_FAILED_PREFIX.concat(nullSafeGet(messageSupplier))); } return (T) obj; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.instanceOf(Foo.class, foo, "Foo expected");
	 * 
* * @param type * the type to check against * @param obj * the object to check * @param exceptionClass * Throwable class * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending object's type will be appended. In any * other case, a ":" with a space and the name of the offending * object's type will be appended. * @throws IllegalArgumentException * if the object is not an instance of type */ @SuppressWarnings("unchecked") public static T isInstanceOf(Class type, Object obj, Class exceptionClass, String fmtMessage, Object... args) { notNull(type, "Type to check against must not be null"); if (!type.isInstance(obj)) { instanceCheckFailed(type, obj, exceptionClass, doFormat(fmtMessage, args)); } return (T) obj; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.instanceOf(Foo.class, foo, "Foo expected");
	 * 
* * @param type * the type to check against * @param obj * the object to check * @param exceptionClass * Throwable class * @param messageSupplier * a supplier for the exception message to use if the assertion * fails * @throws IllegalArgumentException * if the object is not an instance of type */ @SuppressWarnings("unchecked") public static T isInstanceOf(Class type, Object obj, Class exceptionClass, Supplier messageSupplier) { notNull(type, "Type to check against must not be null"); if (!type.isInstance(obj)) { instanceCheckFailed(type, obj, exceptionClass, nullSafeGet(messageSupplier)); } return (T) obj; } /** * Assert that the provided object is an instance of the provided class. * *
	 * Assert2.instanceOf(Foo.class, foo);
	 * 
* * @param type * the type to check against * @param obj * the object to check * @throws IllegalArgumentException * if the object is not an instance of type */ @SuppressWarnings("unchecked") public static T isInstanceOf(Class type, Object obj) { isInstanceOf(type, obj, ""); return (T) obj; } /** * Assert that {@code superType.isAssignableFrom(subType)} is {@code true}. * *
	 * Assert2.isAssignable(Number.class, myClass, "Number expected");
	 * 
* * @param superType * the super type to check against * @param subType * the sub type to check * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending sub type will be appended. In any other * case, a ":" with a space and the name of the offending sub * type will be appended. * @throws IllegalArgumentException * if the classes are not assignable */ public static void isAssignable(Class superType, Class subType, String fmtMessage, Object... args) { notNull(superType, "Super type to check against must not be null"); if (subType == null || !superType.isAssignableFrom(subType)) { assignableCheckFailed(superType, subType, IllegalArgumentException.class, doFormat(fmtMessage, args)); } } /** * Assert that {@code superType.isAssignableFrom(subType)} is {@code true}. * *
	 * Assert2.isAssignable(Number.class, myClass, "Number expected");
	 * 
* * @param superType * the super type to check against * @param subType * the sub type to check * @param exceptionClass * Throwable class * @param fmtMessage * a message which will be prepended to provide further context. * If it is empty or ends in ":" or ";" or "," or ".", a full * exception message will be appended. If it ends in a space, the * name of the offending sub type will be appended. In any other * case, a ":" with a space and the name of the offending sub * type will be appended. * @throws IllegalArgumentException * if the classes are not assignable */ public static void isAssignable(Class superType, Class subType, Class exceptionClass, String fmtMessage, Object... args) { notNull(superType, "Super type to check against must not be null"); if (subType == null || !superType.isAssignableFrom(subType)) { assignableCheckFailed(superType, subType, exceptionClass, doFormat(fmtMessage, args)); } } /** * Assert that {@code superType.isAssignableFrom(subType)} is {@code true}. * *
	 * Assert2.isAssignable(Number.class, myClass);
	 * 
* * @param superType * the super type to check * @param subType * the sub type to check * @throws IllegalArgumentException * if the classes are not assignable */ public static void isAssignable(Class superType, Class subType) { isAssignable(superType, subType, ""); } /** * Assertion parameters in range * * @param paramValue * @param lowerValue * @param upperValue */ public static void assertInRange(long paramValue, long lowerValue, long upperValue) { if (!checkParameterInRange(paramValue, lowerValue, true, upperValue, true)) { throw new IllegalArgumentException(format("%d not in valid range [%d, %d]", paramValue, lowerValue, upperValue)); } } /** * Check parameters in range * * @param param * @param from * @param leftInclusive * @param to * @param rightInclusive * @return */ private static boolean checkParameterInRange(long param, long from, boolean leftInclusive, long to, boolean rightInclusive) { if (leftInclusive && rightInclusive) { // [from, to] if (from <= param && param <= to) { return true; } else { return false; } } else if (leftInclusive && !rightInclusive) { // [from, to) if (from <= param && param < to) { return true; } else { return false; } } else if (!leftInclusive && !rightInclusive) { // (from, to) if (from < param && param < to) { return true; } else { return false; } } else { // (from, to] if (from < param && param <= to) { return true; } else { return false; } } } /** * Check instance failed * * @param type * @param obj * @param exceptionClass * @param msg */ private static void instanceCheckFailed(Class type, Object obj, Class exceptionClass, String msg) { String className = (obj != null ? obj.getClass().getName() : "null"); String result = ""; boolean defaultMessage = true; if (isNotBlank(msg)) { if (endsWithSeparator(msg)) { result = msg + " "; } else { result = messageWithTypeName(msg, className); defaultMessage = false; } } if (defaultMessage) { result = result + ("Object of class [" + className + "] must be an instance of " + type); } doWrapException(exceptionClass, result); } /** * Check assignable failed * * @param superType * @param subType * @param exceptionClass * @param msg */ private static void assignableCheckFailed(Class superType, Class subType, Class exceptionClass, String msg) { String result = ""; boolean defaultMessage = true; if (isNotBlank(msg)) { if (endsWithSeparator(msg)) { result = msg + " "; } else { result = messageWithTypeName(msg, subType); defaultMessage = false; } } if (defaultMessage) { result = result + (subType + " is not assignable to " + superType); } doWrapException(exceptionClass, result); } private static boolean endsWithSeparator(String msg) { return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith(".")); } private static String messageWithTypeName(String msg, Object typeName) { return msg + (msg.endsWith(" ") ? "" : ": ") + typeName; } /** * Do format throwable message. * * @param format * @param args * @return */ private static String doFormat(String format, Object... args) { if (Objects.nonNull(args) && args.length > 0) { return String.format(format, args); } return format; } @Nullable private static String nullSafeGet(@Nullable Supplier messageSupplier) { return (messageSupplier != null ? messageSupplier.get() : null); } /** * Do wrap assertion exception. * * @param exceptionClass * @param fmtMessage * @param args */ private static void doWrapException(Class exceptionClass, String fmtMessage, Object... args) { RuntimeException th = newRuntimeExceptionInstance(exceptionClass); // Init cause message try { detailMessageField.set(th, ASSERT_FAILED_PREFIX.concat(doFormat(fmtMessage, args))); } catch (Exception ex) { throw new Error( "Unexpected reflection exception - ".concat(ex.getClass().getName()).concat(": ").concat(ex.getMessage())); } // Remove useless stack elements StackTraceElement[] stackEles = th.getStackTrace(); List availableStackEles = new ArrayList<>(max(stackEles.length - 4, 4)); for (int i = 0, j = 0; i < stackEles.length; i++) { StackTraceElement st = stackEles[i]; if (j == 0) { if (NEW_RUNTIMEEXCEPTION_INSTANCE_METHOD.equals(st.getClassName().concat("#").concat(st.getMethodName()))) j = i; } else availableStackEles.add(st); } th.setStackTrace(availableStackEles.toArray(new StackTraceElement[] {})); throw th; } /** * New create throwable instance. * * @param exceptionClass * @return */ private static RuntimeException newRuntimeExceptionInstance(Class exceptionClass) { return ObjectInstantiators.newInstance(exceptionClass); } /** * @see new IllegalArgumentException("[Assertion failed] - xxx required"); */ final private static String ASSERT_FAILED_PREFIX = "[AF] - "; final private static String NEW_RUNTIMEEXCEPTION_INSTANCE_METHOD = Assert2.class.getName() + "#newRuntimeExceptionInstance"; final private static Field detailMessageField; final private static Field causeField; static { try { detailMessageField = Throwable.class.getDeclaredField("detailMessage"); causeField = Throwable.class.getDeclaredField("cause"); detailMessageField.setAccessible(true); causeField.setAccessible(true); } catch (Exception e) { throw new IllegalStateException(e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy