Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java (.../Arg.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java (.../Arg.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -32,8 +32,6 @@ * The resource field defaults to 'true'. *

*

Instances of this class are configured with an <arg> xml element.

- * - * @version $Revision: 1739356 $ */ //TODO mutable non-private fields public class Arg implements Cloneable, Serializable { @@ -43,24 +41,24 @@ /** * The resource bundle name that this Arg's key should be * resolved in (optional). - * @since Validator 1.1 + * @since 1.1 */ - protected String bundle = null; + protected String bundle; /** * The key or value of the argument. */ - protected String key = null; + protected String key; /** * The name dependency that this argument goes with (optional). */ - protected String name = null; + protected String name; /** * This argument's position in the message. Set postion=0 to * make a replacement in this string: "some msg {0}". - * @since Validator 1.1 + * @since 1.1 */ protected int position = -1; @@ -80,15 +78,15 @@ try { return super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e.toString()); + } catch (final CloneNotSupportedException e) { + throw new UnsupportedOperationException(e.toString(), e); } } /** * Returns the resource bundle name. * @return the bundle name. - * @since Validator 1.1 + * @since 1.1 */ public String getBundle() { return this.bundle; @@ -120,7 +118,7 @@ /** * Tests whether or not the key is a resource key or literal value. - * @return true if key is a resource key. + * @return {@code true} if key is a resource key. */ public boolean isResource() { return this.resource; @@ -129,41 +127,41 @@ /** * Sets the resource bundle name. * @param bundle The new bundle name. - * @since Validator 1.1 + * @since 1.1 */ - public void setBundle(String bundle) { + public void setBundle(final String bundle) { this.bundle = bundle; } /** * Sets the key/value. * @param key They to access the argument. */ - public void setKey(String key) { + public void setKey(final String key) { this.key = key; } /** * Sets the name of the dependency. * @param name the name of the dependency. */ - public void setName(String name) { + public void setName(final String name) { this.name = name; } /** - * Set this argument's replacement position. + * Sets this argument's replacement position. * @param position set this argument's replacement position. */ - public void setPosition(int position) { + public void setPosition(final int position) { this.position = position; } /** * Sets whether or not the key is a resource. * @param resource If true indicates the key is a resource. */ - public void setResource(boolean resource) { + public void setResource(final boolean resource) { this.resource = resource; } @@ -173,7 +171,7 @@ */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("Arg: name="); results.append(name); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java (.../CreditCardValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java (.../CreditCardValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -48,16 +48,80 @@ * here. *

* - * @version $Revision: 1739358 $ - * @since Validator 1.1 + * @since 1.1 * @deprecated Use the new CreditCardValidator in the routines package. This class * will be removed in a future release. */ // CHECKSTYLE:OFF (deprecated code) @Deprecated public class CreditCardValidator { + private static class Amex implements CreditCardType { + static final Amex INSTANCE = new Amex(); + private static final String PREFIX = "34,37,"; + @Override + public boolean matches(final String card) { + final String prefix2 = card.substring(0, 2) + ","; + return PREFIX.contains(prefix2) && card.length() == 15; + } + } + /** + * CreditCardType implementations define how validation is performed + * for one type/brand of credit card. + * @since 1.1.2 + */ + public interface CreditCardType { + + /** + * Returns true if the card number matches this type of credit + * card. Note that this method is not responsible + * for analyzing the general form of the card number because + * CreditCardValidator performs those checks before + * calling this method. It is generally only required to valid the + * length and prefix of the number to determine if it's the correct + * type. + * @param card The card number, never null. + * @return true if the number matches. + */ + boolean matches(String card); + + } + + private static class Discover implements CreditCardType { + static final Discover INSTANCE = new Discover(); + private static final String PREFIX = "6011"; + @Override + public boolean matches(final String card) { + return card.substring(0, 4).equals(PREFIX) && card.length() == 16; + } + } + + private static class Mastercard implements CreditCardType { + static final Mastercard INSTANCE = new Mastercard(); + private static final String PREFIX = "51,52,53,54,55,"; + @Override + public boolean matches(final String card) { + final String prefix2 = card.substring(0, 2) + ","; + return PREFIX.contains(prefix2) && card.length() == 16; + } + } + + /** + * Change to support Visa Carte Blue used in France + * has been removed - see Bug 35926 + */ + private static class Visa implements CreditCardType { + static final Visa INSTANCE = new Visa(); + private static final String PREFIX = "4"; + + @Override + public boolean matches(final String card) { + return card.substring(0, 1).equals(PREFIX) && (card.length() == 13 || card.length() == 16); + } + } + + /** * Option specifying that no cards are allowed. This is useful if * you want only custom card types to validate so you turn off the * default cards with this option. @@ -68,7 +132,7 @@ * v.isValid(aCardNumber); * * - * @since Validator 1.1.2 + * @since 1.1.2 */ public static final int NONE = 0; @@ -95,7 +159,7 @@ /** * The CreditCardTypes that are allowed to pass validation. */ - private final Collection cardTypes = new ArrayList(); + private final Collection cardTypes = new ArrayList<>(); /** * Create a new CreditCardValidator with default options. @@ -110,43 +174,51 @@ * CreditCardValidator.VISA + CreditCardValidator.AMEX to specify that * those are the only valid card types. */ - public CreditCardValidator(int options) { - super(); - - Flags f = new Flags(options); + public CreditCardValidator(final int options) { + final Flags f = new Flags(options); if (f.isOn(VISA)) { - this.cardTypes.add(new Visa()); + this.cardTypes.add(Visa.INSTANCE); } if (f.isOn(AMEX)) { - this.cardTypes.add(new Amex()); + this.cardTypes.add(Amex.INSTANCE); } if (f.isOn(MASTERCARD)) { - this.cardTypes.add(new Mastercard()); + this.cardTypes.add(Mastercard.INSTANCE); } if (f.isOn(DISCOVER)) { - this.cardTypes.add(new Discover()); + this.cardTypes.add(Discover.INSTANCE); } } /** + * Adds an allowed CreditCardType that participates in the card + * validation algorithm. + * @param type The type that is now allowed to pass validation. + * @since 1.1.2 + */ + public void addAllowedCardType(final CreditCardType type){ + this.cardTypes.add(type); + } + + /** * Checks if the field is a valid credit card number. * @param card The card number to validate. * @return Whether the card number is valid. */ - public boolean isValid(String card) { - if ((card == null) || (card.length() < 13) || (card.length() > 19)) { + public boolean isValid(final String card) { + if (card == null || card.length() < 13 || card.length() > 19) { return false; } if (!this.luhnCheck(card)) { return false; } - for (Object cardType : this.cardTypes) { - CreditCardType type = (CreditCardType) cardType; + for (final Object cardType : this.cardTypes) { + final CreditCardType type = (CreditCardType) cardType; if (type.matches(card)) { return true; } @@ -156,34 +228,24 @@ } /** - * Adds an allowed CreditCardType that participates in the card - * validation algorithm. - * @param type The type that is now allowed to pass validation. - * @since Validator 1.1.2 - */ - public void addAllowedCardType(CreditCardType type){ - this.cardTypes.add(type); - } - - /** * Checks for a valid credit card number. * @param cardNumber Credit Card Number. * @return Whether the card number passes the luhnCheck. */ - protected boolean luhnCheck(String cardNumber) { + protected boolean luhnCheck(final String cardNumber) { // number must be validated as 0..9 numeric first!! - int digits = cardNumber.length(); - int oddOrEven = digits & 1; + final int digits = cardNumber.length(); + final int oddOrEven = digits & 1; long sum = 0; for (int count = 0; count < digits; count++) { int digit = 0; try { digit = Integer.parseInt(cardNumber.charAt(count) + ""); - } catch(NumberFormatException e) { + } catch (final NumberFormatException e) { return false; } - if (((count & 1) ^ oddOrEven) == 0) { // not + if ((count & 1 ^ oddOrEven) == 0) { // not digit *= 2; if (digit > 9) { digit -= 9; @@ -192,69 +254,7 @@ sum += digit; } - return (sum == 0) ? false : (sum % 10 == 0); + return sum == 0 ? false : sum % 10 == 0; } - /** - * CreditCardType implementations define how validation is performed - * for one type/brand of credit card. - * @since Validator 1.1.2 - */ - public interface CreditCardType { - - /** - * Returns true if the card number matches this type of credit - * card. Note that this method is not responsible - * for analyzing the general form of the card number because - * CreditCardValidator performs those checks before - * calling this method. It is generally only required to valid the - * length and prefix of the number to determine if it's the correct - * type. - * @param card The card number, never null. - * @return true if the number matches. - */ - boolean matches(String card); - - } - - /** - * Change to support Visa Carte Blue used in France - * has been removed - see Bug 35926 - */ - private static class Visa implements CreditCardType { - private static final String PREFIX = "4"; - @Override - public boolean matches(String card) { - return ( - card.substring(0, 1).equals(PREFIX) - && (card.length() == 13 || card.length() == 16)); - } - } - - private static class Amex implements CreditCardType { - private static final String PREFIX = "34,37,"; - @Override - public boolean matches(String card) { - String prefix2 = card.substring(0, 2) + ","; - return ((PREFIX.contains(prefix2)) && (card.length() == 15)); - } - } - - private static class Discover implements CreditCardType { - private static final String PREFIX = "6011"; - @Override - public boolean matches(String card) { - return (card.substring(0, 4).equals(PREFIX) && (card.length() == 16)); - } - } - - private static class Mastercard implements CreditCardType { - private static final String PREFIX = "51,52,53,54,55,"; - @Override - public boolean matches(String card) { - String prefix2 = card.substring(0, 2) + ","; - return ((PREFIX.contains(prefix2)) && (card.length() == 16)); - } - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/DateValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/DateValidator.java (.../DateValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/DateValidator.java (.../DateValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -28,8 +28,7 @@ * getInstance() method. *

* - * @version $Revision: 1739358 $ - * @since Validator 1.1 + * @since 1.1 * @deprecated Use the new DateValidator, CalendarValidator or TimeValidator in the * routines package. This class will be removed in a future release. */ @@ -53,80 +52,79 @@ * Protected constructor for subclasses to use. */ protected DateValidator() { - super(); } /** - *

Checks if the field is a valid date. The pattern is used with - * java.text.SimpleDateFormat. If strict is true, then the - * length will be checked so '2/12/1999' will not pass validation with - * the format 'MM/dd/yyyy' because the month isn't two digits. - * The setLenient method is set to false for all.

+ *

Checks if the field is a valid date. The Locale is + * used with java.text.DateFormat. The setLenient method + * is set to {@code false} for all.

* * @param value The value validation is being performed on. - * @param datePattern The pattern passed to SimpleDateFormat. - * @param strict Whether or not to have an exact match of the datePattern. + * @param locale The locale to use for the date format, defaults to the default + * system default if null. * @return true if the date is valid. */ - public boolean isValid(String value, String datePattern, boolean strict) { + public boolean isValid(final String value, final Locale locale) { - if (value == null - || datePattern == null - || datePattern.length() <= 0) { - + if (value == null) { return false; } - SimpleDateFormat formatter = new SimpleDateFormat(datePattern); + DateFormat formatter; + if (locale != null) { + formatter = DateFormat.getDateInstance(DateFormat.SHORT, locale); + } else { + formatter = + DateFormat.getDateInstance( + DateFormat.SHORT, + Locale.getDefault()); + } + formatter.setLenient(false); try { formatter.parse(value); - } catch(ParseException e) { + } catch (final ParseException e) { return false; } - if (strict && (datePattern.length() != value.length())) { - return false; - } - return true; } /** - *

Checks if the field is a valid date. The Locale is - * used with java.text.DateFormat. The setLenient method - * is set to false for all.

+ *

Checks if the field is a valid date. The pattern is used with + * java.text.SimpleDateFormat. If strict is true, then the + * length will be checked so '2/12/1999' will not pass validation with + * the format 'MM/dd/yyyy' because the month isn't two digits. + * The setLenient method is set to {@code false} for all.

* * @param value The value validation is being performed on. - * @param locale The locale to use for the date format, defaults to the default - * system default if null. + * @param datePattern The pattern passed to SimpleDateFormat. + * @param strict Whether or not to have an exact match of the datePattern. * @return true if the date is valid. */ - public boolean isValid(String value, Locale locale) { + public boolean isValid(final String value, final String datePattern, final boolean strict) { - if (value == null) { + if (value == null + || datePattern == null + || datePattern.isEmpty()) { + return false; } - DateFormat formatter = null; - if (locale != null) { - formatter = DateFormat.getDateInstance(DateFormat.SHORT, locale); - } else { - formatter = - DateFormat.getDateInstance( - DateFormat.SHORT, - Locale.getDefault()); - } - + final SimpleDateFormat formatter = new SimpleDateFormat(datePattern); formatter.setLenient(false); try { formatter.parse(value); - } catch(ParseException e) { + } catch (final ParseException e) { return false; } + if (strict && datePattern.length() != value.length()) { + return false; + } + return true; } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java (.../EmailValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java (.../EmailValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,11 +16,11 @@ */ package org.apache.commons.validator; -import org.apache.commons.validator.routines.InetAddressValidator; - import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.validator.routines.InetAddressValidator; + /** *

Perform email validations.

*

@@ -36,8 +36,7 @@ * is no TLD "somedog" *

. * - * @version $Revision: 1739358 $ - * @since Validator 1.1 + * @since 1.1 * @deprecated Use the new EmailValidator in the routines package. This class * will be removed in a future release. */ @@ -54,7 +53,7 @@ // NOT USED private static final Pattern EMAIL_PATTERN = Pattern.compile("^(.+)@(.+)$"); private static final Pattern IP_DOMAIN_PATTERN = Pattern.compile("^\\[(.*)\\]$"); private static final Pattern TLD_PATTERN = Pattern.compile("^([a-zA-Z]+)$"); - + private static final Pattern USER_PATTERN = Pattern.compile("^\\s*" + WORD + "(\\." + WORD + ")*$"); private static final Pattern DOMAIN_PATTERN = Pattern.compile("^" + ATOM + "(\\." + ATOM + ")*\\s*$"); private static final Pattern ATOM_PATTERN = Pattern.compile("(" + ATOM + ")"); @@ -76,7 +75,6 @@ * Protected constructor for subclasses to use. */ protected EmailValidator() { - super(); } /** @@ -86,7 +84,7 @@ * value is considered invalid. * @return true if the email address is valid. */ - public boolean isValid(String email) { + public boolean isValid(final String email) { return org.apache.commons.validator.routines.EmailValidator.getInstance().isValid(email); } @@ -95,14 +93,14 @@ * @param domain being validated. * @return true if the email address's domain is valid. */ - protected boolean isValidDomain(String domain) { + protected boolean isValidDomain(final String domain) { boolean symbolic = false; // see if domain is an IP address in brackets - Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); + final Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); if (ipDomainMatcher.matches()) { - InetAddressValidator inetAddressValidator = + final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); if (inetAddressValidator.isValid(ipDomainMatcher.group(1))) { return true; @@ -112,44 +110,34 @@ symbolic = DOMAIN_PATTERN.matcher(domain).matches(); } - if (symbolic) { - if (!isValidSymbolicDomain(domain)) { - return false; - } - } else { + if (!symbolic) { return false; } + if (!isValidSymbolicDomain(domain)) { + return false; + } return true; } /** - * Returns true if the user component of an email address is valid. - * @param user being validated - * @return true if the user name is valid. - */ - protected boolean isValidUser(String user) { - return USER_PATTERN.matcher(user).matches(); - } - - /** * Validates an IP address. Returns true if valid. * @param ipAddress IP address * @return true if the ip address is valid. */ - protected boolean isValidIpAddress(String ipAddress) { - Matcher ipAddressMatcher = IP_DOMAIN_PATTERN.matcher(ipAddress); + protected boolean isValidIpAddress(final String ipAddress) { + final Matcher ipAddressMatcher = IP_DOMAIN_PATTERN.matcher(ipAddress); for (int i = 1; i <= 4; i++) { // CHECKSTYLE IGNORE MagicNumber - String ipSegment = ipAddressMatcher.group(i); - if (ipSegment == null || ipSegment.length() <= 0) { + final String ipSegment = ipAddressMatcher.group(i); + if (ipSegment == null || ipSegment.isEmpty()) { return false; } int iIpSegment = 0; try { iIpSegment = Integer.parseInt(ipSegment); - } catch(NumberFormatException e) { + } catch (final NumberFormatException e) { return false; } @@ -167,60 +155,66 @@ * @return true if the symbolic domain name is valid. */ protected boolean isValidSymbolicDomain(String domain) { - String[] domainSegment = new String[10]; // CHECKSTYLE IGNORE MagicNumber + final String[] domainSegment = new String[10]; // CHECKSTYLE IGNORE MagicNumber boolean match = true; int i = 0; - Matcher atomMatcher = ATOM_PATTERN.matcher(domain); + final Matcher atomMatcher = ATOM_PATTERN.matcher(domain); while (match) { match = atomMatcher.matches(); if (match) { domainSegment[i] = atomMatcher.group(1); - int l = domainSegment[i].length() + 1; + final int l = domainSegment[i].length() + 1; domain = - (l >= domain.length()) + l >= domain.length() ? "" : domain.substring(l); i++; - } + } } - int len = i; - + final int len = i; + // Make sure there's a host name preceding the domain. if (len < 2) { return false; } - - // TODO: the tld should be checked against some sort of configurable - // list - String tld = domainSegment[len - 1]; - if (tld.length() > 1) { - if (! TLD_PATTERN.matcher(tld).matches()) { - return false; - } - } else { + + final String tld = domainSegment[len - 1]; + if (tld.length() <= 1) { return false; } + if (! TLD_PATTERN.matcher(tld).matches()) { + return false; + } return true; } + /** - * Recursively remove comments, and replace with a single space. The simpler - * regexps in the Email Addressing FAQ are imperfect - they will miss escaped - * chars in atoms, for example. - * Derived From Mail::RFC822::Address + * Returns true if the user component of an email address is valid. + * @param user being validated + * @return true if the user name is valid. + */ + protected boolean isValidUser(final String user) { + return USER_PATTERN.matcher(user).matches(); + } + + /** + * Recursively remove comments, and replace with a single space. The simpler regexps in the Email Addressing FAQ are imperfect - they will miss escaped + * chars in atoms, for example. Derived From Mail::RFC822::Address + * * @param emailStr The email address * @return address with comments removed. - */ - protected String stripComments(String emailStr) { - String result = emailStr; - String commentPat = "^((?:[^\"\\\\]|\\\\.)*(?:\"(?:[^\"\\\\]|\\\\.)*\"(?:[^\"\\\\]|\111111\\\\.)*)*)\\((?:[^()\\\\]|\\\\.)*\\)/"; - Pattern commentMatcher = Pattern.compile(commentPat); - - while (commentMatcher.matcher(result).matches()) { - result = result.replaceFirst(commentPat, "\1 "); - } - return result; + */ + protected String stripComments(final String emailStr) { + String result = emailStr; + final String commentPat = "^((?:[^\"\\\\]|\\\\.)*(?:\"(?:[^\"\\\\]|\\\\.)*\"(?:[^\"\\\\]|\111111\\\\.)*)*)\\((?:[^()\\\\]|\\\\.)*\\)/"; + final Pattern commentMatcher = Pattern.compile(commentPat); + + while (commentMatcher.matcher(result).matches()) { + result = result.replaceFirst(commentPat, "\1 "); + } + return result; } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java (.../Field.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java (.../Field.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -22,7 +22,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -42,7 +41,6 @@ * release. *

* - * @version $Revision: 1739361 $ * @see org.apache.commons.validator.Form */ // TODO mutable non-private fields @@ -80,52 +78,52 @@ /** * The Field's property name. */ - protected String property = null; + protected String property; /** * The Field's indexed property name. */ - protected String indexedProperty = null; + protected String indexedProperty; /** * The Field's indexed list property name. */ - protected String indexedListProperty = null; + protected String indexedListProperty; /** * The Field's unique key. */ - protected String key = null; + protected String key; /** * A comma separated list of validator's this field depends on. */ - protected String depends = null; + protected String depends; /** * The Page Number */ - protected int page = 0; + protected int page; /** * The flag that indicates whether scripting should be generated * by the client for client-side validation. - * @since Validator 1.4 + * @since 1.4 */ protected boolean clientValidation = true; /** * The order of the Field in the Form. */ - protected int fieldOrder = 0; + protected int fieldOrder; /** * Internal representation of this.depends String as a List. This List * gets updated whenever setDepends() gets called. This List is * synchronized so a call to setDepends() (which clears the List) won't * interfere with a call to isDependency(). */ - private final List dependencyList = Collections.synchronizedList(new ArrayList()); + private final List dependencyList = Collections.synchronizedList(new ArrayList<>()); /** * @deprecated Subclasses should use getVarMap() instead. @@ -143,220 +141,104 @@ * Holds Maps of arguments. args[0] returns the Map for the first * replacement argument. Start with a 0 length array so that it will * only grow to the size of the highest argument position. - * @since Validator 1.1 + * @since 1.1 */ @SuppressWarnings("unchecked") // cannot instantiate generic array, so have to assume this is OK protected Map[] args = new Map[0]; /** - * Gets the page value that the Field is associated with for - * validation. - * @return The page number. + * Add an Arg to the replacement argument list. + * @since 1.1 + * @param arg Validation message's argument. */ - public int getPage() { - return this.page; - } + public void addArg(final Arg arg) { + // TODO this first if check can go away after arg0, etc. are removed from dtd + if (arg == null || arg.getKey() == null || arg.getKey().isEmpty()) { + return; + } - /** - * Sets the page value that the Field is associated with for - * validation. - * @param page The page number. - */ - public void setPage(int page) { - this.page = page; - } + determineArgPosition(arg); + ensureArgsCapacity(arg); - /** - * Gets the position of the Field in the validation list. - * @return The field position. - */ - public int getFieldOrder() { - return this.fieldOrder; - } + Map argMap = this.args[arg.getPosition()]; + if (argMap == null) { + argMap = new HashMap<>(); + this.args[arg.getPosition()] = argMap; + } - /** - * Sets the position of the Field in the validation list. - * @param fieldOrder The field position. - */ - public void setFieldOrder(int fieldOrder) { - this.fieldOrder = fieldOrder; - } + if (arg.getName() == null) { + argMap.put(DEFAULT_ARG, arg); + } else { + argMap.put(arg.getName(), arg); + } - /** - * Gets the property name of the field. - * @return The field's property name. - */ - public String getProperty() { - return this.property; } /** - * Sets the property name of the field. - * @param property The field's property name. - */ - public void setProperty(String property) { - this.property = property; - } - - /** - * Gets the indexed property name of the field. This - * is the method name that can take an int as - * a parameter for indexed property value retrieval. - * @return The field's indexed property name. - */ - public String getIndexedProperty() { - return this.indexedProperty; - } - - /** - * Sets the indexed property name of the field. - * @param indexedProperty The field's indexed property name. - */ - public void setIndexedProperty(String indexedProperty) { - this.indexedProperty = indexedProperty; - } - - /** - * Gets the indexed property name of the field. This - * is the method name that will return an array or a - * Collection used to retrieve the - * list and then loop through the list performing the specified - * validations. - * @return The field's indexed List property name. - */ - public String getIndexedListProperty() { - return this.indexedListProperty; - } - - /** - * Sets the indexed property name of the field. - * @param indexedListProperty The field's indexed List property name. - */ - public void setIndexedListProperty(String indexedListProperty) { - this.indexedListProperty = indexedListProperty; - } - - /** - * Gets the validation rules for this field as a comma separated list. - * @return A comma separated list of validator names. - */ - public String getDepends() { - return this.depends; - } - - /** - * Sets the validation rules for this field as a comma separated list. - * @param depends A comma separated list of validator names. - */ - public void setDepends(String depends) { - this.depends = depends; - - this.dependencyList.clear(); - - StringTokenizer st = new StringTokenizer(depends, ","); - while (st.hasMoreTokens()) { - String depend = st.nextToken().trim(); - - if (depend != null && depend.length() > 0) { - this.dependencyList.add(depend); - } - } - } - - /** * Add a Msg to the Field. * @param msg A validation message. */ - public void addMsg(Msg msg) { + public void addMsg(final Msg msg) { getMsgMap().put(msg.getName(), msg); } /** - * Retrieve a message value. - * @param key Validation key. - * @return A validation message for a specified validator. + * Add a Var, based on the values passed in, to the + * Field. + * @param name Name of the validation. + * @param value The Argument's value. + * @param jsType The JavaScript type. */ - public String getMsg(String key) { - Msg msg = getMessage(key); - return (msg == null) ? null : msg.getKey(); + public void addVar(final String name, final String value, final String jsType) { + this.addVar(new Var(name, value, jsType)); } /** - * Retrieve a message object. - * @since Validator 1.1.4 - * @param key Validation key. - * @return A validation message for a specified validator. + * Add a Var to the Field. + * @param v The Validator Argument. */ - public Msg getMessage(String key) { - return getMsgMap().get(key); + public void addVar(final Var v) { + this.getVarMap().put(v.getName(), v); } /** - * The Field's messages are returned as an - * unmodifiable Map. - * @since Validator 1.1.4 - * @return Map of validation messages for the field. + * Creates and returns a copy of this object. + * @return A copy of the Field. */ - public Map getMessages() { - return Collections.unmodifiableMap(getMsgMap()); - } - - /** - * Determines whether client-side scripting should be generated - * for this field. The default is true - * @return true for scripting; otherwise false - * @see #setClientValidation(boolean) - * @since Validator 1.4 - */ - public boolean isClientValidation() { - return this.clientValidation; - } - - /** - * Sets the flag that determines whether client-side scripting should - * be generated for this field. - * @param clientValidation the scripting flag - * @see #isClientValidation() - * @since Validator 1.4 - */ - public void setClientValidation(boolean clientValidation) { - this.clientValidation = clientValidation; - } - - /** - * Add an Arg to the replacement argument list. - * @since Validator 1.1 - * @param arg Validation message's argument. - */ - public void addArg(Arg arg) { - // TODO this first if check can go away after arg0, etc. are removed from dtd - if (arg == null || arg.getKey() == null || arg.getKey().length() == 0) { - return; + @Override + public Object clone() { + Field field = null; + try { + field = (Field) super.clone(); + } catch (final CloneNotSupportedException e) { + throw new UnsupportedOperationException(e.toString(), e); } - determineArgPosition(arg); - ensureArgsCapacity(arg); + @SuppressWarnings("unchecked") // empty array always OK; cannot check this at compile time + final Map[] tempMap = new Map[this.args.length]; + field.args = tempMap; + for (int i = 0; i < this.args.length; i++) { + if (this.args[i] == null) { + continue; + } - Map argMap = this.args[arg.getPosition()]; - if (argMap == null) { - argMap = new HashMap(); - this.args[arg.getPosition()] = argMap; + final Map argMap = new HashMap<>(this.args[i]); + argMap.forEach((validatorName, arg) -> argMap.put(validatorName, (Arg) arg.clone())); + field.args[i] = argMap; } - if (arg.getName() == null) { - argMap.put(DEFAULT_ARG, arg); - } else { - argMap.put(arg.getName(), arg); - } + field.hVars = ValidatorUtils.copyFastHashMap(hVars); + field.hMsgs = ValidatorUtils.copyFastHashMap(hMsgs); + return field; } /** * Calculate the position of the Arg */ - private void determineArgPosition(Arg arg) { + private void determineArgPosition(final Arg arg) { - int position = arg.getPosition(); + final int position = arg.getPosition(); // position has been explicity set if (position >= 0) { @@ -371,11 +253,11 @@ // determine the position of the last argument with // the same name or the last default argument - String key = arg.getName() == null ? DEFAULT_ARG : arg.getName(); + final String keyName = arg.getName() == null ? DEFAULT_ARG : arg.getName(); int lastPosition = -1; - int lastDefault = -1; + int lastDefault = -1; for (int i = 0; i < args.length; i++) { - if (args[i] != null && args[i].containsKey(key)) { + if (args[i] != null && args[i].containsKey(keyName)) { lastPosition = i; } if (args[i] != null && args[i].containsKey(DEFAULT_ARG)) { @@ -398,22 +280,34 @@ * @param arg Determine if the args array is long enough to store this arg's * position. */ - private void ensureArgsCapacity(Arg arg) { + private void ensureArgsCapacity(final Arg arg) { if (arg.getPosition() >= this.args.length) { @SuppressWarnings("unchecked") // cannot check this at compile time, but it is OK + final Map[] newArgs = new Map[arg.getPosition() + 1]; System.arraycopy(this.args, 0, newArgs, 0, this.args.length); this.args = newArgs; } } /** + * Generate correct key value. + */ + public void generateKey() { + if (this.isIndexed()) { + this.key = this.indexedListProperty + TOKEN_INDEXED + "." + this.property; + } else { + this.key = this.property; + } + } + + /** * Gets the default Arg object at the given position. * @param position Validation message argument's position. * @return The default Arg or null if not found. - * @since Validator 1.1 + * @since 1.1 */ - public Arg getArg(int position) { + public Arg getArg(final int position) { return this.getArg(DEFAULT_ARG, position); } @@ -425,93 +319,145 @@ * Arg for the given position (if any) will be retrieved. * @param position The Arg number to find. * @return The Arg with the given name and position or null if not found. - * @since Validator 1.1 + * @since 1.1 */ - public Arg getArg(String key, int position) { - if ((position >= this.args.length) || (this.args[position] == null)) { + public Arg getArg(final String key, final int position) { + if (position >= this.args.length || this.args[position] == null) { return null; } - Arg arg = args[position].get(key); + final Arg arg = args[position].get(key); // Didn't find default arg so exit, otherwise we would get into // infinite recursion - if ((arg == null) && key.equals(DEFAULT_ARG)) { + if (arg == null && key.equals(DEFAULT_ARG)) { return null; } - return (arg == null) ? this.getArg(position) : arg; + return arg == null ? this.getArg(position) : arg; } /** * Retrieves the Args for the given validator name. * @param key The validator's args to retrieve. * @return An Arg[] sorted by the Args' positions (i.e. the Arg at index 0 * has a position of 0). - * @since Validator 1.1.1 + * @since 1.1.1 */ - public Arg[] getArgs(String key){ - Arg[] args = new Arg[this.args.length]; + public Arg[] getArgs(final String key) { + final Arg[] argList = new Arg[this.args.length]; for (int i = 0; i < this.args.length; i++) { - args[i] = this.getArg(key, i); + argList[i] = this.getArg(key, i); } - return args; + return argList; } /** - * Add a Var to the Field. - * @param v The Validator Argument. + * Gets an unmodifiable List of the dependencies in the same + * order they were defined in parameter passed to the setDepends() method. + * @return A list of the Field's dependancies. */ - public void addVar(Var v) { - this.getVarMap().put(v.getName(), v); + public List getDependencyList() { + return Collections.unmodifiableList(this.dependencyList); } /** - * Add a Var, based on the values passed in, to the - * Field. - * @param name Name of the validation. - * @param value The Argument's value. - * @param jsType The Javascript type. + * Gets the validation rules for this field as a comma separated list. + * @return A comma separated list of validator names. */ - public void addVar(String name, String value, String jsType) { - this.addVar(new Var(name, value, jsType)); + public String getDepends() { + return this.depends; } /** - * Retrieve a variable. - * @param mainKey The Variable's key - * @return the Variable + * Gets the position of the Field in the validation list. + * @return The field position. */ - public Var getVar(String mainKey) { - return getVarMap().get(mainKey); + public int getFieldOrder() { + return this.fieldOrder; } /** - * Retrieve a variable's value. - * @param mainKey The Variable's key - * @return the Variable's value + * Gets the indexed property name of the field. This + * is the method name that will return an array or a + * Collection used to retrieve the + * list and then loop through the list performing the specified + * validations. + * @return The field's indexed List property name. */ - public String getVarValue(String mainKey) { - String value = null; + public String getIndexedListProperty() { + return this.indexedListProperty; + } - Object o = getVarMap().get(mainKey); - if (o != null && o instanceof Var) { - Var v = (Var) o; - value = v.getValue(); + /** + * Gets the indexed property name of the field. This + * is the method name that can take an int as + * a parameter for indexed property value retrieval. + * @return The field's indexed property name. + */ + public String getIndexedProperty() { + return this.indexedProperty; + } + + /** + * Returns an indexed property from the object we're validating. + * + * @param bean The bean to extract the indexed values from. + * @throws ValidatorException If there's an error looking up the property + * or, the property found is not indexed. + */ + Object[] getIndexedProperty(final Object bean) throws ValidatorException { + Object indexProp = null; + + try { + indexProp = PropertyUtils.getProperty(bean, this.getIndexedListProperty()); + + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new ValidatorException(e.getMessage()); } - return value; + if (indexProp instanceof Collection) { + return ((Collection) indexProp).toArray(); + + } + if (indexProp.getClass().isArray()) { + return (Object[]) indexProp; + + } + throw new ValidatorException(this.getKey() + " is not indexed"); + } /** - * The Field's variables are returned as an - * unmodifiable Map. - * @return the Map of Variable's for a Field. + * Returns the size of an indexed property from the object we're validating. + * + * @param bean The bean to extract the indexed values from. + * @throws ValidatorException If there's an error looking up the property + * or, the property found is not indexed. */ - public Map getVars() { - return Collections.unmodifiableMap(getVarMap()); + private int getIndexedPropertySize(final Object bean) throws ValidatorException { + Object indexProp = null; + + try { + indexProp = PropertyUtils.getProperty(bean, this.getIndexedListProperty()); + + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new ValidatorException(e.getMessage()); + } + + if (indexProp == null) { + return 0; + } + if (indexProp instanceof Collection) { + return ((Collection) indexProp).size(); + } + if (indexProp.getClass().isArray()) { + return ((Object[]) indexProp).length; + } + throw new ValidatorException(this.getKey() + " is not indexed"); + } /** @@ -527,51 +473,162 @@ } /** - * Sets a unique key for the field. This can be used to change - * the key temporarily to have a unique key for an indexed field. - * @param key a unique key for the field + * Retrieve a message object. + * @since 1.1.4 + * @param key Validation key. + * @return A validation message for a specified validator. */ - public void setKey(String key) { - this.key = key; + public Msg getMessage(final String key) { + return getMsgMap().get(key); } /** - * If there is a value specified for the indexedProperty field then - * true will be returned. Otherwise it will be - * false. - * @return Whether the Field is indexed. + * The Field's messages are returned as an + * unmodifiable Map. + * @since 1.1.4 + * @return Map of validation messages for the field. */ - public boolean isIndexed() { - return ((indexedListProperty != null && indexedListProperty.length() > 0)); + public Map getMessages() { + return Collections.unmodifiableMap(getMsgMap()); } /** - * Generate correct key value. + * Retrieve a message value. + * @param key Validation key. + * @return A validation message for a specified validator. */ - public void generateKey() { - if (this.isIndexed()) { - this.key = this.indexedListProperty + TOKEN_INDEXED + "." + this.property; - } else { - this.key = this.property; + public String getMsg(final String key) { + final Msg msg = getMessage(key); + return msg == null ? null : msg.getKey(); + } + + /** + * Returns a Map of String Msg names to Msg objects. + * @since 1.2.0 + * @return A Map of the Field's messages. + */ + @SuppressWarnings("unchecked") // FastHashMap does not support generics + protected Map getMsgMap() { + return hMsgs; + } + + /** + * Gets the page value that the Field is associated with for + * validation. + * @return The page number. + */ + public int getPage() { + return this.page; + } + + /** + * Gets the property name of the field. + * @return The field's property name. + */ + public String getProperty() { + return this.property; + } + + /** + * Retrieve a variable. + * @param mainKey The Variable's key + * @return the Variable + */ + public Var getVar(final String mainKey) { + return getVarMap().get(mainKey); + } + + /** + * Returns a Map of String Var names to Var objects. + * @since 1.2.0 + * @return A Map of the Field's variables. + */ + @SuppressWarnings("unchecked") // FastHashMap does not support generics + protected Map getVarMap() { + return hVars; + } + + /** + * The Field's variables are returned as an + * unmodifiable Map. + * @return the Map of Variable's for a Field. + */ + public Map getVars() { + return Collections.unmodifiableMap(getVarMap()); + } + + /** + * Retrieve a variable's value. + * @param mainKey The Variable's key + * @return the Variable's value + */ + public String getVarValue(final String mainKey) { + String value = null; + + final Var v = getVarMap().get(mainKey); + if (v != null) { + value = v.getValue(); } + + return value; } /** + * Called when a validator name is used in a depends clause but there is + * no know ValidatorAction configured for that name. + * @param name The name of the validator in the depends list. + * @throws ValidatorException + */ + private void handleMissingAction(final String name) throws ValidatorException { + throw new ValidatorException("No ValidatorAction named " + name + + " found for field " + this.getProperty()); + } + + /** + * Determines whether client-side scripting should be generated + * for this field. The default is {@code true} + * @return {@code true} for scripting; otherwise false + * @see #setClientValidation(boolean) + * @since 1.4 + */ + public boolean isClientValidation() { + return this.clientValidation; + } + + /** + * Checks if the validator is listed as a dependency. + * @param validatorName Name of the validator to check. + * @return Whether the field is dependant on a validator. + */ + public boolean isDependency(final String validatorName) { + return this.dependencyList.contains(validatorName); + } + + /** + * If there is a value specified for the indexedProperty field then + * {@code true} will be returned. Otherwise it will be + * {@code false}. + * @return Whether the Field is indexed. + */ + public boolean isIndexed() { + return indexedListProperty != null && !indexedListProperty.isEmpty(); + } + + /** * Replace constants with values in fields and process the depends field * to create the dependency Map. */ - void process(Map globalConstants, Map constants) { + void process(final Map globalConstants, final Map constants) { this.hMsgs.setFast(false); this.hVars.setFast(true); this.generateKey(); // Process FormSet Constants - for (Iterator> i = constants.entrySet().iterator(); i.hasNext();) { - Entry entry = i.next(); - String key = entry.getKey(); - String key2 = TOKEN_START + key + TOKEN_END; - String replaceValue = entry.getValue(); + for (final Entry entry : constants.entrySet()) { + final String key1 = entry.getKey(); + final String key2 = TOKEN_START + key1 + TOKEN_END; + final String replaceValue = entry.getValue(); property = ValidatorUtils.replace(property, key2, replaceValue); @@ -581,11 +638,10 @@ } // Process Global Constants - for (Iterator> i = globalConstants.entrySet().iterator(); i.hasNext();) { - Entry entry = i.next(); - String key = entry.getKey(); - String key2 = TOKEN_START + key + TOKEN_END; - String replaceValue = entry.getValue(); + for (final Entry entry : globalConstants.entrySet()) { + final String key1 = entry.getKey(); + final String key2 = TOKEN_START + key1 + TOKEN_END; + final String replaceValue = entry.getValue(); property = ValidatorUtils.replace(property, key2, replaceValue); @@ -595,11 +651,10 @@ } // Process Var Constant Replacement - for (Iterator i = getVarMap().keySet().iterator(); i.hasNext();) { - String key = i.next(); - String key2 = TOKEN_START + TOKEN_VAR + key + TOKEN_END; - Var var = this.getVar(key); - String replaceValue = var.getValue(); + for (final String key1 : getVarMap().keySet()) { + final String key2 = TOKEN_START + TOKEN_VAR + key1 + TOKEN_END; + final Var var = this.getVar(key1); + final String replaceValue = var.getValue(); this.processMessageComponents(key2, replaceValue); } @@ -608,28 +663,30 @@ } /** - * Replace the vars value with the key/value pairs passed in. + * Replace the arg Collection key value with the key/value + * pairs passed in. */ - private void processVars(String key, String replaceValue) { - Iterator i = getVarMap().keySet().iterator(); - while (i.hasNext()) { - String varKey = i.next(); - Var var = this.getVar(varKey); - - var.setValue(ValidatorUtils.replace(var.getValue(), key, replaceValue)); + private void processArg(final String key, final String replaceValue) { + for (final Map argMap : this.args) { + if (argMap == null) { + continue; + } + for (final Arg arg : argMap.values()) { + if (arg != null) { + arg.setKey(ValidatorUtils.replace(arg.getKey(), key, replaceValue)); + } + } } - } /** * Replace the args key value with the key/value pairs passed in. */ - private void processMessageComponents(String key, String replaceValue) { - String varKey = TOKEN_START + TOKEN_VAR; + private void processMessageComponents(final String key, final String replaceValue) { + final String varKey = TOKEN_START + TOKEN_VAR; // Process Messages if (key != null && !key.startsWith(varKey)) { - for (Iterator i = getMsgMap().values().iterator(); i.hasNext();) { - Msg msg = i.next(); + for (final Msg msg : getMsgMap().values()) { msg.setKey(ValidatorUtils.replace(msg.getKey(), key, replaceValue)); } } @@ -638,83 +695,131 @@ } /** - * Replace the arg Collection key value with the key/value - * pairs passed in. + * Replace the vars value with the key/value pairs passed in. */ - private void processArg(String key, String replaceValue) { - for (int i = 0; i < this.args.length; i++) { + private void processVars(final String key, final String replaceValue) { + for (final String varKey : getVarMap().keySet()) { + final Var var = this.getVar(varKey); + var.setValue(ValidatorUtils.replace(var.getValue(), key, replaceValue)); + } - Map argMap = this.args[i]; - if (argMap == null) { - continue; - } + } - Iterator iter = argMap.values().iterator(); - while (iter.hasNext()) { - Arg arg = iter.next(); + /** + * Calls all of the validators that this validator depends on. + * TODO ValidatorAction should know how to run its own dependencies. + * @param va Run dependent validators for this action. + * @param results + * @param actions + * @param pos + * @return true if all of the dependent validations passed. + * @throws ValidatorException If there's an error running a validator + */ + private boolean runDependentValidators( + final ValidatorAction va, + final ValidatorResults results, + final Map actions, + final Map params, + final int pos) + throws ValidatorException { - if (arg != null) { - arg.setKey( - ValidatorUtils.replace(arg.getKey(), key, replaceValue)); - } + final List dependentValidators = va.getDependencyList(); + + if (dependentValidators.isEmpty()) { + return true; + } + + for (final String depend : dependentValidators) { + final ValidatorAction action = actions.get(depend); + if (action == null) { + this.handleMissingAction(depend); } + + if (!this.validateForRule(action, results, actions, params, pos)) { + return false; + } } + + return true; } /** - * Checks if the validator is listed as a dependency. - * @param validatorName Name of the validator to check. - * @return Whether the field is dependant on a validator. + * Sets the flag that determines whether client-side scripting should + * be generated for this field. + * @param clientValidation the scripting flag + * @see #isClientValidation() + * @since 1.4 */ - public boolean isDependency(String validatorName) { - return this.dependencyList.contains(validatorName); + public void setClientValidation(final boolean clientValidation) { + this.clientValidation = clientValidation; } /** - * Gets an unmodifiable List of the dependencies in the same - * order they were defined in parameter passed to the setDepends() method. - * @return A list of the Field's dependancies. + * Sets the validation rules for this field as a comma separated list. + * @param depends A comma separated list of validator names. */ - public List getDependencyList() { - return Collections.unmodifiableList(this.dependencyList); + public void setDepends(final String depends) { + this.depends = depends; + + this.dependencyList.clear(); + + final StringTokenizer st = new StringTokenizer(depends, ","); + while (st.hasMoreTokens()) { + final String depend = st.nextToken().trim(); + + if (depend != null && !depend.isEmpty()) { + this.dependencyList.add(depend); + } + } } /** - * Creates and returns a copy of this object. - * @return A copy of the Field. + * Sets the position of the Field in the validation list. + * @param fieldOrder The field position. */ - @Override - public Object clone() { - Field field = null; - try { - field = (Field) super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e.toString()); - } + public void setFieldOrder(final int fieldOrder) { + this.fieldOrder = fieldOrder; + } - @SuppressWarnings("unchecked") // empty array always OK; cannot check this at compile time - final Map[] tempMap = new Map[this.args.length]; - field.args = tempMap; - for (int i = 0; i < this.args.length; i++) { - if (this.args[i] == null) { - continue; - } + /** + * Sets the indexed property name of the field. + * @param indexedListProperty The field's indexed List property name. + */ + public void setIndexedListProperty(final String indexedListProperty) { + this.indexedListProperty = indexedListProperty; + } + /** + * Sets the indexed property name of the field. + * @param indexedProperty The field's indexed property name. + */ + public void setIndexedProperty(final String indexedProperty) { + this.indexedProperty = indexedProperty; + } - Map argMap = new HashMap(this.args[i]); - Iterator> iter = argMap.entrySet().iterator(); - while (iter.hasNext()) { - Entry entry = iter.next(); - String validatorName = entry.getKey(); - Arg arg = entry.getValue(); - argMap.put(validatorName, (Arg) arg.clone()); - } - field.args[i] = argMap; - } + /** + * Sets a unique key for the field. This can be used to change + * the key temporarily to have a unique key for an indexed field. + * @param key a unique key for the field + */ + public void setKey(final String key) { + this.key = key; + } - field.hVars = ValidatorUtils.copyFastHashMap(hVars); - field.hMsgs = ValidatorUtils.copyFastHashMap(hMsgs); + /** + * Sets the page value that the Field is associated with for + * validation. + * @param page The page number. + */ + public void setPage(final int page) { + this.page = page; + } - return field; + /** + * Sets the property name of the field. + * @param property The field's property name. + */ + public void setProperty(final String property) { + this.property = property; } /** @@ -723,7 +828,7 @@ */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("\t\tkey = " + key + "\n"); results.append("\t\tproperty = " + property + "\n"); @@ -735,12 +840,11 @@ if (hVars != null) { results.append("\t\tVars:\n"); - for (Iterator i = getVarMap().keySet().iterator(); i.hasNext();) { - Object key = i.next(); + for (final Object key1 : getVarMap().keySet()) { results.append("\t\t\t"); - results.append(key); + results.append(key1); results.append("="); - results.append(getVarMap().get(key)); + results.append(getVarMap().get(key1)); results.append("\n"); } } @@ -749,139 +853,6 @@ } /** - * Returns an indexed property from the object we're validating. - * - * @param bean The bean to extract the indexed values from. - * @throws ValidatorException If there's an error looking up the property - * or, the property found is not indexed. - */ - Object[] getIndexedProperty(Object bean) throws ValidatorException { - Object indexedProperty = null; - - try { - indexedProperty = - PropertyUtils.getProperty(bean, this.getIndexedListProperty()); - - } catch(IllegalAccessException e) { - throw new ValidatorException(e.getMessage()); - } catch(InvocationTargetException e) { - throw new ValidatorException(e.getMessage()); - } catch(NoSuchMethodException e) { - throw new ValidatorException(e.getMessage()); - } - - if (indexedProperty instanceof Collection) { - return ((Collection) indexedProperty).toArray(); - - } else if (indexedProperty.getClass().isArray()) { - return (Object[]) indexedProperty; - - } else { - throw new ValidatorException(this.getKey() + " is not indexed"); - } - - } - /** - * Returns the size of an indexed property from the object we're validating. - * - * @param bean The bean to extract the indexed values from. - * @throws ValidatorException If there's an error looking up the property - * or, the property found is not indexed. - */ - private int getIndexedPropertySize(Object bean) throws ValidatorException { - Object indexedProperty = null; - - try { - indexedProperty = - PropertyUtils.getProperty(bean, this.getIndexedListProperty()); - - } catch(IllegalAccessException e) { - throw new ValidatorException(e.getMessage()); - } catch(InvocationTargetException e) { - throw new ValidatorException(e.getMessage()); - } catch(NoSuchMethodException e) { - throw new ValidatorException(e.getMessage()); - } - - if (indexedProperty == null) { - return 0; - } else if (indexedProperty instanceof Collection) { - return ((Collection)indexedProperty).size(); - } else if (indexedProperty.getClass().isArray()) { - return ((Object[])indexedProperty).length; - } else { - throw new ValidatorException(this.getKey() + " is not indexed"); - } - - } - - /** - * Executes the given ValidatorAction and all ValidatorActions that it - * depends on. - * @return true if the validation succeeded. - */ - private boolean validateForRule( - ValidatorAction va, - ValidatorResults results, - Map actions, - Map params, - int pos) - throws ValidatorException { - - ValidatorResult result = results.getValidatorResult(this.getKey()); - if (result != null && result.containsAction(va.getName())) { - return result.isValid(va.getName()); - } - - if (!this.runDependentValidators(va, results, actions, params, pos)) { - return false; - } - - return va.executeValidationMethod(this, params, results, pos); - } - - /** - * Calls all of the validators that this validator depends on. - * TODO ValidatorAction should know how to run its own dependencies. - * @param va Run dependent validators for this action. - * @param results - * @param actions - * @param pos - * @return true if all of the dependent validations passed. - * @throws ValidatorException If there's an error running a validator - */ - private boolean runDependentValidators( - ValidatorAction va, - ValidatorResults results, - Map actions, - Map params, - int pos) - throws ValidatorException { - - List dependentValidators = va.getDependencyList(); - - if (dependentValidators.isEmpty()) { - return true; - } - - Iterator iter = dependentValidators.iterator(); - while (iter.hasNext()) { - String depend = iter.next(); - - ValidatorAction action = actions.get(depend); - if (action == null) { - this.handleMissingAction(depend); - } - - if (!this.validateForRule(action, results, actions, params, pos)) { - return false; - } - } - - return true; - } - - /** * Run the configured validations on this field. Run all validations * in the depends clause over each item in turn, returning when the first * one fails. @@ -892,37 +863,35 @@ * this field. * @throws ValidatorException If an error occurs during validation. */ - public ValidatorResults validate(Map params, Map actions) - throws ValidatorException { + public ValidatorResults validate(final Map params, final Map actions) + throws ValidatorException { if (this.getDepends() == null) { return new ValidatorResults(); } - ValidatorResults allResults = new ValidatorResults(); + final ValidatorResults allResults = new ValidatorResults(); - Object bean = params.get(Validator.BEAN_PARAM); - int numberOfFieldsToValidate = - this.isIndexed() ? this.getIndexedPropertySize(bean) : 1; + final Object bean = params.get(Validator.BEAN_PARAM); + final int numberOfFieldsToValidate = this.isIndexed() ? this.getIndexedPropertySize(bean) : 1; for (int fieldNumber = 0; fieldNumber < numberOfFieldsToValidate; fieldNumber++) { - Iterator dependencies = this.dependencyList.iterator(); - ValidatorResults results = new ValidatorResults(); - while (dependencies.hasNext()) { - String depend = dependencies.next(); + final ValidatorResults results = new ValidatorResults(); + synchronized (dependencyList) { + for (final String depend : this.dependencyList) { - ValidatorAction action = actions.get(depend); - if (action == null) { - this.handleMissingAction(depend); - } + final ValidatorAction action = actions.get(depend); + if (action == null) { + this.handleMissingAction(depend); + } - boolean good = - validateForRule(action, results, actions, params, fieldNumber); + final boolean good = validateForRule(action, results, actions, params, fieldNumber); - if (!good) { - allResults.merge(results); - return allResults; + if (!good) { + allResults.merge(results); + return allResults; + } } } allResults.merge(results); @@ -932,34 +901,28 @@ } /** - * Called when a validator name is used in a depends clause but there is - * no know ValidatorAction configured for that name. - * @param name The name of the validator in the depends list. - * @throws ValidatorException + * Executes the given ValidatorAction and all ValidatorActions that it + * depends on. + * @return true if the validation succeeded. */ - private void handleMissingAction(String name) throws ValidatorException { - throw new ValidatorException("No ValidatorAction named " + name - + " found for field " + this.getProperty()); - } + private boolean validateForRule( + final ValidatorAction va, + final ValidatorResults results, + final Map actions, + final Map params, + final int pos) + throws ValidatorException { - /** - * Returns a Map of String Msg names to Msg objects. - * @since Validator 1.2.0 - * @return A Map of the Field's messages. - */ - @SuppressWarnings("unchecked") // FastHashMap does not support generics - protected Map getMsgMap() { - return hMsgs; - } + final ValidatorResult result = results.getValidatorResult(this.getKey()); + if (result != null && result.containsAction(va.getName())) { + return result.isValid(va.getName()); + } - /** - * Returns a Map of String Var names to Var objects. - * @since Validator 1.2.0 - * @return A Map of the Field's variables. - */ - @SuppressWarnings("unchecked") // FastHashMap does not support generics - protected Map getVarMap() { - return hVars; + if (!this.runDependentValidators(va, results, actions, params, pos)) { + return false; + } + + return va.executeValidationMethod(this, params, results, pos); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java (.../Form.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java (.../Form.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -27,30 +27,29 @@ /** *

- * * This contains a set of validation rules for a form/JavaBean. The information * is contained in a list of Field objects. Instances of this class - * are configured with a <form> xml element.

- * + * are configured with a <form> xml element. + *

+ *

* The use of FastHashMap is deprecated and will be replaced in a future - * release.

- * - * @version $Revision: 1739361 $ + * release. + *

*/ //TODO mutable non-private fields public class Form implements Serializable { private static final long serialVersionUID = 6445211789563796371L; /** The name/key the set of validation rules is stored under. */ - protected String name = null; + protected String name; /** * List of Fields. Used to maintain the order they were added * in although individual Fields can be retrieved using Map * of Fields. */ - protected List lFields = new ArrayList(); + protected List lFields = new ArrayList<>(); /** * Map of Fields keyed on their property value. @@ -63,45 +62,71 @@ /** * The name/key of the form which this form extends from. * - * @since Validator 1.2.0 + * @since 1.2.0 */ - protected String inherit = null; + protected String inherit; /** * Whether or not the this Form was processed for replacing * variables in strings with their values. */ - private boolean processed = false; + private boolean processed; /** - * Gets the name/key of the set of validation rules. + * Add a Field to the Form. * - * @return The name value + * @param f The field */ - public String getName() { - return name; + public void addField(final Field f) { + this.lFields.add(f); + getFieldMap().put(f.getKey(), f); } /** - * Sets the name/key of the set of validation rules. + * Returns true if this Form contains a Field with the given name. * - * @param name The new name value + * @param fieldName The field name + * @return True if this form contains the field by the given name + * @since 1.1 */ - public void setName(String name) { - this.name = name; + public boolean containsField(final String fieldName) { + return getFieldMap().containsKey(fieldName); } /** - * Add a Field to the Form. + * Gets the name/key of the parent set of validation rules. * - * @param f The field + * @return The extends value + * @since 1.2.0 */ - public void addField(Field f) { - this.lFields.add(f); - getFieldMap().put(f.getKey(), f); + public String getExtends() { + return inherit; } /** + * Returns the Field with the given name or null if this Form has no such + * field. + * + * @param fieldName The field name + * @return The field value + * @since 1.1 + */ + public Field getField(final String fieldName) { + return getFieldMap().get(fieldName); + } + + /** + * Returns a Map of String field keys to Field objects. + * + * @return The fieldMap value + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getFieldMap() { + return hFields; + } + + /** * A List of Fields is returned as an unmodifiable * List. * @@ -112,52 +137,58 @@ } /** - * Returns the Field with the given name or null if this Form has no such - * field. + * Gets the name/key of the set of validation rules. * - * @param fieldName The field name - * @return The field value - * @since Validator 1.1 + * @return The name value */ - public Field getField(String fieldName) { - return getFieldMap().get(fieldName); + public String getName() { + return name; } /** - * Returns true if this Form contains a Field with the given name. + * Gets extends flag. * - * @param fieldName The field name - * @return True if this form contains the field by the given name - * @since Validator 1.1 + * @return The extending value + * @since 1.2.0 */ - public boolean containsField(String fieldName) { - return getFieldMap().containsKey(fieldName); + public boolean isExtending() { + return inherit != null; } /** + * Whether or not the this Form was processed for replacing + * variables in strings with their values. + * + * @return The processed value + * @since 1.2.0 + */ + public boolean isProcessed() { + return processed; + } + + /** * Merges the given form into this one. For any field in depends * not present in this form, include it. depends has precedence * in the way the fields are ordered. * * @param depends the form we want to merge - * @since Validator 1.2.0 + * @since 1.2.0 */ - protected void merge(Form depends) { + protected void merge(final Form depends) { - List templFields = new ArrayList(); + final List templFields = new ArrayList<>(); @SuppressWarnings("unchecked") // FastHashMap is not generic + final Map temphFields = new FastHashMap(); - Iterator dependsIt = depends.getFields().iterator(); - while (dependsIt.hasNext()) { - Field defaultField = dependsIt.next(); + for (final Field defaultField : depends.getFields()) { if (defaultField != null) { - String fieldKey = defaultField.getKey(); + final String fieldKey = defaultField.getKey(); if (!this.containsField(fieldKey)) { templFields.add(defaultField); temphFields.put(fieldKey, defaultField); } else { - Field old = getField(fieldKey); + final Field old = getField(fieldKey); getFieldMap().remove(fieldKey); lFields.remove(old); templFields.add(old); @@ -175,23 +206,22 @@ * @param globalConstants A map of global constants * @param constants Local constants * @param forms Map of forms - * @since Validator 1.2.0 + * @since 1.2.0 */ - protected void process(Map globalConstants, Map constants, Map forms) { + protected void process(final Map globalConstants, final Map constants, final Map forms) { if (isProcessed()) { return; } int n = 0;//we want the fields from its parent first if (isExtending()) { - Form parent = forms.get(inherit); + final Form parent = forms.get(inherit); if (parent != null) { if (!parent.isProcessed()) { //we want to go all the way up the tree parent.process(constants, globalConstants, forms); } - for (Iterator i = parent.getFields().iterator(); i.hasNext(); ) { - Field f = i.next(); + for (final Field f : parent.getFields()) { //we want to be able to override any fields we like if (getFieldMap().get(f.getKey()) == null) { lFields.add(n, f); @@ -203,30 +233,49 @@ } hFields.setFast(true); //no need to reprocess parent's fields, we iterate from 'n' - for (Iterator i = lFields.listIterator(n); i.hasNext(); ) { - Field f = i.next(); + for (final Iterator i = lFields.listIterator(n); i.hasNext(); ) { + final Field f = i.next(); f.process(globalConstants, constants); } processed = true; } /** + * Sets the name/key of the parent set of validation rules. + * + * @param inherit The new extends value + * @since 1.2.0 + */ + public void setExtends(final String inherit) { + this.inherit = inherit; + } + + /** + * Sets the name/key of the set of validation rules. + * + * @param name The new name value + */ + public void setName(final String name) { + this.name = name; + } + + /** * Returns a string representation of the object. * * @return string representation */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("Form: "); results.append(name); results.append("\n"); - for (Iterator i = lFields.iterator(); i.hasNext(); ) { + for (final Field lField : lFields) { results.append("\tField: \n"); - results.append(i.next()); + results.append(lField); results.append("\n"); } @@ -246,7 +295,7 @@ * validation messages. * @throws ValidatorException */ - ValidatorResults validate(Map params, Map actions, int page) + ValidatorResults validate(final Map params, final Map actions, final int page) throws ValidatorException { return validate(params, actions, page, null); } @@ -265,27 +314,25 @@ * @throws ValidatorException * @since 1.2.0 */ - ValidatorResults validate(Map params, Map actions, int page, String fieldName) - throws ValidatorException { - ValidatorResults results = new ValidatorResults(); + ValidatorResults validate(final Map params, final Map actions, final int page, final String fieldName) + throws ValidatorException { + final ValidatorResults results = new ValidatorResults(); params.put(Validator.VALIDATOR_RESULTS_PARAM, results); // Only validate a single field if specified if (fieldName != null) { - Field field = getFieldMap().get(fieldName); + final Field field = getFieldMap().get(fieldName); if (field == null) { - throw new ValidatorException("Unknown field "+fieldName+" in form "+getName()); + throw new ValidatorException("Unknown field " + fieldName + " in form " + getName()); } params.put(Validator.FIELD_PARAM, field); if (field.getPage() <= page) { - results.merge(field.validate(params, actions)); + results.merge(field.validate(params, actions)); } } else { - Iterator fields = this.lFields.iterator(); - while (fields.hasNext()) { - Field field = fields.next(); + for (final Field field : this.lFields) { params.put(Validator.FIELD_PARAM, field); @@ -297,56 +344,4 @@ return results; } - - /** - * Whether or not the this Form was processed for replacing - * variables in strings with their values. - * - * @return The processed value - * @since Validator 1.2.0 - */ - public boolean isProcessed() { - return processed; - } - - /** - * Gets the name/key of the parent set of validation rules. - * - * @return The extends value - * @since Validator 1.2.0 - */ - public String getExtends() { - return inherit; - } - - /** - * Sets the name/key of the parent set of validation rules. - * - * @param inherit The new extends value - * @since Validator 1.2.0 - */ - public void setExtends(String inherit) { - this.inherit = inherit; - } - - /** - * Get extends flag. - * - * @return The extending value - * @since Validator 1.2.0 - */ - public boolean isExtending() { - return inherit != null; - } - - /** - * Returns a Map of String field keys to Field objects. - * - * @return The fieldMap value - * @since Validator 1.2.0 - */ - @SuppressWarnings("unchecked") // FastHashMap is not generic - protected Map getFieldMap() { - return hFields; - } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSet.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSet.java (.../FormSet.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSet.java (.../FormSet.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -19,7 +19,6 @@ import java.io.Serializable; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; @@ -30,187 +29,214 @@ * Holds a set of Forms stored associated with a Locale * based on the country, language, and variant specified. Instances of this * class are configured with a <formset> xml element. - * - * @version $Revision: 1739361 $ */ public class FormSet implements Serializable { private static final long serialVersionUID = -8936513232763306055L; + /** + * This is the type of FormSets where no locale is specified. + */ + protected final static int GLOBAL_FORMSET = 1; + + /** + * This is the type of FormSets where only language locale is + * specified. + */ + protected final static int LANGUAGE_FORMSET = 2; + + /** + * This is the type of FormSets where only language and country + * locale are specified. + */ + protected final static int COUNTRY_FORMSET = 3; + + /** + * This is the type of FormSets where full locale has been set. + */ + protected final static int VARIANT_FORMSET = 4; + /** Logging */ private transient Log log = LogFactory.getLog(FormSet.class); /** * Whether or not the this FormSet was processed for replacing * variables in strings with their values. */ - private boolean processed = false; + private boolean processed; /** Language component of Locale (required). */ - private String language = null; + private String language; /** Country component of Locale (optional). */ - private String country = null; + private String country; /** Variant component of Locale (optional). */ - private String variant = null; + private String variant; /** * A Map of Forms using the name field of the * Form as the key. */ - private final Map forms = new HashMap(); + private final Map forms = new HashMap<>(); /** * A Map of Constants using the name field of the * Constant as the key. */ - private final Map constants = new HashMap(); + private final Map constants = new HashMap<>(); /** - * This is the type of FormSets where no locale is specified. + * Flag indicating if this formSet has been merged with its parent (higher + * rank in Locale hierarchy). */ - protected final static int GLOBAL_FORMSET = 1; + private boolean merged; /** - * This is the type of FormSets where only language locale is - * specified. + * Add a Constant to the locale level. + * + * @param name The constant name + * @param value The constant value */ - protected final static int LANGUAGE_FORMSET = 2; + public void addConstant(final String name, final String value) { + if (constants.containsKey(name)) { + getLog().error("Constant '" + name + "' already exists in FormSet[" + this.displayKey() + "] - ignoring."); + } else { + constants.put(name, value); + } + } /** - * This is the type of FormSets where only language and country - * locale are specified. + * Add a Form to the FormSet. + * + * @param f The form */ - protected final static int COUNTRY_FORMSET = 3; + public void addForm(final Form f) { - /** - * This is the type of FormSets where full locale has been set. - */ - protected final static int VARIANT_FORMSET = 4; + final String formName = f.getName(); + if (forms.containsKey(formName)) { + getLog().error("Form '" + formName + "' already exists in FormSet[" + this.displayKey() + "] - ignoring."); - /** - * Flag indicating if this formSet has been merged with its parent (higher - * rank in Locale hierarchy). - */ - private boolean merged; + } else { + forms.put(f.getName(), f); + } - /** - * Has this formSet been merged? - * - * @return true if it has been merged - * @since Validator 1.2.0 - */ - protected boolean isMerged() { - return merged; } /** - * Returns the type of FormSet:GLOBAL_FORMSET, - * LANGUAGE_FORMSET,COUNTRY_FORMSET or VARIANT_FORMSET - * . + * Returns a string representation of the object's key. * - * @return The type value - * @since Validator 1.2.0 - * @throws NullPointerException if there is inconsistency in the locale - * definition (not sure about this) + * @return A string representation of the key */ - protected int getType() { - if (getVariant() != null) { - if (getLanguage() == null || getCountry() == null) { - throw new NullPointerException( - "When variant is specified, country and language must be specified."); + public String displayKey() { + final StringBuilder results = new StringBuilder(); + if (language != null && !language.isEmpty()) { + results.append("language="); + results.append(language); + } + if (country != null && !country.isEmpty()) { + if (results.length() > 0) { + results.append(", "); } - return VARIANT_FORMSET; + results.append("country="); + results.append(country); } - else if (getCountry() != null) { - if (getLanguage() == null) { - throw new NullPointerException( - "When country is specified, language must be specified."); + if (variant != null && !variant.isEmpty()) { + if (results.length() > 0) { + results.append(", "); } - return COUNTRY_FORMSET; + results.append("variant="); + results.append(variant); } - else if (getLanguage() != null) { - return LANGUAGE_FORMSET; + if (results.length() == 0) { + results.append("default"); } - else { - return GLOBAL_FORMSET; - } + + return results.toString(); } /** - * Merges the given FormSet into this one. If any of depends - * s Forms are not in this FormSet then, include - * them, else merge both Forms. Theoretically we should only - * merge a "parent" formSet. + * Gets the equivalent of the country component of Locale. * - * @param depends FormSet to be merged - * @since Validator 1.2.0 + * @return The country value */ - protected void merge(FormSet depends) { - if (depends != null) { - Map pForms = getForms(); - Map dForms = depends.getForms(); - for (Iterator> it = dForms.entrySet().iterator(); it.hasNext(); ) { - Entry entry = it.next(); - String key = entry.getKey(); - Form pForm = pForms.get(key); - if (pForm != null) {//merge, but principal 'rules', don't overwrite - // anything - pForm.merge(entry.getValue()); - } - else {//just add - addForm(entry.getValue()); - } - } - } - merged = true; + public String getCountry() { + return country; } /** - * Whether or not the this FormSet was processed for replacing - * variables in strings with their values. + * Retrieve a Form based on the form name. * - * @return The processed value + * @param formName The form name + * @return The form */ - public boolean isProcessed() { - return processed; + public Form getForm(final String formName) { + return this.forms.get(formName); } /** - * Gets the equivalent of the language component of Locale. + * A Map of Forms is returned as an unmodifiable + * Map with the key based on the form name. * - * @return The language value + * @return The forms map */ - public String getLanguage() { - return language; + public Map getForms() { + return Collections.unmodifiableMap(forms); } /** - * Sets the equivalent of the language component of Locale. + * Gets the equivalent of the language component of Locale. * - * @param language The new language value + * @return The language value */ - public void setLanguage(String language) { - this.language = language; + public String getLanguage() { + return language; } /** - * Gets the equivalent of the country component of Locale. + * Accessor method for Log instance. * - * @return The country value + * The Log instance variable is transient and + * accessing it through this method ensures it + * is re-initialized when this instance is + * de-serialized. + * + * @return The Log instance. */ - public String getCountry() { - return country; + private Log getLog() { + if (log == null) { + log = LogFactory.getLog(FormSet.class); + } + return log; } /** - * Sets the equivalent of the country component of Locale. + * Returns the type of FormSet:GLOBAL_FORMSET, + * LANGUAGE_FORMSET,COUNTRY_FORMSET or VARIANT_FORMSET + * . * - * @param country The new country value + * @return The type value + * @since 1.2.0 + * @throws NullPointerException if there is inconsistency in the locale + * definition (not sure about this) */ - public void setCountry(String country) { - this.country = country; + protected int getType() { + if (getVariant() != null) { + if (getLanguage() == null || getCountry() == null) { + throw new NullPointerException("When variant is specified, country and language must be specified."); + } + return VARIANT_FORMSET; + } + if (getCountry() != null) { + if (getLanguage() == null) { + throw new NullPointerException("When country is specified, language must be specified."); + } + return COUNTRY_FORMSET; + } + if (getLanguage() != null) { + return LANGUAGE_FORMSET; + } + return GLOBAL_FORMSET; } /** @@ -223,114 +249,90 @@ } /** - * Sets the equivalent of the variant component of Locale. + * Has this formSet been merged? * - * @param variant The new variant value + * @return true if it has been merged + * @since 1.2.0 */ - public void setVariant(String variant) { - this.variant = variant; + protected boolean isMerged() { + return merged; } /** - * Add a Constant to the locale level. + * Whether or not the this FormSet was processed for replacing + * variables in strings with their values. * - * @param name The constant name - * @param value The constant value + * @return The processed value */ - public void addConstant(String name, String value) { - - if (constants.containsKey(name)) { - getLog().error("Constant '" + name + "' already exists in FormSet[" - + this.displayKey() + "] - ignoring."); - - } else { - constants.put(name, value); - } - + public boolean isProcessed() { + return processed; } /** - * Add a Form to the FormSet. + * Merges the given FormSet into this one. If any of depends + * s Forms are not in this FormSet then, include + * them, else merge both Forms. Theoretically we should only + * merge a "parent" formSet. * - * @param f The form + * @param depends FormSet to be merged + * @since 1.2.0 */ - public void addForm(Form f) { - - String formName = f.getName(); - if (forms.containsKey(formName)) { - getLog().error("Form '" + formName + "' already exists in FormSet[" - + this.displayKey() + "] - ignoring."); - - } else { - forms.put(f.getName(), f); + protected void merge(final FormSet depends) { + if (depends != null) { + final Map pForms = getForms(); + final Map dForms = depends.getForms(); + for (final Entry entry : dForms.entrySet()) { + final String key = entry.getKey(); + final Form pForm = pForms.get(key); + if (pForm != null) { // merge, but principal 'rules', don't overwrite + // anything + pForm.merge(entry.getValue()); + } else { // just add + addForm(entry.getValue()); + } + } } - + merged = true; } /** - * Retrieve a Form based on the form name. + * Processes all of the Forms. * - * @param formName The form name - * @return The form + * @param globalConstants Global constants */ - public Form getForm(String formName) { - return this.forms.get(formName); + synchronized void process(final Map globalConstants) { + for (final Form f : forms.values()) { + f.process(globalConstants, constants, forms); + } + + processed = true; } /** - * A Map of Forms is returned as an unmodifiable - * Map with the key based on the form name. + * Sets the equivalent of the country component of Locale. * - * @return The forms map + * @param country The new country value */ - public Map getForms() { - return Collections.unmodifiableMap(forms); + public void setCountry(final String country) { + this.country = country; } /** - * Processes all of the Forms. + * Sets the equivalent of the language component of Locale. * - * @param globalConstants Global constants + * @param language The new language value */ - synchronized void process(Map globalConstants) { - for (Iterator
i = forms.values().iterator(); i.hasNext(); ) { - Form f = i.next(); - f.process(globalConstants, constants, forms); - } - - processed = true; + public void setLanguage(final String language) { + this.language = language; } /** - * Returns a string representation of the object's key. + * Sets the equivalent of the variant component of Locale. * - * @return A string representation of the key + * @param variant The new variant value */ - public String displayKey() { - StringBuilder results = new StringBuilder(); - if (language != null && language.length() > 0) { - results.append("language="); - results.append(language); - } - if (country != null && country.length() > 0) { - if (results.length() > 0) { - results.append(", "); - } - results.append("country="); - results.append(country); - } - if (variant != null && variant.length() > 0) { - if (results.length() > 0) { - results.append(", "); - } - results.append("variant="); - results.append(variant ); - } - if (results.length() == 0) { - results.append("default"); - } - - return results.toString(); + public void setVariant(final String variant) { + this.variant = variant; } /** @@ -340,7 +342,7 @@ */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("FormSet: language="); results.append(language); @@ -350,29 +352,12 @@ results.append(variant); results.append("\n"); - for (Iterator i = getForms().values().iterator(); i.hasNext(); ) { + for (final Object name : getForms().values()) { results.append(" "); - results.append(i.next()); + results.append(name); results.append("\n"); } return results.toString(); } - - /** - * Accessor method for Log instance. - * - * The Log instance variable is transient and - * accessing it through this method ensures it - * is re-initialized when this instance is - * de-serialized. - * - * @return The Log instance. - */ - private Log getLog() { - if (log == null) { - log = LogFactory.getLog(FormSet.class); - } - return log; - } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSetFactory.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSetFactory.java (.../FormSetFactory.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSetFactory.java (.../FormSetFactory.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,44 +16,22 @@ */ package org.apache.commons.validator; -import org.xml.sax.Attributes; import org.apache.commons.digester.AbstractObjectCreationFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.xml.sax.Attributes; /** * Factory class used by Digester to create FormSet's. * - * @version $Revision: 1739356 $ - * @since Validator 1.2 + * @since 1.2 */ public class FormSetFactory extends AbstractObjectCreationFactory { /** Logging */ private transient Log log = LogFactory.getLog(FormSetFactory.class); /** - *

Create or retrieve a FormSet for the specified - * attributes.

- * - * @param attributes The sax attributes for the formset element. - * @return The FormSet for a locale. - * @throws Exception If an error occurs creating the FormSet. - */ - @Override - public Object createObject(Attributes attributes) throws Exception { - - ValidatorResources resources = (ValidatorResources)digester.peek(0); - - String language = attributes.getValue("language"); - String country = attributes.getValue("country"); - String variant = attributes.getValue("variant"); - - return createFormSet(resources, language, country, variant); - - } - - /** *

Create or retrieve a FormSet based on the language, country * and variant.

* @@ -62,12 +40,12 @@ * @param country The locale's country. * @param variant The locale's language variant. * @return The FormSet for a locale. - * @since Validator 1.2 + * @since 1.2 */ - private FormSet createFormSet(ValidatorResources resources, - String language, - String country, - String variant) throws Exception { + private FormSet createFormSet(final ValidatorResources resources, + final String language, + final String country, + final String variant) { // Retrieve existing FormSet for the language/country/variant FormSet formSet = resources.getFormSet(language, country, variant); @@ -96,6 +74,27 @@ } /** + *

Create or retrieve a FormSet for the specified + * attributes.

+ * + * @param attributes The sax attributes for the formset element. + * @return The FormSet for a locale. + * @throws Exception If an error occurs creating the FormSet. + */ + @Override + public Object createObject(final Attributes attributes) throws Exception { + + final ValidatorResources resources = (ValidatorResources) digester.peek(0); + + final String language = attributes.getValue("language"); + final String country = attributes.getValue("country"); + final String variant = attributes.getValue("variant"); + + return createFormSet(resources, language, country, variant); + + } + + /** * Accessor method for Log instance. * * The Log instance variable is transient and @@ -107,7 +106,7 @@ */ private Log getLog() { if (log == null) { - log = LogFactory.getLog(FormSetFactory.class); + log = LogFactory.getLog(FormSetFactory.class); } return log; } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java (.../GenericTypeValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java (.../GenericTypeValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -31,8 +31,6 @@ /** * This class contains basic methods for performing validations that return the * correctly typed class based on the validation performed. - * - * @version $Revision: 1716212 $ */ public class GenericTypeValidator implements Serializable { @@ -46,14 +44,14 @@ * @param value The value validation is being performed on. * @return the converted Byte value. */ - public static Byte formatByte(String value) { + public static Byte formatByte(final String value) { if (value == null) { return null; } try { return Byte.valueOf(value); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { return null; } @@ -67,7 +65,7 @@ * null) * @return the converted Byte value. */ - public static Byte formatByte(String value, Locale locale) { + public static Byte formatByte(final String value, final Locale locale) { Byte result = null; if (value != null) { @@ -78,8 +76,8 @@ formatter = NumberFormat.getNumberInstance(Locale.getDefault()); } formatter.setParseIntegerOnly(true); - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && @@ -93,381 +91,381 @@ } /** - * Checks if the value can safely be converted to a short primitive. + * Checks if the field is a valid credit card number. * + *

Reference Sean M. Burke's + * script.

+ * * @param value The value validation is being performed on. - * @return the converted Short value. + * @return the converted Credit Card number. */ - public static Short formatShort(String value) { + public static Long formatCreditCard(final String value) { + return GenericValidator.isCreditCard(value) ? Long.valueOf(value) : null; + } + + /** + * Checks if the field is a valid date. + * + *

The {@code Locale} is used with {@code java.text.DateFormat}. The {@link java.text.DateFormat#setLenient(boolean)} + * method is set to {@code false} for all. + *

+ * + * @param value The value validation is being performed on. + * @param locale The Locale to use to parse the date (system default if null) + * @return the converted Date value. + */ + public static Date formatDate(final String value, final Locale locale) { + Date date = null; + if (value == null) { return null; } try { - return Short.valueOf(value); - } catch (NumberFormatException e) { - return null; + // Get the formatters to check against + DateFormat formatterShort = null; + DateFormat formatterDefault = null; + if (locale != null) { + formatterShort = + DateFormat.getDateInstance(DateFormat.SHORT, locale); + formatterDefault = + DateFormat.getDateInstance(DateFormat.DEFAULT, locale); + } else { + formatterShort = + DateFormat.getDateInstance( + DateFormat.SHORT, + Locale.getDefault()); + formatterDefault = + DateFormat.getDateInstance( + DateFormat.DEFAULT, + Locale.getDefault()); + } + + // Turn off lenient parsing + formatterShort.setLenient(false); + formatterDefault.setLenient(false); + + // Firstly, try with the short form + try { + date = formatterShort.parse(value); + } catch (final ParseException e) { + // Fall back on the default one + date = formatterDefault.parse(value); + } + } catch (final ParseException e) { + // Bad date, so LOG and return null + if (LOG.isDebugEnabled()) { + LOG.debug("Date parse failed value=[" + value + "], " + + "locale=[" + locale + "] " + e); + } } + return date; } /** - * Checks if the value can safely be converted to a short primitive. + * Checks if the field is a valid date. * - * @param value The value validation is being performed on. - * @param locale The locale to use to parse the number (system default if - * null) - * @return the converted Short value. + *

The pattern is used with {@code java.text.SimpleDateFormat}. + * If strict is true, then the length will be checked so '2/12/1999' will + * not pass validation with the format 'MM/dd/yyyy' because the month isn't + * two digits. The {@link java.text.SimpleDateFormat#setLenient(boolean)} + * method is set to {@code false} for all. + *

+ * + * @param value The value validation is being performed on. + * @param datePattern The pattern passed to {@code SimpleDateFormat}. + * @param strict Whether or not to have an exact match of the + * datePattern. + * @return the converted Date value. */ - public static Short formatShort(String value, Locale locale) { - Short result = null; + public static Date formatDate(final String value, final String datePattern, final boolean strict) { + Date date = null; - if (value != null) { - NumberFormat formatter = null; - if (locale != null) { - formatter = NumberFormat.getNumberInstance(locale); - } else { - formatter = NumberFormat.getNumberInstance(Locale.getDefault()); - } - formatter.setParseIntegerOnly(true); - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + if (value == null + || datePattern == null + || datePattern.isEmpty()) { + return null; + } - // If there was no error and we used the whole string - if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && - num.doubleValue() >= Short.MIN_VALUE && - num.doubleValue() <= Short.MAX_VALUE) { - result = Short.valueOf(num.shortValue()); + try { + final SimpleDateFormat formatter = new SimpleDateFormat(datePattern); + formatter.setLenient(false); + + date = formatter.parse(value); + + if (strict && datePattern.length() != value.length()) { + date = null; } + } catch (final ParseException e) { + // Bad date so return null + if (LOG.isDebugEnabled()) { + LOG.debug("Date parse failed value=[" + value + "], " + + "pattern=[" + datePattern + "], " + + "strict=[" + strict + "] " + e); + } } - return result; + return date; } /** - * Checks if the value can safely be converted to a int primitive. + * Checks if the value can safely be converted to a double primitive. * * @param value The value validation is being performed on. - * @return the converted Integer value. + * @return the converted Double value. */ - public static Integer formatInt(String value) { + public static Double formatDouble(final String value) { if (value == null) { return null; } try { - return Integer.valueOf(value); - } catch (NumberFormatException e) { + return Double.valueOf(value); + } catch (final NumberFormatException e) { return null; } } /** - * Checks if the value can safely be converted to an int primitive. + * Checks if the value can safely be converted to a double primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if * null) - * @return the converted Integer value. + * @return the converted Double value. */ - public static Integer formatInt(String value, Locale locale) { - Integer result = null; + public static Double formatDouble(final String value, final Locale locale) { + Double result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { - formatter = NumberFormat.getNumberInstance(locale); + formatter = NumberFormat.getInstance(locale); } else { - formatter = NumberFormat.getNumberInstance(Locale.getDefault()); + formatter = NumberFormat.getInstance(Locale.getDefault()); } - formatter.setParseIntegerOnly(true); - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && - num.doubleValue() >= Integer.MIN_VALUE && - num.doubleValue() <= Integer.MAX_VALUE) { - result = Integer.valueOf(num.intValue()); + num.doubleValue() >= Double.MAX_VALUE * -1 && + num.doubleValue() <= Double.MAX_VALUE) { + result = Double.valueOf(num.doubleValue()); } } return result; } /** - * Checks if the value can safely be converted to a long primitive. + * Checks if the value can safely be converted to a float primitive. * * @param value The value validation is being performed on. - * @return the converted Long value. + * @return the converted Float value. */ - public static Long formatLong(String value) { + public static Float formatFloat(final String value) { if (value == null) { return null; } try { - return Long.valueOf(value); - } catch (NumberFormatException e) { + return Float.valueOf(value); + } catch (final NumberFormatException e) { return null; } } /** - * Checks if the value can safely be converted to a long primitive. + * Checks if the value can safely be converted to a float primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if * null) - * @return the converted Long value. + * @return the converted Float value. */ - public static Long formatLong(String value, Locale locale) { - Long result = null; + public static Float formatFloat(final String value, final Locale locale) { + Float result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { - formatter = NumberFormat.getNumberInstance(locale); + formatter = NumberFormat.getInstance(locale); } else { - formatter = NumberFormat.getNumberInstance(Locale.getDefault()); + formatter = NumberFormat.getInstance(Locale.getDefault()); } - formatter.setParseIntegerOnly(true); - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && - num.doubleValue() >= Long.MIN_VALUE && - num.doubleValue() <= Long.MAX_VALUE) { - result = Long.valueOf(num.longValue()); + num.doubleValue() >= Float.MAX_VALUE * -1 && + num.doubleValue() <= Float.MAX_VALUE) { + result = Float.valueOf(num.floatValue()); } } return result; } /** - * Checks if the value can safely be converted to a float primitive. + * Checks if the value can safely be converted to a int primitive. * * @param value The value validation is being performed on. - * @return the converted Float value. + * @return the converted Integer value. */ - public static Float formatFloat(String value) { + public static Integer formatInt(final String value) { if (value == null) { return null; } try { - return new Float(value); - } catch (NumberFormatException e) { + return Integer.valueOf(value); + } catch (final NumberFormatException e) { return null; } } /** - * Checks if the value can safely be converted to a float primitive. + * Checks if the value can safely be converted to an int primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if * null) - * @return the converted Float value. + * @return the converted Integer value. */ - public static Float formatFloat(String value, Locale locale) { - Float result = null; + public static Integer formatInt(final String value, final Locale locale) { + Integer result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { - formatter = NumberFormat.getInstance(locale); + formatter = NumberFormat.getNumberInstance(locale); } else { - formatter = NumberFormat.getInstance(Locale.getDefault()); + formatter = NumberFormat.getNumberInstance(Locale.getDefault()); } - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + formatter.setParseIntegerOnly(true); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && - num.doubleValue() >= (Float.MAX_VALUE * -1) && - num.doubleValue() <= Float.MAX_VALUE) { - result = new Float(num.floatValue()); + num.doubleValue() >= Integer.MIN_VALUE && + num.doubleValue() <= Integer.MAX_VALUE) { + result = Integer.valueOf(num.intValue()); } } return result; } /** - * Checks if the value can safely be converted to a double primitive. + * Checks if the value can safely be converted to a long primitive. * * @param value The value validation is being performed on. - * @return the converted Double value. + * @return the converted Long value. */ - public static Double formatDouble(String value) { + public static Long formatLong(final String value) { if (value == null) { return null; } try { - return new Double(value); - } catch (NumberFormatException e) { + return Long.valueOf(value); + } catch (final NumberFormatException e) { return null; } } /** - * Checks if the value can safely be converted to a double primitive. + * Checks if the value can safely be converted to a long primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if * null) - * @return the converted Double value. + * @return the converted Long value. */ - public static Double formatDouble(String value, Locale locale) { - Double result = null; + public static Long formatLong(final String value, final Locale locale) { + Long result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { - formatter = NumberFormat.getInstance(locale); + formatter = NumberFormat.getNumberInstance(locale); } else { - formatter = NumberFormat.getInstance(Locale.getDefault()); + formatter = NumberFormat.getNumberInstance(Locale.getDefault()); } - ParsePosition pos = new ParsePosition(0); - Number num = formatter.parse(value, pos); + formatter.setParseIntegerOnly(true); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && - num.doubleValue() >= (Double.MAX_VALUE * -1) && - num.doubleValue() <= Double.MAX_VALUE) { - result = new Double(num.doubleValue()); + num.doubleValue() >= Long.MIN_VALUE && + num.doubleValue() <= Long.MAX_VALUE) { + result = Long.valueOf(num.longValue()); } } return result; } /** - * Checks if the field is a valid date. + * Checks if the value can safely be converted to a short primitive. * - *

The {@code Locale} is used with {@code java.text.DateFormat}. The {@link java.text.DateFormat#setLenient(boolean)} - * method is set to {@code false} for all. - *

- * - * @param value The value validation is being performed on. - * @param locale The Locale to use to parse the date (system default if null) - * @return the converted Date value. + * @param value The value validation is being performed on. + * @return the converted Short value. */ - public static Date formatDate(String value, Locale locale) { - Date date = null; - + public static Short formatShort(final String value) { if (value == null) { return null; } try { - // Get the formatters to check against - DateFormat formatterShort = null; - DateFormat formatterDefault = null; - if (locale != null) { - formatterShort = - DateFormat.getDateInstance(DateFormat.SHORT, locale); - formatterDefault = - DateFormat.getDateInstance(DateFormat.DEFAULT, locale); - } else { - formatterShort = - DateFormat.getDateInstance( - DateFormat.SHORT, - Locale.getDefault()); - formatterDefault = - DateFormat.getDateInstance( - DateFormat.DEFAULT, - Locale.getDefault()); - } - - // Turn off lenient parsing - formatterShort.setLenient(false); - formatterDefault.setLenient(false); - - // Firstly, try with the short form - try { - date = formatterShort.parse(value); - } catch (ParseException e) { - // Fall back on the default one - date = formatterDefault.parse(value); - } - } catch (ParseException e) { - // Bad date, so LOG and return null - if (LOG.isDebugEnabled()) { - LOG.debug("Date parse failed value=[" + value + "], " + - "locale=[" + locale + "] " + e); - } + return Short.valueOf(value); + } catch (final NumberFormatException e) { + return null; } - return date; } /** - * Checks if the field is a valid date. + * Checks if the value can safely be converted to a short primitive. * - *

The pattern is used with {@code java.text.SimpleDateFormat}. - * If strict is true, then the length will be checked so '2/12/1999' will - * not pass validation with the format 'MM/dd/yyyy' because the month isn't - * two digits. The {@link java.text.SimpleDateFormat#setLenient(boolean)} - * method is set to {@code false} for all. - *

- * - * @param value The value validation is being performed on. - * @param datePattern The pattern passed to {@code SimpleDateFormat}. - * @param strict Whether or not to have an exact match of the - * datePattern. - * @return the converted Date value. + * @param value The value validation is being performed on. + * @param locale The locale to use to parse the number (system default if + * null) + * @return the converted Short value. */ - public static Date formatDate(String value, String datePattern, boolean strict) { - Date date = null; + public static Short formatShort(final String value, final Locale locale) { + Short result = null; - if (value == null - || datePattern == null - || datePattern.length() == 0) { - return null; - } + if (value != null) { + NumberFormat formatter = null; + if (locale != null) { + formatter = NumberFormat.getNumberInstance(locale); + } else { + formatter = NumberFormat.getNumberInstance(Locale.getDefault()); + } + formatter.setParseIntegerOnly(true); + final ParsePosition pos = new ParsePosition(0); + final Number num = formatter.parse(value, pos); - try { - SimpleDateFormat formatter = new SimpleDateFormat(datePattern); - formatter.setLenient(false); - - date = formatter.parse(value); - - if (strict && datePattern.length() != value.length()) { - date = null; + // If there was no error and we used the whole string + if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && + num.doubleValue() >= Short.MIN_VALUE && + num.doubleValue() <= Short.MAX_VALUE) { + result = Short.valueOf(num.shortValue()); } - } catch (ParseException e) { - // Bad date so return null - if (LOG.isDebugEnabled()) { - LOG.debug("Date parse failed value=[" + value + "], " + - "pattern=[" + datePattern + "], " + - "strict=[" + strict + "] " + e); - } } - return date; + return result; } - /** - * Checks if the field is a valid credit card number. - * - *

Reference Sean M. Burke's - * script.

- * - * @param value The value validation is being performed on. - * @return the converted Credit Card number. - */ - public static Long formatCreditCard(String value) { - return GenericValidator.isCreditCard(value) ? Long.valueOf(value) : null; - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericValidator.java (.../GenericValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericValidator.java (.../GenericValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -20,15 +20,13 @@ import java.util.Locale; import java.util.regex.Pattern; -import org.apache.commons.validator.routines.UrlValidator; import org.apache.commons.validator.routines.CreditCardValidator; import org.apache.commons.validator.routines.DateValidator; import org.apache.commons.validator.routines.EmailValidator; +import org.apache.commons.validator.routines.UrlValidator; /** * This class contains basic methods for performing validations. - * - * @version $Revision: 1649191 $ */ public class GenericValidator implements Serializable { @@ -46,29 +44,37 @@ new CreditCardValidator(); /** - *

Checks if the field isn't null and length of the field is greater - * than zero not including whitespace.

+ * Calculate an adjustment amount for line endings. * + * See Bug 37962 for the rational behind this. + * * @param value The value validation is being performed on. - * @return true if blank or null. + * @param lineEndLength The length to use for line endings. + * @return the adjustment amount. */ - public static boolean isBlankOrNull(String value) { - return ((value == null) || (value.trim().length() == 0)); + private static int adjustForLineEnding(final String value, final int lineEndLength) { + int nCount = 0; + int rCount = 0; + for (int i = 0; i < value.length(); i++) { + if (value.charAt(i) == '\n') { + nCount++; + } + if (value.charAt(i) == '\r') { + rCount++; + } + } + return nCount * lineEndLength - (rCount + nCount); } /** - *

Checks if the value matches the regular expression.

+ *

Checks if the field isn't null and length of the field is greater + * than zero not including whitespace.

* * @param value The value validation is being performed on. - * @param regexp The regular expression. - * @return true if matches the regular expression. + * @return true if blank or null. */ - public static boolean matchRegexp(String value, String regexp) { - if (regexp == null || regexp.length() <= 0) { - return false; - } - - return Pattern.matches(regexp, value); + public static boolean isBlankOrNull(final String value) { + return value == null || value.trim().isEmpty(); } /** @@ -77,89 +83,78 @@ * @param value The value validation is being performed on. * @return true if the value can be converted to a Byte. */ - public static boolean isByte(String value) { - return (GenericTypeValidator.formatByte(value) != null); + public static boolean isByte(final String value) { + return GenericTypeValidator.formatByte(value) != null; } /** - *

Checks if the value can safely be converted to a short primitive.

- * + * Checks if the field is a valid credit card number. * @param value The value validation is being performed on. - * @return true if the value can be converted to a Short. + * @return true if the value is valid Credit Card Number. */ - public static boolean isShort(String value) { - return (GenericTypeValidator.formatShort(value) != null); + public static boolean isCreditCard(final String value) { + return CREDIT_CARD_VALIDATOR.isValid(value); } /** - *

Checks if the value can safely be converted to a int primitive.

+ *

Checks if the field is a valid date. The Locale is + * used with java.text.DateFormat. The setLenient method + * is set to {@code false} for all.

* * @param value The value validation is being performed on. - * @return true if the value can be converted to an Integer. + * @param locale The locale to use for the date format, defaults to the + * system default if null. + * @return true if the value can be converted to a Date. */ - public static boolean isInt(String value) { - return (GenericTypeValidator.formatInt(value) != null); + public static boolean isDate(final String value, final Locale locale) { + return DateValidator.getInstance().isValid(value, locale); } /** - *

Checks if the value can safely be converted to a long primitive.

+ *

Checks if the field is a valid date. The pattern is used with + * java.text.SimpleDateFormat. If strict is true, then the + * length will be checked so '2/12/1999' will not pass validation with + * the format 'MM/dd/yyyy' because the month isn't two digits. + * The setLenient method is set to {@code false} for all.

* * @param value The value validation is being performed on. - * @return true if the value can be converted to a Long. + * @param datePattern The pattern passed to SimpleDateFormat. + * @param strict Whether or not to have an exact match of the datePattern. + * @return true if the value can be converted to a Date. */ - public static boolean isLong(String value) { - return (GenericTypeValidator.formatLong(value) != null); + public static boolean isDate(final String value, final String datePattern, final boolean strict) { + // TODO method isValid() not yet supported in routines version + return org.apache.commons.validator.DateValidator.getInstance().isValid(value, datePattern, strict); } /** - *

Checks if the value can safely be converted to a float primitive.

- * - * @param value The value validation is being performed on. - * @return true if the value can be converted to a Float. - */ - public static boolean isFloat(String value) { - return (GenericTypeValidator.formatFloat(value) != null); - } - - /** *

Checks if the value can safely be converted to a double primitive.

* * @param value The value validation is being performed on. * @return true if the value can be converted to a Double. */ - public static boolean isDouble(String value) { - return (GenericTypeValidator.formatDouble(value) != null); + public static boolean isDouble(final String value) { + return GenericTypeValidator.formatDouble(value) != null; } /** - *

Checks if the field is a valid date. The Locale is - * used with java.text.DateFormat. The setLenient method - * is set to false for all.

+ *

Checks if a field has a valid e-mail address.

* * @param value The value validation is being performed on. - * @param locale The locale to use for the date format, defaults to the - * system default if null. - * @return true if the value can be converted to a Date. + * @return true if the value is valid Email Address. */ - public static boolean isDate(String value, Locale locale) { - return DateValidator.getInstance().isValid(value, locale); + public static boolean isEmail(final String value) { + return EmailValidator.getInstance().isValid(value); } /** - *

Checks if the field is a valid date. The pattern is used with - * java.text.SimpleDateFormat. If strict is true, then the - * length will be checked so '2/12/1999' will not pass validation with - * the format 'MM/dd/yyyy' because the month isn't two digits. - * The setLenient method is set to false for all.

+ *

Checks if the value can safely be converted to a float primitive.

* * @param value The value validation is being performed on. - * @param datePattern The pattern passed to SimpleDateFormat. - * @param strict Whether or not to have an exact match of the datePattern. - * @return true if the value can be converted to a Date. + * @return true if the value can be converted to a Float. */ - public static boolean isDate(String value, String datePattern, boolean strict) { - // TODO method isValid() not yet supported in routines version - return org.apache.commons.validator.DateValidator.getInstance().isValid(value, datePattern, strict); + public static boolean isFloat(final String value) { + return GenericTypeValidator.formatFloat(value) != null; } /** @@ -171,8 +166,8 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(byte value, byte min, byte max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final byte value, final byte min, final byte max) { + return value >= min && value <= max; } /** @@ -184,8 +179,8 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(int value, int min, int max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final double value, final double min, final double max) { + return value >= min && value <= max; } /** @@ -197,8 +192,8 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(float value, float min, float max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final float value, final float min, final float max) { + return value >= min && value <= max; } /** @@ -210,8 +205,8 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(short value, short min, short max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final int value, final int min, final int max) { + return value >= min && value <= max; } /** @@ -223,8 +218,8 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(long value, long min, long max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final long value, final long min, final long max) { + return value >= min && value <= max; } /** @@ -236,50 +231,76 @@ * @param max The maximum value of the range. * @return true if the value is in the specified range. */ - public static boolean isInRange(double value, double min, double max) { - return ((value >= min) && (value <= max)); + public static boolean isInRange(final short value, final short min, final short max) { + return value >= min && value <= max; } /** - * Checks if the field is a valid credit card number. + *

Checks if the value can safely be converted to a int primitive.

+ * * @param value The value validation is being performed on. - * @return true if the value is valid Credit Card Number. + * @return true if the value can be converted to an Integer. */ - public static boolean isCreditCard(String value) { - return CREDIT_CARD_VALIDATOR.isValid(value); + public static boolean isInt(final String value) { + return GenericTypeValidator.formatInt(value) != null; } /** - *

Checks if a field has a valid e-mail address.

+ *

Checks if the value can safely be converted to a long primitive.

* * @param value The value validation is being performed on. - * @return true if the value is valid Email Address. + * @return true if the value can be converted to a Long. */ - public static boolean isEmail(String value) { - return EmailValidator.getInstance().isValid(value); + public static boolean isLong(final String value) { + return GenericTypeValidator.formatLong(value) != null; } /** - *

Checks if a field is a valid url address.

+ *

Checks if the value can safely be converted to a short primitive.

+ * + * @param value The value validation is being performed on. + * @return true if the value can be converted to a Short. + */ + public static boolean isShort(final String value) { + return GenericTypeValidator.formatShort(value) != null; + } + + /** + *

Checks if a field is a valid URL address.

* If you need to modify what is considered valid then * consider using the UrlValidator directly. * * @param value The value validation is being performed on. * @return true if the value is valid Url. */ - public static boolean isUrl(String value) { + public static boolean isUrl(final String value) { return URL_VALIDATOR.isValid(value); } /** + *

Checks if the value matches the regular expression.

+ * + * @param value The value validation is being performed on. + * @param regexp The regular expression. + * @return true if matches the regular expression. + */ + public static boolean matchRegexp(final String value, final String regexp) { + if (regexp == null || regexp.isEmpty()) { + return false; + } + + return Pattern.matches(regexp, value); + } + + /** *

Checks if the value's length is less than or equal to the max.

* * @param value The value validation is being performed on. * @param max The maximum length. * @return true if the value's length is less than the specified maximum. */ - public static boolean maxLength(String value, int max) { - return (value.length() <= max); + public static boolean maxLength(final String value, final int max) { + return value.length() <= max; } /** @@ -290,91 +311,79 @@ * @param lineEndLength The length to use for line endings. * @return true if the value's length is less than the specified maximum. */ - public static boolean maxLength(String value, int max, int lineEndLength) { - int adjustAmount = adjustForLineEnding(value, lineEndLength); - return ((value.length() + adjustAmount) <= max); + public static boolean maxLength(final String value, final int max, final int lineEndLength) { + final int adjustAmount = adjustForLineEnding(value, lineEndLength); + return value.length() + adjustAmount <= max; } /** - *

Checks if the value's length is greater than or equal to the min.

+ *

Checks if the value is less than or equal to the max.

* * @param value The value validation is being performed on. - * @param min The minimum length. - * @return true if the value's length is more than the specified minimum. + * @param max The maximum numeric value. + * @return true if the value is <= the specified maximum. */ - public static boolean minLength(String value, int min) { - return (value.length() >= min); + public static boolean maxValue(final double value, final double max) { + return value <= max; } /** - *

Checks if the value's adjusted length is greater than or equal to the min.

+ *

Checks if the value is less than or equal to the max.

* * @param value The value validation is being performed on. - * @param min The minimum length. - * @param lineEndLength The length to use for line endings. - * @return true if the value's length is more than the specified minimum. + * @param max The maximum numeric value. + * @return true if the value is <= the specified maximum. */ - public static boolean minLength(String value, int min, int lineEndLength) { - int adjustAmount = adjustForLineEnding(value, lineEndLength); - return ((value.length() + adjustAmount) >= min); + public static boolean maxValue(final float value, final float max) { + return value <= max; } + // See http://issues.apache.org/bugzilla/show_bug.cgi?id=29015 WRT the "value" methods + /** - * Calculate an adjustment amount for line endings. + *

Checks if the value is less than or equal to the max.

* - * See Bug 37962 for the rational behind this. - * * @param value The value validation is being performed on. - * @param lineEndLength The length to use for line endings. - * @return the adjustment amount. + * @param max The maximum numeric value. + * @return true if the value is <= the specified maximum. */ - private static int adjustForLineEnding(String value, int lineEndLength) { - int nCount = 0; - int rCount = 0; - for (int i = 0; i < value.length(); i++) { - if (value.charAt(i) == '\n') { - nCount++; - } - if (value.charAt(i) == '\r') { - rCount++; - } - } - return ((nCount * lineEndLength) - (rCount + nCount)); + public static boolean maxValue(final int value, final int max) { + return value <= max; } - // See http://issues.apache.org/bugzilla/show_bug.cgi?id=29015 WRT the "value" methods - /** - *

Checks if the value is greater than or equal to the min.

+ *

Checks if the value is less than or equal to the max.

* * @param value The value validation is being performed on. - * @param min The minimum numeric value. - * @return true if the value is >= the specified minimum. + * @param max The maximum numeric value. + * @return true if the value is <= the specified maximum. */ - public static boolean minValue(int value, int min) { - return (value >= min); + public static boolean maxValue(final long value, final long max) { + return value <= max; } /** - *

Checks if the value is greater than or equal to the min.

+ *

Checks if the value's length is greater than or equal to the min.

* * @param value The value validation is being performed on. - * @param min The minimum numeric value. - * @return true if the value is >= the specified minimum. + * @param min The minimum length. + * @return true if the value's length is more than the specified minimum. */ - public static boolean minValue(long value, long min) { - return (value >= min); + public static boolean minLength(final String value, final int min) { + return value.length() >= min; } /** - *

Checks if the value is greater than or equal to the min.

+ *

Checks if the value's adjusted length is greater than or equal to the min.

* * @param value The value validation is being performed on. - * @param min The minimum numeric value. - * @return true if the value is >= the specified minimum. + * @param min The minimum length. + * @param lineEndLength The length to use for line endings. + * @return true if the value's length is more than the specified minimum. */ - public static boolean minValue(double value, double min) { - return (value >= min); + public static boolean minLength(final String value, final int min, final int lineEndLength) { + final int adjustAmount = adjustForLineEnding(value, lineEndLength); + return value.length() + adjustAmount >= min; } /** @@ -384,52 +393,41 @@ * @param min The minimum numeric value. * @return true if the value is >= the specified minimum. */ - public static boolean minValue(float value, float min) { - return (value >= min); + public static boolean minValue(final double value, final double min) { + return value >= min; } /** - *

Checks if the value is less than or equal to the max.

+ *

Checks if the value is greater than or equal to the min.

* * @param value The value validation is being performed on. - * @param max The maximum numeric value. - * @return true if the value is <= the specified maximum. + * @param min The minimum numeric value. + * @return true if the value is >= the specified minimum. */ - public static boolean maxValue(int value, int max) { - return (value <= max); + public static boolean minValue(final float value, final float min) { + return value >= min; } /** - *

Checks if the value is less than or equal to the max.

+ *

Checks if the value is greater than or equal to the min.

* * @param value The value validation is being performed on. - * @param max The maximum numeric value. - * @return true if the value is <= the specified maximum. + * @param min The minimum numeric value. + * @return true if the value is >= the specified minimum. */ - public static boolean maxValue(long value, long max) { - return (value <= max); + public static boolean minValue(final int value, final int min) { + return value >= min; } /** - *

Checks if the value is less than or equal to the max.

+ *

Checks if the value is greater than or equal to the min.

* * @param value The value validation is being performed on. - * @param max The maximum numeric value. - * @return true if the value is <= the specified maximum. + * @param min The minimum numeric value. + * @return true if the value is >= the specified minimum. */ - public static boolean maxValue(double value, double max) { - return (value <= max); + public static boolean minValue(final long value, final long min) { + return value >= min; } - /** - *

Checks if the value is less than or equal to the max.

- * - * @param value The value validation is being performed on. - * @param max The maximum numeric value. - * @return true if the value is <= the specified maximum. - */ - public static boolean maxValue(float value, float max) { - return (value <= max); - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ISBNValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ISBNValidator.java (.../ISBNValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ISBNValidator.java (.../ISBNValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -18,15 +18,14 @@ /** * A class for validating 10 digit ISBN codes. - * Based on this + * Based on this * * algorithm * * NOTE: This has been replaced by the new * {@link org.apache.commons.validator.routines.ISBNValidator}. * - * @version $Revision: 1739358 $ - * @since Validator 1.2.0 + * @since 1.2.0 * @deprecated Use the new ISBNValidator in the routines package */ @Deprecated @@ -36,7 +35,6 @@ * Default Constructor. */ public ISBNValidator() { - super(); } /** @@ -49,7 +47,7 @@ * considered invalid. * @return true if the string is a valid ISBN code. */ - public boolean isValid(String isbn) { + public boolean isValid(final String isbn) { return org.apache.commons.validator.routines.ISBNValidator.getInstance().isValidISBN10(isbn); } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Msg.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Msg.java (.../Msg.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Msg.java (.../Msg.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -23,8 +23,6 @@ * and a pluggable validator instead of using the default message * stored in the ValidatorAction (aka pluggable validator). * Instances of this class are configured with a <msg> xml element. - * - * @version $Revision: 1739356 $ */ //TODO mutable non-private fields public class Msg implements Cloneable, Serializable { @@ -34,44 +32,57 @@ /** * The resource bundle name that this Msg's key should be * resolved in (optional). - * @since Validator 1.1 + * @since 1.1 */ - protected String bundle = null; + protected String bundle; /** * The key or value of the argument. */ - protected String key = null; + protected String key; /** * The name dependency that this argument goes with (optional). */ - protected String name = null; + protected String name; /** * Whether or not the key is a message resource (optional). Defaults to * true. If it is 'true', the value will try to be resolved as a message * resource. - * @since Validator 1.1.4 + * @since 1.1.4 */ protected boolean resource = true; /** + * Creates and returns a copy of this object. + * @return A copy of the Msg. + */ + @Override + public Object clone() { + try { + return super.clone(); + + } catch (final CloneNotSupportedException e) { + throw new UnsupportedOperationException(e.toString(), e); + } + } + + /** * Returns the resource bundle name. * @return The bundle name. - * @since Validator 1.1 + * @since 1.1 */ public String getBundle() { return this.bundle; } /** - * Sets the resource bundle name. - * @param bundle The new bundle name. - * @since Validator 1.1 + * Gets the key/value. + * @return The message key/value. */ - public void setBundle(String bundle) { - this.bundle = bundle; + public String getKey() { + return key; } /** @@ -83,68 +94,55 @@ } /** - * Sets the name of the dependency. - * @param name The dependency name. + * Tests whether or not the key is a resource key or literal value. + * @return {@code true} if key is a resource key. + * @since 1.1.4 */ - public void setName(String name) { - this.name = name; + public boolean isResource() { + return this.resource; } /** - * Gets the key/value. - * @return The message key/value. + * Sets the resource bundle name. + * @param bundle The new bundle name. + * @since 1.1 */ - public String getKey() { - return key; + public void setBundle(final String bundle) { + this.bundle = bundle; } /** * Sets the key/value. * @param key The message key/value. */ - public void setKey(String key) { + public void setKey(final String key) { this.key = key; } /** - * Tests whether or not the key is a resource key or literal value. - * @return true if key is a resource key. - * @since Validator 1.1.4 + * Sets the name of the dependency. + * @param name The dependency name. */ - public boolean isResource() { - return this.resource; + public void setName(final String name) { + this.name = name; } /** * Sets whether or not the key is a resource. * @param resource If true indicates the key is a resource. - * @since Validator 1.1.4 + * @since 1.1.4 */ - public void setResource(boolean resource) { + public void setResource(final boolean resource) { this.resource = resource; } /** - * Creates and returns a copy of this object. - * @return A copy of the Msg. - */ - @Override - public Object clone() { - try { - return super.clone(); - - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e.toString()); - } - } - - /** * Returns a string representation of the object. * @return Msg String representation. */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("Msg: name="); results.append(name); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java (.../UrlValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java (.../UrlValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -48,31 +48,30 @@ * String[] schemes = {"http","https"}. * UrlValidator urlValidator = new UrlValidator(schemes); * if (urlValidator.isValid("ftp://foo.bar.com/")) { - * System.out.println("url is valid"); + * System.out.println("URL is valid"); * } else { - * System.out.println("url is invalid"); + * System.out.println("URL is invalid"); * } * - * prints "url is invalid" + * prints "URL is invalid" * If instead the default constructor is used. * * UrlValidator urlValidator = new UrlValidator(); * if (urlValidator.isValid("ftp://foo.bar.com/")) { - * System.out.println("url is valid"); + * System.out.println("URL is valid"); * } else { - * System.out.println("url is invalid"); + * System.out.println("URL is invalid"); * } * - * prints out "url is valid" + * prints out "URL is valid" * * * @see * * Uniform Resource Identifiers (URI): Generic Syntax * * - * @version $Revision: 1739358 $ - * @since Validator 1.1 + * @since 1.1 * @deprecated Use the new UrlValidator in the routines package. This class * will be removed in a future release. */ @@ -176,7 +175,7 @@ /** * The set of schemes that are allowed to be in a URL. */ - private final Set allowedSchemes = new HashSet(); + private final Set allowedSchemes = new HashSet<>(); /** * If no schemes are provided, default to this set. @@ -191,35 +190,35 @@ } /** + * Initialize a UrlValidator with the given validation options. + * @param options The options should be set using the public constants declared in + * this class. To set multiple options you simply add them together. For example, + * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. + */ + public UrlValidator(final int options) { + this(null, options); + } + + /** * Behavior of validation is modified by passing in several strings options: - * @param schemes Pass in one or more url schemes to consider valid, passing in + * @param schemes Pass in one or more URL schemes to consider valid, passing in * a null will default to "http,https,ftp" being valid. * If a non-null schemes is specified then all valid schemes must * be specified. Setting the ALLOW_ALL_SCHEMES option will * ignore the contents of schemes. */ - public UrlValidator(String[] schemes) { + public UrlValidator(final String[] schemes) { this(schemes, 0); } /** - * Initialize a UrlValidator with the given validation options. - * @param options The options should be set using the public constants declared in - * this class. To set multiple options you simply add them together. For example, - * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. - */ - public UrlValidator(int options) { - this(null, options); - } - - /** * Behavour of validation is modified by passing in options: * @param schemes The set of valid schemes. * @param options The options should be set using the public constants declared in * this class. To set multiple options you simply add them together. For example, * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. */ - public UrlValidator(String[] schemes, int options) { + public UrlValidator(String[] schemes, final int options) { this.options = new Flags(options); if (this.options.isOn(ALLOW_ALL_SCHEMES)) { @@ -234,13 +233,32 @@ } /** - *

Checks if a field has a valid url address.

+ * Returns the number of times the token appears in the target. + * @param token Token value to be counted. + * @param target Target value to count tokens in. + * @return the number of tokens. + */ + protected int countToken(final String token, final String target) { + int tokenIndex = 0; + int count = 0; + while (tokenIndex != -1) { + tokenIndex = target.indexOf(token, tokenIndex); + if (tokenIndex > -1) { + tokenIndex++; + count++; + } + } + return count; + } + + /** + *

Checks if a field has a valid URL address.

* * @param value The value validation is being performed on. A null * value is considered invalid. - * @return true if the url is valid. + * @return true if the URL is valid. */ - public boolean isValid(String value) { + public boolean isValid(final String value) { if (value == null) { return false; } @@ -249,7 +267,7 @@ } // Check the whole url address structure - Matcher urlMatcher = URL_PATTERN.matcher(value); + final Matcher urlMatcher = URL_PATTERN.matcher(value); if (!urlMatcher.matches()) { return false; } @@ -278,52 +296,28 @@ } /** - * Validate scheme. If schemes[] was initialized to a non null, - * then only those scheme's are allowed. Note this is slightly different - * than for the constructor. - * @param scheme The scheme to validate. A null value is considered - * invalid. - * @return true if valid. - */ - protected boolean isValidScheme(String scheme) { - if (scheme == null) { - return false; - } - - if (!SCHEME_PATTERN.matcher(scheme).matches()) { - return false; - } - - if (options.isOff(ALLOW_ALL_SCHEMES) && !allowedSchemes.contains(scheme)) { - return false; - } - - return true; - } - - /** * Returns true if the authority is properly formatted. An authority is the combination * of hostname and port. A null authority value is considered invalid. * @param authority Authority value to validate. * @return true if authority (hostname and port) is valid. */ - protected boolean isValidAuthority(String authority) { + protected boolean isValidAuthority(final String authority) { if (authority == null) { return false; } - InetAddressValidator inetAddressValidator = + final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); - Matcher authorityMatcher = AUTHORITY_PATTERN.matcher(authority); + final Matcher authorityMatcher = AUTHORITY_PATTERN.matcher(authority); if (!authorityMatcher.matches()) { return false; } boolean hostname = false; // check if authority is IP address or hostname String hostIP = authorityMatcher.group(PARSE_AUTHORITY_HOST_IP); - boolean ipV4Address = inetAddressValidator.isValid(hostIP); + final boolean ipV4Address = inetAddressValidator.isValid(hostIP); if (!ipV4Address) { // Domain is hostname name @@ -334,33 +328,33 @@ if (hostname) { // LOW-TECH FIX FOR VALIDATOR-202 // TODO: Rewrite to use ArrayList and .add semantics: see VALIDATOR-203 - char[] chars = hostIP.toCharArray(); + final char[] chars = hostIP.toCharArray(); int size = 1; - for(int i=0; i= hostIP.length()) + segmentLength >= hostIP.length() ? "" : hostIP.substring(segmentLength); segmentCount++; } } - String topLevel = domainSegment[segmentCount - 1]; + final String topLevel = domainSegment[segmentCount - 1]; if (topLevel.length() < 2 || topLevel.length() > 4) { // CHECKSTYLE IGNORE MagicNumber (deprecated code) return false; } @@ -380,12 +374,12 @@ return false; } - String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); + final String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); if (port != null && !PORT_PATTERN.matcher(port).matches()) { return false; } - String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); + final String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); if (!GenericValidator.isBlankOrNull(extra)) { return false; } @@ -394,11 +388,24 @@ } /** + * Returns true if the given fragment is null or fragments are allowed. + * @param fragment Fragment value to validate. + * @return true if fragment is valid. + */ + protected boolean isValidFragment(final String fragment) { + if (fragment == null) { + return true; + } + + return options.isOff(NO_FRAGMENTS); + } + + /** * Returns true if the path is valid. A null value is considered invalid. * @param path Path value to validate. * @return true if path is valid. */ - protected boolean isValidPath(String path) { + protected boolean isValidPath(final String path) { if (path == null) { return false; } @@ -407,14 +414,14 @@ return false; } - int slash2Count = countToken("//", path); - if (options.isOff(ALLOW_2_SLASHES) && (slash2Count > 0)) { + final int slash2Count = countToken("//", path); + if (options.isOff(ALLOW_2_SLASHES) && slash2Count > 0) { return false; } - int slashCount = countToken("/", path); - int dot2Count = countToken("..", path); - if (dot2Count > 0 && (slashCount - slash2Count - 1) <= dot2Count){ + final int slashCount = countToken("/", path); + final int dot2Count = countToken("..", path); + if (dot2Count > 0 && slashCount - slash2Count - 1 <= dot2Count) { return false; } @@ -426,7 +433,7 @@ * @param query Query value to validate. * @return true if query is valid. */ - protected boolean isValidQuery(String query) { + protected boolean isValidQuery(final String query) { if (query == null) { return true; } @@ -435,34 +442,26 @@ } /** - * Returns true if the given fragment is null or fragments are allowed. - * @param fragment Fragment value to validate. - * @return true if fragment is valid. + * Validate scheme. If schemes[] was initialized to a non null, + * then only those scheme's are allowed. Note this is slightly different + * than for the constructor. + * @param scheme The scheme to validate. A null value is considered + * invalid. + * @return true if valid. */ - protected boolean isValidFragment(String fragment) { - if (fragment == null) { - return true; + protected boolean isValidScheme(final String scheme) { + if (scheme == null) { + return false; } - return options.isOff(NO_FRAGMENTS); - } + if (!SCHEME_PATTERN.matcher(scheme).matches()) { + return false; + } - /** - * Returns the number of times the token appears in the target. - * @param token Token value to be counted. - * @param target Target value to count tokens in. - * @return the number of tokens. - */ - protected int countToken(String token, String target) { - int tokenIndex = 0; - int count = 0; - while (tokenIndex != -1) { - tokenIndex = target.indexOf(token, tokenIndex); - if (tokenIndex > -1) { - tokenIndex++; - count++; - } + if (options.isOff(ALLOW_ALL_SCHEMES) && !allowedSchemes.contains(scheme)) { + return false; } - return count; + + return true; } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java (.../Validator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java (.../Validator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -25,8 +25,6 @@ * Validations are processed by the validate method. An instance of * ValidatorResources is used to define the validators * (validation methods) and the validation rules for a JavaBean. - * - * @version $Revision: 1651910 $ */ // TODO mutable fields should be made private and accessed via suitable methods only public class Validator implements Serializable { @@ -92,71 +90,71 @@ /** * The Validator Resources. */ - protected ValidatorResources resources = null; + protected ValidatorResources resources; /** * The name of the form to validate */ - protected String formName = null; + protected String formName; /** * The name of the field on the form to validate * @since 1.2.0 */ - protected String fieldName = null; + protected String fieldName; /** * Maps validation method parameter class names to the objects to be passed * into the method. */ - protected Map parameters = new HashMap(); // + protected Map parameters = new HashMap<>(); // /** * The current page number to validate. */ - protected int page = 0; + protected int page; /** * The class loader to use for instantiating application objects. * If not specified, the context class loader, or the class loader * used to load Digester itself, is used, based on the value of the * useContextClassLoader variable. */ - protected transient ClassLoader classLoader = null; + protected transient ClassLoader classLoader; /** * Whether or not to use the Context ClassLoader when loading classes - * for instantiating new objects. Default is false. + * for instantiating new objects. Default is {@code false}. */ - protected boolean useContextClassLoader = false; + protected boolean useContextClassLoader; /** - * Set this to true to not return Fields that pass validation. Only return failures. + * Sets this to true to not return Fields that pass validation. Only return failures. */ - protected boolean onlyReturnErrors = false; + protected boolean onlyReturnErrors; /** - * Construct a Validator that will + * Constructs a Validator that will * use the ValidatorResources * passed in to retrieve pluggable validators * the different sets of validation rules. * * @param resources ValidatorResources to use during validation. */ - public Validator(ValidatorResources resources) { + public Validator(final ValidatorResources resources) { this(resources, null); } /** - * Construct a Validator that will + * Constructs a Validator that will * use the ValidatorResources * passed in to retrieve pluggable validators * the different sets of validation rules. * * @param resources ValidatorResources to use during validation. * @param formName Key used for retrieving the set of validation rules. */ - public Validator(ValidatorResources resources, String formName) { + public Validator(final ValidatorResources resources, final String formName) { if (resources == null) { throw new IllegalArgumentException("Resources cannot be null."); } @@ -166,7 +164,7 @@ } /** - * Construct a Validator that will + * Constructs a Validator that will * use the ValidatorResources * passed in to retrieve pluggable validators * the different sets of validation rules. @@ -176,7 +174,7 @@ * @param fieldName Key used for retrieving the set of validation rules for a field * @since 1.2.0 */ - public Validator(ValidatorResources resources, String formName, String fieldName) { + public Validator(final ValidatorResources resources, final String formName, final String fieldName) { if (resources == null) { throw new IllegalArgumentException("Resources cannot be null."); } @@ -187,16 +185,76 @@ } /** - * Set a parameter of a pluggable validation method. + * Clears the form name, resources that were added, and the page that was + * set (if any). This can be called to reinitialize the Validator instance + * so it can be reused. The form name (key to set of validation rules) and any + * resources needed, like the JavaBean being validated, will need to + * set and/or added to this instance again. The + * ValidatorResources will not be removed since it can be used + * again and is thread safe. + */ + public void clear() { + this.formName = null; + this.fieldName = null; + this.parameters = new HashMap<>(); + this.page = 0; + } + + /** + * Return the class loader to be used for instantiating application objects + * when required. This is determined based upon the following rules: + *
    + *
  • The class loader set by setClassLoader(), if any
  • + *
  • The thread context class loader, if it exists and the + * useContextClassLoader property is set to true
  • + *
  • The class loader used to load the Digester class itself. + *
+ * @return the class loader. + */ + public ClassLoader getClassLoader() { + if (this.classLoader != null) { + return this.classLoader; + } + + if (this.useContextClassLoader) { + final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); + if (contextLoader != null) { + return contextLoader; + } + } + + return this.getClass().getClassLoader(); + } + + /** + * Gets the form name which is the key to a set of validation rules. + * @return the name of the form. + */ + public String getFormName() { + return formName; + } + + /** + * Returns true if the Validator is only returning Fields that fail validation. + * @return whether only failed fields are returned. + */ + public boolean getOnlyReturnErrors() { + return onlyReturnErrors; + } + + /** + * Gets the page. * - * @param parameterClassName The full class name of the parameter of the - * validation method that corresponds to the value/instance passed in with it. + *

+ * This in conjunction with the page property of + * a {@code Field} can control the processing of fields. If the field's + * page is less than or equal to this page value, it will be processed. + *

* - * @param parameterValue The instance that will be passed into the - * validation method. + * @return the page number. */ - public void setParameter(String parameterClassName, Object parameterValue) { - this.parameters.put(parameterClassName, parameterValue); + public int getPage() { + return page; } /** @@ -207,24 +265,27 @@ * validation method that corresponds to the value/instance passed in with it. * @return value of the specified parameter. */ - public Object getParameterValue(String parameterClassName) { + public Object getParameterValue(final String parameterClassName) { return this.parameters.get(parameterClassName); } /** - * Gets the form name which is the key to a set of validation rules. - * @return the name of the form. + * Return the boolean as to whether the context classloader should be used. + * @return whether the context classloader should be used. */ - public String getFormName() { - return formName; + public boolean getUseContextClassLoader() { + return this.useContextClassLoader; } /** - * Sets the form name which is the key to a set of validation rules. - * @param formName the name of the form. + * Sets the class loader to be used for instantiating application objects + * when required. + * + * @param classLoader The new class loader to use, or null + * to revert to the standard rules */ - public void setFormName(String formName) { - this.formName = formName; + public void setClassLoader(final ClassLoader classLoader) { + this.classLoader = classLoader; } /** @@ -233,26 +294,29 @@ * @param fieldName The name of the field in a form set * @since 1.2.0 */ - public void setFieldName(String fieldName) { + public void setFieldName(final String fieldName) { this.fieldName = fieldName; } /** - * Gets the page. - * - *

- * This in conjunction with the page property of - * a {@code Field} can control the processing of fields. If the field's - * page is less than or equal to this page value, it will be processed. - *

- * - * @return the page number. + * Sets the form name which is the key to a set of validation rules. + * @param formName the name of the form. */ - public int getPage() { - return page; + public void setFormName(final String formName) { + this.formName = formName; } /** + * Configures which Fields the Validator returns from the validate() method. Set this + * to true to only return Fields that failed validation. By default, validate() returns + * all fields. + * @param onlyReturnErrors whether only failed fields are returned. + */ + public void setOnlyReturnErrors(final boolean onlyReturnErrors) { + this.onlyReturnErrors = onlyReturnErrors; + } + + /** * Sets the page. *

* This in conjunction with the page property of @@ -262,35 +326,24 @@ * * @param page the page number. */ - public void setPage(int page) { + public void setPage(final int page) { this.page = page; } /** - * Clears the form name, resources that were added, and the page that was - * set (if any). This can be called to reinitialize the Validator instance - * so it can be reused. The form name (key to set of validation rules) and any - * resources needed, like the JavaBean being validated, will need to - * set and/or added to this instance again. The - * ValidatorResources will not be removed since it can be used - * again and is thread safe. + * Sets a parameter of a pluggable validation method. + * + * @param parameterClassName The full class name of the parameter of the + * validation method that corresponds to the value/instance passed in with it. + * + * @param parameterValue The instance that will be passed into the + * validation method. */ - public void clear() { - this.formName = null; - this.fieldName = null; - this.parameters = new HashMap(); - this.page = 0; + public void setParameter(final String parameterClassName, final Object parameterValue) { + this.parameters.put(parameterClassName, parameterValue); } /** - * Return the boolean as to whether the context classloader should be used. - * @return whether the context classloader should be used. - */ - public boolean getUseContextClassLoader() { - return this.useContextClassLoader; - } - - /** * Determine whether to use the Context ClassLoader (the one found by * calling Thread.currentThread().getContextClassLoader()) * to resolve/load classes that are defined in various rules. If not @@ -299,48 +352,11 @@ * * @param use determines whether to use Context ClassLoader. */ - public void setUseContextClassLoader(boolean use) { + public void setUseContextClassLoader(final boolean use) { this.useContextClassLoader = use; } /** - * Return the class loader to be used for instantiating application objects - * when required. This is determined based upon the following rules: - *

    - *
  • The class loader set by setClassLoader(), if any
  • - *
  • The thread context class loader, if it exists and the - * useContextClassLoader property is set to true
  • - *
  • The class loader used to load the Digester class itself. - *
- * @return the class loader. - */ - public ClassLoader getClassLoader() { - if (this.classLoader != null) { - return this.classLoader; - } - - if (this.useContextClassLoader) { - ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); - if (contextLoader != null) { - return contextLoader; - } - } - - return this.getClass().getClassLoader(); - } - - /** - * Set the class loader to be used for instantiating application objects - * when required. - * - * @param classLoader The new class loader to use, or null - * to revert to the standard rules - */ - public void setClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - /** * Performs validations based on the configured resources. * * @return The Map returned uses the property of the @@ -357,7 +373,7 @@ this.setParameter(VALIDATOR_PARAM, this); - Form form = this.resources.getForm(locale, this.formName); + final Form form = this.resources.getForm(locale, this.formName); if (form != null) { this.setParameter(FORM_PARAM, form); return form.validate( @@ -370,22 +386,4 @@ return new ValidatorResults(); } - /** - * Returns true if the Validator is only returning Fields that fail validation. - * @return whether only failed fields are returned. - */ - public boolean getOnlyReturnErrors() { - return onlyReturnErrors; - } - - /** - * Configures which Fields the Validator returns from the validate() method. Set this - * to true to only return Fields that failed validation. By default, validate() returns - * all fields. - * @param onlyReturnErrors whether only failed fields are returned. - */ - public void setOnlyReturnErrors(boolean onlyReturnErrors) { - this.onlyReturnErrors = onlyReturnErrors; - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorAction.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorAction.java (.../ValidatorAction.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorAction.java (.../ValidatorAction.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -24,6 +24,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -35,13 +36,10 @@ import org.apache.commons.validator.util.ValidatorUtils; /** - * Contains the information to dynamically create and run a validation - * method. This is the class representation of a pluggable validator that can - * be defined in an xml file with the <validator> element. + * Contains the information to dynamically create and run a validation method. This is the class representation of a pluggable validator that can be defined in + * an xml file with the <validator> element. * * Note: The validation method is assumed to be thread safe. - * - * @version $Revision: 1739361 $ */ public class ValidatorAction implements Serializable { @@ -55,324 +53,404 @@ /** * The name of the validation. */ - private String name = null; + private String name; /** - * The full class name of the class containing - * the validation method associated with this action. + * The full class name of the class containing the validation method associated with this action. */ - private String classname = null; + private String className; /** - * The Class object loaded from the classname. + * The Class object loaded from the class name. */ - private Class validationClass = null; + private Class validationClass; /** - * The full method name of the validation to be performed. The method - * must be thread safe. + * The full method name of the validation to be performed. The method must be thread safe. */ - private String method = null; + private String method; /** * The Method object loaded from the method name. */ - private Method validationMethod = null; + private transient Method validationMethod; /** *

- * The method signature of the validation method. This should be a comma - * delimited list of the full class names of each parameter in the correct - * order that the method takes. + * The method signature of the validation method. This should be a comma delimited list of the full class names of each parameter in the correct order that + * the method takes. *

*

- * Note: java.lang.Object is reserved for the - * JavaBean that is being validated. The ValidatorAction - * and Field that are associated with a field's - * validation will automatically be populated if they are - * specified in the method signature. + * Note: java.lang.Object is reserved for the JavaBean that is being validated. The ValidatorAction and Field that + * are associated with a field's validation will automatically be populated if they are specified in the method signature. *

*/ - private String methodParams = - Validator.BEAN_PARAM - + "," - + Validator.VALIDATOR_ACTION_PARAM - + "," - + Validator.FIELD_PARAM; + private String methodParams = Validator.BEAN_PARAM + "," + Validator.VALIDATOR_ACTION_PARAM + "," + Validator.FIELD_PARAM; /** * The Class objects for each entry in methodParameterList. */ - private Class[] parameterClasses = null; + private Class[] parameterClasses; /** - * The other ValidatorActions that this one depends on. If - * any errors occur in an action that this one depends on, this action will - * not be processsed. + * The other ValidatorActions that this one depends on. If any errors occur in an action that this one depends on, this action will not be + * processsed. */ - private String depends = null; + private String depends; /** * The default error message associated with this action. */ - private String msg = null; + private String msg; /** - * An optional field to contain the name to be used if JavaScript is - * generated. + * An optional field to contain the name to be used if JavaScript is generated. */ - private String jsFunctionName = null; + private String jsFunctionName; /** - * An optional field to contain the class path to be used to retrieve the - * JavaScript function. + * An optional field to contain the class path to be used to retrieve the JavaScript function. */ - private String jsFunction = null; + private String jsFunction; /** - * An optional field to containing a JavaScript representation of the - * java method assocated with this action. + * An optional field to containing a JavaScript representation of the Java method assocated with this action. */ - private String javascript = null; + private String javascript; /** - * If the java method matching the correct signature isn't static, the - * instance is stored in the action. This assumes the method is thread - * safe. + * If the Java method matching the correct signature isn't static, the instance is stored in the action. This assumes the method is thread safe. */ - private Object instance = null; + private Object instance; /** - * An internal List representation of the other ValidatorActions - * this one depends on (if any). This List gets updated - * whenever setDepends() gets called. This is synchronized so a call to - * setDepends() (which clears the List) won't interfere with a call to - * isDependency(). + * An internal List representation of the other ValidatorActions this one depends on (if any). This List gets updated whenever setDepends() + * gets called. This is synchronized so a call to setDepends() (which clears the List) won't interfere with a call to isDependency(). */ - private final List dependencyList = Collections.synchronizedList(new ArrayList()); + private final List dependencyList = Collections.synchronizedList(new ArrayList<>()); /** - * An internal List representation of all the validation method's - * parameters defined in the methodParams String. + * An internal List representation of all the validation method's parameters defined in the methodParams String. */ - private final List methodParameterList = new ArrayList(); + private final List methodParameterList = new ArrayList<>(); /** - * Gets the name of the validator action. - * @return Validator Action name. + * Dynamically runs the validation method for this validator and returns true if the data is valid. + * + * @param field + * @param params A Map of class names to parameter values. + * @param results + * @param pos The index of the list property to validate if it's indexed. + * @throws ValidatorException */ - public String getName() { - return name; + boolean executeValidationMethod(final Field field, + // TODO What is this the correct value type? + // both ValidatorAction and Validator are added as parameters + final Map params, final ValidatorResults results, final int pos) throws ValidatorException { + + params.put(Validator.VALIDATOR_ACTION_PARAM, this); + + try { + if (this.validationMethod == null) { + synchronized (this) { + final ClassLoader loader = this.getClassLoader(params); + this.loadValidationClass(loader); + this.loadParameterClasses(loader); + this.loadValidationMethod(); + } + } + + final Object[] paramValues = this.getParameterValues(params); + + if (field.isIndexed()) { + this.handleIndexedField(field, pos, paramValues); + } + + Object result = null; + try { + result = validationMethod.invoke(getValidationClassInstance(), paramValues); + + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new ValidatorException(e.getMessage()); + } catch (final InvocationTargetException e) { + + if (e.getTargetException() instanceof Exception) { + throw (Exception) e.getTargetException(); + + } + if (e.getTargetException() instanceof Error) { + throw (Error) e.getTargetException(); + } + } + + final boolean valid = this.isValid(result); + if (!valid || valid && !onlyReturnErrors(params)) { + results.add(field, this.name, valid, result); + } + + if (!valid) { + return false; + } + + // TODO This catch block remains for backward compatibility. Remove + // this for Validator 2.0 when exception scheme changes. + } catch (final Exception e) { + if (e instanceof ValidatorException) { + throw (ValidatorException) e; + } + + getLog().error("Unhandled exception thrown during validation: " + e.getMessage(), e); + + results.add(field, this.name, false); + return false; + } + + return true; } /** - * Sets the name of the validator action. - * @param name Validator Action name. + * @return A file name suitable for passing to a {@link ClassLoader#getResourceAsStream(String)} method. */ - public void setName(String name) { - this.name = name; + private String formatJavaScriptFileName() { + String fname = this.jsFunction.substring(1); + + if (!this.jsFunction.startsWith("/")) { + fname = jsFunction.replace('.', '/') + ".js"; + } + + return fname; } /** + * Used to generate the JavaScript name when it is not specified. + */ + private String generateJsFunction() { + final StringBuilder jsName = new StringBuilder("org.apache.commons.validator.javascript"); + + jsName.append(".validate"); + jsName.append(name.substring(0, 1).toUpperCase()); + jsName.append(name.substring(1)); + + return jsName.toString(); + } + + /** + * Returns the ClassLoader set in the Validator contained in the parameter Map. + */ + private ClassLoader getClassLoader(final Map params) { + final Validator v = getValidator(params); + return v.getClassLoader(); + } + + /** * Gets the class of the validator action. + * * @return Class name of the validator Action. */ public String getClassname() { - return classname; + return className; } /** - * Sets the class of the validator action. - * @param classname Class name of the validator Action. + * Returns the dependent validator names as an unmodifiable List. + * + * @return List of the validator action's depedents. */ - public void setClassname(String classname) { - this.classname = classname; + public List getDependencyList() { + return Collections.unmodifiableList(this.dependencyList); } /** - * Gets the name of method being called for the validator action. - * @return The method name. + * Gets the dependencies of the validator action as a comma separated list of validator names. + * + * @return The validator action's dependencies. */ - public String getMethod() { - return method; + public String getDepends() { + return this.depends; } /** - * Sets the name of method being called for the validator action. - * @param method The method name. + * Gets the JavaScript equivalent of the Java class and method associated with this action. + * + * @return The JavaScript validation. */ - public void setMethod(String method) { - this.method = method; + public synchronized String getJavascript() { + return javascript; } /** - * Gets the method parameters for the method. - * @return Method's parameters. + * Gets the JavaScript function name. This is optional and can be used instead of validator action name for the name of the JavaScript function/object. + * + * @return The JavaScript function name. */ - public String getMethodParams() { - return methodParams; + public String getJsFunctionName() { + return jsFunctionName; } /** - * Sets the method parameters for the method. - * @param methodParams A comma separated list of parameters. + * Accessor method for Log instance. + * + * The Log instance variable is transient and accessing it through this method ensures it is re-initialized when this instance is de-serialized. + * + * @return The Log instance. */ - public void setMethodParams(String methodParams) { - this.methodParams = methodParams; - - this.methodParameterList.clear(); - - StringTokenizer st = new StringTokenizer(methodParams, ","); - while (st.hasMoreTokens()) { - String value = st.nextToken().trim(); - - if (value != null && value.length() > 0) { - this.methodParameterList.add(value); - } + private Log getLog() { + if (log == null) { + log = LogFactory.getLog(ValidatorAction.class); } + return log; } /** - * Gets the dependencies of the validator action as a comma separated list - * of validator names. - * @return The validator action's dependencies. + * Gets the name of method being called for the validator action. + * + * @return The method name. */ - public String getDepends() { - return this.depends; + public String getMethod() { + return method; } /** - * Sets the dependencies of the validator action. - * @param depends A comma separated list of validator names. + * Gets the method parameters for the method. + * + * @return Method's parameters. */ - public void setDepends(String depends) { - this.depends = depends; - - this.dependencyList.clear(); - - StringTokenizer st = new StringTokenizer(depends, ","); - while (st.hasMoreTokens()) { - String depend = st.nextToken().trim(); - - if (depend != null && depend.length() > 0) { - this.dependencyList.add(depend); - } - } + public String getMethodParams() { + return methodParams; } /** * Gets the message associated with the validator action. + * * @return The message for the validator action. */ public String getMsg() { return msg; } /** - * Sets the message associated with the validator action. - * @param msg The message for the validator action. + * Gets the name of the validator action. + * + * @return Validator Action name. */ - public void setMsg(String msg) { - this.msg = msg; + public String getName() { + return name; } /** - * Gets the Javascript function name. This is optional and can - * be used instead of validator action name for the name of the - * Javascript function/object. - * @return The Javascript function name. + * Converts a List of parameter class names into their values contained in the parameters Map. + * + * @param params A Map of class names to parameter values. + * @return An array containing the value object for each parameter. This array is in the same order as the given List and is suitable for passing to the + * validation method. */ - public String getJsFunctionName() { - return jsFunctionName; + private Object[] getParameterValues(final Map params) { + + final Object[] paramValue = new Object[this.methodParameterList.size()]; + + for (int i = 0; i < this.methodParameterList.size(); i++) { + final String paramClassName = this.methodParameterList.get(i); + paramValue[i] = params.get(paramClassName); + } + + return paramValue; } /** - * Sets the Javascript function name. This is optional and can - * be used instead of validator action name for the name of the - * Javascript function/object. - * @param jsFunctionName The Javascript function name. + * Return an instance of the validation class or null if the validation method is static so does not require an instance to be executed. */ - public void setJsFunctionName(String jsFunctionName) { - this.jsFunctionName = jsFunctionName; + private Object getValidationClassInstance() throws ValidatorException { + if (Modifier.isStatic(this.validationMethod.getModifiers())) { + this.instance = null; + + } else if (this.instance == null) { + try { + this.instance = this.validationClass.getConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + final String msg1 = "Couldn't create instance of " + this.className + ". " + e.getMessage(); + + throw new ValidatorException(msg1); + } + } + + return this.instance; } + private Validator getValidator(final Map params) { + return (Validator) params.get(Validator.VALIDATOR_PARAM); + } + /** - * Sets the fully qualified class path of the Javascript function. - *

- * This is optional and can be used instead of the setJavascript(). - * Attempting to call both setJsFunction and setJavascript - * will result in an IllegalStateException being thrown.

- *

- * If neither setJsFunction or setJavascript is set then - * validator will attempt to load the default javascript definition. - *

- *
-     * Examples
-     *   If in the validator.xml :
-     * #1:
-     *      <validator name="tire"
-     *            jsFunction="com.yourcompany.project.tireFuncion">
-     *     Validator will attempt to load com.yourcompany.project.validateTireFunction.js from
-     *     its class path.
-     * #2:
-     *    <validator name="tire">
-     *      Validator will use the name attribute to try and load
-     *         org.apache.commons.validator.javascript.validateTire.js
-     *      which is the default javascript definition.
-     * 
- * @param jsFunction The Javascript function's fully qualified class path. + * Modifies the paramValue array with indexed fields. + * + * @param field + * @param pos + * @param paramValues */ - public void setJsFunction(String jsFunction) { - if (javascript != null) { - throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()"); - } + private void handleIndexedField(final Field field, final int pos, final Object[] paramValues) throws ValidatorException { - this.jsFunction = jsFunction; + final int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM); + final int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM); + + final Object[] indexedList = field.getIndexedProperty(paramValues[beanIndex]); + + // Set current iteration object to the parameter array + paramValues[beanIndex] = indexedList[pos]; + + // Set field clone with the key modified to represent + // the current field + final Field indexedField = (Field) field.clone(); + indexedField.setKey(ValidatorUtils.replace(indexedField.getKey(), Field.TOKEN_INDEXED, "[" + pos + "]")); + + paramValues[fieldIndex] = indexedField; } /** - * Gets the Javascript equivalent of the java class and method - * associated with this action. - * @return The Javascript validation. + * Initialize based on set. */ - public String getJavascript() { - return javascript; + protected void init() { + this.loadJavascriptFunction(); } /** - * Sets the Javascript equivalent of the java class and method - * associated with this action. - * @param javascript The Javascript validation. + * Checks whether or not the value passed in is in the depends field. + * + * @param validatorName Name of the dependency to check. + * @return Whether the named validator is a dependant. */ - public void setJavascript(String javascript) { - if (jsFunction != null) { - throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()"); - } + public boolean isDependency(final String validatorName) { + return this.dependencyList.contains(validatorName); + } - this.javascript = javascript; + /** + * If the result object is a Boolean, it will return its value. If not it will return {@code false} if the object is null and + * {@code true} if it isn't. + */ + private boolean isValid(final Object result) { + if (result instanceof Boolean) { + final Boolean valid = (Boolean) result; + return valid.booleanValue(); + } + return result != null; } /** - * Initialize based on set. + * @return true if the JavaScript for this action has already been loaded. */ - protected void init() { - this.loadJavascriptFunction(); + private boolean javaScriptAlreadyLoaded() { + return this.javascript != null; } /** - * Load the javascript function specified by the given path. For this - * implementation, the jsFunction property should contain a - * fully qualified package and script name, separated by periods, to be - * loaded from the class loader that created this instance. + * Load the JavaScript function specified by the given path. For this implementation, the jsFunction property should contain a fully qualified + * package and script name, separated by periods, to be loaded from the class loader that created this instance. * - * TODO if the path begins with a '/' the path will be intepreted as - * absolute, and remain unchanged. If this fails then it will attempt to - * treat the path as a file path. It is assumed the script ends with a - * '.js'. + * TODO if the path begins with a '/' the path will be intepreted as absolute, and remain unchanged. If this fails then it will attempt to treat the path as + * a file path. It is assumed the script ends with a '.js'. */ protected synchronized void loadJavascriptFunction() { - if (this.javascriptAlreadyLoaded()) { + if (this.javaScriptAlreadyLoaded()) { return; } @@ -384,413 +462,300 @@ this.jsFunction = this.generateJsFunction(); } - String javascriptFileName = this.formatJavascriptFileName(); + final String javaScriptFileName = this.formatJavaScriptFileName(); if (getLog().isTraceEnabled()) { - getLog().trace(" Loading js function '" + javascriptFileName + "'"); + getLog().trace(" Loading js function '" + javaScriptFileName + "'"); } - this.javascript = this.readJavascriptFile(javascriptFileName); + this.javascript = this.readJavaScriptFile(javaScriptFileName); if (getLog().isTraceEnabled()) { - getLog().trace(" Loading javascript function completed"); + getLog().trace(" Loading JavaScript function completed"); } } /** - * Read a javascript function from a file. - * @param javascriptFileName The file containing the javascript. - * @return The javascript function or null if it could not be loaded. + * Converts a List of parameter class names into their Class objects. Stores the output in {@link #parameterClasses}. This array is in the same order as the + * given List and is suitable for passing to the validation method. + * + * @throws ValidatorException if a class cannot be loaded. */ - private String readJavascriptFile(String javascriptFileName) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = this.getClass().getClassLoader(); - } + private void loadParameterClasses(final ClassLoader loader) throws ValidatorException { - InputStream is = classLoader.getResourceAsStream(javascriptFileName); - if (is == null) { - is = this.getClass().getResourceAsStream(javascriptFileName); + if (this.parameterClasses != null) { + return; } - if (is == null) { - getLog().debug(" Unable to read javascript name "+javascriptFileName); - return null; - } + final Class[] parameterClasses = new Class[this.methodParameterList.size()]; - StringBuilder buffer = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); // TODO encoding - try { - String line = null; - while ((line = reader.readLine()) != null) { - buffer.append(line).append("\n"); - } + for (int i = 0; i < this.methodParameterList.size(); i++) { + final String paramClassName = this.methodParameterList.get(i); - } catch(IOException e) { - getLog().error("Error reading javascript file.", e); - - } finally { try { - reader.close(); - } catch(IOException e) { - getLog().error("Error closing stream to javascript file.", e); + parameterClasses[i] = loader.loadClass(paramClassName); + + } catch (final ClassNotFoundException e) { + throw new ValidatorException(e.getMessage()); } } - String function = buffer.toString(); - return function.equals("") ? null : function; + this.parameterClasses = parameterClasses; } /** - * @return A filename suitable for passing to a - * ClassLoader.getResourceAsStream() method. + * Load the Class object for the configured validation class name. + * + * @param loader The ClassLoader used to load the Class object. + * @throws ValidatorException */ - private String formatJavascriptFileName() { - String name = this.jsFunction.substring(1); + private void loadValidationClass(final ClassLoader loader) throws ValidatorException { - if (!this.jsFunction.startsWith("/")) { - name = jsFunction.replace('.', '/') + ".js"; + if (this.validationClass != null) { + return; } - return name; + try { + this.validationClass = loader.loadClass(this.className); + } catch (final ClassNotFoundException e) { + throw new ValidatorException(e.toString()); + } } /** - * @return true if the javascript for this action has already been loaded. + * Load the Method object for the configured validation method name. + * + * @throws ValidatorException */ - private boolean javascriptAlreadyLoaded() { - return (this.javascript != null); - } + private void loadValidationMethod() throws ValidatorException { + if (this.validationMethod != null) { + return; + } - /** - * Used to generate the javascript name when it is not specified. - */ - private String generateJsFunction() { - StringBuilder jsName = - new StringBuilder("org.apache.commons.validator.javascript"); + try { + this.validationMethod = this.validationClass.getMethod(this.method, this.parameterClasses); - jsName.append(".validate"); - jsName.append(name.substring(0, 1).toUpperCase()); - jsName.append(name.substring(1, name.length())); - - return jsName.toString(); + } catch (final NoSuchMethodException e) { + throw new ValidatorException("No such validation method: " + e.getMessage()); + } } /** - * Checks whether or not the value passed in is in the depends field. - * @param validatorName Name of the dependency to check. - * @return Whether the named validator is a dependant. + * Returns the onlyReturnErrors setting in the Validator contained in the parameter Map. */ - public boolean isDependency(String validatorName) { - return this.dependencyList.contains(validatorName); + private boolean onlyReturnErrors(final Map params) { + final Validator v = getValidator(params); + return v.getOnlyReturnErrors(); } /** - * Returns the dependent validator names as an unmodifiable - * List. - * @return List of the validator action's depedents. + * Opens an input stream for reading the specified resource. + *

+ * The search order is described in the documentation for {@link ClassLoader#getResource(String)}. + *

+ * + * @param name The resource name + * @return An input stream for reading the resource, or {@code null} if the resource could not be found */ - public List getDependencyList() { - return Collections.unmodifiableList(this.dependencyList); + private InputStream openInputStream(final String javaScriptFileName, ClassLoader classLoader) { + InputStream is = null; + if (classLoader != null) { + is = classLoader.getResourceAsStream(javaScriptFileName); + } + if (is == null) { + return getClass().getResourceAsStream(javaScriptFileName); + } + return is; } /** - * Returns a string representation of the object. - * @return a string representation. + * Reads a JavaScript function from a file. + * + * @param javaScriptFileName The file containing the JavaScript. + * @return The JavaScript function or null if it could not be loaded. */ - @Override - public String toString() { - StringBuilder results = new StringBuilder("ValidatorAction: "); - results.append(name); - results.append("\n"); - - return results.toString(); - } - - /** - * Dynamically runs the validation method for this validator and returns - * true if the data is valid. - * @param field - * @param params A Map of class names to parameter values. - * @param results - * @param pos The index of the list property to validate if it's indexed. - * @throws ValidatorException - */ - boolean executeValidationMethod( - Field field, - // TODO What is this the correct value type? - // both ValidatorAction and Validator are added as parameters - Map params, - ValidatorResults results, - int pos) - throws ValidatorException { - - params.put(Validator.VALIDATOR_ACTION_PARAM, this); - - try { - if (this.validationMethod == null) { - synchronized(this) { - ClassLoader loader = this.getClassLoader(params); - this.loadValidationClass(loader); - this.loadParameterClasses(loader); - this.loadValidationMethod(); - } + private String readJavaScriptFile(final String javaScriptFileName) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = getClass().getClassLoader(); + } + // BufferedReader closes InputStreamReader closes InputStream + final InputStream is = openInputStream(javaScriptFileName, classLoader); + if (is == null) { + getLog().debug(" Unable to read javascript name " + javaScriptFileName); + return null; + } + final StringBuilder buffer = new StringBuilder(); + // TODO encoding + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + String line = null; + while ((line = reader.readLine()) != null) { + buffer.append(line).append("\n"); } + } catch (final IOException e) { + getLog().error("Error reading JavaScript file.", e); - Object[] paramValues = this.getParameterValues(params); - - if (field.isIndexed()) { - this.handleIndexedField(field, pos, paramValues); - } - - Object result = null; - try { - result = - validationMethod.invoke( - getValidationClassInstance(), - paramValues); - - } catch (IllegalArgumentException e) { - throw new ValidatorException(e.getMessage()); - } catch (IllegalAccessException e) { - throw new ValidatorException(e.getMessage()); - } catch (InvocationTargetException e) { - - if (e.getTargetException() instanceof Exception) { - throw (Exception) e.getTargetException(); - - } else if (e.getTargetException() instanceof Error) { - throw (Error) e.getTargetException(); - } - } - - boolean valid = this.isValid(result); - if (!valid || (valid && !onlyReturnErrors(params))) { - results.add(field, this.name, valid, result); - } - - if (!valid) { - return false; - } - - // TODO This catch block remains for backward compatibility. Remove - // this for Validator 2.0 when exception scheme changes. - } catch (Exception e) { - if (e instanceof ValidatorException) { - throw (ValidatorException) e; - } - - getLog().error( - "Unhandled exception thrown during validation: " + e.getMessage(), - e); - - results.add(field, this.name, false); - return false; } - - return true; + final String function = buffer.toString(); + return function.isEmpty() ? null : function; } /** - * Load the Method object for the configured validation method name. - * @throws ValidatorException + * Sets the class of the validator action. + * + * @param className Class name of the validator Action. + * @deprecated Use {@link #setClassName(String)}. */ - private void loadValidationMethod() throws ValidatorException { - if (this.validationMethod != null) { - return; - } - - try { - this.validationMethod = - this.validationClass.getMethod(this.method, this.parameterClasses); - - } catch (NoSuchMethodException e) { - throw new ValidatorException("No such validation method: " + - e.getMessage()); - } + @Deprecated + public void setClassname(final String className) { + this.className = className; } /** - * Load the Class object for the configured validation class name. - * @param loader The ClassLoader used to load the Class object. - * @throws ValidatorException + * Sets the class of the validator action. + * + * @param className Class name of the validator Action. */ - private void loadValidationClass(ClassLoader loader) - throws ValidatorException { - - if (this.validationClass != null) { - return; - } - - try { - this.validationClass = loader.loadClass(this.classname); - } catch (ClassNotFoundException e) { - throw new ValidatorException(e.toString()); - } + public void setClassName(final String className) { + this.className = className; } /** - * Converts a List of parameter class names into their Class objects. - * Stores the output in {@link parameterClasses}. This - * array is in the same order as the given List and is suitable for passing - * to the validation method. - * @throws ValidatorException if a class cannot be loaded. + * Sets the dependencies of the validator action. + * + * @param depends A comma separated list of validator names. */ - private void loadParameterClasses(ClassLoader loader) - throws ValidatorException { + public void setDepends(final String depends) { + this.depends = depends; - if (this.parameterClasses != null) { - return; - } + this.dependencyList.clear(); - Class[] parameterClasses = new Class[this.methodParameterList.size()]; + final StringTokenizer st = new StringTokenizer(depends, ","); + while (st.hasMoreTokens()) { + final String depend = st.nextToken().trim(); - for (int i = 0; i < this.methodParameterList.size(); i++) { - String paramClassName = this.methodParameterList.get(i); - - try { - parameterClasses[i] = loader.loadClass(paramClassName); - - } catch (ClassNotFoundException e) { - throw new ValidatorException(e.getMessage()); + if (depend != null && !depend.isEmpty()) { + this.dependencyList.add(depend); } } - - this.parameterClasses = parameterClasses; } /** - * Converts a List of parameter class names into their values contained in - * the parameters Map. - * @param params A Map of class names to parameter values. - * @return An array containing the value object for each parameter. This - * array is in the same order as the given List and is suitable for passing - * to the validation method. + * Sets the JavaScript equivalent of the Java class and method associated with this action. + * + * @param javaScript The JavaScript validation. */ - private Object[] getParameterValues(Map params) { - - Object[] paramValue = new Object[this.methodParameterList.size()]; - - for (int i = 0; i < this.methodParameterList.size(); i++) { - String paramClassName = this.methodParameterList.get(i); - paramValue[i] = params.get(paramClassName); + public synchronized void setJavascript(final String javaScript) { + if (jsFunction != null) { + throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()"); } - return paramValue; + this.javascript = javaScript; } /** - * Return an instance of the validation class or null if the validation - * method is static so does not require an instance to be executed. + * Sets the fully qualified class path of the JavaScript function. + *

+ * This is optional and can be used instead of the setJavascript(). Attempting to call both setJsFunction and + * setJavascript will result in an IllegalStateException being thrown. + *

+ *

+ * If neither setJsFunction or setJavascript is set then validator will attempt to load the default JavaScript definition. + *

+ * + *
+     * Examples
+     *   If in the validator.xml :
+     * #1:
+     *      <validator name="tire"
+     *            jsFunction="com.yourcompany.project.tireFuncion">
+     *     Validator will attempt to load com.yourcompany.project.validateTireFunction.js from
+     *     its class path.
+     * #2:
+     *    <validator name="tire">
+     *      Validator will use the name attribute to try and load
+     *         org.apache.commons.validator.javascript.validateTire.js
+     *      which is the default JavaScript definition.
+     * 
+ * + * @param jsFunction The JavaScript function's fully qualified class path. */ - private Object getValidationClassInstance() throws ValidatorException { - if (Modifier.isStatic(this.validationMethod.getModifiers())) { - this.instance = null; - - } else { - if (this.instance == null) { - try { - this.instance = this.validationClass.newInstance(); - } catch (InstantiationException e) { - String msg = - "Couldn't create instance of " - + this.classname - + ". " - + e.getMessage(); - - throw new ValidatorException(msg); - - } catch (IllegalAccessException e) { - String msg = - "Couldn't create instance of " - + this.classname - + ". " - + e.getMessage(); - - throw new ValidatorException(msg); - } - } + public synchronized void setJsFunction(final String jsFunction) { + if (javascript != null) { + throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()"); } - return this.instance; + this.jsFunction = jsFunction; } /** - * Modifies the paramValue array with indexed fields. + * Sets the JavaScript function name. This is optional and can be used instead of validator action name for the name of the JavaScript function/object. * - * @param field - * @param pos - * @param paramValues + * @param jsFunctionName The JavaScript function name. */ - private void handleIndexedField(Field field, int pos, Object[] paramValues) - throws ValidatorException { + public void setJsFunctionName(final String jsFunctionName) { + this.jsFunctionName = jsFunctionName; + } - int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM); - int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM); - - Object indexedList[] = field.getIndexedProperty(paramValues[beanIndex]); - - // Set current iteration object to the parameter array - paramValues[beanIndex] = indexedList[pos]; - - // Set field clone with the key modified to represent - // the current field - Field indexedField = (Field) field.clone(); - indexedField.setKey( - ValidatorUtils.replace( - indexedField.getKey(), - Field.TOKEN_INDEXED, - "[" + pos + "]")); - - paramValues[fieldIndex] = indexedField; + /** + * Sets the name of method being called for the validator action. + * + * @param method The method name. + */ + public void setMethod(final String method) { + this.method = method; } /** - * If the result object is a Boolean, it will return its - * value. If not it will return false if the object is - * null and true if it isn't. + * Sets the method parameters for the method. + * + * @param methodParams A comma separated list of parameters. */ - private boolean isValid(Object result) { - if (result instanceof Boolean) { - Boolean valid = (Boolean) result; - return valid.booleanValue(); + public void setMethodParams(final String methodParams) { + this.methodParams = methodParams; + + this.methodParameterList.clear(); + + final StringTokenizer st = new StringTokenizer(methodParams, ","); + while (st.hasMoreTokens()) { + final String value = st.nextToken().trim(); + + if (value != null && !value.isEmpty()) { + this.methodParameterList.add(value); + } } - return result != null; } /** - * Returns the ClassLoader set in the Validator contained in the parameter - * Map. + * Sets the message associated with the validator action. + * + * @param msg The message for the validator action. */ - private ClassLoader getClassLoader(Map params) { - Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); - return v.getClassLoader(); + public void setMsg(final String msg) { + this.msg = msg; } /** - * Returns the onlyReturnErrors setting in the Validator contained in the - * parameter Map. + * Sets the name of the validator action. + * + * @param name Validator Action name. */ - private boolean onlyReturnErrors(Map params) { - Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); - return v.getOnlyReturnErrors(); + public void setName(final String name) { + this.name = name; } /** - * Accessor method for Log instance. + * Returns a string representation of the object. * - * The Log instance variable is transient and - * accessing it through this method ensures it - * is re-initialized when this instance is - * de-serialized. - * - * @return The Log instance. + * @return a string representation. */ - private Log getLog() { - if (log == null) { - log = LogFactory.getLog(ValidatorAction.class); - } - return log; + @Override + public String toString() { + final StringBuilder results = new StringBuilder("ValidatorAction: "); + results.append(name); + results.append("\n"); + + return results.toString(); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java (.../ValidatorException.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java (.../ValidatorException.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -20,8 +20,6 @@ * The base exception for the Validator Framework. All other * Exceptions thrown during calls to * Validator.validate() are considered errors. - * - * @version $Revision: 1649191 $ */ public class ValidatorException extends Exception { @@ -31,15 +29,14 @@ * Constructs an Exception with no specified detail message. */ public ValidatorException() { - super(); } /** * Constructs an Exception with the specified detail message. * * @param message The error message. */ - public ValidatorException(String message) { + public ValidatorException(final String message) { super(message); } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java (.../ValidatorResources.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java (.../ValidatorResources.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -21,7 +21,6 @@ import java.io.Serializable; import java.net.URL; import java.util.Collections; -import java.util.Iterator; import java.util.Locale; import java.util.Map; @@ -31,8 +30,8 @@ import org.apache.commons.digester.xmlrules.DigesterLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.xml.sax.SAXException; import org.xml.sax.Attributes; +import org.xml.sax.SAXException; /** *

@@ -49,8 +48,6 @@ * The use of FastHashMap is deprecated and will be replaced in a future * release. *

- * - * @version $Revision: 1739361 $ */ //TODO mutable non-private fields public class ValidatorResources implements Serializable { @@ -65,7 +62,7 @@ * the versions of the configuration file DTDs that we know about. There * MUST be an even number of Strings in this list! */ - private static final String REGISTRATIONS[] = { + private static final String[] REGISTRATIONS = { "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN", "/org/apache/commons/validator/resources/validator_1_0.dtd", "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0.1//EN", @@ -82,6 +79,14 @@ "/org/apache/commons/validator/resources/validator_1_4_0.dtd" }; + /** + * The default locale on our server. + */ + protected static Locale defaultLocale = Locale.getDefault(); + + private static final String ARGS_PATTERN + = "form-validation/formset/form/field/arg"; + private transient Log log = LogFactory.getLog(ValidatorResources.class); /** @@ -109,34 +114,28 @@ protected FastHashMap hActions = new FastHashMap(); // /** - * The default locale on our server. + * This is the default FormSet (without locale). (We probably don't need + * the defaultLocale anymore.) */ - protected static Locale defaultLocale = Locale.getDefault(); + protected FormSet defaultFormSet; /** * Create an empty ValidatorResources object. */ public ValidatorResources() { - super(); } /** - * This is the default FormSet (without locale). (We probably don't need - * the defaultLocale anymore.) - */ - protected FormSet defaultFormSet; - - /** * Create a ValidatorResources object from an InputStream. * * @param in InputStream to a validation.xml configuration file. It's the client's * responsibility to close this stream. * @throws SAXException if the validation XML files are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.1 + * @since 1.1 */ - public ValidatorResources(InputStream in) throws IOException, SAXException { + public ValidatorResources(final InputStream in) throws IOException, SAXException { this(new InputStream[]{in}); } @@ -149,14 +148,12 @@ * @throws SAXException if the validation XML files are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.1 + * @since 1.1 */ - public ValidatorResources(InputStream[] streams) + public ValidatorResources(final InputStream[] streams) throws IOException, SAXException { - super(); - - Digester digester = initDigester(); + final Digester digester = initDigester(); for (int i = 0; i < streams.length; i++) { if (streams[i] == null) { throw new IllegalArgumentException("Stream[" + i + "] is null"); @@ -175,10 +172,10 @@ * @throws SAXException if the validation XML files are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.2 + * @since 1.2 */ - public ValidatorResources(String uri) throws IOException, SAXException { - this(new String[]{uri}); + public ValidatorResources(final String uri) throws IOException, SAXException { + this(new String[] { uri }); } /** @@ -189,17 +186,15 @@ * @throws SAXException if the validation XML files are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.2 + * @since 1.2 */ - public ValidatorResources(String[] uris) + public ValidatorResources(final String... uris) throws IOException, SAXException { - super(); - - Digester digester = initDigester(); - for (int i = 0; i < uris.length; i++) { + final Digester digester = initDigester(); + for (final String element : uris) { digester.push(this); - digester.parse(uris[i]); + digester.parse(element); } this.process(); @@ -213,9 +208,9 @@ * @throws SAXException if the validation XML file are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.3.1 + * @since 1.3.1 */ - public ValidatorResources(URL url) + public ValidatorResources(final URL url) throws IOException, SAXException { this(new URL[]{url}); } @@ -228,70 +223,75 @@ * @throws SAXException if the validation XML files are not valid or well * formed. * @throws IOException if an I/O error occurs processing the XML files - * @since Validator 1.3.1 + * @since 1.3.1 */ - public ValidatorResources(URL[] urls) + public ValidatorResources(final URL[] urls) throws IOException, SAXException { - super(); - - Digester digester = initDigester(); - for (int i = 0; i < urls.length; i++) { + final Digester digester = initDigester(); + for (final URL url : urls) { digester.push(this); - digester.parse(urls[i]); + digester.parse(url); } this.process(); } /** - * Initialize the digester. + * Add a global constant to the resource. + * @param name The constant name. + * @param value The constant value. */ - private Digester initDigester() { - URL rulesUrl = this.getClass().getResource(VALIDATOR_RULES); - if (rulesUrl == null) { - // Fix for Issue# VALIDATOR-195 - rulesUrl = ValidatorResources.class.getResource(VALIDATOR_RULES); - } + public void addConstant(final String name, final String value) { if (getLog().isDebugEnabled()) { - getLog().debug("Loading rules from '" + rulesUrl + "'"); + getLog().debug("Adding Global Constant: " + name + "," + value); } - Digester digester = DigesterLoader.createDigester(rulesUrl); - digester.setNamespaceAware(true); - digester.setValidating(true); - digester.setUseContextClassLoader(true); - // Add rules for arg0-arg3 elements - addOldArgRules(digester); + this.hConstants.put(name, value); + } - // register DTDs - for (int i = 0; i < REGISTRATIONS.length; i += 2) { - URL url = this.getClass().getResource(REGISTRATIONS[i + 1]); - if (url != null) { - digester.register(REGISTRATIONS[i], url.toString()); + /** + * Add a FormSet to this ValidatorResources + * object. It will be associated with the Locale of the + * FormSet. + * @param fs The form set to add. + * @since 1.1 + */ + public void addFormSet(final FormSet fs) { + final String key = this.buildKey(fs); + if (key.isEmpty()) { // there can only be one default formset + if (getLog().isWarnEnabled() && defaultFormSet != null) { + // warn the user he might not get the expected results + getLog().warn("Overriding default FormSet definition."); } + defaultFormSet = fs; + } else { + final FormSet formset = getFormSets().get(key); + if (formset == null) { // it hasn't been included yet + if (getLog().isDebugEnabled()) { + getLog().debug("Adding FormSet '" + fs + "'."); + } + } else if (getLog().isWarnEnabled()) { // warn the user he might not + // get the expected results + getLog().warn("Overriding FormSet definition. Duplicate for locale: " + key); + } + getFormSets().put(key, fs); } - return digester; } - private static final String ARGS_PATTERN - = "form-validation/formset/form/field/arg"; - /** * Create a Rule to handle arg0-arg3 * elements. This will allow validation.xml files that use the * versions of the DTD prior to Validator 1.2.0 to continue * working. */ - private void addOldArgRules(Digester digester) { - + private void addOldArgRules(final Digester digester) { // Create a new rule to process args elements - Rule rule = new Rule() { + final Rule rule = new Rule() { @Override - public void begin(String namespace, String name, - Attributes attributes) throws Exception { + public void begin(final String namespace, final String name, final Attributes attributes) { // Create the Arg - Arg arg = new Arg(); + final Arg arg = new Arg(); arg.setKey(attributes.getValue("key")); arg.setName(attributes.getValue("name")); if ("false".equalsIgnoreCase(attributes.getValue("resource"))) { @@ -300,13 +300,12 @@ try { final int length = "arg".length(); // skip the arg prefix arg.setPosition(Integer.parseInt(name.substring(length))); - } catch (Exception ex) { - getLog().error("Error parsing Arg position: " - + name + " " + arg + " " + ex); + } catch (final Exception ex) { + getLog().error("Error parsing Arg position: " + name + " " + arg + " " + ex); } // Add the arg to the parent field - ((Field)getDigester().peek(0)).addArg(arg); + ((Field) getDigester().peek(0)).addArg(arg); } }; @@ -319,57 +318,13 @@ } /** - * Add a FormSet to this ValidatorResources - * object. It will be associated with the Locale of the - * FormSet. - * @param fs The form set to add. - * @since Validator 1.1 - */ - public void addFormSet(FormSet fs) { - String key = this.buildKey(fs); - if (key.length() == 0) {// there can only be one default formset - if (getLog().isWarnEnabled() && defaultFormSet != null) { - // warn the user he might not get the expected results - getLog().warn("Overriding default FormSet definition."); - } - defaultFormSet = fs; - } else { - FormSet formset = getFormSets().get(key); - if (formset == null) {// it hasn't been included yet - if (getLog().isDebugEnabled()) { - getLog().debug("Adding FormSet '" + fs.toString() + "'."); - } - } else if (getLog().isWarnEnabled()) {// warn the user he might not - // get the expected results - getLog() - .warn("Overriding FormSet definition. Duplicate for locale: " - + key); - } - getFormSets().put(key, fs); - } - } - - /** - * Add a global constant to the resource. - * @param name The constant name. - * @param value The constant value. - */ - public void addConstant(String name, String value) { - if (getLog().isDebugEnabled()) { - getLog().debug("Adding Global Constant: " + name + "," + value); - } - - this.hConstants.put(name, value); - } - - /** * Add a ValidatorAction to the resource. It also creates an * instance of the class based on the ValidatorActions - * classname and retrieves the Method instance and sets them + * class name and retrieves the Method instance and sets them * in the ValidatorAction. * @param va The validator action. */ - public void addValidatorAction(ValidatorAction va) { + public void addValidatorAction(final ValidatorAction va) { va.init(); getActions().put(va.getName(), va); @@ -380,44 +335,47 @@ } /** - * Get a ValidatorAction based on it's name. - * @param key The validator action key. - * @return The validator action. - */ - public ValidatorAction getValidatorAction(String key) { - return getActions().get(key); - } - - /** - * Get an unmodifiable Map of the ValidatorActions. - * @return Map of validator actions. - */ - public Map getValidatorActions() { - return Collections.unmodifiableMap(getActions()); - } - - /** * Builds a key to store the FormSet under based on it's * language, country, and variant values. * @param fs The Form Set. * @return generated key for a formset. */ - protected String buildKey(FormSet fs) { + protected String buildKey(final FormSet fs) { return this.buildLocale(fs.getLanguage(), fs.getCountry(), fs.getVariant()); } /** * Assembles a Locale code from the given parts. */ - private String buildLocale(String lang, String country, String variant) { - String key = ((lang != null && lang.length() > 0) ? lang : ""); - key += ((country != null && country.length() > 0) ? "_" + country : ""); - key += ((variant != null && variant.length() > 0) ? "_" + variant : ""); + private String buildLocale(final String lang, final String country, final String variant) { + String key = lang != null && !lang.isEmpty() ? lang : ""; + key += country != null && !country.isEmpty() ? "_" + country : ""; + key += variant != null && !variant.isEmpty() ? "_" + variant : ""; return key; } /** + * Returns a Map of String ValidatorAction names to their ValidatorAction. + * @return Map of Validator Actions + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getActions() { + return hActions; + } + + /** + * Returns a Map of String constant names to their String values. + * @return Map of Constants + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getConstants() { + return hConstants; + } + + /** *

Gets a Form based on the name of the form and the * Locale that most closely matches the Locale * passed in. The order of Locale matching is:

@@ -430,9 +388,9 @@ * @param locale The Locale. * @param formKey The key for the Form. * @return The validator Form. - * @since Validator 1.1 + * @since 1.1 */ - public Form getForm(Locale locale, String formKey) { + public Form getForm(final Locale locale, final String formKey) { return this.getForm(locale.getLanguage(), locale.getCountry(), locale .getVariant(), formKey); } @@ -452,29 +410,27 @@ * @param variant The locale's language variant. * @param formKey The key for the Form. * @return The validator Form. - * @since Validator 1.1 + * @since 1.1 */ - public Form getForm(String language, String country, String variant, - String formKey) { + public Form getForm(final String language, final String country, final String variant, final String formKey) { Form form = null; // Try language/country/variant String key = this.buildLocale(language, country, variant); - if (key.length() > 0) { - FormSet formSet = getFormSets().get(key); + if (!key.isEmpty()) { + final FormSet formSet = getFormSets().get(key); if (formSet != null) { form = formSet.getForm(formKey); } } - String localeKey = key; + final String localeKey = key; - // Try language/country if (form == null) { key = buildLocale(language, country, null); - if (key.length() > 0) { - FormSet formSet = getFormSets().get(key); + if (!key.isEmpty()) { + final FormSet formSet = getFormSets().get(key); if (formSet != null) { form = formSet.getForm(formKey); } @@ -484,8 +440,8 @@ // Try language if (form == null) { key = buildLocale(language, null, null); - if (key.length() > 0) { - FormSet formSet = getFormSets().get(key); + if (!key.isEmpty()) { + final FormSet formSet = getFormSets().get(key); if (formSet != null) { form = formSet.getForm(formKey); } @@ -500,61 +456,58 @@ if (form == null) { if (getLog().isWarnEnabled()) { - getLog().warn("Form '" + formKey + "' not found for locale '" + - localeKey + "'"); + getLog().warn("Form '" + formKey + "' not found for locale '" + localeKey + "'"); } - } else { - if (getLog().isDebugEnabled()) { - getLog().debug("Form '" + formKey + "' found in formset '" + - key + "' for locale '" + localeKey + "'"); - } + } else if (getLog().isDebugEnabled()) { + getLog().debug("Form '" + formKey + "' found in formset '" + key + "' for locale '" + localeKey + "'"); } return form; } /** - * Process the ValidatorResources object. Currently sets the - * FastHashMap s to the 'fast' mode and call the processes - * all other resources. Note : The framework calls this - * automatically when ValidatorResources is created from an XML file. If you - * create an instance of this class by hand you must call - * this method when finished. + *

Gets a FormSet based on the language, country + * and variant.

+ * @param language The locale's language. + * @param country The locale's country. + * @param variant The locale's language variant. + * @return The FormSet for a locale. + * @since 1.2 */ - public void process() { - hFormSets.setFast(true); - hConstants.setFast(true); - hActions.setFast(true); + FormSet getFormSet(final String language, final String country, final String variant) { + final String key = buildLocale(language, country, variant); + if (key.isEmpty()) { + return defaultFormSet; + } + return getFormSets().get(key); + } - this.processForms(); + /** + * Returns a Map of String locale keys to Lists of their FormSets. + * @return Map of Form sets + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getFormSets() { + return hFormSets; } /** - *

Process the Form objects. This clones the Fields - * that don't exist in a FormSet compared to its parent - * FormSet.

+ * Accessor method for Log instance. + * + * The Log instance variable is transient and + * accessing it through this method ensures it + * is re-initialized when this instance is + * de-serialized. + * + * @return The Log instance. */ - private void processForms() { - if (defaultFormSet == null) {// it isn't mandatory to have a - // default formset - defaultFormSet = new FormSet(); + private Log getLog() { + if (log == null) { + log = LogFactory.getLog(ValidatorResources.class); } - defaultFormSet.process(getConstants()); - // Loop through FormSets and merge if necessary - for (Iterator i = getFormSets().keySet().iterator(); i.hasNext();) { - String key = i.next(); - FormSet fs = getFormSets().get(key); - fs.merge(getParent(fs)); - } - - // Process Fully Constructed FormSets - for (Iterator i = getFormSets().values().iterator(); i.hasNext();) { - FormSet fs = i.next(); - if (!fs.isProcessed()) { - fs.process(getConstants()); - } - } + return log; } /** @@ -567,23 +520,20 @@ * the formSet we want to get the parent from * @return fs's parent */ - private FormSet getParent(FormSet fs) { + private FormSet getParent(final FormSet fs) { FormSet parent = null; if (fs.getType() == FormSet.LANGUAGE_FORMSET) { parent = defaultFormSet; } else if (fs.getType() == FormSet.COUNTRY_FORMSET) { - parent = getFormSets().get(buildLocale(fs.getLanguage(), - null, null)); + parent = getFormSets().get(buildLocale(fs.getLanguage(), null, null)); if (parent == null) { parent = defaultFormSet; } } else if (fs.getType() == FormSet.VARIANT_FORMSET) { - parent = getFormSets().get(buildLocale(fs.getLanguage(), fs - .getCountry(), null)); + parent = getFormSets().get(buildLocale(fs.getLanguage(), fs.getCountry(), null)); if (parent == null) { - parent = getFormSets().get(buildLocale(fs.getLanguage(), - null, null)); + parent = getFormSets().get(buildLocale(fs.getLanguage(), null, null)); if (parent == null) { parent = defaultFormSet; } @@ -593,70 +543,91 @@ } /** - *

Gets a FormSet based on the language, country - * and variant.

- * @param language The locale's language. - * @param country The locale's country. - * @param variant The locale's language variant. - * @return The FormSet for a locale. - * @since Validator 1.2 + * Gets a ValidatorAction based on it's name. + * @param key The validator action key. + * @return The validator action. */ - FormSet getFormSet(String language, String country, String variant) { - - String key = buildLocale(language, country, variant); - - if (key.length() == 0) { - return defaultFormSet; - } - - return getFormSets().get(key); + public ValidatorAction getValidatorAction(final String key) { + return getActions().get(key); } /** - * Returns a Map of String locale keys to Lists of their FormSets. - * @return Map of Form sets - * @since Validator 1.2.0 + * Gets an unmodifiable Map of the ValidatorActions. + * @return Map of validator actions. */ - @SuppressWarnings("unchecked") // FastHashMap is not generic - protected Map getFormSets() { - return hFormSets; + public Map getValidatorActions() { + return Collections.unmodifiableMap(getActions()); } /** - * Returns a Map of String constant names to their String values. - * @return Map of Constants - * @since Validator 1.2.0 + * Initialize the digester. */ - @SuppressWarnings("unchecked") // FastHashMap is not generic - protected Map getConstants() { - return hConstants; + private Digester initDigester() { + URL rulesUrl = this.getClass().getResource(VALIDATOR_RULES); + if (rulesUrl == null) { + // Fix for Issue# VALIDATOR-195 + rulesUrl = ValidatorResources.class.getResource(VALIDATOR_RULES); + } + if (getLog().isDebugEnabled()) { + getLog().debug("Loading rules from '" + rulesUrl + "'"); + } + final Digester digester = DigesterLoader.createDigester(rulesUrl); + digester.setNamespaceAware(true); + digester.setValidating(true); + digester.setUseContextClassLoader(true); + + // Add rules for arg0-arg3 elements + addOldArgRules(digester); + + // register DTDs + for (int i = 0; i < REGISTRATIONS.length; i += 2) { + final URL url = this.getClass().getResource(REGISTRATIONS[i + 1]); + if (url != null) { + digester.register(REGISTRATIONS[i], url.toString()); + } + } + return digester; } /** - * Returns a Map of String ValidatorAction names to their ValidatorAction. - * @return Map of Validator Actions - * @since Validator 1.2.0 + * Process the ValidatorResources object. Currently sets the + * FastHashMap s to the 'fast' mode and call the processes + * all other resources. Note : The framework calls this + * automatically when ValidatorResources is created from an XML file. If you + * create an instance of this class by hand you must call + * this method when finished. */ - @SuppressWarnings("unchecked") // FastHashMap is not generic - protected Map getActions() { - return hActions; + public void process() { + hFormSets.setFast(true); + hConstants.setFast(true); + hActions.setFast(true); + + this.processForms(); } /** - * Accessor method for Log instance. - * - * The Log instance variable is transient and - * accessing it through this method ensures it - * is re-initialized when this instance is - * de-serialized. - * - * @return The Log instance. + *

Process the Form objects. This clones the Fields + * that don't exist in a FormSet compared to its parent + * FormSet.

*/ - private Log getLog() { - if (log == null) { - log = LogFactory.getLog(ValidatorResources.class); + private void processForms() { + if (defaultFormSet == null) { // it isn't mandatory to have a + // default formset + defaultFormSet = new FormSet(); } - return log; + defaultFormSet.process(getConstants()); + // Loop through FormSets and merge if necessary + for (final String key : getFormSets().keySet()) { + final FormSet fs = getFormSets().get(key); + fs.merge(getParent(fs)); + } + + // Process Fully Constructed FormSets + for (final FormSet fs : getFormSets().values()) { + if (!fs.isProcessed()) { + fs.process(getConstants()); + } + } } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java (.../ValidatorResult.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java (.../ValidatorResult.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -19,38 +19,110 @@ import java.io.Serializable; import java.util.Collections; import java.util.HashMap; -import java.util.Map; import java.util.Iterator; +import java.util.Map; /** * This contains the results of a set of validation rules processed * on a JavaBean. - * - * @version $Revision: 1739361 $ */ //TODO mutable non-private fields public class ValidatorResult implements Serializable { + /** + * Contains the status of the validation. + */ + protected static class ResultStatus implements Serializable { + + private static final long serialVersionUID = 4076665918535320007L; + + /** Whether or not the validation passed. */ + private boolean valid; + + /** Result returned by a validation method. */ + private Object result; + + /** + * Constructs a Result status. + * @param valid Whether the validator passed or failed. + * @param result Value returned by the validator. + */ + public ResultStatus(final boolean valid, final Object result) { + this.valid = valid; + this.result = result; + } + /** + * Provided for backwards binary compatibility only. + * + * @param ignored ignored by this method + * @param valid Whether the validator passed or failed. + * @param result Value returned by the validator. + * + * @deprecated Use {@code ResultStatus(boolean, Object)} instead + */ + @Deprecated + public ResultStatus(final ValidatorResult ignored, final boolean valid, final Object result) { + this(valid, result); + } + + /** + * Gets the result returned by a validation method. + * This can be used to retrieve to the correctly + * typed value of a date validation for example. + * @return The value returned by the validation. + */ + public Object getResult() { + return result; + } + + /** + * Tests whether or not the validation passed. + * @return true if the result was good. + */ + public boolean isValid() { + return valid; + } + + /** + * Sets the result returned by a validation method. + * This can be used to retrieve to the correctly + * typed value of a date validation for example. + * @param result The value returned by the validation. + */ + public void setResult(final Object result) { + this.result = result; + } + + /** + * Sets whether or not the validation passed. + * @param valid Whether the validation passed. + */ + public void setValid(final boolean valid) { + this.valid = valid; + } + + } + private static final long serialVersionUID = -3713364681647250531L; /** * Map of results. The key is the name of the ValidatorAction * and the value is whether or not this field passed or not. */ - protected Map hAction = new HashMap(); + protected Map hAction = new HashMap<>(); /** * Field being validated. * TODO This variable is not used. Need to investigate removing it. */ - protected Field field = null; + protected Field field; /** * Constructs a ValidatorResult with the associated field being * validated. * @param field Field that was validated. */ - public ValidatorResult(Field field) { + public ValidatorResult(final Field field) { this.field = field; } @@ -59,7 +131,7 @@ * @param validatorName Name of the validator. * @param result Whether the validation passed or failed. */ - public void add(String validatorName, boolean result) { + public void add(final String validatorName, final boolean result) { this.add(validatorName, result, null); } @@ -69,7 +141,7 @@ * @param result Whether the validation passed or failed. * @param value Value returned by the validator. */ - public void add(String validatorName, boolean result, Object value) { + public void add(final String validatorName, final boolean result, final Object value) { hAction.put(validatorName, new ResultStatus(result, value)); } @@ -78,39 +150,11 @@ * @param validatorName Name of the validator. * @return true if the validator is in the result. */ - public boolean containsAction(String validatorName) { + public boolean containsAction(final String validatorName) { return hAction.containsKey(validatorName); } /** - * Indicate whether a specified validation passed. - * @param validatorName Name of the validator. - * @return true if the validation passed. - */ - public boolean isValid(String validatorName) { - ResultStatus status = hAction.get(validatorName); - return (status == null) ? false : status.isValid(); - } - - /** - * Return the result of a validation. - * @param validatorName Name of the validator. - * @return The validation result. - */ - public Object getResult(String validatorName) { - ResultStatus status = hAction.get(validatorName); - return (status == null) ? null : status.getResult(); - } - - /** - * Return an Iterator of the action names contained in this Result. - * @return The set of action names. - */ - public Iterator getActions() { - return Collections.unmodifiableMap(hAction).keySet().iterator(); - } - - /** * Return a Map of the validator actions in this Result. * @return Map of validator actions. * @deprecated Use getActions() to return the set of actions @@ -124,6 +168,14 @@ } /** + * Return an Iterator of the action names contained in this Result. + * @return The set of action names. + */ + public Iterator getActions() { + return Collections.unmodifiableMap(hAction).keySet().iterator(); + } + + /** * Returns the Field that was validated. * @return The Field associated with this result. */ @@ -132,74 +184,23 @@ } /** - * Contains the status of the validation. + * Return the result of a validation. + * @param validatorName Name of the validator. + * @return The validation result. */ - protected static class ResultStatus implements Serializable { + public Object getResult(final String validatorName) { + final ResultStatus status = hAction.get(validatorName); + return status == null ? null : status.getResult(); + } - private static final long serialVersionUID = 4076665918535320007L; - - private boolean valid = false; - private Object result = null; - - /** - * Construct a Result status. - * @param valid Whether the validator passed or failed. - * @param result Value returned by the validator. - */ - public ResultStatus(boolean valid, Object result) { - this.valid = valid; - this.result = result; - } - /** - * Provided for backwards binary compatibility only. - * - * @param ignored ignored by this method - * @param valid Whether the validator passed or failed. - * @param result Value returned by the validator. - * - * @deprecated Use {@code ResultStatus(boolean, Object)} instead - */ - @Deprecated - public ResultStatus(ValidatorResult ignored, boolean valid, Object result) { - this(valid, result); - } - - /** - * Tests whether or not the validation passed. - * @return true if the result was good. - */ - public boolean isValid() { - return valid; - } - - /** - * Sets whether or not the validation passed. - * @param valid Whether the validation passed. - */ - public void setValid(boolean valid) { - this.valid = valid; - } - - /** - * Gets the result returned by a validation method. - * This can be used to retrieve to the correctly - * typed value of a date validation for example. - * @return The value returned by the validation. - */ - public Object getResult() { - return result; - } - - /** - * Sets the result returned by a validation method. - * This can be used to retrieve to the correctly - * typed value of a date validation for example. - * @param result The value returned by the validation. - */ - public void setResult(Object result) { - this.result = result; - } - + /** + * Indicate whether a specified validation passed. + * @param validatorName Name of the validator. + * @return true if the validation passed. + */ + public boolean isValid(final String validatorName) { + final ResultStatus status = hAction.get(validatorName); + return status == null ? false : status.isValid(); } } \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java (.../ValidatorResults.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java (.../ValidatorResults.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -26,8 +26,6 @@ /** * This contains the results of a set of validation rules processed * on a JavaBean. - * - * @version $Revision: 1739361 $ */ //TODO mutable non-private fields public class ValidatorResults implements Serializable { @@ -37,25 +35,16 @@ /** * Map of validation results. */ - protected Map hResults = new HashMap(); + protected Map hResults = new HashMap<>(); /** - * Merge another ValidatorResults into mine. - * - * @param results ValidatorResults to merge. - */ - public void merge(ValidatorResults results) { - this.hResults.putAll(results.hResults); - } - - /** * Add a the result of a validator action. * * @param field The field validated. * @param validatorName The name of the validator. * @param result The result of the validation. */ - public void add(Field field, String validatorName, boolean result) { + public void add(final Field field, final String validatorName, final boolean result) { this.add(field, validatorName, result, null); } @@ -68,10 +57,10 @@ * @param value The value returned by the validator. */ public void add( - Field field, - String validatorName, - boolean result, - Object value) { + final Field field, + final String validatorName, + final boolean result, + final Object value) { ValidatorResult validatorResult = this.getValidatorResult(field.getKey()); @@ -91,30 +80,6 @@ } /** - * Return true if there are no messages recorded - * in this collection, or false otherwise. - * - * @return Whether these results are empty. - */ - public boolean isEmpty() { - return this.hResults.isEmpty(); - } - - /** - * Gets the ValidatorResult associated - * with the key passed in. The key the ValidatorResult - * is stored under is the Field's getKey method. - * - * @param key The key generated from Field (this is often just - * the field name). - * - * @return The result of a specified key. - */ - public ValidatorResult getValidatorResult(String key) { - return this.hResults.get(key); - } - - /** * Return the set of property names for which at least one message has * been recorded. * @return An unmodifiable Set of the property names. @@ -124,21 +89,20 @@ } /** - * Get a Map of any Objects returned from + * Gets a Map of any Objects returned from * validation routines. * * @return Map of objections returned by validators. */ public Map getResultValueMap() { - Map results = new HashMap(); + final Map results = new HashMap<>(); - for (Iterator i = hResults.keySet().iterator(); i.hasNext();) { - String propertyKey = i.next(); - ValidatorResult vr = this.getValidatorResult(propertyKey); + for (final String propertyKey : hResults.keySet()) { + final ValidatorResult vr = this.getValidatorResult(propertyKey); - for (Iterator x = vr.getActions(); x.hasNext();) { - String actionKey = x.next(); - Object result = vr.getResult(actionKey); + for (final Iterator x = vr.getActions(); x.hasNext();) { + final String actionKey = x.next(); + final Object result = vr.getResult(actionKey); if (result != null && !(result instanceof Boolean)) { results.put(propertyKey, result); @@ -149,4 +113,37 @@ return results; } + /** + * Gets the ValidatorResult associated + * with the key passed in. The key the ValidatorResult + * is stored under is the Field's getKey method. + * + * @param key The key generated from Field (this is often just + * the field name). + * + * @return The result of a specified key. + */ + public ValidatorResult getValidatorResult(final String key) { + return this.hResults.get(key); + } + + /** + * Return {@code true} if there are no messages recorded + * in this collection, or {@code false} otherwise. + * + * @return Whether these results are empty. + */ + public boolean isEmpty() { + return this.hResults.isEmpty(); + } + + /** + * Merge another ValidatorResults into mine. + * + * @param results ValidatorResults to merge. + */ + public void merge(final ValidatorResults results) { + this.hResults.putAll(results.hResults); + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java (.../Var.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java (.../Var.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -22,8 +22,6 @@ * A variable that can be associated with a Field for * passing in information to a pluggable validator. Instances of this class are * configured with a <var> xml element. - * - * @version $Revision: 1739356 $ */ public class Var implements Cloneable, Serializable { @@ -50,144 +48,143 @@ /** * The name of the variable. */ - private String name = null; + private String name; /** * The key or value the variable. */ - private String value = null; + private String value; /** * The optional JavaScript type of the variable. */ - private String jsType = null; + private String jsType; /** * Whether the variable is a resource [false] */ - private boolean resource = false; + private boolean resource; /** * The bundle for a variable (when resource = 'true'). */ - private String bundle = null; + private String bundle; /** * Default Constructor. */ public Var() { - super(); } /** * Constructs a variable with a specified name, value - * and Javascript type. + * and JavaScript type. * @param name Variable name. * @param value Variable value. - * @param jsType Variable Javascript type. + * @param jsType Variable JavaScript type. */ - public Var(String name, String value, String jsType) { + public Var(final String name, final String value, final String jsType) { this.name = name; this.value = value; this.jsType = jsType; } /** - * Gets the name of the variable. - * @return The name of the variable. + * Creates and returns a copy of this object. + * @return A copy of the variable. */ - public String getName() { - return this.name; - } + @Override + public Object clone() { + try { + return super.clone(); - /** - * Sets the name of the variable. - * @param name The name of the variable. - */ - public void setName(String name) { - this.name = name; + } catch (final CloneNotSupportedException e) { + throw new UnsupportedOperationException(e.toString(), e); + } } /** - * Gets the value of the variable. - * @return The value of the variable. + * Returns the resource bundle name. + * @return The bundle name. + * @since 1.2.0 */ - public String getValue() { - return this.value; + public String getBundle() { + return this.bundle; } /** - * Sets the value of the variable. - * @param value The value of the variable. + * Gets the JavaScript type of the variable. + * @return The JavaScript type of the variable. */ - public void setValue(String value) { - this.value = value; + public String getJsType() { + return this.jsType; } /** - * Tests whether or not the value is a resource key or literal value. - * @return true if value is a resource key. - * @since Validator 1.2.0 + * Gets the name of the variable. + * @return The name of the variable. */ - public boolean isResource() { - return this.resource; + public String getName() { + return this.name; } /** - * Sets whether or not the value is a resource. - * @param resource If true indicates the value is a resource. - * @since Validator 1.2.0 + * Gets the value of the variable. + * @return The value of the variable. */ - public void setResource(boolean resource) { - this.resource = resource; + public String getValue() { + return this.value; } /** - * Returns the resource bundle name. - * @return The bundle name. - * @since Validator 1.2.0 + * Tests whether or not the value is a resource key or literal value. + * @return {@code true} if value is a resource key. + * @since 1.2.0 */ - public String getBundle() { - return this.bundle; + public boolean isResource() { + return this.resource; } /** * Sets the resource bundle name. * @param bundle The new bundle name. - * @since Validator 1.2.0 + * @since 1.2.0 */ - public void setBundle(String bundle) { + public void setBundle(final String bundle) { this.bundle = bundle; } /** - * Gets the JavaScript type of the variable. - * @return The Javascript type of the variable. + * Sets the JavaScript type of the variable. + * @param jsType The JavaScript type of the variable. */ - public String getJsType() { - return this.jsType; + public void setJsType(final String jsType) { + this.jsType = jsType; } /** - * Sets the JavaScript type of the variable. - * @param jsType The Javascript type of the variable. + * Sets the name of the variable. + * @param name The name of the variable. */ - public void setJsType(String jsType) { - this.jsType = jsType; + public void setName(final String name) { + this.name = name; } /** - * Creates and returns a copy of this object. - * @return A copy of the variable. + * Sets whether or not the value is a resource. + * @param resource If true indicates the value is a resource. + * @since 1.2.0 */ - @Override - public Object clone() { - try { - return super.clone(); + public void setResource(final boolean resource) { + this.resource = resource; + } - } catch(CloneNotSupportedException e) { - throw new RuntimeException(e.toString()); - } + /** + * Sets the value of the variable. + * @param value The value of the variable. + */ + public void setValue(final String value) { + this.value = value; } /** @@ -196,7 +193,7 @@ */ @Override public String toString() { - StringBuilder results = new StringBuilder(); + final StringBuilder results = new StringBuilder(); results.append("Var: name="); results.append(name); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/package-info.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/package-info.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/package-info.java (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -0,0 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The Validator package provides validation for JavaBeans based on an xml file. + * + * + * + * + *

Introduction

+ *

A common issue when receiving data either electronically or from + * user input is verifying the integrity of the data. This work is + * repetitive and becomes even more complicated when different sets + * of validation rules need to be applied to the same set of data based + * on locale for example. Error messages may also vary by locale. + * This package attempts to address some of these issues and + * speed development and maintenance of validation rules. + *

+ *

In order to use the Validator, the following basic steps are required:

+ *
    + *
  • Create a new instance of the + * org.apache.commons.validator.Validator class. Currently + * Validator instances may be safely reused if the current ValidatorResources + * are the same, as long as + * you have completed any previous validation, and you do not try to utilize + * a particular Validator instance from more than one thread at a time.
  • + *
  • Add any resources + * needed to perform the validations. Such as the JavaBean to validate.
  • + *
  • Call the validate method on org.apache.commons.validator.Validator.
  • + *
+ * + *

Overview

+ *

+ * The Commons Validator is a basic validation framework that + * lets you define validation rules for a JavaBean in an xml file. + * Validators, the validation definition, can also be defined in + * the xml file. An example of a validator would be defining + * what method and class will be called to perform the validation + * for a required field. Validation rules can be grouped together + * based on locale and a JavaBean/Form that the rules are associated + * with. The framework has basic support for user-defined constants + * which can be used in some field attributes. + *

+ *

+ * Validation rules can be defined in an xml file which keeps + * them abstracted from JavaBean you are validating. The + * property reference to a field supports nested properties + * using the Apache Commons BeanUtils + * (http://commons.apache.org/beanutils/) package. + * Error messages and the arguments for error messages can be + * associated with a fields validation. + *

+ * + *

Resources

+ *

+ * After a Validator instance is created, instances of + * classes can be added to it to be passed into + * validation methods by calling the setParameter() + * method. Below is a list of reserved parameters (class names). + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Reserved Parameters
Class NameValidator ContstantDescription
java.lang.ObjectValidator.BEAN_PARAMJavaBean that is being validated
java.util.LocaleValidator.LOCALE_PARAM + * Locale to use when retrieving a FormSet. + * The default locale will be used if one + * isn't specified. + *
org.apache.commons.validator.ValidatorActionValidator.VALIDATOR_ACTION_PARAM + * This is automatically added to a Validator's + * resources as a validation is being processed. + * If this class name is used when defining + * a method signature for a pluggable validator, + * the current ValidatorAction will be passed into + * the validation method. + *
org.apache.commons.validator.FieldValidator.FIELD_PARAM + * This is automatically added to a Validator's + * resources as a validation is being processed. + * If this class name is used when defining + * a method signature for a pluggable validator, + * the current Field will be passed into + * the validation method. + *
+ * + *

Usage Example

+ *

+ * This is a basic example setting up a required validator for + * a name bean. This example is a working unit test (reference + * org.apache.commons.validator.RequiredNameTest and + * validator-name-required.xml located under validator/src/test). + *

+ *

+ * Create an xml file with your validator and validation rules. + * Setup your required validator in your xml file.
+ *
+ * XML Example
+ * Validator Example
+ * Pluggable Validator Example + *

+ * + *

XML Example

+ *

+ * Definition of a 'required' pluggable validator.
+ *

+ * <form-validation>
+ * <global>
+ * <validator name="required"
+ * classname="org.apache.commons.validator.TestValidator"
+ * method="validateRequired"
+ * methodParams="java.lang.Object, org.apache.commons.validator.Field"/>
+ * </global>
+ * <formset>
+ * </formset>
+ * </form-validation>
+ * 
+ *

+ * Add validation rules to require a first name and a last name.
+ *

+ * <form-validation>
+ * <global>
+ * <validator name="required"
+ * classname="org.apache.commons.validator.TestValidator"
+ * method="validateRequired"
+ * methodParams="java.lang.Object, org.apache.commons.validator.Field"/>
+ * </global>
+ * 
+ * <formset>
+ * <form    name="nameForm">
+ * <field property="firstName" depends="required">
+ * <arg0 key="nameForm.firstname.displayname"/>
+ * </field>
+ * <field property="lastName" depends="required">
+ * <arg0 key="nameForm.lastname.displayname"/>
+ * </field>
+ * </form>
+ * </formset>
+ * 
+ * </form-validation>
+ * 
+ * + *

Validator Example

+ *

+ * Excerpts from org.apache.commons.validator.RequiredNameTest + *

+ *
+ * InputStream in = this.getClass().getResourceAsStream("validator-name-required.xml");
+ * // Create an instance of ValidatorResources to initialize from an xml file.
+ * ValidatorResources resources = new ValidatorResources(in);
+ * // Create bean to run test on.
+ * Name name = new Name();
+ * // Construct validator based on the loaded resources and the form key
+ * Validator validator = new Validator(resources, "nameForm");
+ * // add the name bean to the validator as a resource
+ * // for the validations to be performed on.
+ * validator.setParameter(Validator.BEAN_PARAM, name);
+ * // Get results of the validation.
+ * Map results;
+ * // throws ValidatorException (catch clause not shown here)
+ * results = validator.validate();
+ * if (results.get("firstName") == null) {
+ * // no error
+ * } else {
+ * // number of errors for first name
+ * int errors = ((Integer)results.get("firstName")).intValue();
+ * }
+ * 
+ * + *

Pluggable Validator Example

+ *

+ * Validation method defined in the 'required' pluggable validator + * (excerpt from org.apache.commons.validator.TestValidator). + *

+ *
+ * public static boolean validateRequired(Object bean, Field field) {
+ * String value = ValidatorUtil.getValueAsString(bean, field.getProperty());
+ * return GenericValidator.isBlankOrNull(value);
+ * }
+ * 
+ */ +package org.apache.commons.validator; Fisheye: Tag b233be65d6df2834368af4d2e555a00795aa0f07 refers to a dead (removed) revision in file `3rdParty_sources/commons-validator/org/apache/commons/validator/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java (.../AbstractCalendarValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java (.../AbstractCalendarValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,9 +16,9 @@ */ package org.apache.commons.validator.routines; +import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.Format; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; @@ -30,236 +30,83 @@ *

This is a base class for building Date / Time * Validators using format parsing.

* - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public abstract class AbstractCalendarValidator extends AbstractFormatValidator { private static final long serialVersionUID = -1410008585975827379L; + /** + * The date style to use for Locale validation. + */ private final int dateStyle; + /** + * The time style to use for Locale validation. + */ private final int timeStyle; /** - * Construct an instance with the specified strict, + * Constructs an instance with the specified strict, * time and date style parameters. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param dateStyle the date style to use for Locale validation. * @param timeStyle the time style to use for Locale validation. */ - public AbstractCalendarValidator(boolean strict, int dateStyle, int timeStyle) { + public AbstractCalendarValidator(final boolean strict, final int dateStyle, final int timeStyle) { super(strict); this.dateStyle = dateStyle; this.timeStyle = timeStyle; } /** - *

Validate using the specified Locale. + *

Compares the field from two calendars indicating whether the field for the + * first calendar is equal to, less than or greater than the field from the + * second calendar. * - * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @param locale The locale to use for the Format, defaults to the default - * @return true if the value is valid. + * @param value The Calendar value. + * @param compare The Calendar to check the value against. + * @param field The field to compare for the calendars. + * @return Zero if the first calendar's field is equal to the seconds, -1 + * if it is less than the seconds or +1 if it is greater than the seconds. */ - @Override - public boolean isValid(String value, String pattern, Locale locale) { - Object parsedValue = parse(value, pattern, locale, (TimeZone)null); - return (parsedValue == null ? false : true); - } - - /** - *

Format an object into a String using - * the default Locale.

- * - * @param value The value validation is being performed on. - * @param timeZone The Time Zone used to format the date, - * system default if null (unless value is a Calendar. - * @return The value formatted as a String. - */ - public String format(Object value, TimeZone timeZone) { - return format(value, (String)null, (Locale)null, timeZone); - } - - /** - *

Format an object into a String using - * the specified pattern.

- * - * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @param timeZone The Time Zone used to format the date, - * system default if null (unless value is a Calendar. - * @return The value formatted as a String. - */ - public String format(Object value, String pattern, TimeZone timeZone) { - return format(value, pattern, (Locale)null, timeZone); - } - - /** - *

Format an object into a String using - * the specified Locale.

- * - * @param value The value validation is being performed on. - * @param locale The locale to use for the Format. - * @param timeZone The Time Zone used to format the date, - * system default if null (unless value is a Calendar. - * @return The value formatted as a String. - */ - public String format(Object value, Locale locale, TimeZone timeZone) { - return format(value, (String)null, locale, timeZone); - } - - /** - *

Format an object using the specified pattern and/or - * Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @param locale The locale to use for the Format. - * @return The value formatted as a String. - */ - @Override - public String format(Object value, String pattern, Locale locale) { - return format(value, pattern, locale, (TimeZone)null); - } - - /** - *

Format an object using the specified pattern and/or - * Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @param locale The locale to use for the Format. - * @param timeZone The Time Zone used to format the date, - * system default if null (unless value is a Calendar. - * @return The value formatted as a String. - */ - public String format(Object value, String pattern, Locale locale, TimeZone timeZone) { - DateFormat formatter = (DateFormat)getFormat(pattern, locale); - if (timeZone != null) { - formatter.setTimeZone(timeZone); - } else if (value instanceof Calendar) { - formatter.setTimeZone(((Calendar)value).getTimeZone()); + private int calculateCompareResult(final Calendar value, final Calendar compare, final int field) { + final int difference = value.get(field) - compare.get(field); + if (difference < 0) { + return -1; } - return format(value, formatter); - } - - /** - *

Format a value with the specified DateFormat.

- * - * @param value The value to be formatted. - * @param formatter The Format to use. - * @return The formatted value. - */ - @Override - protected String format(Object value, Format formatter) { - if (value == null) { - return null; - } else if (value instanceof Calendar) { - value = ((Calendar)value).getTime(); + if (difference > 0) { + return 1; } - return formatter.format(value); + return 0; } /** - *

Checks if the value is valid against a specified pattern.

+ *

Calculate the quarter for the specified Calendar.

* - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed value if valid or null if invalid. + * @param calendar The Calendar value. + * @param monthOfFirstQuarter The month that the first quarter starts. + * @return The calculated quarter. */ - protected Object parse(String value, String pattern, Locale locale, TimeZone timeZone) { + private int calculateQuarter(final Calendar calendar, final int monthOfFirstQuarter) { + // Add Year + int year = calendar.get(Calendar.YEAR); - value = (value == null ? null : value.trim()); - if (value == null || value.length() == 0) { - return null; + final int month = calendar.get(Calendar.MONTH) + 1; + final int relativeMonth = month >= monthOfFirstQuarter + ? month - monthOfFirstQuarter + : month + 12 - monthOfFirstQuarter; // CHECKSTYLE IGNORE MagicNumber + final int quarter = relativeMonth / 3 + 1; // CHECKSTYLE IGNORE MagicNumber + // adjust the year if the quarter doesn't start in January + if (month < monthOfFirstQuarter) { + --year; } - DateFormat formatter = (DateFormat)getFormat(pattern, locale); - if (timeZone != null) { - formatter.setTimeZone(timeZone); - } - return parse(value, formatter); - + return year * 10 + quarter; // CHECKSTYLE IGNORE MagicNumber } /** - *

Process the parsed value, performing any further validation - * and type conversion required.

- * - * @param value The parsed object created. - * @param formatter The Format used to parse the value with. - * @return The parsed value converted to the appropriate type - * if valid or null if invalid. - */ - @Override - protected abstract Object processParsedValue(Object value, Format formatter); - - /** - *

Returns a DateFormat for the specified pattern - * and/or Locale.

- * - * @param pattern The pattern used to validate the value against or - * null to use the default for the Locale. - * @param locale The locale to use for the currency format, system default if null. - * @return The DateFormat to created. - */ - @Override - protected Format getFormat(String pattern, Locale locale) { - DateFormat formatter = null; - boolean usePattern = (pattern != null && pattern.length() > 0); - if (!usePattern) { - formatter = (DateFormat)getFormat(locale); - } else if (locale == null) { - formatter = new SimpleDateFormat(pattern); - } else { - DateFormatSymbols symbols = new DateFormatSymbols(locale); - formatter = new SimpleDateFormat(pattern, symbols); - } - formatter.setLenient(false); - return formatter; - } - - /** - *

Returns a DateFormat for the specified Locale.

- * - * @param locale The locale a DateFormat is required for, - * system default if null. - * @return The DateFormat to created. - */ - protected Format getFormat(Locale locale) { - - DateFormat formatter = null; - if (dateStyle >= 0 && timeStyle >= 0) { - if (locale == null) { - formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle); - } else { - formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); - } - } else if (timeStyle >= 0) { - if (locale == null) { - formatter = DateFormat.getTimeInstance(timeStyle); - } else { - formatter = DateFormat.getTimeInstance(timeStyle, locale); - } - } else { - int useDateStyle = dateStyle >= 0 ? dateStyle : DateFormat.SHORT; - if (locale == null) { - formatter = DateFormat.getDateInstance(useDateStyle); - } else { - formatter = DateFormat.getDateInstance(useDateStyle, locale); - } - } - formatter.setLenient(false); - return formatter; - - } - - /** *

Compares a calendar value to another, indicating whether it is * equal, less then or more than at a specified level.

* @@ -271,9 +118,9 @@ * @return Zero if the first value is equal to the second, -1 * if it is less than the second or +1 if it is greater than the second. */ - protected int compare(Calendar value, Calendar compare, int field) { + protected int compare(final Calendar value, final Calendar compare, final int field) { - int result = 0; + int result; // Compare Year result = calculateCompareResult(value, compare, Calendar.YEAR); @@ -304,9 +151,9 @@ // Compare Date result = calculateCompareResult(value, compare, Calendar.DATE); - if (result != 0 || (field == Calendar.DATE || + if (result != 0 || field == Calendar.DATE || field == Calendar.DAY_OF_WEEK || - field == Calendar.DAY_OF_WEEK_IN_MONTH)) { + field == Calendar.DAY_OF_WEEK_IN_MONTH) { return result; } @@ -316,6 +163,28 @@ } /** + *

Compares a calendar's quarter value to another, indicating whether it is + * equal, less then or more than the specified quarter.

+ * + * @param value The Calendar value. + * @param compare The Calendar to check the value against. + * @param monthOfFirstQuarter The month that the first quarter starts. + * @return Zero if the first quarter is equal to the second, -1 + * if it is less than the second or +1 if it is greater than the second. + */ + protected int compareQuarters(final Calendar value, final Calendar compare, final int monthOfFirstQuarter) { + final int valueQuarter = calculateQuarter(value, monthOfFirstQuarter); + final int compareQuarter = calculateQuarter(compare, monthOfFirstQuarter); + if (valueQuarter < compareQuarter) { + return -1; + } + if (valueQuarter > compareQuarter) { + return 1; + } + return 0; + } + + /** *

Compares a calendar time value to another, indicating whether it is * equal, less then or more than at a specified level.

* @@ -327,13 +196,13 @@ * @return Zero if the first value is equal to the second, -1 * if it is less than the second or +1 if it is greater than the second. */ - protected int compareTime(Calendar value, Calendar compare, int field) { + protected int compareTime(final Calendar value, final Calendar compare, final int field) { - int result = 0; + int result; // Compare Hour result = calculateCompareResult(value, compare, Calendar.HOUR_OF_DAY); - if (result != 0 || (field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY)) { + if (result != 0 || field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY) { return result; } @@ -359,69 +228,206 @@ } /** - *

Compares a calendar's quarter value to another, indicating whether it is - * equal, less then or more than the specified quarter.

+ *

Format a value with the specified DateFormat.

* - * @param value The Calendar value. - * @param compare The Calendar to check the value against. - * @param monthOfFirstQuarter The month that the first quarter starts. - * @return Zero if the first quarter is equal to the second, -1 - * if it is less than the second or +1 if it is greater than the second. + * @param value The value to be formatted. + * @param formatter The Format to use. + * @return The formatted value. */ - protected int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) { - int valueQuarter = calculateQuarter(value, monthOfFirstQuarter); - int compareQuarter = calculateQuarter(compare, monthOfFirstQuarter); - if (valueQuarter < compareQuarter) { - return -1; - } else if (valueQuarter > compareQuarter) { - return 1; - } else { - return 0; + @Override + protected String format(Object value, final Format formatter) { + if (value == null) { + return null; } + if (value instanceof Calendar) { + value = ((Calendar)value).getTime(); + } + return formatter.format(value); } /** - *

Calculate the quarter for the specified Calendar.

+ *

Format an object into a String using + * the specified Locale.

* - * @param calendar The Calendar value. - * @param monthOfFirstQuarter The month that the first quarter starts. - * @return The calculated quarter. + * @param value The value validation is being performed on. + * @param locale The locale to use for the Format. + * @param timeZone The Time Zone used to format the date, + * system default if null (unless value is a Calendar. + * @return The value formatted as a String. */ - private int calculateQuarter(Calendar calendar, int monthOfFirstQuarter) { - // Add Year - int year = calendar.get(Calendar.YEAR); + public String format(final Object value, final Locale locale, final TimeZone timeZone) { + return format(value, (String)null, locale, timeZone); + } - int month = (calendar.get(Calendar.MONTH) + 1); - int relativeMonth = (month >= monthOfFirstQuarter) - ? (month - monthOfFirstQuarter) - : (month + (12 - monthOfFirstQuarter)); // CHECKSTYLE IGNORE MagicNumber - int quarter = ((relativeMonth / 3) + 1); // CHECKSTYLE IGNORE MagicNumber - // adjust the year if the quarter doesn't start in January - if (month < monthOfFirstQuarter) { - --year; + /** + *

Format an object using the specified pattern and/or + * Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to format the value. + * @param locale The locale to use for the Format. + * @return The value formatted as a String. + */ + @Override + public String format(final Object value, final String pattern, final Locale locale) { + return format(value, pattern, locale, (TimeZone)null); + } + + /** + *

Format an object using the specified pattern and/or + * Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to format the value. + * @param locale The locale to use for the Format. + * @param timeZone The Time Zone used to format the date, + * system default if null (unless value is a Calendar. + * @return The value formatted as a String. + */ + public String format(final Object value, final String pattern, final Locale locale, final TimeZone timeZone) { + final DateFormat formatter = (DateFormat)getFormat(pattern, locale); + if (timeZone != null) { + formatter.setTimeZone(timeZone); + } else if (value instanceof Calendar) { + formatter.setTimeZone(((Calendar)value).getTimeZone()); } - return (year * 10) + quarter; // CHECKSTYLE IGNORE MagicNumber + return format(value, formatter); } /** - *

Compares the field from two calendars indicating whether the field for the - * first calendar is equal to, less than or greater than the field from the - * second calendar. + *

Format an object into a String using + * the specified pattern.

* - * @param value The Calendar value. - * @param compare The Calendar to check the value against. - * @param field The field to compare for the calendars. - * @return Zero if the first calendar's field is equal to the seconds, -1 - * if it is less than the seconds or +1 if it is greater than the seconds. + * @param value The value validation is being performed on. + * @param pattern The pattern used to format the value. + * @param timeZone The Time Zone used to format the date, + * system default if null (unless value is a Calendar. + * @return The value formatted as a String. */ - private int calculateCompareResult(Calendar value, Calendar compare, int field) { - int difference = value.get(field) - compare.get(field); - if (difference < 0) { - return -1; - } else if (difference > 0) { - return 1; + public String format(final Object value, final String pattern, final TimeZone timeZone) { + return format(value, pattern, (Locale)null, timeZone); + } + + /** + *

Format an object into a String using + * the default Locale.

+ * + * @param value The value validation is being performed on. + * @param timeZone The Time Zone used to format the date, + * system default if null (unless value is a Calendar. + * @return The value formatted as a String. + */ + public String format(final Object value, final TimeZone timeZone) { + return format(value, (String)null, (Locale)null, timeZone); + } + + /** + *

Returns a DateFormat for the specified Locale.

+ * + * @param locale The locale a DateFormat is required for, + * system default if null. + * @return The DateFormat to created. + */ + protected Format getFormat(final Locale locale) { + + DateFormat formatter; + if (dateStyle >= 0 && timeStyle >= 0) { + if (locale == null) { + formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle); + } else { + formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); + } + } else if (timeStyle >= 0) { + if (locale == null) { + formatter = DateFormat.getTimeInstance(timeStyle); + } else { + formatter = DateFormat.getTimeInstance(timeStyle, locale); + } } else { - return 0; + final int useDateStyle = dateStyle >= 0 ? dateStyle : DateFormat.SHORT; + if (locale == null) { + formatter = DateFormat.getDateInstance(useDateStyle); + } else { + formatter = DateFormat.getDateInstance(useDateStyle, locale); + } } + formatter.setLenient(false); + return formatter; + } + + /** + *

Returns a DateFormat for the specified pattern + * and/or Locale.

+ * + * @param pattern The pattern used to validate the value against or + * null to use the default for the Locale. + * @param locale The locale to use for the currency format, system default if null. + * @return The DateFormat to created. + */ + @Override + protected Format getFormat(final String pattern, final Locale locale) { + DateFormat formatter; + final boolean usePattern = pattern != null && !pattern.isEmpty(); + if (!usePattern) { + formatter = (DateFormat)getFormat(locale); + } else if (locale == null) { + formatter = new SimpleDateFormat(pattern); + } else { + final DateFormatSymbols symbols = new DateFormatSymbols(locale); + formatter = new SimpleDateFormat(pattern, symbols); + } + formatter.setLenient(false); + return formatter; + } + + /** + *

Validate using the specified Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to format the value. + * @param locale The locale to use for the Format, defaults to the default + * @return {@code true} if the value is valid. + */ + @Override + public boolean isValid(final String value, final String pattern, final Locale locale) { + final Object parsedValue = parse(value, pattern, locale, (TimeZone)null); + return parsedValue == null ? false : true; + } + + /** + *

Checks if the value is valid against a specified pattern.

+ * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed value if valid or null if invalid. + */ + protected Object parse(String value, final String pattern, final Locale locale, final TimeZone timeZone) { + + value = value == null ? null : value.trim(); + if (value == null || value.isEmpty()) { + return null; + } + final DateFormat formatter = (DateFormat)getFormat(pattern, locale); + if (timeZone != null) { + formatter.setTimeZone(timeZone); + } + return parse(value, formatter); + + } + + /** + *

Process the parsed value, performing any further validation + * and type conversion required.

+ * + * @param value The parsed object created. + * @param formatter The Format used to parse the value with. + * @return The parsed value converted to the appropriate type + * if valid or null if invalid. + */ + @Override + protected abstract Object processParsedValue(Object value, Format formatter); } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java (.../AbstractFormatValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java (.../AbstractFormatValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,158 +16,171 @@ */ package org.apache.commons.validator.routines; +import java.io.Serializable; import java.text.Format; import java.text.ParsePosition; import java.util.Locale; -import java.io.Serializable; /** *

Abstract class for Format based Validation.

* *

This is a base class for building Date and Number * Validators using format parsing.

* - * @version $Revision: 1649191 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public abstract class AbstractFormatValidator implements Serializable { private static final long serialVersionUID = -4690687565200568258L; + /** + * Whether to use strict format. + */ private final boolean strict; /** - * Construct an instance with the specified strict setting. + * Constructs an instance with the specified strict setting. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. */ - public AbstractFormatValidator(boolean strict) { + public AbstractFormatValidator(final boolean strict) { this.strict = strict; } /** - *

Indicates whether validated values should adhere - * strictly to the Format used.

+ *

Format an object into a String using + * the default Locale.

* - *

Typically implementations of Format - * ignore invalid characters at the end of the value - * and just stop parsing. For example parsing a date - * value of 01/01/20x0 using a pattern - * of dd/MM/yyyy will result in a year - * of 20 if strict is set - * to false, whereas setting strict - * to true will cause this value to fail - * validation.

- * - * @return true if strict Format - * parsing should be used. + * @param value The value validation is being performed on. + * @return The value formatted as a String. */ - public boolean isStrict() { - return strict; + public String format(final Object value) { + return format(value, (String)null, (Locale)null); } /** - *

Validate using the default Locale. + *

Format a value with the specified Format.

* - * @param value The value validation is being performed on. - * @return true if the value is valid. + * @param value The value to be formatted. + * @param formatter The Format to use. + * @return The formatted value. */ - public boolean isValid(String value) { - return isValid(value, (String)null, (Locale)null); + protected String format(final Object value, final Format formatter) { + return formatter.format(value); } /** - *

Validate using the specified pattern. + *

Format an object into a String using + * the specified Locale.

* * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return true if the value is valid. + * @param locale The locale to use for the Format. + * @return The value formatted as a String. */ - public boolean isValid(String value, String pattern) { - return isValid(value, pattern, (Locale)null); + public String format(final Object value, final Locale locale) { + return format(value, (String)null, locale); } /** - *

Validate using the specified Locale. + *

Format an object into a String using + * the specified pattern.

* * @param value The value validation is being performed on. - * @param locale The locale to use for the Format, defaults to the default - * @return true if the value is valid. + * @param pattern The pattern used to format the value. + * @return The value formatted as a String. */ - public boolean isValid(String value, Locale locale) { - return isValid(value, (String)null, locale); + public String format(final Object value, final String pattern) { + return format(value, pattern, (Locale)null); } /** - *

Validate using the specified pattern and/or Locale. + *

Format an object using the specified pattern and/or + * Locale. * * @param value The value validation is being performed on. * @param pattern The pattern used to format the value. - * @param locale The locale to use for the Format, defaults to the default - * @return true if the value is valid. + * @param locale The locale to use for the Format. + * @return The value formatted as a String. */ - public abstract boolean isValid(String value, String pattern, Locale locale); + public String format(final Object value, final String pattern, final Locale locale) { + final Format formatter = getFormat(pattern, locale); + return format(value, formatter); + } /** - *

Format an object into a String using - * the default Locale.

+ *

Returns a Format for the specified pattern + * and/or Locale.

* - * @param value The value validation is being performed on. - * @return The value formatted as a String. + * @param pattern The pattern used to validate the value against or + * null to use the default for the Locale. + * @param locale The locale to use for the currency format, system default if null. + * @return The NumberFormat to created. */ - public String format(Object value) { - return format(value, (String)null, (Locale)null); + protected abstract Format getFormat(String pattern, Locale locale); + + /** + *

Indicates whether validated values should adhere + * strictly to the Format used.

+ * + *

Typically implementations of Format + * ignore invalid characters at the end of the value + * and just stop parsing. For example parsing a date + * value of 01/01/20x0 using a pattern + * of dd/MM/yyyy will result in a year + * of 20 if strict is set + * to {@code false}, whereas setting strict + * to {@code true} will cause this value to fail + * validation.

+ * + * @return {@code true} if strict Format + * parsing should be used. + */ + public boolean isStrict() { + return strict; } /** - *

Format an object into a String using - * the specified pattern.

+ *

Validate using the default Locale. * * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @return The value formatted as a String. + * @return {@code true} if the value is valid. */ - public String format(Object value, String pattern) { - return format(value, pattern, (Locale)null); + public boolean isValid(final String value) { + return isValid(value, (String)null, (Locale)null); } /** - *

Format an object into a String using - * the specified Locale.

+ *

Validate using the specified Locale. * * @param value The value validation is being performed on. - * @param locale The locale to use for the Format. - * @return The value formatted as a String. + * @param locale The locale to use for the Format, defaults to the default + * @return {@code true} if the value is valid. */ - public String format(Object value, Locale locale) { - return format(value, (String)null, locale); + public boolean isValid(final String value, final Locale locale) { + return isValid(value, (String)null, locale); } /** - *

Format an object using the specified pattern and/or - * Locale. + *

Validate using the specified pattern. * * @param value The value validation is being performed on. - * @param pattern The pattern used to format the value. - * @param locale The locale to use for the Format. - * @return The value formatted as a String. + * @param pattern The pattern used to validate the value against. + * @return {@code true} if the value is valid. */ - public String format(Object value, String pattern, Locale locale) { - Format formatter = getFormat(pattern, locale); - return format(value, formatter); + public boolean isValid(final String value, final String pattern) { + return isValid(value, pattern, (Locale)null); } /** - *

Format a value with the specified Format.

+ *

Validate using the specified pattern and/or Locale. * - * @param value The value to be formatted. - * @param formatter The Format to use. - * @return The formatted value. + * @param value The value validation is being performed on. + * @param pattern The pattern used to format the value. + * @param locale The locale to use for the Format, defaults to the default + * @return {@code true} if the value is valid. */ - protected String format(Object value, Format formatter) { - return formatter.format(value); - } + public abstract boolean isValid(String value, String pattern, Locale locale); /** *

Parse the value with the specified Format.

@@ -176,9 +189,9 @@ * @param formatter The Format to parse the value with. * @return The parsed value if valid or null if invalid. */ - protected Object parse(String value, Format formatter) { + protected Object parse(final String value, final Format formatter) { - ParsePosition pos = new ParsePosition(0); + final ParsePosition pos = new ParsePosition(0); Object parsedValue = formatter.parseObject(value, pos); if (pos.getErrorIndex() > -1) { return null; @@ -207,15 +220,4 @@ */ protected abstract Object processParsedValue(Object value, Format formatter); - /** - *

Returns a Format for the specified pattern - * and/or Locale.

- * - * @param pattern The pattern used to validate the value against or - * null to use the default for the Locale. - * @param locale The locale to use for the currency format, system default if null. - * @return The NumberFormat to created. - */ - protected abstract Format getFormat(String pattern, Locale locale); - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractNumberValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractNumberValidator.java (.../AbstractNumberValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractNumberValidator.java (.../AbstractNumberValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,10 +16,10 @@ */ package org.apache.commons.validator.routines; +import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.Format; import java.text.NumberFormat; -import java.text.DecimalFormat; import java.util.Locale; /** @@ -28,8 +28,7 @@ *

This is a base class for building Number * Validators using format parsing.

* - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public abstract class AbstractNumberValidator extends AbstractFormatValidator { @@ -42,40 +41,136 @@ public static final int CURRENCY_FORMAT = 1; /** Percent NumberFormat type */ - public static final int PERCENT_FORMAT = 2; + public static final int PERCENT_FORMAT = 2; + /** + * {@code true} if fractions are allowed or {@code false} if integers only. + */ private final boolean allowFractions; - private final int formatType; /** - * Construct an instance with specified strict + * The NumberFormat type to create for validation, default is STANDARD_FORMAT. + */ + private final int formatType; + + /** + * Constructs an instance with specified strict * and decimal parameters. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. - * @param allowFractions true if fractions are - * allowed or false if integers only. + * @param allowFractions {@code true} if fractions are + * allowed or {@code false} if integers only. */ - public AbstractNumberValidator(boolean strict, int formatType, boolean allowFractions) { + public AbstractNumberValidator(final boolean strict, final int formatType, final boolean allowFractions) { super(strict); this.allowFractions = allowFractions; this.formatType = formatType; } /** - *

Indicates whether the number being validated is - * a decimal or integer.

+ *

Returns the multiplier of the NumberFormat.

* - * @return true if decimals are allowed - * or false if the number is an integer. + * @param format The NumberFormat to determine the + * multiplier of. + * @return The multiplying factor for the format.. */ - public boolean isAllowFractions() { - return allowFractions; + protected int determineScale(final NumberFormat format) { + if (!isStrict()) { + return -1; + } + if (!isAllowFractions() || format.isParseIntegerOnly()) { + return 0; + } + final int minimumFraction = format.getMinimumFractionDigits(); + final int maximumFraction = format.getMaximumFractionDigits(); + if (minimumFraction != maximumFraction) { + return -1; + } + int scale = minimumFraction; + if (format instanceof DecimalFormat) { + final int multiplier = ((DecimalFormat) format).getMultiplier(); + if (multiplier == 100) { // CHECKSTYLE IGNORE MagicNumber + scale += 2; // CHECKSTYLE IGNORE MagicNumber + } else if (multiplier == 1000) { // CHECKSTYLE IGNORE MagicNumber + scale += 3; // CHECKSTYLE IGNORE MagicNumber + } + } else if (formatType == PERCENT_FORMAT) { + scale += 2; // CHECKSTYLE IGNORE MagicNumber + } + return scale; } /** + *

Returns a NumberFormat for the specified Locale.

+ * + * @param locale The locale a NumberFormat is required for, + * system default if null. + * @return The NumberFormat to created. + */ + protected Format getFormat(final Locale locale) { + NumberFormat formatter; + switch (formatType) { + case CURRENCY_FORMAT: + if (locale == null) { + formatter = NumberFormat.getCurrencyInstance(); + } else { + formatter = NumberFormat.getCurrencyInstance(locale); + } + break; + case PERCENT_FORMAT: + if (locale == null) { + formatter = NumberFormat.getPercentInstance(); + } else { + formatter = NumberFormat.getPercentInstance(locale); + } + break; + default: + if (locale == null) { + formatter = NumberFormat.getInstance(); + } else { + formatter = NumberFormat.getInstance(locale); + } + if (!isAllowFractions()) { + formatter.setParseIntegerOnly(true); + } + break; + } + return formatter; + } + + /** + *

Returns a NumberFormat for the specified pattern + * and/or Locale.

+ * + * @param pattern The pattern used to validate the value against or + * null to use the default for the Locale. + * @param locale The locale to use for the currency format, system default if null. + * @return The NumberFormat to created. + */ + @Override + protected Format getFormat(final String pattern, final Locale locale) { + + NumberFormat formatter; + final boolean usePattern = pattern != null && !pattern.isEmpty(); + if (!usePattern) { + formatter = (NumberFormat) getFormat(locale); + } else if (locale == null) { + formatter = new DecimalFormat(pattern); + } else { + final DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale); + formatter = new DecimalFormat(pattern, symbols); + } + + if (!isAllowFractions()) { + formatter.setParseIntegerOnly(true); + } + return formatter; + } + + /** *

Indicates the type of NumberFormat created * by this validator instance.

* @@ -86,18 +181,14 @@ } /** - *

Validate using the specified Locale.

+ *

Indicates whether the number being validated is + * a decimal or integer.

* - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return true if the value is valid. + * @return {@code true} if decimals are allowed + * or {@code false} if the number is an integer. */ - @Override - public boolean isValid(String value, String pattern, Locale locale) { - Object parsedValue = parse(value, pattern, locale); - return (parsedValue == null ? false : true); + public boolean isAllowFractions() { + return allowFractions; } /** @@ -106,44 +197,59 @@ * @param value The value validation is being performed on. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(Number value, Number min, Number max) { - return (minValue(value, min) && maxValue(value, max)); + public boolean isInRange(final Number value, final Number min, final Number max) { + return minValue(value, min) && maxValue(value, max); } /** - * Check if the value is greater than or equal to a minimum. + *

Validate using the specified Locale.

* * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return {@code true} if the value is valid. */ - public boolean minValue(Number value, Number min) { - if (isAllowFractions()) { - return (value.doubleValue() >= min.doubleValue()); - } - return (value.longValue() >= min.longValue()); + @Override + public boolean isValid(final String value, final String pattern, final Locale locale) { + final Object parsedValue = parse(value, pattern, locale); + return parsedValue == null ? false : true; } /** * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. * @param max The maximum value. - * @return true if the value is less than + * @return {@code true} if the value is less than * or equal to the maximum. */ - public boolean maxValue(Number value, Number max) { + public boolean maxValue(final Number value, final Number max) { if (isAllowFractions()) { - return (value.doubleValue() <= max.doubleValue()); + return value.doubleValue() <= max.doubleValue(); } - return (value.longValue() <= max.longValue()); + return value.longValue() <= max.longValue(); } /** + * Check if the value is greater than or equal to a minimum. + * + * @param value The value validation is being performed on. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(final Number value, final Number min) { + if (isAllowFractions()) { + return value.doubleValue() >= min.doubleValue(); + } + return value.longValue() >= min.longValue(); + } + + /** *

Parse the value using the specified pattern.

* * @param value The value validation is being performed on. @@ -152,13 +258,12 @@ * @param locale The locale to use for the date format, system default if null. * @return The parsed value if valid or null if invalid. */ - protected Object parse(String value, String pattern, Locale locale) { - - value = (value == null ? null : value.trim()); - if (value == null || value.length() == 0) { + protected Object parse(String value, final String pattern, final Locale locale) { + value = value == null ? null : value.trim(); + if (value == null || value.isEmpty()) { return null; } - Format formatter = getFormat(pattern, locale); + final Format formatter = getFormat(pattern, locale); return parse(value, formatter); } @@ -174,101 +279,4 @@ */ @Override protected abstract Object processParsedValue(Object value, Format formatter); - - /** - *

Returns a NumberFormat for the specified pattern - * and/or Locale.

- * - * @param pattern The pattern used to validate the value against or - * null to use the default for the Locale. - * @param locale The locale to use for the currency format, system default if null. - * @return The NumberFormat to created. - */ - @Override - protected Format getFormat(String pattern, Locale locale) { - - NumberFormat formatter = null; - boolean usePattern = (pattern != null && pattern.length() > 0); - if (!usePattern) { - formatter = (NumberFormat)getFormat(locale); - } else if (locale == null) { - formatter = new DecimalFormat(pattern); - } else { - DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale); - formatter = new DecimalFormat(pattern, symbols); - } - - if (determineScale(formatter) == 0) { - formatter.setParseIntegerOnly(true); - } - return formatter; - } - - /** - *

Returns the multiplier of the NumberFormat.

- * - * @param format The NumberFormat to determine the - * multiplier of. - * @return The multiplying factor for the format.. - */ - protected int determineScale(NumberFormat format) { - if (!isStrict()) { - return -1; - } - if (!isAllowFractions() || format.isParseIntegerOnly()) { - return 0; - } - int minimumFraction = format.getMinimumFractionDigits(); - int maximumFraction = format.getMaximumFractionDigits(); - if (minimumFraction != maximumFraction) { - return -1; - } - int scale = minimumFraction; - if (format instanceof DecimalFormat) { - int multiplier = ((DecimalFormat)format).getMultiplier(); - if (multiplier == 100) { // CHECKSTYLE IGNORE MagicNumber - scale += 2; // CHECKSTYLE IGNORE MagicNumber - } else if (multiplier == 1000) { // CHECKSTYLE IGNORE MagicNumber - scale += 3; // CHECKSTYLE IGNORE MagicNumber - } - } else if (formatType == PERCENT_FORMAT) { - scale += 2; // CHECKSTYLE IGNORE MagicNumber - } - return scale; - } - - /** - *

Returns a NumberFormat for the specified Locale.

- * - * @param locale The locale a NumberFormat is required for, - * system default if null. - * @return The NumberFormat to created. - */ - protected Format getFormat(Locale locale) { - NumberFormat formatter = null; - switch (formatType) { - case CURRENCY_FORMAT: - if (locale == null) { - formatter = NumberFormat.getCurrencyInstance(); - } else { - formatter = NumberFormat.getCurrencyInstance(locale); - } - break; - case PERCENT_FORMAT: - if (locale == null) { - formatter = NumberFormat.getPercentInstance(); - } else { - formatter = NumberFormat.getPercentInstance(locale); - } - break; - default: - if (locale == null) { - formatter = NumberFormat.getInstance(); - } else { - formatter = NumberFormat.getInstance(locale); - } - break; - } - return formatter; - } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigDecimalValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigDecimalValidator.java (.../BigDecimalValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigDecimalValidator.java (.../BigDecimalValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -63,8 +63,7 @@ *
  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class BigDecimalValidator extends AbstractNumberValidator { @@ -81,7 +80,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public BigDecimalValidator() { this(true); @@ -90,10 +89,10 @@ /** *

    Construct an instance with the specified strict setting.

    * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. */ - public BigDecimalValidator(boolean strict) { + public BigDecimalValidator(final boolean strict) { this(strict, STANDARD_FORMAT, true); } @@ -113,104 +112,53 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. - * @param allowFractions true if fractions are - * allowed or false if integers only. + * @param allowFractions {@code true} if fractions are + * allowed or {@code false} if integers only. */ - protected BigDecimalValidator(boolean strict, int formatType, - boolean allowFractions) { + protected BigDecimalValidator(final boolean strict, final int formatType, + final boolean allowFractions) { super(strict, formatType, allowFractions); } /** - *

    Validate/convert a BigDecimal using the default - * Locale. - * - * @param value The value validation is being performed on. - * @return The parsed BigDecimal if valid or null - * if invalid. - */ - public BigDecimal validate(String value) { - return (BigDecimal)parse(value, (String)null, (Locale)null); - } - - /** - *

    Validate/convert a BigDecimal using the - * specified pattern. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @return The parsed BigDecimal if valid or null if invalid. - */ - public BigDecimal validate(String value, String pattern) { - return (BigDecimal)parse(value, pattern, (Locale)null); - } - - /** - *

    Validate/convert a BigDecimal using the - * specified Locale. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed BigDecimal if valid or null if invalid. - */ - public BigDecimal validate(String value, Locale locale) { - return (BigDecimal)parse(value, (String)null, locale); - } - - /** - *

    Validate/convert a BigDecimal using the - * specified pattern and/ or Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed BigDecimal if valid or null if invalid. - */ - public BigDecimal validate(String value, String pattern, Locale locale) { - return (BigDecimal)parse(value, pattern, locale); - } - - /** * Check if the value is within a specified range. * * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(BigDecimal value, double min, double max) { - return (value.doubleValue() >= min && value.doubleValue() <= max); + public boolean isInRange(final BigDecimal value, final double min, final double max) { + return value.doubleValue() >= min && value.doubleValue() <= max; } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(BigDecimal value, double min) { - return (value.doubleValue() >= min); + public boolean maxValue(final BigDecimal value, final double max) { + return value.doubleValue() <= max; } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(BigDecimal value, double max) { - return (value.doubleValue() <= max); + public boolean minValue(final BigDecimal value, final double min) { + return value.doubleValue() >= min; } /** @@ -222,19 +170,70 @@ * BigDecimal. */ @Override - protected Object processParsedValue(Object value, Format formatter) { - BigDecimal decimal = null; + protected Object processParsedValue(final Object value, final Format formatter) { + BigDecimal decimal; if (value instanceof Long) { decimal = BigDecimal.valueOf(((Long)value).longValue()); } else { decimal = new BigDecimal(value.toString()); } - int scale = determineScale((NumberFormat)formatter); + final int scale = determineScale((NumberFormat)formatter); if (scale >= 0) { decimal = decimal.setScale(scale, BigDecimal.ROUND_DOWN); } return decimal; } + + /** + *

    Validate/convert a BigDecimal using the default + * Locale. + * + * @param value The value validation is being performed on. + * @return The parsed BigDecimal if valid or null + * if invalid. + */ + public BigDecimal validate(final String value) { + return (BigDecimal)parse(value, (String)null, (Locale)null); + } + + /** + *

    Validate/convert a BigDecimal using the + * specified Locale. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed BigDecimal if valid or null if invalid. + */ + public BigDecimal validate(final String value, final Locale locale) { + return (BigDecimal)parse(value, (String)null, locale); + } + + /** + *

    Validate/convert a BigDecimal using the + * specified pattern. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @return The parsed BigDecimal if valid or null if invalid. + */ + public BigDecimal validate(final String value, final String pattern) { + return (BigDecimal)parse(value, pattern, (Locale)null); + } + + /** + *

    Validate/convert a BigDecimal using the + * specified pattern and/ or Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed BigDecimal if valid or null if invalid. + */ + public BigDecimal validate(final String value, final String pattern, final Locale locale) { + return (BigDecimal)parse(value, pattern, locale); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java (.../BigIntegerValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java (.../BigIntegerValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -60,8 +60,7 @@ *

  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class BigIntegerValidator extends AbstractNumberValidator { @@ -78,7 +77,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public BigIntegerValidator() { this(true, STANDARD_FORMAT); @@ -100,112 +99,112 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public BigIntegerValidator(boolean strict, int formatType) { + public BigIntegerValidator(final boolean strict, final int formatType) { super(strict, formatType, false); } /** - *

    Validate/convert a BigInteger using the default - * Locale. + * Check if the value is within a specified range. * - * @param value The value validation is being performed on. - * @return The parsed BigInteger if valid or null - * if invalid. + * @param value The Number value to check. + * @param min The minimum value of the range. + * @param max The maximum value of the range. + * @return {@code true} if the value is within the + * specified range. */ - public BigInteger validate(String value) { - return (BigInteger)parse(value, (String)null, (Locale)null); + public boolean isInRange(final BigInteger value, final long min, final long max) { + return value.longValue() >= min && value.longValue() <= max; } /** - *

    Validate/convert a BigInteger using the - * specified pattern. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed BigInteger if valid or null if invalid. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public BigInteger validate(String value, String pattern) { - return (BigInteger)parse(value, pattern, (Locale)null); + public boolean maxValue(final BigInteger value, final long max) { + return value.longValue() <= max; } /** - *

    Validate/convert a BigInteger using the - * specified Locale. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed BigInteger if valid or null if invalid. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public BigInteger validate(String value, Locale locale) { - return (BigInteger)parse(value, (String)null, locale); + public boolean minValue(final BigInteger value, final long min) { + return value.longValue() >= min; } /** - *

    Validate/convert a BigInteger using the - * specified pattern and/ or Locale. + * Convert the parsed value to a BigInteger. * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed BigInteger if valid or null if invalid. + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * BigInteger. */ - public BigInteger validate(String value, String pattern, Locale locale) { - return (BigInteger)parse(value, pattern, locale); + @Override + protected Object processParsedValue(final Object value, final Format formatter) { + return BigInteger.valueOf(((Number)value).longValue()); } /** - * Check if the value is within a specified range. + *

    Validate/convert a BigInteger using the default + * Locale. * - * @param value The Number value to check. - * @param min The minimum value of the range. - * @param max The maximum value of the range. - * @return true if the value is within the - * specified range. + * @param value The value validation is being performed on. + * @return The parsed BigInteger if valid or null + * if invalid. */ - public boolean isInRange(BigInteger value, long min, long max) { - return (value.longValue() >= min && value.longValue() <= max); + public BigInteger validate(final String value) { + return (BigInteger)parse(value, (String)null, (Locale)null); } /** - * Check if the value is greater than or equal to a minimum. + *

    Validate/convert a BigInteger using the + * specified Locale. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed BigInteger if valid or null if invalid. */ - public boolean minValue(BigInteger value, long min) { - return (value.longValue() >= min); + public BigInteger validate(final String value, final Locale locale) { + return (BigInteger)parse(value, (String)null, locale); } /** - * Check if the value is less than or equal to a maximum. + *

    Validate/convert a BigInteger using the + * specified pattern. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param pattern The pattern used to validate the value against. + * @return The parsed BigInteger if valid or null if invalid. */ - public boolean maxValue(BigInteger value, long max) { - return (value.longValue() <= max); + public BigInteger validate(final String value, final String pattern) { + return (BigInteger)parse(value, pattern, (Locale)null); } /** - * Convert the parsed value to a BigInteger. + *

    Validate/convert a BigInteger using the + * specified pattern and/ or Locale. * - * @param value The parsed Number object created. - * @param formatter The Format used to parse the value with. - * @return The parsed Number converted to a - * BigInteger. + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed BigInteger if valid or null if invalid. */ - @Override - protected Object processParsedValue(Object value, Format formatter) { - return BigInteger.valueOf(((Number)value).longValue()); + public BigInteger validate(final String value, final String pattern, final Locale locale) { + return (BigInteger)parse(value, pattern, locale); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java (.../ByteValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java (.../ByteValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -59,8 +59,7 @@ *

  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class ByteValidator extends AbstractNumberValidator { @@ -77,7 +76,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public ByteValidator() { this(true, STANDARD_FORMAT); @@ -99,158 +98,160 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public ByteValidator(boolean strict, int formatType) { + public ByteValidator(final boolean strict, final int formatType) { super(strict, formatType, false); } /** - *

    Validate/convert a Byte using the default - * Locale. + * Check if the value is within a specified range. * - * @param value The value validation is being performed on. - * @return The parsed Byte if valid or null - * if invalid. + * @param value The Number value to check. + * @param min The minimum value of the range. + * @param max The maximum value of the range. + * @return {@code true} if the value is within the + * specified range. */ - public Byte validate(String value) { - return (Byte)parse(value, (String)null, (Locale)null); + public boolean isInRange(final byte value, final byte min, final byte max) { + return value >= min && value <= max; } /** - *

    Validate/convert a Byte using the - * specified pattern. + * Check if the value is within a specified range. * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Byte if valid or null if invalid. + * @param value The Number value to check. + * @param min The minimum value of the range. + * @param max The maximum value of the range. + * @return {@code true} if the value is within the + * specified range. */ - public Byte validate(String value, String pattern) { - return (Byte)parse(value, pattern, (Locale)null); + public boolean isInRange(final Byte value, final byte min, final byte max) { + return isInRange(value.byteValue(), min, max); } /** - *

    Validate/convert a Byte using the - * specified Locale. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Byte if valid or null if invalid. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public Byte validate(String value, Locale locale) { - return (Byte)parse(value, (String)null, locale); + public boolean maxValue(final byte value, final byte max) { + return value <= max; } /** - *

    Validate/convert a Byte using the - * specified pattern and/ or Locale. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Byte if valid or null if invalid. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public Byte validate(String value, String pattern, Locale locale) { - return (Byte)parse(value, pattern, locale); + public boolean maxValue(final Byte value, final byte max) { + return maxValue(value.byteValue(), max); } /** - * Check if the value is within a specified range. + * Check if the value is greater than or equal to a minimum. * - * @param value The Number value to check. - * @param min The minimum value of the range. - * @param max The maximum value of the range. - * @return true if the value is within the - * specified range. + * @param value The value validation is being performed on. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean isInRange(byte value, byte min, byte max) { - return (value >= min && value <= max); + public boolean minValue(final byte value, final byte min) { + return value >= min; } /** - * Check if the value is within a specified range. + * Check if the value is greater than or equal to a minimum. * - * @param value The Number value to check. - * @param min The minimum value of the range. - * @param max The maximum value of the range. - * @return true if the value is within the - * specified range. + * @param value The value validation is being performed on. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean isInRange(Byte value, byte min, byte max) { - return isInRange(value.byteValue(), min, max); + public boolean minValue(final Byte value, final byte min) { + return minValue(value.byteValue(), min); } /** - * Check if the value is greater than or equal to a minimum. + *

    Perform further validation and convert the Number to + * a Byte.

    * - * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * Byte if valid or null if invalid. */ - public boolean minValue(byte value, byte min) { - return (value >= min); + @Override + protected Object processParsedValue(final Object value, final Format formatter) { + + // Parsed value will be Long if it fits in a long and is not fractional + if (value instanceof Long) { + final long longValue = ((Long)value).longValue(); + if (longValue >= Byte.MIN_VALUE && + longValue <= Byte.MAX_VALUE) { + return Byte.valueOf((byte)longValue); + } + } + return null; } /** - * Check if the value is greater than or equal to a minimum. + *

    Validate/convert a Byte using the default + * Locale. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @return The parsed Byte if valid or null + * if invalid. */ - public boolean minValue(Byte value, byte min) { - return minValue(value.byteValue(), min); + public Byte validate(final String value) { + return (Byte)parse(value, (String)null, (Locale)null); } /** - * Check if the value is less than or equal to a maximum. + *

    Validate/convert a Byte using the + * specified Locale. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Byte if valid or null if invalid. */ - public boolean maxValue(byte value, byte max) { - return (value <= max); + public Byte validate(final String value, final Locale locale) { + return (Byte)parse(value, (String)null, locale); } /** - * Check if the value is less than or equal to a maximum. + *

    Validate/convert a Byte using the + * specified pattern. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param pattern The pattern used to validate the value against. + * @return The parsed Byte if valid or null if invalid. */ - public boolean maxValue(Byte value, byte max) { - return maxValue(value.byteValue(), max); + public Byte validate(final String value, final String pattern) { + return (Byte)parse(value, pattern, (Locale)null); } /** - *

    Perform further validation and convert the Number to - * a Byte.

    + *

    Validate/convert a Byte using the + * specified pattern and/ or Locale. * - * @param value The parsed Number object created. - * @param formatter The Format used to parse the value with. - * @return The parsed Number converted to a - * Byte if valid or null if invalid. + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Byte if valid or null if invalid. */ - @Override - protected Object processParsedValue(Object value, Format formatter) { - - long longValue = ((Number)value).longValue(); - - if (longValue < Byte.MIN_VALUE || - longValue > Byte.MAX_VALUE) { - return null; - } - return Byte.valueOf((byte)longValue); + public Byte validate(final String value, final String pattern, final Locale locale) { + return (Byte)parse(value, pattern, locale); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java (.../CalendarValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java (.../CalendarValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -82,8 +82,7 @@ *

  • using the format for the default Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class CalendarValidator extends AbstractCalendarValidator { @@ -92,6 +91,26 @@ private static final CalendarValidator VALIDATOR = new CalendarValidator(); /** + *

    Adjusts a Calendar's value to a different TimeZone.

    + * + * @param value The value to adjust. + * @param timeZone The new time zone to use to adjust the Calendar to. + */ + public static void adjustToTimeZone(final Calendar value, final TimeZone timeZone) { + if (value.getTimeZone().hasSameRules(timeZone)) { + value.setTimeZone(timeZone); + } else { + final int year = value.get(Calendar.YEAR); + final int month = value.get(Calendar.MONTH); + final int date = value.get(Calendar.DATE); + final int hour = value.get(Calendar.HOUR_OF_DAY); + final int minute = value.get(Calendar.MINUTE); + value.setTimeZone(timeZone); + value.set(year, month, date, hour, minute); + } + } + + /** * Return a singleton instance of this validator. * @return A singleton instance of the CalendarValidator. */ @@ -100,73 +119,127 @@ } /** - * Construct a strict instance with short + * Constructs a strict instance with short * date style. */ public CalendarValidator() { this(true, DateFormat.SHORT); } /** - * Construct an instance with the specified strict + * Constructs an instance with the specified strict * and date style parameters. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param dateStyle the date style to use for Locale validation. */ - public CalendarValidator(boolean strict, int dateStyle) { + public CalendarValidator(final boolean strict, final int dateStyle) { super(strict, dateStyle, -1); } /** - *

    Validate/convert a Calendar using the default - * Locale and TimeZone. + *

    Compare Dates (day, month and year - not time).

    * - * @param value The value validation is being performed on. - * @return The parsed Calendar if valid or null - * if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the dates are equal, -1 if first + * date is less than the seconds and +1 if the first + * date is greater than. */ - public Calendar validate(String value) { - return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null); + public int compareDates(final Calendar value, final Calendar compare) { + return compare(value, compare, Calendar.DATE); } /** - *

    Validate/convert a Calendar using the specified - * TimeZone and default Locale. + *

    Compare Months (month and year).

    * - * @param value The value validation is being performed on. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Calendar if valid or null - * if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the months are equal, -1 if first + * parameter's month is less than the seconds and +1 if the first + * parameter's month is greater than. */ - public Calendar validate(String value, TimeZone timeZone) { - return (Calendar)parse(value, (String)null, (Locale)null, timeZone); + public int compareMonths(final Calendar value, final Calendar compare) { + return compare(value, compare, Calendar.MONTH); } /** - *

    Validate/convert a Calendar using the specified - * pattern and default TimeZone. + *

    Compare Quarters (quarter and year).

    * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Calendar if valid or null if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to check the value against. + * @return Zero if the quarters are equal, -1 if first + * parameter's quarter is less than the seconds and +1 if the first + * parameter's quarter is greater than. */ - public Calendar validate(String value, String pattern) { - return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + public int compareQuarters(final Calendar value, final Calendar compare) { + return compareQuarters(value, compare, 1); } /** - *

    Validate/convert a Calendar using the specified - * pattern and TimeZone. + *

    Compare Quarters (quarter and year).

    * + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @param monthOfFirstQuarter The month that the first quarter starts. + * @return Zero if the quarters are equal, -1 if first + * parameter's quarter is less than the seconds and +1 if the first + * parameter's quarter is greater than. + */ + @Override + public int compareQuarters(final Calendar value, final Calendar compare, final int monthOfFirstQuarter) { + return super.compareQuarters(value, compare, monthOfFirstQuarter); + } + + /** + *

    Compare Weeks (week and year).

    + * + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the weeks are equal, -1 if first + * parameter's week is less than the seconds and +1 if the first + * parameter's week is greater than. + */ + public int compareWeeks(final Calendar value, final Calendar compare) { + return compare(value, compare, Calendar.WEEK_OF_YEAR); + } + + /** + *

    Compare Years.

    + * + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the years are equal, -1 if first + * parameter's year is less than the seconds and +1 if the first + * parameter's year is greater than. + */ + public int compareYears(final Calendar value, final Calendar compare) { + return compare(value, compare, Calendar.YEAR); + } + + /** + *

    Convert the parsed Date to a Calendar.

    + * + * @param value The parsed Date object created. + * @param formatter The Format used to parse the value with. + * @return The parsed value converted to a Calendar. + */ + @Override + protected Object processParsedValue(final Object value, final Format formatter) { + return ((DateFormat)formatter).getCalendar(); + } + + /** + *

    Validate/convert a Calendar using the default + * Locale and TimeZone. + * * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Calendar if valid or null if invalid. + * @return The parsed Calendar if valid or null + * if invalid. */ - public Calendar validate(String value, String pattern, TimeZone timeZone) { - return (Calendar)parse(value, pattern, (Locale)null, timeZone); + public Calendar validate(final String value) { + return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null); } /** @@ -177,7 +250,7 @@ * @param locale The locale to use for the date format, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, Locale locale) { + public Calendar validate(final String value, final Locale locale) { return (Calendar)parse(value, (String)null, locale, (TimeZone)null); } @@ -190,11 +263,23 @@ * @param timeZone The Time Zone used to parse the date, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, Locale locale, TimeZone timeZone) { + public Calendar validate(final String value, final Locale locale, final TimeZone timeZone) { return (Calendar)parse(value, (String)null, locale, timeZone); } /** + *

    Validate/convert a Calendar using the specified + * pattern and default TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed Calendar if valid or null if invalid. + */ + public Calendar validate(final String value, final String pattern) { + return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + } + + /** *

    Validate/convert a Calendar using the specified pattern * and Locale and the default TimeZone. * @@ -204,7 +289,7 @@ * @param locale The locale to use for the date format, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, String pattern, Locale locale) { + public Calendar validate(final String value, final String pattern, final Locale locale) { return (Calendar)parse(value, pattern, locale, (TimeZone)null); } @@ -219,120 +304,34 @@ * @param timeZone The Time Zone used to parse the date, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) { + public Calendar validate(final String value, final String pattern, final Locale locale, final TimeZone timeZone) { return (Calendar)parse(value, pattern, locale, timeZone); } /** - *

    Adjusts a Calendar's value to a different TimeZone.

    + *

    Validate/convert a Calendar using the specified + * pattern and TimeZone. * - * @param value The value to adjust. - * @param timeZone The new time zone to use to adjust the Calendar to. + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Calendar if valid or null if invalid. */ - public static void adjustToTimeZone(Calendar value, TimeZone timeZone) { - if (value.getTimeZone().hasSameRules(timeZone)) { - value.setTimeZone(timeZone); - } else { - int year = value.get(Calendar.YEAR); - int month = value.get(Calendar.MONTH); - int date = value.get(Calendar.DATE); - int hour = value.get(Calendar.HOUR_OF_DAY); - int minute = value.get(Calendar.MINUTE); - value.setTimeZone(timeZone); - value.set(year, month, date, hour, minute); - } + public Calendar validate(final String value, final String pattern, final TimeZone timeZone) { + return (Calendar)parse(value, pattern, (Locale)null, timeZone); } /** - *

    Compare Dates (day, month and year - not time).

    + *

    Validate/convert a Calendar using the specified + * TimeZone and default Locale. * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the dates are equal, -1 if first - * date is less than the seconds and +1 if the first - * date is greater than. + * @param value The value validation is being performed on. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Calendar if valid or null + * if invalid. */ - public int compareDates(Calendar value, Calendar compare) { - return compare(value, compare, Calendar.DATE); + public Calendar validate(final String value, final TimeZone timeZone) { + return (Calendar)parse(value, (String)null, (Locale)null, timeZone); } - /** - *

    Compare Weeks (week and year).

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the weeks are equal, -1 if first - * parameter's week is less than the seconds and +1 if the first - * parameter's week is greater than. - */ - public int compareWeeks(Calendar value, Calendar compare) { - return compare(value, compare, Calendar.WEEK_OF_YEAR); - } - - /** - *

    Compare Months (month and year).

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the months are equal, -1 if first - * parameter's month is less than the seconds and +1 if the first - * parameter's month is greater than. - */ - public int compareMonths(Calendar value, Calendar compare) { - return compare(value, compare, Calendar.MONTH); - } - - /** - *

    Compare Quarters (quarter and year).

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to check the value against. - * @return Zero if the quarters are equal, -1 if first - * parameter's quarter is less than the seconds and +1 if the first - * parameter's quarter is greater than. - */ - public int compareQuarters(Calendar value, Calendar compare) { - return compareQuarters(value, compare, 1); - } - - /** - *

    Compare Quarters (quarter and year).

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @param monthOfFirstQuarter The month that the first quarter starts. - * @return Zero if the quarters are equal, -1 if first - * parameter's quarter is less than the seconds and +1 if the first - * parameter's quarter is greater than. - */ - @Override - public int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) { - return super.compareQuarters(value, compare, monthOfFirstQuarter); - } - - /** - *

    Compare Years.

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the years are equal, -1 if first - * parameter's year is less than the seconds and +1 if the first - * parameter's year is greater than. - */ - public int compareYears(Calendar value, Calendar compare) { - return compare(value, compare, Calendar.YEAR); - } - - /** - *

    Convert the parsed Date to a Calendar.

    - * - * @param value The parsed Date object created. - * @param formatter The Format used to parse the value with. - * @return The parsed value converted to a Calendar. - */ - @Override - protected Object processParsedValue(Object value, Format formatter) { - return ((DateFormat)formatter).getCalendar(); - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CodeValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CodeValidator.java (.../CodeValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CodeValidator.java (.../CodeValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -43,7 +43,7 @@ * nor do they generally check the format/length). * To be sure that you are passing valid input to a method use {@link #validate(String)} as follows: *
    - * Object valid = validator.validate(input); 
    + * Object valid = validator.validate(input);
      * if (valid != null) {
      *    some_method(valid.toString());
      * }
    @@ -63,103 +63,109 @@
      * expression (i.e. use the (?:   ) notation).
      * 
    * Or just avoid using parentheses except for the parts you want to capture - * - * @version $Revision: 1781789 $ - * @since Validator 1.4 + * + * @since 1.4 */ public final class CodeValidator implements Serializable { private static final long serialVersionUID = 446960910870938233L; + /** The format regular expression validator. */ private final RegexValidator regexValidator; + + /** The minimum length of the code. */ private final int minLength; + + /** The maximum length of the code. */ private final int maxLength; + + /** The check digit validation routine. */ private final CheckDigit checkdigit; /** - * Construct a code validator with a specified regular - * expression and {@link CheckDigit}. - * The RegexValidator validator is created to be case-sensitive + * Constructs a code validator with a specified regular expression, + * validator and {@link CheckDigit} validation. * - * @param regex The format regular expression - * @param checkdigit The check digit validation routine + * @param regexValidator The format regular expression validator + * @param checkdigit The check digit validation routine. */ - public CodeValidator(String regex, CheckDigit checkdigit) { - this(regex, -1, -1, checkdigit); + public CodeValidator(final RegexValidator regexValidator, final CheckDigit checkdigit) { + this(regexValidator, -1, -1, checkdigit); } /** - * Construct a code validator with a specified regular - * expression, length and {@link CheckDigit}. - * The RegexValidator validator is created to be case-sensitive + * Constructs a code validator with a specified regular expression, + * validator, length and {@link CheckDigit} validation. * - * @param regex The format regular expression. + * @param regexValidator The format regular expression validator * @param length The length of the code - * (sets the mimimum/maximum to the same) + * (sets the mimimum/maximum to the same value) * @param checkdigit The check digit validation routine */ - public CodeValidator(String regex, int length, CheckDigit checkdigit) { - this(regex, length, length, checkdigit); + public CodeValidator(final RegexValidator regexValidator, final int length, final CheckDigit checkdigit) { + this(regexValidator, length, length, checkdigit); } /** - * Construct a code validator with a specified regular - * expression, minimum/maximum length and {@link CheckDigit} validation. - * The RegexValidator validator is created to be case-sensitive + * Constructs a code validator with a specified regular expression + * validator, minimum/maximum length and {@link CheckDigit} validation. * - * @param regex The regular expression + * @param regexValidator The format regular expression validator * @param minLength The minimum length of the code * @param maxLength The maximum length of the code * @param checkdigit The check digit validation routine */ - public CodeValidator(String regex, int minLength, int maxLength, - CheckDigit checkdigit) { - if (regex != null && regex.length() > 0) { - this.regexValidator = new RegexValidator(regex); - } else { - this.regexValidator = null; - } + public CodeValidator(final RegexValidator regexValidator, final int minLength, final int maxLength, + final CheckDigit checkdigit) { + this.regexValidator = regexValidator; this.minLength = minLength; this.maxLength = maxLength; this.checkdigit = checkdigit; } /** - * Construct a code validator with a specified regular expression, - * validator and {@link CheckDigit} validation. + * Constructs a code validator with a specified regular + * expression and {@link CheckDigit}. + * The RegexValidator validator is created to be case-sensitive * - * @param regexValidator The format regular expression validator - * @param checkdigit The check digit validation routine. + * @param regex The format regular expression + * @param checkdigit The check digit validation routine */ - public CodeValidator(RegexValidator regexValidator, CheckDigit checkdigit) { - this(regexValidator, -1, -1, checkdigit); + public CodeValidator(final String regex, final CheckDigit checkdigit) { + this(regex, -1, -1, checkdigit); } /** - * Construct a code validator with a specified regular expression, - * validator, length and {@link CheckDigit} validation. + * Constructs a code validator with a specified regular + * expression, length and {@link CheckDigit}. + * The RegexValidator validator is created to be case-sensitive * - * @param regexValidator The format regular expression validator + * @param regex The format regular expression. * @param length The length of the code - * (sets the mimimum/maximum to the same value) + * (sets the mimimum/maximum to the same) * @param checkdigit The check digit validation routine */ - public CodeValidator(RegexValidator regexValidator, int length, CheckDigit checkdigit) { - this(regexValidator, length, length, checkdigit); + public CodeValidator(final String regex, final int length, final CheckDigit checkdigit) { + this(regex, length, length, checkdigit); } /** - * Construct a code validator with a specified regular expression - * validator, minimum/maximum length and {@link CheckDigit} validation. + * Constructs a code validator with a specified regular + * expression, minimum/maximum length and {@link CheckDigit} validation. + * The RegexValidator validator is created to be case-sensitive * - * @param regexValidator The format regular expression validator + * @param regex The regular expression * @param minLength The minimum length of the code * @param maxLength The maximum length of the code * @param checkdigit The check digit validation routine */ - public CodeValidator(RegexValidator regexValidator, int minLength, int maxLength, - CheckDigit checkdigit) { - this.regexValidator = regexValidator; + public CodeValidator(final String regex, final int minLength, final int maxLength, + final CheckDigit checkdigit) { + if (regex != null && !regex.isEmpty()) { + this.regexValidator = new RegexValidator(regex); + } else { + this.regexValidator = null; + } this.minLength = minLength; this.maxLength = maxLength; this.checkdigit = checkdigit; @@ -178,29 +184,29 @@ } /** - * Return the minimum length of the code. + * Return the maximum length of the code. *

    * N.B. Optional, if less than zero the - * minimum length will not be checked. + * maximum length will not be checked. * - * @return The minimum length of the code or - * -1 if the code has no minimum length + * @return The maximum length of the code or + * -1 if the code has no maximum length */ - public int getMinLength() { - return minLength; + public int getMaxLength() { + return maxLength; } /** - * Return the maximum length of the code. + * Return the minimum length of the code. *

    * N.B. Optional, if less than zero the - * maximum length will not be checked. + * minimum length will not be checked. * - * @return The maximum length of the code or - * -1 if the code has no maximum length + * @return The minimum length of the code or + * -1 if the code has no minimum length */ - public int getMaxLength() { - return maxLength; + public int getMinLength() { + return minLength; } /** @@ -216,8 +222,8 @@ } /** - * Validate the code returning either true - * or false. + * Validate the code returning either {@code true} + * or {@code false}. *

    * This calls {@link #validate(String)} and returns false * if the return value is null, true otherwise. @@ -227,11 +233,11 @@ * change the input as part of the validation. * * @param input The code to validate - * @return true if valid, otherwise - * false + * @return {@code true} if valid, otherwise + * {@code false} */ - public boolean isValid(String input) { - return (validate(input) != null); + public boolean isValid(final String input) { + return validate(input) != null; } /** @@ -246,14 +252,14 @@ * @return The code if valid, otherwise null * if invalid */ - public Object validate(String input) { + public Object validate(final String input) { if (input == null) { return null; } String code = input.trim(); - if (code.length() == 0) { + if (code.isEmpty()) { return null; } @@ -266,8 +272,8 @@ } // check the length (must be done after validate as that can change the code) - if ((minLength >= 0 && code.length() < minLength) || - (maxLength >= 0 && code.length() > maxLength)) { + if (minLength >= 0 && code.length() < minLength || + maxLength >= 0 && code.length() > maxLength) { return null; } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java (.../CreditCardValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java (.../CreditCardValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,18 +16,19 @@ */ package org.apache.commons.validator.routines; -import org.apache.commons.validator.routines.checkdigit.CheckDigit; -import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.ArrayList; +import org.apache.commons.validator.routines.checkdigit.CheckDigit; +import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; + /** * Perform credit card validations. * *

    - * By default, all supported card types are allowed. You can specify which + * By default, AMEX + VISA + MASTERCARD + DISCOVER card types are allowed. You can specify which * cards should pass validation by configuring the validation options. For * example, *

    @@ -73,21 +74,14 @@ * This can be combined with a list of {@code CodeValidator}s *

    *

    - * More information can be found in Michael Gilleland's essay + * More information can be found in Michael Gilleland's essay * Anatomy of Credit Card Numbers. *

    * - * @version $Revision: 1782740 $ - * @since Validator 1.4 + * @since 1.4 */ public class CreditCardValidator implements Serializable { - private static final long serialVersionUID = 5955978921148959496L; - - private static final int MIN_CC_LENGTH = 12; // minimum allowed length - - private static final int MAX_CC_LENGTH = 19; // maximum allowed length - /** * Class that represents a credit card range. * @since 1.6 @@ -106,7 +100,8 @@ * The low and high parameters may be shorter than the length * of an IIN (currently 6 digits) in which case subsequent digits * are ignored and may range from 0-9. - *
    + *

    + *

    * The low and high parameters may be different lengths. * e.g. Discover "644" and "65". *

    @@ -115,7 +110,7 @@ * @param minLen the minimum length of the entire number * @param maxLen the maximum length of the entire number */ - public CreditCardRange(String low, String high, int minLen, int maxLen) { + public CreditCardRange(final String low, final String high, final int minLen, final int maxLen) { this.low = low; this.high = high; this.minLen = minLen; @@ -130,15 +125,16 @@ * The low and high parameters may be shorter than the length * of an IIN (currently 6 digits) in which case subsequent digits * are ignored and may range from 0-9. - *
    + *

    + *

    * The low and high parameters may be different lengths. * e.g. Discover "644" and "65". *

    - * @param low the low digits of the IIN range + * @param low the low digits of the IIN range * @param high the high digits of the IIN range * @param lengths array of valid lengths */ - public CreditCardRange(String low, String high, int [] lengths) { + public CreditCardRange(final String low, final String high, final int [] lengths) { this.low = low; this.high = high; this.minLen = -1; @@ -147,6 +143,12 @@ } } + private static final long serialVersionUID = 5955978921148959496L; + + private static final int MIN_CC_LENGTH = 12; // minimum allowed length + + private static final int MAX_CC_LENGTH = 19; // maximum allowed length + /** * Option specifying that no cards are allowed. This is useful if * you want only custom card types to validate so you turn off the @@ -200,69 +202,66 @@ @Deprecated public static final long MASTERCARD_PRE_OCT2016 = 1 << 6; // CHECKSTYLE IGNORE MagicNumber - /** - * The CreditCardTypes that are allowed to pass validation. - */ - private final List cardTypes = new ArrayList(); - - /** * Luhn checkdigit validator for the card numbers. */ private static final CheckDigit LUHN_VALIDATOR = LuhnCheckDigit.LUHN_CHECK_DIGIT; /** * American Express (Amex) Card Validator - *

    - * 34xxxx (15)
    - * 37xxxx (15)
    + *

      + *
    • 34xxxx (15)
    • + *
    • 37xxxx (15)
    • + *
    */ public static final CodeValidator AMEX_VALIDATOR = new CodeValidator("^(3[47]\\d{13})$", LUHN_VALIDATOR); /** * Diners Card Validator - *

    - * 300xxx - 305xxx (14)
    - * 3095xx (14)
    - * 36xxxx (14)
    - * 38xxxx (14)
    - * 39xxxx (14)
    + *

      + *
    • 300xxx - 305xxx (14)
    • + *
    • 3095xx (14)
    • + *
    • 36xxxx (14)
    • + *
    • 38xxxx (14)
    • + *
    • 39xxxx (14)
    • + *
    */ public static final CodeValidator DINERS_VALIDATOR = new CodeValidator("^(30[0-5]\\d{11}|3095\\d{10}|36\\d{12}|3[8-9]\\d{12})$", LUHN_VALIDATOR); /** * Discover Card regular expressions - *

    - * 6011xx (16)
    - * 644xxx - 65xxxx (16)
    + *

      + *
    • 6011xx (16)
    • + *
    • 644xxx - 65xxxx (16)
    • + *
    */ - private static final RegexValidator DISCOVER_REGEX = new RegexValidator(new String[] {"^(6011\\d{12})$", "^(64[4-9]\\d{13})$", "^(65\\d{14})$"}); + private static final RegexValidator DISCOVER_REGEX = new RegexValidator("^(6011\\d{12,13})$", "^(64[4-9]\\d{13})$", "^(65\\d{14})$", "^(62[2-8]\\d{13})$"); /** Discover Card Validator */ public static final CodeValidator DISCOVER_VALIDATOR = new CodeValidator(DISCOVER_REGEX, LUHN_VALIDATOR); /** * Mastercard regular expressions - *

    - * 2221xx - 2720xx (16)
    - * 51xxx - 55xxx (16)
    + *

      + *
    • 2221xx - 2720xx (16)
    • + *
    • 51xxx - 55xxx (16)
    • + *
    */ private static final RegexValidator MASTERCARD_REGEX = new RegexValidator( - new String[] { "^(5[1-5]\\d{14})$", // 51 - 55 (pre Oct 2016) // valid from October 2016 "^(2221\\d{12})$", // 222100 - 222199 "^(222[2-9]\\d{12})$",// 222200 - 222999 "^(22[3-9]\\d{13})$", // 223000 - 229999 "^(2[3-6]\\d{14})$", // 230000 - 269999 "^(27[01]\\d{13})$", // 270000 - 271999 - "^(2720\\d{12})$", // 272000 - 272099 - }); + "^(2720\\d{12})$" // 272000 - 272099 + ); /** Mastercard Card Validator */ public static final CodeValidator MASTERCARD_VALIDATOR = new CodeValidator(MASTERCARD_REGEX, LUHN_VALIDATOR); - /** + /** * Mastercard Card Validator (pre Oct 2016) * @deprecated for use until Oct 2016 only */ @@ -273,88 +272,138 @@ * Visa Card Validator *

    * 4xxxxx (13 or 16) + *

    */ public static final CodeValidator VISA_VALIDATOR = new CodeValidator("^(4)(\\d{12}|\\d{15})$", LUHN_VALIDATOR); - /** VPay (Visa) Card Validator + /** + * VPay (Visa) Card Validator *

    - * 4xxxxx (13-19) + * 4xxxxx (13-19) + *

    * @since 1.5.0 */ public static final CodeValidator VPAY_VALIDATOR = new CodeValidator("^(4)(\\d{12,18})$", LUHN_VALIDATOR); + // package protected for unit test access + static CodeValidator createRangeValidator(final CreditCardRange[] creditCardRanges, final CheckDigit digitCheck) { + return new CodeValidator( + // must be numeric (rest of validation is done later) + new RegexValidator("(\\d+)") { + private static final long serialVersionUID = 1L; + private final transient CreditCardRange[] ccr = creditCardRanges.clone(); + + @Override + public boolean isValid(final String value) { + return validate(value) != null; + } + + @Override + public String[] match(final String value) { + return new String[] { validate(value) }; + } + + @Override + // must return full string + public String validate(final String value) { + if (super.match(value) != null) { + final int length = value.length(); + for (final CreditCardRange range : ccr) { + if (validLength(length, range)) { + if (range.high == null) { // single prefix only + if (value.startsWith(range.low)) { + return value; + } + } else if (range.low.compareTo(value) <= 0 // no need to trim value here + && + // here we have to ignore digits beyond the prefix + range.high.compareTo(value.substring(0, range.high.length())) >= 0) { + return value; + } + } + } + } + return null; + } + }, digitCheck); + } + /** - * Create a new CreditCardValidator with default options. - * The default options are: - * AMEX, VISA, MASTERCARD and DISCOVER + * Creates a new generic CreditCardValidator which validates the syntax and check digit only. + * Does not check the Issuer Identification Number (IIN) + * + * @return the validator + * @since 1.6 */ - public CreditCardValidator() { - this(AMEX + VISA + MASTERCARD + DISCOVER); + public static CreditCardValidator genericCreditCardValidator() { + return genericCreditCardValidator(MIN_CC_LENGTH, MAX_CC_LENGTH); } /** - * Create a new CreditCardValidator with the specified options. - * @param options Pass in - * CreditCardValidator.VISA + CreditCardValidator.AMEX to specify that - * those are the only valid card types. + * Creates a new generic CreditCardValidator which validates the syntax and check digit only. + * Does not check the Issuer Identification Number (IIN) + * + * @param length exact length + * @return the validator + * @since 1.6 */ - public CreditCardValidator(long options) { - super(); + public static CreditCardValidator genericCreditCardValidator(final int length) { + return genericCreditCardValidator(length, length); + } - if (isOn(options, VISA)) { - this.cardTypes.add(VISA_VALIDATOR); - } + /** + * Creates a new generic CreditCardValidator which validates the syntax and check digit only. + * Does not check the Issuer Identification Number (IIN) + * + * @param minLen minimum allowed length + * @param maxLen maximum allowed length + * @return the validator + * @since 1.6 + */ + public static CreditCardValidator genericCreditCardValidator(final int minLen, final int maxLen) { + return new CreditCardValidator(new CodeValidator[] {new CodeValidator("(\\d+)", minLen, maxLen, LUHN_VALIDATOR)}); + } - if (isOn(options, VPAY)) { - this.cardTypes.add(VPAY_VALIDATOR); + // package protected for unit test access + static boolean validLength(final int valueLength, final CreditCardRange range) { + if (range.lengths != null) { + for (final int length : range.lengths) { + if (valueLength == length) { + return true; + } + } + return false; } + return valueLength >= range.minLen && valueLength <= range.maxLen; + } - if (isOn(options, AMEX)) { - this.cardTypes.add(AMEX_VALIDATOR); - } + /** + * The CreditCardTypes that are allowed to pass validation. + */ + private final List cardTypes = new ArrayList<>(); - if (isOn(options, MASTERCARD)) { - this.cardTypes.add(MASTERCARD_VALIDATOR); - } - - if (isOn(options, MASTERCARD_PRE_OCT2016)) { - this.cardTypes.add(MASTERCARD_VALIDATOR_PRE_OCT2016); - } - - if (isOn(options, DISCOVER)) { - this.cardTypes.add(DISCOVER_VALIDATOR); - } - - if (isOn(options, DINERS)) { - this.cardTypes.add(DINERS_VALIDATOR); - } + /** + * Constructs a new CreditCardValidator with default options. + * The default options are: + * AMEX, VISA, MASTERCARD and DISCOVER + */ + public CreditCardValidator() { + this(AMEX + VISA + MASTERCARD + DISCOVER); } /** - * Create a new CreditCardValidator with the specified {@link CodeValidator}s. + * Constructs a new CreditCardValidator with the specified {@link CodeValidator}s. * @param creditCardValidators Set of valid code validators */ - public CreditCardValidator(CodeValidator[] creditCardValidators) { + public CreditCardValidator(final CodeValidator[] creditCardValidators) { if (creditCardValidators == null) { throw new IllegalArgumentException("Card validators are missing"); } Collections.addAll(cardTypes, creditCardValidators); } /** - * Create a new CreditCardValidator with the specified {@link CreditCardRange}s. - * @param creditCardRanges Set of valid code validators - * @since 1.6 - */ - public CreditCardValidator(CreditCardRange[] creditCardRanges) { - if (creditCardRanges == null) { - throw new IllegalArgumentException("Card ranges are missing"); - } - Collections.addAll(cardTypes, createRangeValidator(creditCardRanges, LUHN_VALIDATOR)); - } - - /** - * Create a new CreditCardValidator with the specified {@link CodeValidator}s + * Constructs a new CreditCardValidator with the specified {@link CodeValidator}s * and {@link CreditCardRange}s. *

    * This can be used to combine predefined validators such as {@link #MASTERCARD_VALIDATOR} @@ -363,7 +412,7 @@ * @param creditCardRanges Set of valid code validators * @since 1.6 */ - public CreditCardValidator(CodeValidator[] creditCardValidators, CreditCardRange[] creditCardRanges) { + public CreditCardValidator(final CodeValidator[] creditCardValidators, final CreditCardRange[] creditCardRanges) { if (creditCardValidators == null) { throw new IllegalArgumentException("Card validators are missing"); } @@ -375,51 +424,76 @@ } /** - * Create a new generic CreditCardValidator which validates the syntax and check digit only. - * Does not check the Issuer Identification Number (IIN) - * - * @param minLen minimum allowed length - * @param maxLen maximum allowed length - * @return the validator + * Constructs a new CreditCardValidator with the specified {@link CreditCardRange}s. + * @param creditCardRanges Set of valid code validators * @since 1.6 */ - public static CreditCardValidator genericCreditCardValidator(int minLen, int maxLen) { - return new CreditCardValidator(new CodeValidator[] {new CodeValidator("(\\d+)", minLen, maxLen, LUHN_VALIDATOR)}); + public CreditCardValidator(final CreditCardRange[] creditCardRanges) { + if (creditCardRanges == null) { + throw new IllegalArgumentException("Card ranges are missing"); + } + Collections.addAll(cardTypes, createRangeValidator(creditCardRanges, LUHN_VALIDATOR)); } /** - * Create a new generic CreditCardValidator which validates the syntax and check digit only. - * Does not check the Issuer Identification Number (IIN) - * - * @param length exact length - * @return the validator - * @since 1.6 + * Constructs a new CreditCardValidator with the specified options. + * @param options Pass in + * CreditCardValidator.VISA + CreditCardValidator.AMEX to specify that + * those are the only valid card types. */ - public static CreditCardValidator genericCreditCardValidator(int length) { - return genericCreditCardValidator(length, length); + public CreditCardValidator(final long options) { + if (isOn(options, VISA)) { + this.cardTypes.add(VISA_VALIDATOR); + } + + if (isOn(options, VPAY)) { + this.cardTypes.add(VPAY_VALIDATOR); + } + + if (isOn(options, AMEX)) { + this.cardTypes.add(AMEX_VALIDATOR); + } + + if (isOn(options, MASTERCARD)) { + this.cardTypes.add(MASTERCARD_VALIDATOR); + } + + if (isOn(options, MASTERCARD_PRE_OCT2016)) { + this.cardTypes.add(MASTERCARD_VALIDATOR_PRE_OCT2016); + } + + if (isOn(options, DISCOVER)) { + this.cardTypes.add(DISCOVER_VALIDATOR); + } + + if (isOn(options, DINERS)) { + this.cardTypes.add(DINERS_VALIDATOR); + } } /** - * Create a new generic CreditCardValidator which validates the syntax and check digit only. - * Does not check the Issuer Identification Number (IIN) + * Tests whether the given flag is on. If the flag is not a power of 2 + * (ie. 3) this tests whether the combination of flags is on. * - * @return the validator - * @since 1.6 + * @param options The options specified. + * @param flag Flag value to check. + * + * @return whether the specified flag value is on. */ - public static CreditCardValidator genericCreditCardValidator() { - return genericCreditCardValidator(MIN_CC_LENGTH, MAX_CC_LENGTH); + private boolean isOn(final long options, final long flag) { + return (options & flag) > 0; } /** * Checks if the field is a valid credit card number. * @param card The card number to validate. * @return Whether the card number is valid. */ - public boolean isValid(String card) { - if (card == null || card.length() == 0) { + public boolean isValid(final String card) { + if (card == null || card.isEmpty()) { return false; } - for (CodeValidator cardType : cardTypes) { + for (final CodeValidator cardType : cardTypes) { if (cardType.isValid(card)) { return true; } @@ -433,12 +507,12 @@ * @return The card number if valid or null * if invalid. */ - public Object validate(String card) { - if (card == null || card.length() == 0) { + public Object validate(final String card) { + if (card == null || card.isEmpty()) { return null; } Object result = null; - for (CodeValidator cardType : cardTypes) { + for (final CodeValidator cardType : cardTypes) { result = cardType.validate(card); if (result != null) { return result; @@ -448,70 +522,4 @@ } - // package protected for unit test access - static boolean validLength(int valueLength, CreditCardRange range) { - if (range.lengths != null) { - for(int length : range.lengths) { - if (valueLength == length) { - return true; - } - } - return false; - } - return valueLength >= range.minLen && valueLength <= range.maxLen; - } - - // package protected for unit test access - static CodeValidator createRangeValidator(final CreditCardRange[] creditCardRanges, final CheckDigit digitCheck ) { - return new CodeValidator( - // must be numeric (rest of validation is done later) - new RegexValidator("(\\d+)") { - private static final long serialVersionUID = 1L; - private CreditCardRange[] ccr = creditCardRanges.clone(); - @Override - // must return full string - public String validate(String value) { - if (super.match(value) != null) { - int length = value.length(); - for(CreditCardRange range : ccr) { - if (validLength(length, range)) { - if (range.high == null) { // single prefix only - if (value.startsWith(range.low)) { - return value; - } - } else if (range.low.compareTo(value) <= 0 // no need to trim value here - && - // here we have to ignore digits beyond the prefix - range.high.compareTo(value.substring(0, range.high.length())) >= 0) { - return value; - } - } - } - } - return null; - } - @Override - public boolean isValid(String value) { - return validate(value) != null; - } - @Override - public String[] match(String value) { - return new String[]{validate(value)}; - } - }, digitCheck); - } - - /** - * Tests whether the given flag is on. If the flag is not a power of 2 - * (ie. 3) this tests whether the combination of flags is on. - * - * @param options The options specified. - * @param flag Flag value to check. - * - * @return whether the specified flag value is on. - */ - private boolean isOn(long options, long flag) { - return (options & flag) > 0; - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CurrencyValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CurrencyValidator.java (.../CurrencyValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CurrencyValidator.java (.../CurrencyValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -24,7 +24,7 @@ * *

    This is one implementation of a currency validator that has the following features:

    *
      - *
    • It is lenient about the the presence of the currency symbol
    • + *
    • It is lenient about the presence of the currency symbol
    • *
    • It converts the currency to a java.math.BigDecimal
    • *
    * @@ -37,10 +37,9 @@ * *

    Pick the appropriate validator, depending on the type (e.g Float, Double, Integer, Long etc) * you want the currency converted to. One thing to note - only the CurrencyValidator - * implements lenient behaviour regarding the currency symbol.

    + * implements lenient behavior regarding the currency symbol.

    * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class CurrencyValidator extends BigDecimalValidator { @@ -60,21 +59,21 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public CurrencyValidator() { this(true, true); } /** - * Construct an instance with the specified strict setting. + * Constructs an instance with the specified strict setting. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. - * @param allowFractions true if fractions are - * allowed or false if integers only. + * @param allowFractions {@code true} if fractions are + * allowed or {@code false} if integers only. */ - public CurrencyValidator(boolean strict, boolean allowFractions) { + public CurrencyValidator(final boolean strict, final boolean allowFractions) { super(strict, CURRENCY_FORMAT, allowFractions); } @@ -83,7 +82,7 @@ * *

    This implementation is lenient whether the currency symbol * is present or not. The default NumberFormat - * behaviour is for the parsing to "fail" if the currency + * behavior is for the parsing to "fail" if the currency * symbol is missing. This method re-parses with a format * without the currency symbol if it fails initially.

    * @@ -92,7 +91,7 @@ * @return The parsed value if valid or null if invalid. */ @Override - protected Object parse(String value, Format formatter) { + protected Object parse(final String value, final Format formatter) { // Initial parse of the value Object parsedValue = super.parse(value, formatter); @@ -101,10 +100,10 @@ } // Re-parse using a pattern without the currency symbol - DecimalFormat decimalFormat = (DecimalFormat)formatter; - String pattern = decimalFormat.toPattern(); + final DecimalFormat decimalFormat = (DecimalFormat)formatter; + final String pattern = decimalFormat.toPattern(); if (pattern.indexOf(CURRENCY_SYMBOL) >= 0) { - StringBuilder buffer = new StringBuilder(pattern.length()); + final StringBuilder buffer = new StringBuilder(pattern.length()); for (int i = 0; i < pattern.length(); i++) { if (pattern.charAt(i) != CURRENCY_SYMBOL) { buffer.append(pattern.charAt(i)); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java (.../DateValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java (.../DateValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -79,8 +79,7 @@ *
  • using the format for the default Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class DateValidator extends AbstractCalendarValidator { @@ -97,131 +96,26 @@ } /** - * Construct a strict instance with short + * Constructs a strict instance with short * date style. */ public DateValidator() { this(true, DateFormat.SHORT); } /** - * Construct an instance with the specified strict + * Constructs an instance with the specified strict * and date style parameters. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param dateStyle the date style to use for Locale validation. */ - public DateValidator(boolean strict, int dateStyle) { + public DateValidator(final boolean strict, final int dateStyle) { super(strict, dateStyle, -1); } /** - *

    Validate/convert a Date using the default - * Locale and TimeZone. - * - * @param value The value validation is being performed on. - * @return The parsed Date if valid or null - * if invalid. - */ - public Date validate(String value) { - return (Date)parse(value, (String)null, (Locale)null, (TimeZone)null); - } - - /** - *

    Validate/convert a Date using the specified - * TimeZone and default Locale. - * - * @param value The value validation is being performed on. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, TimeZone timeZone) { - return (Date)parse(value, (String)null, (Locale)null, timeZone); - } - - /** - *

    Validate/convert a Date using the specified - * pattern and default TimeZone. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, String pattern) { - return (Date)parse(value, pattern, (Locale)null, (TimeZone)null); - } - - /** - *

    Validate/convert a Date using the specified - * pattern and TimeZone. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, String pattern, TimeZone timeZone) { - return (Date)parse(value, pattern, (Locale)null, timeZone); - } - - /** - *

    Validate/convert a Date using the specified - * Locale and default TimeZone. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, Locale locale) { - return (Date)parse(value, (String)null, locale, (TimeZone)null); - } - - /** - *

    Validate/convert a Date using the specified - * Locale and TimeZone. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the date format, system default if null. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, Locale locale, TimeZone timeZone) { - return (Date)parse(value, (String)null, locale, timeZone); - } - - /** - *

    Validate/convert a Date using the specified pattern - * and Locale and the default TimeZone. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, String pattern, Locale locale) { - return (Date)parse(value, pattern, locale, (TimeZone)null); - } - - /** - *

    Validate/convert a Date using the specified - * pattern, and Locale and TimeZone. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @param timeZone The Time Zone used to parse the date, system default if null. - * @return The parsed Date if valid or null if invalid. - */ - public Date validate(String value, String pattern, Locale locale, TimeZone timeZone) { - return (Date)parse(value, pattern, locale, timeZone); - } - - /** *

    Compare Dates (day, month and year - not time).

    * * @param value The Calendar value to check. @@ -231,29 +125,13 @@ * date is less than the seconds and +1 if the first * date is greater than. */ - public int compareDates(Date value, Date compare, TimeZone timeZone) { - Calendar calendarValue = getCalendar(value, timeZone); - Calendar calendarCompare = getCalendar(compare, timeZone); + public int compareDates(final Date value, final Date compare, final TimeZone timeZone) { + final Calendar calendarValue = getCalendar(value, timeZone); + final Calendar calendarCompare = getCalendar(compare, timeZone); return compare(calendarValue, calendarCompare, Calendar.DATE); } /** - *

    Compare Weeks (week and year).

    - * - * @param value The Date value to check. - * @param compare The Date to compare the value to. - * @param timeZone The Time Zone used to compare the dates, system default if null. - * @return Zero if the weeks are equal, -1 if first - * parameter's week is less than the seconds and +1 if the first - * parameter's week is greater than. - */ - public int compareWeeks(Date value, Date compare, TimeZone timeZone) { - Calendar calendarValue = getCalendar(value, timeZone); - Calendar calendarCompare = getCalendar(compare, timeZone); - return compare(calendarValue, calendarCompare, Calendar.WEEK_OF_YEAR); - } - - /** *

    Compare Months (month and year).

    * * @param value The Date value to check. @@ -263,9 +141,9 @@ * parameter's month is less than the seconds and +1 if the first * parameter's month is greater than. */ - public int compareMonths(Date value, Date compare, TimeZone timeZone) { - Calendar calendarValue = getCalendar(value, timeZone); - Calendar calendarCompare = getCalendar(compare, timeZone); + public int compareMonths(final Date value, final Date compare, final TimeZone timeZone) { + final Calendar calendarValue = getCalendar(value, timeZone); + final Calendar calendarCompare = getCalendar(compare, timeZone); return compare(calendarValue, calendarCompare, Calendar.MONTH); } @@ -279,7 +157,7 @@ * parameter's quarter is less than the seconds and +1 if the first * parameter's quarter is greater than. */ - public int compareQuarters(Date value, Date compare, TimeZone timeZone) { + public int compareQuarters(final Date value, final Date compare, final TimeZone timeZone) { return compareQuarters(value, compare, timeZone, 1); } @@ -294,13 +172,29 @@ * parameter's quarter is less than the seconds and +1 if the first * parameter's quarter is greater than. */ - public int compareQuarters(Date value, Date compare, TimeZone timeZone, int monthOfFirstQuarter) { - Calendar calendarValue = getCalendar(value, timeZone); - Calendar calendarCompare = getCalendar(compare, timeZone); + public int compareQuarters(final Date value, final Date compare, final TimeZone timeZone, final int monthOfFirstQuarter) { + final Calendar calendarValue = getCalendar(value, timeZone); + final Calendar calendarCompare = getCalendar(compare, timeZone); return super.compareQuarters(calendarValue, calendarCompare, monthOfFirstQuarter); } /** + *

    Compare Weeks (week and year).

    + * + * @param value The Date value to check. + * @param compare The Date to compare the value to. + * @param timeZone The Time Zone used to compare the dates, system default if null. + * @return Zero if the weeks are equal, -1 if first + * parameter's week is less than the seconds and +1 if the first + * parameter's week is greater than. + */ + public int compareWeeks(final Date value, final Date compare, final TimeZone timeZone) { + final Calendar calendarValue = getCalendar(value, timeZone); + final Calendar calendarCompare = getCalendar(compare, timeZone); + return compare(calendarValue, calendarCompare, Calendar.WEEK_OF_YEAR); + } + + /** *

    Compare Years.

    * * @param value The Date value to check. @@ -310,41 +204,146 @@ * parameter's year is less than the seconds and +1 if the first * parameter's year is greater than. */ - public int compareYears(Date value, Date compare, TimeZone timeZone) { - Calendar calendarValue = getCalendar(value, timeZone); - Calendar calendarCompare = getCalendar(compare, timeZone); + public int compareYears(final Date value, final Date compare, final TimeZone timeZone) { + final Calendar calendarValue = getCalendar(value, timeZone); + final Calendar calendarCompare = getCalendar(compare, timeZone); return compare(calendarValue, calendarCompare, Calendar.YEAR); } /** + *

    Convert a Date to a Calendar.

    + * + * @param value The date value to be converted. + * @return The converted Calendar. + */ + private Calendar getCalendar(final Date value, final TimeZone timeZone) { + + Calendar calendar; + if (timeZone != null) { + calendar = Calendar.getInstance(timeZone); + } else { + calendar = Calendar.getInstance(); + } + calendar.setTime(value); + return calendar; + + } + + /** *

    Returns the parsed Date unchanged.

    * * @param value The parsed Date object created. * @param formatter The Format used to parse the value with. * @return The parsed value converted to a Calendar. */ @Override - protected Object processParsedValue(Object value, Format formatter) { + protected Object processParsedValue(final Object value, final Format formatter) { return value; } /** - *

    Convert a Date to a Calendar.

    + *

    Validate/convert a Date using the default + * Locale and TimeZone. * - * @param value The date value to be converted. - * @return The converted Calendar. + * @param value The value validation is being performed on. + * @return The parsed Date if valid or null + * if invalid. */ - private Calendar getCalendar(Date value, TimeZone timeZone) { + public Date validate(final String value) { + return (Date)parse(value, (String)null, (Locale)null, (TimeZone)null); + } - Calendar calendar = null; - if (timeZone != null) { - calendar = Calendar.getInstance(timeZone); - } else { - calendar = Calendar.getInstance(); - } - calendar.setTime(value); - return calendar; + /** + *

    Validate/convert a Date using the specified + * Locale and default TimeZone. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final Locale locale) { + return (Date)parse(value, (String)null, locale, (TimeZone)null); + } + /** + *

    Validate/convert a Date using the specified + * Locale and TimeZone. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the date format, system default if null. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final Locale locale, final TimeZone timeZone) { + return (Date)parse(value, (String)null, locale, timeZone); } + /** + *

    Validate/convert a Date using the specified + * pattern and default TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final String pattern) { + return (Date)parse(value, pattern, (Locale)null, (TimeZone)null); + } + + /** + *

    Validate/convert a Date using the specified pattern + * and Locale and the default TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final String pattern, final Locale locale) { + return (Date)parse(value, pattern, locale, (TimeZone)null); + } + + /** + *

    Validate/convert a Date using the specified + * pattern, and Locale and TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final String pattern, final Locale locale, final TimeZone timeZone) { + return (Date)parse(value, pattern, locale, timeZone); + } + + /** + *

    Validate/convert a Date using the specified + * pattern and TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final String pattern, final TimeZone timeZone) { + return (Date)parse(value, pattern, (Locale)null, timeZone); + } + + /** + *

    Validate/convert a Date using the specified + * TimeZone and default Locale. + * + * @param value The value validation is being performed on. + * @param timeZone The Time Zone used to parse the date, system default if null. + * @return The parsed Date if valid or null if invalid. + */ + public Date validate(final String value, final TimeZone timeZone) { + return (Date)parse(value, (String)null, (Locale)null, timeZone); + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java (.../DomainValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java (.../DomainValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -19,6 +19,7 @@ import java.io.Serializable; import java.net.IDN; import java.util.Arrays; +import java.util.List; import java.util.Locale; /** @@ -58,232 +59,128 @@ * {@link java.net.InetAddress} for that functionality.) *

    * - * @version $Revision: 1781829 $ - * @since Validator 1.4 + * @since 1.4 */ public class DomainValidator implements Serializable { - private static final int MAX_DOMAIN_LENGTH = 253; - - private static final String[] EMPTY_STRING_ARRAY = new String[0]; - - private static final long serialVersionUID = -4407125112880174009L; - - // Regular expression strings for hostnames (derived from RFC2396 and RFC 1123) - - // RFC2396: domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum - // Max 63 characters - private static final String DOMAIN_LABEL_REGEX = "\\p{Alnum}(?>[\\p{Alnum}-]{0,61}\\p{Alnum})?"; - - // RFC2396 toplabel = alpha | alpha *( alphanum | "-" ) alphanum - // Max 63 characters - private static final String TOP_LABEL_REGEX = "\\p{Alpha}(?>[\\p{Alnum}-]{0,61}\\p{Alnum})?"; - - // RFC2396 hostname = *( domainlabel "." ) toplabel [ "." ] - // Note that the regex currently requires both a domain label and a top level label, whereas - // the RFC does not. This is because the regex is used to detect if a TLD is present. - // If the match fails, input is checked against DOMAIN_LABEL_REGEX (hostnameRegex) - // RFC1123 sec 2.1 allows hostnames to start with a digit - private static final String DOMAIN_NAME_REGEX = - "^(?:" + DOMAIN_LABEL_REGEX + "\\.)+" + "(" + TOP_LABEL_REGEX + ")\\.?$"; - - private final boolean allowLocal; - /** - * Singleton instance of this validator, which - * doesn't consider local addresses as valid. + * enum used by {@link DomainValidator#updateTLDOverride(ArrayType, String[])} + * to determine which override array to update / fetch + * @since 1.5.0 + * @since 1.5.1 made public and added read-only array references */ - private static final DomainValidator DOMAIN_VALIDATOR = new DomainValidator(false); - - /** - * Singleton instance of this validator, which does - * consider local addresses valid. - */ - private static final DomainValidator DOMAIN_VALIDATOR_WITH_LOCAL = new DomainValidator(true); - - /** - * RegexValidator for matching domains. - */ - private final RegexValidator domainRegex = - new RegexValidator(DOMAIN_NAME_REGEX); - /** - * RegexValidator for matching a local hostname - */ - // RFC1123 sec 2.1 allows hostnames to start with a digit - private final RegexValidator hostnameRegex = - new RegexValidator(DOMAIN_LABEL_REGEX); - - /** - * Returns the singleton instance of this validator. It - * will not consider local addresses as valid. - * @return the singleton instance of this validator - */ - public static synchronized DomainValidator getInstance() { - inUse = true; - return DOMAIN_VALIDATOR; + public enum ArrayType { + /** Update (or get a copy of) the GENERIC_TLDS_PLUS table containing additonal generic TLDs */ + GENERIC_PLUS, + /** Update (or get a copy of) the GENERIC_TLDS_MINUS table containing deleted generic TLDs */ + GENERIC_MINUS, + /** Update (or get a copy of) the COUNTRY_CODE_TLDS_PLUS table containing additonal country code TLDs */ + COUNTRY_CODE_PLUS, + /** Update (or get a copy of) the COUNTRY_CODE_TLDS_MINUS table containing deleted country code TLDs */ + COUNTRY_CODE_MINUS, + /** Gets a copy of the generic TLDS table */ + GENERIC_RO, + /** Gets a copy of the country code table */ + COUNTRY_CODE_RO, + /** Gets a copy of the infrastructure table */ + INFRASTRUCTURE_RO, + /** Gets a copy of the local table */ + LOCAL_RO, + /** + * Update (or get a copy of) the LOCAL_TLDS_PLUS table containing additional local TLDs + * @since 1.7 + */ + LOCAL_PLUS, + /** + * Update (or get a copy of) the LOCAL_TLDS_MINUS table containing deleted local TLDs + * @since 1.7 + */ + LOCAL_MINUS + ; } - /** - * Returns the singleton instance of this validator, - * with local validation as required. - * @param allowLocal Should local addresses be considered valid? - * @return the singleton instance of this validator - */ - public static synchronized DomainValidator getInstance(boolean allowLocal) { - inUse = true; - if(allowLocal) { - return DOMAIN_VALIDATOR_WITH_LOCAL; + private static class IDNBUGHOLDER { + private static final boolean IDN_TOASCII_PRESERVES_TRAILING_DOTS = keepsTrailingDot(); + private static boolean keepsTrailingDot() { + final String input = "a."; // must be a valid name + return input.equals(IDN.toASCII(input)); } - return DOMAIN_VALIDATOR; } - /** Private constructor. */ - private DomainValidator(boolean allowLocal) { - this.allowLocal = allowLocal; - } - /** - * Returns true if the specified String parses - * as a valid domain name with a recognized top-level domain. - * The parsing is case-insensitive. - * @param domain the parameter to check for domain name syntax - * @return true if the parameter is a valid domain name + * Used to specify overrides when creating a new class. + * @since 1.7 */ - public boolean isValid(String domain) { - if (domain == null) { - return false; - } - domain = unicodeToASCII(domain); - // hosts must be equally reachable via punycode and Unicode; - // Unicode is never shorter than punycode, so check punycode - // if domain did not convert, then it will be caught by ASCII - // checks in the regexes below - if (domain.length() > MAX_DOMAIN_LENGTH) { - return false; - } - String[] groups = domainRegex.match(domain); - if (groups != null && groups.length > 0) { - return isValidTld(groups[0]); - } - return allowLocal && hostnameRegex.isValid(domain); - } + public static class Item { + final ArrayType type; + final String[] values; - // package protected for unit test access - // must agree with isValid() above - final boolean isValidDomainSyntax(String domain) { - if (domain == null) { - return false; + /** + * Constructs a new instance. + * @param type ArrayType, e.g. GENERIC_PLUS, LOCAL_PLUS + * @param values array of TLDs. Will be lower-cased and sorted + */ + public Item(final ArrayType type, final String... values) { + this.type = type; + this.values = values; // no need to copy here } - domain = unicodeToASCII(domain); - // hosts must be equally reachable via punycode and Unicode; - // Unicode is never shorter than punycode, so check punycode - // if domain did not convert, then it will be caught by ASCII - // checks in the regexes below - if (domain.length() > MAX_DOMAIN_LENGTH) { - return false; - } - String[] groups = domainRegex.match(domain); - return (groups != null && groups.length > 0) - || hostnameRegex.isValid(domain); } - /** - * Returns true if the specified String matches any - * IANA-defined top-level domain. Leading dots are ignored if present. - * The search is case-insensitive. - * @param tld the parameter to check for TLD status, not null - * @return true if the parameter is a TLD - */ - public boolean isValidTld(String tld) { - tld = unicodeToASCII(tld); - if(allowLocal && isValidLocalTld(tld)) { - return true; - } - return isValidInfrastructureTld(tld) - || isValidGenericTld(tld) - || isValidCountryCodeTld(tld); - } + // Regular expression strings for hostnames (derived from RFC2396 and RFC 1123) - /** - * Returns true if the specified String matches any - * IANA-defined infrastructure top-level domain. Leading dots are - * ignored if present. The search is case-insensitive. - * @param iTld the parameter to check for infrastructure TLD status, not null - * @return true if the parameter is an infrastructure TLD - */ - public boolean isValidInfrastructureTld(String iTld) { - final String key = chompLeadingDot(unicodeToASCII(iTld).toLowerCase(Locale.ENGLISH)); - return arrayContains(INFRASTRUCTURE_TLDS, key); - } + private static class LazyHolder { // IODH - /** - * Returns true if the specified String matches any - * IANA-defined generic top-level domain. Leading dots are ignored - * if present. The search is case-insensitive. - * @param gTld the parameter to check for generic TLD status, not null - * @return true if the parameter is a generic TLD - */ - public boolean isValidGenericTld(String gTld) { - final String key = chompLeadingDot(unicodeToASCII(gTld).toLowerCase(Locale.ENGLISH)); - return (arrayContains(GENERIC_TLDS, key) || arrayContains(genericTLDsPlus, key)) - && !arrayContains(genericTLDsMinus, key); - } + /** + * Singleton instance of this validator, which + * doesn't consider local addresses as valid. + */ + private static final DomainValidator DOMAIN_VALIDATOR = new DomainValidator(false); - /** - * Returns true if the specified String matches any - * IANA-defined country code top-level domain. Leading dots are - * ignored if present. The search is case-insensitive. - * @param ccTld the parameter to check for country code TLD status, not null - * @return true if the parameter is a country code TLD - */ - public boolean isValidCountryCodeTld(String ccTld) { - final String key = chompLeadingDot(unicodeToASCII(ccTld).toLowerCase(Locale.ENGLISH)); - return (arrayContains(COUNTRY_CODE_TLDS, key) || arrayContains(countryCodeTLDsPlus, key)) - && !arrayContains(countryCodeTLDsMinus, key); - } + /** + * Singleton instance of this validator, which does + * consider local addresses valid. + */ + private static final DomainValidator DOMAIN_VALIDATOR_WITH_LOCAL = new DomainValidator(true); - /** - * Returns true if the specified String matches any - * widely used "local" domains (localhost or localdomain). Leading dots are - * ignored if present. The search is case-insensitive. - * @param lTld the parameter to check for local TLD status, not null - * @return true if the parameter is an local TLD - */ - public boolean isValidLocalTld(String lTld) { - final String key = chompLeadingDot(unicodeToASCII(lTld).toLowerCase(Locale.ENGLISH)); - return arrayContains(LOCAL_TLDS, key); } - private String chompLeadingDot(String str) { - if (str.startsWith(".")) { - return str.substring(1); - } - return str; - } + /** Maximum allowable length ({@value}) of a domain name */ + private static final int MAX_DOMAIN_LENGTH = 253; - // --------------------------------------------- - // ----- TLDs defined by IANA - // ----- Authoritative and comprehensive list at: - // ----- http://data.iana.org/TLD/tlds-alpha-by-domain.txt + private static final String[] EMPTY_STRING_ARRAY = {}; - // Note that the above list is in UPPER case. - // The code currently converts strings to lower case (as per the tables below) + private static final long serialVersionUID = -4407125112880174009L; - // IANA also provide an HTML list at http://www.iana.org/domains/root/db - // Note that this contains several country code entries which are NOT in - // the text file. These all have the "Not assigned" in the "Sponsoring Organisation" column - // For example (as of 2015-01-02): - // .bl country-code Not assigned - // .um country-code Not assigned + // RFC2396: domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + // Max 63 characters + private static final String DOMAIN_LABEL_REGEX = "\\p{Alnum}(?>[\\p{Alnum}-]{0,61}\\p{Alnum})?"; + // RFC2396 toplabel = alpha | alpha *( alphanum | "-" ) alphanum + // Max 63 characters + private static final String TOP_LABEL_REGEX = "\\p{Alpha}(?>[\\p{Alnum}-]{0,61}\\p{Alnum})?"; + + /** + * The above instances must only be returned via the getInstance() methods. + * This is to ensure that the override data arrays are properly protected. + */ + + // RFC2396 hostname = *( domainlabel "." ) toplabel [ "." ] + // Note that the regex currently requires both a domain label and a top level label, whereas + // the RFC does not. This is because the regex is used to detect if a TLD is present. + // If the match fails, input is checked against DOMAIN_LABEL_REGEX (hostnameRegex) + // RFC1123 sec 2.1 allows hostnames to start with a digit + private static final String DOMAIN_NAME_REGEX = + "^(?:" + DOMAIN_LABEL_REGEX + "\\.)+" + "(" + TOP_LABEL_REGEX + ")\\.?$"; + private static final String UNEXPECTED_ENUM_VALUE = "Unexpected enum value: "; + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static final String[] INFRASTRUCTURE_TLDS = new String[] { + private static final String[] INFRASTRUCTURE_TLDS = { "arpa", // internet infrastructure }; // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static final String[] GENERIC_TLDS = new String[] { - // Taken from Version 2017020400, Last Updated Sat Feb 4 07:07:01 2017 UTC + private static final String[] GENERIC_TLDS = { + // Taken from Version 2023011200, Last Updated Thu Jan 12 07:07:01 2023 UTC "aaa", // aaa American Automobile Association, Inc. "aarp", // aarp AARP "abarth", // abarth Fiat Chrysler Automobiles N.V. @@ -299,20 +196,21 @@ "accountant", // accountant dot Accountant Limited "accountants", // accountants Knob Town, LLC "aco", // aco ACO Severin Ahlmann GmbH & Co. KG - "active", // active The Active Network, Inc +// "active", // active The Active Network, Inc "actor", // actor United TLD Holdco Ltd. - "adac", // adac Allgemeiner Deutscher Automobil-Club e.V. (ADAC) +// "adac", // adac Allgemeiner Deutscher Automobil-Club e.V. (ADAC) "ads", // ads Charleston Road Registry Inc. "adult", // adult ICM Registry AD LLC "aeg", // aeg Aktiebolaget Electrolux "aero", // aero Societe Internationale de Telecommunications Aeronautique (SITA INC USA) "aetna", // aetna Aetna Life Insurance Company - "afamilycompany", // afamilycompany Johnson Shareholdings, Inc. +// "afamilycompany", // afamilycompany Johnson Shareholdings, Inc. "afl", // afl Australian Football League + "africa", // africa ZA Central Registry NPC trading as Registry.Africa "agakhan", // agakhan Fondation Aga Khan (Aga Khan Foundation) "agency", // agency Steel Falls, LLC "aig", // aig American International Group, Inc. - "aigo", // aigo aigo Digital Technology Co,Ltd. +// "aigo", // aigo aigo Digital Technology Co,Ltd. [Not assigned as of Jul 25] "airbus", // airbus Airbus S.A.S. "airforce", // airforce United TLD Holdco Ltd. "airtel", // airtel Bharti Airtel Limited @@ -325,6 +223,7 @@ "ally", // ally Ally Financial Inc. "alsace", // alsace REGION D ALSACE "alstom", // alstom ALSTOM + "amazon", // amazon Amazon Registry Services, Inc. "americanexpress", // americanexpress American Express Travel Related Services Company, Inc. "americanfamily", // americanfamily AmFam, Inc. "amex", // amex American Express Travel Related Services Company, Inc. @@ -340,6 +239,7 @@ "app", // app Charleston Road Registry Inc. "apple", // apple Apple Inc. "aquarelle", // aquarelle Aquarelle.com + "arab", // arab League of Arab States "aramco", // aramco Aramco Services Company "archi", // archi STARTING DOT LIMITED "army", // army United TLD Holdco Ltd. @@ -401,14 +301,14 @@ "biz", // biz Neustar, Inc. "black", // black Afilias Limited "blackfriday", // blackfriday Uniregistry, Corp. - "blanco", // blanco BLANCO GmbH + Co KG +// "blanco", // blanco BLANCO GmbH + Co KG "blockbuster", // blockbuster Dish DBS Corporation "blog", // blog Knock Knock WHOIS There, LLC "bloomberg", // bloomberg Bloomberg IP Holdings LLC "blue", // blue Afilias Limited "bms", // bms Bristol-Myers Squibb Company "bmw", // bmw Bayerische Motoren Werke Aktiengesellschaft - "bnl", // bnl Banca Nazionale del Lavoro +// "bnl", // bnl Banca Nazionale del Lavoro "bnpparibas", // bnpparibas BNP Paribas "boats", // boats DERBoats, LLC "boehringer", // boehringer Boehringer Ingelheim International GmbH @@ -418,7 +318,7 @@ "boo", // boo Charleston Road Registry Inc. "book", // book Amazon Registry Services, Inc. "booking", // booking Booking.com B.V. - "boots", // boots THE BOOTS COMPANY PLC +// "boots", // boots THE BOOTS COMPANY PLC "bosch", // bosch Robert Bosch GMBH "bostik", // bostik Bostik SA "boston", // boston Boston TLD Management, LLC @@ -431,8 +331,8 @@ "broker", // broker DOTBROKER REGISTRY LTD "brother", // brother Brother Industries, Ltd. "brussels", // brussels DNS.be vzw - "budapest", // budapest Top Level Domain Holdings Limited - "bugatti", // bugatti Bugatti International SA +// "budapest", // budapest Top Level Domain Holdings Limited +// "bugatti", // bugatti Bugatti International SA "build", // build Plan Bee LLC "builders", // builders Atomic Madison, LLC "business", // business Spring Cross, LLC @@ -447,7 +347,7 @@ "cam", // cam AC Webconnecting Holding B.V. "camera", // camera Atomic Maple, LLC "camp", // camp Delta Dynamite, LLC - "cancerresearch", // cancerresearch Australian Cancer Research Foundation +// "cancerresearch", // cancerresearch Australian Cancer Research Foundation "canon", // canon Canon Inc. "capetown", // capetown ZA Central Registry NPC trading as ZA Central Registry "capital", // capital Delta Mill, LLC @@ -459,10 +359,10 @@ "career", // career dotCareer LLC "careers", // careers Wild Corner, LLC "cars", // cars Uniregistry, Corp. - "cartier", // cartier Richemont DNS Inc. +// "cartier", // cartier Richemont DNS Inc. "casa", // casa Top Level Domain Holdings Limited "case", // case CNH Industrial N.V. - "caseih", // caseih CNH Industrial N.V. +// "caseih", // caseih CNH Industrial N.V. "cash", // cash Delta Lake, LLC "casino", // casino Binky Sky, LLC "cat", // cat Fundacio puntCAT @@ -472,22 +372,23 @@ "cbn", // cbn The Christian Broadcasting Network, Inc. "cbre", // cbre CBRE, Inc. "cbs", // cbs CBS Domains Inc. - "ceb", // ceb The Corporate Executive Board Company +// "ceb", // ceb The Corporate Executive Board Company "center", // center Tin Mill, LLC "ceo", // ceo CEOTLD Pty Ltd "cern", // cern European Organization for Nuclear Research ("CERN") "cfa", // cfa CFA Institute "cfd", // cfd DOTCFD REGISTRY LTD "chanel", // chanel Chanel International B.V. "channel", // channel Charleston Road Registry Inc. + "charity", // charity Corn Lake, LLC "chase", // chase JPMorgan Chase & Co. "chat", // chat Sand Fields, LLC "cheap", // cheap Sand Cover, LLC "chintai", // chintai CHINTAI Corporation - "chloe", // chloe Richemont DNS Inc. +// "chloe", // chloe Richemont DNS Inc. (Not assigned) "christmas", // christmas Uniregistry, Corp. "chrome", // chrome Charleston Road Registry Inc. - "chrysler", // chrysler FCA US LLC. +// "chrysler", // chrysler FCA US LLC. "church", // church Holly Fileds, LLC "cipriani", // cipriani Hotel Cipriani Srl "circle", // circle Amazon Registry Services, Inc. @@ -533,6 +434,7 @@ "coupon", // coupon Amazon Registry Services, Inc. "coupons", // coupons Black Island, LLC "courses", // courses OPEN UNIVERSITIES AUSTRALIA PTY LTD + "cpa", // cpa American Institute of Certified Public Accountants "credit", // credit Snow Shadow, LLC "creditcard", // creditcard Binky Frostbite, LLC "creditunion", // creditunion CUNA Performance Resources, LLC @@ -541,7 +443,7 @@ "crs", // crs Federated Co-operatives Limited "cruise", // cruise Viking River Cruises (Bermuda) Ltd. "cruises", // cruises Spring Way, LLC - "csc", // csc Alliance-One Services, Inc. +// "csc", // csc Alliance-One Services, Inc. "cuisinella", // cuisinella SALM S.A.S. "cymru", // cymru Nominet UK "cyou", // cyou Beijing Gamease Age Digital Technology Co., Ltd. @@ -582,19 +484,19 @@ "dnp", // dnp Dai Nippon Printing Co., Ltd. "docs", // docs Charleston Road Registry Inc. "doctor", // doctor Brice Trail, LLC - "dodge", // dodge FCA US LLC. +// "dodge", // dodge FCA US LLC. "dog", // dog Koko Mill, LLC - "doha", // doha Communications Regulatory Authority (CRA) +// "doha", // doha Communications Regulatory Authority (CRA) "domains", // domains Sugar Cross, LLC // "doosan", // doosan Doosan Corporation (retired) "dot", // dot Dish DBS Corporation "download", // download dot Support Limited "drive", // drive Charleston Road Registry Inc. "dtv", // dtv Dish DBS Corporation "dubai", // dubai Dubai Smart Government Department - "duck", // duck Johnson Shareholdings, Inc. +// "duck", // duck Johnson Shareholdings, Inc. "dunlop", // dunlop The Goodyear Tire & Rubber Company - "duns", // duns The Dun & Bradstreet Corporation +// "duns", // duns The Dun & Bradstreet Corporation "dupont", // dupont E. I. du Pont de Nemours and Company "durban", // durban ZA Central Registry NPC trading as ZA Central Registry "dvag", // dvag Deutsche Vermögensberatung Aktiengesellschaft DVAG @@ -611,18 +513,19 @@ "engineer", // engineer United TLD Holdco Ltd. "engineering", // engineering Romeo Canyon "enterprises", // enterprises Snow Oaks, LLC - "epost", // epost Deutsche Post AG +// "epost", // epost Deutsche Post AG "epson", // epson Seiko Epson Corporation "equipment", // equipment Corn Station, LLC "ericsson", // ericsson Telefonaktiebolaget L M Ericsson "erni", // erni ERNI Group Holding AG "esq", // esq Charleston Road Registry Inc. "estate", // estate Trixy Park, LLC - "esurance", // esurance Esurance Insurance Company + // "esurance", // esurance Esurance Insurance Company (not assigned as at Version 2020062100) + "etisalat", // etisalat Emirates Telecommunic "eurovision", // eurovision European Broadcasting Union (EBU) "eus", // eus Puntueus Fundazioa "events", // events Pioneer Maple, LLC - "everbank", // everbank EverBank +// "everbank", // everbank EverBank "exchange", // exchange Spring Falls, LLC "expert", // expert Magic Pass, LLC "exposed", // exposed Victor Beach, LLC @@ -682,7 +585,7 @@ "frontier", // frontier Frontier Communications Corporation "ftr", // ftr Frontier Communications Corporation "fujitsu", // fujitsu Fujitsu Limited - "fujixerox", // fujixerox Xerox DNHC LLC +// "fujixerox", // fujixerox Xerox DNHC LLC "fun", // fun DotSpace, Inc. "fund", // fund John Castle, LLC "furniture", // furniture Lone Fields, LLC @@ -696,6 +599,7 @@ "games", // games United TLD Holdco Ltd. "gap", // gap The Gap, Inc. "garden", // garden Top Level Domain Holdings Limited + "gay", // gay Top Level Design, LLC "gbiz", // gbiz Charleston Road Registry Inc. "gdn", // gdn Joint Stock Company "Navigation-information systems" "gea", // gea GEA Group Aktiengesellschaft @@ -707,7 +611,7 @@ "gifts", // gifts Goose Sky, LLC "gives", // gives United TLD Holdco Ltd. "giving", // giving Giving Limited - "glade", // glade Johnson Shareholdings, Inc. +// "glade", // glade Johnson Shareholdings, Inc. "glass", // glass Black Cover, LLC "gle", // gle Charleston Road Registry Inc. "global", // global Dot Global Domain Registry Limited @@ -721,7 +625,7 @@ "goldpoint", // goldpoint YODOBASHI CAMERA CO.,LTD. "golf", // golf Lone Falls, LLC "goo", // goo NTT Resonant Inc. - "goodhands", // goodhands Allstate Fire and Casualty Insurance Company +// "goodhands", // goodhands Allstate Fire and Casualty Insurance Company "goodyear", // goodyear The Goodyear Tire & Rubber Company "goog", // goog Charleston Road Registry Inc. "google", // google Charleston Road Registry Inc. @@ -733,6 +637,7 @@ "gratis", // gratis Pioneer Tigers, LLC "green", // green Afilias Limited "gripe", // gripe Corn Sunset, LLC + "grocery", // grocery Wal-Mart Stores, Inc. "group", // group Romeo Town, LLC "guardian", // guardian The Guardian Life Insurance Company of America "gucci", // gucci Guccio Gucci S.p.a. @@ -767,18 +672,19 @@ "homes", // homes DERHomes, LLC "homesense", // homesense The TJX Companies, Inc. "honda", // honda Honda Motor Co., Ltd. - "honeywell", // honeywell Honeywell GTLD LLC +// "honeywell", // honeywell Honeywell GTLD LLC "horse", // horse Top Level Domain Holdings Limited "hospital", // hospital Ruby Pike, LLC "host", // host DotHost Inc. "hosting", // hosting Uniregistry, Corp. "hot", // hot Amazon Registry Services, Inc. "hoteles", // hoteles Travel Reservations SRL + "hotels", // hotels Booking.com B.V. "hotmail", // hotmail Microsoft Corporation "house", // house Sugar Park, LLC "how", // how Charleston Road Registry Inc. "hsbc", // hsbc HSBC Holdings PLC - "htc", // htc HTC corporation +// "htc", // htc HTC corporation (Not assigned) "hughes", // hughes Hughes Satellite Systems Corporation "hyatt", // hyatt Hyatt GTLD, L.L.C. "hyundai", // hyundai Hyundai Motor Company @@ -794,6 +700,7 @@ "imdb", // imdb Amazon Registry Services, Inc. "immo", // immo Auburn Bloom, LLC "immobilien", // immobilien United TLD Holdco Ltd. + "inc", // inc Intercap Holdings Inc. "industries", // industries Outer House, LLC "infiniti", // infiniti NISSAN MOTOR CO., LTD. "info", // info Afilias Limited @@ -803,29 +710,29 @@ "insurance", // insurance fTLD Registry Services LLC "insure", // insure Pioneer Willow, LLC "int", // int Internet Assigned Numbers Authority - "intel", // intel Intel Corporation +// "intel", // intel Intel Corporation "international", // international Wild Way, LLC "intuit", // intuit Intuit Administrative Services, Inc. "investments", // investments Holly Glen, LLC "ipiranga", // ipiranga Ipiranga Produtos de Petroleo S.A. "irish", // irish Dot-Irish LLC - "iselect", // iselect iSelect Ltd +// "iselect", // iselect iSelect Ltd "ismaili", // ismaili Fondation Aga Khan (Aga Khan Foundation) "ist", // ist Istanbul Metropolitan Municipality "istanbul", // istanbul Istanbul Metropolitan Municipality / Medya A.S. "itau", // itau Itau Unibanco Holding S.A. "itv", // itv ITV Services Limited - "iveco", // iveco CNH Industrial N.V. - "iwc", // iwc Richemont DNS Inc. +// "iveco", // iveco CNH Industrial N.V. +// "iwc", // iwc Richemont DNS Inc. "jaguar", // jaguar Jaguar Land Rover Ltd "java", // java Oracle Corporation "jcb", // jcb JCB Co., Ltd. - "jcp", // jcp JCP Media, Inc. +// "jcp", // jcp JCP Media, Inc. "jeep", // jeep FCA US LLC. "jetzt", // jetzt New TLD Company AB "jewelry", // jewelry Wild Bloom, LLC "jio", // jio Affinity Names, Inc. - "jlc", // jlc Richemont DNS Inc. +// "jlc", // jlc Richemont DNS Inc. "jll", // jll Jones Lang LaSalle Incorporated "jmp", // jmp Matrix IP LLC "jnj", // jnj Johnson & Johnson Services, Inc. @@ -844,6 +751,7 @@ "kerryproperties", // kerryproperties Kerry Trading Co. Limited "kfh", // kfh Kuwait Finance House "kia", // kia KIA MOTORS CORPORATION + "kids", // kids DotKids Foundation Limited "kim", // kim Afilias Limited "kinder", // kinder Ferrero Trading Lux S.A. "kindle", // kindle Amazon Registry Services, Inc. @@ -859,12 +767,12 @@ "kuokgroup", // kuokgroup Kerry Trading Co. Limited "kyoto", // kyoto Academic Institution: Kyoto Jyoho Gakuen "lacaixa", // lacaixa CAIXA D'ESTALVIS I PENSIONS DE BARCELONA - "ladbrokes", // ladbrokes LADBROKES INTERNATIONAL PLC +// "ladbrokes", // ladbrokes LADBROKES INTERNATIONAL PLC "lamborghini", // lamborghini Automobili Lamborghini S.p.A. "lamer", // lamer The Estée Lauder Companies Inc. "lancaster", // lancaster LANCASTER "lancia", // lancia Fiat Chrysler Automobiles N.V. - "lancome", // lancome L'Oréal +// "lancome", // lancome L'Oréal "land", // land Pine Moon, LLC "landrover", // landrover Jaguar Land Rover Ltd "lanxess", // lanxess LANXESS Corporation @@ -882,7 +790,7 @@ "lego", // lego LEGO Juris A/S "lexus", // lexus TOYOTA MOTOR CORPORATION "lgbt", // lgbt Afilias Limited - "liaison", // liaison Liaison Technologies, Incorporated +// "liaison", // liaison Liaison Technologies, Incorporated "lidl", // lidl Schwarz Domains und Services GmbH & Co. KG "life", // life Trixy Oaks, LLC "lifeinsurance", // lifeinsurance American Council of Life Insurers @@ -898,12 +806,14 @@ "lipsy", // lipsy Lipsy Ltd "live", // live United TLD Holdco Ltd. "living", // living Lifestyle Domain Holdings, Inc. - "lixil", // lixil LIXIL Group Corporation +// "lixil", // lixil LIXIL Group Corporation + "llc", // llc Afilias plc + "llp", // llp Dot Registry LLC "loan", // loan dot Loan Limited "loans", // loans June Woods, LLC "locker", // locker Dish DBS Corporation "locus", // locus Locus Analytics LLC - "loft", // loft Annco, Inc. +// "loft", // loft Annco, Inc. "lol", // lol Uniregistry, Corp. "london", // london Dot London Domains Limited "lotte", // lotte Lotte Holdings Co., Ltd. @@ -914,7 +824,7 @@ "ltd", // ltd Over Corner, LLC "ltda", // ltda InterNetX Corp. "lundbeck", // lundbeck H. Lundbeck A/S - "lupin", // lupin LUPIN LIMITED +// "lupin", // lupin LUPIN LIMITED "luxe", // luxe Top Level Domain Holdings Limited "luxury", // luxury Luxury Partners LLC "macys", // macys Macys, Inc. @@ -925,6 +835,7 @@ "man", // man MAN SE "management", // management John Goodbye, LLC "mango", // mango PUNTO FA S.L. + "map", // map Charleston Road Registry Inc. "market", // market Unitied TLD Holdco, Ltd "marketing", // marketing Fern Pass, LLC "markets", // markets DOTMARKETS REGISTRY LTD @@ -933,8 +844,8 @@ "maserati", // maserati Fiat Chrysler Automobiles N.V. "mattel", // mattel Mattel Sites, Inc. "mba", // mba Lone Hollow, LLC - "mcd", // mcd McDonald’s Corporation - "mcdonalds", // mcdonalds McDonald’s Corporation +// "mcd", // mcd McDonald’s Corporation (Not assigned) +// "mcdonalds", // mcdonalds McDonald’s Corporation (Not assigned) "mckinsey", // mckinsey McKinsey Holdings, Inc. "med", // med Medistry LLC "media", // media Grand Glen, LLC @@ -944,8 +855,9 @@ "memorial", // memorial Dog Beach, LLC "men", // men Exclusive Registry Limited "menu", // menu Wedding TLD2, LLC - "meo", // meo PT Comunicacoes S.A. - "metlife", // metlife MetLife Services and Solutions, LLC +// "meo", // meo PT Comunicacoes S.A. + "merckmsd", // merckmsd MSD Registry Holdings, Inc. +// "metlife", // metlife MetLife Services and Solutions, LLC "miami", // miami Top Level Domain Holdings Limited "microsoft", // microsoft Microsoft Corporation "mil", // mil DoD Network Information Center @@ -958,36 +870,37 @@ "mma", // mma MMA IARD "mobi", // mobi Afilias Technologies Limited dba dotMobi "mobile", // mobile Dish DBS Corporation - "mobily", // mobily GreenTech Consultancy Company W.L.L. +// "mobily", // mobily GreenTech Consultancy Company W.L.L. "moda", // moda United TLD Holdco Ltd. "moe", // moe Interlink Co., Ltd. "moi", // moi Amazon Registry Services, Inc. "mom", // mom Uniregistry, Corp. "monash", // monash Monash University "money", // money Outer McCook, LLC "monster", // monster Monster Worldwide, Inc. - "montblanc", // montblanc Richemont DNS Inc. - "mopar", // mopar FCA US LLC. +// "montblanc", // montblanc Richemont DNS Inc. (Not assigned) +// "mopar", // mopar FCA US LLC. "mormon", // mormon IRI Domain Management, LLC ("Applicant") "mortgage", // mortgage United TLD Holdco, Ltd "moscow", // moscow Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) "moto", // moto Motorola Trademark Holdings, LLC "motorcycles", // motorcycles DERMotorcycles, LLC "mov", // mov Charleston Road Registry Inc. "movie", // movie New Frostbite, LLC - "movistar", // movistar Telefónica S.A. +// "movistar", // movistar Telefónica S.A. "msd", // msd MSD Registry Holdings, Inc. "mtn", // mtn MTN Dubai Limited - "mtpc", // mtpc Mitsubishi Tanabe Pharma Corporation +// "mtpc", // mtpc Mitsubishi Tanabe Pharma Corporation (Retired) "mtr", // mtr MTR Corporation Limited "museum", // museum Museum Domain Management Association + "music", // music DotMusic Limited "mutual", // mutual Northwestern Mutual MU TLD Registry, LLC // "mutuelle", // mutuelle Fédération Nationale de la Mutualité Française (Retired) "nab", // nab National Australia Bank Limited - "nadex", // nadex Nadex Domains, Inc +// "nadex", // nadex Nadex Domains, Inc "nagoya", // nagoya GMO Registry, Inc. "name", // name VeriSign Information Services, Inc. - "nationwide", // nationwide Nationwide Mutual Insurance Company +// "nationwide", // nationwide Nationwide Mutual Insurance Company "natura", // natura NATURA COSMÉTICOS S.A. "navy", // navy United TLD Holdco Ltd. "nba", // nba NBA REGISTRY, LLC @@ -998,7 +911,7 @@ "network", // network Trixy Manor, LLC "neustar", // neustar NeuStar, Inc. "new", // new Charleston Road Registry Inc. - "newholland", // newholland CNH Industrial N.V. +// "newholland", // newholland CNH Industrial N.V. "news", // news United TLD Holdco Ltd. "next", // next Next plc "nextdirect", // nextdirect Next plc @@ -1024,7 +937,7 @@ "nyc", // nyc The City of New York by and through the New York City Department of Information Technology & Telecommunications "obi", // obi OBI Group Holding SE & Co. KGaA "observer", // observer Top Level Spectrum, Inc. - "off", // off Johnson Shareholdings, Inc. +// "off", // off Johnson Shareholdings, Inc. "office", // office Microsoft Corporation "okinawa", // okinawa BusinessRalliart inc. "olayan", // olayan Crescent Holding GmbH @@ -1036,23 +949,23 @@ "ong", // ong Public Interest Registry "onl", // onl I-REGISTRY Ltd., Niederlassung Deutschland "online", // online DotOnline Inc. - "onyourside", // onyourside Nationwide Mutual Insurance Company +// "onyourside", // onyourside Nationwide Mutual Insurance Company "ooo", // ooo INFIBEAM INCORPORATION LIMITED "open", // open American Express Travel Related Services Company, Inc. "oracle", // oracle Oracle Corporation "orange", // orange Orange Brand Services Limited "org", // org Public Interest Registry (PIR) "organic", // organic Afilias Limited - "orientexpress", // orientexpress Orient Express +// "orientexpress", // orientexpress Orient Express (retired 2017-04-11) "origins", // origins The Estée Lauder Companies Inc. "osaka", // osaka Interlink Co., Ltd. "otsuka", // otsuka Otsuka Holdings Co., Ltd. "ott", // ott Dish DBS Corporation "ovh", // ovh OVH SAS "page", // page Charleston Road Registry Inc. - "pamperedchef", // pamperedchef The Pampered Chef, Ltd. +// "pamperedchef", // pamperedchef The Pampered Chef, Ltd. (Not assigned) "panasonic", // panasonic Panasonic Corporation - "panerai", // panerai Richemont DNS Inc. +// "panerai", // panerai Richemont DNS Inc. "paris", // paris City of Paris "pars", // pars Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. "partners", // partners Magic Glen, LLC @@ -1064,13 +977,14 @@ "pet", // pet Afilias plc "pfizer", // pfizer Pfizer Inc. "pharmacy", // pharmacy National Association of Boards of Pharmacy + "phd", // phd Charleston Road Registry Inc. "philips", // philips Koninklijke Philips N.V. "phone", // phone Dish DBS Corporation "photo", // photo Uniregistry, Corp. "photography", // photography Sugar Glen, LLC "photos", // photos Sea Corner, LLC "physio", // physio PhysBiz Pty Ltd - "piaget", // piaget Richemont DNS Inc. +// "piaget", // piaget Richemont DNS Inc. "pics", // pics Uniregistry, Corp. "pictet", // pictet Pictet Europe S.A. "pictures", // pictures Foggy Sky, LLC @@ -1111,10 +1025,10 @@ "qpon", // qpon dotCOOL, Inc. "quebec", // quebec PointQuébec Inc "quest", // quest Quest ION Limited - "qvc", // qvc QVC, Inc. +// "qvc", // qvc QVC, Inc. "racing", // racing Premier Registry Limited "radio", // radio European Broadcasting Union (EBU) - "raid", // raid Johnson Shareholdings, Inc. +// "raid", // raid Johnson Shareholdings, Inc. "read", // read Amazon Registry Services, Inc. "realestate", // realestate dotRealEstate LLC "realtor", // realtor Real Estate Domains LLC @@ -1142,17 +1056,18 @@ "rich", // rich I-REGISTRY Ltd., Niederlassung Deutschland "richardli", // richardli Pacific Century Asset Management (HK) Limited "ricoh", // ricoh Ricoh Company, Ltd. - "rightathome", // rightathome Johnson Shareholdings, Inc. + // "rightathome", // rightathome Johnson Shareholdings, Inc. (retired 2020-07-31) "ril", // ril Reliance Industries Limited "rio", // rio Empresa Municipal de Informática SA - IPLANRIO "rip", // rip United TLD Holdco Ltd. - "rmit", // rmit Royal Melbourne Institute of Technology +// "rmit", // rmit Royal Melbourne Institute of Technology "rocher", // rocher Ferrero Trading Lux S.A. "rocks", // rocks United TLD Holdco, LTD. "rodeo", // rodeo Top Level Domain Holdings Limited "rogers", // rogers Rogers Communications Canada Inc. "room", // room Amazon Registry Services, Inc. "rsvp", // rsvp Charleston Road Registry Inc. + "rugby", // rugby World Rugby Strategic Developments Limited "ruhr", // ruhr regiodot GmbH & Co. KG "run", // run Snow Park, LLC "rwe", // rwe RWE AG @@ -1169,7 +1084,7 @@ "sandvikcoromant", // sandvikcoromant Sandvik AB "sanofi", // sanofi Sanofi "sap", // sap SAP AG - "sapo", // sapo PT Comunicacoes S.A. +// "sapo", // sapo PT Comunicacoes S.A. "sarl", // sarl Delta Orchard, LLC "sas", // sas Research IP LLC "save", // save Amazon Registry Services, Inc. @@ -1185,17 +1100,18 @@ "schule", // schule Outer Moon, LLC "schwarz", // schwarz Schwarz Domains und Services GmbH & Co. KG "science", // science dot Science Limited - "scjohnson", // scjohnson Johnson Shareholdings, Inc. - "scor", // scor SCOR SE +// "scjohnson", // scjohnson Johnson Shareholdings, Inc. + // "scor", // scor SCOR SE (not assigned as at Version 2020062100) "scot", // scot Dot Scot Registry Limited + "search", // search Charleston Road Registry Inc. "seat", // seat SEAT, S.A. (Sociedad Unipersonal) "secure", // secure Amazon Registry Services, Inc. "security", // security XYZ.COM LLC "seek", // seek Seek Limited "select", // select iSelect Ltd "sener", // sener Sener Ingeniería y Sistemas, S.A. "services", // services Fox Castle, LLC - "ses", // ses SES +// "ses", // ses SES "seven", // seven Seven West Media Ltd "sew", // sew SEW-EURODRIVE GmbH & Co KG "sex", // sex ICM Registry SX LLC @@ -1213,7 +1129,7 @@ "shouji", // shouji QIHOO 360 TECHNOLOGY CO. LTD. "show", // show Snow Beach, LLC "showtime", // showtime CBS Domains Inc. - "shriram", // shriram Shriram Capital Ltd. +// "shriram", // shriram Shriram Capital Ltd. "silk", // silk Amazon Registry Services, Inc. "sina", // sina Sina Corporation "singles", // singles Fern Madison, LLC @@ -1236,19 +1152,21 @@ "song", // song Amazon Registry Services, Inc. "sony", // sony Sony Corporation "soy", // soy Charleston Road Registry Inc. + "spa", // spa Asia Spa and Wellness Promotion Council Limited "space", // space DotSpace Inc. - "spiegel", // spiegel SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG +// "spiegel", // spiegel SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG + "sport", // sport Global Association of International Sports Federations (GAISF) "spot", // spot Amazon Registry Services, Inc. - "spreadbetting", // spreadbetting DOTSPREADBETTING REGISTRY LTD +// "spreadbetting", // spreadbetting DOTSPREADBETTING REGISTRY LTD "srl", // srl InterNetX Corp. - "srt", // srt FCA US LLC. +// "srt", // srt FCA US LLC. "stada", // stada STADA Arzneimittel AG "staples", // staples Staples, Inc. "star", // star Star India Private Limited - "starhub", // starhub StarHub Limited +// "starhub", // starhub StarHub Limited "statebank", // statebank STATE BANK OF INDIA "statefarm", // statefarm State Farm Mutual Automobile Insurance Company - "statoil", // statoil Statoil ASA +// "statoil", // statoil Statoil ASA "stc", // stc Saudi Telecom Company "stcgroup", // stcgroup Saudi Telecom Company "stockholm", // stockholm Stockholms kommun @@ -1266,18 +1184,18 @@ "surgery", // surgery Tin Avenue, LLC "suzuki", // suzuki SUZUKI MOTOR CORPORATION "swatch", // swatch The Swatch Group Ltd - "swiftcover", // swiftcover Swiftcover Insurance Services Limited +// "swiftcover", // swiftcover Swiftcover Insurance Services Limited "swiss", // swiss Swiss Confederation "sydney", // sydney State of New South Wales, Department of Premier and Cabinet - "symantec", // symantec Symantec Corporation +// "symantec", // symantec Symantec Corporation [Not assigned as of Jul 25] "systems", // systems Dash Cypress, LLC "tab", // tab Tabcorp Holdings Limited "taipei", // taipei Taipei City Government "talk", // talk Amazon Registry Services, Inc. "taobao", // taobao Alibaba Group Holding Limited "target", // target Target Domain Holdings, LLC "tatamotors", // tatamotors Tata Motors Ltd - "tatar", // tatar Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" + "tatar", // tatar LLC "Coordination Center of Regional Domain of Tatarstan Republic" "tattoo", // tattoo Uniregistry, Corp. "tax", // tax Storm Orchard, LLC "taxi", // taxi Pine Falls, LLC @@ -1287,8 +1205,8 @@ "tech", // tech Dot Tech LLC "technology", // technology Auburn Falls, LLC "tel", // tel Telnic Ltd. - "telecity", // telecity TelecityGroup International Limited - "telefonica", // telefonica Telefónica S.A. +// "telecity", // telecity TelecityGroup International Limited +// "telefonica", // telefonica Telefónica S.A. "temasek", // temasek Temasek Holdings (Private) Limited "tennis", // tennis Cotton Bloom, LLC "teva", // teva Teva Pharmaceutical Industries Limited @@ -1333,7 +1251,7 @@ "tvs", // tvs T V SUNDRAM IYENGAR & SONS PRIVATE LIMITED "ubank", // ubank National Australia Bank Limited "ubs", // ubs UBS AG - "uconnect", // uconnect FCA US LLC. +// "uconnect", // uconnect FCA US LLC. "unicom", // unicom China United Network Communications Corporation Limited "university", // university Little Station, LLC "uno", // uno Dot Latin LLC @@ -1357,8 +1275,8 @@ "virgin", // virgin Virgin Enterprises Limited "visa", // visa Visa Worldwide Pte. Limited "vision", // vision Koko Station, LLC - "vista", // vista Vistaprint Limited - "vistaprint", // vistaprint Vistaprint Limited +// "vista", // vista Vistaprint Limited +// "vistaprint", // vistaprint Vistaprint Limited "viva", // viva Saudi Telecom Company "vivo", // vivo Telefonica Brasil S.A. "vlaanderen", // vlaanderen DNS.be vzw @@ -1375,7 +1293,7 @@ "walter", // walter Sandvik AB "wang", // wang Zodiac Registry Limited "wanggou", // wanggou Amazon Registry Services, Inc. - "warman", // warman Weir Group IP Limited +// "warman", // warman Weir Group IP Limited "watch", // watch Sand Shadow, LLC "watches", // watches Richemont DNS Inc. "weather", // weather The Weather Channel, LLC @@ -1415,7 +1333,7 @@ "xn--30rr7y", // 慈善 Excellent First Limited "xn--3bst00m", // 集团 Eagle Horizon Limited "xn--3ds443g", // 在线 TLD REGISTRY LIMITED - "xn--3oq18vl8pn36a", // 大众汽车 Volkswagen (China) Investment Co., Ltd. +// "xn--3oq18vl8pn36a", // 大众汽车 Volkswagen (China) Investment Co., Ltd. "xn--3pxu8k", // 点看 VeriSign Sarl "xn--42c2d9a", // คอม VeriSign Sarl "xn--45q11c", // 八卦 Zodiac Scorpio Limited @@ -1440,14 +1358,15 @@ "xn--c1avg", // орг Public Interest Registry "xn--c2br7g", // नेट VeriSign Sarl "xn--cck2b3b", // ストア Amazon Registry Services, Inc. + "xn--cckwcxetd", // アマゾン Amazon Registry Services, Inc. "xn--cg4bki", // 삼성 SAMSUNG SDS CO., LTD "xn--czr694b", // 商标 HU YI GLOBAL INFORMATION RESOURCES(HOLDING) COMPANY.HONGKONG LIMITED "xn--czrs0t", // 商店 Wild Island, LLC "xn--czru2d", // 商城 Zodiac Aquarius Limited "xn--d1acj3b", // дети The Foundation for Network Initiatives “The Smart Internet” "xn--eckvdtc9d", // ポイント Amazon Registry Services, Inc. "xn--efvy88h", // 新闻 Xinhua News Agency Guangdong Branch 新华通讯社广东分社 - "xn--estv75g", // 工行 Industrial and Commercial Bank of China Limited +// "xn--estv75g", // 工行 Industrial and Commercial Bank of China Limited "xn--fct429k", // 家電 Amazon Registry Services, Inc. "xn--fhbei", // كوم VeriSign Sarl "xn--fiq228c5hs", // 中文网 TLD REGISTRY LIMITED @@ -1463,27 +1382,31 @@ "xn--imr513n", // 餐厅 HU YI GLOBAL INFORMATION RESOURCES (HOLDING) COMPANY. HONGKONG LIMITED "xn--io0a7i", // 网络 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center) "xn--j1aef", // ком VeriSign Sarl - "xn--jlq61u9w7b", // 诺基亚 Nokia Corporation + "xn--jlq480n2rg", // 亚马逊 Amazon Registry Services, Inc. +// "xn--jlq61u9w7b", // 诺基亚 Nokia Corporation "xn--jvr189m", // 食品 Amazon Registry Services, Inc. "xn--kcrx77d1x4a", // 飞利浦 Koninklijke Philips N.V. - "xn--kpu716f", // 手表 Richemont DNS Inc. +// "xn--kpu716f", // 手表 Richemont DNS Inc. [Not assigned as of Jul 25] "xn--kput3i", // 手机 Beijing RITT-Net Technology Development Co., Ltd "xn--mgba3a3ejt", // ارامكو Aramco Services Company "xn--mgba7c0bbn0a", // العليان Crescent Holding GmbH + "xn--mgbaakc7dvf", // اتصالات Emirates Telecommunications Corporation (trading as Etisalat) "xn--mgbab2bd", // بازار CORE Association - "xn--mgbb9fbpob", // موبايلي GreenTech Consultancy Company W.L.L. +// "xn--mgbb9fbpob", // موبايلي GreenTech Consultancy Company W.L.L. "xn--mgbca7dzdo", // ابوظبي Abu Dhabi Systems and Information Centre "xn--mgbi4ecexp", // كاثوليك Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) "xn--mgbt3dhd", // همراه Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. "xn--mk1bu44c", // 닷컴 VeriSign Sarl "xn--mxtq1m", // 政府 Net-Chinese Co., Ltd. "xn--ngbc5azd", // شبكة International Domain Registry Pty. Ltd. "xn--ngbe9e0a", // بيتك Kuwait Finance House + "xn--ngbrx", // عرب League of Arab States "xn--nqv7f", // 机构 Public Interest Registry "xn--nqv7fs00ema", // 组织机构 Public Interest Registry "xn--nyqy26a", // 健康 Stable Tone Limited + "xn--otu796d", // 招聘 Dot Trademark TLD Holding Company Limited "xn--p1acf", // рус Rusnames Limited - "xn--pbt977c", // 珠宝 Richemont DNS Inc. +// "xn--pbt977c", // 珠宝 Richemont DNS Inc. [Not assigned as of Jul 25] "xn--pssy2u", // 大拿 VeriSign Sarl "xn--q9jyb4c", // みんな Charleston Road Registry Inc. "xn--qcka1pmc", // グーグル Charleston Road Registry Inc. @@ -1502,7 +1425,7 @@ "xn--w4rs40l", // 嘉里 Kerry Trading Co. Limited "xn--xhq521b", // 广东 Guangzhou YU Wei Information Technology Co., Ltd. "xn--zfr164b", // 政务 China Organizational Name Administration Center - "xperia", // xperia Sony Mobile Communications AB +// "xperia", // xperia Sony Mobile Communications AB "xxx", // xxx ICM Registry LLC "xyz", // xyz XYZ.COM LLC "yachts", // yachts DERYachts, LLC @@ -1519,13 +1442,14 @@ "zara", // zara Industria de Diseño Textil, S.A. (INDITEX, S.A.) "zero", // zero Amazon Registry Services, Inc. "zip", // zip Charleston Road Registry Inc. - "zippo", // zippo Zadco Company +// "zippo", // zippo Zadco Company "zone", // zone Outer Falls, LLC "zuerich", // zuerich Kanton Zürich (Canton of Zurich) }; // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static final String[] COUNTRY_CODE_TLDS = new String[] { + private static final String[] COUNTRY_CODE_TLDS = { + // Taken from Version 2023011200, Last Updated Thu Jan 12 07:07:01 2023 UTC "ac", // Ascension Island "ad", // Andorra "ae", // United Arab Emirates @@ -1732,6 +1656,7 @@ "sn", // Senegal "so", // Somalia "sr", // Suriname + "ss", // ss National Communication Authority (NCA) "st", // São Tomé and Príncipe "su", // Soviet Union (deprecated) "sv", // El Salvador @@ -1770,8 +1695,12 @@ "vu", // Vanuatu "wf", // Wallis and Futuna "ws", // Samoa (formerly Western Samoa) + "xn--2scrj9c", // ಭಾರತ National Internet eXchange of India "xn--3e0b707e", // 한국 KISA (Korea Internet & Security Agency) + "xn--3hcrj9c", // ଭାରତ National Internet eXchange of India + "xn--45br5cyl", // ভাৰত National Internet eXchange of India "xn--45brj9c", // ভারত National Internet Exchange of India + "xn--4dbrk0ce", // ישראל The Israel Internet Association (RA) "xn--54b7fta0cc", // বাংলা Posts and Telecommunications Division "xn--80ao21a", // қаз Association of IT Companies of Kazakhstan "xn--90a3ac", // срб Serbian National Internet Domain Registry (RNIDS) @@ -1784,7 +1713,9 @@ "xn--fpcrj9c3d", // భారత్ National Internet Exchange of India "xn--fzc2c9e2c", // ලංකා LK Domain Registry "xn--gecrj9c", // ભારત National Internet Exchange of India + "xn--h2breg3eve", // भारतम् National Internet eXchange of India "xn--h2brj9c", // भारत National Internet Exchange of India + "xn--h2brj9c8c", // भारोत National Internet eXchange of India "xn--j1amh", // укр Ukrainian Network Information Centre (UANIC), Inc. "xn--j6w193g", // 香港 Hong Kong Internet Registration Corporation Ltd. "xn--kprw13d", // 台湾 Taiwan Network Information Center (TWNIC) @@ -1794,10 +1725,15 @@ "xn--mgb9awbf", // عمان Telecommunications Regulatory Authority (TRA) "xn--mgba3a4f16a", // ایران Institute for Research in Fundamental Sciences (IPM) "xn--mgbaam7a8h", // امارات Telecommunications Regulatory Authority (TRA) + "xn--mgbah1a3hjkrd", // موريتانيا Université de Nouakchott Al Aasriya + "xn--mgbai9azgqp6j", // پاکستان National Telecommunication Corporation "xn--mgbayh7gpa", // الاردن National Information Technology Center (NITC) + "xn--mgbbh1a", // بارت National Internet eXchange of India "xn--mgbbh1a71e", // بھارت National Internet Exchange of India "xn--mgbc0a9azcg", // المغرب Agence Nationale de Réglementation des Télécommunications (ANRT) + "xn--mgbcpq6gpa1a", // البحرين Telecommunications Regulatory Authority (TRA) "xn--mgberp4a5d4ar", // السعودية Communications and Information Technology Commission + "xn--mgbgu82a", // ڀارت National Internet eXchange of India "xn--mgbpl2fh", // ????? Sudan Internet Society "xn--mgbtx2b", // عراق Communications and Media Commission (CMC) "xn--mgbx4cd0ab", // مليسيا MYNIC Berhad @@ -1807,7 +1743,10 @@ "xn--ogbpf8fl", // سورية National Agency for Network Services (NANS) "xn--p1ai", // рф Coordination Center for TLD RU "xn--pgbs0dh", // تونس Agence Tunisienne d'Internet + "xn--q7ce6a", // ລາວ Lao National Internet Center (LANIC) + "xn--qxa6a", // ευ EURid vzw/asbl "xn--qxam", // ελ ICS-FORTH GR + "xn--rvc1e0am3e", // ഭാരതം National Internet eXchange of India "xn--s9brj9c", // ਭਾਰਤ National Internet Exchange of India "xn--wgbh1c", // مصر National Telecommunication Regulatory Authority - NTRA "xn--wgbl6a", // قطر Communications Regulatory Authority @@ -1824,80 +1763,207 @@ }; // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static final String[] LOCAL_TLDS = new String[] { + private static final String[] LOCAL_TLDS = { "localdomain", // Also widely used as localhost.localdomain "localhost", // RFC2606 defined }; - - // Additional arrays to supplement or override the built in ones. - // The PLUS arrays are valid keys, the MINUS arrays are invalid keys - /* * This field is used to detect whether the getInstance has been called. * After this, the method updateTLDOverride is not allowed to be called. * This field does not need to be volatile since it is only accessed from - * synchronized methods. + * synchronized methods. */ - private static boolean inUse = false; - + private static boolean inUse; /* - * These arrays are mutable, but they don't need to be volatile. - * They can only be updated by the updateTLDOverride method, and any readers must get an instance - * using the getInstance methods which are all (now) synchronised. + * These arrays are mutable. + * They can only be updated by the updateTLDOverride method, and readers must first get an instance + * using the getInstance methods which are all (now) synchronized. + * The only other access is via getTLDEntries which is now synchronized. */ // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static volatile String[] countryCodeTLDsPlus = EMPTY_STRING_ARRAY; - + private static String[] countryCodeTLDsPlus = EMPTY_STRING_ARRAY; // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static volatile String[] genericTLDsPlus = EMPTY_STRING_ARRAY; + private static String[] genericTLDsPlus = EMPTY_STRING_ARRAY; + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static String[] countryCodeTLDsMinus = EMPTY_STRING_ARRAY; + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static String[] genericTLDsMinus = EMPTY_STRING_ARRAY; + // N.B. The constructors are deliberately private to avoid possible problems with unsafe publication. + // It is vital that the static override arrays are not mutable once they have been used in an instance + // The arrays could be copied into the instance variables, however if the static array were changed it could + // result in different settings for the shared default instances + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static volatile String[] countryCodeTLDsMinus = EMPTY_STRING_ARRAY; + private static String[] localTLDsMinus = EMPTY_STRING_ARRAY; // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search - private static volatile String[] genericTLDsMinus = EMPTY_STRING_ARRAY; + private static String[] localTLDsPlus = EMPTY_STRING_ARRAY; /** - * enum used by {@link DomainValidator#updateTLDOverride(ArrayType, String[])} - * to determine which override array to update / fetch - * @since 1.5.0 - * @since 1.5.1 made public and added read-only array references + * Check if a sorted array contains the specified key + * + * @param sortedArray the array to search + * @param key the key to find + * @return {@code true} if the array contains the key */ - public enum ArrayType { - /** Update (or get a copy of) the GENERIC_TLDS_PLUS table containing additonal generic TLDs */ - GENERIC_PLUS, - /** Update (or get a copy of) the GENERIC_TLDS_MINUS table containing deleted generic TLDs */ - GENERIC_MINUS, - /** Update (or get a copy of) the COUNTRY_CODE_TLDS_PLUS table containing additonal country code TLDs */ - COUNTRY_CODE_PLUS, - /** Update (or get a copy of) the COUNTRY_CODE_TLDS_MINUS table containing deleted country code TLDs */ - COUNTRY_CODE_MINUS, - /** Get a copy of the generic TLDS table */ - GENERIC_RO, - /** Get a copy of the country code table */ - COUNTRY_CODE_RO, - /** Get a copy of the infrastructure table */ - INFRASTRUCTURE_RO, - /** Get a copy of the local table */ - LOCAL_RO - ; - }; + private static boolean arrayContains(final String[] sortedArray, final String key) { + return Arrays.binarySearch(sortedArray, key) >= 0; + } - // For use by unit test code only - static synchronized void clearTLDOverrides() { - inUse = false; - countryCodeTLDsPlus = EMPTY_STRING_ARRAY; - countryCodeTLDsMinus = EMPTY_STRING_ARRAY; - genericTLDsPlus = EMPTY_STRING_ARRAY; - genericTLDsMinus = EMPTY_STRING_ARRAY; + /** + * Returns the singleton instance of this validator. It + * will not consider local addresses as valid. + * @return the singleton instance of this validator + */ + public static synchronized DomainValidator getInstance() { + inUse = true; + return LazyHolder.DOMAIN_VALIDATOR; } + /** + * Returns the singleton instance of this validator, + * with local validation as required. + * @param allowLocal Should local addresses be considered valid? + * @return the singleton instance of this validator + */ + public static synchronized DomainValidator getInstance(final boolean allowLocal) { + inUse = true; + if (allowLocal) { + return LazyHolder.DOMAIN_VALIDATOR_WITH_LOCAL; + } + return LazyHolder.DOMAIN_VALIDATOR; + } + + /** + * Returns a new instance of this validator. + * The user can provide a list of {@link Item} entries which can + * be used to override the generic and country code lists. + * Note that any such entries override values provided by the + * {@link #updateTLDOverride(ArrayType, String[])} method + * If an entry for a particular type is not provided, then + * the class override (if any) is retained. + * + * @param allowLocal Should local addresses be considered valid? + * @param items - array of {@link Item} entries + * @return an instance of this validator + * @since 1.7 + */ + public static synchronized DomainValidator getInstance(final boolean allowLocal, final List items) { + inUse = true; + return new DomainValidator(allowLocal, items); + } + + /** + * Gets a copy of a class level internal array. + * @param table the array type (any of the enum values) + * @return a copy of the array + * @throws IllegalArgumentException if the table type is unexpected (should not happen) + * @since 1.5.1 + */ + public static synchronized String[] getTLDEntries(final ArrayType table) { + final String[] array; + switch (table) { + case COUNTRY_CODE_MINUS: + array = countryCodeTLDsMinus; + break; + case COUNTRY_CODE_PLUS: + array = countryCodeTLDsPlus; + break; + case GENERIC_MINUS: + array = genericTLDsMinus; + break; + case GENERIC_PLUS: + array = genericTLDsPlus; + break; + case LOCAL_MINUS: + array = localTLDsMinus; + break; + case LOCAL_PLUS: + array = localTLDsPlus; + break; + case GENERIC_RO: + array = GENERIC_TLDS; + break; + case COUNTRY_CODE_RO: + array = COUNTRY_CODE_TLDS; + break; + case INFRASTRUCTURE_RO: + array = INFRASTRUCTURE_TLDS; + break; + case LOCAL_RO: + array = LOCAL_TLDS; + break; + default: + throw new IllegalArgumentException(UNEXPECTED_ENUM_VALUE + table); + } + return Arrays.copyOf(array, array.length); // clone the array + } + + /* + * Check if input contains only ASCII + * Treats null as all ASCII + */ + private static boolean isOnlyASCII(final String input) { + if (input == null) { + return true; + } + for (int i = 0; i < input.length(); i++) { + if (input.charAt(i) > 0x7F) { // CHECKSTYLE IGNORE MagicNumber + return false; + } + } + return true; + } + + /** + * Converts potentially Unicode input to punycode. + * If conversion fails, returns the original input. + * + * @param input the string to convert, not null + * @return converted input, or original input if conversion fails + */ + // Needed by UrlValidator + static String unicodeToASCII(final String input) { + if (isOnlyASCII(input)) { // skip possibly expensive processing + return input; + } + try { + final String ascii = IDN.toASCII(input); + if (IDNBUGHOLDER.IDN_TOASCII_PRESERVES_TRAILING_DOTS) { + return ascii; + } + final int length = input.length(); + if (length == 0) { // check there is a last character + return input; + } + // RFC3490 3.1. 1) + // Whenever dots are used as label separators, the following + // characters MUST be recognized as dots: U+002E (full stop), U+3002 + // (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61 + // (halfwidth ideographic full stop). + final char lastChar = input.charAt(length - 1);// fetch original last char + switch (lastChar) { + case '\u002E': // "." full stop + case '\u3002': // ideographic full stop + case '\uFF0E': // fullwidth full stop + case '\uFF61': // halfwidth ideographic full stop + return ascii + "."; // restore the missing stop + default: + return ascii; + } + } catch (final IllegalArgumentException e) { // input is not valid + return input; + } + } + + /** * Update one of the TLD override arrays. * This must only be done at program startup, before any instances are accessed using getInstance. *

    * For example: *

    - * {@code DomainValidator.updateTLDOverride(ArrayType.GENERIC_PLUS, new String[]{"apache"})} + * {@code DomainValidator.updateTLDOverride(ArrayType.GENERIC_PLUS, "apache")} *

    * To clear an override array, provide an empty array. * @@ -1908,23 +1974,25 @@ *

  • COUNTRY_CODE_PLUS
  • *
  • GENERIC_MINUS
  • *
  • GENERIC_PLUS
  • + *
  • LOCAL_MINUS
  • + *
  • LOCAL_PLUS
  • * * @param tlds the array of TLDs, must not be null * @throws IllegalStateException if the method is called after getInstance * @throws IllegalArgumentException if one of the read-only tables is requested * @since 1.5.0 */ - public static synchronized void updateTLDOverride(ArrayType table, String [] tlds) { + public static synchronized void updateTLDOverride(final ArrayType table, final String... tlds) { if (inUse) { throw new IllegalStateException("Can only invoke this method before calling getInstance"); } - String [] copy = new String[tlds.length]; + final String[] copy = new String[tlds.length]; // Comparisons are always done with lower-case entries for (int i = 0; i < tlds.length; i++) { copy[i] = tlds[i].toLowerCase(Locale.ENGLISH); } Arrays.sort(copy); - switch(table) { + switch (table) { case COUNTRY_CODE_MINUS: countryCodeTLDsMinus = copy; break; @@ -1937,129 +2005,314 @@ case GENERIC_PLUS: genericTLDsPlus = copy; break; + case LOCAL_MINUS: + localTLDsMinus = copy; + break; + case LOCAL_PLUS: + localTLDsPlus = copy; + break; case COUNTRY_CODE_RO: case GENERIC_RO: case INFRASTRUCTURE_RO: case LOCAL_RO: throw new IllegalArgumentException("Cannot update the table: " + table); default: - throw new IllegalArgumentException("Unexpected enum value: " + table); + throw new IllegalArgumentException(UNEXPECTED_ENUM_VALUE + table); } } + /** Whether to allow local overrides. */ + private final boolean allowLocal; + + // --------------------------------------------- + // ----- TLDs defined by IANA + // ----- Authoritative and comprehensive list at: + // ----- http://data.iana.org/TLD/tlds-alpha-by-domain.txt + + // Note that the above list is in UPPER case. + // The code currently converts strings to lower case (as per the tables below) + + // IANA also provide an HTML list at http://www.iana.org/domains/root/db + // Note that this contains several country code entries which are NOT in + // the text file. These all have the "Not assigned" in the "Sponsoring Organisation" column + // For example (as of 2015-01-02): + // .bl country-code Not assigned + // .um country-code Not assigned + /** - * Get a copy of the internal array. + * RegexValidator for matching domains. + */ + private final RegexValidator domainRegex = + new RegexValidator(DOMAIN_NAME_REGEX); + + /** + * RegexValidator for matching a local hostname + */ + // RFC1123 sec 2.1 allows hostnames to start with a digit + private final RegexValidator hostnameRegex = + new RegexValidator(DOMAIN_LABEL_REGEX); + + /** Local override. */ + final String[] myCountryCodeTLDsMinus; + + /** Local override. */ + final String[] myCountryCodeTLDsPlus; + + // Additional arrays to supplement or override the built in ones. + // The PLUS arrays are valid keys, the MINUS arrays are invalid keys + + /** Local override. */ + final String[] myGenericTLDsPlus; + + /** Local override. */ + final String[] myGenericTLDsMinus; + + /** Local override. */ + final String[] myLocalTLDsPlus; + + /** Local override. */ + final String[] myLocalTLDsMinus; + + /* + * It is vital that instances are immutable. This is because the default instances are shared. + */ + + /** + * Private constructor. + */ + private DomainValidator(final boolean allowLocal) { + this.allowLocal = allowLocal; + // link to class overrides + myCountryCodeTLDsMinus = countryCodeTLDsMinus; + myCountryCodeTLDsPlus = countryCodeTLDsPlus; + myGenericTLDsPlus = genericTLDsPlus; + myGenericTLDsMinus = genericTLDsMinus; + myLocalTLDsPlus = localTLDsPlus; + myLocalTLDsMinus = localTLDsMinus; + } + + /** + * Private constructor, allowing local overrides + * @since 1.7 + */ + private DomainValidator(final boolean allowLocal, final List items) { + this.allowLocal = allowLocal; + + // default to class overrides + String[] ccMinus = countryCodeTLDsMinus; + String[] ccPlus = countryCodeTLDsPlus; + String[] genMinus = genericTLDsMinus; + String[] genPlus = genericTLDsPlus; + String[] localMinus = localTLDsMinus; + String[] localPlus = localTLDsPlus; + + // apply the instance overrides + for (final Item item : items) { + final String[] copy = new String[item.values.length]; + // Comparisons are always done with lower-case entries + for (int i = 0; i < item.values.length; i++) { + copy[i] = item.values[i].toLowerCase(Locale.ENGLISH); + } + Arrays.sort(copy); + switch (item.type) { + case COUNTRY_CODE_MINUS: { + ccMinus = copy; + break; + } + case COUNTRY_CODE_PLUS: { + ccPlus = copy; + break; + } + case GENERIC_MINUS: { + genMinus = copy; + break; + } + case GENERIC_PLUS: { + genPlus = copy; + break; + } + case LOCAL_MINUS: { + localMinus = copy; + break; + } + case LOCAL_PLUS: { + localPlus = copy; + break; + } + default: + break; + } + } + + // init the instance overrides + myCountryCodeTLDsMinus = ccMinus; + myCountryCodeTLDsPlus = ccPlus; + myGenericTLDsMinus = genMinus; + myGenericTLDsPlus = genPlus; + myLocalTLDsMinus = localMinus; + myLocalTLDsPlus = localPlus; + } + + private String chompLeadingDot(final String str) { + if (str.startsWith(".")) { + return str.substring(1); + } + return str; + } + + /** + * Gets a copy of an instance level internal array. * @param table the array type (any of the enum values) * @return a copy of the array - * @throws IllegalArgumentException if the table type is unexpected (should not happen) - * @since 1.5.1 + * @throws IllegalArgumentException if the table type is unexpected, e.g. GENERIC_RO + * @since 1.7 */ - public static String [] getTLDEntries(ArrayType table) { - final String array[]; - switch(table) { + public String[] getOverrides(final ArrayType table) { + final String[] array; + switch (table) { case COUNTRY_CODE_MINUS: - array = countryCodeTLDsMinus; + array = myCountryCodeTLDsMinus; break; case COUNTRY_CODE_PLUS: - array = countryCodeTLDsPlus; + array = myCountryCodeTLDsPlus; break; case GENERIC_MINUS: - array = genericTLDsMinus; + array = myGenericTLDsMinus; break; case GENERIC_PLUS: - array = genericTLDsPlus; + array = myGenericTLDsPlus; break; - case GENERIC_RO: - array = GENERIC_TLDS; + case LOCAL_MINUS: + array = myLocalTLDsMinus; break; - case COUNTRY_CODE_RO: - array = COUNTRY_CODE_TLDS; + case LOCAL_PLUS: + array = myLocalTLDsPlus; break; - case INFRASTRUCTURE_RO: - array = INFRASTRUCTURE_TLDS; - break; - case LOCAL_RO: - array = LOCAL_TLDS; - break; default: - throw new IllegalArgumentException("Unexpected enum value: " + table); + throw new IllegalArgumentException(UNEXPECTED_ENUM_VALUE + table); } return Arrays.copyOf(array, array.length); // clone the array } /** - * Converts potentially Unicode input to punycode. - * If conversion fails, returns the original input. - * - * @param input the string to convert, not null - * @return converted input, or original input if conversion fails + * Does this instance allow local addresses? + * + * @return true if local addresses are allowed. + * @since 1.7 */ - // Needed by UrlValidator - static String unicodeToASCII(String input) { - if (isOnlyASCII(input)) { // skip possibly expensive processing - return input; - } - try { - final String ascii = IDN.toASCII(input); - if (IDNBUGHOLDER.IDN_TOASCII_PRESERVES_TRAILING_DOTS) { - return ascii; - } - final int length = input.length(); - if (length == 0) {// check there is a last character - return input; - } - // RFC3490 3.1. 1) - // Whenever dots are used as label separators, the following - // characters MUST be recognized as dots: U+002E (full stop), U+3002 - // (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61 - // (halfwidth ideographic full stop). - char lastChar = input.charAt(length-1);// fetch original last char - switch(lastChar) { - case '\u002E': // "." full stop - case '\u3002': // ideographic full stop - case '\uFF0E': // fullwidth full stop - case '\uFF61': // halfwidth ideographic full stop - return ascii + "."; // restore the missing stop - default: - return ascii; - } - } catch (IllegalArgumentException e) { // input is not valid - return input; - } + public boolean isAllowLocal() { + return this.allowLocal; } - private static class IDNBUGHOLDER { - private static boolean keepsTrailingDot() { - final String input = "a."; // must be a valid name - return input.equals(IDN.toASCII(input)); + /** + * Returns true if the specified String parses + * as a valid domain name with a recognized top-level domain. + * The parsing is case-insensitive. + * @param domain the parameter to check for domain name syntax + * @return true if the parameter is a valid domain name + */ + public boolean isValid(String domain) { + if (domain == null) { + return false; } - private static final boolean IDN_TOASCII_PRESERVES_TRAILING_DOTS = keepsTrailingDot(); + domain = unicodeToASCII(domain); + // hosts must be equally reachable via punycode and Unicode + // Unicode is never shorter than punycode, so check punycode + // if domain did not convert, then it will be caught by ASCII + // checks in the regexes below + if (domain.length() > MAX_DOMAIN_LENGTH) { + return false; + } + final String[] groups = domainRegex.match(domain); + if (groups != null && groups.length > 0) { + return isValidTld(groups[0]); + } + return allowLocal && hostnameRegex.isValid(domain); } - /* - * Check if input contains only ASCII - * Treats null as all ASCII + /** + * Returns true if the specified String matches any + * IANA-defined country code top-level domain. Leading dots are + * ignored if present. The search is case-insensitive. + * @param ccTld the parameter to check for country code TLD status, not null + * @return true if the parameter is a country code TLD */ - private static boolean isOnlyASCII(String input) { - if (input == null) { - return true; + public boolean isValidCountryCodeTld(final String ccTld) { + final String key = chompLeadingDot(unicodeToASCII(ccTld).toLowerCase(Locale.ENGLISH)); + return (arrayContains(COUNTRY_CODE_TLDS, key) || arrayContains(myCountryCodeTLDsPlus, key)) && !arrayContains(myCountryCodeTLDsMinus, key); + } + + // package protected for unit test access + // must agree with isValid() above + final boolean isValidDomainSyntax(String domain) { + if (domain == null) { + return false; } - for(int i=0; i < input.length(); i++) { - if (input.charAt(i) > 0x7F) { // CHECKSTYLE IGNORE MagicNumber - return false; - } + domain = unicodeToASCII(domain); + // hosts must be equally reachable via punycode and Unicode + // Unicode is never shorter than punycode, so check punycode + // if domain did not convert, then it will be caught by ASCII + // checks in the regexes below + if (domain.length() > MAX_DOMAIN_LENGTH) { + return false; } - return true; + final String[] groups = domainRegex.match(domain); + return groups != null && groups.length > 0 || hostnameRegex.isValid(domain); } + /** + * Returns true if the specified String matches any + * IANA-defined generic top-level domain. Leading dots are ignored + * if present. The search is case-insensitive. + * @param gTld the parameter to check for generic TLD status, not null + * @return true if the parameter is a generic TLD + */ + public boolean isValidGenericTld(final String gTld) { + final String key = chompLeadingDot(unicodeToASCII(gTld).toLowerCase(Locale.ENGLISH)); + return (arrayContains(GENERIC_TLDS, key) || arrayContains(myGenericTLDsPlus, key)) && !arrayContains(myGenericTLDsMinus, key); + } /** - * Check if a sorted array contains the specified key - * - * @param sortedArray the array to search - * @param key the key to find - * @return {@code true} if the array contains the key + * Returns true if the specified String matches any + * IANA-defined infrastructure top-level domain. Leading dots are + * ignored if present. The search is case-insensitive. + * @param iTld the parameter to check for infrastructure TLD status, not null + * @return true if the parameter is an infrastructure TLD */ - private static boolean arrayContains(String[] sortedArray, String key) { - return Arrays.binarySearch(sortedArray, key) >= 0; + public boolean isValidInfrastructureTld(final String iTld) { + final String key = chompLeadingDot(unicodeToASCII(iTld).toLowerCase(Locale.ENGLISH)); + return arrayContains(INFRASTRUCTURE_TLDS, key); } + + /** + * Returns true if the specified String matches any + * widely used "local" domains (localhost or localdomain). Leading dots are + * ignored if present. The search is case-insensitive. + * @param lTld the parameter to check for local TLD status, not null + * @return true if the parameter is an local TLD + */ + public boolean isValidLocalTld(final String lTld) { + final String key = chompLeadingDot(unicodeToASCII(lTld).toLowerCase(Locale.ENGLISH)); + return (arrayContains(LOCAL_TLDS, key) || arrayContains(myLocalTLDsPlus, key)) + && !arrayContains(myLocalTLDsMinus, key); + } + + /** + * Returns true if the specified String matches any + * IANA-defined top-level domain. Leading dots are ignored if present. + * The search is case-insensitive. + *

    + * If allowLocal is true, the TLD is checked using {@link #isValidLocalTld(String)}. + * The TLD is then checked against {@link #isValidInfrastructureTld(String)}, + * {@link #isValidGenericTld(String)} and {@link #isValidCountryCodeTld(String)} + * @param tld the parameter to check for TLD status, not null + * @return true if the parameter is a TLD + */ + public boolean isValidTld(final String tld) { + if (allowLocal && isValidLocalTld(tld)) { + return true; + } + return isValidInfrastructureTld(tld) + || isValidGenericTld(tld) + || isValidCountryCodeTld(tld); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java (.../DoubleValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java (.../DoubleValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -59,8 +59,7 @@ *

  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class DoubleValidator extends AbstractNumberValidator { @@ -77,7 +76,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public DoubleValidator() { this(true, STANDARD_FORMAT); @@ -99,76 +98,26 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public DoubleValidator(boolean strict, int formatType) { + public DoubleValidator(final boolean strict, final int formatType) { super(strict, formatType, true); } /** - *

    Validate/convert a Double using the default - * Locale. - * - * @param value The value validation is being performed on. - * @return The parsed Double if valid or null - * if invalid. - */ - public Double validate(String value) { - return (Double)parse(value, (String)null, (Locale)null); - } - - /** - *

    Validate/convert a Double using the - * specified pattern. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed BigDecimal if valid or null if invalid. - */ - public Double validate(String value, String pattern) { - return (Double)parse(value, pattern, (Locale)null); - } - - /** - *

    Validate/convert a Double using the - * specified Locale. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Double if valid or null if invalid. - */ - public Double validate(String value, Locale locale) { - return (Double)parse(value, (String)null, locale); - } - - /** - *

    Validate/convert a Double using the - * specified pattern and/ or Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Double if valid or null if invalid. - */ - public Double validate(String value, String pattern, Locale locale) { - return (Double)parse(value, pattern, locale); - } - - /** * Check if the value is within a specified range. * * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(double value, double min, double max) { - return (value >= min && value <= max); + public boolean isInRange(final double value, final double min, final double max) { + return value >= min && value <= max; } /** @@ -177,59 +126,59 @@ * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(Double value, double min, double max) { + public boolean isInRange(final Double value, final double min, final double max) { return isInRange(value.doubleValue(), min, max); } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(double value, double min) { - return (value >= min); + public boolean maxValue(final double value, final double max) { + return value <= max; } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(Double value, double min) { - return minValue(value.doubleValue(), min); + public boolean maxValue(final Double value, final double max) { + return maxValue(value.doubleValue(), max); } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(double value, double max) { - return (value <= max); + public boolean minValue(final double value, final double min) { + return value >= min; } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(Double value, double max) { - return maxValue(value.doubleValue(), max); + public boolean minValue(final Double value, final double min) { + return minValue(value.doubleValue(), min); } /** @@ -241,12 +190,62 @@ * or null if invalid. */ @Override - protected Object processParsedValue(Object value, Format formatter) { + protected Object processParsedValue(final Object value, final Format formatter) { if (value instanceof Double) { return value; } - return new Double(((Number)value).doubleValue()); + return Double.valueOf(((Number)value).doubleValue()); } + + /** + *

    Validate/convert a Double using the default + * Locale. + * + * @param value The value validation is being performed on. + * @return The parsed Double if valid or null + * if invalid. + */ + public Double validate(final String value) { + return (Double)parse(value, (String)null, (Locale)null); + } + + /** + *

    Validate/convert a Double using the + * specified Locale. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Double if valid or null if invalid. + */ + public Double validate(final String value, final Locale locale) { + return (Double)parse(value, (String)null, locale); + } + + /** + *

    Validate/convert a Double using the + * specified pattern. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed BigDecimal if valid or null if invalid. + */ + public Double validate(final String value, final String pattern) { + return (Double)parse(value, pattern, (Locale)null); + } + + /** + *

    Validate/convert a Double using the + * specified pattern and/ or Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Double if valid or null if invalid. + */ + public Double validate(final String value, final String pattern, final Locale locale) { + return (Double)parse(value, pattern, locale); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java (.../EmailValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java (.../EmailValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -30,8 +30,7 @@ * This implementation is not guaranteed to catch all possible errors in an email address. *

    . * - * @version $Revision: 1723573 $ - * @since Validator 1.4 + * @since 1.4 */ public class EmailValidator implements Serializable { @@ -42,19 +41,16 @@ private static final String QUOTED_USER = "(\"(\\\\\"|[^\"])*\")"; private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")"; - private static final String EMAIL_REGEX = "^\\s*?(.+)@(.+?)\\s*$"; + private static final String EMAIL_REGEX = "^(.+)@(\\S+)$"; private static final String IP_DOMAIN_REGEX = "^\\[(.*)\\]$"; - private static final String USER_REGEX = "^\\s*" + WORD + "(\\." + WORD + ")*$"; + private static final String USER_REGEX = "^" + WORD + "(\\." + WORD + ")*$"; private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX); private static final Pattern IP_DOMAIN_PATTERN = Pattern.compile(IP_DOMAIN_REGEX); private static final Pattern USER_PATTERN = Pattern.compile(USER_REGEX); private static final int MAX_USERNAME_LEN = 64; - private final boolean allowLocal; - private final boolean allowTld; - /** * Singleton instance of this class, which * doesn't consider local addresses as valid. @@ -73,7 +69,6 @@ */ private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL = new EmailValidator(true, false); - /** * Singleton instance of this class, which does * consider local addresses valid. @@ -94,34 +89,44 @@ * with local validation as required. * * @param allowLocal Should local addresses be considered valid? + * @return singleton instance of this validator + */ + public static EmailValidator getInstance(final boolean allowLocal) { + return getInstance(allowLocal, false); + } + + /** + * Returns the Singleton instance of this validator, + * with local validation as required. + * + * @param allowLocal Should local addresses be considered valid? * @param allowTld Should TLDs be allowed? * @return singleton instance of this validator */ - public static EmailValidator getInstance(boolean allowLocal, boolean allowTld) { - if(allowLocal) { + public static EmailValidator getInstance(final boolean allowLocal, final boolean allowTld) { + if (allowLocal) { if (allowTld) { return EMAIL_VALIDATOR_WITH_LOCAL_WITH_TLD; - } else { - return EMAIL_VALIDATOR_WITH_LOCAL; } - } else { - if (allowTld) { - return EMAIL_VALIDATOR_WITH_TLD; - } else { - return EMAIL_VALIDATOR; - } + return EMAIL_VALIDATOR_WITH_LOCAL; } + if (allowTld) { + return EMAIL_VALIDATOR_WITH_TLD; + } + return EMAIL_VALIDATOR; } + private final boolean allowTld; + + private final DomainValidator domainValidator; + /** - * Returns the Singleton instance of this validator, - * with local validation as required. + * Protected constructor for subclasses to use. * * @param allowLocal Should local addresses be considered valid? - * @return singleton instance of this validator */ - public static EmailValidator getInstance(boolean allowLocal) { - return getInstance(allowLocal, false); + protected EmailValidator(final boolean allowLocal) { + this(allowLocal, false); } /** @@ -130,21 +135,29 @@ * @param allowLocal Should local addresses be considered valid? * @param allowTld Should TLDs be allowed? */ - protected EmailValidator(boolean allowLocal, boolean allowTld) { - super(); - this.allowLocal = allowLocal; + protected EmailValidator(final boolean allowLocal, final boolean allowTld) { this.allowTld = allowTld; + this.domainValidator = DomainValidator.getInstance(allowLocal); } /** - * Protected constructor for subclasses to use. + * constructor for creating instances with the specified domainValidator * * @param allowLocal Should local addresses be considered valid? + * @param allowTld Should TLDs be allowed? + * @param domainValidator allow override of the DomainValidator. + * The instance must have the same allowLocal setting. + * @since 1.7 */ - protected EmailValidator(boolean allowLocal) { - super(); - this.allowLocal = allowLocal; - this.allowTld = false; + public EmailValidator(final boolean allowLocal, final boolean allowTld, final DomainValidator domainValidator) { + this.allowTld = allowTld; + if (domainValidator == null) { + throw new IllegalArgumentException("DomainValidator cannot be null"); + } + if (domainValidator.isAllowLocal() != allowLocal) { + throw new IllegalArgumentException("DomainValidator must agree with allowLocal setting"); + } + this.domainValidator = domainValidator; } /** @@ -154,7 +167,7 @@ * value is considered invalid. * @return true if the email address is valid. */ - public boolean isValid(String email) { + public boolean isValid(final String email) { if (email == null) { return false; } @@ -164,7 +177,7 @@ } // Check the whole email address structure - Matcher emailMatcher = EMAIL_PATTERN.matcher(email); + final Matcher emailMatcher = EMAIL_PATTERN.matcher(email); if (!emailMatcher.matches()) { return false; } @@ -186,23 +199,20 @@ * @param domain being validated, may be in IDN format * @return true if the email address's domain is valid. */ - protected boolean isValidDomain(String domain) { + protected boolean isValidDomain(final String domain) { // see if domain is an IP address in brackets - Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); + final Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); if (ipDomainMatcher.matches()) { - InetAddressValidator inetAddressValidator = + final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); return inetAddressValidator.isValid(ipDomainMatcher.group(1)); } // Domain is symbolic name - DomainValidator domainValidator = - DomainValidator.getInstance(allowLocal); if (allowTld) { - return domainValidator.isValid(domain) || (!domain.startsWith(".") && domainValidator.isValidTld(domain)); - } else { - return domainValidator.isValid(domain); + return domainValidator.isValid(domain) || !domain.startsWith(".") && domainValidator.isValidTld(domain); } + return domainValidator.isValid(domain); } /** @@ -211,12 +221,12 @@ * @param user being validated * @return true if the user name is valid. */ - protected boolean isValidUser(String user) { - + protected boolean isValidUser(final String user) { + if (user == null || user.length() > MAX_USERNAME_LEN) { return false; } - + return USER_PATTERN.matcher(user).matches(); } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/FloatValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/FloatValidator.java (.../FloatValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/FloatValidator.java (.../FloatValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -59,8 +59,7 @@ *
  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class FloatValidator extends AbstractNumberValidator { @@ -77,7 +76,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public FloatValidator() { this(true, STANDARD_FORMAT); @@ -99,76 +98,26 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public FloatValidator(boolean strict, int formatType) { + public FloatValidator(final boolean strict, final int formatType) { super(strict, formatType, true); } /** - *

    Validate/convert a Float using the default - * Locale. - * - * @param value The value validation is being performed on. - * @return The parsed Float if valid or null - * if invalid. - */ - public Float validate(String value) { - return (Float)parse(value, (String)null, (Locale)null); - } - - /** - *

    Validate/convert a Float using the - * specified pattern. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Float if valid or null if invalid. - */ - public Float validate(String value, String pattern) { - return (Float)parse(value, pattern, (Locale)null); - } - - /** - *

    Validate/convert a Float using the - * specified Locale. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Float if valid or null if invalid. - */ - public Float validate(String value, Locale locale) { - return (Float)parse(value, (String)null, locale); - } - - /** - *

    Validate/convert a Float using the - * specified pattern and/ or Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Float if valid or null if invalid. - */ - public Float validate(String value, String pattern, Locale locale) { - return (Float)parse(value, pattern, locale); - } - - /** * Check if the value is within a specified range. * * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(float value, float min, float max) { - return (value >= min && value <= max); + public boolean isInRange(final float value, final float min, final float max) { + return value >= min && value <= max; } /** @@ -177,59 +126,59 @@ * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(Float value, float min, float max) { + public boolean isInRange(final Float value, final float min, final float max) { return isInRange(value.floatValue(), min, max); } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(float value, float min) { - return (value >= min); + public boolean maxValue(final float value, final float max) { + return value <= max; } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(Float value, float min) { - return minValue(value.floatValue(), min); + public boolean maxValue(final Float value, final float max) { + return maxValue(value.floatValue(), max); } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(float value, float max) { - return (value <= max); + public boolean minValue(final float value, final float min) { + return value >= min; } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(Float value, float max) { - return maxValue(value.floatValue(), max); + public boolean minValue(final Float value, final float min) { + return minValue(value.floatValue(), min); } /** @@ -242,9 +191,9 @@ * Float if valid or null if invalid. */ @Override - protected Object processParsedValue(Object value, Format formatter) { + protected Object processParsedValue(final Object value, final Format formatter) { - double doubleValue = ((Number)value).doubleValue(); + final double doubleValue = ((Number) value).doubleValue(); if (doubleValue > 0) { if (doubleValue < Float.MIN_VALUE) { @@ -253,8 +202,8 @@ if (doubleValue > Float.MAX_VALUE) { return null; } - } else if (doubleValue < 0){ - double posDouble = doubleValue * -1; + } else if (doubleValue < 0) { + final double posDouble = doubleValue * -1; if (posDouble < Float.MIN_VALUE) { return null; } @@ -263,8 +212,58 @@ } } - return new Float((float)doubleValue); + return Float.valueOf((float) doubleValue); } + /** + *

    Validate/convert a Float using the default + * Locale. + * + * @param value The value validation is being performed on. + * @return The parsed Float if valid or null + * if invalid. + */ + public Float validate(final String value) { + return (Float)parse(value, (String)null, (Locale)null); + } + + /** + *

    Validate/convert a Float using the + * specified Locale. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Float if valid or null if invalid. + */ + public Float validate(final String value, final Locale locale) { + return (Float)parse(value, (String)null, locale); + } + + /** + *

    Validate/convert a Float using the + * specified pattern. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed Float if valid or null if invalid. + */ + public Float validate(final String value, final String pattern) { + return (Float)parse(value, pattern, (Locale)null); + } + + /** + *

    Validate/convert a Float using the + * specified pattern and/ or Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Float if valid or null if invalid. + */ + public Float validate(final String value, final String pattern, final Locale locale) { + return (Float)parse(value, pattern, locale); + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java (.../IBANValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java (.../IBANValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,21 +16,40 @@ */ package org.apache.commons.validator.routines; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Map; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; -import org.apache.commons.validator.routines.RegexValidator; import org.apache.commons.validator.routines.checkdigit.IBANCheckDigit; /** * IBAN Validator. + *

    + * The validator includes a default set of formats derived from the IBAN registry at + * https://www.swift.com/standards/data-standards/iban. + *

    + *

    + * This can get out of date, but the set can be adjusted by creating a validator and using the + * {@link #setValidator(String, int, String)} or + * {@link #setValidator(Validator)} + * method to add (or remove) an entry. + *

    + *

    + * For example: + *

    + *
    + * IBANValidator ibv = new IBANValidator();
    + * ibv.setValidator("XX", 12, "XX\\d{10}")
    + * 
    + *

    + * The singleton default instance cannot be modified in this way. + *

    * @since 1.5.0 */ public class IBANValidator { - private final Map formatValidators; - /** * The validation class */ @@ -46,32 +65,148 @@ */ private static final int MIN_LEN = 8; private static final int MAX_LEN = 34; // defined by [3] + final String countryCode; - final RegexValidator validator; - final int lengthOfIBAN; // used to avoid unnecessary regex matching + final String[] otherCountryCodes; + final RegexValidator regexValidator; + final int ibanLength; // used to avoid unnecessary regex matching /** - * Creates the validator - * @param cc the country code - * @param len the length of the IBAN - * @param format the regex to use to check the format + * Creates the validator. + * @param countryCode the country code + * @param ibanLength the length of the IBAN + * @param regexWithCC the regex to use to check the format, the regex MUST start with the country code. */ - public Validator(String cc, int len, String format) { - if (!(cc.length() == 2 && Character.isUpperCase(cc.charAt(0)) && Character.isUpperCase(cc.charAt(1)))) { + public Validator(final String countryCode, final int ibanLength, final String regexWithCC) { + this(countryCode, ibanLength, regexWithCC.substring(countryCode.length()), new String[] {}); + } + + /** + * Creates the validator. + * @param countryCode the country code + * @param ibanLength the length of the IBAN + * @param regexWithoutCC the regex to use to check the format, the regex MUST NOT start with the country code. + */ + Validator(final String countryCode, final int ibanLength, final String regexWithoutCC, final String... otherCountryCodes) { + if (!(countryCode.length() == 2 && Character.isUpperCase(countryCode.charAt(0)) && Character.isUpperCase(countryCode.charAt(1)))) { throw new IllegalArgumentException("Invalid country Code; must be exactly 2 upper-case characters"); } - if (len > MAX_LEN || len < MIN_LEN) { - throw new IllegalArgumentException("Invalid length parameter, must be in range "+MIN_LEN+" to "+MAX_LEN+" inclusive: " +len); + if (ibanLength > MAX_LEN || ibanLength < MIN_LEN) { + throw new IllegalArgumentException("Invalid length parameter, must be in range " + MIN_LEN + " to " + MAX_LEN + " inclusive: " + ibanLength); } - if (!format.startsWith(cc)) { - throw new IllegalArgumentException("countryCode '"+cc+"' does not agree with format: " + format); + final String regex = countryCode + regexWithoutCC; + if (!regex.startsWith(countryCode)) { + throw new IllegalArgumentException("countryCode '" + countryCode + "' does not agree with format: " + regex); } - this.countryCode = cc; - this.lengthOfIBAN = len; - this.validator = new RegexValidator(format); + this.countryCode = countryCode; + this.otherCountryCodes = otherCountryCodes.clone(); + final List regexList = new ArrayList<>(this.otherCountryCodes.length + 1); + regexList.add(countryCode + regexWithoutCC); + for (String otherCc : otherCountryCodes) { + regexList.add(otherCc + regexWithoutCC); + } + this.ibanLength = ibanLength; + this.regexValidator = new RegexValidator(regexList); } + + /** + * Gets the RegexValidator. + * + * @return the RegexValidator. + * @since 1.8 + */ + public RegexValidator getRegexValidator() { + return regexValidator; + } } + private static final int SHORT_CODE_LEN = 2; + + private static final Validator[] DEFAULT_VALIDATORS = { // + new Validator("AD", 24, "AD\\d{10}[A-Z0-9]{12}"), // Andorra + new Validator("AE", 23, "AE\\d{21}"), // United Arab Emirates (The) + new Validator("AL", 28, "AL\\d{10}[A-Z0-9]{16}"), // Albania + new Validator("AT", 20, "AT\\d{18}"), // Austria + new Validator("AZ", 28, "AZ\\d{2}[A-Z]{4}[A-Z0-9]{20}"), // Azerbaijan + new Validator("BA", 20, "BA\\d{18}"), // Bosnia and Herzegovina + new Validator("BE", 16, "BE\\d{14}"), // Belgium + new Validator("BG", 22, "BG\\d{2}[A-Z]{4}\\d{6}[A-Z0-9]{8}"), // Bulgaria + new Validator("BH", 22, "BH\\d{2}[A-Z]{4}[A-Z0-9]{14}"), // Bahrain + new Validator("BI", 27, "BI\\d{25}"), // Burundi + new Validator("BR", 29, "BR\\d{25}[A-Z]{1}[A-Z0-9]{1}"), // Brazil + new Validator("BY", 28, "BY\\d{2}[A-Z0-9]{4}\\d{4}[A-Z0-9]{16}"), // Republic of Belarus + new Validator("CH", 21, "CH\\d{7}[A-Z0-9]{12}"), // Switzerland + new Validator("CR", 22, "CR\\d{20}"), // Costa Rica + new Validator("CY", 28, "CY\\d{10}[A-Z0-9]{16}"), // Cyprus + new Validator("CZ", 24, "CZ\\d{22}"), // Czechia + new Validator("DE", 22, "DE\\d{20}"), // Germany + new Validator("DJ", 27, "DJ\\d{25}"), // Djibouti + new Validator("DK", 18, "DK\\d{16}"), // Denmark + new Validator("DO", 28, "DO\\d{2}[A-Z0-9]{4}\\d{20}"), // Dominican Republic + new Validator("EE", 20, "EE\\d{18}"), // Estonia + new Validator("EG", 29, "EG\\d{27}"), // Egypt + new Validator("ES", 24, "ES\\d{22}"), // Spain + new Validator("FI", 18, "\\d{16}", "AX"), // Finland + new Validator("FO", 18, "FO\\d{16}"), // Faroe Islands + new Validator("FR", 27, "\\d{12}[A-Z0-9]{11}\\d{2}", "GF", "GP", "MQ", "RE", "PF", "TF", "YT", "NC", "BL", "MF", "PM", "WF"), // France + new Validator("GB", 22, "\\d{2}[A-Z]{4}\\d{14}", "IM", "JE", "GG"), // United Kingdom + new Validator("GE", 22, "GE\\d{2}[A-Z]{2}\\d{16}"), // Georgia + new Validator("GI", 23, "GI\\d{2}[A-Z]{4}[A-Z0-9]{15}"), // Gibraltar + new Validator("GL", 18, "GL\\d{16}"), // Greenland + new Validator("GR", 27, "GR\\d{9}[A-Z0-9]{16}"), // Greece + new Validator("GT", 28, "GT\\d{2}[A-Z0-9]{24}"), // Guatemala + new Validator("HR", 21, "HR\\d{19}"), // Croatia + new Validator("HU", 28, "HU\\d{26}"), // Hungary + new Validator("IE", 22, "IE\\d{2}[A-Z]{4}\\d{14}"), // Ireland + new Validator("IL", 23, "IL\\d{21}"), // Israel + new Validator("IQ", 23, "IQ\\d{2}[A-Z]{4}\\d{15}"), // Iraq + new Validator("IS", 26, "IS\\d{24}"), // Iceland + new Validator("IT", 27, "IT\\d{2}[A-Z]{1}\\d{10}[A-Z0-9]{12}"), // Italy + new Validator("JO", 30, "JO\\d{2}[A-Z]{4}\\d{4}[A-Z0-9]{18}"), // Jordan + new Validator("KW", 30, "KW\\d{2}[A-Z]{4}[A-Z0-9]{22}"), // Kuwait + new Validator("KZ", 20, "KZ\\d{5}[A-Z0-9]{13}"), // Kazakhstan + new Validator("LB", 28, "LB\\d{6}[A-Z0-9]{20}"), // Lebanon + new Validator("LC", 32, "LC\\d{2}[A-Z]{4}[A-Z0-9]{24}"), // Saint Lucia + new Validator("LI", 21, "LI\\d{7}[A-Z0-9]{12}"), // Liechtenstein + new Validator("LT", 20, "LT\\d{18}"), // Lithuania + new Validator("LU", 20, "LU\\d{5}[A-Z0-9]{13}"), // Luxembourg + new Validator("LV", 21, "LV\\d{2}[A-Z]{4}[A-Z0-9]{13}"), // Latvia + new Validator("LY", 25, "LY\\d{23}"), // Libya + new Validator("MC", 27, "MC\\d{12}[A-Z0-9]{11}\\d{2}"), // Monaco + new Validator("MD", 24, "MD\\d{2}[A-Z0-9]{20}"), // Moldova + new Validator("ME", 22, "ME\\d{20}"), // Montenegro + new Validator("MK", 19, "MK\\d{5}[A-Z0-9]{10}\\d{2}"), // Macedonia + new Validator("MR", 27, "MR\\d{25}"), // Mauritania + new Validator("MT", 31, "MT\\d{2}[A-Z]{4}\\d{5}[A-Z0-9]{18}"), // Malta + new Validator("MU", 30, "MU\\d{2}[A-Z]{4}\\d{19}[A-Z]{3}"), // Mauritius + new Validator("NL", 18, "NL\\d{2}[A-Z]{4}\\d{10}"), // Netherlands (The) + new Validator("NO", 15, "NO\\d{13}"), // Norway + new Validator("PK", 24, "PK\\d{2}[A-Z]{4}[A-Z0-9]{16}"), // Pakistan + new Validator("PL", 28, "PL\\d{26}"), // Poland + new Validator("PS", 29, "PS\\d{2}[A-Z]{4}[A-Z0-9]{21}"), // Palestine, State of + new Validator("PT", 25, "PT\\d{23}"), // Portugal + new Validator("QA", 29, "QA\\d{2}[A-Z]{4}[A-Z0-9]{21}"), // Qatar + new Validator("RO", 24, "RO\\d{2}[A-Z]{4}[A-Z0-9]{16}"), // Romania + new Validator("RS", 22, "RS\\d{20}"), // Serbia + new Validator("RU", 33, "RU\\d{31}"), // Russia + new Validator("SA", 24, "SA\\d{4}[A-Z0-9]{18}"), // Saudi Arabia + new Validator("SC", 31, "SC\\d{2}[A-Z]{4}\\d{20}[A-Z]{3}"), // Seychelles + new Validator("SD", 18, "SD\\d{16}"), // Sudan + new Validator("SE", 24, "SE\\d{22}"), // Sweden + new Validator("SI", 19, "SI\\d{17}"), // Slovenia + new Validator("SK", 24, "SK\\d{22}"), // Slovakia + new Validator("SM", 27, "SM\\d{2}[A-Z]{1}\\d{10}[A-Z0-9]{12}"), // San Marino + new Validator("ST", 25, "ST\\d{23}"), // Sao Tome and Principe + new Validator("SV", 28, "SV\\d{2}[A-Z]{4}\\d{20}"), // El Salvador + new Validator("TL", 23, "TL\\d{21}"), // Timor-Leste + new Validator("TN", 24, "TN\\d{22}"), // Tunisia + new Validator("TR", 26, "TR\\d{8}[A-Z0-9]{16}"), // Turkey + new Validator("UA", 29, "UA\\d{8}[A-Z0-9]{19}"), // Ukraine + new Validator("VA", 22, "VA\\d{20}"), // Vatican City State + new Validator("VG", 24, "VG\\d{2}[A-Z]{4}\\d{16}"), // Virgin Islands + new Validator("XK", 20, "XK\\d{18}"), // Kosovo + }; + /* * Wikipedia [1] says that only uppercase is allowed. * The SWIFT PDF file [2] implies that lower case is allowed. @@ -89,135 +224,80 @@ * upper case for IBANs. * * [1] https://en.wikipedia.org/wiki/International_Bank_Account_Number - * [2] http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf + * [2] http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf (404) + * => https://www.swift.com/sites/default/files/resources/iban_registry.pdf + * The above is an old version (62, Jan 2016) + * As of May 2020, the current IBAN standards are located at: + * https://www.swift.com/standards/data-standards/iban + * The above page contains links for the PDF and TXT (CSV) versions of the registry + * Warning: these may not agree -- in the past there have been discrepancies. + * The TXT file can be used to determine changes which can be cross-checked in the PDF file. * [3] http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf */ - - private static final Validator[] DEFAULT_FORMATS = { - new Validator("AD", 24, "AD\\d{10}[A-Z0-9]{12}" ), // Andorra - new Validator("AE", 23, "AE\\d{21}" ), // United Arab Emirates - new Validator("AL", 28, "AL\\d{10}[A-Z0-9]{16}" ), // Albania - new Validator("AT", 20, "AT\\d{18}" ), // Austria - new Validator("AZ", 28, "AZ\\d{2}[A-Z]{4}[A-Z0-9]{20}" ), // Republic of Azerbaijan - new Validator("BA", 20, "BA\\d{18}" ), // Bosnia and Herzegovina - new Validator("BE", 16, "BE\\d{14}" ), // Belgium - new Validator("BG", 22, "BG\\d{2}[A-Z]{4}\\d{6}[A-Z0-9]{8}" ), // Bulgaria - new Validator("BH", 22, "BH\\d{2}[A-Z]{4}[A-Z0-9]{14}" ), // Bahrain (Kingdom of) - new Validator("BR", 29, "BR\\d{25}[A-Z]{1}[A-Z0-9]{1}" ), // Brazil - new Validator("BY", 28, "BY\\d{2}[A-Z0-9]{4}\\d{4}[A-Z0-9]{16}" ), // Republic of Belarus - new Validator("CH", 21, "CH\\d{7}[A-Z0-9]{12}" ), // Switzerland - new Validator("CR", 22, "CR\\d{20}" ), // Costa Rica - new Validator("CY", 28, "CY\\d{10}[A-Z0-9]{16}" ), // Cyprus - new Validator("CZ", 24, "CZ\\d{22}" ), // Czech Republic - new Validator("DE", 22, "DE\\d{20}" ), // Germany - new Validator("DK", 18, "DK\\d{16}" ), // Denmark - new Validator("DO", 28, "DO\\d{2}[A-Z0-9]{4}\\d{20}" ), // Dominican Republic - new Validator("EE", 20, "EE\\d{18}" ), // Estonia - new Validator("ES", 24, "ES\\d{22}" ), // Spain - new Validator("FI", 18, "FI\\d{16}" ), // Finland - new Validator("FO", 18, "FO\\d{16}" ), // Denmark (Faroes) - new Validator("FR", 27, "FR\\d{12}[A-Z0-9]{11}\\d{2}" ), // France - new Validator("GB", 22, "GB\\d{2}[A-Z]{4}\\d{14}" ), // United Kingdom - new Validator("GE", 22, "GE\\d{2}[A-Z]{2}\\d{16}" ), // Georgia - new Validator("GI", 23, "GI\\d{2}[A-Z]{4}[A-Z0-9]{15}" ), // Gibraltar - new Validator("GL", 18, "GL\\d{16}" ), // Denmark (Greenland) - new Validator("GR", 27, "GR\\d{9}[A-Z0-9]{16}" ), // Greece - new Validator("GT", 28, "GT\\d{2}[A-Z0-9]{24}" ), // Guatemala - new Validator("HR", 21, "HR\\d{19}" ), // Croatia - new Validator("HU", 28, "HU\\d{26}" ), // Hungary - new Validator("IE", 22, "IE\\d{2}[A-Z]{4}\\d{14}" ), // Ireland - new Validator("IL", 23, "IL\\d{21}" ), // Israel - new Validator("IS", 26, "IS\\d{24}" ), // Iceland - new Validator("IT", 27, "IT\\d{2}[A-Z]{1}\\d{10}[A-Z0-9]{12}" ), // Italy - new Validator("IQ", 23, "IQ\\d{2}[A-Z]{4}\\d{15}" ), // Iraq - new Validator("JO", 30, "JO\\d{2}[A-Z]{4}\\d{4}[A-Z0-9]{18}" ), // Jordan - new Validator("KW", 30, "KW\\d{2}[A-Z]{4}[A-Z0-9]{22}" ), // Kuwait - new Validator("KZ", 20, "KZ\\d{5}[A-Z0-9]{13}" ), // Kazakhstan - new Validator("LB", 28, "LB\\d{6}[A-Z0-9]{20}" ), // Lebanon - new Validator("LC", 32, "LC\\d{2}[A-Z]{4}[A-Z0-9]{24}" ), // Saint Lucia - new Validator("LI", 21, "LI\\d{7}[A-Z0-9]{12}" ), // Liechtenstein (Principality of) - new Validator("LT", 20, "LT\\d{18}" ), // Lithuania - new Validator("LU", 20, "LU\\d{5}[A-Z0-9]{13}" ), // Luxembourg - new Validator("LV", 21, "LV\\d{2}[A-Z]{4}[A-Z0-9]{13}" ), // Latvia - new Validator("MC", 27, "MC\\d{12}[A-Z0-9]{11}\\d{2}" ), // Monaco - new Validator("MD", 24, "MD\\d{2}[A-Z0-9]{20}" ), // Moldova - new Validator("ME", 22, "ME\\d{20}" ), // Montenegro - new Validator("MK", 19, "MK\\d{5}[A-Z0-9]{10}\\d{2}" ), // Macedonia, Former Yugoslav Republic of - new Validator("MR", 27, "MR\\d{25}" ), // Mauritania - new Validator("MT", 31, "MT\\d{2}[A-Z]{4}\\d{5}[A-Z0-9]{18}" ), // Malta - new Validator("MU", 30, "MU\\d{2}[A-Z]{4}\\d{19}[A-Z]{3}" ), // Mauritius - new Validator("NL", 18, "NL\\d{2}[A-Z]{4}\\d{10}" ), // The Netherlands - new Validator("NO", 15, "NO\\d{13}" ), // Norway - new Validator("PK", 24, "PK\\d{2}[A-Z]{4}[A-Z0-9]{16}" ), // Pakistan - new Validator("PL", 28, "PL\\d{26}" ), // Poland - new Validator("PS", 29, "PS\\d{2}[A-Z]{4}[A-Z0-9]{21}" ), // Palestine, State of - new Validator("PT", 25, "PT\\d{23}" ), // Portugal - new Validator("QA", 29, "QA\\d{2}[A-Z]{4}[A-Z0-9]{21}" ), // Qatar - new Validator("RO", 24, "RO\\d{2}[A-Z]{4}[A-Z0-9]{16}" ), // Romania - new Validator("RS", 22, "RS\\d{20}" ), // Serbia - new Validator("SA", 24, "SA\\d{4}[A-Z0-9]{18}" ), // Saudi Arabia - new Validator("SC", 31, "SC\\d{2}[A-Z]{4}\\d{20}[A-Z]{3}" ), // Seychelles - new Validator("SE", 24, "SE\\d{22}" ), // Sweden - new Validator("SI", 19, "SI\\d{17}" ), // Slovenia - new Validator("SK", 24, "SK\\d{22}" ), // Slovak Republic - new Validator("SM", 27, "SM\\d{2}[A-Z]{1}\\d{10}[A-Z0-9]{12}" ), // San Marino - new Validator("ST", 25, "ST\\d{23}" ), // Sao Tome and Principe - new Validator("TL", 23, "TL\\d{21}" ), // Timor-Leste - new Validator("TN", 24, "TN\\d{22}" ), // Tunisia - new Validator("TR", 26, "TR\\d{8}[A-Z0-9]{16}" ), // Turkey - new Validator("UA", 29, "UA\\d{8}[A-Z0-9]{19}" ), // Ukraine - new Validator("VG", 24, "VG\\d{2}[A-Z]{4}\\d{16}" ), // Virgin Islands, British - new Validator("XK", 20, "XK\\d{18}" ), // Republic of Kosovo - }; /** The singleton instance which uses the default formats */ public static final IBANValidator DEFAULT_IBAN_VALIDATOR = new IBANValidator(); /** * Return a singleton instance of the IBAN validator using the default formats * - * @return A singleton instance of the ISBN validator + * @return A singleton instance of the IBAN validator */ public static IBANValidator getInstance() { return DEFAULT_IBAN_VALIDATOR; } + private final ConcurrentMap validatorMap; + /** * Create a default IBAN validator. */ public IBANValidator() { - this(DEFAULT_FORMATS); + this(DEFAULT_VALIDATORS); } /** * Create an IBAN validator from the specified map of IBAN formats. * - * @param formatMap map of IBAN formats + * @param validators map of IBAN formats */ - public IBANValidator(Validator[] formatMap) { - this.formatValidators = createValidators(formatMap); + public IBANValidator(final Validator[] validators) { + this.validatorMap = createValidators(validators); } - private Map createValidators(Validator[] formatMap) { - Map m = new ConcurrentHashMap(); - for(Validator v : formatMap) { - m.put(v.countryCode, v); + private ConcurrentMap createValidators(final Validator[] validators) { + final ConcurrentMap map = new ConcurrentHashMap<>(); + for (final Validator validator : validators) { + map.put(validator.countryCode, validator); + for (String otherCC : validator.otherCountryCodes) { + map.put(otherCC, validator); + } } - return m; + return map; } /** - * Validate an IBAN Code + * Gets a copy of the default Validators. * - * @param code The value validation is being performed on - * @return true if the value is valid + * @return a copy of the default Validator array */ - public boolean isValid(String code) { - Validator formatValidator = getValidator(code); - if (formatValidator == null || code.length() != formatValidator.lengthOfIBAN || !formatValidator.validator.isValid(code)) { - return false; + public Validator[] getDefaultValidators() { + return Arrays.copyOf(DEFAULT_VALIDATORS, DEFAULT_VALIDATORS.length); + } + + /** + * Gets the Validator for a given IBAN + * + * @param code a string starting with the ISO country code (e.g. an IBAN) + * + * @return the validator or {@code null} if there is not one registered. + */ + public Validator getValidator(final String code) { + if (code == null || code.length() < SHORT_CODE_LEN) { // ensure we can extract the code + return null; } - return IBANCheckDigit.IBAN_CHECK_DIGIT.isValid(code); + final String key = code.substring(0, SHORT_CODE_LEN); + return validatorMap.get(key); } /** @@ -226,68 +306,58 @@ * @param code the code to check * @return true if there is a validator */ - public boolean hasValidator(String code) { + public boolean hasValidator(final String code) { return getValidator(code) != null; } /** - * Gets a copy of the default Validators. - * - * @return a copy of the default Validator array + * Validate an IBAN Code + * + * @param code The value validation is being performed on + * @return {@code true} if the value is valid */ - public Validator[] getDefaultValidators() { - return Arrays.copyOf(DEFAULT_FORMATS, DEFAULT_FORMATS.length); - } - - /** - * Get the Validator for a given IBAN - * - * @param code a string starting with the ISO country code (e.g. an IBAN) - * - * @return the validator or {@code null} if there is not one registered. - */ - public Validator getValidator(String code) { - if (code == null || code.length() < 2) { // ensure we can extract the code - return null; + public boolean isValid(final String code) { + final Validator formatValidator = getValidator(code); + if (formatValidator == null || code.length() != formatValidator.ibanLength || !formatValidator.regexValidator.isValid(code)) { + return false; } - String key = code.substring(0, 2); - return formatValidators.get(key); + return IBANCheckDigit.IBAN_CHECK_DIGIT.isValid(code); } /** * Installs a validator. - * Will replace any existing entry which has the same countryCode - * - * @param validator the instance to install. + * Will replace any existing entry which has the same countryCode. + * + * @param countryCode the country code + * @param length the length of the IBAN. Must be ≥ 8 and ≤ 32. + * If the length is < 0, the validator is removed, and the format is not used. + * @param format the format of the IBAN (as a regular expression) * @return the previous Validator, or {@code null} if there was none + * @throws IllegalArgumentException if there is a problem * @throws IllegalStateException if an attempt is made to modify the singleton validator */ - public Validator setValidator(Validator validator) { + public Validator setValidator(final String countryCode, final int length, final String format) { if (this == DEFAULT_IBAN_VALIDATOR) { throw new IllegalStateException("The singleton validator cannot be modified"); } - return formatValidators.put(validator.countryCode, validator); + if (length < 0) { + return validatorMap.remove(countryCode); + } + return setValidator(new Validator(countryCode, length, format)); } /** * Installs a validator. - * Will replace any existing entry which has the same countryCode. - * - * @param countryCode the country code - * @param length the length of the IBAN. Must be ≥ 8 and ≤ 32. - * If the length is < 0, the validator is removed, and the format is not used. - * @param format the format of the IBAN (as a regular expression) + * Will replace any existing entry which has the same countryCode + * + * @param validator the instance to install. * @return the previous Validator, or {@code null} if there was none - * @throws IllegalArgumentException if there is a problem * @throws IllegalStateException if an attempt is made to modify the singleton validator */ - public Validator setValidator(String countryCode, int length, String format) { + public Validator setValidator(final Validator validator) { if (this == DEFAULT_IBAN_VALIDATOR) { throw new IllegalStateException("The singleton validator cannot be modified"); } - if (length < 0) { - return formatValidators.remove(countryCode); - } - return setValidator(new Validator(countryCode, length, format)); + return validatorMap.put(validator.countryCode, validator); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java (.../ISBNValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java (.../ISBNValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -17,9 +17,10 @@ package org.apache.commons.validator.routines; import java.io.Serializable; + +import org.apache.commons.validator.routines.checkdigit.CheckDigitException; import org.apache.commons.validator.routines.checkdigit.EAN13CheckDigit; import org.apache.commons.validator.routines.checkdigit.ISBN10CheckDigit; -import org.apache.commons.validator.routines.checkdigit.CheckDigitException; /** * ISBN-10 and ISBN-13 Code Validation. @@ -33,7 +34,7 @@ * characters removed if valid or null if invalid. *

    * This validator also provides the facility to convert ISBN-10 codes to - * ISBN-13 if the convert property is true. + * ISBN-13 if the convert property is {@code true}. *

    * From 1st January 2007 the book industry will start to use a new 13 digit * ISBN number (rather than this 10 digit ISBN number). ISBN-13 codes are @@ -50,8 +51,18 @@ * Transition details. * * - * @version $Revision: 1715435 $ - * @since Validator 1.4 + *

    ISBN-13s are either prefixed with 978 or 979. 978 prefixes are only assigned + * to the ISBN agency. 979 prefixes may be assigned to ISBNs or ISMNs + * (International + * Standard Music Numbers). + *

      + *
    • 979-0 are assigned to the ISMN agency
    • + *
    • 979-10, 979-11, 979-12 are assigned to the ISBN agency
    • + *
    + * All other 979 prefixed EAN-13 numbers have not yet been assigned to an agency. The + * validator validates all 13 digit codes with 978 or 979 prefixes. + * + * @since 1.4 */ public class ISBNValidator implements Serializable { @@ -69,32 +80,21 @@ * or spaces. The first group is 1-5 characters, second 1-7, third 1-6, * and fourth is 1 digit or an X. */ - static final String ISBN10_REGEX = - "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9X])))$"; + static final String ISBN10_REGEX = "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9X])))$"; /** * ISBN-13 consists of 5 groups of numbers separated by either dashes (-) * or spaces. The first group is 978 or 979, the second group is * 1-5 characters, third 1-7, fourth 1-6, and fifth is 1 digit. */ - static final String ISBN13_REGEX = - "^(978|979)(?:(\\d{10})|(?:" + SEP + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9])))$"; + static final String ISBN13_REGEX = "^(978|979)(?:(\\d{10})|(?:" + SEP + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9])))$"; /** ISBN Code Validator (which converts ISBN-10 codes to ISBN-13 */ private static final ISBNValidator ISBN_VALIDATOR = new ISBNValidator(); /** ISBN Code Validator (which converts ISBN-10 codes to ISBN-13 */ private static final ISBNValidator ISBN_VALIDATOR_NO_CONVERT = new ISBNValidator(false); - - /** ISBN-10 Code Validator */ - private final CodeValidator isbn10Validator = new CodeValidator(ISBN10_REGEX, 10, ISBN10CheckDigit.ISBN10_CHECK_DIGIT); - - /** ISBN-13 Code Validator */ - private final CodeValidator isbn13Validator = new CodeValidator(ISBN13_REGEX, 13, EAN13CheckDigit.EAN13_CHECK_DIGIT); - - private final boolean convert; - /** * Return a singleton instance of the ISBN validator which * converts ISBN-10 codes to ISBN-13. @@ -109,65 +109,106 @@ * Return a singleton instance of the ISBN validator specifying * whether ISBN-10 codes should be converted to ISBN-13. * - * @param convert true if valid ISBN-10 codes - * should be converted to ISBN-13 codes or false + * @param convert {@code true} if valid ISBN-10 codes + * should be converted to ISBN-13 codes or {@code false} * if valid ISBN-10 codes should be returned unchanged. * @return A singleton instance of the ISBN validator. */ - public static ISBNValidator getInstance(boolean convert) { - return (convert ? ISBN_VALIDATOR : ISBN_VALIDATOR_NO_CONVERT); + public static ISBNValidator getInstance(final boolean convert) { + return convert ? ISBN_VALIDATOR : ISBN_VALIDATOR_NO_CONVERT; } + /** ISBN-10 Code Validator */ + private final CodeValidator isbn10Validator = new CodeValidator(ISBN10_REGEX, 10, ISBN10CheckDigit.ISBN10_CHECK_DIGIT); + + /** ISBN-13 Code Validator */ + private final CodeValidator isbn13Validator = new CodeValidator(ISBN13_REGEX, 13, EAN13CheckDigit.EAN13_CHECK_DIGIT); + + private final boolean convert; + /** - * Construct an ISBN validator which converts ISBN-10 codes + * Constructs an ISBN validator which converts ISBN-10 codes * to ISBN-13. */ public ISBNValidator() { this(true); } /** - * Construct an ISBN validator indicating whether + * Constructs an ISBN validator indicating whether * ISBN-10 codes should be converted to ISBN-13. * - * @param convert true if valid ISBN-10 codes - * should be converted to ISBN-13 codes or false + * @param convert {@code true} if valid ISBN-10 codes + * should be converted to ISBN-13 codes or {@code false} * if valid ISBN-10 codes should be returned unchanged. */ - public ISBNValidator(boolean convert) { + public ISBNValidator(final boolean convert) { this.convert = convert; } /** + * Convert an ISBN-10 code to an ISBN-13 code. + *

    + * This method requires a valid ISBN-10 with NO formatting + * characters. + * + * @param isbn10 The ISBN-10 code to convert + * @return A converted ISBN-13 code or null + * if the ISBN-10 code is not valid + */ + public String convertToISBN13(final String isbn10) { + + if (isbn10 == null) { + return null; + } + + final String input = isbn10.trim(); + if (input.length() != ISBN_10_LEN) { + throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'"); + } + + // Calculate the new ISBN-13 code (drop the original checkdigit) + String isbn13 = "978" + input.substring(0, ISBN_10_LEN - 1); + try { + final String checkDigit = isbn13Validator.getCheckDigit().calculate(isbn13); + isbn13 += checkDigit; + return isbn13; + } catch (final CheckDigitException e) { + throw new IllegalArgumentException("Check digit error for '" + input + "' - " + e.getMessage()); + } + + } + + /** * Check the code is either a valid ISBN-10 or ISBN-13 code. * * @param code The code to validate. - * @return true if a valid ISBN-10 or - * ISBN-13 code, otherwise false. + * @return {@code true} if a valid ISBN-10 or + * ISBN-13 code, otherwise {@code false}. */ - public boolean isValid(String code) { - return (isValidISBN13(code) || isValidISBN10(code)); + public boolean isValid(final String code) { + return isValidISBN13(code) || isValidISBN10(code); } /** * Check the code is a valid ISBN-10 code. * * @param code The code to validate. - * @return true if a valid ISBN-10 - * code, otherwise false. + * @return {@code true} if a valid ISBN-10 + * code, otherwise {@code false}. */ - public boolean isValidISBN10(String code) { + public boolean isValidISBN10(final String code) { return isbn10Validator.isValid(code); } /** * Check the code is a valid ISBN-13 code. * * @param code The code to validate. - * @return true if a valid ISBN-13 - * code, otherwise false. + * @return {@code true} if a valid ISBN-13 + * code, otherwise {@code false}. */ - public boolean isValidISBN13(String code) { + public boolean isValidISBN13(final String code) { return isbn13Validator.isValid(code); } @@ -178,12 +219,12 @@ * formatting characters removed (i.e. space or hyphen). *

    * Converts an ISBN-10 codes to ISBN-13 if - * convertToISBN13 is true. + * convertToISBN13 is {@code true}. * * @param code The code to validate. * @return A valid ISBN code if valid, otherwise null. */ - public String validate(String code) { + public String validate(final String code) { String result = validateISBN13(code); if (result == null) { result = validateISBN10(code); @@ -204,9 +245,9 @@ * @return A valid ISBN-10 code if valid, * otherwise null. */ - public String validateISBN10(String code) { - Object result = isbn10Validator.validate(code); - return (result == null ? null : result.toString()); + public String validateISBN10(final String code) { + final Object result = isbn10Validator.validate(code); + return result == null ? null : result.toString(); } /** @@ -219,42 +260,9 @@ * @return A valid ISBN-13 code if valid, * otherwise null. */ - public String validateISBN13(String code) { - Object result = isbn13Validator.validate(code); - return (result == null ? null : result.toString()); + public String validateISBN13(final String code) { + final Object result = isbn13Validator.validate(code); + return result == null ? null : result.toString(); } - /** - * Convert an ISBN-10 code to an ISBN-13 code. - *

    - * This method requires a valid ISBN-10 with NO formatting - * characters. - * - * @param isbn10 The ISBN-10 code to convert - * @return A converted ISBN-13 code or null - * if the ISBN-10 code is not valid - */ - public String convertToISBN13(String isbn10) { - - if (isbn10 == null) { - return null; - } - - String input = isbn10.trim(); - if (input.length() != ISBN_10_LEN) { - throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'"); - } - - // Calculate the new ISBN-13 code (drop the original checkdigit) - String isbn13 = "978" + input.substring(0, ISBN_10_LEN - 1); - try { - String checkDigit = isbn13Validator.getCheckDigit().calculate(isbn13); - isbn13 += checkDigit; - return isbn13; - } catch (CheckDigitException e) { - throw new IllegalArgumentException("Check digit error for '" + input + "' - " + e.getMessage()); - } - - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISINValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISINValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISINValidator.java (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.validator.routines; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Locale; + +import org.apache.commons.validator.routines.checkdigit.ISINCheckDigit; + +/** + * ISIN (International Securities Identifying Number) validation. + * + *

    + * ISIN Numbers are 12 character alphanumeric codes used to identify Securities. + *

    + * + *

    + * ISINs consist of two alphabetic characters, + * which are the ISO 3166-1 alpha-2 code for the issuing country, + * nine alpha-numeric characters (the National Securities Identifying Number, or NSIN, which identifies the security), + * and one numerical check digit. + * They are 12 characters in length. + *

    + * + *

    + * See Wikipedia - ISIN + * for more details. + *

    + * + * @since 1.7 + */ +public class ISINValidator implements Serializable { + + private static final long serialVersionUID = -5964391439144260936L; + + private static final String ISIN_REGEX = "([A-Z]{2}[A-Z0-9]{9}[0-9])"; + + private static final CodeValidator VALIDATOR = new CodeValidator(ISIN_REGEX, 12, ISINCheckDigit.ISIN_CHECK_DIGIT); + + /** ISIN Code Validator (no countryCode check) */ + private static final ISINValidator ISIN_VALIDATOR_FALSE = new ISINValidator(false); + + /** ISIN Code Validator (with countryCode check) */ + private static final ISINValidator ISIN_VALIDATOR_TRUE = new ISINValidator(true); + + private static final String [] CCODES = Locale.getISOCountries(); + + private static final String [] SPECIALS = { + "EZ", // http://www.anna-web.org/standards/isin-iso-6166/ + "XS", // https://www.isin.org/isin/ + }; + + static { + Arrays.sort(CCODES); // we cannot assume the codes are sorted + Arrays.sort(SPECIALS); // Just in case ... + } + + /** + * Return a singleton instance of the ISIN validator + * @param checkCountryCode whether to check the country-code prefix or not + * @return A singleton instance of the appropriate ISIN validator. + */ + public static ISINValidator getInstance(final boolean checkCountryCode) { + return checkCountryCode ? ISIN_VALIDATOR_TRUE : ISIN_VALIDATOR_FALSE; + } + + private final boolean checkCountryCode; + + private ISINValidator(final boolean checkCountryCode) { + this.checkCountryCode = checkCountryCode; + } + + private boolean checkCode(final String code) { + return Arrays.binarySearch(CCODES, code) >= 0 + || + Arrays.binarySearch(SPECIALS, code) >= 0 + ; + } + + /** + * Check the code is a valid ISIN code after any transformation + * by the validate routine. + * @param code The code to validate. + * @return {@code true} if a valid ISIN + * code, otherwise {@code false}. + */ + public boolean isValid(final String code) { + final boolean valid = VALIDATOR.isValid(code); + if (valid && checkCountryCode) { + return checkCode(code.substring(0,2)); + } + return valid; + } + + /** + * Check the code is valid ISIN code. + * + * @param code The code to validate. + * @return A valid ISIN code if valid, otherwise null. + */ + public Object validate(final String code) { + final Object validate = VALIDATOR.validate(code); + if (validate != null && checkCountryCode) { + return checkCode(code.substring(0,2)) ? validate : null; + } + return validate; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISSNValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISSNValidator.java (.../ISSNValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISSNValidator.java (.../ISSNValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -28,15 +28,15 @@ * uniquely identify a serial publication. *
      * The format is:
    - * 
    + *
      * ISSN dddd-dddC
      * where:
      * d = decimal digit (0-9)
      * C = checksum (0-9 or X)
    - * 
    + *
      * The checksum is formed by adding the first 7 digits multiplied by
      * the position in the entire number (counting from the right).
    - * 
    + *
      * For example, abcd-efg would be 8a + 7b + 6c + 5d + 4e +3f +2g.
      * The check digit is modulus 11, where the value 10 is represented by 'X'
      * For example:
    @@ -45,15 +45,15 @@
      *
      * This class strips off the 'ISSN ' prefix if it is present before passing
      * the remainder to the checksum routine.
    - * 
    + *
      * 
    *

    * Note: the {@link #isValid(String)} and {@link #validate(String)} methods strip off any leading * or trailing spaces before doing the validation. * To ensure that only a valid code (without 'ISSN ' prefix) is passed to a method, * use the following code: *

    - * Object valid = validator.validate(input); 
    + * Object valid = validator.validate(input);
      * if (valid != null) {
      *    some_method(valid.toString());
      * }
    @@ -66,8 +66,18 @@
     
         private static final String ISSN_REGEX = "(?:ISSN )?(\\d{4})-(\\d{3}[0-9X])$"; // We don't include the '-' in the code, so it is 8 chars
     
    -    private static final CodeValidator VALIDATOR = new CodeValidator(ISSN_REGEX, 8, ISSNCheckDigit.ISSN_CHECK_DIGIT);
    +    private static final int ISSN_LEN = 8;
     
    +    private static final String ISSN_PREFIX = "977";
    +
    +    private static final String EAN_ISSN_REGEX = "^(977)(?:(\\d{10}))$";
    +
    +    private static final int EAN_ISSN_LEN = 13;
    +
    +    private static final CodeValidator VALIDATOR = new CodeValidator(ISSN_REGEX, ISSN_LEN, ISSNCheckDigit.ISSN_CHECK_DIGIT);
    +
    +    private static final CodeValidator EAN_VALIDATOR = new CodeValidator(EAN_ISSN_REGEX, EAN_ISSN_LEN, EAN13CheckDigit.EAN13_CHECK_DIGIT);
    +
         /** ISSN Code Validator */
         private static final ISSNValidator ISSN_VALIDATOR = new ISSNValidator();
     
    @@ -81,30 +91,6 @@
         }
     
         /**
    -     * Check the code is a valid ISSN code after any transformation
    -     * by the validate routine.
    -     * @param code The code to validate.
    -     * @return true if a valid ISSN
    -     * code, otherwise false.
    -     */
    -    public boolean isValid(String code) {
    -        return VALIDATOR.isValid(code);
    -    }
    -
    -    /**
    -     * Check the code is valid ISSN code.
    -     * 

    - * If valid, this method returns the ISSN code with - * the 'ISSN ' prefix removed (if it was present) - * - * @param code The code to validate. - * @return A valid ISSN code if valid, otherwise null. - */ - public Object validate(String code) { - return VALIDATOR.validate(code); - } - - /** * Convert an ISSN code to an EAN-13 code. *

    * This method requires a valid ISSN code. @@ -113,31 +99,106 @@ * method. * * @param issn The ISSN code to convert - * @param suffix the two digit suffix, e.g. "00" + * @param suffix the two digit suffix, e.g. "00" * @return A converted EAN-13 code or null * if the input ISSN code is not valid */ - public String convertToEAN13(String issn, String suffix) { + public String convertToEAN13(final String issn, final String suffix) { if (suffix == null || !suffix.matches("\\d\\d")) { - throw new IllegalArgumentException("Suffix must be two digits: '" + suffix + "'"); + throw new IllegalArgumentException("Suffix must be two digits: '" + suffix + "'"); } - Object result = validate(issn); + final Object result = validate(issn); if (result == null) { return null; } // Calculate the new EAN-13 code final String input = result.toString(); - String ean13 = "977" + input.substring(0, input.length() -1) + suffix; + String ean13 = ISSN_PREFIX + input.substring(0, input.length() - 1) + suffix; try { - String checkDigit = EAN13CheckDigit.EAN13_CHECK_DIGIT.calculate(ean13); + final String checkDigit = EAN13CheckDigit.EAN13_CHECK_DIGIT.calculate(ean13); ean13 += checkDigit; return ean13; - } catch (CheckDigitException e) { // Should not happen + } catch (final CheckDigitException e) { // Should not happen throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage()); } } + + /** + * Extract an ISSN code from an ISSN-EAN-13 code. + *

    + * This method requires a valid ISSN-EAN-13 code with NO formatting + * characters. + * That is a 13 digit EAN-13 code with the '977' prefix + * + * @param ean13 The ISSN code to convert + * @return A valid ISSN code or null + * if the input ISSN EAN-13 code is not valid + * @since 1.7 + */ + public String extractFromEAN13(final String ean13) { + String input = ean13.trim(); + if (input.length() != EAN_ISSN_LEN ) { + throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'"); + } + if (!input.startsWith(ISSN_PREFIX)) { + throw new IllegalArgumentException("Prefix must be " + ISSN_PREFIX + " to contain an ISSN: '" + ean13 + "'"); + } + final Object result = validateEan(input); + if (result == null) { + return null; + } + // Calculate the ISSN code + input = result.toString(); + try { + //CHECKSTYLE:OFF: MagicNumber + final String issnBase = input.substring(3, 10); // TODO: how to derive these + //CHECKSTYLE:ON: MagicNumber + final String checkDigit = ISSNCheckDigit.ISSN_CHECK_DIGIT.calculate(issnBase); + final String issn = issnBase + checkDigit; + return issn; + } catch (final CheckDigitException e) { // Should not happen + throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage()); + } + } + + /** + * Check the code is a valid ISSN code after any transformation + * by the validate routine. + * @param code The code to validate. + * @return {@code true} if a valid ISSN + * code, otherwise {@code false}. + */ + public boolean isValid(final String code) { + return VALIDATOR.isValid(code); + } + + /** + * Check the code is valid ISSN code. + *

    + * If valid, this method returns the ISSN code with + * the 'ISSN ' prefix removed (if it was present) + * + * @param code The code to validate. + * @return A valid ISSN code if valid, otherwise null. + */ + public Object validate(final String code) { + return VALIDATOR.validate(code); + } + + /** + * Check the code is a valid EAN code. + *

    + * If valid, this method returns the EAN code + * + * @param code The code to validate. + * @return A valid EAN code if valid, otherwise null. + * @since 1.7 + */ + public Object validateEan(final String code) { + return EAN_VALIDATOR.validate(code); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java (.../InetAddressValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java (.../InetAddressValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.regex.Pattern; /** *

    InetAddress validation and conversion routines (java.net.InetAddress).

    @@ -31,11 +32,12 @@ * This class is a Singleton; you can retrieve the instance via the {@link #getInstance()} method. *

    * - * @version $Revision: 1783032 $ - * @since Validator 1.4 + * @since 1.4 */ public class InetAddressValidator implements Serializable { + private static final int MAX_BYTE = 128; + private static final int IPV4_MAX_OCTET_VALUE = 255; private static final int MAX_UNSIGNED_SHORT = 0xffff; @@ -58,9 +60,9 @@ */ private static final InetAddressValidator VALIDATOR = new InetAddressValidator(); - /** IPv4 RegexValidator */ - private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX); + private static final Pattern DIGITS_PATTERN = Pattern.compile("\\d{1,3}"); + private static final Pattern ID_CHECK_PATTERN = Pattern.compile("[^\\s/%]+"); /** * Returns the singleton instance of this validator. * @return the singleton instance of this validator @@ -69,12 +71,15 @@ return VALIDATOR; } + /** IPv4 RegexValidator */ + private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX); + /** - * Checks if the specified string is a valid IP address. + * Checks if the specified string is a valid IPv4 or IPv6 address. * @param inetAddress the string to validate * @return true if the string validates as an IP address */ - public boolean isValid(String inetAddress) { + public boolean isValid(final String inetAddress) { return isValidInet4Address(inetAddress) || isValidInet6Address(inetAddress); } @@ -83,25 +88,25 @@ * @param inet4Address the IPv4 address to validate * @return true if the argument contains a valid IPv4 address */ - public boolean isValidInet4Address(String inet4Address) { + public boolean isValidInet4Address(final String inet4Address) { // verify that address conforms to generic IPv4 format - String[] groups = ipv4Validator.match(inet4Address); + final String[] groups = ipv4Validator.match(inet4Address); if (groups == null) { return false; } // verify that address subgroups are legal - for (String ipSegment : groups) { - if (ipSegment == null || ipSegment.length() == 0) { + for (final String ipSegment : groups) { + if (ipSegment == null || ipSegment.isEmpty()) { return false; } int iIpSegment = 0; try { iIpSegment = Integer.parseInt(ipSegment); - } catch(NumberFormatException e) { + } catch (final NumberFormatException e) { return false; } @@ -122,37 +127,63 @@ * Validates an IPv6 address. Returns true if valid. * @param inet6Address the IPv6 address to validate * @return true if the argument contains a valid IPv6 address - * + * * @since 1.4.1 */ public boolean isValidInet6Address(String inet6Address) { - boolean containsCompressedZeroes = inet6Address.contains("::"); - if (containsCompressedZeroes && (inet6Address.indexOf("::") != inet6Address.lastIndexOf("::"))) { + String[] parts; + // remove prefix size. This will appear after the zone id (if any) + parts = inet6Address.split("/", -1); + if (parts.length > 2) { + return false; // can only have one prefix specifier + } + if (parts.length == 2) { + if (!DIGITS_PATTERN.matcher(parts[1]).matches()) { + return false; // not a valid number + } + final int bits = Integer.parseInt(parts[1]); // cannot fail because of RE check + if (bits < 0 || bits > MAX_BYTE) { + return false; // out of range + } + } + // remove zone-id + parts = parts[0].split("%", -1); + if (parts.length > 2) { return false; } - if ((inet6Address.startsWith(":") && !inet6Address.startsWith("::")) - || (inet6Address.endsWith(":") && !inet6Address.endsWith("::"))) { + // The id syntax is implementation independent, but it presumably cannot allow: + // whitespace, '/' or '%' + if (parts.length == 2 && !ID_CHECK_PATTERN.matcher(parts[1]).matches()) { + return false; // invalid id + } + inet6Address = parts[0]; + final boolean containsCompressedZeroes = inet6Address.contains("::"); + if (containsCompressedZeroes && inet6Address.indexOf("::") != inet6Address.lastIndexOf("::")) { return false; } + if (inet6Address.startsWith(":") && !inet6Address.startsWith("::") + || inet6Address.endsWith(":") && !inet6Address.endsWith("::")) { + return false; + } String[] octets = inet6Address.split(":"); if (containsCompressedZeroes) { - List octetList = new ArrayList(Arrays.asList(octets)); + final List octetList = new ArrayList<>(Arrays.asList(octets)); if (inet6Address.endsWith("::")) { // String.split() drops ending empty segments octetList.add(""); } else if (inet6Address.startsWith("::") && !octetList.isEmpty()) { octetList.remove(0); } - octets = octetList.toArray(new String[octetList.size()]); + octets = octetList.toArray(new String[0]); } if (octets.length > IPV6_MAX_HEX_GROUPS) { return false; } int validOctets = 0; int emptyOctets = 0; // consecutive empty chunks for (int index = 0; index < octets.length; index++) { - String octet = octets[index]; - if (octet.length() == 0) { + final String octet = octets[index]; + if (octet.isEmpty()) { emptyOctets++; if (emptyOctets > 1) { return false; @@ -173,7 +204,7 @@ int octetInt = 0; try { octetInt = Integer.parseInt(octet, BASE_16); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { return false; } if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) { @@ -182,7 +213,7 @@ } validOctets++; } - if (validOctets > IPV6_MAX_HEX_GROUPS || (validOctets < IPV6_MAX_HEX_GROUPS && !containsCompressedZeroes)) { + if (validOctets > IPV6_MAX_HEX_GROUPS || validOctets < IPV6_MAX_HEX_GROUPS && !containsCompressedZeroes) { return false; } return true; Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IntegerValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IntegerValidator.java (.../IntegerValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IntegerValidator.java (.../IntegerValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -59,8 +59,7 @@ *
  • using a specified pattern with a specified Locale
  • * * - * @version $Revision: 1782756 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class IntegerValidator extends AbstractNumberValidator { @@ -77,7 +76,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public IntegerValidator() { this(true, STANDARD_FORMAT); @@ -99,157 +98,159 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public IntegerValidator(boolean strict, int formatType) { + public IntegerValidator(final boolean strict, final int formatType) { super(strict, formatType, false); } /** - *

    Validate/convert an Integer using the default - * Locale. + * Check if the value is within a specified range. * - * @param value The value validation is being performed on. - * @return The parsed Integer if valid or null - * if invalid. + * @param value The Number value to check. + * @param min The minimum value of the range. + * @param max The maximum value of the range. + * @return {@code true} if the value is within the + * specified range. */ - public Integer validate(String value) { - return (Integer)parse(value, (String)null, (Locale)null); + public boolean isInRange(final int value, final int min, final int max) { + return value >= min && value <= max; } /** - *

    Validate/convert an Integer using the - * specified pattern. + * Check if the value is within a specified range. * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Integer if valid or null if invalid. + * @param value The Number value to check. + * @param min The minimum value of the range. + * @param max The maximum value of the range. + * @return {@code true} if the value is within the + * specified range. */ - public Integer validate(String value, String pattern) { - return (Integer)parse(value, pattern, (Locale)null); + public boolean isInRange(final Integer value, final int min, final int max) { + return isInRange(value.intValue(), min, max); } /** - *

    Validate/convert an Integer using the - * specified Locale. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Integer if valid or null if invalid. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public Integer validate(String value, Locale locale) { - return (Integer)parse(value, (String)null, locale); + public boolean maxValue(final int value, final int max) { + return value <= max; } /** - *

    Validate/convert a Integer using the - * specified pattern and/ or Locale. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Integer if valid or null if invalid. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public Integer validate(String value, String pattern, Locale locale) { - return (Integer)parse(value, pattern, locale); + public boolean maxValue(final Integer value, final int max) { + return maxValue(value.intValue(), max); } /** - * Check if the value is within a specified range. + * Check if the value is greater than or equal to a minimum. * - * @param value The Number value to check. - * @param min The minimum value of the range. - * @param max The maximum value of the range. - * @return true if the value is within the - * specified range. + * @param value The value validation is being performed on. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean isInRange(int value, int min, int max) { - return (value >= min && value <= max); + public boolean minValue(final int value, final int min) { + return value >= min; } /** - * Check if the value is within a specified range. + * Check if the value is greater than or equal to a minimum. * - * @param value The Number value to check. - * @param min The minimum value of the range. - * @param max The maximum value of the range. - * @return true if the value is within the - * specified range. + * @param value The value validation is being performed on. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean isInRange(Integer value, int min, int max) { - return isInRange(value.intValue(), min, max); + public boolean minValue(final Integer value, final int min) { + return minValue(value.intValue(), min); } /** - * Check if the value is greater than or equal to a minimum. + *

    Perform further validation and convert the Number to + * an Integer.

    * - * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to an + * Integer if valid or null if invalid. */ - public boolean minValue(int value, int min) { - return (value >= min); + @Override + protected Object processParsedValue(final Object value, final Format formatter) { + + // Parsed value will be Long if it fits in a long and is not fractional + if (value instanceof Long) { + final long longValue = ((Long)value).longValue(); + if (longValue >= Integer.MIN_VALUE && + longValue <= Integer.MAX_VALUE) { + return Integer.valueOf((int)longValue); + } + } + return null; } /** - * Check if the value is greater than or equal to a minimum. + *

    Validate/convert an Integer using the default + * Locale. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @return The parsed Integer if valid or null + * if invalid. */ - public boolean minValue(Integer value, int min) { - return minValue(value.intValue(), min); + public Integer validate(final String value) { + return (Integer)parse(value, (String)null, (Locale)null); } /** - * Check if the value is less than or equal to a maximum. + *

    Validate/convert an Integer using the + * specified Locale. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Integer if valid or null if invalid. */ - public boolean maxValue(int value, int max) { - return (value <= max); + public Integer validate(final String value, final Locale locale) { + return (Integer)parse(value, (String)null, locale); } /** - * Check if the value is less than or equal to a maximum. + *

    Validate/convert an Integer using the + * specified pattern. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param pattern The pattern used to validate the value against. + * @return The parsed Integer if valid or null if invalid. */ - public boolean maxValue(Integer value, int max) { - return maxValue(value.intValue(), max); + public Integer validate(final String value, final String pattern) { + return (Integer)parse(value, pattern, (Locale)null); } /** - *

    Perform further validation and convert the Number to - * an Integer.

    + *

    Validate/convert a Integer using the + * specified pattern and/ or Locale. * - * @param value The parsed Number object created. - * @param formatter The Format used to parse the value with. - * @return The parsed Number converted to an - * Integer if valid or null if invalid. + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Integer if valid or null if invalid. */ - @Override - protected Object processParsedValue(Object value, Format formatter) { - - long longValue = ((Number)value).longValue(); - - if (longValue < Integer.MIN_VALUE || - longValue > Integer.MAX_VALUE) { - return null; - } - return Integer.valueOf((int)longValue); + public Integer validate(final String value, final String pattern, final Locale locale) { + return (Integer)parse(value, pattern, locale); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java (.../LongValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java (.../LongValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -58,8 +58,7 @@ *

  • using the format for the default Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class LongValidator extends AbstractNumberValidator { @@ -76,7 +75,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public LongValidator() { this(true, STANDARD_FORMAT); @@ -98,76 +97,26 @@ * percent number formats (the default). * * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public LongValidator(boolean strict, int formatType) { + public LongValidator(final boolean strict, final int formatType) { super(strict, formatType, false); } /** - *

    Validate/convert a Long using the default - * Locale. - * - * @param value The value validation is being performed on. - * @return The parsed Long if valid or null - * if invalid. - */ - public Long validate(String value) { - return (Long)parse(value, (String)null, (Locale)null); - } - - /** - *

    Validate/convert a Long using the - * specified pattern. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Long if valid or null if invalid. - */ - public Long validate(String value, String pattern) { - return (Long)parse(value, pattern, (Locale)null); - } - - /** - *

    Validate/convert a Long using the - * specified Locale. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Long if valid or null if invalid. - */ - public Long validate(String value, Locale locale) { - return (Long)parse(value, (String)null, locale); - } - - /** - *

    Validate/convert a Long using the - * specified pattern and/ or Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Long if valid or null if invalid. - */ - public Long validate(String value, String pattern, Locale locale) { - return (Long)parse(value, pattern, locale); - } - - /** * Check if the value is within a specified range. * * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(long value, long min, long max) { - return (value >= min && value <= max); + public boolean isInRange(final long value, final long min, final long max) { + return value >= min && value <= max; } /** @@ -176,59 +125,59 @@ * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(Long value, long min, long max) { + public boolean isInRange(final Long value, final long min, final long max) { return isInRange(value.longValue(), min, max); } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(long value, long min) { - return (value >= min); + public boolean maxValue(final long value, final long max) { + return value <= max; } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(Long value, long min) { - return minValue(value.longValue(), min); + public boolean maxValue(final Long value, final long max) { + return maxValue(value.longValue(), max); } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(long value, long max) { - return (value <= max); + public boolean minValue(final long value, final long min) { + return value >= min; } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(Long value, long max) { - return maxValue(value.longValue(), max); + public boolean minValue(final Long value, final long min) { + return minValue(value.longValue(), min); } /** @@ -240,12 +189,63 @@ * Long. */ @Override - protected Object processParsedValue(Object value, Format formatter) { + protected Object processParsedValue(final Object value, final Format formatter) { + // Parsed value will be Long if it fits in a long and is not fractional if (value instanceof Long) { return value; } - return Long.valueOf(((Number)value).longValue()); + return null; } + + /** + *

    Validate/convert a Long using the default + * Locale. + * + * @param value The value validation is being performed on. + * @return The parsed Long if valid or null + * if invalid. + */ + public Long validate(final String value) { + return (Long)parse(value, (String)null, (Locale)null); + } + + /** + *

    Validate/convert a Long using the + * specified Locale. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Long if valid or null if invalid. + */ + public Long validate(final String value, final Locale locale) { + return (Long)parse(value, (String)null, locale); + } + + /** + *

    Validate/convert a Long using the + * specified pattern. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed Long if valid or null if invalid. + */ + public Long validate(final String value, final String pattern) { + return (Long)parse(value, pattern, (Locale)null); + } + + /** + *

    Validate/convert a Long using the + * specified pattern and/ or Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Long if valid or null if invalid. + */ + public Long validate(final String value, final String pattern, final Locale locale) { + return (Long)parse(value, pattern, locale); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java (.../PercentValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java (.../PercentValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,16 +16,16 @@ */ package org.apache.commons.validator.routines; +import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.Format; -import java.math.BigDecimal; /** *

    Percentage Validation and Conversion routines (java.math.BigDecimal).

    * *

    This is one implementation of a percent validator that has the following features:

    *
      - *
    • It is lenient about the the presence of the percent symbol
    • + *
    • It is lenient about the presence of the percent symbol
    • *
    • It converts the percent to a java.math.BigDecimal
    • *
    * @@ -42,8 +42,7 @@ * and BigInteger) since percentages are converted to fractions (i.e 50% is * converted to 0.5).

    * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class PercentValidator extends BigDecimalValidator { @@ -65,19 +64,19 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public PercentValidator() { this(true); } /** - * Construct an instance with the specified strict setting. + * Constructs an instance with the specified strict setting. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. */ - public PercentValidator(boolean strict) { + public PercentValidator(final boolean strict) { super(strict, PERCENT_FORMAT, true); } @@ -86,7 +85,7 @@ * *

    This implementation is lenient whether the currency symbol * is present or not. The default NumberFormat - * behaviour is for the parsing to "fail" if the currency + * behavior is for the parsing to "fail" if the currency * symbol is missing. This method re-parses with a format * without the currency symbol if it fails initially.

    * @@ -95,7 +94,7 @@ * @return The parsed value if valid or null if invalid. */ @Override - protected Object parse(String value, Format formatter) { + protected Object parse(final String value, final Format formatter) { // Initial parse of the value BigDecimal parsedValue = (BigDecimal)super.parse(value, formatter); @@ -104,10 +103,10 @@ } // Re-parse using a pattern without the percent symbol - DecimalFormat decimalFormat = (DecimalFormat)formatter; - String pattern = decimalFormat.toPattern(); + final DecimalFormat decimalFormat = (DecimalFormat)formatter; + final String pattern = decimalFormat.toPattern(); if (pattern.indexOf(PERCENT_SYMBOL) >= 0) { - StringBuilder buffer = new StringBuilder(pattern.length()); + final StringBuilder buffer = new StringBuilder(pattern.length()); for (int i = 0; i < pattern.length(); i++) { if (pattern.charAt(i) != PERCENT_SYMBOL) { buffer.append(pattern.charAt(i)); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java (.../RegexValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java (.../RegexValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -17,13 +17,14 @@ package org.apache.commons.validator.routines; import java.io.Serializable; -import java.util.regex.Pattern; +import java.util.List; import java.util.regex.Matcher; +import java.util.regex.Pattern; /** - * Regular Expression validation (using JDK 1.4+ regex support). + * Regular Expression validation (using the JRE's regular expression support). *

    - * Construct the validator either for a single regular expression or a set (array) of + * Constructs the validator either for a single regular expression or a set (array) of * regular expressions. By default validation is case sensitive but constructors * are provided to allow case in-sensitive validation. For example to create * a validator which does case in-sensitive validation for a set of regular @@ -37,7 +38,7 @@ *

    * *
      - *
    • Validate true or false:
    • + *
    • Validate {@code true} or {@code false}:
    • *
    • *
        *
      • boolean valid = validator.isValid(value);
      • @@ -64,8 +65,7 @@ * to the {@link Pattern} API are safe to use in a multi-threaded environment. *

        * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public class RegexValidator implements Serializable { @@ -74,131 +74,169 @@ private final Pattern[] patterns; /** - * Construct a case sensitive validator for a single - * regular expression. + * Constructs a case sensitive validator that matches any one + * in the list of regular expressions. * - * @param regex The regular expression this validator will + * @param regexs The set of regular expressions this validator will * validate against */ - public RegexValidator(String regex) { - this(regex, true); + RegexValidator(final List regexs) { + this(regexs.toArray(new String[] {}), true); } /** - * Construct a validator for a single regular expression - * with the specified case sensitivity. + * Constructs a case sensitive validator for a single + * regular expression. * * @param regex The regular expression this validator will * validate against - * @param caseSensitive when true matching is case - * sensitive, otherwise matching is case in-sensitive */ - public RegexValidator(String regex, boolean caseSensitive) { - this(new String[] {regex}, caseSensitive); + public RegexValidator(final String regex) { + this(regex, true); } /** - * Construct a case sensitive validator that matches any one - * of the set of regular expressions. + * Constructs a case sensitive validator that matches any one + * in the array of regular expressions. * * @param regexs The set of regular expressions this validator will * validate against */ - public RegexValidator(String[] regexs) { + public RegexValidator(final String... regexs) { this(regexs, true); } /** - * Construct a validator that matches any one of the set of regular + * Constructs a validator for a single regular expression + * with the specified case sensitivity. + * + * @param regex The regular expression this validator will + * validate against + * @param caseSensitive when {@code true} matching is case + * sensitive, otherwise matching is case in-sensitive + */ + public RegexValidator(final String regex, final boolean caseSensitive) { + this(new String[] { regex }, caseSensitive); + } + + /** + * Constructs a validator that matches any one of the set of regular * expressions with the specified case sensitivity. * * @param regexs The set of regular expressions this validator will * validate against - * @param caseSensitive when true matching is case + * @param caseSensitive when {@code true} matching is case * sensitive, otherwise matching is case in-sensitive */ - public RegexValidator(String[] regexs, boolean caseSensitive) { + public RegexValidator(final String[] regexs, final boolean caseSensitive) { if (regexs == null || regexs.length == 0) { throw new IllegalArgumentException("Regular expressions are missing"); } patterns = new Pattern[regexs.length]; - int flags = (caseSensitive ? 0: Pattern.CASE_INSENSITIVE); + final int flags = caseSensitive ? 0 : Pattern.CASE_INSENSITIVE; for (int i = 0; i < regexs.length; i++) { - if (regexs[i] == null || regexs[i].length() == 0) { + if (regexs[i] == null || regexs[i].isEmpty()) { throw new IllegalArgumentException("Regular expression[" + i + "] is missing"); } - patterns[i] = Pattern.compile(regexs[i], flags); + patterns[i] = Pattern.compile(regexs[i], flags); } } /** - * Validate a value against the set of regular expressions. + * Gets a copy of the Patterns. * + * @return a copy of the Patterns. + * @since 1.8 + */ + public Pattern[] getPatterns() { + return patterns.clone(); + } + + /** + * Validates a value against the set of regular expressions. + * * @param value The value to validate. - * @return true if the value is valid - * otherwise false. + * @return {@code true} if the value is valid + * otherwise {@code false}. */ - public boolean isValid(String value) { + public boolean isValid(final String value) { if (value == null) { return false; } - for (int i = 0; i < patterns.length; i++) { - if (patterns[i].matcher(value).matches()) { + for (final Pattern pattern : patterns) { + if (pattern.matcher(value).matches()) { return true; } } return false; } /** - * Validate a value against the set of regular expressions + * Validates a value against the set of regular expressions * returning the array of matched groups. * * @param value The value to validate. * @return String array of the groups matched if * valid or null if invalid */ - public String[] match(String value) { + public String[] match(final String value) { if (value == null) { return null; } - for (int i = 0; i < patterns.length; i++) { - Matcher matcher = patterns[i].matcher(value); + for (final Pattern pattern : patterns) { + final Matcher matcher = pattern.matcher(value); if (matcher.matches()) { - int count = matcher.groupCount(); - String[] groups = new String[count]; + final int count = matcher.groupCount(); + final String[] groups = new String[count]; for (int j = 0; j < count; j++) { - groups[j] = matcher.group(j+1); + groups[j] = matcher.group(j + 1); } return groups; } } return null; } + /** + * Provides a String representation of this validator. + * @return A String representation of this validator. + */ + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder(); + buffer.append("RegexValidator{"); + for (int i = 0; i < patterns.length; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(patterns[i].pattern()); + } + buffer.append("}"); + return buffer.toString(); + } /** - * Validate a value against the set of regular expressions + * Validates a value against the set of regular expressions * returning a String value of the aggregated groups. * * @param value The value to validate. * @return Aggregated String value comprised of the * groups matched if valid or null if invalid */ - public String validate(String value) { + public String validate(final String value) { if (value == null) { return null; } - for (int i = 0; i < patterns.length; i++) { - Matcher matcher = patterns[i].matcher(value); + for (final Pattern pattern : patterns) { + final Matcher matcher = pattern.matcher(value); if (matcher.matches()) { - int count = matcher.groupCount(); + final int count = matcher.groupCount(); if (count == 1) { return matcher.group(1); } - StringBuilder buffer = new StringBuilder(); + final StringBuilder buffer = new StringBuilder(); for (int j = 0; j < count; j++) { - String component = matcher.group(j+1); + final String component = matcher.group(j + 1); if (component != null) { buffer.append(component); } @@ -209,22 +247,4 @@ return null; } - /** - * Provide a String representation of this validator. - * @return A String representation of this validator - */ - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - buffer.append("RegexValidator{"); - for (int i = 0; i < patterns.length; i++) { - if (i > 0) { - buffer.append(","); - } - buffer.append(patterns[i].pattern()); - } - buffer.append("}"); - return buffer.toString(); - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ShortValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ShortValidator.java (.../ShortValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ShortValidator.java (.../ShortValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -59,8 +59,7 @@ *
      • using a specified pattern with a specified Locale
      • *
      * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class ShortValidator extends AbstractNumberValidator { @@ -77,7 +76,7 @@ } /** - * Construct a strict instance. + * Constructs a strict instance. */ public ShortValidator() { this(true, STANDARD_FORMAT); @@ -99,76 +98,26 @@ * percent number formats (the default).
    • *
    * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param formatType The NumberFormat type to * create for validation, default is STANDARD_FORMAT. */ - public ShortValidator(boolean strict, int formatType) { + public ShortValidator(final boolean strict, final int formatType) { super(strict, formatType, false); } /** - *

    Validate/convert a Short using the default - * Locale. - * - * @param value The value validation is being performed on. - * @return The parsed Short if valid or null - * if invalid. - */ - public Short validate(String value) { - return (Short)parse(value, (String)null, (Locale)null); - } - - /** - *

    Validate/convert a Short using the - * specified pattern. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Short if valid or null if invalid. - */ - public Short validate(String value, String pattern) { - return (Short)parse(value, pattern, (Locale)null); - } - - /** - *

    Validate/convert a Short using the - * specified Locale. - * - * @param value The value validation is being performed on. - * @param locale The locale to use for the number format, system default if null. - * @return The parsed Short if valid or null if invalid. - */ - public Short validate(String value, Locale locale) { - return (Short)parse(value, (String)null, locale); - } - - /** - *

    Validate/convert a Short using the - * specified pattern and/ or Locale. - * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against, or the - * default for the Locale if null. - * @param locale The locale to use for the date format, system default if null. - * @return The parsed Short if valid or null if invalid. - */ - public Short validate(String value, String pattern, Locale locale) { - return (Short)parse(value, pattern, locale); - } - - /** * Check if the value is within a specified range. * * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(short value, short min, short max) { - return (value >= min && value <= max); + public boolean isInRange(final short value, final short min, final short max) { + return value >= min && value <= max; } /** @@ -177,59 +126,59 @@ * @param value The Number value to check. * @param min The minimum value of the range. * @param max The maximum value of the range. - * @return true if the value is within the + * @return {@code true} if the value is within the * specified range. */ - public boolean isInRange(Short value, short min, short max) { + public boolean isInRange(final Short value, final short min, final short max) { return isInRange(value.shortValue(), min, max); } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(short value, short min) { - return (value >= min); + public boolean maxValue(final short value, final short max) { + return value <= max; } /** - * Check if the value is greater than or equal to a minimum. + * Check if the value is less than or equal to a maximum. * * @param value The value validation is being performed on. - * @param min The minimum value. - * @return true if the value is greater than - * or equal to the minimum. + * @param max The maximum value. + * @return {@code true} if the value is less than + * or equal to the maximum. */ - public boolean minValue(Short value, short min) { - return minValue(value.shortValue(), min); + public boolean maxValue(final Short value, final short max) { + return maxValue(value.shortValue(), max); } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(short value, short max) { - return (value <= max); + public boolean minValue(final short value, final short min) { + return value >= min; } /** - * Check if the value is less than or equal to a maximum. + * Check if the value is greater than or equal to a minimum. * * @param value The value validation is being performed on. - * @param max The maximum value. - * @return true if the value is less than - * or equal to the maximum. + * @param min The minimum value. + * @return {@code true} if the value is greater than + * or equal to the minimum. */ - public boolean maxValue(Short value, short max) { - return maxValue(value.shortValue(), max); + public boolean minValue(final Short value, final short min) { + return minValue(value.shortValue(), min); } /** @@ -242,14 +191,64 @@ * Short if valid or null if invalid. */ @Override - protected Object processParsedValue(Object value, Format formatter) { + protected Object processParsedValue(final Object value, final Format formatter) { - long longValue = ((Number)value).longValue(); + final long longValue = ((Number)value).longValue(); if (longValue < Short.MIN_VALUE || longValue > Short.MAX_VALUE) { return null; } return Short.valueOf((short)longValue); } + + /** + *

    Validate/convert a Short using the default + * Locale. + * + * @param value The value validation is being performed on. + * @return The parsed Short if valid or null + * if invalid. + */ + public Short validate(final String value) { + return (Short)parse(value, (String)null, (Locale)null); + } + + /** + *

    Validate/convert a Short using the + * specified Locale. + * + * @param value The value validation is being performed on. + * @param locale The locale to use for the number format, system default if null. + * @return The parsed Short if valid or null if invalid. + */ + public Short validate(final String value, final Locale locale) { + return (Short)parse(value, (String)null, locale); + } + + /** + *

    Validate/convert a Short using the + * specified pattern. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed Short if valid or null if invalid. + */ + public Short validate(final String value, final String pattern) { + return (Short)parse(value, pattern, (Locale)null); + } + + /** + *

    Validate/convert a Short using the + * specified pattern and/ or Locale. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against, or the + * default for the Locale if null. + * @param locale The locale to use for the date format, system default if null. + * @return The parsed Short if valid or null if invalid. + */ + public Short validate(final String value, final String pattern, final Locale locale) { + return (Short)parse(value, pattern, locale); + } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java (.../TimeValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java (.../TimeValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -79,8 +79,7 @@ *

  • using the format for the default Locale
  • * * - * @version $Revision: 1739356 $ - * @since Validator 1.3.0 + * @since 1.3.0 */ public class TimeValidator extends AbstractCalendarValidator { @@ -97,72 +96,99 @@ } /** - * Construct a strict instance with short + * Constructs a strict instance with short * time style. */ public TimeValidator() { this(true, DateFormat.SHORT); } /** - * Construct an instance with the specified strict + * Constructs an instance with the specified strict * and time style parameters. * - * @param strict true if strict + * @param strict {@code true} if strict * Format parsing should be used. * @param timeStyle the time style to use for Locale validation. */ - public TimeValidator(boolean strict, int timeStyle) { + public TimeValidator(final boolean strict, final int timeStyle) { super(strict, -1, timeStyle); } /** - *

    Validate/convert a time using the default Locale - * and TimeZone. + *

    Compare Hours.

    * - * @param value The value validation is being performed on. - * @return The parsed Calendar if valid or null - * if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the hours are equal, -1 if first + * parameter's hour is less than the seconds and +1 if the first + * parameter's hour is greater than. */ - public Calendar validate(String value) { - return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null); + public int compareHours(final Calendar value, final Calendar compare) { + return compareTime(value, compare, Calendar.HOUR_OF_DAY); } /** - *

    Validate/convert a time using the specified TimeZone - * and default Locale. + *

    Compare Minutes (hours and minutes).

    * - * @param value The value validation is being performed on. - * @param timeZone The Time Zone used to parse the time, system default if null. - * @return The parsed Calendar if valid or null if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the hours are equal, -1 if first + * parameter's minutes are less than the seconds and +1 if the first + * parameter's minutes are greater than. */ - public Calendar validate(String value, TimeZone timeZone) { - return (Calendar)parse(value, (String)null, (Locale)null, timeZone); + public int compareMinutes(final Calendar value, final Calendar compare) { + return compareTime(value, compare, Calendar.MINUTE); } /** - *

    Validate/convert a time using the specified pattern and - * default TimeZone. + *

    Compare Seconds (hours, minutes and seconds).

    * - * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @return The parsed Calendar if valid or null if invalid. + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the hours are equal, -1 if first + * parameter's seconds are less than the seconds and +1 if the first + * parameter's seconds are greater than. */ - public Calendar validate(String value, String pattern) { - return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + public int compareSeconds(final Calendar value, final Calendar compare) { + return compareTime(value, compare, Calendar.SECOND); } /** - *

    Validate/convert a time using the specified pattern + *

    Compare Times (hour, minute, second and millisecond - not date).

    + * + * @param value The Calendar value to check. + * @param compare The Calendar to compare the value to. + * @return Zero if the hours are equal, -1 if first + * time is less than the seconds and +1 if the first + * time is greater than. + */ + public int compareTime(final Calendar value, final Calendar compare) { + return compareTime(value, compare, Calendar.MILLISECOND); + } + + /** + *

    Convert the parsed Date to a Calendar.

    + * + * @param value The parsed Date object created. + * @param formatter The Format used to parse the value with. + * @return The parsed value converted to a Calendar. + */ + @Override + protected Object processParsedValue(final Object value, final Format formatter) { + return ((DateFormat)formatter).getCalendar(); + } + + /** + *

    Validate/convert a time using the default Locale * and TimeZone. * * @param value The value validation is being performed on. - * @param pattern The pattern used to validate the value against. - * @param timeZone The Time Zone used to parse the time, system default if null. - * @return The parsed Calendar if valid or null if invalid. + * @return The parsed Calendar if valid or null + * if invalid. */ - public Calendar validate(String value, String pattern, TimeZone timeZone) { - return (Calendar)parse(value, pattern, (Locale)null, timeZone); + public Calendar validate(final String value) { + return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null); } /** @@ -173,24 +199,36 @@ * @param locale The locale to use for the time format, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, Locale locale) { + public Calendar validate(final String value, final Locale locale) { return (Calendar)parse(value, (String)null, locale, (TimeZone)null); } /** - *

    Validate/convert a time using the specified specified Locale + *

    Validate/convert a time using the specified Locale * and TimeZone. * * @param value The value validation is being performed on. * @param locale The locale to use for the time format, system default if null. * @param timeZone The Time Zone used to parse the time, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, Locale locale, TimeZone timeZone) { + public Calendar validate(final String value, final Locale locale, final TimeZone timeZone) { return (Calendar)parse(value, (String)null, locale, timeZone); } /** + *

    Validate/convert a time using the specified pattern and + * default TimeZone. + * + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @return The parsed Calendar if valid or null if invalid. + */ + public Calendar validate(final String value, final String pattern) { + return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + } + + /** *

    Validate/convert a time using the specified pattern and Locale * and the default TimeZone. * @@ -200,7 +238,7 @@ * @param locale The locale to use for the date format, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, String pattern, Locale locale) { + public Calendar validate(final String value, final String pattern, final Locale locale) { return (Calendar)parse(value, pattern, locale, (TimeZone)null); } @@ -215,71 +253,32 @@ * @param timeZone The Time Zone used to parse the date, system default if null. * @return The parsed Calendar if valid or null if invalid. */ - public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) { + public Calendar validate(final String value, final String pattern, final Locale locale, final TimeZone timeZone) { return (Calendar)parse(value, pattern, locale, timeZone); } /** - *

    Compare Times (hour, minute, second and millisecond - not date).

    + *

    Validate/convert a time using the specified pattern + * and TimeZone. * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the hours are equal, -1 if first - * time is less than the seconds and +1 if the first - * time is greater than. + * @param value The value validation is being performed on. + * @param pattern The pattern used to validate the value against. + * @param timeZone The Time Zone used to parse the time, system default if null. + * @return The parsed Calendar if valid or null if invalid. */ - public int compareTime(Calendar value, Calendar compare) { - return compareTime(value, compare, Calendar.MILLISECOND); + public Calendar validate(final String value, final String pattern, final TimeZone timeZone) { + return (Calendar)parse(value, pattern, (Locale)null, timeZone); } /** - *

    Compare Seconds (hours, minutes and seconds).

    + *

    Validate/convert a time using the specified TimeZone + * and default Locale. * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the hours are equal, -1 if first - * parameter's seconds are less than the seconds and +1 if the first - * parameter's seconds are greater than. + * @param value The value validation is being performed on. + * @param timeZone The Time Zone used to parse the time, system default if null. + * @return The parsed Calendar if valid or null if invalid. */ - public int compareSeconds(Calendar value, Calendar compare) { - return compareTime(value, compare, Calendar.SECOND); + public Calendar validate(final String value, final TimeZone timeZone) { + return (Calendar)parse(value, (String)null, (Locale)null, timeZone); } - - /** - *

    Compare Minutes (hours and minutes).

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the hours are equal, -1 if first - * parameter's minutes are less than the seconds and +1 if the first - * parameter's minutes are greater than. - */ - public int compareMinutes(Calendar value, Calendar compare) { - return compareTime(value, compare, Calendar.MINUTE); - } - - /** - *

    Compare Hours.

    - * - * @param value The Calendar value to check. - * @param compare The Calendar to compare the value to. - * @return Zero if the hours are equal, -1 if first - * parameter's hour is less than the seconds and +1 if the first - * parameter's hour is greater than. - */ - public int compareHours(Calendar value, Calendar compare) { - return compareTime(value, compare, Calendar.HOUR_OF_DAY); - } - - /** - *

    Convert the parsed Date to a Calendar.

    - * - * @param value The parsed Date object created. - * @param formatter The Format used to parse the value with. - * @return The parsed value converted to a Calendar. - */ - @Override - protected Object processParsedValue(Object value, Format formatter) { - return ((DateFormat)formatter).getCalendar(); - } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/UrlValidator.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/UrlValidator.java (.../UrlValidator.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/UrlValidator.java (.../UrlValidator.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -48,31 +48,30 @@ * String[] schemes = {"http","https"}. * UrlValidator urlValidator = new UrlValidator(schemes); * if (urlValidator.isValid("ftp://foo.bar.com/")) { - * System.out.println("url is valid"); + * System.out.println("URL is valid"); * } else { - * System.out.println("url is invalid"); + * System.out.println("URL is invalid"); * } * - * prints "url is invalid" + * prints "URL is invalid" * If instead the default constructor is used. * * UrlValidator urlValidator = new UrlValidator(); * if (urlValidator.isValid("ftp://foo.bar.com/")) { - * System.out.println("url is valid"); + * System.out.println("URL is valid"); * } else { - * System.out.println("url is invalid"); + * System.out.println("URL is invalid"); * } * - * prints out "url is valid" + * prints out "URL is valid" *
    * * @see * * Uniform Resource Identifiers (URI): Generic Syntax * * - * @version $Revision: 1783203 $ - * @since Validator 1.4 + * @since 1.4 */ public class UrlValidator implements Serializable { @@ -105,53 +104,32 @@ public static final long ALLOW_LOCAL_URLS = 1 << 3; // CHECKSTYLE IGNORE MagicNumber /** - * This expression derived/taken from the BNF for URI (RFC2396). - */ - private static final String URL_REGEX = - "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"; - // 12 3 4 5 6 7 8 9 - private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX); - - /** - * Schema/Protocol (ie. http:, ftp:, file:, etc). - */ - private static final int PARSE_URL_SCHEME = 2; - - /** - * Includes hostname/ip and port number. - */ - private static final int PARSE_URL_AUTHORITY = 4; - - private static final int PARSE_URL_PATH = 5; - - private static final int PARSE_URL_QUERY = 7; - - private static final int PARSE_URL_FRAGMENT = 9; - - /** * Protocol scheme (e.g. http, ftp, https). */ private static final String SCHEME_REGEX = "^\\p{Alpha}[\\p{Alnum}\\+\\-\\.]*"; private static final Pattern SCHEME_PATTERN = Pattern.compile(SCHEME_REGEX); // Drop numeric, and "+-." for now - // TODO does not allow for optional userinfo. + // TODO does not allow for optional userinfo. // Validation of character set is done by isValidAuthority private static final String AUTHORITY_CHARS_REGEX = "\\p{Alnum}\\-\\."; // allows for IPV4 but not IPV6 - private static final String IPV6_REGEX = "[0-9a-fA-F:]+"; // do this as separate match because : could cause ambiguity with port prefix + // Allow for IPv4 mapped addresses: ::FFF:123.123.123.123 + private static final String IPV6_REGEX = "::FFFF:(?:\\d{1,3}\\.){3}\\d{1,3}|[0-9a-fA-F:]+"; // do this as separate match because : could cause ambiguity with port prefix // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" // We assume that password has the same valid chars as user info private static final String USERINFO_CHARS_REGEX = "[a-zA-Z0-9%-._~!$&'()*+,;=]"; + // since neither ':' nor '@' are allowed chars, we don't need to use non-greedy matching private static final String USERINFO_FIELD_REGEX = USERINFO_CHARS_REGEX + "+" + // At least one character for the name "(?::" + USERINFO_CHARS_REGEX + "*)?@"; // colon and password may be absent + private static final String AUTHORITY_REGEX = - "(?:\\[("+IPV6_REGEX+")\\]|(?:(?:"+USERINFO_FIELD_REGEX+")?([" + AUTHORITY_CHARS_REGEX + "]*)))(?::(\\d*))?(.*)?"; - // 1 e.g. user:pass@ 2 3 4 + "(?:\\[(" + IPV6_REGEX + ")\\]|(?:(?:" + USERINFO_FIELD_REGEX + ")?([" + AUTHORITY_CHARS_REGEX + "]*)))(?::(\\d*))?(.*)?"; + // 1 e.g. user:pass@ 2 3 4 private static final Pattern AUTHORITY_PATTERN = Pattern.compile(AUTHORITY_REGEX); private static final int PARSE_AUTHORITY_IPV6 = 1; @@ -172,6 +150,37 @@ private static final Pattern QUERY_PATTERN = Pattern.compile(QUERY_REGEX); /** + * If no schemes are provided, default to this set. + */ + private static final String[] DEFAULT_SCHEMES = {"http", "https", "ftp"}; // Must be lower-case + + /** + * Singleton instance of this class with default schemes and options. + */ + private static final UrlValidator DEFAULT_URL_VALIDATOR = new UrlValidator(); + + /** + * Returns the singleton instance of this class with default schemes and options. + * @return singleton instance with default schemes and options + */ + public static UrlValidator getInstance() { + return DEFAULT_URL_VALIDATOR; + } + + /** + * Tests whether the given flag is on. If the flag is not a power of 2 + * (e.g. 3) this tests whether the combination of flags is on. + * + * @param flag Flag value to check. + * @param options what to check + * + * @return whether the specified flag value is on. + */ + private static boolean isOn(final long flag, final long options) { + return (options & flag) > 0; + } + + /** * Holds the set of current validation options. */ private final long options; @@ -187,183 +196,205 @@ */ private final RegexValidator authorityValidator; - /** - * If no schemes are provided, default to this set. - */ - private static final String[] DEFAULT_SCHEMES = {"http", "https", "ftp"}; // Must be lower-case + private final DomainValidator domainValidator; /** - * Singleton instance of this class with default schemes and options. + * Create a UrlValidator with default properties. */ - private static final UrlValidator DEFAULT_URL_VALIDATOR = new UrlValidator(); + public UrlValidator() { + this(null); + } /** - * Returns the singleton instance of this class with default schemes and options. - * @return singleton instance with default schemes and options + * Initialize a UrlValidator with the given validation options. + * @param options The options should be set using the public constants declared in + * this class. To set multiple options you simply add them together. For example, + * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. */ - public static UrlValidator getInstance() { - return DEFAULT_URL_VALIDATOR; + public UrlValidator(final long options) { + this(null, null, options); } /** - * Create a UrlValidator with default properties. + * Initialize a UrlValidator with the given validation options. + * @param authorityValidator Regular expression validator used to validate the authority part + * This allows the user to override the standard set of domains. + * @param options Validation options. Set using the public constants of this class. + * To set multiple options, simply add them together: + *

    ALLOW_2_SLASHES + NO_FRAGMENTS

    + * enables both of those options. */ - public UrlValidator() { - this(null); + public UrlValidator(final RegexValidator authorityValidator, final long options) { + this(null, authorityValidator, options); } /** * Behavior of validation is modified by passing in several strings options: - * @param schemes Pass in one or more url schemes to consider valid, passing in + * @param schemes Pass in one or more URL schemes to consider valid, passing in * a null will default to "http,https,ftp" being valid. * If a non-null schemes is specified then all valid schemes must * be specified. Setting the ALLOW_ALL_SCHEMES option will * ignore the contents of schemes. */ - public UrlValidator(String[] schemes) { + public UrlValidator(final String[] schemes) { this(schemes, 0L); } /** - * Initialize a UrlValidator with the given validation options. - * @param options The options should be set using the public constants declared in - * this class. To set multiple options you simply add them together. For example, - * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. - */ - public UrlValidator(long options) { - this(null, null, options); - } - - /** * Behavior of validation is modified by passing in options: * @param schemes The set of valid schemes. Ignored if the ALLOW_ALL_SCHEMES option is set. * @param options The options should be set using the public constants declared in * this class. To set multiple options you simply add them together. For example, * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options. */ - public UrlValidator(String[] schemes, long options) { + public UrlValidator(final String[] schemes, final long options) { this(schemes, null, options); } /** - * Initialize a UrlValidator with the given validation options. + * Customizable constructor. Validation behavior is modified by passing in options. + * @param schemes the set of valid schemes. Ignored if the ALLOW_ALL_SCHEMES option is set. * @param authorityValidator Regular expression validator used to validate the authority part - * This allows the user to override the standard set of domains. * @param options Validation options. Set using the public constants of this class. * To set multiple options, simply add them together: *

    ALLOW_2_SLASHES + NO_FRAGMENTS

    * enables both of those options. */ - public UrlValidator(RegexValidator authorityValidator, long options) { - this(null, authorityValidator, options); + public UrlValidator(final String[] schemes, final RegexValidator authorityValidator, final long options) { + this(schemes, authorityValidator, options, DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS, options))); } /** - * Customizable constructor. Validation behavior is modifed by passing in options. + * Customizable constructor. Validation behavior is modified by passing in options. * @param schemes the set of valid schemes. Ignored if the ALLOW_ALL_SCHEMES option is set. * @param authorityValidator Regular expression validator used to validate the authority part * @param options Validation options. Set using the public constants of this class. * To set multiple options, simply add them together: *

    ALLOW_2_SLASHES + NO_FRAGMENTS

    * enables both of those options. + * @param domainValidator the DomainValidator to use; must agree with ALLOW_LOCAL_URLS setting + * @since 1.7 */ - public UrlValidator(String[] schemes, RegexValidator authorityValidator, long options) { + public UrlValidator(String[] schemes, final RegexValidator authorityValidator, final long options, final DomainValidator domainValidator) { this.options = options; + if (domainValidator == null) { + throw new IllegalArgumentException("DomainValidator must not be null"); + } + if (domainValidator.isAllowLocal() != (options & ALLOW_LOCAL_URLS) > 0) { + throw new IllegalArgumentException("DomainValidator disagrees with ALLOW_LOCAL_URLS setting"); + } + this.domainValidator = domainValidator; if (isOn(ALLOW_ALL_SCHEMES)) { allowedSchemes = Collections.emptySet(); } else { if (schemes == null) { schemes = DEFAULT_SCHEMES; } - allowedSchemes = new HashSet(schemes.length); - for(int i=0; i < schemes.length; i++) { - allowedSchemes.add(schemes[i].toLowerCase(Locale.ENGLISH)); + allowedSchemes = new HashSet<>(schemes.length); + for (final String scheme : schemes) { + allowedSchemes.add(scheme.toLowerCase(Locale.ENGLISH)); } } this.authorityValidator = authorityValidator; } /** - *

    Checks if a field has a valid url address.

    + * Returns the number of times the token appears in the target. + * @param token Token value to be counted. + * @param target Target value to count tokens in. + * @return the number of tokens. + */ + protected int countToken(final String token, final String target) { + int tokenIndex = 0; + int count = 0; + while (tokenIndex != -1) { + tokenIndex = target.indexOf(token, tokenIndex); + if (tokenIndex > -1) { + tokenIndex++; + count++; + } + } + return count; + } + + /** + * Tests whether the given flag is off. If the flag is not a power of 2 + * (ie. 3) this tests whether the combination of flags is off. * + * @param flag Flag value to check. + * + * @return whether the specified flag value is off. + */ + private boolean isOff(final long flag) { + return (options & flag) == 0; + } + + /** + * Tests whether the given flag is on. If the flag is not a power of 2 + * (ie. 3) this tests whether the combination of flags is on. + * + * @param flag Flag value to check. + * + * @return whether the specified flag value is on. + */ + private boolean isOn(final long flag) { + return (options & flag) > 0; + } + + /** + *

    Checks if a field has a valid URL address.

    + * * Note that the method calls #isValidAuthority() * which checks that the domain is valid. * * @param value The value validation is being performed on. A null * value is considered invalid. - * @return true if the url is valid. + * @return true if the URL is valid. */ - public boolean isValid(String value) { + public boolean isValid(final String value) { if (value == null) { return false; } - // Check the whole url address structure - Matcher urlMatcher = URL_PATTERN.matcher(value); - if (!urlMatcher.matches()) { + URI uri; // ensure value is a valid URI + try { + uri = new URI(value); + } catch (final URISyntaxException e) { return false; } + // OK, perform additional validation - String scheme = urlMatcher.group(PARSE_URL_SCHEME); + final String scheme = uri.getScheme(); if (!isValidScheme(scheme)) { return false; } - String authority = urlMatcher.group(PARSE_URL_AUTHORITY); - if ("file".equals(scheme)) {// Special case - file: allows an empty authority - if (authority != null) { - if (authority.contains(":")) { // but cannot allow trailing : - return false; - } - } - // drop through to continue validation - } else { // not file: - // Validate the authority - if (!isValidAuthority(authority)) { - return false; - } + final String authority = uri.getRawAuthority(); + if ("file".equals(scheme) && (authority == null || authority.isEmpty())) { // Special case - file: allows an empty authority + return true; // this is a local file - nothing more to do here } - - if (!isValidPath(urlMatcher.group(PARSE_URL_PATH))) { + if ("file".equals(scheme) && authority != null && authority.contains(":")) { return false; } - - if (!isValidQuery(urlMatcher.group(PARSE_URL_QUERY))) { + // Validate the authority + if (!isValidAuthority(authority)) { return false; } - if (!isValidFragment(urlMatcher.group(PARSE_URL_FRAGMENT))) { + if (!isValidPath(uri.getRawPath())) { return false; } - return true; - } - - /** - * Validate scheme. If schemes[] was initialized to a non null, - * then only those schemes are allowed. - * Otherwise the default schemes are "http", "https", "ftp". - * Matching is case-blind. - * @param scheme The scheme to validate. A null value is considered - * invalid. - * @return true if valid. - */ - protected boolean isValidScheme(String scheme) { - if (scheme == null) { + if (!isValidQuery(uri.getRawQuery())) { return false; } - // TODO could be removed if external schemes were checked in the ctor before being stored - if (!SCHEME_PATTERN.matcher(scheme).matches()) { + if (!isValidFragment(uri.getRawFragment())) { return false; } - if (isOff(ALLOW_ALL_SCHEMES) && !allowedSchemes.contains(scheme.toLowerCase(Locale.ENGLISH))) { - return false; - } - return true; } @@ -377,7 +408,7 @@ * @param authority Authority value to validate, alllows IDN * @return true if authority (hostname and port) is valid. */ - protected boolean isValidAuthority(String authority) { + protected boolean isValidAuthority(final String authority) { if (authority == null) { return false; } @@ -389,58 +420,70 @@ // convert to ASCII if possible final String authorityASCII = DomainValidator.unicodeToASCII(authority); - Matcher authorityMatcher = AUTHORITY_PATTERN.matcher(authorityASCII); + final Matcher authorityMatcher = AUTHORITY_PATTERN.matcher(authorityASCII); if (!authorityMatcher.matches()) { return false; } // We have to process IPV6 separately because that is parsed in a different group - String ipv6 = authorityMatcher.group(PARSE_AUTHORITY_IPV6); + final String ipv6 = authorityMatcher.group(PARSE_AUTHORITY_IPV6); if (ipv6 != null) { - InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); - if (!inetAddressValidator.isValidInet6Address(ipv6)) { - return false; - } + final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); + if (!inetAddressValidator.isValidInet6Address(ipv6)) { + return false; + } } else { - String hostLocation = authorityMatcher.group(PARSE_AUTHORITY_HOST_IP); + final String hostLocation = authorityMatcher.group(PARSE_AUTHORITY_HOST_IP); // check if authority is hostname or IP address: // try a hostname first since that's much more likely - DomainValidator domainValidator = DomainValidator.getInstance(isOn(ALLOW_LOCAL_URLS)); - if (!domainValidator.isValid(hostLocation)) { + if (!this.domainValidator.isValid(hostLocation)) { // try an IPv4 address - InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); + final InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); if (!inetAddressValidator.isValidInet4Address(hostLocation)) { // isn't IPv4, so the URL is invalid return false; } } - String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); - if (port != null && port.length() > 0) { + final String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); + if (port != null && !port.isEmpty()) { try { - int iPort = Integer.parseInt(port); + final int iPort = Integer.parseInt(port); if (iPort < 0 || iPort > MAX_UNSIGNED_16_BIT_INT) { return false; } - } catch (NumberFormatException nfe) { + } catch (final NumberFormatException nfe) { return false; // this can happen for big numbers } } } - String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); - if (extra != null && extra.trim().length() > 0){ + final String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); + if (extra != null && !extra.trim().isEmpty()) { return false; } return true; } /** + * Returns true if the given fragment is null or fragments are allowed. + * @param fragment Fragment value to validate. + * @return true if fragment is valid. + */ + protected boolean isValidFragment(final String fragment) { + if (fragment == null) { + return true; + } + + return isOff(NO_FRAGMENTS); + } + + /** * Returns true if the path is valid. A null value is considered invalid. * @param path Path value to validate. * @return true if path is valid. */ - protected boolean isValidPath(String path) { + protected boolean isValidPath(final String path) { if (path == null) { return false; } @@ -450,18 +493,19 @@ } try { - URI uri = new URI(null,null,path,null); - String norm = uri.normalize().getPath(); - if (norm.startsWith("/../") // Trying to go via the parent dir + // Don't omit host otherwise leading path may be taken as host if it starts with // + final URI uri = new URI(null,"localhost",path,null); + final String norm = uri.normalize().getPath(); + if (norm.startsWith("/../") // Trying to go via the parent dir || norm.equals("/..")) { // Trying to go to the parent dir return false; } - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { return false; } - - int slash2Count = countToken("//", path); - if (isOff(ALLOW_2_SLASHES) && (slash2Count > 0)) { + + final int slash2Count = countToken("//", path); + if (isOff(ALLOW_2_SLASHES) && slash2Count > 0) { return false; } @@ -473,7 +517,7 @@ * @param query Query value to validate. * @return true if query is valid. */ - protected boolean isValidQuery(String query) { + protected boolean isValidQuery(final String query) { if (query == null) { return true; } @@ -482,63 +526,28 @@ } /** - * Returns true if the given fragment is null or fragments are allowed. - * @param fragment Fragment value to validate. - * @return true if fragment is valid. + * Validate scheme. If schemes[] was initialized to a non null, + * then only those schemes are allowed. + * Otherwise the default schemes are "http", "https", "ftp". + * Matching is case-blind. + * @param scheme The scheme to validate. A null value is considered + * invalid. + * @return true if valid. */ - protected boolean isValidFragment(String fragment) { - if (fragment == null) { - return true; + protected boolean isValidScheme(final String scheme) { + if (scheme == null) { + return false; } - return isOff(NO_FRAGMENTS); - } + if (!SCHEME_PATTERN.matcher(scheme).matches()) { + return false; + } - /** - * Returns the number of times the token appears in the target. - * @param token Token value to be counted. - * @param target Target value to count tokens in. - * @return the number of tokens. - */ - protected int countToken(String token, String target) { - int tokenIndex = 0; - int count = 0; - while (tokenIndex != -1) { - tokenIndex = target.indexOf(token, tokenIndex); - if (tokenIndex > -1) { - tokenIndex++; - count++; - } + if (isOff(ALLOW_ALL_SCHEMES) && !allowedSchemes.contains(scheme.toLowerCase(Locale.ENGLISH))) { + return false; } - return count; - } - /** - * Tests whether the given flag is on. If the flag is not a power of 2 - * (ie. 3) this tests whether the combination of flags is on. - * - * @param flag Flag value to check. - * - * @return whether the specified flag value is on. - */ - private boolean isOn(long flag) { - return (options & flag) > 0; + return true; } - /** - * Tests whether the given flag is off. If the flag is not a power of 2 - * (ie. 3) this tests whether the combination of flags is off. - * - * @param flag Flag value to check. - * - * @return whether the specified flag value is off. - */ - private boolean isOff(long flag) { - return (options & flag) == 0; - } - - // Unit test access to pattern matcher - Matcher matchURL(String value) { - return URL_PATTERN.matcher(value); - } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ABANumberCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ABANumberCheckDigit.java (.../ABANumberCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ABANumberCheckDigit.java (.../ABANumberCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -41,8 +41,7 @@ * Routing transit number. *

    * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class ABANumberCheckDigit extends ModulusCheckDigit { @@ -52,13 +51,13 @@ public static final CheckDigit ABAN_CHECK_DIGIT = new ABANumberCheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {3, 1, 7}; + private static final int[] POSITION_WEIGHT = {3, 1, 7}; /** - * Construct a modulus 10 Check Digit routine for ABA Numbers. + * Constructs a modulus 10 Check Digit routine for ABA Numbers. */ public ABANumberCheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** @@ -77,8 +76,8 @@ * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int weight = POSITION_WEIGHT[rightPos % 3]; // CHECKSTYLE IGNORE MagicNumber + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + final int weight = POSITION_WEIGHT[rightPos % 3]; // CHECKSTYLE IGNORE MagicNumber return charValue * weight; } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CUSIPCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CUSIPCheckDigit.java (.../CUSIPCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CUSIPCheckDigit.java (.../CUSIPCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -36,8 +36,7 @@ * for more details. *

    * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class CUSIPCheckDigit extends ModulusCheckDigit { @@ -47,13 +46,13 @@ public static final CheckDigit CUSIP_CHECK_DIGIT = new CUSIPCheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {2, 1}; + private static final int[] POSITION_WEIGHT = {2, 1}; /** - * Construct an CUSIP Indetifier Check Digit routine. + * Constructs a CUSIP Identifier Check Digit routine. */ public CUSIPCheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** @@ -63,12 +62,12 @@ * @param leftPos The position of the character in the code, counting from left to right * @param rightPos The position of the character in the code, counting from right to left * @return The integer value of the character - * @throws CheckDigitException if character is not alphanumeric + * @throws CheckDigitException if the character is not alphanumeric */ @Override - protected int toInt(char character, int leftPos, int rightPos) + protected int toInt(final char character, final int leftPos, final int rightPos) throws CheckDigitException { - int charValue = Character.getNumericValue(character); + final int charValue = Character.getNumericValue(character); // the final character is only allowed to reach 9 final int charMax = rightPos == 1 ? 9 : 35; // CHECKSTYLE IGNORE MagicNumber if (charValue < 0 || charValue > charMax) { @@ -79,7 +78,7 @@ } /** - *

    Calculates the weighted value of a charcter in the + *

    Calculates the weighted value of a character in the * code at a specified position.

    * *

    For CUSIP (from right to left) odd digits are weighted @@ -88,13 +87,13 @@ * * @param charValue The numeric value of the character. * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left + * @param rightPos The position of the character in the code, counting from right to left * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int weight = POSITION_WEIGHT[rightPos % 2]; - int weightedValue = (charValue * weight); + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + final int weight = POSITION_WEIGHT[rightPos % 2]; + final int weightedValue = charValue * weight; return ModulusCheckDigit.sumDigits(weightedValue); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java (.../CheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java (.../CheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,6 +16,8 @@ */ package org.apache.commons.validator.routines.checkdigit; +import org.apache.commons.validator.routines.CodeValidator; + /** * Check Digit calculation and validation. *

    @@ -28,24 +30,23 @@ *

    *

    * Although Commons Validator is primarily concerned with validation, - * {@link CheckDigit} also defines behaviour for calculating/generating check + * {@link CheckDigit} also defines behavior for calculating/generating check * digits, since it makes sense that users will want to (re-)use the * same logic for both. The {@link org.apache.commons.validator.routines.ISBNValidator} * makes specific use of this feature by providing the facility to validate ISBN-10 codes * and then convert them to the new ISBN-13 standard. *

    *

    - * CheckDigit is used by the new generic @link CodeValidator} implementation. + * CheckDigit is used by the new generic {@link CodeValidator} implementation. *

    * - *

    Implementations

    - * See the + *

    Implementations

    + * See the * Package Summary for a full * list of implementations provided within Commons Validator. * * @see org.apache.commons.validator.routines.CodeValidator - * @version $Revision: 1649287 $ - * @since Validator 1.4 + * @since 1.4 */ public interface CheckDigit { @@ -63,8 +64,8 @@ * Validates the check digit for the code. * * @param code The code to validate, the string must include the check digit. - * @return true if the check digit is valid, otherwise - * false. + * @return {@code true} if the check digit is valid, otherwise + * {@code false}. */ boolean isValid(String code); Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java (.../CheckDigitException.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java (.../CheckDigitException.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -19,36 +19,35 @@ /** * Check Digit calculation/validation error. * - * @version $Revision: 1649191 $ - * @since Validator 1.4 + * @since 1.4 */ public class CheckDigitException extends Exception { private static final long serialVersionUID = -3519894732624685477L; /** - * Construct an Exception with no message. + * Constructs an Exception with no message. */ public CheckDigitException() { } /** - * Construct an Exception with a message. + * Constructs an Exception with a message. * * @param msg The error message. */ - public CheckDigitException(String msg) { + public CheckDigitException(final String msg) { super(msg); } /** - * Construct an Exception with a message and + * Constructs an Exception with a message and * the underlying cause. * * @param msg The error message. * @param cause The underlying cause of the error */ - public CheckDigitException(String msg, Throwable cause) { + public CheckDigitException(final String msg, final Throwable cause) { super(msg, cause); } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java (.../EAN13CheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java (.../EAN13CheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -37,8 +37,7 @@ * Standard Book Number (ISBN). * * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class EAN13CheckDigit extends ModulusCheckDigit { @@ -48,13 +47,13 @@ public static final CheckDigit EAN13_CHECK_DIGIT = new EAN13CheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {3, 1}; + private static final int[] POSITION_WEIGHT = {3, 1}; /** - * Construct a modulus 10 Check Digit routine for EAN/UPC. + * Constructs a modulus 10 Check Digit routine for EAN/UPC. */ public EAN13CheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** @@ -71,8 +70,7 @@ * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int weight = POSITION_WEIGHT[rightPos % 2]; - return charValue * weight; + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + return charValue * POSITION_WEIGHT[rightPos % 2]; } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java (.../IBANCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java (.../IBANCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -37,8 +37,7 @@ * Wikipedia - * IBAN number. * - * @version $Revision: 1739357 $ - * @since Validator 1.4 + * @since 1.4 */ public final class IBANCheckDigit implements CheckDigit, Serializable { @@ -56,36 +55,12 @@ private static final long MODULUS = 97; /** - * Construct Check Digit routine for IBAN Numbers. + * Constructs Check Digit routine for IBAN Numbers. */ public IBANCheckDigit() { } /** - * Validate the check digit of an IBAN code. - * - * @param code The code to validate - * @return true if the check digit is valid, otherwise - * false - */ - @Override - public boolean isValid(String code) { - if (code == null || code.length() < MIN_CODE_LEN) { - return false; - } - String check = code.substring(2,4); // CHECKSTYLE IGNORE MagicNumber - if ("00".equals(check) || "01".equals(check) || "99".equals(check)) { - return false; - } - try { - int modulusResult = calculateModulus(code); - return (modulusResult == 1); - } catch (CheckDigitException ex) { - return false; - } - } - - /** * Calculate the Check Digit for an IBAN code. *

    * Note: The check digit is the third and fourth @@ -99,14 +74,13 @@ @Override public String calculate(String code) throws CheckDigitException { if (code == null || code.length() < MIN_CODE_LEN) { - throw new CheckDigitException("Invalid Code length=" + - (code == null ? 0 : code.length())); + throw new CheckDigitException("Invalid Code length=" + (code == null ? 0 : code.length())); } code = code.substring(0, 2) + "00" + code.substring(4); // CHECKSTYLE IGNORE MagicNumber - int modulusResult = calculateModulus(code); - int charValue = (98 - modulusResult); // CHECKSTYLE IGNORE MagicNumber - String checkDigit = Integer.toString(charValue); - return (charValue > 9 ? checkDigit : "0" + checkDigit); // CHECKSTYLE IGNORE MagicNumber + final int modulusResult = calculateModulus(code); + final int charValue = 98 - modulusResult; // CHECKSTYLE IGNORE MagicNumber + final String checkDigit = Integer.toString(charValue); + return charValue > 9 ? checkDigit : "0" + checkDigit; // CHECKSTYLE IGNORE MagicNumber } /** @@ -117,21 +91,43 @@ * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ - private int calculateModulus(String code) throws CheckDigitException { - String reformattedCode = code.substring(4) + code.substring(0, 4); // CHECKSTYLE IGNORE MagicNumber + private int calculateModulus(final String code) throws CheckDigitException { + final String reformattedCode = code.substring(4) + code.substring(0, 4); // CHECKSTYLE IGNORE MagicNumber long total = 0; for (int i = 0; i < reformattedCode.length(); i++) { - int charValue = Character.getNumericValue(reformattedCode.charAt(i)); + final int charValue = Character.getNumericValue(reformattedCode.charAt(i)); if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { - throw new CheckDigitException("Invalid Character[" + - i + "] = '" + charValue + "'"); + throw new CheckDigitException("Invalid Character[" + i + "] = '" + charValue + "'"); } total = (charValue > 9 ? total * 100 : total * 10) + charValue; // CHECKSTYLE IGNORE MagicNumber if (total > MAX) { total = total % MODULUS; } } - return (int)(total % MODULUS); + return (int) (total % MODULUS); } + /** + * Validate the check digit of an IBAN code. + * + * @param code The code to validate + * @return {@code true} if the check digit is valid, otherwise + * {@code false} + */ + @Override + public boolean isValid(final String code) { + if (code == null || code.length() < MIN_CODE_LEN) { + return false; + } + final String check = code.substring(2, 4); // CHECKSTYLE IGNORE MagicNumber + if ("00".equals(check) || "01".equals(check) || "99".equals(check)) { + return false; + } + try { + return calculateModulus(code) == 1; + } catch (final CheckDigitException ex) { + return false; + } + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java (.../ISBN10CheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java (.../ISBN10CheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -39,8 +39,7 @@ * Transition details. * * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class ISBN10CheckDigit extends ModulusCheckDigit { @@ -50,27 +49,28 @@ public static final CheckDigit ISBN10_CHECK_DIGIT = new ISBN10CheckDigit(); /** - * Construct a modulus 11 Check Digit routine for ISBN-10. + * Constructs a modulus 11 Check Digit routine for ISBN-10. */ public ISBN10CheckDigit() { - super(11); // CHECKSTYLE IGNORE MagicNumber + super(MODULUS_11); } /** - * Calculates the weighted value of a charcter in the - * code at a specified position. + *

    Convert an integer value to a character at a specified position.

    * - *

    For ISBN-10 (from right to left) digits are weighted - * by their position.

    + *

    Value '10' for position 1 (check digit) converted to 'X'.

    * - * @param charValue The numeric value of the character. - * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left - * @return The weighted value of the character. + * @param charValue The integer value of the character. + * @return The converted character. + * @throws CheckDigitException if an error occurs. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - return charValue * rightPos; + protected String toCheckDigit(final int charValue) + throws CheckDigitException { + if (charValue == 10) { // CHECKSTYLE IGNORE MagicNumber + return "X"; + } + return super.toCheckDigit(charValue); } /** @@ -86,7 +86,7 @@ * @throws CheckDigitException if an error occurs. */ @Override - protected int toInt(char character, int leftPos, int rightPos) + protected int toInt(final char character, final int leftPos, final int rightPos) throws CheckDigitException { if (rightPos == 1 && character == 'X') { return 10; // CHECKSTYLE IGNORE MagicNumber @@ -95,21 +95,20 @@ } /** - *

    Convert an integer value to a character at a specified position.

    + * Calculates the weighted value of a character in the + * code at a specified position. * - *

    Value '10' for position 1 (check digit) converted to 'X'.

    + *

    For ISBN-10 (from right to left) digits are weighted + * by their position.

    * - * @param charValue The integer value of the character. - * @return The converted character. - * @throws CheckDigitException if an error occurs. + * @param charValue The numeric value of the character. + * @param leftPos The position of the character in the code, counting from left to right + * @param rightPos The positionof the character in the code, counting from right to left + * @return The weighted value of the character. */ @Override - protected String toCheckDigit(int charValue) - throws CheckDigitException { - if (charValue == 10) { // CHECKSTYLE IGNORE MagicNumber - return "X"; - } - return super.toCheckDigit(charValue); + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + return charValue * rightPos; } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java (.../ISBNCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java (.../ISBNCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -31,8 +31,7 @@ * ISBN number (rather than this 10 digit ISBN number) which uses the EAN-13 / UPC * standard. * - * @version $Revision: 1739357 $ - * @since Validator 1.4 + * @since 1.4 */ public final class ISBNCheckDigit implements CheckDigit, Serializable { @@ -45,7 +44,7 @@ public static final CheckDigit ISBN13_CHECK_DIGIT = EAN13CheckDigit.EAN13_CHECK_DIGIT; /** Singleton combined ISBN-10 / ISBN-13 Check Digit instance */ - public static final CheckDigit ISBN_CHECK_DIGIT = new ISBNCheckDigit(); + public static final CheckDigit ISBN_CHECK_DIGIT = new ISBNCheckDigit(); /** * Calculate an ISBN-10 or ISBN-13 check digit, depending @@ -64,16 +63,17 @@ * check digit. */ @Override - public String calculate(String code) throws CheckDigitException { - if (code == null || code.length() == 0) { + public String calculate(final String code) throws CheckDigitException { + if (code == null || code.isEmpty()) { throw new CheckDigitException("ISBN Code is missing"); - } else if (code.length() == 9) { // CHECKSTYLE IGNORE MagicNumber + } + if (code.length() == 9) { // CHECKSTYLE IGNORE MagicNumber return ISBN10_CHECK_DIGIT.calculate(code); - } else if (code.length() == 12) { // CHECKSTYLE IGNORE MagicNumber + } + if (code.length() == 12) { // CHECKSTYLE IGNORE MagicNumber return ISBN13_CHECK_DIGIT.calculate(code); - } else { - throw new CheckDigitException("Invalid ISBN Length = " + code.length()); } + throw new CheckDigitException("Invalid ISBN Length = " + code.length()); } /** @@ -86,21 +86,22 @@ * * @param code The ISBN code to validate (should have a length of * 10 or 13) - * @return true if the code has a length of 10 and is + * @return {@code true} if the code has a length of 10 and is * a valid ISBN-10 check digit or the code has a length of 13 and is - * a valid ISBN-13 check digit - otherwise false. + * a valid ISBN-13 check digit - otherwise {@code false}. */ @Override - public boolean isValid(String code) { + public boolean isValid(final String code) { if (code == null) { return false; - } else if (code.length() == 10) { // CHECKSTYLE IGNORE MagicNumber + } + if (code.length() == 10) { // CHECKSTYLE IGNORE MagicNumber return ISBN10_CHECK_DIGIT.isValid(code); - } else if (code.length() == 13) { // CHECKSTYLE IGNORE MagicNumber + } + if (code.length() == 13) { // CHECKSTYLE IGNORE MagicNumber return ISBN13_CHECK_DIGIT.isValid(code); - } else { - return false; } + return false; } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java (.../ISINCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java (.../ISINCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -36,8 +36,7 @@ * for more details. *

    * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class ISINCheckDigit extends ModulusCheckDigit { @@ -49,13 +48,13 @@ public static final CheckDigit ISIN_CHECK_DIGIT = new ISINCheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {2, 1}; + private static final int[] POSITION_WEIGHT = {2, 1}; /** - * Construct an ISIN Indetifier Check Digit routine. + * Constructs an ISIN Identifier Check Digit routine. */ public ISINCheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** @@ -68,44 +67,43 @@ * for the specified code */ @Override - protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { - StringBuilder transformed = new StringBuilder(code.length() * 2); + protected int calculateModulus(final String code, final boolean includesCheckDigit) throws CheckDigitException { + final StringBuilder transformed = new StringBuilder(code.length() * 2); // CHECKSTYLE IGNORE MagicNumber if (includesCheckDigit) { - char checkDigit = code.charAt(code.length()-1); // fetch the last character - if (!Character.isDigit(checkDigit)){ - throw new CheckDigitException("Invalid checkdigit["+ checkDigit+ "] in " + code); + final char checkDigit = code.charAt(code.length() - 1); // fetch the last character + if (!Character.isDigit(checkDigit)) { + throw new CheckDigitException("Invalid checkdigit[" + checkDigit + "] in " + code); } } for (int i = 0; i < code.length(); i++) { - int charValue = Character.getNumericValue(code.charAt(i)); + final int charValue = Character.getNumericValue(code.charAt(i)); if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { - throw new CheckDigitException("Invalid Character[" + - (i + 1) + "] = '" + charValue + "'"); + throw new CheckDigitException("Invalid Character[" + (i + 1) + "] = '" + charValue + "'"); } - // this converts alphanumerics to two digits - // so there is no need to overload toInt() + // this converts alphanumerics to two digits + // so there is no need to overload toInt() transformed.append(charValue); } return super.calculateModulus(transformed.toString(), includesCheckDigit); } /** - *

    Calculates the weighted value of a charcter in the + *

    Calculates the weighted value of a character in the * code at a specified position.

    * - *

    For Luhn (from right to left) odd digits are weighted + *

    For ISIN (from right to left) odd digits are weighted * with a factor of one and even digits with a factor - * of two. Weighted values > 9, have 9 subtracted

    + * of two. Weighted values are reduced to their digital root

    * * @param charValue The numeric value of the character. - * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left + * @param leftPos The position of the character in the code, counting from left to right + * @param rightPos The position of the character in the code, counting from right to left * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int weight = POSITION_WEIGHT[rightPos % 2]; - int weightedValue = (charValue * weight); + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + final int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber + final int weightedValue = charValue * weight; return ModulusCheckDigit.sumDigits(weightedValue); } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java (.../ISSNCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java (.../ISSNCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -20,14 +20,14 @@ * International Standard Serial Number (ISSN) * is an eight-digit serial number used to * uniquely identify a serial publication. - *
     
    + * 
      * The format is:
    - * 
    + *
      * ISSN dddd-dddC
      * where:
      * d = decimal digit (0-9)
      * C = checksum (0-9 or X)
    - * 
    + *
      * The checksum is formed by adding the first 7 digits multiplied by
      * the position in the entire number (counting from the right).
      * For example, abcd-efg would be 8a + 7b + 6c + 5d + 4e +3f +2g.
    @@ -48,38 +48,37 @@
      */
     public final class ISSNCheckDigit extends ModulusCheckDigit {
     
    -
         private static final long serialVersionUID = 1L;
     
         /** Singleton ISSN Check Digit instance */
         public static final CheckDigit ISSN_CHECK_DIGIT = new ISSNCheckDigit();
     
         /**
    -     * Creates the instance using a checkdigit modulus of 11
    +     * Creates the instance using a checkdigit modulus of 11.
          */
         public ISSNCheckDigit() {
    -        super(11); // CHECKSTYLE IGNORE MagicNumber
    +        super(MODULUS_11);
         }
     
         @Override
    -    protected int weightedValue(int charValue, int leftPos, int rightPos) throws CheckDigitException {
    -        return charValue * (9 - leftPos); // CHECKSTYLE IGNORE MagicNumber
    -    }
    -
    -    @Override
    -    protected String toCheckDigit(int charValue) throws CheckDigitException {
    +    protected String toCheckDigit(final int charValue) throws CheckDigitException {
             if (charValue == 10) { // CHECKSTYLE IGNORE MagicNumber
                 return "X";
             }
             return super.toCheckDigit(charValue);
         }
     
         @Override
    -    protected int toInt(char character, int leftPos, int rightPos)
    +    protected int toInt(final char character, final int leftPos, final int rightPos)
                 throws CheckDigitException {
             if (rightPos == 1 && character == 'X') {
                 return 10; // CHECKSTYLE IGNORE MagicNumber
             }
             return super.toInt(character, leftPos, rightPos);
         }
    +
    +    @Override
    +    protected int weightedValue(final int charValue, final int leftPos, final int rightPos) throws CheckDigitException {
    +        return charValue * (9 - leftPos); // CHECKSTYLE IGNORE MagicNumber
    +    }
     }
    Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java
    ===================================================================
    diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07
    --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java	(.../LuhnCheckDigit.java)	(revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80)
    +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java	(.../LuhnCheckDigit.java)	(revision b233be65d6df2834368af4d2e555a00795aa0f07)
    @@ -34,8 +34,7 @@
      * for more details.
      * 

    * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class LuhnCheckDigit extends ModulusCheckDigit { @@ -45,17 +44,17 @@ public static final CheckDigit LUHN_CHECK_DIGIT = new LuhnCheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {2, 1}; + private static final int[] POSITION_WEIGHT = {2, 1}; /** - * Construct a modulus 10 Luhn Check Digit routine. + * Constructs a modulus 10 Luhn Check Digit routine. */ public LuhnCheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** - *

    Calculates the weighted value of a charcter in the + *

    Calculates the weighted value of a character in the * code at a specified position.

    * *

    For Luhn (from right to left) odd digits are weighted @@ -64,13 +63,13 @@ * * @param charValue The numeric value of the character. * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left + * @param rightPos The position of the character in the code, counting from right to left * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber - int weightedValue = charValue * weight; - return weightedValue > 9 ? (weightedValue - 9) : weightedValue; // CHECKSTYLE IGNORE MagicNumber + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + final int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber + final int weightedValue = charValue * weight; + return weightedValue > 9 ? weightedValue - 9 : weightedValue; // CHECKSTYLE IGNORE MagicNumber } } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java (.../ModulusCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java (.../ModulusCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -21,79 +21,73 @@ /** * Abstract Modulus Check digit calculation/validation. *

    - * Provides a base class for building modulus Check - * Digit routines. + * Provides a base class for building modulus Check Digit routines. + *

    *

    - * This implementation only handles single-digit numeric codes, such as - * EAN-13. For alphanumeric codes such as EAN-128 you - * will need to implement/override the toInt() and - * toChar() methods. - *

    + * This implementation only handles single-digit numeric codes, such as EAN-13. For alphanumeric codes such as EAN-128 you will need + * to implement/override the toInt() and toChar() methods. + *

    * - * @version $Revision: 1739357 $ - * @since Validator 1.4 + * @since 1.4 */ public abstract class ModulusCheckDigit implements CheckDigit, Serializable { + static final int MODULUS_10 = 10; + static final int MODULUS_11 = 11; private static final long serialVersionUID = 2948962251251528941L; - // N.B. The modulus can be > 10 provided that the implementing class overrides toCheckDigit and toInt - // (for example as in ISBN10CheckDigit) - private final int modulus; - /** - * Construct a {@link CheckDigit} routine for a specified modulus. + * Add together the individual digits in a number. * - * @param modulus The modulus value to use for the check digit calculation + * @param number The number whose digits are to be added + * @return The sum of the digits */ - public ModulusCheckDigit(int modulus) { - this.modulus = modulus; + public static int sumDigits(final int number) { + int total = 0; + int todo = number; + while (todo > 0) { + total += todo % 10; // CHECKSTYLE IGNORE MagicNumber + todo = todo / 10; // CHECKSTYLE IGNORE MagicNumber + } + return total; } /** - * Return the modulus value this check digit routine is based on. - * - * @return The modulus value this check digit routine is based on + * The modulus can be greater than 10 provided that the implementing class overrides toCheckDigit and toInt (for example as in ISBN10CheckDigit). */ - public int getModulus() { - return modulus; + private final int modulus; + + /** + * Constructs a modulus 10 {@link CheckDigit} routine for a specified modulus. + */ + ModulusCheckDigit() { + this(MODULUS_10); } /** - * Validate a modulus check digit for a code. + * Constructs a {@link CheckDigit} routine for a specified modulus. * - * @param code The code to validate - * @return true if the check digit is valid, otherwise - * false + * @param modulus The modulus value to use for the check digit calculation */ - @Override - public boolean isValid(String code) { - if (code == null || code.length() == 0) { - return false; - } - try { - int modulusResult = calculateModulus(code, true); - return (modulusResult == 0); - } catch (CheckDigitException ex) { - return false; - } + public ModulusCheckDigit(final int modulus) { + this.modulus = modulus; } /** * Calculate a modulus Check Digit for a code which does not yet have one. * - * @param code The code for which to calculate the Check Digit; + * @param code The code for which to calculate the Check Digit; * the check digit should not be included * @return The calculated Check Digit * @throws CheckDigitException if an error occurs calculating the check digit */ @Override - public String calculate(String code) throws CheckDigitException { - if (code == null || code.length() == 0) { + public String calculate(final String code) throws CheckDigitException { + if (code == null || code.isEmpty()) { throw new CheckDigitException("Code is missing"); } - int modulusResult = calculateModulus(code, false); - int charValue = (modulus - modulusResult) % modulus; + final int modulusResult = calculateModulus(code, false); + final int charValue = (modulus - modulusResult) % modulus; return toCheckDigit(charValue); } @@ -106,13 +100,13 @@ * @throws CheckDigitException if an error occurs calculating the modulus * for the specified code */ - protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { + protected int calculateModulus(final String code, final boolean includesCheckDigit) throws CheckDigitException { int total = 0; for (int i = 0; i < code.length(); i++) { - int lth = code.length() + (includesCheckDigit ? 0 : 1); - int leftPos = i + 1; - int rightPos = lth - i; - int charValue = toInt(code.charAt(i), leftPos, rightPos); + final int lth = code.length() + (includesCheckDigit ? 0 : 1); + final int leftPos = i + 1; + final int rightPos = lth - i; + final int charValue = toInt(code.charAt(i), leftPos, rightPos); total += weightedValue(charValue, leftPos, rightPos); } if (total == 0) { @@ -122,46 +116,32 @@ } /** - * Calculates the weighted value of a character in the - * code at a specified position. - *

    - * Some modulus routines weight the value of a character - * depending on its position in the code (e.g. ISBN-10), while - * others use different weighting factors for odd/even positions - * (e.g. EAN or Luhn). Implement the appropriate mechanism - * required by overriding this method. + * Return the modulus value this check digit routine is based on. * - * @param charValue The numeric value of the character - * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left - * @return The weighted value of the character - * @throws CheckDigitException if an error occurs calculating - * the weighted value + * @return The modulus value this check digit routine is based on */ - protected abstract int weightedValue(int charValue, int leftPos, int rightPos) - throws CheckDigitException; + public int getModulus() { + return modulus; + } - /** - * Convert a character at a specified position to an integer value. - *

    - * Note: this implementation only handlers numeric values - * For non-numeric characters, override this method to provide - * character-->integer conversion. + * Validate a modulus check digit for a code. * - * @param character The character to convert - * @param leftPos The position of the character in the code, counting from left to right (for identifiying the position in the string) - * @param rightPos The position of the character in the code, counting from right to left (not used here) - * @return The integer value of the character - * @throws CheckDigitException if character is non-numeric + * @param code The code to validate + * @return {@code true} if the check digit is valid, otherwise + * {@code false} */ - protected int toInt(char character, int leftPos, int rightPos) - throws CheckDigitException { - if (Character.isDigit(character)) { - return Character.getNumericValue(character); + @Override + public boolean isValid(final String code) { + if (code == null || code.isEmpty()) { + return false; } - throw new CheckDigitException("Invalid Character[" + - leftPos + "] = '" + character + "'"); + try { + final int modulusResult = calculateModulus(code, true); + return modulusResult == 0; + } catch (final CheckDigitException ex) { + return false; + } } /** @@ -176,7 +156,7 @@ * @throws CheckDigitException if integer character value * doesn't represent a numeric character */ - protected String toCheckDigit(int charValue) + protected String toCheckDigit(final int charValue) throws CheckDigitException { if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber return Integer.toString(charValue); @@ -186,19 +166,45 @@ } /** - * Add together the individual digits in a number. + * Convert a character at a specified position to an integer value. + *

    + * Note: this implementation only handlers numeric values + * For non-numeric characters, override this method to provide + * character-->integer conversion. * - * @param number The number whose digits are to be added - * @return The sum of the digits + * @param character The character to convert + * @param leftPos The position of the character in the code, counting from left to right (for identifiying the position in the string) + * @param rightPos The position of the character in the code, counting from right to left (not used here) + * @return The integer value of the character + * @throws CheckDigitException if character is non-numeric */ - public static int sumDigits(int number) { - int total = 0; - int todo = number; - while (todo > 0) { - total += todo % 10; // CHECKSTYLE IGNORE MagicNumber - todo = todo / 10; // CHECKSTYLE IGNORE MagicNumber + protected int toInt(final char character, final int leftPos, final int rightPos) + throws CheckDigitException { + if (Character.isDigit(character)) { + return Character.getNumericValue(character); } - return total; + throw new CheckDigitException("Invalid Character[" + + leftPos + "] = '" + character + "'"); } + /** + * Calculates the weighted value of a character in the + * code at a specified position. + *

    + * Some modulus routines weight the value of a character + * depending on its position in the code (e.g. ISBN-10), while + * others use different weighting factors for odd/even positions + * (e.g. EAN or Luhn). Implement the appropriate mechanism + * required by overriding this method. + * + * @param charValue The numeric value of the character + * @param leftPos The position of the character in the code, counting from left to right + * @param rightPos The positionof the character in the code, counting from right to left + * @return The weighted value of the character + * @throws CheckDigitException if an error occurs calculating + * the weighted value + */ + protected abstract int weightedValue(int charValue, int leftPos, int rightPos) + throws CheckDigitException; + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java =================================================================== diff -u -ra5b247dd91cb3ffabf9de46cba029e5537fad087 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java (.../ModulusTenCheckDigit.java) (revision a5b247dd91cb3ffabf9de46cba029e5537fad087) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java (.../ModulusTenCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -23,7 +23,7 @@ /** * General Modulus 10 Check Digit calculation/validation. * - *

    How if Works

    + *

    How it Works

    *

    * This implementation calculates/validates the check digit in the following * way: @@ -42,7 +42,7 @@ *

  • The weighted values of each character are totalled.
  • *
  • The total modulo 10 will be zero for a code with a valid Check Digit.
  • * - *

    Limitations

    + *

    Limitations

    *

    * This implementation has the following limitations: *

      @@ -57,26 +57,26 @@ *

      * Note: This implementation can be combined with the * {@link CodeValidator} in order to ensure the length and characters are valid. - * - *

      Example Usage

      + * + *

      Example Usage

      *

      * This implementation was added after a number of Modulus 10 routines and these * are shown re-implemented using this routine below: - * + * *

      * ABA Number Check Digit Routine (equivalent of * {@link ABANumberCheckDigit}). Weighting factors are [1, 7, 3] * applied from right to left. - * + * *

        * CheckDigit routine = new ModulusTenCheckDigit(new int[] { 1, 7, 3 }, true);
        * 
      - * + * *

      * CUSIP Check Digit Routine (equivalent of {@link CUSIPCheckDigit}). * Weighting factors are [1, 2] applied from right to left and the * digits of the weighted value are summed. - * + * *

        * CheckDigit routine = new ModulusTenCheckDigit(new int[] { 1, 2 }, true, true);
        * 
      @@ -85,7 +85,7 @@ * EAN-13 / UPC Check Digit Routine (equivalent of * {@link EAN13CheckDigit}). Weighting factors are [1, 3] applied * from right to left. - * + * *
        * CheckDigit routine = new ModulusTenCheckDigit(new int[] { 1, 3 }, true);
        * 
      @@ -94,7 +94,7 @@ * Luhn Check Digit Routine (equivalent of {@link LuhnCheckDigit}). * Weighting factors are [1, 2] applied from right to left and the * digits of the weighted value are summed. - * + * *
        * CheckDigit routine = new ModulusTenCheckDigit(new int[] { 1, 2 }, true, true);
        * 
      @@ -103,60 +103,70 @@ * SEDOL Check Digit Routine (equivalent of {@link SedolCheckDigit}). * Weighting factors are [1, 3, 1, 7, 3, 9, 1] applied from left to * right. - * + * *
        * CheckDigit routine = new ModulusTenCheckDigit(new int[] { 1, 3, 1, 7, 3, 9, 1 });
        * 
      * - * @since Validator 1.6 - * @version $Revision: 1739356 $ + * @since 1.6 */ public final class ModulusTenCheckDigit extends ModulusCheckDigit { private static final long serialVersionUID = -3752929983453368497L; + /** + * The weighted values to apply based on the character position + */ private final int[] postitionWeight; + + /** + * {@code true} if use positionWeights from right to left + */ private final boolean useRightPos; + + /** + * {@code true} if sum the digits of the weighted value + */ private final boolean sumWeightedDigits; /** - * Construct a modulus 10 Check Digit routine with the specified weighting + * Constructs a modulus 10 Check Digit routine with the specified weighting * from left to right. - * + * * @param postitionWeight the weighted values to apply based on the * character position */ - public ModulusTenCheckDigit(int[] postitionWeight) { + public ModulusTenCheckDigit(final int[] postitionWeight) { this(postitionWeight, false, false); } /** - * Construct a modulus 10 Check Digit routine with the specified weighting, + * Constructs a modulus 10 Check Digit routine with the specified weighting, * indicating whether its from the left or right. - * + * * @param postitionWeight the weighted values to apply based on the * character position - * @param useRightPos true if use positionWeights from right to + * @param useRightPos {@code true} if use positionWeights from right to * left */ - public ModulusTenCheckDigit(int[] postitionWeight, boolean useRightPos) { + public ModulusTenCheckDigit(final int[] postitionWeight, final boolean useRightPos) { this(postitionWeight, useRightPos, false); } /** - * Construct a modulus 10 Check Digit routine with the specified weighting, + * Constructs a modulus 10 Check Digit routine with the specified weighting, * indicating whether its from the left or right and whether the weighted * digits should be summed. - * + * * @param postitionWeight the weighted values to apply based on the * character position - * @param useRightPos true if use positionWeights from right to + * @param useRightPos {@code true} if use positionWeights from right to * left - * @param sumWeightedDigits true if sum the digits of the + * @param sumWeightedDigits {@code true} if sum the digits of the * weighted value */ - public ModulusTenCheckDigit(int[] postitionWeight, boolean useRightPos, boolean sumWeightedDigits) { - super(10); // CHECKSTYLE IGNORE MagicNumber + public ModulusTenCheckDigit(final int[] postitionWeight, final boolean useRightPos, final boolean sumWeightedDigits) { + super(); this.postitionWeight = Arrays.copyOf(postitionWeight, postitionWeight.length); this.useRightPos = useRightPos; this.sumWeightedDigits = sumWeightedDigits; @@ -168,12 +178,12 @@ * Note: assumes last digit is the check digit * * @param code The code to validate - * @return true if the check digit is valid, otherwise - * false + * @return {@code true} if the check digit is valid, otherwise + * {@code false} */ @Override - public boolean isValid(String code) { - if (code == null || code.length() == 0) { + public boolean isValid(final String code) { + if (code == null || code.isEmpty()) { return false; } if (!Character.isDigit(code.charAt(code.length() - 1))) { @@ -199,15 +209,26 @@ * negative number */ @Override - protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { - int num = Character.getNumericValue(character); + protected int toInt(final char character, final int leftPos, final int rightPos) throws CheckDigitException { + final int num = Character.getNumericValue(character); if (num < 0) { throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); } return num; } /** + * Return a string representation of this implementation. + * + * @return a string representation + */ + @Override + public String toString() { + return getClass().getSimpleName() + "[postitionWeight=" + Arrays.toString(postitionWeight) + ", useRightPos=" + + useRightPos + ", sumWeightedDigits=" + sumWeightedDigits + "]"; + } + + /** * Calculates the weighted value of a character in the code at a * specified position. * @@ -219,25 +240,14 @@ * @return The weighted value of the character. */ @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - int pos = useRightPos ? rightPos : leftPos; - int weight = postitionWeight[(pos - 1) % postitionWeight.length]; + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + final int pos = useRightPos ? rightPos : leftPos; + final int weight = postitionWeight[(pos - 1) % postitionWeight.length]; int weightedValue = charValue * weight; if (sumWeightedDigits) { weightedValue = ModulusCheckDigit.sumDigits(weightedValue); } return weightedValue; } - /** - * Return a string representation of this implementation. - * - * @return a string representation - */ - @Override - public String toString() { - return getClass().getSimpleName() + "[postitionWeight=" + Arrays.toString(postitionWeight) + ", useRightPos=" - + useRightPos + ", sumWeightedDigits=" + sumWeightedDigits + "]"; - } - } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java (.../SedolCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java (.../SedolCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -36,8 +36,7 @@ * for more details. *

      * - * @version $Revision: 1739356 $ - * @since Validator 1.4 + * @since 1.4 */ public final class SedolCheckDigit extends ModulusCheckDigit { @@ -49,13 +48,13 @@ public static final CheckDigit SEDOL_CHECK_DIGIT = new SedolCheckDigit(); /** weighting given to digits depending on their right position */ - private static final int[] POSITION_WEIGHT = new int[] {1, 3, 1, 7, 3, 9, 1}; + private static final int[] POSITION_WEIGHT = {1, 3, 1, 7, 3, 9, 1}; /** - * Construct a modulus 11 Check Digit routine for ISBN-10. + * Constructs a modulus 10 Check Digit routine for ISBN-10. */ public SedolCheckDigit() { - super(10); // CHECKSTYLE IGNORE MagicNumber + super(); } /** @@ -68,28 +67,14 @@ * for the specified code */ @Override - protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { + protected int calculateModulus(final String code, final boolean includesCheckDigit) throws CheckDigitException { if (code.length() > POSITION_WEIGHT.length) { throw new CheckDigitException("Invalid Code Length = " + code.length()); } return super.calculateModulus(code, includesCheckDigit); } /** - * Calculates the weighted value of a charcter in the - * code at a specified position. - * - * @param charValue The numeric value of the character. - * @param leftPos The position of the character in the code, counting from left to right - * @param rightPos The positionof the character in the code, counting from right to left - * @return The weighted value of the character. - */ - @Override - protected int weightedValue(int charValue, int leftPos, int rightPos) { - return charValue * POSITION_WEIGHT[leftPos - 1]; - } - - /** * Convert a character at a specified position to an integer value. * * @param character The character to convert @@ -99,9 +84,9 @@ * @throws CheckDigitException if character is not alphanumeric */ @Override - protected int toInt(char character, int leftPos, int rightPos) + protected int toInt(final char character, final int leftPos, final int rightPos) throws CheckDigitException { - int charValue = Character.getNumericValue(character); + final int charValue = Character.getNumericValue(character); // the check digit is only allowed to reach 9 final int charMax = rightPos == 1 ? 9 : MAX_ALPHANUMERIC_VALUE; // CHECKSTYLE IGNORE MagicNumber if (charValue < 0 || charValue > charMax) { @@ -111,4 +96,18 @@ return charValue; } + /** + * Calculates the weighted value of a character in the + * code at a specified position. + * + * @param charValue The numeric value of the character. + * @param leftPos The position of the character in the code, counting from left to right + * @param rightPos The positionof the character in the code, counting from right to left + * @return The weighted value of the character. + */ + @Override + protected int weightedValue(final int charValue, final int leftPos, final int rightPos) { + return charValue * POSITION_WEIGHT[leftPos - 1]; + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java (.../VerhoeffCheckDigit.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java (.../VerhoeffCheckDigit.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -28,8 +28,7 @@ * See Wikipedia * - Verhoeff algorithm for more details. * - * @version $Revision: 1739357 $ - * @since Validator 1.4 + * @since 1.4 */ public final class VerhoeffCheckDigit implements CheckDigit, Serializable { @@ -39,54 +38,33 @@ public static final CheckDigit VERHOEFF_CHECK_DIGIT = new VerhoeffCheckDigit(); /** D - multiplication table */ - private static final int[][] D_TABLE = new int[][] { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, - {1, 2, 3, 4, 0, 6, 7, 8, 9, 5}, - {2, 3, 4, 0, 1, 7, 8, 9, 5, 6}, - {3, 4, 0, 1, 2, 8, 9, 5, 6, 7}, - {4, 0, 1, 2, 3, 9, 5, 6, 7, 8}, - {5, 9, 8, 7, 6, 0, 4, 3, 2, 1}, - {6, 5, 9, 8, 7, 1, 0, 4, 3, 2}, - {7, 6, 5, 9, 8, 2, 1, 0, 4, 3}, - {8, 7, 6, 5, 9, 3, 2, 1, 0, 4}, - {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}; + private static final int[][] D_TABLE = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 2, 3, 4, 0, 6, 7, 8, 9, 5}, + {2, 3, 4, 0, 1, 7, 8, 9, 5, 6}, + {3, 4, 0, 1, 2, 8, 9, 5, 6, 7}, + {4, 0, 1, 2, 3, 9, 5, 6, 7, 8}, + {5, 9, 8, 7, 6, 0, 4, 3, 2, 1}, + {6, 5, 9, 8, 7, 1, 0, 4, 3, 2}, + {7, 6, 5, 9, 8, 2, 1, 0, 4, 3}, + {8, 7, 6, 5, 9, 3, 2, 1, 0, 4}, + {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}; /** P - permutation table */ - private static final int[][] P_TABLE = new int[][] { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, - {1, 5, 7, 6, 2, 8, 3, 0, 9, 4}, - {5, 8, 0, 3, 7, 9, 6, 1, 4, 2}, - {8, 9, 1, 6, 0, 4, 3, 5, 2, 7}, - {9, 4, 5, 3, 1, 2, 6, 8, 7, 0}, - {4, 2, 8, 6, 5, 7, 3, 9, 0, 1}, - {2, 7, 9, 3, 8, 0, 6, 4, 1, 5}, - {7, 0, 4, 6, 9, 1, 3, 2, 5, 8}}; + private static final int[][] P_TABLE = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 5, 7, 6, 2, 8, 3, 0, 9, 4}, + {5, 8, 0, 3, 7, 9, 6, 1, 4, 2}, + {8, 9, 1, 6, 0, 4, 3, 5, 2, 7}, + {9, 4, 5, 3, 1, 2, 6, 8, 7, 0}, + {4, 2, 8, 6, 5, 7, 3, 9, 0, 1}, + {2, 7, 9, 3, 8, 0, 6, 4, 1, 5}, + {7, 0, 4, 6, 9, 1, 3, 2, 5, 8}}; /** inv: inverse table */ - private static final int[] INV_TABLE = new int[] - {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}; + private static final int[] INV_TABLE = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}; - /** - * Validate the Verhoeff Check Digit for a code. - * - * @param code The code to validate - * @return true if the check digit is valid, - * otherwise false - */ - @Override - public boolean isValid(String code) { - if (code == null || code.length() == 0) { - return false; - } - try { - return (calculateChecksum(code, true) == 0); - } catch (CheckDigitException e) { - return false; - } - } - - /** * Calculate a Verhoeff Check Digit for a code. * * @param code The code to calculate the Check Digit for @@ -95,11 +73,11 @@ * the check digit for the specified code */ @Override - public String calculate(String code) throws CheckDigitException { - if (code == null || code.length() == 0) { + public String calculate(final String code) throws CheckDigitException { + if (code == null || code.isEmpty()) { throw new CheckDigitException("Code is missing"); } - int checksum = calculateChecksum(code, false); + final int checksum = calculateChecksum(code, false); return Integer.toString(INV_TABLE[checksum]); } @@ -111,19 +89,38 @@ * @return The checksum value * @throws CheckDigitException if the code contains an invalid character (i.e. not numeric) */ - private int calculateChecksum(String code, boolean includesCheckDigit) throws CheckDigitException { + private int calculateChecksum(final String code, final boolean includesCheckDigit) throws CheckDigitException { int checksum = 0; for (int i = 0; i < code.length(); i++) { - int idx = code.length() - (i + 1); - int num = Character.getNumericValue(code.charAt(idx)); + final int idx = code.length() - (i + 1); + final int num = Character.getNumericValue(code.charAt(idx)); if (num < 0 || num > 9) { // CHECKSTYLE IGNORE MagicNumber throw new CheckDigitException("Invalid Character[" + - i + "] = '" + ((int)code.charAt(idx)) + "'"); + i + "] = '" + (int)code.charAt(idx) + "'"); } - int pos = includesCheckDigit ? i : i + 1; + final int pos = includesCheckDigit ? i : i + 1; checksum = D_TABLE[checksum][P_TABLE[pos % 8][num]]; // CHECKSTYLE IGNORE MagicNumber } return checksum; } + /** + * Validate the Verhoeff Check Digit for a code. + * + * @param code The code to validate + * @return {@code true} if the check digit is valid, + * otherwise {@code false} + */ + @Override + public boolean isValid(final String code) { + if (code == null || code.isEmpty()) { + return false; + } + try { + return calculateChecksum(code, true) == 0; + } catch (final CheckDigitException e) { + return false; + } + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package-info.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package-info.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package-info.java (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This package contains Check Digit validation/calculation routines. + *

      + * Note that these do not validate the input for length or syntax. Such validation is performed by the org.apache.commons.validator.routines.XYZValidator + * classes. + *

      + */ +package org.apache.commons.validator.routines.checkdigit; \ No newline at end of file Fisheye: Tag b233be65d6df2834368af4d2e555a00795aa0f07 refers to a dead (removed) revision in file `3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package-info.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package-info.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package-info.java (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -0,0 +1,741 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This package contains independent validation routines. + *

      Table of Contents

      + * + * + *

      1. Overview

      + *

      + * Commons Validator serves two purposes: + *

      + *
        + *
      • To provide standard, independent validation routines/functions.
      • + *
      • To provide a mini framework for Validation.
      • + *
      + *

      + * This package has been created, since version 1.3.0, in an attempt to clearly + * separate these two concerns and is the location for the standard, independent + * validation routines/functions in Commons Validator. + *

      + *

      + * The contents of this package have no dependencies on the framework aspect of + * Commons Validator and can be used on their own. + *

      + * + *

      2. Date and Time Validators

      + * + *

      2.1 Overview

      + *

      + * The date and time validators either validate according to a specified format + * or use a standard format for a specified Locale. + *

      + *
        + *
      • Date Validator - validates dates + * converting to a java.util.Date type.
      • + *
      • Calendar Validator - validates dates + * converting to a java.util.Calendar type.
      • + *
      • Time Validator - validates times + * converting to a java.util.Calendar type.
      • + *
      + * + *

      2.2 Validating a Date Value

      + *

      + * You can either use one of the isValid() methods to just determine + * if a date is valid, or use one of the validate() methods to + * validate a date and convert it to a java.util.Date... + *

      + *
      + * // Get the Date validator
      + * DateValidator validator = DateValidator.getInstance();
      + * // Validate/Convert the date
      + * Date fooDate = validator.validate(fooString, "dd/MM/yyyy");
      + * if (fooDate == null) {
      + * // error...not a valid date
      + * return;
      + * }
      + * 
      + *

      The following methods are provided to validate a date/time (return a boolean result): + *

      + *
        + *
      • isValid(value)
      • + *
      • isValid(value, pattern)
      • + *
      • isValid(value, Locale)
      • + *
      • isValid(value, pattern, Locale)
      • + *
      + *

      The following methods are provided to validate a date/time and convert it to either a + * java.util.Date or java.util.Calendar: + *

      + *
        + *
      • validate(value)
      • + *
      • validate(value, pattern)
      • + *
      • validate(value, Locale)
      • + *
      • validate(value, pattern, Locale)
      • + *
      + * + *

      2.3 Formatting

      + *

      + * Formatting and validating are two sides of the same coin. Typically + * input values which are converted from Strings according to a + * specified format also have to be rendered for output in + * the same format. These validators provide the mechanism for formatting from + * date/time objects to Strings. The following methods are provided to format + * date/time values as Strings: + *

      + *
        + *
      • format(date/calendar)
      • + *
      • format(date/calendar, pattern)
      • + *
      • format(date/calendar, Locale)
      • + *
      • format(date/calendar, pattern, Locale)
      • + *
      + * + *

      2.4 Time Zones

      + *

      + * If the date being parsed relates to a different time zone than the + * system default, you can specify the TimeZone to use when + * validating/converting: + *

      + *
      + * // Get the GMT time zone
      + * TimeZone GMT = TimeZone.getInstance("GMT");
      + * // Validate/Convert the date using GMT
      + * Date fooDate = validator.validate(fooString, "dd/MM/yyyy", GMT);
      + * 
      + *

      The following Time Zone flavors of the Validation/Conversion methods + * are provided:

      + *
        + *
      • validate(value, TimeZone)
      • + *
      • validate(value, pattern, TimeZone)
      • + *
      • validate(value, Locale, TimeZone)
      • + *
      • validate(value, pattern, Locale, TimeZone)
      • + *
      + * + *

      2.5 Comparing Dates and Times

      + *

      + * As well as validating that a value is a valid date or time, these validators + * also provide date comparison functions. The DateValidator + * and CalendarValidator provide functions for comparing years, + * quarters, months, weeks and dates and the TimeValidator provides + * functions for comparing hours, minutes, seconds and milliseconds. + * For example, to check that a date is in the current month, you could use + * the compareMonths() method, which compares the year and month + * components of a date: + *

      + *
      + * // Check if the date is in the current month
      + * int compare = validator.compareMonths(fooDate, new Date(), null);
      + * if (compare == 0) {
      + * // do current month processing
      + * return;
      + * }
      + * // Check if the date is in the previous quarter
      + * compare = validator.compareQuarters(fooDate, new Date(), null);
      + * if (compare < 0) {
      + * // do previous quarter processing
      + * return;
      + * }
      + * // Check if the date is in the next year
      + * compare = validator.compareYears(fooDate, new Date(), null);
      + * if (compare > 0) {
      + * // do next year processing
      + * return;
      + * }
      + * 
      + * + *

      3 Numeric Validators

      + * + *

      3.1 Overview

      + *

      + * The numeric validators either validate according to a specified format + * or use a standard format for a specified Locale or use + * a custom format for a specified Locale. + *

      + *
        + *
      • Byte Validator - validates numbers + * converting to a java.lang.Byte type.
      • + *
      • Short Validator - validates numbers + * converting to a java.lang.Short type.
      • + *
      • Integer Validator - validates numbers + * converting to a java.lang.Integer type.
      • + *
      • Long Validator - validates numbers + * converting to a java.lang.Long type.
      • + *
      • Float Validator - validates numbers + * converting to a java.lang.Float type.
      • + *
      • Double Validator - validates numbers + * converting to a java.lang.Double type.
      • + *
      • BigInteger Validator - validates numbers + * converting to a java.math.BigInteger type.
      • + *
      • BigDecimal Validator - validates numbers + * converting to a java.math.BigDecimal type.
      • + *
      + * + *

      3.2 Validating a Numeric Value

      + *

      + * You can either use one of the isValid() methods to just determine + * if a number is valid, or use one of the validate() methods to + * validate a number and convert it to an appropriate type. + *

      + *

      + * The following example validates an integer against a custom pattern + * for the German locale. Please note the format is specified using + * the standard symbols for java.text.DecimalFormat so although + * the decimal separator is indicated as a period (".") in the format, the + * validator will check using the German decimal separator - which is a comma (","). + *

      + *
      + * // Get the Integer validator
      + * IntegerValidator validator = IntegerValidator.getInstance();
      + * // Validate/Convert the number
      + * Integer fooInteger = validator.validate(fooString, "#,##0.00", Locale.GERMAN);
      + * if (fooInteger == null) {
      + * // error...not a valid Integer
      + * return;
      + * }
      + * 
      + *

      The following methods are provided to validate a number (return a boolean result):

      + *
        + *
      • isValid(value)
      • + *
      • isValid(value, pattern)
      • + *
      • isValid(value, Locale)
      • + *
      • isValid(value, pattern, Locale)
      • + *
      + *

      The following methods are provided to validate a number and convert it one of + * the java.lang.Number implementations:

      + *
        + *
      • validate(value)
      • + *
      • validate(value, pattern)
      • + *
      • validate(value, Locale)
      • + *
      • validate(value, pattern, Locale)
      • + *
      + * + *

      3.3 Formatting

      + *

      + * Formatting and validating are two sides of the same coin. Typically + * input values which are converted from Strings according to a + * specified format also have to be rendered for output in + * the same format. These validators provide the mechanism for formatting from + * numeric objects to Strings. The following methods are provided to format + * numeric values as Strings: + *

      + *
        + *
      • format(number)
      • + *
      • format(number, pattern)
      • + *
      • format(number, Locale)
      • + *
      • format(number, pattern, Locale)
      • + *
      + * + *

      3.4 Comparing Numbers

      + *

      + * As well as validating that a value is a valid number, these validators + * also provide functions for validating the minimum, maximum + * and range of a value. + *

      + *
      + * // Check the number is between 25 and 75
      + * if (validator.isInRange(fooInteger, 25, 75) {
      + * // valid...in the specified range
      + * return;
      + * }
      + * 
      + * + *

      3.5 Currency Validation

      + *

      + * A default Currency Validator + * implementation is provided, although all the numeric validators + * support currency validation. The default implementation converts + * currency amounts to a java.math.BigDecimal and additionally + * it provides lenient currency symbol validation. That is, currency + * amounts are valid with or without the currency symbol. + *

      + *
      + * BigDecimalValidator validator = CurrencyValidator.getInstance();
      + * BigDecimal fooAmount = validator.validate("$12,500.00", Locale.US);
      + * if (fooAmount == null) {
      + * // error...not a valid currency amount
      + * return;
      + * }
      + * // Check the amount is a minimum of $1,000
      + * if (validator.minValue(fooAmount, 1000) {
      + * // valid...in the specified range
      + * return;
      + * }
      + * 
      + *

      + * If, for example, you want to use the Integer + * Validator to validate a currency, then you can simply create a + * new instance with the appropriate format style. Note that + * the other validators do not support the lenient currency symbol + * validation. + *

      + *
      + * IntegerValidator validator =
      + * new IntegerValidator(true, IntegerValidator.CURRENCY_FORMAT);
      + * String pattern = "#,###" + '\u00A4' + '\u00A4';  // Use international symbol
      + * Integer fooAmount = validator.validate("10.100EUR", pattern, Locale.GERMAN);
      + * if (fooAmount == null) {
      + * // error...not a valid currency amount
      + * return;
      + * }
      + * 
      + * + *

      3.6 Percent Validation

      + *

      + * A default Percent Validator + * implementation is provided, although the Float, + * Double and BigDecimal validators also support + * percent validation. The default implementation converts + * percent amounts to a java.math.BigDecimal and additionally + * it provides lenient percent symbol validation. That is, percent + * amounts are valid with or without the percent symbol. + *

      + *
      + * BigDecimalValidator validator = PercentValidator.getInstance();
      + * BigDecimal fooPercent = validator.validate("20%", Locale.US);
      + * if (fooPercent == null) {
      + * // error...not a valid percent
      + * return;
      + * }
      + * // Check the percent is between 10% and 90%
      + * if (validator.isInRange(fooPercent, 0.1, 0.9) {
      + * // valid...in the specified range
      + * return;
      + * }
      + * 
      + *

      + * If, for example, you want to use the Float + * Validator to validate a percent, then you can simply create a + * new instance with the appropriate format style. Note that + * the other validators do not support the lenient percent symbol + * validation. + *

      + *
      + * FloatValidator validator =
      + * new FloatValidator(true, FloatValidator.PERCENT_FORMAT);
      + * Float fooPercent = validator.validate("20%", "###%");
      + * if (fooPercent == null) {
      + * // error...not a valid percent
      + * return;
      + * }
      + * 
      + *

      + * Note: in theory the other numeric validators besides + * Float, Double and BigDecimal (i.e. Byte, + * Short, Integer, Long and BigInteger) + * also support percent validation. However, since they don't allow fractions + * they will only work with percentages greater than 100%. + *

      + * + *

      4. Other Validators

      + * + *

      4.1 Overview

      + *

      + * This section lists other available validators. + *

      + * + * + *

      4.2 Regular Expression Validation

      + *

      + * Regular expression validation can be done either by using the static + * methods provied by RegexValidator or + * by creating a new instance, which caches and re-uses compiled Patterns. + *

      + *
        + *
      • Method Flavours - three flavors of validation metods are provided:
      • + *
      • + *
          + *
        • isValid() methods return true/false to indicate + * whether validation was successful.
        • + *
        • validate() methods return a String + * value of the matched groups aggregated together or + * null if invalid.
        • + *
        • match() methods return a String array + * of the matched groups or null if invalid.
        • + *
        + *
      • + *
      • Case Sensitivity - matching can be done in either a case + * sensitive or case in-sensitive way.
      • + *
      • Multiple Expressions - instances of the + * RegexValidator + * can be created to either match against a single regular expression + * or set (String array) of regular expressions.
      • + *
      + *

      + * Below is an example of using one of the static methods to validate, + * matching in a case insensitive manner and returning a String + * of the matched groups (which doesn't include the hyphen). + *

      + *
      + * // set up the parameters
      + * boolean caseSensitive   = false;
      + * String regex            = "^([A-Z]*)(?:\\-)([A-Z]*)$";
      + * // validate - result should be a String of value "abcdef"
      + * String result = RegexValidator.validate("abc-def", regex, caseSensitive);
      + * 
      + *

      The following static methods are provided for regular expression validation: + *

      + *
        + *
      • isValid(value, regex)
      • + *
      • isValid(value, regex, caseSensitive)
      • + *
      • validate(value, regex)
      • + *
      • validate(value, regex, caseSensitive)
      • + *
      • match(value, regex)
      • + *
      • match(value, regex, caseSensitive)
      • + *
      + *

      + * Below is an example of creating an instance of + * RegexValidator matching in a case insensitive + * manner against a set of regular expressions: + *

      + *
      + * // set up the parameters
      + * boolean caseSensitive = false;
      + * String regex1   = "^([A-Z]*)(?:\\-)([A-Z]*)*$"
      + * String regex2   = "^([A-Z]*)$";
      + * String[] regexs = new String[] {regex1, regex1};
      + * // Create the validator
      + * RegexValidator validator = new RegexValidator(regexs, caseSensitive);
      + * // Validate true/false
      + * boolean valid = validator.isValid("abc-def");
      + * // Validate and return a String
      + * String result = validator.validate("abc-def");
      + * // Validate and return a String[]
      + * String[] groups = validator.match("abc-def");
      + * 
      + *

      See the + * RegexValidator Javadoc for a full list + * of the available constructors. + *

      + * + *

      4.3 Check Digit validation/calculation

      + *

      + * CheckDigit defines a new + * type for the calculation and validation of check digits with the + * following methods: + *

      + *
        + *
      • isValid(code) - validates the check digit of a code, + * returning {@code true} or {@code false}.
      • + *
      • calculate(code) - calulates the check digit for a code + * returning the check digit character.
      • + *
      + *

      + * The following implementations are provided: + *

      + *
        + *
      • ABANumberCheckDigit + * for ABA Number (or Routing Transit Number (RTN)) check digit calculation.
      • + *
      • CUSIPCheckDigit + * for CUSIP (North American Securities) check digit calculation.
      • + *
      • EAN13CheckDigit + * for EAN-13, UPC, ISBN-13 check digit calculation.
      • + *
      • ISBNCheckDigit + * for ISBN-10 and ISBN-13 check digit calculation.
      • + *
      • ISBN10CheckDigit + * for ISBN-10 check digit calculation.
      • + *
      • ISINCheckDigit + * for ISIN International Securities Identifying Number check digit calculation.
      • + *
      • LuhnCheckDigit + * for Luhn check digit calculation - used by credit cards.
      • + *
      • ModulusCheckDigit + * - abstract class for custom modulus check digit + * implementations.
      • + *
      • SedolCheckDigit + * for SEDOL (UK Securities) check digit calculation.
      • + *
      • VerhoeffCheckDigit + * for Verhoeff (Dihedral) check digit calculation.
      • + *
      + *

      + * The following examples show validating the check digit of a code: + *

      + *
      + * // Luhn check digit validation
      + * boolean valid = LuhnCheckDigit.INSTANCE.isValid(code);
      + * // EAN / UPC / ISBN-13 check digit validation
      + * boolean valid = EAN13CheckDigit.INSTANCE.isValid(code);
      + * // ISBN-10 check digit validation
      + * boolean valid = ISBNCheckDigit.ISBN10.isValid(code);
      + * boolean valid = ISBN10CheckDigit.INSTANCE.isValid(code);
      + * // ISBN-13 check digit validation
      + * boolean valid = ISBNCheckDigit.ISBN13.isValid(code);
      + * // ISBN-10 or ISBN-13 check digit validation
      + * boolean valid = ISBNCheckDigit.ISBN.isValid(code);
      + * 
      + *

      + * The following examples show calulating the check digit of a code: + *

      + *
      + * // Luhn check digit validation
      + * char checkdigit = LuhnCheckDigit.INSTANCE.calculate(code);
      + * // EAN / UPC / ISBN-13 check digit validation
      + * char checkdigit = EAN13CheckDigit.INSTANCE.calculate(code);
      + * // ISBN-10 check digit validation
      + * char checkdigit = ISBNCheckDigit.ISBN10.isValid(code);
      + * char checkdigit = ISBN10CheckDigit.INSTANCE.calculate(code);
      + * // ISBN-13 check digit validation
      + * char checkdigit = ISBNCheckDigit.ISBN13.calculate(code);
      + * // ISBN-10 or ISBN-13 check digit validation
      + * char checkdigit = ISBNCheckDigit.ISBN.calculate(code);
      + * 
      + * + *

      4.4 General Code validation

      + *

      + * CodeValidator provides a generic + * implementation for validating codes. It performs the following + * validations on a code: + *

      + *
        + *
      • Format - the format of the code is validated using + * a regular expression (see RegexValidator).
      • + *
      • Length - the minimum/maximum length of the code is + * checked - after being parsed by the regular expression - with which + * format characters can be removed with the use of + * non-capturing groups.
      • + *
      • Check Digit - a CheckDigit + * routine checks that code's check digit is valid.
      • + *
      + *

      + * For example to create a validator to validate EAN-13 codes (numeric, + * with a length of 13): + *

      + *
      + * // Create an EAN-13 code validator
      + * CodeValidator validator = new CodeValidator("^[0-9]*$", 13, EAN13CheckDigit.INSTANCE);
      + * // Validate an EAN-13 code
      + * if (!validator.isValid(code)) {
      + * ... // invalid
      + * }
      + * 
      + * + *

      4.5 ISBN validation

      + *

      + * ISBNValidator provides ISBN-10 + * and ISBN-13 validation and can optionally convert + * ISBN-10 codes to ISBN-13. + *

      + *
        + *
      • ISBN-10 - validates using a + * CodeValidator with the + * ISBN10CheckDigit + * routine.
      • + *
      • + *
          + *
        • isValidISBN10(value) - returns a boolean
        • + *
        • validateISBN10(value) - returns a reformatted ISBN-10 code
        • + *
        + *
      • + *
      • ISBN-13 - validates using a + * CodeValidator with the + * EAN13CheckDigit + * routine.
      • + *
      • + *
          + *
        • isValidISBN13(value) - returns a boolean
        • + *
        • validateISBN13(value) - returns a reformatted ISBN-13 code
        • + *
        + *
      • + *
      • ISBN-10 and ISBN-13 - validates codes are either + * valid ISBN-10 or valid ISBN-13 - optionally can convert ISBN-10 codes to ISBN-13.
      • + *
      • + *
          + *
        • isValid(value) - returns a boolean
        • + *
        • validate(value) - returns a reformatted ISBN code + * (converts ISBN-10 to ISBN-13 if the convert option is {@code true}).
        • + *
        + *
      • + *
      + *

      + * For example to validate + *

      + *
      + * // Validate an ISBN-10 or ISBN-13 code
      + * if (!ISBNValidator.getInstance().isValid(code)) {
      + * ... // invalid
      + * }
      + * // Validate an ISBN-10 or ISBN-13 code (converting to ISBN-13)
      + * String code = ISBNValidator.getInstance().validate(code);
      + * // Validate an ISBN-10 or ISBN-13 code (not converting)
      + * String code = ISBNValidator.getInstance(false).validate(code);
      + * 
      + * + *

      4.6 IP Address Validation

      + *

      + * InetAddressValidator provides + * IPv4 address validation. + *

      + *

      + * For example: + *

      + *
      + * // Get an InetAddressValidator
      + * InetAddressValidator validator = InetAddressValidator.getInstance();
      + * // Validate an IPv4 address
      + * if (!validator.isValid(candidateInetAddress)) {
      + * ... // invalid
      + * }
      + * 
      + * + *

      4.7 Email Address Validation

      + *

      + * EmailValidator provides email address + * validation according to RFC 822 standards. + *

      + *

      + * For example: + *

      + *
      + * // Get an EmailValidator
      + * EmailValidator validator = EmailValidator.getInstance();
      + * // Validate an email address
      + * boolean isAddressValid = validator.isValid("user@apache.org");
      + * // Validate a variable containing an email address
      + * if (!validator.isValid(addressFromUserForm)) {
      + * webController.sendRedirect(ERROR_REDIRECT, "Email address isn't valid");
      + * // etc.
      + * }
      + * 
      + * + *

      4.8 URL Validation

      + *

      + * UrlValidator provides URL validation by + * checking the scheme, authority, path, query, and fragment in turn. Clients + * may specify valid schemes to be used in validating in addition to or instead of + * the default values (HTTP, HTTPS, FTP). The UrlValidator also supports options + * that change the parsing rules; for example, the ALLOW_2_SLASHES option instructs + * the Validator to allow consecutive slash characters in the path component, which + * is considered an error by default. + * For more information on the available options, see the UrlValidator documentation. + *

      + *

      + * For example: + *

      + *
      + * // Get an UrlValidator
      + * UrlValidator defaultValidator = new UrlValidator(); // default schemes
      + * if (defaultValidator.isValid("http://www.apache.org")) {
      + * ... // valid
      + * }
      + * if (!defaultValidator.isValid("http//www.oops.com")) {
      + * ... // invalid
      + * }
      + * // Get an UrlValidator with custom schemes
      + * String[] customSchemes = { "sftp", "scp", "https" };
      + * UrlValidator customValidator = new UrlValidator(customSchemes);
      + * if (!customValidator.isValid("http://www.apache.org")) {
      + * ... // invalid due to insecure protocol
      + * }
      + * // Get an UrlValidator that allows double slashes in the path
      + * UrlValidator doubleSlashValidator = new UrlValidator(UrlValidator.ALLOW_2_SLASHES);
      + * if (doubleSlashValidator.isValid("http://www.apache.org//projects")) {
      + * ... // valid only in this Validator instance
      + * }
      + * 
      + * + *

      4.9 Domain Name Validation

      + *

      + * DomainValidator provides validation of Internet + * domain names as specified by RFC1034/RFC1123 and according to the IANA-recognized + * list of top-level domains (TLDs). Clients may validate an entire domain name, a + * TLD of any category, or a TLD within a specific category. + *

      + *

      + * For example: + *

      + *
      + * // Get a DomainValidator
      + * DomainValidator validator = DomainValidator.getInstance();
      + * // Validate a domain name
      + * if (validator.isValid("www.apache.org")) {
      + * ... // valid
      + * }
      + * if (!validator.isValid("www.apache.wrong")) {
      + * ... // invalid
      + * }
      + * // Validate a TLD
      + * if (validator.isValidTld(".com")) {
      + * ... // valid
      + * }
      + * if (validator.isValidTld("org")) {
      + * ... // valid, the leading dot is optional
      + * }
      + * if (validator.isValidTld(".us")) {
      + * ... // valid, country code TLDs are also accepted
      + * }
      + * // Validate TLDs in categories
      + * if (validator.isValidGenericTld(".name")) {
      + * ... // valid
      + * }
      + * if (!validator.isValidGenericTld(".uk")) {
      + * ... // invalid, .uk is a country code TLD
      + * }
      + * if (!validator.isValidCountryCodeTld(".info")) {
      + * ... // invalid, .info is a generic TLD
      + * }
      + * 
      + */ +package org.apache.commons.validator.routines; \ No newline at end of file Fisheye: Tag b233be65d6df2834368af4d2e555a00795aa0f07 refers to a dead (removed) revision in file `3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java (.../Flags.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java (.../Flags.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -35,8 +35,6 @@ * There cannot be a flag with a value of 3 because that represents Flag 1 * and Flag 2 both being on/true. *

      - * - * @version $Revision: 1739356 $ */ public class Flags implements Serializable, Cloneable { @@ -45,140 +43,77 @@ /** * Represents the current flag state. */ - private long flags = 0; + private long flags; /** * Create a new Flags object. */ public Flags() { - super(); } /** * Initialize a new Flags object with the given flags. * * @param flags collection of boolean flags to represent. */ - public Flags(long flags) { - super(); + public Flags(final long flags) { this.flags = flags; } /** - * Returns the current flags. - * - * @return collection of boolean flags represented. - */ - public long getFlags() { - return this.flags; - } - - /** - * Tests whether the given flag is on. If the flag is not a power of 2 - * (ie. 3) this tests whether the combination of flags is on. - * - * @param flag Flag value to check. - * - * @return whether the specified flag value is on. - */ - public boolean isOn(long flag) { - return (this.flags & flag) == flag; - } - - /** - * Tests whether the given flag is off. If the flag is not a power of 2 - * (ie. 3) this tests whether the combination of flags is off. - * - * @param flag Flag value to check. - * - * @return whether the specified flag value is off. - */ - public boolean isOff(long flag) { - return (this.flags & flag) == 0; - } - - /** - * Turns on the given flag. If the flag is not a power of 2 (ie. 3) this - * turns on multiple flags. - * - * @param flag Flag value to turn on. - */ - public void turnOn(long flag) { - this.flags |= flag; - } - - /** - * Turns off the given flag. If the flag is not a power of 2 (ie. 3) this - * turns off multiple flags. - * - * @param flag Flag value to turn off. - */ - public void turnOff(long flag) { - this.flags &= ~flag; - } - - /** - * Turn off all flags. - */ - public void turnOffAll() { - this.flags = 0; - } - - /** * Turn off all flags. This is a synonym for turnOffAll(). - * @since Validator 1.1.1 + * @since 1.1.1 */ public void clear() { this.flags = 0; } /** - * Turn on all 64 flags. - */ - public void turnOnAll() { - this.flags = 0xFFFFFFFFFFFFFFFFl; - } - - /** * Clone this Flags object. * * @return a copy of this object. - * @see java.lang.Object#clone() + * @see Object#clone() */ @Override public Object clone() { try { return super.clone(); - } catch(CloneNotSupportedException e) { - throw new RuntimeException("Couldn't clone Flags object."); + } catch (final CloneNotSupportedException e) { + throw new UnsupportedOperationException("Couldn't clone Flags object.", e); } } /** * Tests if two Flags objects are in the same state. * @param obj object being tested - * @see java.lang.Object#equals(java.lang.Object) + * @see Object#equals(Object) * * @return whether the objects are equal. */ @Override - public boolean equals(Object obj) { + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } if (!(obj instanceof Flags)) { return false; } + Flags other = (Flags) obj; + return flags == other.flags; + } - if (obj == this) { - return true; - } - - Flags f = (Flags) obj; - - return this.flags == f.flags; + /** + * Returns the current flags. + * + * @return collection of boolean flags represented. + */ + public long getFlags() { + return this.flags; } /** * The hash code is based on the current state of the flags. - * @see java.lang.Object#hashCode() + * @see Object#hashCode() * * @return the hash code for this object. */ @@ -188,6 +123,30 @@ } /** + * Tests whether the given flag is off. If the flag is not a power of 2 + * (ie. 3) this tests whether the combination of flags is off. + * + * @param flag Flag value to check. + * + * @return whether the specified flag value is off. + */ + public boolean isOff(final long flag) { + return (this.flags & flag) == 0; + } + + /** + * Tests whether the given flag is on. If the flag is not a power of 2 + * (ie. 3) this tests whether the combination of flags is on. + * + * @param flag Flag value to check. + * + * @return whether the specified flag value is on. + */ + public boolean isOn(final long flag) { + return (this.flags & flag) == flag; + } + + /** * Returns a 64 length String with the first flag on the right and the * 64th flag on the left. A 1 indicates the flag is on, a 0 means it's * off. @@ -196,11 +155,45 @@ */ @Override public String toString() { - StringBuilder bin = new StringBuilder(Long.toBinaryString(this.flags)); + final StringBuilder bin = new StringBuilder(Long.toBinaryString(this.flags)); for (int i = 64 - bin.length(); i > 0; i--) { // CHECKSTYLE IGNORE MagicNumber bin.insert(0, "0"); } return bin.toString(); } + /** + * Turns off the given flag. If the flag is not a power of 2 (ie. 3) this + * turns off multiple flags. + * + * @param flag Flag value to turn off. + */ + public void turnOff(final long flag) { + this.flags &= ~flag; + } + + /** + * Turn off all flags. + */ + public void turnOffAll() { + this.flags = 0; + } + + /** + * Turns on the given flag. If the flag is not a power of 2 (ie. 3) this + * turns on multiple flags. + * + * @param flag Flag value to turn on. + */ + public void turnOn(final long flag) { + this.flags |= flag; + } + + /** + * Turn on all 64 flags. + */ + public void turnOnAll() { + this.flags = 0xFFFFFFFFFFFFFFFFL; + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java (.../ValidatorUtils.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java (.../ValidatorUtils.java) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -16,12 +16,9 @@ */ package org.apache.commons.validator.util; -import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Map.Entry; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.FastHashMap; // DEPRECATED @@ -37,120 +34,29 @@ * The use of FastHashMap is deprecated and will be replaced in a future * release. *

      - * - * @version $Revision: 1739361 $ */ public class ValidatorUtils { private static final Log LOG = LogFactory.getLog(ValidatorUtils.class); /** - *

      Replace part of a String with another value.

      - * - * @param value String to perform the replacement on. - * @param key The name of the constant. - * @param replaceValue The value of the constant. - * - * @return The modified value. - */ - public static String replace(String value, String key, String replaceValue) { - - if (value == null || key == null || replaceValue == null) { - return value; - } - - int pos = value.indexOf(key); - - if (pos < 0) { - return value; - } - - int length = value.length(); - int start = pos; - int end = pos + key.length(); - - if (length == key.length()) { - value = replaceValue; - - } else if (end == length) { - value = value.substring(0, start) + replaceValue; - - } else { - value = - value.substring(0, start) - + replaceValue - + replace(value.substring(end), key, replaceValue); - } - - return value; - } - - /** - * Convenience method for getting a value from a bean property as a - * String. If the property is a String[] or - * Collection and it is empty, an empty String - * "" is returned. Otherwise, property.toString() is returned. This method - * may return null if there was an error retrieving the - * property. - * - * @param bean The bean object. - * @param property The name of the property to access. - * - * @return The value of the property. - */ - public static String getValueAsString(Object bean, String property) { - Object value = null; - - try { - value = PropertyUtils.getProperty(bean, property); - - } catch(IllegalAccessException e) { - LOG.error(e.getMessage(), e); - } catch(InvocationTargetException e) { - LOG.error(e.getMessage(), e); - } catch(NoSuchMethodException e) { - LOG.error(e.getMessage(), e); - } - - if (value == null) { - return null; - } - - if (value instanceof String[]) { - return ((String[]) value).length > 0 ? value.toString() : ""; - - } else if (value instanceof Collection) { - return ((Collection) value).isEmpty() ? "" : value.toString(); - - } else { - return value.toString(); - } - - } - - /** * Makes a deep copy of a FastHashMap if the values * are Msg, Arg, * or Var. Otherwise it is a shallow copy. * - * @param map FastHashMap to copy. + * @param fastHashMap FastHashMap to copy. * @return FastHashMap A copy of the FastHashMap that was * passed in. * @deprecated This method is not part of Validator's public API. Validator * will use it internally until FastHashMap references are removed. Use * copyMap() instead. */ @Deprecated - public static FastHashMap copyFastHashMap(FastHashMap map) { - FastHashMap results = new FastHashMap(); - + public static FastHashMap copyFastHashMap(final FastHashMap fastHashMap) { + final FastHashMap results = new FastHashMap(); @SuppressWarnings("unchecked") // FastHashMap is not generic - Iterator> i = map.entrySet().iterator(); - while (i.hasNext()) { - Entry entry = i.next(); - String key = entry.getKey(); - Object value = entry.getValue(); - + final HashMap map = fastHashMap; + map.forEach((key, value) -> { if (value instanceof Msg) { results.put(key, ((Msg) value).clone()); } else if (value instanceof Arg) { @@ -160,8 +66,7 @@ } else { results.put(key, value); } - } - + }); results.setFast(true); return results; } @@ -175,15 +80,9 @@ * * @return A copy of the Map that was passed in. */ - public static Map copyMap(Map map) { - Map results = new HashMap(); - - Iterator> i = map.entrySet().iterator(); - while (i.hasNext()) { - Entry entry = i.next(); - String key = entry.getKey(); - Object value = entry.getValue(); - + public static Map copyMap(final Map map) { + final Map results = new HashMap<>(); + map.forEach((key, value) -> { if (value instanceof Msg) { results.put(key, ((Msg) value).clone()); } else if (value instanceof Arg) { @@ -193,8 +92,63 @@ } else { results.put(key, value); } - } + }); return results; } + /** + * Convenience method for getting a value from a bean property as a + * String. If the property is a String[] or + * Collection and it is empty, an empty String + * "" is returned. Otherwise, property.toString() is returned. This method + * may return null if there was an error retrieving the + * property. + * + * @param bean The bean object. + * @param property The name of the property to access. + * + * @return The value of the property. + */ + public static String getValueAsString(final Object bean, final String property) { + Object value = null; + + try { + value = PropertyUtils.getProperty(bean, property); + + } catch (ReflectiveOperationException e) { + LOG.error(e.getMessage(), e); + } + + if (value == null) { + return null; + } + + if (value instanceof String[]) { + return ((String[]) value).length > 0 ? value.toString() : ""; + + } + if (value instanceof Collection) { + return ((Collection) value).isEmpty() ? "" : value.toString(); + + } + return value.toString(); + + } + + /** + *

      Replace part of a String with another value.

      + * + * @param value String to perform the replacement on. + * @param key The name of the constant. + * @param replaceValue The value of the constant. + * + * @return The modified value. + */ + public static String replace(String value, final String key, final String replaceValue) { + if (value == null || key == null || replaceValue == null) { + return value; + } + return value.replace(key, replaceValue); + } + } Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package-info.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package-info.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package-info.java (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This package contains utility classes used by Commons Validator. + */ +package org.apache.commons.validator.util; \ No newline at end of file Fisheye: Tag b233be65d6df2834368af4d2e555a00795aa0f07 refers to a dead (removed) revision in file `3rdParty_sources/commons-validator/org/apache/commons/validator/util/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/versions.txt =================================================================== diff -u -rf353711e365040e186d33adb027851ac0910c551 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- 3rdParty_sources/versions.txt (.../versions.txt) (revision f353711e365040e186d33adb027851ac0910c551) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -23,7 +23,7 @@ Commons IO 2.11 -Commons Validator 1.6 +Commons Validator 1.8.0 CSRF Guard 4.1.3 with a custom modification in CsrfGuardUtils.java Index: idea_project/.idea/libraries/3rdParty.xml =================================================================== diff -u -red81b9f982735b5dfaa60ebfbc942d3e74e28d0b -rb233be65d6df2834368af4d2e555a00795aa0f07 --- idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision ed81b9f982735b5dfaa60ebfbc942d3e74e28d0b) +++ idea_project/.idea/libraries/3rdParty.xml (.../3rdParty.xml) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -8,7 +8,6 @@ - @@ -57,6 +56,7 @@ + Index: lams_build/lib/jakarta-commons/commons-validator-1.6.jar =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb233be65d6df2834368af4d2e555a00795aa0f07 Binary files differ Index: lams_build/lib/jakarta-commons/commons-validator-1.8.0.jar =================================================================== diff -u Binary files differ Index: lams_build/lib/jakarta-commons/validator.module.xml =================================================================== diff -u -r5661c79b661c18221c0eb5e32fe7ec54110e5a65 -rb233be65d6df2834368af4d2e555a00795aa0f07 --- lams_build/lib/jakarta-commons/validator.module.xml (.../validator.module.xml) (revision 5661c79b661c18221c0eb5e32fe7ec54110e5a65) +++ lams_build/lib/jakarta-commons/validator.module.xml (.../validator.module.xml) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -17,7 +17,7 @@ - + Index: lams_build/liblist.txt =================================================================== diff -u -red81b9f982735b5dfaa60ebfbc942d3e74e28d0b -rb233be65d6df2834368af4d2e555a00795aa0f07 --- lams_build/liblist.txt (.../liblist.txt) (revision ed81b9f982735b5dfaa60ebfbc942d3e74e28d0b) +++ lams_build/liblist.txt (.../liblist.txt) (revision b233be65d6df2834368af4d2e555a00795aa0f07) @@ -40,7 +40,7 @@ commons-collections4-4.4.jar 4.4 Apache Software License 2.0 The Apache Software Foundation adds many powerful data structures that accelerate development of Java applications commons-digester-2.1.jar 2.1 Apache Software License 2.0 The Apache Software Foundation XML -> Java object mapping tool commons-fileupload-1.3.3.jar 1.3.3 Apache Software License 1.1 The Apache Software Foundation File upload component for Java servlets - commons-validator-1.6.jar 1.6 Apache License 2.0 The Apache Software Foundation Commons Validator + commons-validator-1.8.jar 1.8 Apache License 2.0 The Apache Software Foundation Commons Validator commons-discovery-0.5.jar 0.5 Apache License 2.0 The Apache Software Foundation commons-compress-1.26.1.jar 1.26.1 Apache License 2.0 The Apache Software Foundation Defines an API for working with ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200, bzip2, 7z, arj, lzma, snappy, DEFLATE, lz4, Brotli, Zstandard, DEFLATE64 and Z files commons-io-2.15.1.jar 2.11 Apache License 2.0 The Apache Software Foundation