jp.co.ctc_g.jse.core.validation.util.Validators.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.ctc_g.jse.core.validation.util.Validators.java

Source

/*
 * 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;
    }
}