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