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

com.liferay.portal.kernel.util.Validator Maven / Gradle / Ivy

There is a newer version: 7.4.3.112-ga112
Show newest version
/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.kernel.util;

import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringPool;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Provides utility methods related to data validation and format checking.
 *
 * @author Brian Wing Shun Chan
 * @author Alysa Carver
 */
public class Validator {

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(boolean boolean1, boolean boolean2) {
		if (boolean1 == boolean2) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(byte byte1, byte byte2) {
		if (byte1 == byte2) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(char char1, char char2) {
		if (char1 == char2) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(double double1, double double2) {
		if (Double.compare(double1, double2) == 0) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(float float1, float float2) {
		if (Float.compare(float1, float2) == 0) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(int int1, int int2) {
		if (int1 == int2) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(long long1, long long2) {
		if (long1 == long2) {
			return true;
		}

		return false;
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(Object obj1, Object obj2) {
		if (obj1 == obj2) {
			return true;
		}
		else if ((obj1 == null) || (obj2 == null)) {
			return false;
		}

		return obj1.equals(obj2);
	}

	/**
	 * @deprecated As of Judson (7.1.x)
	 */
	@Deprecated
	public static boolean equals(short short1, short short2) {
		if (short1 == short2) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the boolean arrays are equal.
	 *
	 * @param  booleanArray1 the first boolean array
	 * @param  booleanArray2 the second boolean array
	 * @return true if the booleans arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(
		boolean[] booleanArray1, boolean[] booleanArray2) {

		Boolean[] booleanObjArray1 = ArrayUtil.toArray(booleanArray1);

		Arrays.sort(booleanObjArray1);

		Boolean[] booleanObjArray2 = ArrayUtil.toArray(booleanArray2);

		Arrays.sort(booleanObjArray2);

		return Arrays.equals(booleanObjArray1, booleanObjArray2);
	}

	/**
	 * Returns true if the byte arrays are equal.
	 *
	 * @param  byteArray1 the first byte array
	 * @param  byteArray2 the second byte array
	 * @return true if the byte arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(byte[] byteArray1, byte[] byteArray2) {
		byteArray1 = ArrayUtil.clone(byteArray1);

		Arrays.sort(byteArray1);

		byteArray2 = ArrayUtil.clone(byteArray2);

		Arrays.sort(byteArray2);

		return Arrays.equals(byteArray1, byteArray2);
	}

	/**
	 * Returns true if the char arrays are equal.
	 *
	 * @param  charArray1 the first char array
	 * @param  charArray2 the second char array
	 * @return true if the char arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(char[] charArray1, char[] charArray2) {
		charArray1 = ArrayUtil.clone(charArray1);

		Arrays.sort(charArray1);

		charArray2 = ArrayUtil.clone(charArray2);

		Arrays.sort(charArray2);

		return Arrays.equals(charArray1, charArray2);
	}

	/**
	 * Returns true if the double arrays are equal.
	 *
	 * @param  doubleArray1 the first double array
	 * @param  doubleArray2 the second double array
	 * @return true if the double arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(
		double[] doubleArray1, double[] doubleArray2) {

		doubleArray1 = ArrayUtil.clone(doubleArray1);

		Arrays.sort(doubleArray1);

		doubleArray2 = ArrayUtil.clone(doubleArray2);

		Arrays.sort(doubleArray2);

		return Arrays.equals(doubleArray1, doubleArray2);
	}

	/**
	 * Returns true if the float arrays are equal.
	 *
	 * @param  floatArray1 the first float array
	 * @param  floatArray2 the second char array
	 * @return true if the float arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(
		float[] floatArray1, float[] floatArray2) {

		floatArray1 = ArrayUtil.clone(floatArray1);

		Arrays.sort(floatArray1);

		floatArray2 = ArrayUtil.clone(floatArray2);

		Arrays.sort(floatArray2);

		return Arrays.equals(floatArray1, floatArray2);
	}

	/**
	 * Returns true if the int arrays are equal.
	 *
	 * @param  intArray1 the first int array
	 * @param  intArray2 the second int array
	 * @return true if the int arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(int[] intArray1, int[] intArray2) {
		intArray1 = ArrayUtil.clone(intArray1);

		Arrays.sort(intArray1);

		intArray2 = ArrayUtil.clone(intArray2);

		Arrays.sort(intArray2);

		return Arrays.equals(intArray1, intArray2);
	}

	/**
	 * Returns true if the long arrays are equal.
	 *
	 * @param  longArray1 the first long array
	 * @param  longArray2 the second long array
	 * @return true if the long arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(long[] longArray1, long[] longArray2) {
		longArray1 = ArrayUtil.clone(longArray1);

		Arrays.sort(longArray1);

		longArray2 = ArrayUtil.clone(longArray2);

		Arrays.sort(longArray2);

		return Arrays.equals(longArray1, longArray2);
	}

	/**
	 * Returns true if the object arrays are equal.
	 *
	 * @param  objArray1 the first object array
	 * @param  objArray2 the second object array
	 * @return true if the object arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(Object[] objArray1, Object[] objArray2) {
		objArray1 = ArrayUtil.clone(objArray1);

		Arrays.sort(objArray1);

		objArray2 = ArrayUtil.clone(objArray2);

		Arrays.sort(objArray2);

		return Arrays.equals(objArray1, objArray2);
	}

	/**
	 * Returns true if the short arrays are equal.
	 *
	 * @param  shortArray1 the first short array
	 * @param  shortArray2 the second short array
	 * @return true if the short arrays are equal; false
	 *         otherwise
	 */
	public static boolean equalsSorted(
		short[] shortArray1, short[] shortArray2) {

		shortArray1 = ArrayUtil.clone(shortArray1);

		Arrays.sort(shortArray1);

		shortArray2 = ArrayUtil.clone(shortArray2);

		Arrays.sort(shortArray2);

		return Arrays.equals(shortArray1, shortArray2);
	}

	/**
	 * Returns true if the string is an email address. The only
	 * requirements are that the string consist of two parts separated by an @
	 * symbol, and that it contain no whitespace.
	 *
	 * @param  address the string to check
	 * @return true if the string is an email address;
	 *         false otherwise
	 */
	public static boolean isAddress(String address) {
		if (isNull(address)) {
			return false;
		}

		String[] tokens = address.split(StringPool.AT);

		if (tokens.length != 2) {
			return false;
		}

		for (String token : tokens) {
			for (char c : token.toCharArray()) {
				if (Character.isWhitespace(c)) {
					return false;
				}
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is an alphanumeric name, meaning
	 * it contains nothing but English letters, numbers, and spaces.
	 *
	 * @param  name the string to check
	 * @return true if the string is an Alphanumeric name;
	 *         false otherwise
	 */
	public static boolean isAlphanumericName(String name) {
		if (isNull(name)) {
			return false;
		}

		String trimmedName = name.trim();

		for (char c : trimmedName.toCharArray()) {
			if (!isChar(c) && !isDigit(c) && !Character.isWhitespace(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the character is in the ASCII character set.
	 * This includes characters with integer values between 32 and 126
	 * (inclusive).
	 *
	 * @param  c the character to check
	 * @return true if the character is in the ASCII character set;
	 *         false otherwise
	 */
	public static boolean isAscii(char c) {
		int i = c;

		if ((i >= 32) && (i <= 126)) {
			return true;
		}

		return false;
	}

	public static boolean isBlank(String s) {
		if (s == null) {
			return true;
		}

		if (s.length() == 0) {
			return true;
		}

		return false;
	}

	public static boolean isBoolean(String value) {
		return ArrayUtil.contains(_BOOLEANS, value);
	}

	/**
	 * Returns true if the character is an upper or lower case
	 * English letter.
	 *
	 * @param  c the character to check
	 * @return true if the character is an upper or lower case
	 *         English letter; false otherwise
	 */
	public static boolean isChar(char c) {
		int x = c;

		if (((x >= _CHAR_LOWER_CASE_BEGIN) && (x <= _CHAR_LOWER_CASE_END)) ||
			((x >= _CHAR_UPPER_CASE_BEGIN) && (x <= _CHAR_UPPER_CASE_END))) {

			return true;
		}

		return false;
	}

	/**
	 * Returns true if string consists only of upper and lower case
	 * English letters.
	 *
	 * @param  s the string to check
	 * @return true if the string consists only of upper and lower
	 *         case English letters
	 */
	public static boolean isChar(String s) {
		if (isNull(s)) {
			return false;
		}

		for (char c : s.toCharArray()) {
			if (!isChar(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the string contains content. The only
	 * requirement is that it contain content that is not whitespace.
	 *
	 * @param  s the string to check
	 * @return true if the string contains content;
	 *         false otherwise
	 */
	public static boolean isContent(String s) {
		if (isNotNull(
				StringUtil.removeChars(s, CharPool.NEW_LINE, CharPool.TAB))) {

			return true;
		}

		return false;
	}

	/**
	 * Returns true if the date is valid in the Gregorian calendar.
	 *
	 * @param  month the month to check
	 * @param  day the day to check
	 * @param  year the year to check
	 * @return true if the date is valid in the Gregorian calendar;
	 *         false otherwise
	 */
	public static boolean isDate(int month, int day, int year) {
		return isGregorianDate(month, day, year);
	}

	/**
	 * Returns true if the character is a digit between 0 and 9
	 * (inclusive).
	 *
	 * @param  c the character to check
	 * @return true if the character is a digit between 0 and 9
	 *         (inclusive); false otherwise
	 */
	public static boolean isDigit(char c) {
		int x = c;

		if ((x >= _DIGIT_BEGIN) && (x <= _DIGIT_END)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string consists of only digits between 0
	 * and 9 (inclusive).
	 *
	 * @param  s the string to check
	 * @return true if the string consists of only digits between 0
	 *         and 9 (inclusive); false otherwise
	 */
	public static boolean isDigit(String s) {
		if (isNull(s)) {
			return false;
		}

		for (char c : s.toCharArray()) {
			if (!isDigit(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is a valid domain name. See
	 * RFC-1034 (section 3), RFC-1123 (section 2.1), and RFC-952 (section B.
	 * Lexical grammar).
	 *
	 * @param  domainName the string to check
	 * @return true if the string is a valid domain name;
	 *         false otherwise
	 */
	public static boolean isDomain(String domainName) {

		// See RFC-1034 (section 3), RFC-1123 (section 2.1), and RFC-952
		// (section B. Lexical grammar)

		if (isNull(domainName)) {
			return false;
		}

		if (domainName.length() > 255) {
			return false;
		}

		if (domainName.startsWith(StringPool.PERIOD)) {
			return false;
		}

		String[] domainNameArray = StringUtil.split(
			domainName, CharPool.PERIOD);

		for (String domainNamePart : domainNameArray) {
			char[] domainNamePartCharArray = domainNamePart.toCharArray();

			for (int i = 0; i < domainNamePartCharArray.length; i++) {
				char c = domainNamePartCharArray[i];

				if ((i == 0) && (c == CharPool.DASH)) {
					return false;
				}

				if ((i == (domainNamePartCharArray.length - 1)) &&
					(c == CharPool.DASH)) {

					return false;
				}

				if (!Character.isLetterOrDigit(c) && (c != CharPool.DASH)) {
					return false;
				}
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is a valid email address.
	 *
	 * @param  emailAddress the string to check
	 * @return true if the string is a valid email address;
	 *         false otherwise
	 */
	public static boolean isEmailAddress(String emailAddress) {
		if (isNull(emailAddress)) {
			return false;
		}

		Matcher matcher = _emailAddressPattern.matcher(emailAddress);

		return matcher.matches();
	}

	/**
	 * Returns true if the character is a special character in an
	 * email address.
	 *
	 * @param  c the character to check
	 * @return true if the character is a special character in an
	 *         email address; false otherwise
	 */
	public static boolean isEmailAddressSpecialChar(char c) {

		// LEP-1445

		for (char specialChar : _EMAIL_ADDRESS_SPECIAL_CHAR) {
			if (c == specialChar) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Returns true if the file extension is valid.
	 *
	 * @param  fileExtension string to check
	 * @return true if the extension is valid; false
	 *         otherwise
	 */
	public static boolean isFileExtension(String fileExtension) {
		if (isNull(fileExtension) ||
			fileExtension.contains(StringPool.BACK_SLASH) ||
			fileExtension.contains(StringPool.NULL_CHAR) ||
			fileExtension.contains(StringPool.SLASH)) {

			return false;
		}

		return true;
	}

	public static boolean isFileName(String name) {
		if (isNull(name) || name.equals(StringPool.PERIOD) ||
			name.equals(StringPool.DOUBLE_PERIOD) ||
			name.contains(StringPool.BACK_SLASH) ||
			name.contains(StringPool.NULL_CHAR) ||
			name.contains(StringPool.SLASH)) {

			return false;
		}

		return true;
	}

	public static boolean isFilePath(String path, boolean parentDirAllowed) {
		if (isNull(path)) {
			return false;
		}

		if (path.contains(StringPool.NULL_CHAR)) {
			return false;
		}

		if (parentDirAllowed) {
			return true;
		}

		if (path.equals(StringPool.DOUBLE_PERIOD)) {
			return false;
		}

		String normalizedPath = path.replace(
			CharPool.BACK_SLASH, CharPool.SLASH);

		if (normalizedPath.startsWith(
				StringPool.DOUBLE_PERIOD.concat(StringPool.SLASH))) {

			return false;
		}

		if (normalizedPath.endsWith(
				StringPool.SLASH.concat(StringPool.DOUBLE_PERIOD))) {

			return false;
		}

		if (normalizedPath.contains(
				StringBundler.concat(
					StringPool.SLASH, StringPool.DOUBLE_PERIOD,
					StringPool.SLASH))) {

			return false;
		}

		return true;
	}

	/**
	 * Returns true if the date is valid in the Gregorian calendar.
	 *
	 * @param  month the month (0-based, meaning 0 for January)
	 * @param  day the day of the month
	 * @param  year the year
	 * @return true if the date is valid; false
	 *         otherwise
	 */
	public static boolean isGregorianDate(int month, int day, int year) {
		if ((month < 0) || (month > 11)) {
			return false;
		}

		int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

		if (month == 1) {
			int febMax = 28;

			if ((((year % 4) == 0) && ((year % 100) != 0)) ||
				((year % 400) == 0)) {

				febMax = 29;
			}

			if ((day < 1) || (day > febMax)) {
				return false;
			}
		}
		else if ((day < 1) || (day > months[month])) {
			return false;
		}

		return true;
	}

	/**
	 * Returns true if the string is a hexidecimal number. At
	 * present the only requirement is that the string is not null;
	 * it does not actually check the format of the string.
	 *
	 * @param  s the string to check
	 * @return true if the string is a hexidecimal number;
	 *         false otherwise
	 * @see    #isNull(String)
	 */
	public static boolean isHex(String s) {
		if (isNull(s)) {
			return false;
		}

		return true;
	}

	/**
	 * Returns true if the string is a valid host name.
	 *
	 * @param  name the string to check
	 * @return true if the string is a valid host name;
	 *         false otherwise
	 */
	public static boolean isHostName(String name) {
		if (isNull(name)) {
			return false;
		}

		char[] nameCharArray = name.toCharArray();

		if ((nameCharArray[0] == CharPool.DASH) ||
			(nameCharArray[0] == CharPool.PERIOD) ||
			(nameCharArray[nameCharArray.length - 1] == CharPool.DASH)) {

			return false;
		}

		for (char c : nameCharArray) {
			if (!isChar(c) && !isDigit(c) && (c != CharPool.CLOSE_BRACKET) &&
				(c != CharPool.COLON) && (c != CharPool.DASH) &&
				(c != CharPool.OPEN_BRACKET) && (c != CharPool.PERIOD)) {

				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is an HTML document. The only
	 * requirement is that it contain the opening and closing html tags.
	 *
	 * @param  s the string to check
	 * @return true if the string is an HTML document;
	 *         false otherwise
	 */
	public static boolean isHTML(String s) {
		if (isNull(s)) {
			return false;
		}

		if ((s.contains("") || s.contains("")) &&
			(s.contains("") || s.contains(""))) {

			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is a valid IPv4 or IPv6 IP
	 * address.
	 *
	 * @param  ipAddress the string to check
	 * @return true if the string is a valid IPv4 or IPv6 IP
	 *         address; false otherwise
	 */
	public static boolean isIPAddress(String ipAddress) {
		if (isIPv4Address(ipAddress) || isIPv6Address(ipAddress)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is a valid IPv4 IP address.
	 *
	 * @param  ipAddress the string to check
	 * @return true if the string is a valid IPv4 IP address;
	 *         false otherwise
	 */
	public static boolean isIPv4Address(String ipAddress) {
		Matcher matcher = _ipv4AddressPattern.matcher(ipAddress);

		return matcher.matches();
	}

	/**
	 * Returns true if the string is a valid IPv6 IP address.
	 *
	 * @param  ipAddress the string to check
	 * @return true if the string is a valid IPv6 IP address;
	 *         false otherwise
	 */
	public static boolean isIPv6Address(String ipAddress) {
		if (isNull(ipAddress)) {
			return false;
		}

		if ((ipAddress.charAt(0) == CharPool.OPEN_BRACKET) &&
			(ipAddress.charAt(ipAddress.length() - 1) ==
				CharPool.CLOSE_BRACKET)) {

			ipAddress = ipAddress.substring(1, ipAddress.length() - 1);
		}

		Matcher matcher = _ipv6AddressPattern.matcher(ipAddress);

		return matcher.matches();
	}

	/**
	 * Returns true if the date is valid in the Julian calendar.
	 *
	 * @param  month the month (0-based, meaning 0 for January)
	 * @param  day the day of the month
	 * @param  year the year
	 * @return true if the date is valid in the Julian calendar;
	 *         false otherwise
	 */
	public static boolean isJulianDate(int month, int day, int year) {
		if ((month < 0) || (month > 11)) {
			return false;
		}

		int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

		if (month == 1) {
			int febMax = 28;

			if ((year % 4) == 0) {
				febMax = 29;
			}

			if ((day < 1) || (day > febMax)) {
				return false;
			}
		}
		else if ((day < 1) || (day > months[month])) {
			return false;
		}

		return true;
	}

	/**
	 * Returns true if the string contains a valid number according
	 * to the Luhn algorithm, commonly used to validate credit card numbers.
	 *
	 * @param  number the string to check
	 * @return true if the string contains a valid number according
	 *         to the Luhn algorithm; false otherwise
	 */
	public static boolean isLUHN(String number) {
		if (number == null) {
			return false;
		}

		int sum = 0;

		int length = number.length();

		for (int i = 0; i < length; i++) {
			int x = number.charAt(length - 1 - i) - CharPool.NUMBER_0;

			if ((x > 9) || (x < 0)) {
				return false;
			}

			if ((i % 2) == 1) {
				x *= 2;

				if (x > 9) {
					x -= 9;
				}
			}

			sum += x;
		}

		if ((sum % 10) == 0) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is a name, meaning it contains
	 * nothing but English letters and spaces.
	 *
	 * @param  name the string to check
	 * @return true if the string is a name; false
	 *         otherwise
	 */
	public static boolean isName(String name) {
		if (isNull(name)) {
			return false;
		}

		String trimmedName = name.trim();

		for (char c : trimmedName.toCharArray()) {
			if (!isChar(c) && !Character.isWhitespace(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the long number object is not
	 * null, meaning it is neither a null reference or
	 * zero.
	 *
	 * @param  l the long number object to check
	 * @return true if the long number object is not
	 *         null; false otherwise
	 */
	public static boolean isNotNull(Long l) {
		return !isNull(l);
	}

	/**
	 * Returns true if the object is not null, using
	 * the rules from {@link #isNotNull(Long)} or {@link #isNotNull(String)} if
	 * the object is one of these types.
	 *
	 * @param  obj the object to check
	 * @return true if the object is not null;
	 *         false otherwise
	 */
	public static boolean isNotNull(Object obj) {
		return !isNull(obj);
	}

	/**
	 * Returns true if the string is not null, meaning
	 * it is not a null reference, an empty string, whitespace, or
	 * the string "null", with or without leading or trailing
	 * whitespace.
	 *
	 * @param  s the string to check
	 * @return true if the string is not null;
	 *         false otherwise
	 */
	public static boolean isNotNull(String s) {
		return !isNull(s);
	}

	/**
	 * Returns true if the long number object is null,
	 * meaning it is either a null reference or zero.
	 *
	 * @param  l the long number object to check
	 * @return true if the long number object is null;
	 *         false otherwise
	 */
	public static boolean isNull(Long l) {
		if ((l == null) || (l.longValue() == 0)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the object is null, using the
	 * rules from {@link #isNull(Long)} or {@link #isNull(String)} if the object
	 * is one of these types.
	 *
	 * @param  obj the object to check
	 * @return true if the object is null;
	 *         false otherwise
	 */
	public static boolean isNull(Object obj) {
		if (obj instanceof Long) {
			return isNull((Long)obj);
		}
		else if (obj instanceof String) {
			return isNull((String)obj);
		}
		else if (obj == null) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is null, meaning it
	 * is a null reference, an empty string, whitespace, or the
	 * string "null", with or without leading or trailing
	 * whitespace.
	 *
	 * @param  s the string to check
	 * @return true if the string is null;
	 *         false otherwise
	 */
	public static boolean isNull(String s) {
		if (s == null) {
			return true;
		}

		int counter = 0;

		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);

			if (c == CharPool.SPACE) {
				continue;
			}
			else if (counter > 3) {
				return false;
			}

			if (counter == 0) {
				if (c != CharPool.LOWER_CASE_N) {
					return false;
				}
			}
			else if (counter == 1) {
				if (c != CharPool.LOWER_CASE_U) {
					return false;
				}
			}
			else if ((counter == 2) || (counter == 3)) {
				if (c != CharPool.LOWER_CASE_L) {
					return false;
				}
			}

			counter++;
		}

		if ((counter == 0) || (counter == 4)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is a decimal integer number,
	 * meaning it contains nothing but decimal digits.
	 *
	 * @param  number the string to check
	 * @return true if the string is a decimal integer number;
	 *         false otherwise
	 */
	public static boolean isNumber(String number) {
		if (isNull(number)) {
			return false;
		}

		for (char c : number.toCharArray()) {
			if (!isDigit(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is a valid password, meaning it
	 * is at least four characters long and contains only letters and decimal
	 * digits.
	 *
	 * @param  password the string to check
	 * @return true if the string is a valid password;
	 *         false otherwise
	 */
	public static boolean isPassword(String password) {
		if (isNull(password)) {
			return false;
		}

		if (password.length() < 4) {
			return false;
		}

		for (char c : password.toCharArray()) {
			if (!isChar(c) && !isDigit(c)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns true if the string is a valid phone number. The only
	 * requirement is that there are decimal digits in the string; length and
	 * format are not checked.
	 *
	 * @param  phoneNumber the string to check
	 * @return true if the string is a valid phone number;
	 *         false otherwise
	 */
	public static boolean isPhoneNumber(String phoneNumber) {
		return isNumber(StringUtil.extractDigits(phoneNumber));
	}

	public static boolean isUri(String uri) {
		if (isNotNull(uri)) {
			try {
				new URI(uri);

				return true;
			}
			catch (URISyntaxException urise) {
			}
		}

		return false;
	}

	/**
	 * Returns true if the string is a valid URL based on the rules
	 * in {@link URL}.
	 *
	 * @param  url the string to check
	 * @return true if the string is a valid URL;
	 *         false otherwise
	 */
	public static boolean isUrl(String url) {
		return isUrl(url, false);
	}

	/**
	 * Returns true if the string is a valid URL based on the rules
	 * in {@link URL}. This method can also validate root relative URLs.
	 *
	 * @param  url the string to check
	 * @param  acceptRootRelative whether a root relative URL should be accepted
	 * @return true if the string is a valid URL;
	 *         false otherwise
	 */
	public static boolean isUrl(String url, boolean acceptRootRelative) {
		if (isNotNull(url)) {
			if (acceptRootRelative && (url.charAt(0) == '/')) {
				return true;
			}

			if (url.indexOf(CharPool.COLON) == -1) {
				return false;
			}

			try {
				new URL(url);

				return true;
			}
			catch (MalformedURLException murle) {
			}
		}

		return false;
	}

	/**
	 * Returns true if the string is a valid variable name in Java.
	 *
	 * @param  variableName the string to check
	 * @return true if the string is a valid variable name in Java;
	 *         false otherwise
	 */
	public static boolean isVariableName(String variableName) {
		if (isNull(variableName) ||
			ArrayUtil.contains(_JAVA_KEYWORDS, variableName)) {

			return false;
		}

		Matcher matcher = _variableNamePattern.matcher(variableName);

		if (matcher.matches()) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is a valid variable term, meaning
	 * it begins with "[$" and ends with "$]".
	 *
	 * @param  s the string to check
	 * @return true if the string is a valid variable term;
	 *         false otherwise
	 */
	public static boolean isVariableTerm(String s) {
		if (s.startsWith(_VARIABLE_TERM_BEGIN) &&
			s.endsWith(_VARIABLE_TERM_END)) {

			return true;
		}

		return false;
	}

	/**
	 * Returns true if the character is whitespace, meaning it is
	 * either the null character '0' or whitespace according to
	 * {@link Character#isWhitespace(char)}.
	 *
	 * @param  c the character to check
	 * @return true if the character is whitespace;
	 *         false otherwise
	 */
	public static boolean isWhitespace(char c) {
		int i = c;

		if ((i == 0) || Character.isWhitespace(c)) {
			return true;
		}

		return false;
	}

	/**
	 * Returns true if the string is an XML document. The only
	 * requirement is that it contain either the xml start tag "".
	 *
	 * @param  s the string to check
	 * @return true if the string is an XML document;
	 *         false otherwise
	 */
	public static boolean isXml(String s) {
		if (isNull(s)) {
			return false;
		}
		else if (s.startsWith(_XML_BEGIN) || s.startsWith(_XML_EMPTY)) {
			return true;
		}

		return false;
	}

	private static final String[] _BOOLEANS = {"false", "on", "off", "true"};

	private static final int _CHAR_LOWER_CASE_BEGIN = 97;

	private static final int _CHAR_LOWER_CASE_END = 122;

	private static final int _CHAR_UPPER_CASE_BEGIN = 65;

	private static final int _CHAR_UPPER_CASE_END = 90;

	private static final int _DIGIT_BEGIN = 48;

	private static final int _DIGIT_END = 57;

	private static final char[] _EMAIL_ADDRESS_SPECIAL_CHAR = {
		'.', '!', '#', '$', '%', '&', '\'', '*', '+', '-', '/', '=', '?', '^',
		'_', '`', '{', '|', '}', '~'
	};

	private static final String[] _JAVA_KEYWORDS = {
		"abstract", "assert", "boolean", "break", "byte", "case", "catch",
		"char", "class", "const", "continue", "default", "do", "double", "else",
		"enum", "extends", "false", "final", "finally", "float", "for", "goto",
		"if", "implements", "import", "instanceof", "int", "interface", "long",
		"native", "new", "null", "package", "private", "protected", "public",
		"return", "short", "static", "strictfp", "super", "switch",
		"synchronized", "this", "throw", "throws", "transient", "true", "try",
		"void", "volatile", "while"
	};

	private static final String _VARIABLE_TERM_BEGIN = "[$";

	private static final String _VARIABLE_TERM_END = "$]";

	private static final String _XML_BEGIN = "";

	private static final Pattern _emailAddressPattern = Pattern.compile(
		"[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@" +
			"(?:\\w(?:[\\w-]*\\w)?\\.)*\\w(?:[\\w-]*\\w)?");
	private static final Pattern _ipv4AddressPattern;
	private static final Pattern _ipv6AddressPattern;
	private static final Pattern _variableNamePattern = Pattern.compile(
		"[_a-zA-Z]+[_a-zA-Z0-9]*");

	static {
		StringBundler sb = new StringBundler(6);

		sb.append("^");
		sb.append("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.");
		sb.append("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.");
		sb.append("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.");
		sb.append("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
		sb.append("$");

		_ipv4AddressPattern = Pattern.compile(sb.toString());

		sb = new StringBundler(28);

		sb.append("^");
		sb.append("\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|");
		sb.append("((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:");
		sb.append("((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|");
		sb.append("((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]");
		sb.append("?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|");
		sb.append("((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|");
		sb.append("[1-9]?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|");
		sb.append("((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|");
		sb.append("[1-9]?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|");
		sb.append("(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|");
		sb.append("((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|");
		sb.append("[1-9]?\\d)");
		sb.append("(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|");
		sb.append("(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:");
		sb.append("((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.");
		sb.append("(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*");
		sb.append("$");

		_ipv6AddressPattern = Pattern.compile(sb.toString());
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy