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}