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