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