View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.validator.routines;
18  
19  import java.io.Serializable;
20  import java.text.Format;
21  import java.text.ParsePosition;
22  import java.util.Locale;
23  
24  /**
25   * <p>Abstract class for <em>Format</em> based Validation.</p>
26   *
27   * <p>This is a <em>base</em> class for building Date and Number
28   *    Validators using format parsing.</p>
29   *
30   * @since 1.3.0
31   */
32  public abstract class AbstractFormatValidator implements Serializable {
33  
34      private static final long serialVersionUID = -4690687565200568258L;
35  
36      /**
37       * Whether to use strict format.
38       */
39      private final boolean strict;
40  
41      /**
42       * Constructs an instance with the specified strict setting.
43       *
44       * @param strict {@code true} if strict
45       *        {@code Format} parsing should be used.
46       */
47      public AbstractFormatValidator(final boolean strict) {
48          this.strict = strict;
49      }
50  
51      /**
52       * <p>Format an object into a {@link String} using
53       * the default Locale.</p>
54       *
55       * @param value The value validation is being performed on.
56       * @return The value formatted as a {@link String}.
57       */
58      public String format(final Object value) {
59          return format(value, (String) null, (Locale) null);
60      }
61  
62      /**
63       * <p>Format a value with the specified {@code Format}.</p>
64       *
65       * @param value The value to be formatted.
66       * @param formatter The Format to use.
67       * @return The formatted value.
68       */
69      protected String format(final Object value, final Format formatter) {
70          return formatter.format(value);
71      }
72  
73      /**
74       * <p>Format an object into a {@link String} using
75       * the specified Locale.</p>
76       *
77       * @param value The value validation is being performed on.
78       * @param locale The locale to use for the Format.
79       * @return The value formatted as a {@link String}.
80       */
81      public String format(final Object value, final Locale locale) {
82          return format(value, (String) null, locale);
83      }
84  
85      /**
86       * <p>Format an object into a {@link String} using
87       * the specified pattern.</p>
88       *
89       * @param value The value validation is being performed on.
90       * @param pattern The pattern used to format the value.
91       * @return The value formatted as a {@link String}.
92       */
93      public String format(final Object value, final String pattern) {
94          return format(value, pattern, (Locale) null);
95      }
96  
97      /**
98       * <p>Format an object using the specified pattern and/or
99       *    {@link Locale}.
100      *
101      * @param value The value validation is being performed on.
102      * @param pattern The pattern used to format the value.
103      * @param locale The locale to use for the Format.
104      * @return The value formatted as a {@link String}.
105      */
106     public String format(final Object value, final String pattern, final Locale locale) {
107         return format(value, getFormat(pattern, locale));
108     }
109 
110     /**
111      * <p>Returns a {@code Format} for the specified <em>pattern</em>
112      *    and/or {@link Locale}.</p>
113      *
114      * @param pattern The pattern used to validate the value against or
115      *        {@code null} to use the default for the {@link Locale}.
116      * @param locale The locale to use for the currency format, system default if null.
117      * @return The {@code NumberFormat} to created.
118      */
119     protected abstract Format getFormat(String pattern, Locale locale);
120 
121     /**
122      * <p>Indicates whether validated values should adhere
123      *    strictly to the {@code Format} used.</p>
124      *
125      * <p>Typically implementations of {@code Format}
126      *    ignore invalid characters at the end of the value
127      *    and just stop parsing. For example parsing a date
128      *    value of {@code 01/01/20x0} using a pattern
129      *    of {@code dd/MM/yyyy} will result in a year
130      *    of {@code 20} if {@code strict} is set
131      *    to {@code false}, whereas setting {@code strict}
132      *    to {@code true} will cause this value to fail
133      *    validation.</p>
134      *
135      * @return {@code true} if strict {@code Format}
136      *         parsing should be used.
137      */
138     public boolean isStrict() {
139         return strict;
140     }
141 
142     /**
143      * <p>Validate using the default {@link Locale}.
144      *
145      * @param value The value validation is being performed on.
146      * @return {@code true} if the value is valid.
147      */
148     public boolean isValid(final String value) {
149         return isValid(value, (String) null, (Locale) null);
150     }
151 
152     /**
153      * <p>Validate using the specified {@link Locale}.
154      *
155      * @param value The value validation is being performed on.
156      * @param locale The locale to use for the Format, defaults to the default
157      * @return {@code true} if the value is valid.
158      */
159     public boolean isValid(final String value, final Locale locale) {
160         return isValid(value, (String) null, locale);
161     }
162 
163     /**
164      * <p>Validate using the specified <em>pattern</em>.
165      *
166      * @param value The value validation is being performed on.
167      * @param pattern The pattern used to validate the value against.
168      * @return {@code true} if the value is valid.
169      */
170     public boolean isValid(final String value, final String pattern) {
171         return isValid(value, pattern, (Locale) null);
172     }
173 
174     /**
175      * <p>Validate using the specified pattern and/or {@link Locale}.
176      *
177      * @param value The value validation is being performed on.
178      * @param pattern The pattern used to format the value.
179      * @param locale The locale to use for the Format, defaults to the default
180      * @return {@code true} if the value is valid.
181      */
182     public abstract boolean isValid(String value, String pattern, Locale locale);
183 
184     /**
185      * <p>Parse the value with the specified {@code Format}.</p>
186      *
187      * @param value The value to be parsed.
188      * @param formatter The Format to parse the value with.
189      * @return The parsed value if valid or {@code null} if invalid.
190      */
191     protected Object parse(final String value, final Format formatter) {
192         final ParsePosition pos = new ParsePosition(0);
193         Object parsedValue = formatter.parseObject(value, pos);
194         if (pos.getErrorIndex() > -1 || isStrict() && pos.getIndex() < value.length()) {
195             return null;
196         }
197         if (parsedValue != null) {
198             parsedValue = processParsedValue(parsedValue, formatter);
199         }
200         return parsedValue;
201 
202     }
203 
204     /**
205      * <p>Process the parsed value, performing any further validation
206      *    and type conversion required.</p>
207      *
208      * @param value The parsed object created.
209      * @param formatter The Format used to parse the value with.
210      * @return The parsed value converted to the appropriate type
211      *         if valid or {@code null} if invalid.
212      */
213     protected abstract Object processParsedValue(Object value, Format formatter);
214 
215 }