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.routines;
018
019import java.text.Format;
020import java.util.Locale;
021
022/**
023 * <p><b>Integer Validation</b> and Conversion routines (<code>java.lang.Integer</code>).</p>
024 *
025 * <p>This validator provides a number of methods for
026 *    validating/converting a <code>String</code> value to
027 *    a <code>Integer</code> using <code>java.text.NumberFormat</code>
028 *    to parse either:</p>
029 *    <ul>
030 *       <li>using the default format for the default <code>Locale</code></li>
031 *       <li>using a specified pattern with the default <code>Locale</code></li>
032 *       <li>using the default format for a specified <code>Locale</code></li>
033 *       <li>using a specified pattern with a specified <code>Locale</code></li>
034 *    </ul>
035 *
036 * <p>Use one of the <code>isValid()</code> methods to just validate or
037 *    one of the <code>validate()</code> methods to validate and receive a
038 *    <i>converted</i> <code>Integer</code> value.</p>
039 *
040 * <p>Once a value has been sucessfully converted the following
041 *    methods can be used to perform minimum, maximum and range checks:</p>
042 *    <ul>
043 *       <li><code>minValue()</code> checks whether the value is greater
044 *           than or equal to a specified minimum.</li>
045 *       <li><code>maxValue()</code> checks whether the value is less
046 *           than or equal to a specified maximum.</li>
047 *       <li><code>isInRange()</code> checks whether the value is within
048 *           a specified range of values.</li>
049 *    </ul>
050 *
051 * <p>So that the same mechanism used for parsing an <i>input</i> value
052 *    for validation can be used to format <i>output</i>, corresponding
053 *    <code>format()</code> methods are also provided. That is you can
054 *    format either:</p>
055 *    <ul>
056 *       <li>using the default format for the default <code>Locale</code></li>
057 *       <li>using a specified pattern with the default <code>Locale</code></li>
058 *       <li>using the default format for a specified <code>Locale</code></li>
059 *       <li>using a specified pattern with a specified <code>Locale</code></li>
060 *    </ul>
061 *
062 * @version $Revision: 1227719 $ $Date: 2012-01-05 18:45:51 +0100 (Do, 05 Jan 2012) $
063 * @since Validator 1.3.0
064 */
065public class IntegerValidator extends AbstractNumberValidator {
066
067    private static final long serialVersionUID = 422081746310306596L;
068
069    private static final IntegerValidator VALIDATOR = new IntegerValidator();
070
071    /**
072     * Return a singleton instance of this validator.
073     * @return A singleton instance of the IntegerValidator.
074     */
075    public static IntegerValidator getInstance() {
076        return VALIDATOR;
077    }
078
079    /**
080     * Construct a <i>strict</i> instance.
081     */
082    public IntegerValidator() {
083        this(true, STANDARD_FORMAT);
084    }
085
086    /**
087     * <p>Construct an instance with the specified strict setting
088     *    and format type.</p>
089     *
090     * <p>The <code>formatType</code> specified what type of
091     *    <code>NumberFormat</code> is created - valid types
092     *    are:</p>
093     *    <ul>
094     *       <li>AbstractNumberValidator.STANDARD_FORMAT -to create
095     *           <i>standard</i> number formats (the default).</li>
096     *       <li>AbstractNumberValidator.CURRENCY_FORMAT -to create
097     *           <i>currency</i> number formats.</li>
098     *       <li>AbstractNumberValidator.PERCENT_FORMAT -to create
099     *           <i>percent</i> number formats (the default).</li>
100     *    </ul>
101     *
102     * @param strict <code>true</code> if strict
103     *        <code>Format</code> parsing should be used.
104     * @param formatType The <code>NumberFormat</code> type to
105     *        create for validation, default is STANDARD_FORMAT.
106     */
107    public IntegerValidator(boolean strict, int formatType) {
108        super(strict, formatType, false);
109    }
110
111    /**
112     * <p>Validate/convert an <code>Integer</code> using the default
113     *    <code>Locale</code>.
114     *
115     * @param value The value validation is being performed on.
116     * @return The parsed <code>Integer</code> if valid or <code>null</code>
117     *  if invalid.
118     */
119    public Integer validate(String value) {
120        return (Integer)parse(value, (String)null, (Locale)null);
121    }
122
123    /**
124     * <p>Validate/convert an <code>Integer</code> using the
125     *    specified <i>pattern</i>.
126     *
127     * @param value The value validation is being performed on.
128     * @param pattern The pattern used to validate the value against.
129     * @return The parsed <code>Integer</code> if valid or <code>null</code> if invalid.
130     */
131    public Integer validate(String value, String pattern) {
132        return (Integer)parse(value, pattern, (Locale)null);
133    }
134
135    /**
136     * <p>Validate/convert an <code>Integer</code> using the
137     *    specified <code>Locale</code>.
138     *
139     * @param value The value validation is being performed on.
140     * @param locale The locale to use for the number format, system default if null.
141     * @return The parsed <code>Integer</code> if valid or <code>null</code> if invalid.
142     */
143    public Integer validate(String value, Locale locale) {
144        return (Integer)parse(value, (String)null, locale);
145    }
146
147    /**
148     * <p>Validate/convert a <code>Integer</code> using the
149     *    specified pattern and/ or <code>Locale</code>.
150     *
151     * @param value The value validation is being performed on.
152     * @param pattern The pattern used to validate the value against, or the
153     *        default for the <code>Locale</code> if <code>null</code>.
154     * @param locale The locale to use for the date format, system default if null.
155     * @return The parsed <code>Integer</code> if valid or <code>null</code> if invalid.
156     */
157    public Integer validate(String value, String pattern, Locale locale) {
158        return (Integer)parse(value, pattern, locale);
159    }
160
161    /**
162     * Check if the value is within a specified range.
163     *
164     * @param value The <code>Number</code> value to check.
165     * @param min The minimum value of the range.
166     * @param max The maximum value of the range.
167     * @return <code>true</code> if the value is within the
168     *         specified range.
169     */
170    public boolean isInRange(int value, int min, int max) {
171        return (value >= min && value <= max);
172    }
173
174    /**
175     * Check if the value is within a specified range.
176     *
177     * @param value The <code>Number</code> value to check.
178     * @param min The minimum value of the range.
179     * @param max The maximum value of the range.
180     * @return <code>true</code> if the value is within the
181     *         specified range.
182     */
183    public boolean isInRange(Integer value, int min, int max) {
184        return isInRange(value.intValue(), min, max);
185    }
186
187    /**
188     * Check if the value is greater than or equal to a minimum.
189     *
190     * @param value The value validation is being performed on.
191     * @param min The minimum value.
192     * @return <code>true</code> if the value is greater than
193     *         or equal to the minimum.
194     */
195    public boolean minValue(int value, int min) {
196        return (value >= min);
197    }
198
199    /**
200     * Check if the value is greater than or equal to a minimum.
201     *
202     * @param value The value validation is being performed on.
203     * @param min The minimum value.
204     * @return <code>true</code> if the value is greater than
205     *         or equal to the minimum.
206     */
207    public boolean minValue(Integer value, int min) {
208        return minValue(value.intValue(), min);
209    }
210
211    /**
212     * Check if the value is less than or equal to a maximum.
213     *
214     * @param value The value validation is being performed on.
215     * @param max The maximum value.
216     * @return <code>true</code> if the value is less than
217     *         or equal to the maximum.
218     */
219    public boolean maxValue(int value, int max) {
220        return (value <= max);
221    }
222
223    /**
224     * Check if the value is less than or equal to a maximum.
225     *
226     * @param value The value validation is being performed on.
227     * @param max The maximum value.
228     * @return <code>true</code> if the value is less than
229     *         or equal to the maximum.
230     */
231    public boolean maxValue(Integer value, int max) {
232        return maxValue(value.intValue(), max);
233    }
234
235    /**
236     * <p>Perform further validation and convert the <code>Number</code> to
237     * an <code>Integer</code>.</p>
238     *
239     * @param value The parsed <code>Number</code> object created.
240     * @param formatter The Format used to parse the value with.
241     * @return The parsed <code>Number</code> converted to an
242     *   <code>Integer</code> if valid or <code>null</code> if invalid.
243     */
244    protected Object processParsedValue(Object value, Format formatter) {
245
246        long longValue = ((Number)value).longValue();
247
248        if (longValue < Integer.MIN_VALUE ||
249            longValue > Integer.MAX_VALUE) {
250            return null;
251        } else {
252            return new Integer((int)longValue);
253        }
254    }
255}