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