package cn.com.ty.lift.common.verify; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Array; import java.math.BigDecimal; import java.math.BigInteger; import java.net.IDN; import java.time.*; import java.time.chrono.HijrahDate; import java.time.chrono.JapaneseDate; import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistDate; import java.time.temporal.TemporalAccessor; import java.util.*; import java.util.regex.Matcher; import java.util.regex.PatternSyntaxException; import static java.util.regex.Pattern.CASE_INSENSITIVE; /** * the validation for parameter implements javax.validation.constraints.*, * reform from hibernate validator (v6.0.16.Final) * * @author wcz * @since 2020/2/15 */ @Slf4j public class Verifies { private static final int MAX_LOCAL_PART_LENGTH = 64; private static final String LOCAL_PART_ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uFFFF-]"; private static final String LOCAL_PART_INSIDE_QUOTES_ATOM = "([a-z0-9!#$%&'*.(),<>\\[\\]:; @+/=?^_`{|}~\u0080-\uFFFF-]|\\\\\\\\|\\\\\\\")"; /** * Regular expression for the local part of an email address (everything before '@') */ private static final java.util.regex.Pattern LOCAL_PART_PATTERN = java.util.regex.Pattern.compile( "(" + LOCAL_PART_ATOM + "+|\"" + LOCAL_PART_INSIDE_QUOTES_ATOM + "+\")" + "(\\." + "(" + LOCAL_PART_ATOM + "+|\"" + LOCAL_PART_INSIDE_QUOTES_ATOM + "+\")" + ")*", CASE_INSENSITIVE ); /** * This is the maximum length of a domain name. But be aware that each label (parts separated by a dot) of the * domain name must be at most 63 characters long. This is verified by {@link IDN#toASCII(String)}. */ private static final int MAX_DOMAIN_PART_LENGTH = 255; private static final String DOMAIN_CHARS_WITHOUT_DASH = "[a-z\u0080-\uFFFF0-9!#$%&'*+/=?^_`{|}~]"; private static final String DOMAIN_LABEL = "(" + DOMAIN_CHARS_WITHOUT_DASH + "-*)*" + DOMAIN_CHARS_WITHOUT_DASH + "+"; private static final String DOMAIN = DOMAIN_LABEL + "+(\\." + DOMAIN_LABEL + "+)*"; private static final String IP_DOMAIN = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"; //IP v6 regex taken from http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses private static final String IP_V6_DOMAIN = "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"; /** * Regular expression for the domain part of an URL *

* A host string must be a domain string, an IPv4 address string, or "[", followed by an IPv6 address string, * followed by "]". */ private static final java.util.regex.Pattern DOMAIN_PATTERN = java.util.regex.Pattern.compile( DOMAIN + "|\\[" + IP_V6_DOMAIN + "\\]", CASE_INSENSITIVE ); /** * Regular expression for the domain part of an email address (everything after '@') */ private static final java.util.regex.Pattern EMAIL_DOMAIN_PATTERN = java.util.regex.Pattern.compile( DOMAIN + "|\\[" + IP_DOMAIN + "\\]|" + "\\[IPv6:" + IP_V6_DOMAIN + "\\]", CASE_INSENSITIVE ); private static final OptionalInt LESS_THAN = OptionalInt.of(-1); private static final OptionalInt FINITE_VALUE = OptionalInt.empty(); private static final OptionalInt GREATER_THAN = OptionalInt.of(1); private static final short SHORT_ZERO = (short) 0; private static final byte BYTE_ZERO = (byte) 0; private static final Clock SYSTEM_DEFAULT_CLOCK = Clock.offset(Clock.systemDefaultZone(), Duration.ZERO.abs().negated()); private Verifies(){} public static boolean isNull(Object value) { return null == value; } public static boolean notNull(Object value) { return null != value; } private static class VerifyUtils{ private static VerifyException exception(String message){ return new VerifyException(message); } private static void isTrue(boolean expression, String message) { if (expression) { throw exception(message); } } private static void notTrue(boolean expression, String message) { if (!expression) { throw exception(message); } } private static void isNull(Object value, String message) { isTrue(null == value, message); } } private static class IllegalArg{ private static IllegalArgumentException exception(String message) { return new IllegalArgumentException(message); } private static void isTrue(boolean expression, String message) { if (expression) { throw exception(message); } } private static void isNull(Object value, String message) { isTrue(null == value, message); } } public static boolean gt0(int value) { return value > 0; } public static boolean lt0(int value) { return value < 0; } public static boolean gte0(int value) { return value >= 0; } public static boolean lte0(int value) { return value <= 0; } public static boolean isCharSequence(Object value) { return (value instanceof CharSequence); } public static boolean isBigDecimal(Object value) { return (value instanceof BigDecimal); } public static boolean isBigInteger(Object value) { return (value instanceof BigInteger); } public static boolean isLong(Object value) { return (value instanceof Long); } public static boolean isInteger(Object value) { return (value instanceof Integer); } public static boolean isDouble(Object value) { return (value instanceof Double); } public static boolean isFloat(Object value) { return (value instanceof Float); } public static boolean isByte(Object value) { return (value instanceof Byte); } public static boolean isShort(Object value) { return (value instanceof Short); } public static boolean isString(Object value) { return (value instanceof String); } public static boolean isCollection(Object value) { return (value instanceof Collection); } public static boolean isMap(Object value) { return (value instanceof Map); } public static boolean isArray(Object value) { return value.getClass().isArray(); } public static boolean isIterator(Object value) { return (value instanceof Iterator); } public static boolean isEnumeration(Object value) { return (value instanceof Enumeration); } private static BigDecimal newBigDecimal(CharSequence value) { try { BigDecimal bd; if (isString(value)) { bd = new BigDecimal((String) value); } else { bd = new BigDecimal(value.toString()); } return bd; } catch (Exception e) { return null; } } private static BigDecimal newBigDecimal(Number value) { try { BigDecimal bd; if (isLong(value)) { bd = BigDecimal.valueOf((Long) value); } else if (isBigDecimal(value)) { bd = ((BigDecimal) value); } else if (isBigInteger(value)) { bd = new BigDecimal((BigInteger) value); } else if (isDouble(value)) { bd = BigDecimal.valueOf((Double) value); } else if (isFloat(value)) { bd = BigDecimal.valueOf((Float) value); } else { bd = BigDecimal.valueOf(value.doubleValue()); } return bd; } catch (Exception e) { return null; } } private static OptionalInt infinityCheck(Double number, OptionalInt treatNanAs) { OptionalInt result = FINITE_VALUE; if (number == Double.NEGATIVE_INFINITY) { result = LESS_THAN; } else if (number.isNaN()) { result = treatNanAs; } else if (number == Double.POSITIVE_INFINITY) { result = GREATER_THAN; } return result; } private static OptionalInt infinityCheck(Float number, OptionalInt treatNanAs) { OptionalInt result = FINITE_VALUE; if (number == Float.NEGATIVE_INFINITY) { result = LESS_THAN; } else if (number.isNaN()) { result = treatNanAs; } else if (number == Float.POSITIVE_INFINITY) { result = GREATER_THAN; } return result; } /** * Checks the validity of the domain name used in an email. To be valid it should be either a valid host name, or an * IP address wrapped in []. * * @param domain domain to check for validity * @return {@code true} if the provided string is a valid domain, {@code false} otherwise */ public static boolean isValidEmailDomainAddress(String domain) { return isValidDomainAddress(domain, EMAIL_DOMAIN_PATTERN); } /** * Checks validity of a domain name. * * @param domain the domain to check for validity * @return {@code true} if the provided string is a valid domain, {@code false} otherwise */ public static boolean isValidDomainAddress(String domain) { return isValidDomainAddress(domain, DOMAIN_PATTERN); } private static boolean isValidDomainAddress(String domain, java.util.regex.Pattern pattern) { // if we have a trailing dot the domain part we have an invalid email address. // the regular expression match would take care of this, but IDN.toASCII drops the trailing '.' if (domain.endsWith(".")) { return false; } Matcher matcher = pattern.matcher(domain); if (!matcher.matches()) { return false; } String asciiString; try { asciiString = IDN.toASCII(domain); } catch (IllegalArgumentException e) { return false; } if (asciiString.length() > MAX_DOMAIN_PART_LENGTH) { return false; } return true; } //NotNull : Object public static void notNull(Object value, String message) { VerifyUtils.isTrue(isNull(value), message); } //Null : Object public static void isNull(Object value, String message) { VerifyUtils.isTrue(notNull(value), message); } //AssertTrue : Boolean public static void assertTrue(Boolean value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.isTrue(!value, message); } //AssertFalse : Boolean public static void assertFalse(Boolean value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.isTrue(value, message); } //decimalMax : number public static void decimalMax(Number value, BigDecimal maxValue, boolean inclusive, String message) { VerifyUtils.isNull(value, message); IllegalArg.isNull(maxValue, maxValue + " does not represent a valid BigDecimal format."); BigDecimal val = newBigDecimal(value); VerifyUtils.isNull(val, message); int compare = decimalComparator(value, val, maxValue, GREATER_THAN); //inclusive ? comparisonResult <= 0 : comparisonResult < 0; if (inclusive) { VerifyUtils.notTrue(lte0(compare), message); } else { VerifyUtils.notTrue(lt0(compare), message); } } public static void decimalMax(Number value, BigDecimal maxValue, String message) { decimalMax(value, maxValue, true, message); } //decimalMax : CharSequence public static void decimalMax(CharSequence value, BigDecimal maxValue, boolean inclusive, String message) { VerifyUtils.isNull(value, message); IllegalArg.isNull(maxValue, maxValue + " does not represent a valid BigDecimal format."); BigDecimal val = newBigDecimal(value.toString().trim()); VerifyUtils.isNull(val, message); int compare = decimalComparator(value, val, maxValue, GREATER_THAN); //inclusive ? comparisonResult <= 0 : comparisonResult < 0; if (inclusive) { VerifyUtils.notTrue(lte0(compare), message); } else { VerifyUtils.notTrue(lt0(compare), message); } } public static void decimalMax(CharSequence value, BigDecimal maxValue, String message) { decimalMax(value, maxValue, true, message); } //decimalMin : number public static void decimalMin(Number value, BigDecimal minValue, boolean inclusive, String message) { VerifyUtils.isNull(value, message); IllegalArg.isNull(minValue, minValue + " does not represent a valid BigDecimal format."); BigDecimal val = newBigDecimal(value); VerifyUtils.isNull(val, message); int compare = decimalComparator(value, val, minValue, LESS_THAN); //inclusive ? comparisonResult >= 0 : comparisonResult > 0; if (inclusive) { VerifyUtils.notTrue(gte0(compare), message); } else { VerifyUtils.notTrue(gt0(compare), message); } } public static void decimalMin(Number value, BigDecimal minValue, String message) { decimalMin(value, minValue, true, message); } //decimalMin : CharSequence public static void decimalMin(CharSequence value, BigDecimal minValue, boolean inclusive, String message) { VerifyUtils.isNull(value, message); IllegalArg.isNull(minValue, minValue + " does not represent a valid BigDecimal format."); BigDecimal val = newBigDecimal(value.toString().trim()); VerifyUtils.isNull(val, message); int compare = decimalComparator(value, val, minValue, LESS_THAN); //inclusive ? comparisonResult >= 0 : comparisonResult > 0; if (inclusive) { VerifyUtils.notTrue(gte0(compare), message); } else { VerifyUtils.notTrue(gt0(compare), message); } } public static void decimalMin(CharSequence value, BigDecimal minValue, String message) { decimalMin(value, minValue, true, message); } private static int decimalComparator(Object value, BigDecimal val, BigDecimal boundary, OptionalInt treatNanAs) { int compare; if (isLong(value) || isBigInteger(value) || isBigDecimal(value)) { compare = val.compareTo(boundary); } else if (isDouble(value)) { Double v = (Double) value; OptionalInt infinity = infinityCheck(v, treatNanAs); if (infinity.isPresent()) { compare = infinity.getAsInt(); } else { compare = val.compareTo(boundary); } } else if (isFloat(value)) { Float v = (Float) value; OptionalInt infinity = infinityCheck(v, treatNanAs); if (infinity.isPresent()) { compare = infinity.getAsInt(); } else { compare = val.compareTo(boundary); } } else { compare = val.compareTo(boundary); } return compare; } //length : CharSequence,Collection,Map,Array,Iterator,Enumeration public static int length(Object value) { if (isNull(value)) { return 0; } if (isCharSequence(value)) { return ((CharSequence) value).length(); } if (isCollection(value)) { return ((Collection) value).size(); } if (isMap(value)) { return ((Map) value).size(); } if (isArray(value)) { return Array.getLength(value); } int count; if (isIterator(value)) { Iterator iter = (Iterator) value; count = 0; while (iter.hasNext()) { count++; iter.next(); } return count; } if (isEnumeration(value)) { Enumeration enumeration = (Enumeration) value; count = 0; while (enumeration.hasMoreElements()) { count++; enumeration.nextElement(); } return count; } return -1; } //NotEmpty : CharSequence,Collection,Map,Array,Iterator,Enumeration public static void notEmpty(CharSequence value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(gt0(value.length()), message); } public static void notEmpty(Collection value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.isTrue(value.isEmpty(), message); } public static void notEmpty(Map value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.isTrue(value.isEmpty(), message); } public static void notEmpty(Iterator value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(value.hasNext(), message); } public static void notEmpty(Enumeration value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(value.hasMoreElements(), message); } public static void notEmpty(T[] value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(gt0(value.length), message); } public static void between(int value, int min, int max, String message) { IllegalArg.isTrue(lt0(min), "The min parameter cannot be negative."); IllegalArg.isTrue(lt0(max), "The max parameter cannot be negative."); IllegalArg.isTrue(min > max, "The min and max length cannot be negative."); //value >= min && value <= max VerifyUtils.notTrue(value >= min && value <= max, message); } //Size : CharSequence,Collection,Map,Array,Iterator,Enumeration public static void size(Object value, int min, int max, String message) { VerifyUtils.isNull(value, message); between(length(value), min, max, message); } public static void size(Object value, String message) { VerifyUtils.isNull(value, message); between(length(value), 0, Integer.MAX_VALUE, message); } //Size : CharSequence,Collection,Map,Array,Iterator,Enumeration public static void upper(Object value, int min, String message) { VerifyUtils.isNull(value, message); between(length(value), min, Integer.MAX_VALUE, message); } //Size : CharSequence,Collection,Map,Array,Iterator,Enumeration public static void lower(Object value, int max, String message) { VerifyUtils.isNull(value, message); between(length(value), 0, max, message); } public static void digits(BigDecimal value, int maxInteger, int maxFraction, String message) { IllegalArg.isTrue(lt0(maxInteger), "The length of the integer part cannot be negative."); IllegalArg.isTrue(lt0(maxFraction), "The length of the fraction part cannot be negative."); int integerPart = value.precision() - value.scale(); int fractionPart = value.scale() < 0 ? 0 : value.scale(); //maxInteger >= integerPart && maxFraction >= fractionPart VerifyUtils.notTrue(maxInteger >= integerPart && maxFraction >= fractionPart, message); } //Digits : CharSequence,Number public static void digits(CharSequence value, int maxInteger, int maxFraction, String message) { VerifyUtils.isNull(value, message); BigDecimal val = newBigDecimal(value); VerifyUtils.isNull(val, value + " does not represent a valid BigDecimal format."); digits(val, maxInteger, maxFraction, message); } //Digits : CharSequence,Number public static void digits(Number value, int maxInteger, int maxFraction, String message) { VerifyUtils.isNull(value, message); BigDecimal val; if (isBigDecimal(value)) { val = (BigDecimal) value; } else { val = new BigDecimal(value.toString()); } VerifyUtils.isNull(val, value + " does not represent a valid BigDecimal format."); val = val.stripTrailingZeros(); digits(val, maxInteger, maxFraction, message); } //NotBlank : CharSequence public static void notBlank(CharSequence value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(value.toString().trim().isEmpty(), message); } //Email : CharSequence public static void email(CharSequence value, String regexp, Flag[] flags, String message) { VerifyUtils.isNull(value, message); String val = value.toString().trim(); // cannot split email string at @ as it can be a part of quoted local part of email. // so we need to split at a position of last @ present in the string: int splitPosition = val.lastIndexOf('@'); // need to check if VerifyUtils.isTrue(lt0(splitPosition), message); String localPart = val.substring(0, splitPosition); String domainPart = val.substring(splitPosition + 1); VerifyUtils.isTrue(localPart.length() > MAX_LOCAL_PART_LENGTH, message); VerifyUtils.notTrue(LOCAL_PART_PATTERN.matcher(localPart).matches(), message); VerifyUtils.notTrue(isValidEmailDomainAddress(domainPart), message); //valid by the pattern pattern(value, ".*", message); } public static void email(CharSequence value, String message) { Flag[] flags = {}; email(value, ".*", flags, message); } public static void pattern(CharSequence value, String regexp, Flag[] flags, String message) { VerifyUtils.isNull(value, message); IllegalArg.isNull(regexp, "The regexp is Invalid regular expression."); int intFlag = 0; for (Flag flag : flags) { intFlag = intFlag | flag.getValue(); } java.util.regex.Pattern pattern = null; // we only apply the regexp if there is one to apply if (!".*".equals(regexp) || flags.length > 0) { try { pattern = java.util.regex.Pattern.compile(regexp, intFlag); } catch (PatternSyntaxException e) { throw VerifyUtils.exception("The regexp is Invalid regular expression."); } } IllegalArg.isNull(pattern, "The regexp is Invalid regular expression."); VerifyUtils.notTrue(pattern.matcher(value.toString()).matches(), message); } public static void pattern(CharSequence value, String regexp, String message) { Flag[] flags = {}; pattern(value, regexp, flags, message); } /** * Possible Regexp flags. */ public enum Flag { /** * Enables Unix lines mode. * * @see java.util.regex.Pattern#UNIX_LINES */ UNIX_LINES(java.util.regex.Pattern.UNIX_LINES), /** * Enables case-insensitive matching. * * @see java.util.regex.Pattern#CASE_INSENSITIVE */ CASE_INSENSITIVE(java.util.regex.Pattern.CASE_INSENSITIVE), /** * Permits whitespace and comments in pattern. * * @see java.util.regex.Pattern#COMMENTS */ COMMENTS(java.util.regex.Pattern.COMMENTS), /** * Enables multiline mode. * * @see java.util.regex.Pattern#MULTILINE */ MULTILINE(java.util.regex.Pattern.MULTILINE), /** * Enables dotall mode. * * @see java.util.regex.Pattern#DOTALL */ DOTALL(java.util.regex.Pattern.DOTALL), /** * Enables Unicode-aware case folding. * * @see java.util.regex.Pattern#UNICODE_CASE */ UNICODE_CASE(java.util.regex.Pattern.UNICODE_CASE), /** * Enables canonical equivalence. * * @see java.util.regex.Pattern#CANON_EQ */ CANON_EQ(java.util.regex.Pattern.CANON_EQ); //JDK flag value private final int value; Flag(int value) { this.value = value; } /** * @return flag value as defined in {@link java.util.regex.Pattern} */ public int getValue() { return value; } } //Max : CharSequence public static void max(CharSequence value, long max, String message) { VerifyUtils.isNull(value, message); String v = value.toString().trim(); VerifyUtils.isTrue(v.isEmpty(), message); BigDecimal val = newBigDecimal(v); VerifyUtils.isNull(val, message); int compare = val.compareTo(BigDecimal.valueOf(max)); VerifyUtils.notTrue(lte0(compare), message); } //Max : Number public static void max(Number value, long max, String message) { VerifyUtils.isNull(value, message); int compare = numberComparator(value, max, GREATER_THAN); VerifyUtils.notTrue(lte0(compare), message); } //min : CharSequence public static void min(CharSequence value, long min, String message) { VerifyUtils.isNull(value, message); String v = value.toString().trim(); VerifyUtils.isTrue(v.isEmpty(), message); BigDecimal val = newBigDecimal(v); VerifyUtils.isNull(val, message); int compare = val.compareTo(BigDecimal.valueOf(min)); VerifyUtils.notTrue(gte0(compare), message); } //min : Number public static void min(Number value, long min, String message) { VerifyUtils.isNull(value, message); int compare = numberComparator(value, min, LESS_THAN); VerifyUtils.notTrue(gte0(compare), message); } // private static int numberComparator(Number value, long boundary, OptionalInt treatNanAs) { int compare; if (isLong(value)) { compare = ((Long) value).compareTo(boundary); } else if (isDouble(value)) { Double val = (Double) value; OptionalInt infinity = infinityCheck(val, treatNanAs); if (infinity.isPresent()) { compare = infinity.getAsInt(); } else { compare = Double.compare(val, boundary); } } else if (isFloat(value)) { Float val = (Float) value; OptionalInt infinity = infinityCheck(val, treatNanAs); if (infinity.isPresent()) { compare = infinity.getAsInt(); } else { compare = Float.compare(val, boundary); } } else if (isBigDecimal(value)) { compare = ((BigDecimal) value).compareTo(BigDecimal.valueOf(boundary)); } else if (isBigInteger(value)) { compare = ((BigInteger) value).compareTo(BigInteger.valueOf(boundary)); } else { compare = Long.compare(value.longValue(), boundary); } return compare; } private static int signum(Number value, OptionalInt treatNanAs) { int signum; if (isLong(value)) { signum = Long.signum((Long) value); } else if (isInteger(value)) { signum = Integer.signum((Integer) value); } else if (isBigDecimal(value)) { signum = ((BigDecimal) value).signum(); } else if (isBigInteger(value)) { signum = ((BigInteger) value).signum(); } else if (isDouble(value)) { Double val = (Double) value; OptionalInt infinity = infinityCheck(val, treatNanAs); if (infinity.isPresent()) { signum = infinity.getAsInt(); } else { signum = val.compareTo(0D); } } else if (isFloat(value)) { Float val = (Float) value; OptionalInt infinity = infinityCheck(val, treatNanAs); if (infinity.isPresent()) { signum = infinity.getAsInt(); } else { signum = val.compareTo(0F); } } else if (isByte(value)) { signum = ((Byte) value).compareTo(BYTE_ZERO); } else if (isShort(value)) { signum = ((Short) value).compareTo(SHORT_ZERO); } else { signum = Double.compare(value.doubleValue(), 0D); } return signum; } //Negative : Number public static void negative(Number value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(lt0(signum(value, GREATER_THAN)), message); } // NegativeOrZero : Number public static void negativeOrZero(Number value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(lte0(signum(value, GREATER_THAN)), message); } //Positive : Number public static void positive(Number value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(gt0(signum(value, LESS_THAN)), message); } //PositiveOrZero : Number public static void positiveOrZero(Number value, String message) { VerifyUtils.isNull(value, message); VerifyUtils.notTrue(gte0(signum(value, LESS_THAN)), message); } //java.time.temporal.TemporalAccessor public static int dateComparator(TemporalAccessor value) { int compare; if (value instanceof Instant) { compare = ((Instant) value).compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof LocalDateTime) { compare = ((LocalDateTime) value).compareTo(LocalDateTime.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof LocalDate) { compare = ((LocalDate) value).compareTo(LocalDate.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof LocalTime) { compare = ((LocalTime) value).compareTo(LocalTime.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof MonthDay) { compare = ((MonthDay) value).compareTo(MonthDay.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof HijrahDate) { compare = ((HijrahDate) value).compareTo(HijrahDate.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof JapaneseDate) { compare = ((JapaneseDate) value).compareTo(JapaneseDate.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof MinguoDate) { compare = ((MinguoDate) value).compareTo(MinguoDate.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof OffsetDateTime) { compare = ((OffsetDateTime) value).compareTo(OffsetDateTime.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof OffsetTime) { compare = ((OffsetTime) value).compareTo(OffsetTime.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof ThaiBuddhistDate) { compare = ((ThaiBuddhistDate) value).compareTo(ThaiBuddhistDate.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof Year) { compare = ((Year) value).compareTo(Year.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof YearMonth) { compare = ((YearMonth) value).compareTo(YearMonth.now(SYSTEM_DEFAULT_CLOCK)); } else if (value instanceof ZonedDateTime) { compare = ((ZonedDateTime) value).compareTo(ZonedDateTime.now(SYSTEM_DEFAULT_CLOCK)); } else { compare = Integer.MAX_VALUE; } return compare; } //Future : java.time.temporal.TemporalAccessor public static void future(TemporalAccessor value, String message) { VerifyUtils.isNull(value, message); int compare = dateComparator(value); IllegalArg.isTrue(Integer.MAX_VALUE == compare, value.getClass().toString() + " is not a supported TemporalAccessor class temporarily."); VerifyUtils.notTrue(gt0(compare), message); } //Future : java.util.Date, public static void future(Date value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(gt0(compare), message); } //Future : java.util.Calendar public static void future(Calendar value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(gte0(compare), message); } //FutureOrPresent : java.time.temporal.TemporalAccessor public static void futureOrPresent(TemporalAccessor value, String message) { VerifyUtils.isNull(value, message); int compare = dateComparator(value); IllegalArg.isTrue(Integer.MAX_VALUE == compare, value.getClass().toString() + " is not a supported TemporalAccessor class temporarily."); VerifyUtils.notTrue(gte0(compare), message); } //FutureOrPresent : java.util.Date, public static void futureOrPresent(Date value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(gt0(compare), message); } //FutureOrPresent : java.util.Calendar public static void futureOrPresent(Calendar value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(gte0(compare), message); } /////////////// //past : java.time.temporal.TemporalAccessor public static void past(TemporalAccessor value, String message) { VerifyUtils.isNull(value, message); int compare = dateComparator(value); IllegalArg.isNull(Integer.MAX_VALUE == compare, value.getClass().toString() + " is not a supported TemporalAccessor class temporarily."); VerifyUtils.notTrue(lt0(compare), message); } //past : java.util.Date, public static void past(Date value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(lt0(compare), message); } //past : java.util.Calendar public static void past(Calendar value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(lt0(compare), message); } //PastOrPresent : java.time.temporal.TemporalAccessor public static void pastOrPresent(TemporalAccessor value, String message) { VerifyUtils.isNull(value, message); int compare = dateComparator(value); IllegalArg.isTrue(Integer.MAX_VALUE == compare, value.getClass().toString() + " is not a supported TemporalAccessor class temporarily."); VerifyUtils.notTrue(lte0(compare), message); } //PastOrPresent : java.util.Date, public static void pastOrPresent(Date value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(lt0(compare), message); } //PastOrPresent : java.util.Calendar public static void pastOrPresent(Calendar value, String message) { VerifyUtils.isNull(value, message); int compare = value.toInstant().compareTo(Instant.now(SYSTEM_DEFAULT_CLOCK)); VerifyUtils.notTrue(lte0(compare), message); } }