Abstract class for Date/Time/Calendar validation.
29 | * 30 | *This is a base class for building Date / Time 31 | * Validators using format parsing.
32 | * 33 | * @version $Revision: 1739356 $ 34 | * @since Validator 1.3.0 35 | */ 36 | public abstract class AbstractCalendarValidator extends AbstractFormatValidator { 37 | 38 | private static final long serialVersionUID = -1410008585975827379L; 39 | 40 | private final int dateStyle; 41 | 42 | private final int timeStyle; 43 | 44 | /** 45 | * Construct an instance with the specified strict, 46 | * time and date style parameters. 47 | * 48 | * @param stricttrue
if strict
49 | * Format
parsing should be used.
50 | * @param dateStyle the date style to use for Locale validation.
51 | * @param timeStyle the time style to use for Locale validation.
52 | */
53 | public AbstractCalendarValidator(boolean strict, int dateStyle, int timeStyle) {
54 | super(strict);
55 | this.dateStyle = dateStyle;
56 | this.timeStyle = timeStyle;
57 | }
58 |
59 | /**
60 | * Validate using the specified Locale
.
61 | *
62 | * @param value The value validation is being performed on.
63 | * @param pattern The pattern used to format the value.
64 | * @param locale The locale to use for the Format, defaults to the default
65 | * @return true
if the value is valid.
66 | */
67 | @Override
68 | public boolean isValid(String value, String pattern, Locale locale) {
69 | Object parsedValue = parse(value, pattern, locale, (TimeZone)null);
70 | return (parsedValue == null ? false : true);
71 | }
72 |
73 | /**
74 | *
Format an object into a String
using
75 | * the default Locale.
Calendar
.
80 | * @return The value formatted as a String
.
81 | */
82 | public String format(Object value, TimeZone timeZone) {
83 | return format(value, (String)null, (Locale)null, timeZone);
84 | }
85 |
86 | /**
87 | * Format an object into a String
using
88 | * the specified pattern.
Calendar
.
94 | * @return The value formatted as a String
.
95 | */
96 | public String format(Object value, String pattern, TimeZone timeZone) {
97 | return format(value, pattern, (Locale)null, timeZone);
98 | }
99 |
100 | /**
101 | * Format an object into a String
using
102 | * the specified Locale.
Calendar
.
108 | * @return The value formatted as a String
.
109 | */
110 | public String format(Object value, Locale locale, TimeZone timeZone) {
111 | return format(value, (String)null, locale, timeZone);
112 | }
113 |
114 | /**
115 | * Format an object using the specified pattern and/or
116 | * Locale
.
117 | *
118 | * @param value The value validation is being performed on.
119 | * @param pattern The pattern used to format the value.
120 | * @param locale The locale to use for the Format.
121 | * @return The value formatted as a String
.
122 | */
123 | @Override
124 | public String format(Object value, String pattern, Locale locale) {
125 | return format(value, pattern, locale, (TimeZone)null);
126 | }
127 |
128 | /**
129 | *
Format an object using the specified pattern and/or
130 | * Locale
.
131 | *
132 | * @param value The value validation is being performed on.
133 | * @param pattern The pattern used to format the value.
134 | * @param locale The locale to use for the Format.
135 | * @param timeZone The Time Zone used to format the date,
136 | * system default if null (unless value is a Calendar
.
137 | * @return The value formatted as a String
.
138 | */
139 | public String format(Object value, String pattern, Locale locale, TimeZone timeZone) {
140 | DateFormat formatter = (DateFormat)getFormat(pattern, locale);
141 | if (timeZone != null) {
142 | formatter.setTimeZone(timeZone);
143 | } else if (value instanceof Calendar) {
144 | formatter.setTimeZone(((Calendar)value).getTimeZone());
145 | }
146 | return format(value, formatter);
147 | }
148 |
149 | /**
150 | *
Format a value with the specified DateFormat
.
Checks if the value is valid against a specified pattern.
168 | * 169 | * @param value The value validation is being performed on. 170 | * @param pattern The pattern used to validate the value against, or the 171 | * default for theLocale
if null
.
172 | * @param locale The locale to use for the date format, system default if null.
173 | * @param timeZone The Time Zone used to parse the date, system default if null.
174 | * @return The parsed value if valid or null
if invalid.
175 | */
176 | protected Object parse(String value, String pattern, Locale locale, TimeZone timeZone) {
177 |
178 | value = (value == null ? null : value.trim());
179 | if (value == null || value.length() == 0) {
180 | return null;
181 | }
182 | DateFormat formatter = (DateFormat)getFormat(pattern, locale);
183 | if (timeZone != null) {
184 | formatter.setTimeZone(timeZone);
185 | }
186 | return parse(value, formatter);
187 |
188 | }
189 |
190 | /**
191 | * Process the parsed value, performing any further validation 192 | * and type conversion required.
193 | * 194 | * @param value The parsed object created. 195 | * @param formatter The Format used to parse the value with. 196 | * @return The parsed value converted to the appropriate type 197 | * if valid ornull
if invalid.
198 | */
199 | @Override
200 | protected abstract Object processParsedValue(Object value, Format formatter);
201 |
202 | /**
203 | * Returns a DateFormat
for the specified pattern
204 | * and/or Locale
.
null
to use the default for the Locale
.
208 | * @param locale The locale to use for the currency format, system default if null.
209 | * @return The DateFormat
to created.
210 | */
211 | @Override
212 | protected Format getFormat(String pattern, Locale locale) {
213 | DateFormat formatter = null;
214 | boolean usePattern = (pattern != null && pattern.length() > 0);
215 | if (!usePattern) {
216 | formatter = (DateFormat)getFormat(locale);
217 | } else if (locale == null) {
218 | formatter = new SimpleDateFormat(pattern);
219 | } else {
220 | DateFormatSymbols symbols = new DateFormatSymbols(locale);
221 | formatter = new SimpleDateFormat(pattern, symbols);
222 | }
223 | formatter.setLenient(false);
224 | return formatter;
225 | }
226 |
227 | /**
228 | * Returns a DateFormat
for the specified Locale.
DateFormat
is required for,
231 | * system default if null.
232 | * @return The DateFormat
to created.
233 | */
234 | protected Format getFormat(Locale locale) {
235 |
236 | DateFormat formatter = null;
237 | if (dateStyle >= 0 && timeStyle >= 0) {
238 | if (locale == null) {
239 | formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
240 | } else {
241 | formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
242 | }
243 | } else if (timeStyle >= 0) {
244 | if (locale == null) {
245 | formatter = DateFormat.getTimeInstance(timeStyle);
246 | } else {
247 | formatter = DateFormat.getTimeInstance(timeStyle, locale);
248 | }
249 | } else {
250 | int useDateStyle = dateStyle >= 0 ? dateStyle : DateFormat.SHORT;
251 | if (locale == null) {
252 | formatter = DateFormat.getDateInstance(useDateStyle);
253 | } else {
254 | formatter = DateFormat.getDateInstance(useDateStyle, locale);
255 | }
256 | }
257 | formatter.setLenient(false);
258 | return formatter;
259 |
260 | }
261 |
262 | /**
263 | * Compares a calendar value to another, indicating whether it is 264 | * equal, less then or more than at a specified level.
265 | * 266 | * @param value The Calendar value. 267 | * @param compare TheCalendar
to check the value against.
268 | * @param field The field level to compare to - e.g. specifying
269 | * Calendar.MONTH
will compare the year and month
270 | * portions of the calendar.
271 | * @return Zero if the first value is equal to the second, -1
272 | * if it is less than the second or +1 if it is greater than the second.
273 | */
274 | protected int compare(Calendar value, Calendar compare, int field) {
275 |
276 | int result = 0;
277 |
278 | // Compare Year
279 | result = calculateCompareResult(value, compare, Calendar.YEAR);
280 | if (result != 0 || field == Calendar.YEAR) {
281 | return result;
282 | }
283 |
284 | // Compare Week of Year
285 | if (field == Calendar.WEEK_OF_YEAR) {
286 | return calculateCompareResult(value, compare, Calendar.WEEK_OF_YEAR);
287 | }
288 |
289 | // Compare Day of the Year
290 | if (field == Calendar.DAY_OF_YEAR) {
291 | return calculateCompareResult(value, compare, Calendar.DAY_OF_YEAR);
292 | }
293 |
294 | // Compare Month
295 | result = calculateCompareResult(value, compare, Calendar.MONTH);
296 | if (result != 0 || field == Calendar.MONTH) {
297 | return result;
298 | }
299 |
300 | // Compare Week of Month
301 | if (field == Calendar.WEEK_OF_MONTH) {
302 | return calculateCompareResult(value, compare, Calendar.WEEK_OF_MONTH);
303 | }
304 |
305 | // Compare Date
306 | result = calculateCompareResult(value, compare, Calendar.DATE);
307 | if (result != 0 || (field == Calendar.DATE ||
308 | field == Calendar.DAY_OF_WEEK ||
309 | field == Calendar.DAY_OF_WEEK_IN_MONTH)) {
310 | return result;
311 | }
312 |
313 | // Compare Time fields
314 | return compareTime(value, compare, field);
315 |
316 | }
317 |
318 | /**
319 | * Compares a calendar time value to another, indicating whether it is 320 | * equal, less then or more than at a specified level.
321 | * 322 | * @param value The Calendar value. 323 | * @param compare TheCalendar
to check the value against.
324 | * @param field The field level to compare to - e.g. specifying
325 | * Calendar.MINUTE
will compare the hours and minutes
326 | * portions of the calendar.
327 | * @return Zero if the first value is equal to the second, -1
328 | * if it is less than the second or +1 if it is greater than the second.
329 | */
330 | protected int compareTime(Calendar value, Calendar compare, int field) {
331 |
332 | int result = 0;
333 |
334 | // Compare Hour
335 | result = calculateCompareResult(value, compare, Calendar.HOUR_OF_DAY);
336 | if (result != 0 || (field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY)) {
337 | return result;
338 | }
339 |
340 | // Compare Minute
341 | result = calculateCompareResult(value, compare, Calendar.MINUTE);
342 | if (result != 0 || field == Calendar.MINUTE) {
343 | return result;
344 | }
345 |
346 | // Compare Second
347 | result = calculateCompareResult(value, compare, Calendar.SECOND);
348 | if (result != 0 || field == Calendar.SECOND) {
349 | return result;
350 | }
351 |
352 | // Compare Milliseconds
353 | if (field == Calendar.MILLISECOND) {
354 | return calculateCompareResult(value, compare, Calendar.MILLISECOND);
355 | }
356 |
357 | throw new IllegalArgumentException("Invalid field: " + field);
358 |
359 | }
360 |
361 | /**
362 | * Compares a calendar's quarter value to another, indicating whether it is 363 | * equal, less then or more than the specified quarter.
364 | * 365 | * @param value The Calendar value. 366 | * @param compare TheCalendar
to check the value against.
367 | * @param monthOfFirstQuarter The month that the first quarter starts.
368 | * @return Zero if the first quarter is equal to the second, -1
369 | * if it is less than the second or +1 if it is greater than the second.
370 | */
371 | protected int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) {
372 | int valueQuarter = calculateQuarter(value, monthOfFirstQuarter);
373 | int compareQuarter = calculateQuarter(compare, monthOfFirstQuarter);
374 | if (valueQuarter < compareQuarter) {
375 | return -1;
376 | } else if (valueQuarter > compareQuarter) {
377 | return 1;
378 | } else {
379 | return 0;
380 | }
381 | }
382 |
383 | /**
384 | * Calculate the quarter for the specified Calendar.
385 | * 386 | * @param calendar The Calendar value. 387 | * @param monthOfFirstQuarter The month that the first quarter starts. 388 | * @return The calculated quarter. 389 | */ 390 | private int calculateQuarter(Calendar calendar, int monthOfFirstQuarter) { 391 | // Add Year 392 | int year = calendar.get(Calendar.YEAR); 393 | 394 | int month = (calendar.get(Calendar.MONTH) + 1); 395 | int relativeMonth = (month >= monthOfFirstQuarter) 396 | ? (month - monthOfFirstQuarter) 397 | : (month + (12 - monthOfFirstQuarter)); // CHECKSTYLE IGNORE MagicNumber 398 | int quarter = ((relativeMonth / 3) + 1); // CHECKSTYLE IGNORE MagicNumber 399 | // adjust the year if the quarter doesn't start in January 400 | if (month < monthOfFirstQuarter) { 401 | --year; 402 | } 403 | return (year * 10) + quarter; // CHECKSTYLE IGNORE MagicNumber 404 | } 405 | 406 | /** 407 | *Compares the field from two calendars indicating whether the field for the
408 | * first calendar is equal to, less than or greater than the field from the
409 | * second calendar.
410 | *
411 | * @param value The Calendar value.
412 | * @param compare The Calendar
to check the value against.
413 | * @param field The field to compare for the calendars.
414 | * @return Zero if the first calendar's field is equal to the seconds, -1
415 | * if it is less than the seconds or +1 if it is greater than the seconds.
416 | */
417 | private int calculateCompareResult(Calendar value, Calendar compare, int field) {
418 | int difference = value.get(field) - compare.get(field);
419 | if (difference < 0) {
420 | return -1;
421 | } else if (difference > 0) {
422 | return 1;
423 | } else {
424 | return 0;
425 | }
426 | }
427 | }
428 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/AbstractFormatValidator.java:
--------------------------------------------------------------------------------
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 | * http://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.text.Format;
20 | import java.text.ParsePosition;
21 | import java.util.Locale;
22 | import java.io.Serializable;
23 |
24 | /**
25 | *
Abstract class for Format based Validation.
26 | * 27 | *This is a base class for building Date and Number 28 | * Validators using format parsing.
29 | * 30 | * @version $Revision: 1649191 $ 31 | * @since Validator 1.3.0 32 | */ 33 | public abstract class AbstractFormatValidator implements Serializable { 34 | 35 | private static final long serialVersionUID = -4690687565200568258L; 36 | 37 | private final boolean strict; 38 | 39 | /** 40 | * Construct an instance with the specified strict setting. 41 | * 42 | * @param stricttrue
if strict
43 | * Format
parsing should be used.
44 | */
45 | public AbstractFormatValidator(boolean strict) {
46 | this.strict = strict;
47 | }
48 |
49 | /**
50 | * Indicates whether validated values should adhere
51 | * strictly to the Format
used.
Typically implementations of Format
54 | * ignore invalid characters at the end of the value
55 | * and just stop parsing. For example parsing a date
56 | * value of 01/01/20x0
using a pattern
57 | * of dd/MM/yyyy
will result in a year
58 | * of 20
if strict
is set
59 | * to false
, whereas setting strict
60 | * to true
will cause this value to fail
61 | * validation.
true
if strict Format
64 | * parsing should be used.
65 | */
66 | public boolean isStrict() {
67 | return strict;
68 | }
69 |
70 | /**
71 | * Validate using the default Locale
.
72 | *
73 | * @param value The value validation is being performed on.
74 | * @return true
if the value is valid.
75 | */
76 | public boolean isValid(String value) {
77 | return isValid(value, (String)null, (Locale)null);
78 | }
79 |
80 | /**
81 | *
Validate using the specified pattern.
82 | *
83 | * @param value The value validation is being performed on.
84 | * @param pattern The pattern used to validate the value against.
85 | * @return true
if the value is valid.
86 | */
87 | public boolean isValid(String value, String pattern) {
88 | return isValid(value, pattern, (Locale)null);
89 | }
90 |
91 | /**
92 | *
Validate using the specified Locale
.
93 | *
94 | * @param value The value validation is being performed on.
95 | * @param locale The locale to use for the Format, defaults to the default
96 | * @return true
if the value is valid.
97 | */
98 | public boolean isValid(String value, Locale locale) {
99 | return isValid(value, (String)null, locale);
100 | }
101 |
102 | /**
103 | *
Validate using the specified pattern and/or Locale
.
104 | *
105 | * @param value The value validation is being performed on.
106 | * @param pattern The pattern used to format the value.
107 | * @param locale The locale to use for the Format, defaults to the default
108 | * @return true
if the value is valid.
109 | */
110 | public abstract boolean isValid(String value, String pattern, Locale locale);
111 |
112 | /**
113 | *
Format an object into a String
using
114 | * the default Locale.
String
.
118 | */
119 | public String format(Object value) {
120 | return format(value, (String)null, (Locale)null);
121 | }
122 |
123 | /**
124 | * Format an object into a String
using
125 | * the specified pattern.
String
.
130 | */
131 | public String format(Object value, String pattern) {
132 | return format(value, pattern, (Locale)null);
133 | }
134 |
135 | /**
136 | * Format an object into a String
using
137 | * the specified Locale.
String
.
142 | */
143 | public String format(Object value, Locale locale) {
144 | return format(value, (String)null, locale);
145 | }
146 |
147 | /**
148 | * Format an object using the specified pattern and/or
149 | * Locale
.
150 | *
151 | * @param value The value validation is being performed on.
152 | * @param pattern The pattern used to format the value.
153 | * @param locale The locale to use for the Format.
154 | * @return The value formatted as a String
.
155 | */
156 | public String format(Object value, String pattern, Locale locale) {
157 | Format formatter = getFormat(pattern, locale);
158 | return format(value, formatter);
159 | }
160 |
161 | /**
162 | *
Format a value with the specified Format
.
Parse the value with the specified Format
.
null
if invalid.
178 | */
179 | protected Object parse(String value, Format formatter) {
180 |
181 | ParsePosition pos = new ParsePosition(0);
182 | Object parsedValue = formatter.parseObject(value, pos);
183 | if (pos.getErrorIndex() > -1) {
184 | return null;
185 | }
186 |
187 | if (isStrict() && pos.getIndex() < value.length()) {
188 | return null;
189 | }
190 |
191 | if (parsedValue != null) {
192 | parsedValue = processParsedValue(parsedValue, formatter);
193 | }
194 |
195 | return parsedValue;
196 |
197 | }
198 |
199 | /**
200 | * Process the parsed value, performing any further validation 201 | * and type conversion required.
202 | * 203 | * @param value The parsed object created. 204 | * @param formatter The Format used to parse the value with. 205 | * @return The parsed value converted to the appropriate type 206 | * if valid ornull
if invalid.
207 | */
208 | protected abstract Object processParsedValue(Object value, Format formatter);
209 |
210 | /**
211 | * Returns a Format
for the specified pattern
212 | * and/or Locale
.
null
to use the default for the Locale
.
216 | * @param locale The locale to use for the currency format, system default if null.
217 | * @return The NumberFormat
to created.
218 | */
219 | protected abstract Format getFormat(String pattern, Locale locale);
220 |
221 | }
222 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/CodeValidator.java:
--------------------------------------------------------------------------------
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 | * http://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 |
21 | import org.apache.commons.validator.routines.checkdigit.CheckDigit;
22 |
23 | /**
24 | * Generic Code Validation providing format, minimum/maximum
25 | * length and {@link CheckDigit} validations.
26 | * 27 | * Performs the following validations on a code: 28 | *
38 | * Note 39 | * The {@link #isValid(String)} method will return true if the input passes validation. 40 | * Since this includes trimming as well as potentially dropping parts of the input, 41 | * it is possible for a String to pass validation 42 | * but fail the checkdigit test if passed directly to it (the check digit routines generally don't trim input 43 | * nor do they generally check the format/length). 44 | * To be sure that you are passing valid input to a method use {@link #validate(String)} as follows: 45 | *
46 | * Object valid = validator.validate(input); 47 | * if (valid != null) { 48 | * some_method(valid.toString()); 49 | * } 50 | *51 | *
52 | * Configure the validator with the appropriate regular expression, minimum/maximum length 53 | * and {@link CheckDigit} validator and then call one of the two validation 54 | * methods provided:
55 | *boolean isValid(code)
String validate(code)
60 | * Codes often include format characters - such as hyphens - to make them
61 | * more easily human readable. These can be removed prior to length and check digit
62 | * validation by specifying them as a non-capturing group in the regular
63 | * expression (i.e. use the (?: )
notation).
64 | *
65 | * Or just avoid using parentheses except for the parts you want to capture
66 | *
67 | * @version $Revision: 1739011 $
68 | * @since Validator 1.4
69 | */
70 | public final class CodeValidator implements Serializable {
71 |
72 | private static final long serialVersionUID = 446960910870938233L;
73 |
74 | private final RegexValidator regexValidator;
75 | private final int minLength;
76 | private final int maxLength;
77 | private final CheckDigit checkdigit;
78 |
79 | /**
80 | * Construct a code validator with a specified regular
81 | * expression and {@link CheckDigit}.
82 | * The RegexValidator validator is created to be case-sensitive
83 | *
84 | * @param regex The format regular expression
85 | * @param checkdigit The check digit validation routine
86 | */
87 | public CodeValidator(String regex, CheckDigit checkdigit) {
88 | this(regex, -1, -1, checkdigit);
89 | }
90 |
91 | /**
92 | * Construct a code validator with a specified regular
93 | * expression, length and {@link CheckDigit}.
94 | * The RegexValidator validator is created to be case-sensitive
95 | *
96 | * @param regex The format regular expression.
97 | * @param length The length of the code
98 | * (sets the mimimum/maximum to the same)
99 | * @param checkdigit The check digit validation routine
100 | */
101 | public CodeValidator(String regex, int length, CheckDigit checkdigit) {
102 | this(regex, length, length, checkdigit);
103 | }
104 |
105 | /**
106 | * Construct a code validator with a specified regular
107 | * expression, minimum/maximum length and {@link CheckDigit} validation.
108 | * The RegexValidator validator is created to be case-sensitive
109 | *
110 | * @param regex The regular expression
111 | * @param minLength The minimum length of the code
112 | * @param maxLength The maximum length of the code
113 | * @param checkdigit The check digit validation routine
114 | */
115 | public CodeValidator(String regex, int minLength, int maxLength,
116 | CheckDigit checkdigit) {
117 | if (regex != null && regex.length() > 0) {
118 | this.regexValidator = new RegexValidator(regex);
119 | } else {
120 | this.regexValidator = null;
121 | }
122 | this.minLength = minLength;
123 | this.maxLength = maxLength;
124 | this.checkdigit = checkdigit;
125 | }
126 |
127 | /**
128 | * Construct a code validator with a specified regular expression,
129 | * validator and {@link CheckDigit} validation.
130 | *
131 | * @param regexValidator The format regular expression validator
132 | * @param checkdigit The check digit validation routine.
133 | */
134 | public CodeValidator(RegexValidator regexValidator, CheckDigit checkdigit) {
135 | this(regexValidator, -1, -1, checkdigit);
136 | }
137 |
138 | /**
139 | * Construct a code validator with a specified regular expression,
140 | * validator, length and {@link CheckDigit} validation.
141 | *
142 | * @param regexValidator The format regular expression validator
143 | * @param length The length of the code
144 | * (sets the mimimum/maximum to the same value)
145 | * @param checkdigit The check digit validation routine
146 | */
147 | public CodeValidator(RegexValidator regexValidator, int length, CheckDigit checkdigit) {
148 | this(regexValidator, length, length, checkdigit);
149 | }
150 |
151 | /**
152 | * Construct a code validator with a specified regular expression
153 | * validator, minimum/maximum length and {@link CheckDigit} validation.
154 | *
155 | * @param regexValidator The format regular expression validator
156 | * @param minLength The minimum length of the code
157 | * @param maxLength The maximum length of the code
158 | * @param checkdigit The check digit validation routine
159 | */
160 | public CodeValidator(RegexValidator regexValidator, int minLength, int maxLength,
161 | CheckDigit checkdigit) {
162 | this.regexValidator = regexValidator;
163 | this.minLength = minLength;
164 | this.maxLength = maxLength;
165 | this.checkdigit = checkdigit;
166 | }
167 |
168 | /**
169 | * Return the check digit validation routine.
170 | *
171 | * N.B. Optional, if not set no Check Digit 172 | * validation will be performed on the code. 173 | * 174 | * @return The check digit validation routine 175 | */ 176 | public CheckDigit getCheckDigit() { 177 | return checkdigit; 178 | } 179 | 180 | /** 181 | * Return the minimum length of the code. 182 | *
183 | * N.B. Optional, if less than zero the
184 | * minimum length will not be checked.
185 | *
186 | * @return The minimum length of the code or
187 | * -1
if the code has no minimum length
188 | */
189 | public int getMinLength() {
190 | return minLength;
191 | }
192 |
193 | /**
194 | * Return the maximum length of the code.
195 | *
196 | * N.B. Optional, if less than zero the
197 | * maximum length will not be checked.
198 | *
199 | * @return The maximum length of the code or
200 | * -1
if the code has no maximum length
201 | */
202 | public int getMaxLength() {
203 | return maxLength;
204 | }
205 |
206 | /**
207 | * Return the regular expression validator.
208 | *
209 | * N.B. Optional, if not set no regular
210 | * expression validation will be performed on the code.
211 | *
212 | * @return The regular expression validator
213 | */
214 | public RegexValidator getRegexValidator() {
215 | return regexValidator;
216 | }
217 |
218 | /**
219 | * Validate the code returning either true
220 | * or false
.
221 | *
222 | * @param input The code to validate
223 | * @return true
if valid, otherwise
224 | * false
225 | */
226 | public boolean isValid(String input) {
227 | return (validate(input) != null);
228 | }
229 |
230 | /**
231 | * Validate the code returning either the valid code or
232 | * null
if invalid.
233 | *
234 | * @param input The code to validate
235 | * @return The code if valid, otherwise null
236 | * if invalid
237 | */
238 | public Object validate(String input) {
239 |
240 | if (input == null) {
241 | return null;
242 | }
243 |
244 | String code = input.trim();
245 | if (code.length() == 0) {
246 | return null;
247 | }
248 |
249 | // validate/reformat using regular expression
250 | if (regexValidator != null) {
251 | code = regexValidator.validate(code);
252 | if (code == null) {
253 | return null;
254 | }
255 | }
256 |
257 | // check the length (must be done after validate as that can change the code)
258 | if ((minLength >= 0 && code.length() < minLength) ||
259 | (maxLength >= 0 && code.length() > maxLength)) {
260 | return null;
261 | }
262 |
263 | // validate the check digit
264 | if (checkdigit != null && !checkdigit.isValid(code)) {
265 | return null;
266 | }
267 |
268 | return code;
269 |
270 | }
271 |
272 | }
273 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/CreditCardValidator.java:
--------------------------------------------------------------------------------
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 | * http://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 org.apache.commons.validator.routines.checkdigit.CheckDigit;
20 | import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
21 | import java.io.Serializable;
22 | import java.util.Collections;
23 | import java.util.List;
24 | import java.util.ArrayList;
25 |
26 | /**
27 | * Perform credit card validations.
28 | *
29 | *
30 | * By default, all supported card types are allowed. You can specify which 31 | * cards should pass validation by configuring the validation options. For 32 | * example, 33 | *
34 | * 35 | *
36 | * CreditCardValidator ccv = new CreditCardValidator(CreditCardValidator.AMEX + CreditCardValidator.VISA);
37 | *
38 | *
39 | *
40 | * configures the validator to only pass American Express and Visa cards.
41 | * If a card type is not directly supported by this class, you can implement
42 | * the CreditCardType interface and pass an instance into the
43 | * addAllowedCardType
method.
44 | *
47 | * For a similar implementation in Perl, reference Sean M. Burke's 48 | * script. 49 | * More information can be found in Michael Gilleland's essay 50 | * Anatomy of Credit Card Numbers. 51 | *
52 | * 53 | * @version $Revision: 1739207 $ 54 | * @since Validator 1.4 55 | */ 56 | public class CreditCardValidator implements Serializable { 57 | 58 | private static final long serialVersionUID = 5955978921148959496L; 59 | 60 | /** 61 | * Option specifying that no cards are allowed. This is useful if 62 | * you want only custom card types to validate so you turn off the 63 | * default cards with this option. 64 | * 65 | *
66 | *
67 | * CreditCardValidator v = new CreditCardValidator(CreditCardValidator.NONE);
68 | * v.addAllowedCardType(customType);
69 | * v.isValid(aCardNumber);
70 | *
71 | *
72 | */
73 | public static final long NONE = 0;
74 |
75 | /**
76 | * Option specifying that American Express cards are allowed.
77 | */
78 | public static final long AMEX = 1 << 0;
79 |
80 | /**
81 | * Option specifying that Visa cards are allowed.
82 | */
83 | public static final long VISA = 1 << 1;
84 |
85 | /**
86 | * Option specifying that Mastercard cards are allowed.
87 | */
88 | public static final long MASTERCARD = 1 << 2;
89 |
90 | /**
91 | * Option specifying that Discover cards are allowed.
92 | */
93 | public static final long DISCOVER = 1 << 3; // CHECKSTYLE IGNORE MagicNumber
94 |
95 | /**
96 | * Option specifying that Diners cards are allowed.
97 | */
98 | public static final long DINERS = 1 << 4; // CHECKSTYLE IGNORE MagicNumber
99 |
100 | /**
101 | * Option specifying that VPay (Visa) cards are allowed.
102 | * @since 1.5.0
103 | */
104 | public static final long VPAY = 1 << 5; // CHECKSTYLE IGNORE MagicNumber
105 |
106 | /**
107 | * Option specifying that Mastercard cards (pre Oct 2016 only) are allowed.
108 | * @deprecated for use until Oct 2016 only
109 | */
110 | @Deprecated
111 | public static final long MASTERCARD_PRE_OCT2016 = 1 << 6; // CHECKSTYLE IGNORE MagicNumber
112 |
113 |
114 | /**
115 | * The CreditCardTypes that are allowed to pass validation.
116 | */
117 | private final Listnull
246 | * if invalid.
247 | */
248 | public Object validate(String card) {
249 | if (card == null || card.length() == 0) {
250 | return null;
251 | }
252 | Object result = null;
253 | for (CodeValidator cardType : cardTypes) {
254 | result = cardType.validate(card);
255 | if (result != null) {
256 | return result;
257 | }
258 | }
259 | return null;
260 |
261 | }
262 | /**
263 | * Tests whether the given flag is on. If the flag is not a power of 2
264 | * (ie. 3) this tests whether the combination of flags is on.
265 | *
266 | * @param options The options specified.
267 | * @param flag Flag value to check.
268 | *
269 | * @return whether the specified flag value is on.
270 | */
271 | private boolean isOn(long options, long flag) {
272 | return (options & flag) > 0;
273 | }
274 |
275 | }
276 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/DateValidator.java:
--------------------------------------------------------------------------------
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 | * http://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.text.DateFormat;
20 | import java.text.Format;
21 | import java.util.Calendar;
22 | import java.util.Date;
23 | import java.util.Locale;
24 | import java.util.TimeZone;
25 |
26 | /**
27 | * Date Validation and Conversion routines (java.util.Date
).
This validator provides a number of methods for validating/converting
30 | * a String
date value to a java.util.Date
using
31 | * java.text.DateFormat
to parse either:
Locale
Locale
Locale
Locale
For each of the above mechanisms, conversion method (i.e the
40 | * validate
methods) implementations are provided which
41 | * either use the default TimeZone
or allow the
42 | * TimeZone
to be specified.
Use one of the isValid()
methods to just validate or
45 | * one of the validate()
methods to validate and receive a
46 | * converted Date
value.
Implementations of the validate()
method are provided
49 | * to create Date
objects for different time zones
50 | * if the system default is not appropriate.
Once a value has been successfully converted the following 53 | * methods can be used to perform various date comparison checks:
54 | *compareDates()
compares the day, month and
56 | * year of two dates, returning 0, -1 or +1 indicating
57 | * whether the first date is equal, before or after the second.compareWeeks()
compares the week and
59 | * year of two dates, returning 0, -1 or +1 indicating
60 | * whether the first week is equal, before or after the second.compareMonths()
compares the month and
62 | * year of two dates, returning 0, -1 or +1 indicating
63 | * whether the first month is equal, before or after the second.compareQuarters()
compares the quarter and
65 | * year of two dates, returning 0, -1 or +1 indicating
66 | * whether the first quarter is equal, before or after the second.compareYears()
compares the
68 | * year of two dates, returning 0, -1 or +1 indicating
69 | * whether the first year is equal, before or after the second.So that the same mechanism used for parsing an input value
73 | * for validation can be used to format output, corresponding
74 | * format()
methods are also provided. That is you can
75 | * format either:
Locale
Locale
true
if strict
112 | * Format
parsing should be used.
113 | * @param dateStyle the date style to use for Locale validation.
114 | */
115 | public DateValidator(boolean strict, int dateStyle) {
116 | super(strict, dateStyle, -1);
117 | }
118 |
119 | /**
120 | * Validate/convert a Date
using the default
121 | * Locale
and TimeZone
.
122 | *
123 | * @param value The value validation is being performed on.
124 | * @return The parsed Date
if valid or null
125 | * if invalid.
126 | */
127 | public Date validate(String value) {
128 | return (Date)parse(value, (String)null, (Locale)null, (TimeZone)null);
129 | }
130 |
131 | /**
132 | *
Validate/convert a Date
using the specified
133 | * TimeZone
and default Locale
.
134 | *
135 | * @param value The value validation is being performed on.
136 | * @param timeZone The Time Zone used to parse the date, system default if null.
137 | * @return The parsed Date
if valid or null
if invalid.
138 | */
139 | public Date validate(String value, TimeZone timeZone) {
140 | return (Date)parse(value, (String)null, (Locale)null, timeZone);
141 | }
142 |
143 | /**
144 | *
Validate/convert a Date
using the specified
145 | * pattern and default TimeZone
.
146 | *
147 | * @param value The value validation is being performed on.
148 | * @param pattern The pattern used to validate the value against, or the
149 | * default for the Locale
if null
.
150 | * @return The parsed Date
if valid or null
if invalid.
151 | */
152 | public Date validate(String value, String pattern) {
153 | return (Date)parse(value, pattern, (Locale)null, (TimeZone)null);
154 | }
155 |
156 | /**
157 | *
Validate/convert a Date
using the specified
158 | * pattern and TimeZone
.
159 | *
160 | * @param value The value validation is being performed on.
161 | * @param pattern The pattern used to validate the value against, or the
162 | * default for the Locale
if null
.
163 | * @param timeZone The Time Zone used to parse the date, system default if null.
164 | * @return The parsed Date
if valid or null
if invalid.
165 | */
166 | public Date validate(String value, String pattern, TimeZone timeZone) {
167 | return (Date)parse(value, pattern, (Locale)null, timeZone);
168 | }
169 |
170 | /**
171 | *
Validate/convert a Date
using the specified
172 | * Locale
and default TimeZone
.
173 | *
174 | * @param value The value validation is being performed on.
175 | * @param locale The locale to use for the date format, system default if null.
176 | * @return The parsed Date
if valid or null
if invalid.
177 | */
178 | public Date validate(String value, Locale locale) {
179 | return (Date)parse(value, (String)null, locale, (TimeZone)null);
180 | }
181 |
182 | /**
183 | *
Validate/convert a Date
using the specified
184 | * Locale
and TimeZone
.
185 | *
186 | * @param value The value validation is being performed on.
187 | * @param locale The locale to use for the date format, system default if null.
188 | * @param timeZone The Time Zone used to parse the date, system default if null.
189 | * @return The parsed Date
if valid or null
if invalid.
190 | */
191 | public Date validate(String value, Locale locale, TimeZone timeZone) {
192 | return (Date)parse(value, (String)null, locale, timeZone);
193 | }
194 |
195 | /**
196 | *
Validate/convert a Date
using the specified pattern
197 | * and Locale
and the default TimeZone
.
198 | *
199 | * @param value The value validation is being performed on.
200 | * @param pattern The pattern used to validate the value against, or the
201 | * default for the Locale
if null
.
202 | * @param locale The locale to use for the date format, system default if null.
203 | * @return The parsed Date
if valid or null
if invalid.
204 | */
205 | public Date validate(String value, String pattern, Locale locale) {
206 | return (Date)parse(value, pattern, locale, (TimeZone)null);
207 | }
208 |
209 | /**
210 | *
Validate/convert a Date
using the specified
211 | * pattern, and Locale
and TimeZone
.
212 | *
213 | * @param value The value validation is being performed on.
214 | * @param pattern The pattern used to validate the value against, or the
215 | * default for the Locale
if null
.
216 | * @param locale The locale to use for the date format, system default if null.
217 | * @param timeZone The Time Zone used to parse the date, system default if null.
218 | * @return The parsed Date
if valid or null
if invalid.
219 | */
220 | public Date validate(String value, String pattern, Locale locale, TimeZone timeZone) {
221 | return (Date)parse(value, pattern, locale, timeZone);
222 | }
223 |
224 | /**
225 | *
Compare Dates (day, month and year - not time).
226 | * 227 | * @param value TheCalendar
value to check.
228 | * @param compare The Calendar
to compare the value to.
229 | * @param timeZone The Time Zone used to compare the dates, system default if null.
230 | * @return Zero if the dates are equal, -1 if first
231 | * date is less than the seconds and +1 if the first
232 | * date is greater than.
233 | */
234 | public int compareDates(Date value, Date compare, TimeZone timeZone) {
235 | Calendar calendarValue = getCalendar(value, timeZone);
236 | Calendar calendarCompare = getCalendar(compare, timeZone);
237 | return compare(calendarValue, calendarCompare, Calendar.DATE);
238 | }
239 |
240 | /**
241 | * Compare Weeks (week and year).
242 | * 243 | * @param value TheDate
value to check.
244 | * @param compare The Date
to compare the value to.
245 | * @param timeZone The Time Zone used to compare the dates, system default if null.
246 | * @return Zero if the weeks are equal, -1 if first
247 | * parameter's week is less than the seconds and +1 if the first
248 | * parameter's week is greater than.
249 | */
250 | public int compareWeeks(Date value, Date compare, TimeZone timeZone) {
251 | Calendar calendarValue = getCalendar(value, timeZone);
252 | Calendar calendarCompare = getCalendar(compare, timeZone);
253 | return compare(calendarValue, calendarCompare, Calendar.WEEK_OF_YEAR);
254 | }
255 |
256 | /**
257 | * Compare Months (month and year).
258 | * 259 | * @param value TheDate
value to check.
260 | * @param compare The Date
to compare the value to.
261 | * @param timeZone The Time Zone used to compare the dates, system default if null.
262 | * @return Zero if the months are equal, -1 if first
263 | * parameter's month is less than the seconds and +1 if the first
264 | * parameter's month is greater than.
265 | */
266 | public int compareMonths(Date value, Date compare, TimeZone timeZone) {
267 | Calendar calendarValue = getCalendar(value, timeZone);
268 | Calendar calendarCompare = getCalendar(compare, timeZone);
269 | return compare(calendarValue, calendarCompare, Calendar.MONTH);
270 | }
271 |
272 | /**
273 | * Compare Quarters (quarter and year).
274 | * 275 | * @param value TheDate
value to check.
276 | * @param compare The Date
to compare the value to.
277 | * @param timeZone The Time Zone used to compare the dates, system default if null.
278 | * @return Zero if the months are equal, -1 if first
279 | * parameter's quarter is less than the seconds and +1 if the first
280 | * parameter's quarter is greater than.
281 | */
282 | public int compareQuarters(Date value, Date compare, TimeZone timeZone) {
283 | return compareQuarters(value, compare, timeZone, 1);
284 | }
285 |
286 | /**
287 | * Compare Quarters (quarter and year).
288 | * 289 | * @param value TheDate
value to check.
290 | * @param compare The Date
to compare the value to.
291 | * @param timeZone The Time Zone used to compare the dates, system default if null.
292 | * @param monthOfFirstQuarter The month that the first quarter starts.
293 | * @return Zero if the quarters are equal, -1 if first
294 | * parameter's quarter is less than the seconds and +1 if the first
295 | * parameter's quarter is greater than.
296 | */
297 | public int compareQuarters(Date value, Date compare, TimeZone timeZone, int monthOfFirstQuarter) {
298 | Calendar calendarValue = getCalendar(value, timeZone);
299 | Calendar calendarCompare = getCalendar(compare, timeZone);
300 | return super.compareQuarters(calendarValue, calendarCompare, monthOfFirstQuarter);
301 | }
302 |
303 | /**
304 | * Compare Years.
305 | * 306 | * @param value TheDate
value to check.
307 | * @param compare The Date
to compare the value to.
308 | * @param timeZone The Time Zone used to compare the dates, system default if null.
309 | * @return Zero if the years are equal, -1 if first
310 | * parameter's year is less than the seconds and +1 if the first
311 | * parameter's year is greater than.
312 | */
313 | public int compareYears(Date value, Date compare, TimeZone timeZone) {
314 | Calendar calendarValue = getCalendar(value, timeZone);
315 | Calendar calendarCompare = getCalendar(compare, timeZone);
316 | return compare(calendarValue, calendarCompare, Calendar.YEAR);
317 | }
318 |
319 | /**
320 | * Returns the parsed Date
unchanged.
Date
object created.
323 | * @param formatter The Format used to parse the value with.
324 | * @return The parsed value converted to a Calendar
.
325 | */
326 | @Override
327 | protected Object processParsedValue(Object value, Format formatter) {
328 | return value;
329 | }
330 |
331 | /**
332 | * Convert a Date
to a Calendar
.
Calendar
.
336 | */
337 | private Calendar getCalendar(Date value, TimeZone timeZone) {
338 |
339 | Calendar calendar = null;
340 | if (timeZone != null) {
341 | calendar = Calendar.getInstance(timeZone);
342 | } else {
343 | calendar = Calendar.getInstance();
344 | }
345 | calendar.setTime(value);
346 | return calendar;
347 |
348 | }
349 |
350 | }
351 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/RegexValidator.java:
--------------------------------------------------------------------------------
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 | * http://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.util.regex.Pattern;
21 | import java.util.regex.Matcher;
22 |
23 | /**
24 | * Regular Expression validation (using JDK 1.4+ regex support).
25 | * 26 | * Construct the validator either for a single regular expression or a set (array) of 27 | * regular expressions. By default validation is case sensitive but constructors 28 | * are provided to allow case in-sensitive validation. For example to create 29 | * a validator which does case in-sensitive validation for a set of regular 30 | * expressions: 31 | *
32 | *
33 | *
34 | * String[] regexs = new String[] {...};
35 | * RegexValidator validator = new RegexValidator(regexs, false);
36 | *
37 | *
38 | *
39 | * true
or false
:boolean valid = validator.isValid(value);
String result = validator.validate(value);
String[] result = validator.match(value);
63 | * Cached instances pre-compile and re-use {@link Pattern}(s) - which according 64 | * to the {@link Pattern} API are safe to use in a multi-threaded environment. 65 | *
66 | * 67 | * @version $Revision: 1739356 $ 68 | * @since Validator 1.4 69 | */ 70 | public class RegexValidator implements Serializable { 71 | 72 | private static final long serialVersionUID = -8832409930574867162L; 73 | 74 | private final Pattern[] patterns; 75 | 76 | /** 77 | * Construct a case sensitive validator for a single 78 | * regular expression. 79 | * 80 | * @param regex The regular expression this validator will 81 | * validate against 82 | */ 83 | public RegexValidator(String regex) { 84 | this(regex, true); 85 | } 86 | 87 | /** 88 | * Construct a validator for a single regular expression 89 | * with the specified case sensitivity. 90 | * 91 | * @param regex The regular expression this validator will 92 | * validate against 93 | * @param caseSensitive whentrue
matching is case
94 | * sensitive, otherwise matching is case in-sensitive
95 | */
96 | public RegexValidator(String regex, boolean caseSensitive) {
97 | this(new String[] {regex}, caseSensitive);
98 | }
99 |
100 | /**
101 | * Construct a case sensitive validator that matches any one
102 | * of the set of regular expressions.
103 | *
104 | * @param regexs The set of regular expressions this validator will
105 | * validate against
106 | */
107 | public RegexValidator(String[] regexs) {
108 | this(regexs, true);
109 | }
110 |
111 | /**
112 | * Construct a validator that matches any one of the set of regular
113 | * expressions with the specified case sensitivity.
114 | *
115 | * @param regexs The set of regular expressions this validator will
116 | * validate against
117 | * @param caseSensitive when true
matching is case
118 | * sensitive, otherwise matching is case in-sensitive
119 | */
120 | public RegexValidator(String[] regexs, boolean caseSensitive) {
121 | if (regexs == null || regexs.length == 0) {
122 | throw new IllegalArgumentException("Regular expressions are missing");
123 | }
124 | patterns = new Pattern[regexs.length];
125 | int flags = (caseSensitive ? 0: Pattern.CASE_INSENSITIVE);
126 | for (int i = 0; i < regexs.length; i++) {
127 | if (regexs[i] == null || regexs[i].length() == 0) {
128 | throw new IllegalArgumentException("Regular expression[" + i + "] is missing");
129 | }
130 | patterns[i] = Pattern.compile(regexs[i], flags);
131 | }
132 | }
133 |
134 | /**
135 | * Validate a value against the set of regular expressions.
136 | *
137 | * @param value The value to validate.
138 | * @return true
if the value is valid
139 | * otherwise false
.
140 | */
141 | public boolean isValid(String value) {
142 | if (value == null) {
143 | return false;
144 | }
145 | for (int i = 0; i < patterns.length; i++) {
146 | if (patterns[i].matcher(value).matches()) {
147 | return true;
148 | }
149 | }
150 | return false;
151 | }
152 |
153 | /**
154 | * Validate a value against the set of regular expressions
155 | * returning the array of matched groups.
156 | *
157 | * @param value The value to validate.
158 | * @return String array of the groups matched if
159 | * valid or null
if invalid
160 | */
161 | public String[] match(String value) {
162 | if (value == null) {
163 | return null;
164 | }
165 | for (int i = 0; i < patterns.length; i++) {
166 | Matcher matcher = patterns[i].matcher(value);
167 | if (matcher.matches()) {
168 | int count = matcher.groupCount();
169 | String[] groups = new String[count];
170 | for (int j = 0; j < count; j++) {
171 | groups[j] = matcher.group(j+1);
172 | }
173 | return groups;
174 | }
175 | }
176 | return null;
177 | }
178 |
179 |
180 | /**
181 | * Validate a value against the set of regular expressions
182 | * returning a String value of the aggregated groups.
183 | *
184 | * @param value The value to validate.
185 | * @return Aggregated String value comprised of the
186 | * groups matched if valid or null
if invalid
187 | */
188 | public String validate(String value) {
189 | if (value == null) {
190 | return null;
191 | }
192 | for (int i = 0; i < patterns.length; i++) {
193 | Matcher matcher = patterns[i].matcher(value);
194 | if (matcher.matches()) {
195 | int count = matcher.groupCount();
196 | if (count == 1) {
197 | return matcher.group(1);
198 | }
199 | StringBuilder buffer = new StringBuilder();
200 | for (int j = 0; j < count; j++) {
201 | String component = matcher.group(j+1);
202 | if (component != null) {
203 | buffer.append(component);
204 | }
205 | }
206 | return buffer.toString();
207 | }
208 | }
209 | return null;
210 | }
211 |
212 | /**
213 | * Provide a String representation of this validator.
214 | * @return A String representation of this validator
215 | */
216 | @Override
217 | public String toString() {
218 | StringBuilder buffer = new StringBuilder();
219 | buffer.append("RegexValidator{");
220 | for (int i = 0; i < patterns.length; i++) {
221 | if (i > 0) {
222 | buffer.append(",");
223 | }
224 | buffer.append(patterns[i].pattern());
225 | }
226 | buffer.append("}");
227 | return buffer.toString();
228 | }
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/checkdigit/CheckDigit.java:
--------------------------------------------------------------------------------
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 | * http://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.checkdigit;
18 |
19 | /**
20 | * Check Digit calculation and validation.
21 | * 22 | * The logic for validating check digits has previously been 23 | * embedded within the logic for specific code validation, which 24 | * includes other validations such as verifying the format 25 | * or length of a code. {@link CheckDigit} provides for separating out 26 | * the check digit calculation logic enabling it to be more easily 27 | * tested and reused. 28 | *
29 | *30 | * Although Commons Validator is primarily concerned with validation, 31 | * {@link CheckDigit} also defines behaviour for calculating/generating check 32 | * digits, since it makes sense that users will want to (re-)use the 33 | * same logic for both. The {@link org.apache.commons.validator.routines.ISBNValidator} 34 | * makes specific use of this feature by providing the facility to validate ISBN-10 codes 35 | * and then convert them to the new ISBN-13 standard. 36 | *
37 | *38 | * CheckDigit is used by the new generic @link CodeValidator} implementation. 39 | *
40 | * 41 | *true
if the check digit is valid, otherwise
67 | * false
.
68 | */
69 | boolean isValid(String code);
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java:
--------------------------------------------------------------------------------
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 | * http://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.checkdigit;
18 |
19 | /**
20 | * Check Digit calculation/validation error.
21 | *
22 | * @version $Revision: 1649191 $
23 | * @since Validator 1.4
24 | */
25 | public class CheckDigitException extends Exception {
26 |
27 | private static final long serialVersionUID = -3519894732624685477L;
28 |
29 | /**
30 | * Construct an Exception with no message.
31 | */
32 | public CheckDigitException() {
33 | }
34 |
35 | /**
36 | * Construct an Exception with a message.
37 | *
38 | * @param msg The error message.
39 | */
40 | public CheckDigitException(String msg) {
41 | super(msg);
42 | }
43 |
44 | /**
45 | * Construct an Exception with a message and
46 | * the underlying cause.
47 | *
48 | * @param msg The error message.
49 | * @param cause The underlying cause of the error
50 | */
51 | public CheckDigitException(String msg, Throwable cause) {
52 | super(msg, cause);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/library/src/main/java/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java:
--------------------------------------------------------------------------------
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 | * http://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.checkdigit;
18 |
19 | /**
20 | * Modulus 10 Luhn Check Digit calculation/validation.
21 | *
22 | * Luhn check digits are used, for example, by:
23 | * 33 | * See Wikipedia 34 | * for more details. 35 | *
36 | * 37 | * @version $Revision: 1739356 $ 38 | * @since Validator 1.4 39 | */ 40 | public final class LuhnCheckDigit extends ModulusCheckDigit { 41 | 42 | private static final long serialVersionUID = -2976900113942875999L; 43 | 44 | /** Singleton Luhn Check Digit instance */ 45 | public static final CheckDigit LUHN_CHECK_DIGIT = new LuhnCheckDigit(); 46 | 47 | /** weighting given to digits depending on their right position */ 48 | private static final int[] POSITION_WEIGHT = new int[] {2, 1}; 49 | 50 | /** 51 | * Construct a modulus 10 Luhn Check Digit routine. 52 | */ 53 | public LuhnCheckDigit() { 54 | super(10); // CHECKSTYLE IGNORE MagicNumber 55 | } 56 | 57 | /** 58 | *Calculates the weighted value of a charcter in the 59 | * code at a specified position.
60 | * 61 | *For Luhn (from right to left) odd digits are weighted 62 | * with a factor of one and even digits with a factor 63 | * of two. Weighted values > 9, have 9 subtracted
64 | * 65 | * @param charValue The numeric value of the character. 66 | * @param leftPos The position of the character in the code, counting from left to right 67 | * @param rightPos The positionof the character in the code, counting from right to left 68 | * @return The weighted value of the character. 69 | */ 70 | @Override 71 | protected int weightedValue(int charValue, int leftPos, int rightPos) { 72 | int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber 73 | int weightedValue = charValue * weight; 74 | return weightedValue > 9 ? (weightedValue - 9) : weightedValue; // CHECKSTYLE IGNORE MagicNumber 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /library/src/main/java/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java: -------------------------------------------------------------------------------- 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 | * http://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.checkdigit; 18 | 19 | import java.io.Serializable; 20 | 21 | /** 22 | * Abstract Modulus Check digit calculation/validation. 23 | *24 | * Provides a base class for building modulus Check 25 | * Digit routines. 26 | *
27 | * This implementation only handles single-digit numeric codes, such as
28 | * EAN-13. For alphanumeric codes such as EAN-128 you
29 | * will need to implement/override the toInt()
and
30 | * toChar()
methods.
31 | *
32 | *
33 | * @version $Revision: 1739357 $
34 | * @since Validator 1.4
35 | */
36 | public abstract class ModulusCheckDigit implements CheckDigit, Serializable {
37 |
38 | private static final long serialVersionUID = 2948962251251528941L;
39 |
40 | // N.B. The modulus can be > 10 provided that the implementing class overrides toCheckDigit and toInt
41 | // (for example as in ISBN10CheckDigit)
42 | private final int modulus;
43 |
44 | /**
45 | * Construct a {@link CheckDigit} routine for a specified modulus.
46 | *
47 | * @param modulus The modulus value to use for the check digit calculation
48 | */
49 | public ModulusCheckDigit(int modulus) {
50 | this.modulus = modulus;
51 | }
52 |
53 | /**
54 | * Return the modulus value this check digit routine is based on.
55 | *
56 | * @return The modulus value this check digit routine is based on
57 | */
58 | public int getModulus() {
59 | return modulus;
60 | }
61 |
62 | /**
63 | * Validate a modulus check digit for a code.
64 | *
65 | * @param code The code to validate
66 | * @return true
if the check digit is valid, otherwise
67 | * false
68 | */
69 | @Override
70 | public boolean isValid(String code) {
71 | if (code == null || code.length() == 0) {
72 | return false;
73 | }
74 | try {
75 | int modulusResult = calculateModulus(code, true);
76 | return (modulusResult == 0);
77 | } catch (CheckDigitException ex) {
78 | return false;
79 | }
80 | }
81 |
82 | /**
83 | * Calculate a modulus Check Digit for a code which does not yet have one.
84 | *
85 | * @param code The code for which to calculate the Check Digit;
86 | * the check digit should not be included
87 | * @return The calculated Check Digit
88 | * @throws CheckDigitException if an error occurs calculating the check digit
89 | */
90 | @Override
91 | public String calculate(String code) throws CheckDigitException {
92 | if (code == null || code.length() == 0) {
93 | throw new CheckDigitException("Code is missing");
94 | }
95 | int modulusResult = calculateModulus(code, false);
96 | int charValue = (modulus - modulusResult) % modulus;
97 | return toCheckDigit(charValue);
98 | }
99 |
100 | /**
101 | * Calculate the modulus for a code.
102 | *
103 | * @param code The code to calculate the modulus for.
104 | * @param includesCheckDigit Whether the code includes the Check Digit or not.
105 | * @return The modulus value
106 | * @throws CheckDigitException if an error occurs calculating the modulus
107 | * for the specified code
108 | */
109 | protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException {
110 | int total = 0;
111 | for (int i = 0; i < code.length(); i++) {
112 | int lth = code.length() + (includesCheckDigit ? 0 : 1);
113 | int leftPos = i + 1;
114 | int rightPos = lth - i;
115 | int charValue = toInt(code.charAt(i), leftPos, rightPos);
116 | total += weightedValue(charValue, leftPos, rightPos);
117 | }
118 | if (total == 0) {
119 | throw new CheckDigitException("Invalid code, sum is zero");
120 | }
121 | return total % modulus;
122 | }
123 |
124 | /**
125 | * Calculates the weighted value of a character in the
126 | * code at a specified position.
127 | *
128 | * Some modulus routines weight the value of a character 129 | * depending on its position in the code (e.g. ISBN-10), while 130 | * others use different weighting factors for odd/even positions 131 | * (e.g. EAN or Luhn). Implement the appropriate mechanism 132 | * required by overriding this method. 133 | * 134 | * @param charValue The numeric value of the character 135 | * @param leftPos The position of the character in the code, counting from left to right 136 | * @param rightPos The positionof the character in the code, counting from right to left 137 | * @return The weighted value of the character 138 | * @throws CheckDigitException if an error occurs calculating 139 | * the weighted value 140 | */ 141 | protected abstract int weightedValue(int charValue, int leftPos, int rightPos) 142 | throws CheckDigitException; 143 | 144 | 145 | /** 146 | * Convert a character at a specified position to an integer value. 147 | *
148 | * Note: this implementation only handlers numeric values 149 | * For non-numeric characters, override this method to provide 150 | * character-->integer conversion. 151 | * 152 | * @param character The character to convert 153 | * @param leftPos The position of the character in the code, counting from left to right (for identifiying the position in the string) 154 | * @param rightPos The position of the character in the code, counting from right to left (not used here) 155 | * @return The integer value of the character 156 | * @throws CheckDigitException if character is non-numeric 157 | */ 158 | protected int toInt(char character, int leftPos, int rightPos) 159 | throws CheckDigitException { 160 | if (Character.isDigit(character)) { 161 | return Character.getNumericValue(character); 162 | } 163 | throw new CheckDigitException("Invalid Character[" + 164 | leftPos + "] = '" + character + "'"); 165 | } 166 | 167 | /** 168 | * Convert an integer value to a check digit. 169 | *
170 | * Note: this implementation only handles single-digit numeric values
171 | * For non-numeric characters, override this method to provide
172 | * integer-->character conversion.
173 | *
174 | * @param charValue The integer value of the character
175 | * @return The converted character
176 | * @throws CheckDigitException if integer character value
177 | * doesn't represent a numeric character
178 | */
179 | protected String toCheckDigit(int charValue)
180 | throws CheckDigitException {
181 | if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber
182 | return Integer.toString(charValue);
183 | }
184 | throw new CheckDigitException("Invalid Check Digit Value =" +
185 | + charValue);
186 | }
187 |
188 | /**
189 | * Add together the individual digits in a number.
190 | *
191 | * @param number The number whose digits are to be added
192 | * @return The sum of the digits
193 | */
194 | public static int sumDigits(int number) {
195 | int total = 0;
196 | int todo = number;
197 | while (todo > 0) {
198 | total += todo % 10; // CHECKSTYLE IGNORE MagicNumber
199 | todo = todo / 10; // CHECKSTYLE IGNORE MagicNumber
200 | }
201 | return total;
202 | }
203 |
204 | }
205 |
--------------------------------------------------------------------------------
/library/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |