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     *
084     * @param value The value validation is being performed on.
085     * @return true if the value is valid Credit Card Number.
086     */
087    public static boolean isCreditCard(final String value) {
088        return Constants.CREDIT_CARD_VALIDATOR.isValid(value);
089    }
090
091    /**
092     * <p>Checks if the field is a valid date.  The {@link Locale} is
093     * used with {@link DateFormat}.  The setLenient method
094     * is set to {@code false} for all.</p>
095     *
096     * @param value The value validation is being performed on.
097     * @param locale The locale to use for the date format, defaults to the
098     * system default if null.
099     * @return true if the value can be converted to a Date.
100     */
101    public static boolean isDate(final String value, final Locale locale) {
102        return DateValidator.getInstance().isValid(value, locale);
103    }
104
105    /**
106     * <p>Checks if the field is a valid date.  The pattern is used with
107     * {@link SimpleDateFormat}.  If strict is true, then the
108     * length will be checked so '2/12/1999' will not pass validation with
109     * the format 'MM/dd/yyyy' because the month isn't two digits.
110     * The setLenient method is set to {@code false} for all.</p>
111     *
112     * @param value The value validation is being performed on.
113     * @param datePattern The pattern passed to {@link SimpleDateFormat}.
114     * @param strict Whether or not to have an exact match of the datePattern.
115     * @return true if the value can be converted to a Date.
116     */
117    public static boolean isDate(final String value, final String datePattern, final boolean strict) {
118        // TODO method isValid() not yet supported in routines version
119        return org.apache.commons.validator.DateValidator.getInstance().isValid(value, datePattern, strict);
120    }
121
122    /**
123     * <p>Checks if the value can safely be converted to a double primitive.</p>
124     *
125     * @param value The value validation is being performed on.
126     * @return true if the value can be converted to a Double.
127     */
128    public static boolean isDouble(final String value) {
129        return GenericTypeValidator.formatDouble(value) != null;
130    }
131
132    /**
133     * <p>Checks if a field has a valid e-mail address.</p>
134     *
135     * @param value The value validation is being performed on.
136     * @return true if the value is valid Email Address.
137     */
138    public static boolean isEmail(final String value) {
139        return EmailValidator.getInstance().isValid(value);
140    }
141
142    /**
143     * <p>Checks if the value can safely be converted to a float primitive.</p>
144     *
145     * @param value The value validation is being performed on.
146     * @return true if the value can be converted to a Float.
147     */
148    public static boolean isFloat(final String value) {
149        return GenericTypeValidator.formatFloat(value) != null;
150    }
151
152    /**
153    * <p>Checks if a value is within a range (min &amp; max specified
154    * in the vars attribute).</p>
155    *
156    * @param value The value validation is being performed on.
157    * @param min The minimum value of the range.
158    * @param max The maximum value of the range.
159     * @return true if the value is in the specified range.
160    */
161    public static boolean isInRange(final byte value, final byte min, final byte max) {
162        return value >= min && value <= max;
163    }
164
165    /**
166     * <p>Checks if a value is within a range (min &amp; max specified
167     * in the vars attribute).</p>
168     *
169     * @param value The value validation is being performed on.
170     * @param min The minimum value of the range.
171     * @param max The maximum value of the range.
172     * @return true if the value is in the specified range.
173     */
174    public static boolean isInRange(final double value, final double min, final double max) {
175        return value >= min && value <= max;
176    }
177
178    /**
179     * <p>Checks if a value is within a range (min &amp; max specified
180     * in the vars attribute).</p>
181     *
182     * @param value The value validation is being performed on.
183     * @param min The minimum value of the range.
184     * @param max The maximum value of the range.
185     * @return true if the value is in the specified range.
186     */
187    public static boolean isInRange(final float value, final float min, final float max) {
188        return value >= min && value <= max;
189    }
190
191    /**
192     * <p>Checks if a value is within a range (min &amp; max specified
193     * in the vars attribute).</p>
194     *
195     * @param value The value validation is being performed on.
196     * @param min The minimum value of the range.
197     * @param max The maximum value of the range.
198     * @return true if the value is in the specified range.
199     */
200    public static boolean isInRange(final int value, final int min, final int max) {
201        return value >= min && value <= max;
202    }
203
204    /**
205     * <p>Checks if a value is within a range (min &amp; max specified
206     * in the vars attribute).</p>
207     *
208     * @param value The value validation is being performed on.
209     * @param min The minimum value of the range.
210     * @param max The maximum value of the range.
211     * @return true if the value is in the specified range.
212     */
213    public static boolean isInRange(final long value, final long min, final long max) {
214        return value >= min && value <= max;
215    }
216
217    /**
218     * <p>Checks if a value is within a range (min &amp; max specified
219     * in the vars attribute).</p>
220     *
221     * @param value The value validation is being performed on.
222     * @param min The minimum value of the range.
223     * @param max The maximum value of the range.
224     * @return true if the value is in the specified range.
225     */
226    public static boolean isInRange(final short value, final short min, final short max) {
227        return value >= min && value <= max;
228    }
229
230    /**
231     * <p>Checks if the value can safely be converted to an int primitive.</p>
232     *
233     * @param value The value validation is being performed on.
234     * @return true if the value can be converted to an Integer.
235     */
236    public static boolean isInt(final String value) {
237        return GenericTypeValidator.formatInt(value) != null;
238    }
239
240    /**
241     * <p>Checks if the value can safely be converted to a long primitive.</p>
242     *
243     * @param value The value validation is being performed on.
244     * @return true if the value can be converted to a Long.
245     */
246    public static boolean isLong(final String value) {
247        return GenericTypeValidator.formatLong(value) != null;
248    }
249
250    /**
251     * <p>Checks if the value can safely be converted to a short primitive.</p>
252     *
253     * @param value The value validation is being performed on.
254     * @return true if the value can be converted to a Short.
255     */
256    public static boolean isShort(final String value) {
257        return GenericTypeValidator.formatShort(value) != null;
258    }
259
260    /**
261     * <p>Checks if a field is a valid URL address.</p>
262     * If you need to modify what is considered valid then
263     * consider using the UrlValidator directly.
264     *
265     * @param value The value validation is being performed on.
266     * @return true if the value is valid Url.
267     */
268    public static boolean isUrl(final String value) {
269        return Constants.URL_VALIDATOR.isValid(value);
270    }
271
272    /**
273     * <p>Checks if the value matches the regular expression.</p>
274     *
275     * @param value The value validation is being performed on.
276     * @param regexp The regular expression.
277     * @return true if matches the regular expression.
278     */
279    public static boolean matchRegexp(final String value, final String regexp) {
280        if (regexp == null || regexp.isEmpty()) {
281            return false;
282        }
283
284        return Pattern.matches(regexp, value);
285    }
286
287    /**
288     * <p>Checks if the value's length is less than or equal to the max.</p>
289     *
290     * @param value The value validation is being performed on.
291     * @param max The maximum length.
292     * @return true if the value's length is less than the specified maximum.
293     */
294    public static boolean maxLength(final String value, final int max) {
295        return value.length() <= max;
296    }
297
298    /**
299     * <p>Checks if the value's adjusted 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     * @param lineEndLength The length to use for line endings.
304     * @return true if the value's length is less than the specified maximum.
305     */
306    public static boolean maxLength(final String value, final int max, final int lineEndLength) {
307        final int adjustAmount = adjustForLineEnding(value, lineEndLength);
308        return value.length() + adjustAmount <= max;
309    }
310
311    /**
312     * <p>Checks if the value is less than or equal to the max.</p>
313     *
314     * @param value The value validation is being performed on.
315     * @param max The maximum numeric value.
316     * @return true if the value is &lt;= the specified maximum.
317     */
318    public static boolean maxValue(final double value, final double max) {
319        return value <= 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 float value, final float 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 int value, final int max) {
341        return value <= max;
342    }
343
344    // See https://issues.apache.org/bugzilla/show_bug.cgi?id=29015 regarding the "value" methods.
345
346    /**
347     * <p>Checks if the value is less than or equal to the max.</p>
348     *
349     * @param value The value validation is being performed on.
350     * @param max The maximum numeric value.
351     * @return true if the value is &lt;= the specified maximum.
352     */
353    public static boolean maxValue(final long value, final long max) {
354        return value <= max;
355    }
356
357    /**
358     * <p>Checks if the value's length is greater than or equal to the min.</p>
359     *
360     * @param value The value validation is being performed on.
361     * @param min The minimum length.
362     * @return true if the value's length is more than the specified minimum.
363     */
364    public static boolean minLength(final String value, final int min) {
365        return value.length() >= min;
366    }
367
368    /**
369     * <p>Checks if the value's adjusted 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     * @param lineEndLength The length to use for line endings.
374     * @return true if the value's length is more than the specified minimum.
375     */
376    public static boolean minLength(final String value, final int min, final int lineEndLength) {
377        final int adjustAmount = adjustForLineEnding(value, lineEndLength);
378        return value.length() + adjustAmount >= min;
379    }
380
381    /**
382     * <p>Checks if the value is greater than or equal to the min.</p>
383     *
384     * @param value The value validation is being performed on.
385     * @param min The minimum numeric value.
386     * @return true if the value is &gt;= the specified minimum.
387     */
388    public static boolean minValue(final double value, final double min) {
389        return value >= 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 float value, final float 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 int value, final int 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 long value, final long min) {
422        return value >= min;
423    }
424
425    /**
426     * Constructs a new instance.
427     *
428     * @deprecated Will be private in the next major version.
429     */
430    @Deprecated
431    public GenericValidator() {
432        // empty
433    }
434
435}