    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.validator;
    018
    019import java.io.Serializable;
    020import java.text.DateFormat;
    021import java.text.SimpleDateFormat;
    022import java.util.Locale;
    023import java.util.regex.Pattern;
    024
    025import org.apache.commons.validator.routines.CreditCardValidator;
    026import org.apache.commons.validator.routines.DateValidator;
    027import org.apache.commons.validator.routines.EmailValidator;
    028import org.apache.commons.validator.routines.UrlValidator;
    029
    030/**
    031 * This class contains basic methods for performing validations.
    032 */
    033public class GenericValidator implements Serializable {
    034
    035    private static final long serialVersionUID = -7212095066891517618L;
    036
    037    /**
    038     * UrlValidator used in wrapper method.
    039     */
    040    private static final UrlValidator URL_VALIDATOR = new UrlValidator();
    041
    042    /**
    043     * CreditCardValidator used in wrapper method.
    044     */
    045    private static final CreditCardValidator CREDIT_CARD_VALIDATOR = new CreditCardValidator();
    046
    047    /**
    048     * Calculate an adjustment amount for line endings.
    049     *
    050     * See Bug 37962 for the rationale behind this.
    051     *
    052     * @param value The value validation is being performed on.
    053     * @param lineEndLength The length to use for line endings.
    054     * @return the adjustment amount.
    055     */
    056    private static int adjustForLineEnding(final String value, final int lineEndLength) {
    057        int nCount = 0;
    058        int rCount = 0;
    059        for (int i = 0; i < value.length(); i++) {
    060            if (value.charAt(i) == '\n') {
    061                nCount++;
    062            }
    063            if (value.charAt(i) == '\r') {
    064                rCount++;
    065            }
    066        }
    067        final int rnCount = rCount + nCount;
    068        return nCount * lineEndLength - rnCount;
    069    }
    070
    071    /**
    072     * <p>Checks if the field isn't null and length of the field is greater
    073     * than zero not including whitespace.</p>
    074     *
    075     * @param value The value validation is being performed on.
    076     * @return true if blank or null.
    077     */
    078    public static boolean isBlankOrNull(final String value) {
    079        // Don't trim is already empty.
    080        return value == null || value.isEmpty() || value.trim().isEmpty();
    081    }
    082
    083    /**
    084     * <p>Checks if the value can safely be converted to a byte primitive.</p>
    085     *
    086     * @param value The value validation is being performed on.
    087     * @return true if the value can be converted to a Byte.
    088     */
    089    public static boolean isByte(final String value) {
    090        return GenericTypeValidator.formatByte(value) != null;
    091    }
    092
    093    /**
    094     * Checks if the field is a valid credit card number.
    095     * @param value The value validation is being performed on.
    096     * @return true if the value is valid Credit Card Number.
    097     */
    098    public static boolean isCreditCard(final String value) {
    099        return CREDIT_CARD_VALIDATOR.isValid(value);
    100    }
    101
    102    /**
    103     * <p>Checks if the field is a valid date.  The {@link Locale} is
    104     * used with {@link DateFormat}.  The setLenient method
    105     * is set to {@code false} for all.</p>
    106     *
    107     * @param value The value validation is being performed on.
    108     * @param locale The locale to use for the date format, defaults to the
    109     * system default if null.
    110     * @return true if the value can be converted to a Date.
    111     */
    112    public static boolean isDate(final String value, final Locale locale) {
    113        return DateValidator.getInstance().isValid(value, locale);
    114    }
    115
    116    /**
    117     * <p>Checks if the field is a valid date.  The pattern is used with
    118     * {@link SimpleDateFormat}.  If strict is true, then the
    119     * length will be checked so '2/12/1999' will not pass validation with
    120     * the format 'MM/dd/yyyy' because the month isn't two digits.
    121     * The setLenient method is set to {@code false} for all.</p>
    122     *
    123     * @param value The value validation is being performed on.
    124     * @param datePattern The pattern passed to {@link SimpleDateFormat}.
    125     * @param strict Whether or not to have an exact match of the datePattern.
    126     * @return true if the value can be converted to a Date.
    127     */
    128    public static boolean isDate(final String value, final String datePattern, final boolean strict) {
    129        // TODO method isValid() not yet supported in routines version
    130        return org.apache.commons.validator.DateValidator.getInstance().isValid(value, datePattern, strict);
    131    }
    132
    133    /**
    134     * <p>Checks if the value can safely be converted to a double primitive.</p>
    135     *
    136     * @param value The value validation is being performed on.
    137     * @return true if the value can be converted to a Double.
    138     */
    139    public static boolean isDouble(final String value) {
    140        return GenericTypeValidator.formatDouble(value) != null;
    141    }
    142
    143    /**
    144     * <p>Checks if a field has a valid e-mail address.</p>
    145     *
    146     * @param value The value validation is being performed on.
    147     * @return true if the value is valid Email Address.
    148     */
    149    public static boolean isEmail(final String value) {
    150        return EmailValidator.getInstance().isValid(value);
    151    }
    152
    153    /**
    154     * <p>Checks if the value can safely be converted to a float primitive.</p>
    155     *
    156     * @param value The value validation is being performed on.
    157     * @return true if the value can be converted to a Float.
    158     */
    159    public static boolean isFloat(final String value) {
    160        return GenericTypeValidator.formatFloat(value) != null;
    161    }
    162
    163    /**
    164    * <p>Checks if a value is within a range (min &amp; max specified
    165    * in the vars attribute).</p>
    166    *
    167    * @param value The value validation is being performed on.
    168    * @param min The minimum value of the range.
    169    * @param max The maximum value of the range.
    170     * @return true if the value is in the specified range.
    171    */
    172    public static boolean isInRange(final byte value, final byte min, final byte max) {
    173        return value >= min && value <= max;
    174    }
    175
    176    /**
    177     * <p>Checks if a value is within a range (min &amp; max specified
    178     * in the vars attribute).</p>
    179     *
    180     * @param value The value validation is being performed on.
    181     * @param min The minimum value of the range.
    182     * @param max The maximum value of the range.
    183     * @return true if the value is in the specified range.
    184     */
    185    public static boolean isInRange(final double value, final double min, final double max) {
    186        return value >= min && value <= max;
    187    }
    188
    189    /**
    190     * <p>Checks if a value is within a range (min &amp; max specified
    191     * in the vars attribute).</p>
    192     *
    193     * @param value The value validation is being performed on.
    194     * @param min The minimum value of the range.
    195     * @param max The maximum value of the range.
    196     * @return true if the value is in the specified range.
    197     */
    198    public static boolean isInRange(final float value, final float min, final float max) {
    199        return value >= min && value <= max;
    200    }
    201
    202    /**
    203     * <p>Checks if a value is within a range (min &amp; max specified
    204     * in the vars attribute).</p>
    205     *
    206     * @param value The value validation is being performed on.
    207     * @param min The minimum value of the range.
    208     * @param max The maximum value of the range.
    209     * @return true if the value is in the specified range.
    210     */
    211    public static boolean isInRange(final int value, final int min, final int max) {
    212        return value >= min && value <= max;
    213    }
    214
    215    /**
    216     * <p>Checks if a value is within a range (min &amp; max specified
    217     * in the vars attribute).</p>
    218     *
    219     * @param value The value validation is being performed on.
    220     * @param min The minimum value of the range.
    221     * @param max The maximum value of the range.
    222     * @return true if the value is in the specified range.
    223     */
    224    public static boolean isInRange(final long value, final long min, final long max) {
    225        return value >= min && value <= max;
    226    }
    227
    228    /**
    229     * <p>Checks if a value is within a range (min &amp; max specified
    230     * in the vars attribute).</p>
    231     *
    232     * @param value The value validation is being performed on.
    233     * @param min The minimum value of the range.
    234     * @param max The maximum value of the range.
    235     * @return true if the value is in the specified range.
    236     */
    237    public static boolean isInRange(final short value, final short min, final short max) {
    238        return value >= min && value <= max;
    239    }
    240
    241    /**
    242     * <p>Checks if the value can safely be converted to an int primitive.</p>
    243     *
    244     * @param value The value validation is being performed on.
    245     * @return true if the value can be converted to an Integer.
    246     */
    247    public static boolean isInt(final String value) {
    248        return GenericTypeValidator.formatInt(value) != null;
    249    }
    250
    251    /**
    252     * <p>Checks if the value can safely be converted to a long primitive.</p>
    253     *
    254     * @param value The value validation is being performed on.
    255     * @return true if the value can be converted to a Long.
    256     */
    257    public static boolean isLong(final String value) {
    258        return GenericTypeValidator.formatLong(value) != null;
    259    }
    260
    261    /**
    262     * <p>Checks if the value can safely be converted to a short primitive.</p>
    263     *
    264     * @param value The value validation is being performed on.
    265     * @return true if the value can be converted to a Short.
    266     */
    267    public static boolean isShort(final String value) {
    268        return GenericTypeValidator.formatShort(value) != null;
    269    }
    270
    271    /**
    272     * <p>Checks if a field is a valid URL address.</p>
    273     * If you need to modify what is considered valid then
    274     * consider using the UrlValidator directly.
    275     *
    276     * @param value The value validation is being performed on.
    277     * @return true if the value is valid Url.
    278     */
    279    public static boolean isUrl(final String value) {
    280        return URL_VALIDATOR.isValid(value);
    281    }
    282
    283    /**
    284     * <p>Checks if the value matches the regular expression.</p>
    285     *
    286     * @param value The value validation is being performed on.
    287     * @param regexp The regular expression.
    288     * @return true if matches the regular expression.
    289     */
    290    public static boolean matchRegexp(final String value, final String regexp) {
    291        if (regexp == null || regexp.isEmpty()) {
    292            return false;
    293        }
    294
    295        return Pattern.matches(regexp, value);
    296    }
    297
    298    /**
    299     * <p>Checks if the value's length is less than or equal to the max.</p>
    300     *
    301     * @param value The value validation is being performed on.
    302     * @param max The maximum length.
    303     * @return true if the value's length is less than the specified maximum.
    304     */
    305    public static boolean maxLength(final String value, final int max) {
    306        return value.length() <= max;
    307    }
    308
    309    /**
    310     * <p>Checks if the value's adjusted length is less than or equal to the max.</p>
    311     *
    312     * @param value The value validation is being performed on.
    313     * @param max The maximum length.
    314     * @param lineEndLength The length to use for line endings.
    315     * @return true if the value's length is less than the specified maximum.
    316     */
    317    public static boolean maxLength(final String value, final int max, final int lineEndLength) {
    318        final int adjustAmount = adjustForLineEnding(value, lineEndLength);
    319        return value.length() + adjustAmount <= max;
    320    }
    321
    322    /**
    323     * <p>Checks if the value is less than or equal to the max.</p>
    324     *
    325     * @param value The value validation is being performed on.
    326     * @param max The maximum numeric value.
    327     * @return true if the value is &lt;= the specified maximum.
    328     */
    329    public static boolean maxValue(final double value, final double max) {
    330        return value <= max;
    331    }
    332
    333    /**
    334     * <p>Checks if the value is less than or equal to the max.</p>
    335     *
    336     * @param value The value validation is being performed on.
    337     * @param max The maximum numeric value.
    338     * @return true if the value is &lt;= the specified maximum.
    339     */
    340    public static boolean maxValue(final float value, final float max) {
    341        return value <= max;
    342    }
    343
    344    /**
    345     * <p>Checks if the value is less than or equal to the max.</p>
    346     *
    347     * @param value The value validation is being performed on.
    348     * @param max The maximum numeric value.
    349     * @return true if the value is &lt;= the specified maximum.
    350     */
    351    public static boolean maxValue(final int value, final int max) {
    352        return value <= max;
    353    }
    354
    355    // See https://issues.apache.org/bugzilla/show_bug.cgi?id=29015 WRT the "value" methods
    356
    357    /**
    358     * <p>Checks if the value is less than or equal to the max.</p>
    359     *
    360     * @param value The value validation is being performed on.
    361     * @param max The maximum numeric value.
    362     * @return true if the value is &lt;= the specified maximum.
    363     */
    364    public static boolean maxValue(final long value, final long max) {
    365        return value <= max;
    366    }
    367
    368    /**
    369     * <p>Checks if the value's length is greater than or equal to the min.</p>
    370     *
    371     * @param value The value validation is being performed on.
    372     * @param min The minimum length.
    373     * @return true if the value's length is more than the specified minimum.
    374     */
    375    public static boolean minLength(final String value, final int min) {
    376        return value.length() >= min;
    377    }
    378
    379    /**
    380     * <p>Checks if the value's adjusted length is greater than or equal to the min.</p>
    381     *
    382     * @param value The value validation is being performed on.
    383     * @param min The minimum length.
    384     * @param lineEndLength The length to use for line endings.
    385     * @return true if the value's length is more than the specified minimum.
    386     */
    387    public static boolean minLength(final String value, final int min, final int lineEndLength) {
    388        final int adjustAmount = adjustForLineEnding(value, lineEndLength);
    389        return value.length() + adjustAmount >= min;
    390    }
    391
    392    /**
    393     * <p>Checks if the value is greater than or equal to the min.</p>
    394     *
    395     * @param value The value validation is being performed on.
    396     * @param min The minimum numeric value.
    397     * @return true if the value is &gt;= the specified minimum.
    398     */
    399    public static boolean minValue(final double value, final double min) {
    400        return value >= min;
    401    }
    402
    403    /**
    404     * <p>Checks if the value is greater than or equal to the min.</p>
    405     *
    406     * @param value The value validation is being performed on.
    407     * @param min The minimum numeric value.
    408     * @return true if the value is &gt;= the specified minimum.
    409     */
    410    public static boolean minValue(final float value, final float min) {
    411        return value >= min;
    412    }
    413
    414    /**
    415     * <p>Checks if the value is greater than or equal to the min.</p>
    416     *
    417     * @param value The value validation is being performed on.
    418     * @param min The minimum numeric value.
    419     * @return true if the value is &gt;= the specified minimum.
    420     */
    421    public static boolean minValue(final int value, final int min) {
    422        return value >= min;
    423    }
    424
    425    /**
    426     * <p>Checks if the value is greater than or equal to the min.</p>
    427     *
    428     * @param value The value validation is being performed on.
    429     * @param min The minimum numeric value.
    430     * @return true if the value is &gt;= the specified minimum.
    431     */
    432    public static boolean minValue(final long value, final long min) {
    433        return value >= min;
    434    }
    435
    436    /**
    437     * Constructs a new instance.
    438     *
    439     * @deprecated Will be private in the next major version.
    440     */
    441    @Deprecated
    442    public GenericValidator() {
    443        // empty
    444    }
    445
    446}