Java tutorial
/* * Copyright (c) 2013 ITOCHU Techno-Solutions Corporation. * * 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 jp.co.ctc_g.jse.core.validation.util; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.validator.GenericValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * ???????????? * </p> * @author ITOCHU Techno-Solutions Corporation. */ public final class Validators { private static final Logger L = LoggerFactory.getLogger(Validators.class); private static final String BLANK_REGEXP = "\\s"; private static final Pattern BLANK_ALL_PATTERN = Pattern.compile("^[" + BLANK_REGEXP + "]*$"); private static final Pattern BLANK_PATTERN = Pattern.compile("[" + BLANK_REGEXP + "]"); private static final Pattern ALPHABET_PATTERN = Pattern.compile("^\\p{Alpha}+$"); private static final Pattern ALPHAMERIC_PATTERN = Pattern.compile("^\\p{Alnum}+$"); private static final Pattern HALFWIDTH_KATAKANA_PATTERN = Pattern.compile("^[\uff66-\uff9f]+$"); private static final Pattern KATAKANA_PATTERN = Pattern.compile("^[\u30a1-\u30ed\u30ef\u30f2-\u30f4\u30fc]+$"); private static final Pattern HIRAGANA_PATTERN = Pattern.compile("^[\u3041-\u308d\u308f\u3092-\u3093\u30fc]+$"); private static final Pattern IPV4_PATTERN = Pattern.compile( "^((?:1(?:0\\d?|1\\d?|2\\d?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?)?|2(?:[6789]|5[0-5]?|0\\d?|1\\d?|2\\d?|3\\d?|4\\d?)?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?|0)\\." + "(?:1(?:0\\d?|1\\d?|2\\d?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?)?|2(?:[6789]|5[0-5]?|0\\d?|1\\d?|2\\d?|3\\d?|4\\d?)?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?|0)\\." + "(?:1(?:0\\d?|1\\d?|2\\d?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?)?|2(?:[6789]|5[0-5]?|0\\d?|1\\d?|2\\d?|3\\d?|4\\d?)?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?|0)\\." + "(?:1(?:0\\d?|1\\d?|2\\d?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?)?|2(?:[6789]|5[0-5]?|0\\d?|1\\d?|2\\d?|3\\d?|4\\d?)?|3\\d?|4\\d?|5\\d?|6\\d?|7\\d?|8\\d?|9\\d?|0))" + "(?:/([0-9]|[12]\\d|3[0-2]))?$"); private static final Pattern ZIP1_PATTERN = Pattern.compile( "^(?:1(?:5[012345678]|7[013456789]|9[012345678]|3[01234567]|1[0123456]|4[0123456]|2[01345]|0\\d|6\\d|8" + "\\d)|2(?:9[023456789]|0[12345678]|2[01234567]|6[01234567]|8[23456789]|1[0123456]|3\\d|4\\d|5\\d|7\\d" + ")|6(?:2[012345679]|0[01234567]|8[0123459]|1\\d|3\\d|4\\d|5\\d|6\\d|7\\d|9\\d)|5(?:4[012345679]|8[012" + "345679]|0\\d|1\\d|2\\d|3\\d|5\\d|6\\d|7\\d|9\\d)|7(?:2[012356789]|4[012345679]|0\\d|1\\d|3\\d|5\\d|6" + "\\d|7\\d|8\\d|9\\d)|4(?:9[012345678]|2[01245678]|0\\d|1\\d|3\\d|4\\d|5\\d|6\\d|7\\d|8\\d)|0(?:3[0134" + "56789]|0[1234567]|1\\d|2\\d|4\\d|5\\d|6\\d|7\\d|8\\d|9\\d)|9(?:0[01234567]|7[01234569]|1\\d|2\\d|3" + "\\d|4\\d|5\\d|6\\d|8\\d|9\\d)|3(?:0\\d|1\\d|2\\d|3\\d|4\\d|5\\d|6\\d|7\\d|8\\d|9\\d)|8(?:0\\d|1\\d|2" + "\\d|3\\d|4\\d|5\\d|6\\d|7\\d|8\\d|9\\d))$"); private static final Pattern ZIP2_PATTERN = Pattern.compile("^\\d{4}$"); private static final String WINDOWS31_J = "Windows-31J"; private Validators() { } /** * ????????????? * ???\t, \n, \x, 0B, \f, \r, ?, ?????? * @param suspect * @return ???????true */ public static boolean isBlank(CharSequence suspect) { return isEmpty(suspect) || BLANK_ALL_PATTERN.matcher(suspect).matches(); } /** * ??????????? * ???\t, \n, \x, 0B, \f, \r, ?, ?????? * @param suspect * @return ?????true */ public static boolean containBlank(CharSequence suspect) { return suspect == null || suspect.length() == 0 || BLANK_PATTERN.matcher(suspect).find(); } /** * ?????????? * ???<code>null</code>?????<code>0</code>?????? * @param suspect * @return ???true */ public static boolean isEmpty(CharSequence suspect) { return suspect == null || suspect.length() == 0; } /** * ???null??????? * @param suspect * @return null???true */ public static boolean isNull(Object suspect) { return suspect == null; } /** * ?????<code>^\\p{Alpha}+$</code>????????? * @param suspect * @return ???true */ public static boolean isAlphabet(CharSequence suspect) { return ALPHABET_PATTERN.matcher(suspect).matches(); } /** * ?????<code>^\\p{Alnum}+$</code>????????? * @param suspect * @return ???true */ public static boolean isAlphameric(CharSequence suspect) { return ALPHAMERIC_PATTERN.matcher(suspect).matches(); } /** * ?????<code>^[\uff66-\uff9f]+$</code>????????? * @param suspect * @return ???true */ public static boolean isHalfwidthKatakana(CharSequence suspect) { return HALFWIDTH_KATAKANA_PATTERN.matcher(suspect).matches(); } /** * ?????<code>^[\u30a1-\u30ed\u30ef\u30f2-\u30f4\u30fc]+$</code>????????? * @param suspect * @return ???true */ public static boolean isKatakana(CharSequence suspect) { return KATAKANA_PATTERN.matcher(suspect).matches(); } /** * ?????<code>^[\u3041-\u308d\u308f\u3092-\u3093\u30fc]+$</code>????????? * @param suspect * @return ???true */ public static boolean isHiragana(CharSequence suspect) { return HIRAGANA_PATTERN.matcher(suspect).matches(); } /** * ?????????????? * @param pattern * @param suspect * @return ???true */ public static boolean isMatches(Pattern pattern, CharSequence suspect) { return pattern.matcher(suspect).matches(); } /** * ???????????????? * @param regex ?? * @param suspect * @return ???true */ public static boolean isMatches(String regex, CharSequence suspect) { return Pattern.matches(regex, suspect); } /** * ?"Windows-31J"???????????????2?????????? * @param suspect * @return ???true */ public static boolean isZenkaku(CharSequence suspect) { try { byte[] sjis = suspect.toString().getBytes(WINDOWS31_J); return sjis.length == (suspect.length() * 2); } catch (UnsupportedEncodingException e) { return false; } } /** * <p> * ????????????????? * <pre> * <code> * // ??3??? * ^(?:1(?:5[012345678]|7[013456789]|9[012345678]|3[01234567]|1[0123456]|4[0123456]|2[01345]|0\d|6\d|8\d)|2(?:9[023456789]|0[12345678]|2[01234567]|6[01234567]|8[23456789]|1[0123456]|3\d|4\d|5\d|7\d)|6(?:2[012345679]|0[01234567]|8[0123459]|1\d|3\d|4\d|5\d|6\d|7\d|9\d)|5(?:4[012345679]|8[012345679]|0\d|1\d|2\d|3\d|5\d|6\d|7\d|9\d)|7(?:2[012356789]|4[012345679]|0\d|1\d|3\d|5\d|6\d|7\d|8\d|9\d)|4(?:9[012345678]|2[01245678]|0\d|1\d|3\d|4\d|5\d|6\d|7\d|8\d)|0(?:3[013456789]|0[1234567]|1\d|2\d|4\d|5\d|6\d|7\d|8\d|9\d)|9(?:0[01234567]|7[01234569]|1\d|2\d|3\d|4\d|5\d|6\d|8\d|9\d)|3(?:0\d|1\d|2\d|3\d|4\d|5\d|6\d|7\d|8\d|9\d)|8(?:0\d|1\d|2\d|3\d|4\d|5\d|6\d|7\d|8\d|9\d))$ * </code> * </pre> * <pre> * <code> * // ??4??? * ^\d{4}$ * </code> * </pre> * </p> * @param suspect * @param separator * @return ???true */ public static boolean isZipCode(CharSequence suspect, String separator) { String target = suspect.toString(); if (target.length() != (7 + separator.length())) { return false; } String zip1 = target.substring(0, 3); String sep = target.substring(3, 3 + separator.length()); String zip2 = target.substring(3 + separator.length(), target.length()); if (!ZIP1_PATTERN.matcher(zip1).matches()) { return false; } if (!separator.equals(sep)) { return false; } if (!ZIP2_PATTERN.matcher(zip2).matches()) { return false; } return true; } /** * <p> * ??????????????? * <pre> * <code> * ^( * (?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:[6789]|5[0-5]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?|0)\. * (?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:[6789]|5[0-5]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?|0)\. * (?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:[6789]|5[0-5]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?|0)\. * (?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:[6789]|5[0-5]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?|0)) * (?:/([0-9]|[12]\d|3[0-2]) * )?$ * </code> * </pre> * </p> * @param suspect * @return ???true */ public static Matcher isIPv4(CharSequence suspect) { return IPV4_PATTERN.matcher(suspect); } /** * ???IPv4????????? * @param suspect * @param only CIDR?IP * @return ???true */ public static boolean isIPv4(CharSequence suspect, String[] only) { Matcher m = isIPv4(suspect); if (!m.matches()) { return false; } String ipaddr = m.group(1); String cidr = m.group(2); if (cidr != null) { return false; } if (only.length == 0) { return true; } for (String network : only) { if (validateNetwork(ipaddr, network)) return true; } return false; } /** * ????'\u0020'?'\u007e'?????????? * @param suspect * @return ???true */ public static boolean isASCII(CharSequence suspect) { for (int i = 0; i < suspect.length(); i++) { char c = suspect.charAt(i); if (c < '\u0020' || c > '\u007e') { return false; } } return true; } /** * ?????????? * ??{@link GenericValidator#isDate(String, String, boolean)}????? * @param suspect * @param datePattern ?????{@link SimpleDateFormat}?/???? * @param strict ??????? ?<code>true</code>???????????????? * @return GenericValidator#isDate(String, String, boolean)?? */ public static boolean isDate(CharSequence suspect, String datePattern, boolean strict) { return GenericValidator.isDate(suspect.toString(), datePattern, strict); } /** * ?????????????????? * @param suspect * @param signed ?? * @param precision ? * @param scale ?? * @return ?????true */ public static boolean isDecimal(CharSequence suspect, boolean signed, int precision, int scale) { BigDecimal number = toBigDecimal(replaceDecimalValue(suspect)); if (number == null) return true; return isDecimal(number, signed, precision, scale); } /** * ?????????????????? * @param suspect * @param signed ?? * @param precision ? * @param scale ?? * @return ?????true */ public static boolean isDecimal(Number suspect, boolean signed, int precision, int scale) { BigDecimal number = toBigDecimal(suspect); return isDecimal(number, signed, precision, scale); } /** * ???????????? * ??{@link GenericValidator#isEmail(String)}????? * @param suspect * @return GenericValidator#isEmail(String)?? */ public static boolean isEmail(CharSequence suspect) { return GenericValidator.isEmail(suspect.toString()); } /** * ????????????????????? * ??{@link GenericValidator#minLength(String, int)}????? * @param suspect * @param size * @return GenericValidator#minLength(String, int)?? */ public static boolean minLength(CharSequence suspect, int size) { return GenericValidator.minLength(suspect.toString(), size); } /** * ????????????????????? * ??{@link GenericValidator#maxLength(String, int)}????? * @param suspect * @param size * @return GenericValidator#maxLength(String, int)?? */ public static boolean maxLength(CharSequence suspect, int size) { return GenericValidator.maxLength(suspect.toString(), size); } /** * ?????????????? * @param suspect * @param size * @param encoding * @return ???????true * @throws UnsupportedEncodingException */ public static boolean equalsByteLength(CharSequence suspect, int size, String encoding) throws UnsupportedEncodingException { return suspect.toString().getBytes(encoding).length == size; } /** * ????????????????????? * @param suspect * @param size * @param encoding * @return ??????????????true * @throws UnsupportedEncodingException */ public static boolean minByteLength(CharSequence suspect, int size, String encoding) throws UnsupportedEncodingException { return suspect.toString().getBytes(encoding).length >= size; } /** * ????????????????????? * @param suspect * @param size * @param encoding * @return ??????????????true * @throws UnsupportedEncodingException */ public static boolean maxByteLength(CharSequence suspect, int size, String encoding) throws UnsupportedEncodingException { return suspect.toString().getBytes(encoding).length <= size; } /** * ?????????????? * @param suspect * @param target ? * @return ???????false */ public static boolean greaterThan(Number suspect, BigDecimal target) { if (suspect == null) return true; BigDecimal number = toBigDecimal(suspect); return number.compareTo(target) >= 1; } /** * ????????????????????? * @param suspect * @param target ? * @return ???????????false */ public static boolean greaterThanEqualsTo(Number suspect, BigDecimal target) { if (suspect == null) return true; BigDecimal number = toBigDecimal(suspect); return number.compareTo(target) >= 0; } /** * ?????????????? * @param suspect * @param target ? * @return ???????false */ public static boolean lessThan(Number suspect, BigDecimal target) { if (suspect == null) return true; BigDecimal number = toBigDecimal(suspect); return number.compareTo(target) <= -1; } /** * ????????????????????? * @param suspect * @param target ? * @return ???????????false */ public static boolean lessThanEqualsTo(Number suspect, BigDecimal target) { if (suspect == null) return true; BigDecimal number = toBigDecimal(suspect); return number.compareTo(target) <= 0; } /** * ?????????????? * ??{@link java.lang.Object#equals(Object)}??? * @param suspect * @param target * @return ?????true */ public static boolean equalsTo(Object suspect, Object target) { if (suspect == null) return true; return suspect.equals(target); } /** * ????????? * @param suspect * @param target ? * @return ??????false */ public static boolean before(Date suspect, Date target) { if (suspect == null) return true; return suspect.before(target); } /** * ??????????????? * @param suspect * @param target ? * @return ??????????false */ public static boolean beforeEqualsTo(Date suspect, Date target) { if (suspect == null) return true; return suspect.before(target) || suspect.equals(target); } /** * ???????? * @param suspect * @param target ? * @return ?????false */ public static boolean after(Date suspect, Date target) { if (suspect == null) return true; return suspect.after(target); } /** * ?????????????? * @param suspect * @param target ? * @return ?????????false */ public static boolean afterEqualsTo(Date suspect, Date target) { if (suspect == null) return true; return suspect.after(target) || suspect.equals(target); } /** * BigDecimal????? * @param suspect Number * @return */ public static BigDecimal toBigDecimal(Number suspect) { if (suspect instanceof BigDecimal) { return (BigDecimal) suspect; } else { return new BigDecimal(suspect.toString()); } } /** * BigDecimal????? * @param suspect * @return */ public static BigDecimal toBigDecimal(CharSequence suspect) { return toBigDecimal(suspect, false); } /** * BigDecimal????? * @param suspect * @return */ public static BigDecimal toBigDecimal(Object suspect) { if (suspect instanceof BigDecimal) return (BigDecimal) suspect; return toBigDecimal(suspect.toString(), false); } /** * BigDecimal????? * @param suspect * @param throwing true???????? * @return */ public static BigDecimal toBigDecimal(CharSequence suspect, boolean throwing) { BigDecimal value = null; try { value = new BigDecimal(suspect.toString()); } catch (NumberFormatException e) { L.debug("??({})????????????????", new Object[] { suspect }); if (throwing) { throw e; } } return value; } /** * Date????? * @param suspect * @param pattern ?? * @return */ public static Date toDate(CharSequence suspect, String pattern) { return toDate(suspect, pattern, false); } /** * Date????? * @param suspect * @param pattern ?? * @return */ public static Date toDate(Object suspect, String pattern) { if (suspect instanceof Date) return (Date) suspect; return toDate(suspect.toString(), pattern, false); } /** * Date????? * @param suspect * @param pattern ?? * @param throwing true???????? * @return */ public static Date toDate(CharSequence suspect, String pattern, boolean throwing) { Date value = null; try { SimpleDateFormat sdf = new SimpleDateFormat(pattern); sdf.setLenient(false); value = sdf.parse(suspect.toString()); } catch (ParseException e) { L.debug("??({})????????????????", new Object[] { suspect }); if (throwing) { throw new IllegalArgumentException(e); } } return value; } protected static boolean isDecimal(BigDecimal number, boolean signed, int precision, int scale) { if ((!signed) && (number.signum() < 0)) { return false; } int expectedIntPrecision = precision - scale; int actualPrecision = number.precision(); int actualScale = number.scale(); int actualIntPrecision = actualPrecision - actualScale; return (expectedIntPrecision >= actualIntPrecision && scale >= actualScale); } private static boolean validateNetwork(String ipaddr, String network) { Matcher m = IPV4_PATTERN.matcher(network); if (!m.matches()) { return false; } String netaddr = m.group(1); String cidr = m.group(2); if (cidr == null) { return false; } int host = toInt(ipaddr); return (toInt(netaddr) <= host && host <= toBcast(netaddr, cidr)); } private static int toBcast(String addr, String cidr) { int a = toInt(addr); int c = Integer.parseInt(cidr); return a | ~(0xffffffff << (32 - c)); } private static int toInt(String addr) { String[] parts = addr.split("\\."); int i0 = Integer.parseInt(parts[0]); int i1 = Integer.parseInt(parts[1]); int i2 = Integer.parseInt(parts[2]); int i3 = Integer.parseInt(parts[3]); return (i0 << 24) + (i1 << 16) + (i2 << 8) + i3; } private static String replaceDecimalValue(CharSequence suspect) { String source = suspect.toString(); source = source.replace("?", "-"); source = source.replace("", ""); source = source.replace(",", ""); source = source.replace("", "."); return source; } }