Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Arg.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,193 @@ +/* + * 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; + +import java.io.Serializable; + +/** + *

+ * A default argument or an argument for a + * specific validator definition (ex: required) + * can be stored to pass into a message as parameters. This can be used in a + * pluggable validator for constructing locale + * sensitive messages by using java.text.MessageFormat + * or an equivalent class. The resource field can be + * used to determine if the value stored in the argument + * is a value to be retrieved from a locale sensitive + * message retrieval system like java.util.PropertyResourceBundle. + * 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 { + + private static final long serialVersionUID = -8922606779669839294L; + + /** + * The resource bundle name that this Arg's key should be + * resolved in (optional). + * @since Validator 1.1 + */ + protected String bundle = null; + + /** + * The key or value of the argument. + */ + protected String key = null; + + /** + * The name dependency that this argument goes with (optional). + */ + protected String name = null; + + /** + * This argument's position in the message. Set postion=0 to + * make a replacement in this string: "some msg {0}". + * @since Validator 1.1 + */ + protected int position = -1; + + /** + * 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. + */ + protected boolean resource = true; + + /** + * Creates and returns a copy of this object. + * @return A copy of this object. + */ + @Override + public Object clone() { + try { + return super.clone(); + + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e.toString()); + } + } + + /** + * Returns the resource bundle name. + * @return the bundle name. + * @since Validator 1.1 + */ + public String getBundle() { + return this.bundle; + } + + /** + * Gets the key/value. + * @return the key value. + */ + public String getKey() { + return this.key; + } + + /** + * Gets the name of the dependency. + * @return the name of the dependency. + */ + public String getName() { + return this.name; + } + + /** + * Argument's replacement position. + * @return This argument's replacement position. + */ + public int getPosition() { + return this.position; + } + + /** + * Tests whether or not the key is a resource key or literal value. + * @return true if key is a resource key. + */ + public boolean isResource() { + return this.resource; + } + + /** + * Sets the resource bundle name. + * @param bundle The new bundle name. + * @since Validator 1.1 + */ + public void setBundle(String bundle) { + this.bundle = bundle; + } + + /** + * Sets the key/value. + * @param key They to access the argument. + */ + public void setKey(String key) { + this.key = key; + } + + /** + * Sets the name of the dependency. + * @param name the name of the dependency. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Set this argument's replacement position. + * @param position set this argument's replacement position. + */ + public void setPosition(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) { + this.resource = resource; + } + + /** + * Returns a string representation of the object. + * @return a string representation of the object. + */ + @Override + public String toString() { + StringBuilder results = new StringBuilder(); + + results.append("Arg: name="); + results.append(name); + results.append(" key="); + results.append(key); + results.append(" position="); + results.append(position); + results.append(" bundle="); + results.append(bundle); + results.append(" resource="); + results.append(resource); + results.append("\n"); + + return results.toString(); + } + +} \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/CreditCardValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,260 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.validator.util.Flags; + +/** + * Perform credit card validations. + * + *

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

+ * + *
+ * CreditCardValidator ccv = new CreditCardValidator(CreditCardValidator.AMEX + CreditCardValidator.VISA);
+ * 
+ * + *

+ * configures the validator to only pass American Express and Visa cards. + * If a card type is not directly supported by this class, you can implement + * the CreditCardType interface and pass an instance into the + * addAllowedCardType method. + *

+ * + *

+ * For a similar implementation in Perl, reference Sean M. Burke's + * script. + * More information is also available + * here. + *

+ * + * @version $Revision: 1739358 $ + * @since Validator 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 { + + /** + * 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. + *
+     * 
+     * CreditCardValidator v = new CreditCardValidator(CreditCardValidator.NONE);
+     * v.addAllowedCardType(customType);
+     * v.isValid(aCardNumber);
+     * 
+     * 
+ * @since Validator 1.1.2 + */ + public static final int NONE = 0; + + /** + * Option specifying that American Express cards are allowed. + */ + public static final int AMEX = 1 << 0; + + /** + * Option specifying that Visa cards are allowed. + */ + public static final int VISA = 1 << 1; + + /** + * Option specifying that Mastercard cards are allowed. + */ + public static final int MASTERCARD = 1 << 2; + + /** + * Option specifying that Discover cards are allowed. + */ + public static final int DISCOVER = 1 << 3; + + /** + * The CreditCardTypes that are allowed to pass validation. + */ + private final Collection cardTypes = new ArrayList(); + + /** + * Create a new CreditCardValidator with default options. + */ + public CreditCardValidator() { + this(AMEX + VISA + MASTERCARD + DISCOVER); + } + + /** + * Creates 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 CreditCardValidator(int options) { + super(); + + Flags f = new Flags(options); + if (f.isOn(VISA)) { + this.cardTypes.add(new Visa()); + } + + if (f.isOn(AMEX)) { + this.cardTypes.add(new Amex()); + } + + if (f.isOn(MASTERCARD)) { + this.cardTypes.add(new Mastercard()); + } + + if (f.isOn(DISCOVER)) { + this.cardTypes.add(new Discover()); + } + } + + /** + * 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)) { + return false; + } + + if (!this.luhnCheck(card)) { + return false; + } + + for (Object cardType : this.cardTypes) { + CreditCardType type = (CreditCardType) cardType; + if (type.matches(card)) { + return true; + } + } + + return false; + } + + /** + * 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) { + // number must be validated as 0..9 numeric first!! + int digits = cardNumber.length(); + 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) { + return false; + } + + if (((count & 1) ^ oddOrEven) == 0) { // not + digit *= 2; + if (digit > 9) { + digit -= 9; + } + } + sum += digit; + } + + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/DateValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/DateValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,133 @@ +/* + * 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; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Locale; + +/** + *

Perform date validations.

+ *

+ * This class is a Singleton; you can retrieve the instance via the + * getInstance() method. + *

+ * + * @version $Revision: 1739358 $ + * @since Validator 1.1 + * @deprecated Use the new DateValidator, CalendarValidator or TimeValidator in the + * routines package. This class will be removed in a future release. + */ +@Deprecated +public class DateValidator { + + /** + * Singleton instance of this class. + */ + private static final DateValidator DATE_VALIDATOR = new DateValidator(); + + /** + * Returns the Singleton instance of this validator. + * @return A singleton instance of the DateValidator. + */ + public static DateValidator getInstance() { + return DATE_VALIDATOR; + } + + /** + * 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.

+ * + * @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 date is valid. + */ + public boolean isValid(String value, String datePattern, boolean strict) { + + if (value == null + || datePattern == null + || datePattern.length() <= 0) { + + return false; + } + + SimpleDateFormat formatter = new SimpleDateFormat(datePattern); + formatter.setLenient(false); + + try { + formatter.parse(value); + } catch(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.

+ * + * @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. + * @return true if the date is valid. + */ + public boolean isValid(String value, Locale locale) { + + if (value == null) { + return false; + } + + DateFormat formatter = null; + 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) { + return false; + } + + return true; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/EmailValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,226 @@ +/* + * 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; + +import org.apache.commons.validator.routines.InetAddressValidator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *

Perform email validations.

+ *

+ * This class is a Singleton; you can retrieve the instance via the getInstance() method. + *

+ *

+ * Based on a script by Sandeep V. Tamhankar + * http://javascript.internet.com + *

+ *

+ * This implementation is not guaranteed to catch all possible errors in an email address. + * For example, an address like nobody@noplace.somedog will pass validator, even though there + * is no TLD "somedog" + *

. + * + * @version $Revision: 1739358 $ + * @since Validator 1.1 + * @deprecated Use the new EmailValidator in the routines package. This class + * will be removed in a future release. + */ +@Deprecated +public class EmailValidator { + + private static final String SPECIAL_CHARS = "\\p{Cntrl}\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]"; + private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]"; + private static final String QUOTED_USER = "(\"[^\"]*\")"; + private static final String ATOM = VALID_CHARS + '+'; + private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")"; + +// NOT USED private static final Pattern LEGAL_ASCII_PATTERN = Pattern.compile("^\\p{ASCII}+$"); +// 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 + ")"); + + /** + * Singleton instance of this class. + */ + private static final EmailValidator EMAIL_VALIDATOR = new EmailValidator(); + + /** + * Returns the Singleton instance of this validator. + * @return singleton instance of this validator. + */ + public static EmailValidator getInstance() { + return EMAIL_VALIDATOR; + } + + /** + * Protected constructor for subclasses to use. + */ + protected EmailValidator() { + super(); + } + + /** + *

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

+ * + * @param email The value validation is being performed on. A null + * value is considered invalid. + * @return true if the email address is valid. + */ + public boolean isValid(String email) { + return org.apache.commons.validator.routines.EmailValidator.getInstance().isValid(email); + } + + /** + * Returns true if the domain component of an email address is valid. + * @param domain being validated. + * @return true if the email address's domain is valid. + */ + protected boolean isValidDomain(String domain) { + boolean symbolic = false; + + // see if domain is an IP address in brackets + Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); + + if (ipDomainMatcher.matches()) { + InetAddressValidator inetAddressValidator = + InetAddressValidator.getInstance(); + if (inetAddressValidator.isValid(ipDomainMatcher.group(1))) { + return true; + } + } else { + // Domain is symbolic name + symbolic = DOMAIN_PATTERN.matcher(domain).matches(); + } + + if (symbolic) { + if (!isValidSymbolicDomain(domain)) { + return false; + } + } else { + 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); + for (int i = 1; i <= 4; i++) { // CHECKSTYLE IGNORE MagicNumber + String ipSegment = ipAddressMatcher.group(i); + if (ipSegment == null || ipSegment.length() <= 0) { + return false; + } + + int iIpSegment = 0; + + try { + iIpSegment = Integer.parseInt(ipSegment); + } catch(NumberFormatException e) { + return false; + } + + if (iIpSegment > 255) { // CHECKSTYLE IGNORE MagicNumber + return false; + } + + } + return true; + } + + /** + * Validates a symbolic domain name. Returns true if it's valid. + * @param domain symbolic domain name + * @return true if the symbolic domain name is valid. + */ + protected boolean isValidSymbolicDomain(String domain) { + String[] domainSegment = new String[10]; // CHECKSTYLE IGNORE MagicNumber + boolean match = true; + int i = 0; + Matcher atomMatcher = ATOM_PATTERN.matcher(domain); + while (match) { + match = atomMatcher.matches(); + if (match) { + domainSegment[i] = atomMatcher.group(1); + int l = domainSegment[i].length() + 1; + domain = + (l >= domain.length()) + ? "" + : domain.substring(l); + + i++; + } + } + + 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 { + 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 + * @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; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Field.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,965 @@ +/* + * 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; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +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; +import java.util.StringTokenizer; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.collections.FastHashMap; // DEPRECATED +import org.apache.commons.validator.util.ValidatorUtils; + +/** + * This contains the list of pluggable validators to run on a field and any + * message information and variables to perform the validations and generate + * error messages. Instances of this class are configured with a + * <field> xml element. + *

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

+ * + * @version $Revision: 1739361 $ + * @see org.apache.commons.validator.Form + */ +// TODO mutable non-private fields +public class Field implements Cloneable, Serializable { + + private static final long serialVersionUID = -8502647722530192185L; + + /** + * This is the value that will be used as a key if the Arg + * name field has no value. + */ + private static final String DEFAULT_ARG = + "org.apache.commons.validator.Field.DEFAULT"; + + /** + * This indicates an indexed property is being referenced. + */ + public static final String TOKEN_INDEXED = "[]"; + + /** + * The start of a token. + */ + protected static final String TOKEN_START = "${"; + + /** + * The end of a token. + */ + protected static final String TOKEN_END = "}"; + + /** + * A Vriable token. + */ + protected static final String TOKEN_VAR = "var:"; + + /** + * The Field's property name. + */ + protected String property = null; + + /** + * The Field's indexed property name. + */ + protected String indexedProperty = null; + + /** + * The Field's indexed list property name. + */ + protected String indexedListProperty = null; + + /** + * The Field's unique key. + */ + protected String key = null; + + /** + * A comma separated list of validator's this field depends on. + */ + protected String depends = null; + + /** + * The Page Number + */ + protected int page = 0; + + /** + * The flag that indicates whether scripting should be generated + * by the client for client-side validation. + * @since Validator 1.4 + */ + protected boolean clientValidation = true; + + /** + * The order of the Field in the Form. + */ + protected int fieldOrder = 0; + + /** + * 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()); + + /** + * @deprecated Subclasses should use getVarMap() instead. + */ + @Deprecated + protected FastHashMap hVars = new FastHashMap(); // + + /** + * @deprecated Subclasses should use getMsgMap() instead. + */ + @Deprecated + protected FastHashMap hMsgs = new FastHashMap(); // + + /** + * 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 + */ + @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. + */ + public int getPage() { + return this.page; + } + + /** + * 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; + } + + /** + * Gets the position of the Field in the validation list. + * @return The field position. + */ + public int getFieldOrder() { + return this.fieldOrder; + } + + /** + * Sets the position of the Field in the validation list. + * @param fieldOrder The field position. + */ + public void setFieldOrder(int fieldOrder) { + this.fieldOrder = fieldOrder; + } + + /** + * 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) { + getMsgMap().put(msg.getName(), msg); + } + + /** + * Retrieve a message value. + * @param key Validation key. + * @return A validation message for a specified validator. + */ + public String getMsg(String key) { + Msg msg = getMessage(key); + return (msg == null) ? null : msg.getKey(); + } + + /** + * Retrieve a message object. + * @since Validator 1.1.4 + * @param key Validation key. + * @return A validation message for a specified validator. + */ + public Msg getMessage(String key) { + return getMsgMap().get(key); + } + + /** + * The Field's messages are returned as an + * unmodifiable Map. + * @since Validator 1.1.4 + * @return Map of validation messages for 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; + } + + determineArgPosition(arg); + ensureArgsCapacity(arg); + + Map argMap = this.args[arg.getPosition()]; + if (argMap == null) { + argMap = new HashMap(); + this.args[arg.getPosition()] = argMap; + } + + if (arg.getName() == null) { + argMap.put(DEFAULT_ARG, arg); + } else { + argMap.put(arg.getName(), arg); + } + + } + + /** + * Calculate the position of the Arg + */ + private void determineArgPosition(Arg arg) { + + int position = arg.getPosition(); + + // position has been explicity set + if (position >= 0) { + return; + } + + // first arg to be added + if (args == null || args.length == 0) { + arg.setPosition(0); + return; + } + + // 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(); + int lastPosition = -1; + int lastDefault = -1; + for (int i = 0; i < args.length; i++) { + if (args[i] != null && args[i].containsKey(key)) { + lastPosition = i; + } + if (args[i] != null && args[i].containsKey(DEFAULT_ARG)) { + lastDefault = i; + } + } + + if (lastPosition < 0) { + lastPosition = lastDefault; + } + + // allocate the next position + arg.setPosition(++lastPosition); + + } + + /** + * Ensures that the args array can hold the given arg. Resizes the array as + * necessary. + * @param arg Determine if the args array is long enough to store this arg's + * position. + */ + private void ensureArgsCapacity(Arg arg) { + if (arg.getPosition() >= this.args.length) { + @SuppressWarnings("unchecked") // cannot check this at compile time, but it is OK + Map[] newArgs = new Map[arg.getPosition() + 1]; + System.arraycopy(this.args, 0, newArgs, 0, this.args.length); + this.args = newArgs; + } + } + + /** + * 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 + */ + public Arg getArg(int position) { + return this.getArg(DEFAULT_ARG, position); + } + + /** + * Gets the Arg object at the given position. If the key + * finds a null value then the default value will be + * retrieved. + * @param key The name the Arg is stored under. If not found, the default + * 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 + */ + public Arg getArg(String key, int position) { + if ((position >= this.args.length) || (this.args[position] == null)) { + return null; + } + + 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)) { + return null; + } + + 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 + */ + public Arg[] getArgs(String key){ + Arg[] args = new Arg[this.args.length]; + + for (int i = 0; i < this.args.length; i++) { + args[i] = this.getArg(key, i); + } + + return args; + } + + /** + * Add a Var to the Field. + * @param v The Validator Argument. + */ + public void addVar(Var v) { + this.getVarMap().put(v.getName(), v); + } + + /** + * 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 void addVar(String name, String value, String jsType) { + this.addVar(new Var(name, value, jsType)); + } + + /** + * Retrieve a variable. + * @param mainKey The Variable's key + * @return the Variable + */ + public Var getVar(String mainKey) { + return getVarMap().get(mainKey); + } + + /** + * Retrieve a variable's value. + * @param mainKey The Variable's key + * @return the Variable's value + */ + public String getVarValue(String mainKey) { + String value = null; + + Object o = getVarMap().get(mainKey); + if (o != null && o instanceof Var) { + Var v = (Var) o; + value = v.getValue(); + } + + return value; + } + + /** + * 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()); + } + + /** + * Gets a unique key based on the property and indexedProperty fields. + * @return a unique key for the field. + */ + public String getKey() { + if (this.key == null) { + this.generateKey(); + } + + return this.key; + } + + /** + * 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(String key) { + this.key = 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. + */ + public boolean isIndexed() { + return ((indexedListProperty != null && indexedListProperty.length() > 0)); + } + + /** + * Generate correct key value. + */ + public void generateKey() { + if (this.isIndexed()) { + this.key = this.indexedListProperty + TOKEN_INDEXED + "." + this.property; + } else { + this.key = this.property; + } + } + + /** + * Replace constants with values in fields and process the depends field + * to create the dependency Map. + */ + void process(Map globalConstants, 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(); + + property = ValidatorUtils.replace(property, key2, replaceValue); + + processVars(key2, replaceValue); + + this.processMessageComponents(key2, replaceValue); + } + + // 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(); + + property = ValidatorUtils.replace(property, key2, replaceValue); + + processVars(key2, replaceValue); + + this.processMessageComponents(key2, replaceValue); + } + + // 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(); + + this.processMessageComponents(key2, replaceValue); + } + + hMsgs.setFast(true); + } + + /** + * Replace the vars 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)); + } + + } + + /** + * 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; + // Process Messages + if (key != null && !key.startsWith(varKey)) { + for (Iterator i = getMsgMap().values().iterator(); i.hasNext();) { + Msg msg = i.next(); + msg.setKey(ValidatorUtils.replace(msg.getKey(), key, replaceValue)); + } + } + + this.processArg(key, replaceValue); + } + + /** + * Replace the arg Collection key value with the key/value + * pairs passed in. + */ + private void processArg(String key, String replaceValue) { + for (int i = 0; i < this.args.length; i++) { + + Map argMap = this.args[i]; + if (argMap == null) { + continue; + } + + Iterator iter = argMap.values().iterator(); + while (iter.hasNext()) { + Arg arg = iter.next(); + + if (arg != null) { + arg.setKey( + ValidatorUtils.replace(arg.getKey(), key, replaceValue)); + } + } + } + } + + /** + * 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(String validatorName) { + return this.dependencyList.contains(validatorName); + } + + /** + * 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 List getDependencyList() { + return Collections.unmodifiableList(this.dependencyList); + } + + /** + * Creates and returns a copy of this object. + * @return A copy of the Field. + */ + @Override + public Object clone() { + Field field = null; + try { + field = (Field) super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e.toString()); + } + + @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 = 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; + } + + field.hVars = ValidatorUtils.copyFastHashMap(hVars); + field.hMsgs = ValidatorUtils.copyFastHashMap(hMsgs); + + return field; + } + + /** + * Returns a string representation of the object. + * @return A string representation of the object. + */ + @Override + public String toString() { + StringBuilder results = new StringBuilder(); + + results.append("\t\tkey = " + key + "\n"); + results.append("\t\tproperty = " + property + "\n"); + results.append("\t\tindexedProperty = " + indexedProperty + "\n"); + results.append("\t\tindexedListProperty = " + indexedListProperty + "\n"); + results.append("\t\tdepends = " + depends + "\n"); + results.append("\t\tpage = " + page + "\n"); + results.append("\t\tfieldOrder = " + fieldOrder + "\n"); + + if (hVars != null) { + results.append("\t\tVars:\n"); + for (Iterator i = getVarMap().keySet().iterator(); i.hasNext();) { + Object key = i.next(); + results.append("\t\t\t"); + results.append(key); + results.append("="); + results.append(getVarMap().get(key)); + results.append("\n"); + } + } + + return results.toString(); + } + + /** + * 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. + * @param params A Map of parameter class names to parameter values to pass + * into validation methods. + * @param actions A Map of validator names to ValidatorAction objects. + * @return A ValidatorResults object containing validation messages for + * this field. + * @throws ValidatorException If an error occurs during validation. + */ + public ValidatorResults validate(Map params, Map actions) + throws ValidatorException { + + if (this.getDepends() == null) { + return new ValidatorResults(); + } + + ValidatorResults allResults = new ValidatorResults(); + + Object bean = params.get(Validator.BEAN_PARAM); + 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(); + + ValidatorAction action = actions.get(depend); + if (action == null) { + this.handleMissingAction(depend); + } + + boolean good = + validateForRule(action, results, actions, params, fieldNumber); + + if (!good) { + allResults.merge(results); + return allResults; + } + } + allResults.merge(results); + } + + return allResults; + } + + /** + * 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(String name) throws ValidatorException { + throw new ValidatorException("No ValidatorAction named " + name + + " found for field " + this.getProperty()); + } + + /** + * 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; + } + + /** + * 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; + } +} + Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Form.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,352 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections.FastHashMap;// DEPRECATED + +/** + *

+ * + * 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.

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

+ * + * @version $Revision: 1739361 $ + */ +//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; + + /** + * 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(); + + /** + * Map of Fields keyed on their property value. + * + * @deprecated Subclasses should use getFieldMap() instead. + */ + @Deprecated + protected FastHashMap hFields = new FastHashMap(); // + + /** + * The name/key of the form which this form extends from. + * + * @since Validator 1.2.0 + */ + protected String inherit = null; + + /** + * Whether or not the this Form was processed for replacing + * variables in strings with their values. + */ + private boolean processed = false; + + /** + * Gets the name/key of the set of validation rules. + * + * @return The name value + */ + public String getName() { + return name; + } + + /** + * Sets the name/key of the set of validation rules. + * + * @param name The new name value + */ + public void setName(String name) { + this.name = name; + } + + /** + * Add a Field to the Form. + * + * @param f The field + */ + public void addField(Field f) { + this.lFields.add(f); + getFieldMap().put(f.getKey(), f); + } + + /** + * A List of Fields is returned as an unmodifiable + * List. + * + * @return The fields value + */ + public List getFields() { + return Collections.unmodifiableList(lFields); + } + + /** + * 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 Validator 1.1 + */ + public Field getField(String fieldName) { + return getFieldMap().get(fieldName); + } + + /** + * Returns true if this Form contains a Field with the given name. + * + * @param fieldName The field name + * @return True if this form contains the field by the given name + * @since Validator 1.1 + */ + public boolean containsField(String fieldName) { + return getFieldMap().containsKey(fieldName); + } + + /** + * 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 + */ + protected void merge(Form depends) { + + List templFields = new ArrayList(); + @SuppressWarnings("unchecked") // FastHashMap is not generic + Map temphFields = new FastHashMap(); + Iterator dependsIt = depends.getFields().iterator(); + while (dependsIt.hasNext()) { + Field defaultField = dependsIt.next(); + if (defaultField != null) { + String fieldKey = defaultField.getKey(); + if (!this.containsField(fieldKey)) { + templFields.add(defaultField); + temphFields.put(fieldKey, defaultField); + } + else { + Field old = getField(fieldKey); + getFieldMap().remove(fieldKey); + lFields.remove(old); + templFields.add(old); + temphFields.put(fieldKey, old); + } + } + } + lFields.addAll(0, templFields); + getFieldMap().putAll(temphFields); + } + + /** + * Processes all of the Form's Fields. + * + * @param globalConstants A map of global constants + * @param constants Local constants + * @param forms Map of forms + * @since Validator 1.2.0 + */ + protected void process(Map globalConstants, Map constants, Map forms) { + if (isProcessed()) { + return; + } + + int n = 0;//we want the fields from its parent first + if (isExtending()) { + 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(); + //we want to be able to override any fields we like + if (getFieldMap().get(f.getKey()) == null) { + lFields.add(n, f); + getFieldMap().put(f.getKey(), f); + n++; + } + } + } + } + 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(); + f.process(globalConstants, constants); + } + + processed = true; + } + + /** + * Returns a string representation of the object. + * + * @return string representation + */ + @Override + public String toString() { + StringBuilder results = new StringBuilder(); + + results.append("Form: "); + results.append(name); + results.append("\n"); + + for (Iterator i = lFields.iterator(); i.hasNext(); ) { + results.append("\tField: \n"); + results.append(i.next()); + results.append("\n"); + } + + return results.toString(); + } + + /** + * Validate all Fields in this Form on the given page and below. + * + * @param params A Map of parameter class names to parameter + * values to pass into validation methods. + * @param actions A Map of validator names to ValidatorAction + * objects. + * @param page Fields on pages higher than this will not be + * validated. + * @return A ValidatorResults object containing all + * validation messages. + * @throws ValidatorException + */ + ValidatorResults validate(Map params, Map actions, int page) + throws ValidatorException { + return validate(params, actions, page, null); + } + + /** + * Validate all Fields in this Form on the given page and below. + * + * @param params A Map of parameter class names to parameter + * values to pass into validation methods. + * @param actions A Map of validator names to ValidatorAction + * objects. + * @param page Fields on pages higher than this will not be + * validated. + * @return A ValidatorResults object containing all + * validation messages. + * @throws ValidatorException + * @since 1.2.0 + */ + ValidatorResults validate(Map params, Map actions, int page, String fieldName) + throws ValidatorException { + 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); + + if (field == null) { + 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)); + } + } else { + Iterator fields = this.lFields.iterator(); + while (fields.hasNext()) { + Field field = fields.next(); + + params.put(Validator.FIELD_PARAM, field); + + if (field.getPage() <= page) { + results.merge(field.validate(params, actions)); + } + } + } + + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSet.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSet.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,378 @@ +/* + * 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; + +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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * 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; + + /** 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; + + /** Language component of Locale (required). */ + private String language = null; + + /** Country component of Locale (optional). */ + private String country = null; + + /** Variant component of Locale (optional). */ + private String variant = null; + + /** + * A Map of Forms using the name field of the + * Form as the key. + */ + 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(); + + /** + * 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; + + /** + * Flag indicating if this formSet has been merged with its parent (higher + * rank in Locale hierarchy). + */ + private boolean merged; + + /** + * 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 + * . + * + * @return The type value + * @since Validator 1.2.0 + * @throws NullPointerException if there is inconsistency in the locale + * definition (not sure about this) + */ + 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; + } + else if (getCountry() != null) { + if (getLanguage() == null) { + throw new NullPointerException( + "When country is specified, language must be specified."); + } + return COUNTRY_FORMSET; + } + else if (getLanguage() != null) { + return LANGUAGE_FORMSET; + } + else { + return GLOBAL_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 depends FormSet to be merged + * @since Validator 1.2.0 + */ + 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; + } + + /** + * Whether or not the this FormSet was processed for replacing + * variables in strings with their values. + * + * @return The processed value + */ + public boolean isProcessed() { + return processed; + } + + /** + * Gets the equivalent of the language component of Locale. + * + * @return The language value + */ + public String getLanguage() { + return language; + } + + /** + * Sets the equivalent of the language component of Locale. + * + * @param language The new language value + */ + public void setLanguage(String language) { + this.language = language; + } + + /** + * Gets the equivalent of the country component of Locale. + * + * @return The country value + */ + public String getCountry() { + return country; + } + + /** + * Sets the equivalent of the country component of Locale. + * + * @param country The new country value + */ + public void setCountry(String country) { + this.country = country; + } + + /** + * Gets the equivalent of the variant component of Locale. + * + * @return The variant value + */ + public String getVariant() { + return variant; + } + + /** + * Sets the equivalent of the variant component of Locale. + * + * @param variant The new variant value + */ + public void setVariant(String variant) { + this.variant = variant; + } + + /** + * Add a Constant to the locale level. + * + * @param name The constant name + * @param value The constant 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); + } + + } + + /** + * Add a Form to the FormSet. + * + * @param f The form + */ + 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); + } + + } + + /** + * Retrieve a Form based on the form name. + * + * @param formName The form name + * @return The form + */ + public Form getForm(String formName) { + return this.forms.get(formName); + } + + /** + * A Map of Forms is returned as an unmodifiable + * Map with the key based on the form name. + * + * @return The forms map + */ + public Map getForms() { + return Collections.unmodifiableMap(forms); + } + + /** + * Processes all of the Forms. + * + * @param globalConstants Global constants + */ + synchronized void process(Map globalConstants) { + for (Iterator
i = forms.values().iterator(); i.hasNext(); ) { + Form f = i.next(); + f.process(globalConstants, constants, forms); + } + + processed = true; + } + + /** + * Returns a string representation of the object's key. + * + * @return A string representation of the key + */ + 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(); + } + + /** + * Returns a string representation of the object. + * + * @return A string representation + */ + @Override + public String toString() { + StringBuilder results = new StringBuilder(); + + results.append("FormSet: language="); + results.append(language); + results.append(" country="); + results.append(country); + results.append(" variant="); + results.append(variant); + results.append("\n"); + + for (Iterator i = getForms().values().iterator(); i.hasNext(); ) { + results.append(" "); + results.append(i.next()); + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSetFactory.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/FormSetFactory.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,115 @@ +/* + * 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; + +import org.xml.sax.Attributes; +import org.apache.commons.digester.AbstractObjectCreationFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Factory class used by Digester to create FormSet's. + * + * @version $Revision: 1739356 $ + * @since Validator 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.

+ * + * @param resources The validator resources. + * @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 + */ + private FormSet createFormSet(ValidatorResources resources, + String language, + String country, + String variant) throws Exception { + + // Retrieve existing FormSet for the language/country/variant + FormSet formSet = resources.getFormSet(language, country, variant); + if (formSet != null) { + if (getLog().isDebugEnabled()) { + getLog().debug("FormSet[" + formSet.displayKey() + "] found - merging."); + } + return formSet; + } + + // Create a new FormSet for the language/country/variant + formSet = new FormSet(); + formSet.setLanguage(language); + formSet.setCountry(country); + formSet.setVariant(variant); + + // Add the FormSet to the validator resources + resources.addFormSet(formSet); + + if (getLog().isDebugEnabled()) { + getLog().debug("FormSet[" + formSet.displayKey() + "] created."); + } + + return 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 Log getLog() { + if (log == null) { + log = LogFactory.getLog(FormSetFactory.class); + } + return log; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericTypeValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,473 @@ +/* + * 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; + +import java.io.Serializable; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * 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 { + + private static final long serialVersionUID = 5487162314134261703L; + + private static final Log LOG = LogFactory.getLog(GenericTypeValidator.class); + + /** + * Checks if the value can safely be converted to a byte primitive. + * + * @param value The value validation is being performed on. + * @return the converted Byte value. + */ + public static Byte formatByte(String value) { + if (value == null) { + return null; + } + + try { + return Byte.valueOf(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * Checks if the value can safely be converted to a byte 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 Byte value. + */ + public static Byte formatByte(String value, Locale locale) { + Byte result = 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 there was no error and we used the whole string + if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && + num.doubleValue() >= Byte.MIN_VALUE && + num.doubleValue() <= Byte.MAX_VALUE) { + result = Byte.valueOf(num.byteValue()); + } + } + + return result; + } + + /** + * Checks if the value can safely be converted to a short primitive. + * + * @param value The value validation is being performed on. + * @return the converted Short value. + */ + public static Short formatShort(String value) { + if (value == null) { + return null; + } + + try { + return Short.valueOf(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * Checks if the value can safely be converted to a short 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 Short value. + */ + public static Short formatShort(String value, Locale locale) { + Short result = 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 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()); + } + } + + return result; + } + + /** + * Checks if the value can safely be converted to a int primitive. + * + * @param value The value validation is being performed on. + * @return the converted Integer value. + */ + public static Integer formatInt(String value) { + if (value == null) { + return null; + } + + try { + return Integer.valueOf(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * 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 Integer value. + */ + public static Integer formatInt(String value, Locale locale) { + Integer result = 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 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()); + } + } + + return result; + } + + /** + * Checks if the value can safely be converted to a long primitive. + * + * @param value The value validation is being performed on. + * @return the converted Long value. + */ + public static Long formatLong(String value) { + if (value == null) { + return null; + } + + try { + return Long.valueOf(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * 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 Long value. + */ + public static Long formatLong(String value, Locale locale) { + Long result = 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 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()); + } + } + + return result; + } + + /** + * Checks if the value can safely be converted to a float primitive. + * + * @param value The value validation is being performed on. + * @return the converted Float value. + */ + public static Float formatFloat(String value) { + if (value == null) { + return null; + } + + try { + return new Float(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * 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 Float value. + */ + public static Float formatFloat(String value, Locale locale) { + Float result = null; + + if (value != null) { + NumberFormat formatter = null; + if (locale != null) { + formatter = NumberFormat.getInstance(locale); + } else { + formatter = NumberFormat.getInstance(Locale.getDefault()); + } + ParsePosition pos = new ParsePosition(0); + 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()); + } + } + + return result; + } + + /** + * Checks if the value can safely be converted to a double primitive. + * + * @param value The value validation is being performed on. + * @return the converted Double value. + */ + public static Double formatDouble(String value) { + if (value == null) { + return null; + } + + try { + return new Double(value); + } catch (NumberFormatException e) { + return null; + } + + } + + /** + * 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 Double value. + */ + public static Double formatDouble(String value, Locale locale) { + Double result = null; + + if (value != null) { + NumberFormat formatter = null; + if (locale != null) { + formatter = NumberFormat.getInstance(locale); + } else { + formatter = NumberFormat.getInstance(Locale.getDefault()); + } + ParsePosition pos = new ParsePosition(0); + 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()); + } + } + + return result; + } + + /** + * 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(String value, Locale locale) { + Date date = null; + + 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 date; + } + + /** + * Checks if the field is a valid date. + * + *

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 Date formatDate(String value, String datePattern, boolean strict) { + Date date = null; + + if (value == null + || datePattern == null + || datePattern.length() == 0) { + return null; + } + + try { + SimpleDateFormat formatter = new SimpleDateFormat(datePattern); + formatter.setLenient(false); + + date = formatter.parse(value); + + if (strict && datePattern.length() != value.length()) { + date = null; + } + } 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; + } + + /** + * 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/GenericValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,435 @@ +/* + * 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; + +import java.io.Serializable; +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; + +/** + * This class contains basic methods for performing validations. + * + * @version $Revision: 1649191 $ + */ +public class GenericValidator implements Serializable { + + private static final long serialVersionUID = -7212095066891517618L; + + /** + * UrlValidator used in wrapper method. + */ + private static final UrlValidator URL_VALIDATOR = new UrlValidator(); + + /** + * CreditCardValidator used in wrapper method. + */ + private static final CreditCardValidator CREDIT_CARD_VALIDATOR = + new CreditCardValidator(); + + /** + *

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. + * @return true if blank or null. + */ + public static boolean isBlankOrNull(String value) { + return ((value == null) || (value.trim().length() == 0)); + } + + /** + *

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(String value, String regexp) { + if (regexp == null || regexp.length() <= 0) { + return false; + } + + return Pattern.matches(regexp, value); + } + + /** + *

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

+ * + * @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); + } + + /** + *

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(String value) { + return (GenericTypeValidator.formatShort(value) != null); + } + + /** + *

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 can be converted to an Integer. + */ + public static boolean isInt(String value) { + return (GenericTypeValidator.formatInt(value) != null); + } + + /** + *

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 can be converted to a Long. + */ + public static boolean isLong(String value) { + return (GenericTypeValidator.formatLong(value) != null); + } + + /** + *

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); + } + + /** + *

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.

+ * + * @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. + */ + public static boolean isDate(String value, Locale locale) { + return DateValidator.getInstance().isValid(value, locale); + } + + /** + *

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.

+ * + * @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. + */ + 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); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(byte value, byte min, byte max) { + return ((value >= min) && (value <= max)); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(int value, int min, int max) { + return ((value >= min) && (value <= max)); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(float value, float min, float max) { + return ((value >= min) && (value <= max)); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(short value, short min, short max) { + return ((value >= min) && (value <= max)); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(long value, long min, long max) { + return ((value >= min) && (value <= max)); + } + + /** + *

Checks if a value is within a range (min & max specified + * in the vars attribute).

+ * + * @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 in the specified range. + */ + public static boolean isInRange(double value, double min, double max) { + return ((value >= min) && (value <= max)); + } + + /** + * Checks if the field is a valid credit card number. + * @param value The value validation is being performed on. + * @return true if the value is valid Credit Card Number. + */ + public static boolean isCreditCard(String value) { + return CREDIT_CARD_VALIDATOR.isValid(value); + } + + /** + *

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

+ * + * @param value The value validation is being performed on. + * @return true if the value is valid Email Address. + */ + public static boolean isEmail(String value) { + return EmailValidator.getInstance().isValid(value); + } + + /** + *

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) { + return URL_VALIDATOR.isValid(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); + } + + /** + *

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

+ * + * @param value The value validation is being performed on. + * @param max The maximum length. + * @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); + } + + /** + *

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 length. + * @return true if the value's length is more than the specified minimum. + */ + public static boolean minLength(String value, int min) { + return (value.length() >= 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 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 minLength(String value, int min, int lineEndLength) { + int adjustAmount = adjustForLineEnding(value, lineEndLength); + return ((value.length() + adjustAmount) >= min); + } + + /** + * Calculate an adjustment amount for line endings. + * + * 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. + */ + 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)); + } + + // 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.

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

Checks if the value 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. + */ + public static boolean minValue(long value, long min) { + return (value >= min); + } + + /** + *

Checks if the value 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. + */ + public static boolean minValue(double value, double min) { + return (value >= min); + } + + /** + *

Checks if the value 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. + */ + public static boolean minValue(float value, float 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(int value, int max) { + return (value <= max); + } + + /** + *

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(long value, long max) { + return (value <= max); + } + + /** + *

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(double value, double max) { + return (value <= max); + } + + /** + *

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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ISBNValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ISBNValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,56 @@ +/* + * 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; + +/** + * A class for validating 10 digit ISBN codes. + * 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 + * @deprecated Use the new ISBNValidator in the routines package + */ +@Deprecated +public class ISBNValidator { + + /** + * Default Constructor. + */ + public ISBNValidator() { + super(); + } + + /** + * If the ISBN is formatted with space or dash separators its format is + * validated. Then the digits in the number are weighted, summed, and + * divided by 11 according to the ISBN algorithm. If the result is zero, + * the ISBN is valid. This method accepts formatted or raw ISBN codes. + * + * @param isbn Candidate ISBN number to be validated. null is + * considered invalid. + * @return true if the string is a valid ISBN code. + */ + public boolean isValid(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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Msg.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Msg.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,162 @@ +/* + * 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; + +import java.io.Serializable; + +/** + * An alternative message can be associated with a Field + * 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 { + + private static final long serialVersionUID = 5690015734364127124L; + + /** + * The resource bundle name that this Msg's key should be + * resolved in (optional). + * @since Validator 1.1 + */ + protected String bundle = null; + + /** + * The key or value of the argument. + */ + protected String key = null; + + /** + * The name dependency that this argument goes with (optional). + */ + protected String name = null; + + /** + * 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 + */ + protected boolean resource = true; + + /** + * Returns the resource bundle name. + * @return The bundle name. + * @since Validator 1.1 + */ + public String getBundle() { + return this.bundle; + } + + /** + * Sets the resource bundle name. + * @param bundle The new bundle name. + * @since Validator 1.1 + */ + public void setBundle(String bundle) { + this.bundle = bundle; + } + + /** + * Gets the name of the dependency. + * @return The dependency name. + */ + public String getName() { + return name; + } + + /** + * Sets the name of the dependency. + * @param name The dependency name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the key/value. + * @return The message key/value. + */ + public String getKey() { + return key; + } + + /** + * Sets the key/value. + * @param key The message key/value. + */ + public void setKey(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 + */ + public boolean isResource() { + return this.resource; + } + + /** + * Sets whether or not the key is a resource. + * @param resource If true indicates the key is a resource. + * @since Validator 1.1.4 + */ + public void setResource(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(); + + results.append("Msg: name="); + results.append(name); + results.append(" key="); + results.append(key); + results.append(" resource="); + results.append(resource); + results.append(" bundle="); + results.append(bundle); + results.append("\n"); + + return results.toString(); + } + +} \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/UrlValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,468 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.validator.routines.InetAddressValidator; +import org.apache.commons.validator.util.Flags; + +/** + *

Validates URLs.

+ * Behavour of validation is modified by passing in options: + *
    + *
  • ALLOW_2_SLASHES - [FALSE] Allows double '/' characters in the path + * component.
  • + *
  • NO_FRAGMENT- [FALSE] By default fragments are allowed, if this option is + * included then fragments are flagged as illegal.
  • + *
  • ALLOW_ALL_SCHEMES - [FALSE] By default only http, https, and ftp are + * considered valid schemes. Enabling this option will let any scheme pass validation.
  • + *
+ * + *

Originally based in on php script by Debbie Dyer, validation.php v1.2b, Date: 03/07/02, + * http://javascript.internet.com. However, this validation now bears little resemblance + * to the php original.

+ *
+ *   Example of usage:
+ *   Construct a UrlValidator with valid schemes of "http", and "https".
+ *
+ *    String[] schemes = {"http","https"}.
+ *    UrlValidator urlValidator = new UrlValidator(schemes);
+ *    if (urlValidator.isValid("ftp://foo.bar.com/")) {
+ *       System.out.println("url is valid");
+ *    } else {
+ *       System.out.println("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");
+ *    } else {
+ *       System.out.println("url is invalid");
+ *    }
+ *
+ *   prints out "url is valid"
+ *  
+ * + * @see + * + * Uniform Resource Identifiers (URI): Generic Syntax + * + * + * @version $Revision: 1739358 $ + * @since Validator 1.1 + * @deprecated Use the new UrlValidator in the routines package. This class + * will be removed in a future release. + */ +@Deprecated +public class UrlValidator implements Serializable { + + private static final long serialVersionUID = 24137157400029593L; + + /** + * Allows all validly formatted schemes to pass validation instead of + * supplying a set of valid schemes. + */ + public static final int ALLOW_ALL_SCHEMES = 1 << 0; + + /** + * Allow two slashes in the path component of the URL. + */ + public static final int ALLOW_2_SLASHES = 1 << 1; + + /** + * Enabling this options disallows any URL fragments. + */ + public static final int NO_FRAGMENTS = 1 << 2; + + private static final String ALPHA_CHARS = "a-zA-Z"; + +// NOT USED private static final String ALPHA_NUMERIC_CHARS = ALPHA_CHARS + "\\d"; + + private static final String SPECIAL_CHARS = ";/@&=,.?:+$"; + + private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]"; + + // Drop numeric, and "+-." for now + private static final String AUTHORITY_CHARS_REGEX = "\\p{Alnum}\\-\\."; + + private static final String ATOM = VALID_CHARS + '+'; + + /** + * 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 (ie. http:, ftp:,https:). + */ + private static final Pattern SCHEME_PATTERN = Pattern.compile("^\\p{Alpha}[\\p{Alnum}\\+\\-\\.]*"); + + private static final String AUTHORITY_REGEX = + "^([" + AUTHORITY_CHARS_REGEX + "]*)(:\\d*)?(.*)?"; + // 1 2 3 4 + private static final Pattern AUTHORITY_PATTERN = Pattern.compile(AUTHORITY_REGEX); + + private static final int PARSE_AUTHORITY_HOST_IP = 1; + + private static final int PARSE_AUTHORITY_PORT = 2; + + /** + * Should always be empty. + */ + private static final int PARSE_AUTHORITY_EXTRA = 3; + + private static final Pattern PATH_PATTERN = Pattern.compile("^(/[-\\w:@&?=+,.!/~*'%$_;]*)?$"); + + private static final Pattern QUERY_PATTERN = Pattern.compile("^(.*)$"); + + private static final Pattern LEGAL_ASCII_PATTERN = Pattern.compile("^\\p{ASCII}+$"); + + private static final Pattern DOMAIN_PATTERN = + Pattern.compile("^" + ATOM + "(\\." + ATOM + ")*$"); + + private static final Pattern PORT_PATTERN = Pattern.compile("^:(\\d{1,5})$"); + + private static final Pattern ATOM_PATTERN = Pattern.compile("^(" + ATOM + ").*?$"); + + private static final Pattern ALPHA_PATTERN = Pattern.compile("^[" + ALPHA_CHARS + "]"); + + /** + * Holds the set of current validation options. + */ + private final Flags options; + + /** + * The set of schemes that are allowed to be in a URL. + */ + private final Set allowedSchemes = new HashSet(); + + /** + * If no schemes are provided, default to this set. + */ + protected String[] defaultSchemes = {"http", "https", "ftp"}; + + /** + * Create a UrlValidator with default properties. + */ + public UrlValidator() { + this(null); + } + + /** + * 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 + * 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) { + 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) { + this.options = new Flags(options); + + if (this.options.isOn(ALLOW_ALL_SCHEMES)) { + return; + } + + if (schemes == null) { + schemes = this.defaultSchemes; + } + + this.allowedSchemes.addAll(Arrays.asList(schemes)); + } + + /** + *

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. + */ + public boolean isValid(String value) { + if (value == null) { + return false; + } + if (!LEGAL_ASCII_PATTERN.matcher(value).matches()) { + return false; + } + + // Check the whole url address structure + Matcher urlMatcher = URL_PATTERN.matcher(value); + if (!urlMatcher.matches()) { + return false; + } + + if (!isValidScheme(urlMatcher.group(PARSE_URL_SCHEME))) { + return false; + } + + if (!isValidAuthority(urlMatcher.group(PARSE_URL_AUTHORITY))) { + return false; + } + + if (!isValidPath(urlMatcher.group(PARSE_URL_PATH))) { + return false; + } + + if (!isValidQuery(urlMatcher.group(PARSE_URL_QUERY))) { + return false; + } + + if (!isValidFragment(urlMatcher.group(PARSE_URL_FRAGMENT))) { + return false; + } + + return true; + } + + /** + * 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) { + if (authority == null) { + return false; + } + + InetAddressValidator inetAddressValidator = + InetAddressValidator.getInstance(); + + 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); + + if (!ipV4Address) { + // Domain is hostname name + hostname = DOMAIN_PATTERN.matcher(hostIP).matches(); + } + + //rightmost hostname will never start with a digit. + if (hostname) { + // LOW-TECH FIX FOR VALIDATOR-202 + // TODO: Rewrite to use ArrayList and .add semantics: see VALIDATOR-203 + char[] chars = hostIP.toCharArray(); + int size = 1; + for(int i=0; i= hostIP.length()) + ? "" + : hostIP.substring(segmentLength); + + segmentCount++; + } + } + String topLevel = domainSegment[segmentCount - 1]; + if (topLevel.length() < 2 || topLevel.length() > 4) { // CHECKSTYLE IGNORE MagicNumber (deprecated code) + return false; + } + + // First letter of top level must be a alpha + if (!ALPHA_PATTERN.matcher(topLevel.substring(0, 1)).matches()) { + return false; + } + + // Make sure there's a host name preceding the authority. + if (segmentCount < 2) { + return false; + } + } + + if (!hostname && !ipV4Address) { + return false; + } + + String port = authorityMatcher.group(PARSE_AUTHORITY_PORT); + if (port != null && !PORT_PATTERN.matcher(port).matches()) { + return false; + } + + String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); + if (!GenericValidator.isBlankOrNull(extra)) { + return false; + } + + return true; + } + + /** + * 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) { + if (path == null) { + return false; + } + + if (!PATH_PATTERN.matcher(path).matches()) { + return false; + } + + 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){ + return false; + } + + return true; + } + + /** + * Returns true if the query is null or it's a properly formatted query string. + * @param query Query value to validate. + * @return true if query is valid. + */ + protected boolean isValidQuery(String query) { + if (query == null) { + return true; + } + + return QUERY_PATTERN.matcher(query).matches(); + } + + /** + * 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(String fragment) { + if (fragment == null) { + return true; + } + + return options.isOff(NO_FRAGMENTS); + } + + /** + * 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++; + } + } + return count; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Validator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,391 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * 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 { + + private static final long serialVersionUID = -7119418755208731611L; + + /** + * Resources key the JavaBean is stored to perform validation on. + */ + public static final String BEAN_PARAM = "java.lang.Object"; + + /** + * Resources key the ValidatorAction is stored under. + * This will be automatically passed into a validation method + * with the current ValidatorAction if it is + * specified in the method signature. + */ + public static final String VALIDATOR_ACTION_PARAM = + "org.apache.commons.validator.ValidatorAction"; + + /** + * Resources key the ValidatorResults is stored under. + * This will be automatically passed into a validation method + * with the current ValidatorResults if it is + * specified in the method signature. + */ + public static final String VALIDATOR_RESULTS_PARAM = + "org.apache.commons.validator.ValidatorResults"; + + /** + * Resources key the Form is stored under. + * This will be automatically passed into a validation method + * with the current Form if it is + * specified in the method signature. + */ + public static final String FORM_PARAM = "org.apache.commons.validator.Form"; + + /** + * Resources key the Field is stored under. + * This will be automatically passed into a validation method + * with the current Field if it is + * specified in the method signature. + */ + public static final String FIELD_PARAM = "org.apache.commons.validator.Field"; + + /** + * Resources key the Validator is stored under. + * This will be automatically passed into a validation method + * with the current Validator if it is + * specified in the method signature. + */ + public static final String VALIDATOR_PARAM = + "org.apache.commons.validator.Validator"; + + /** + * Resources key the Locale is stored. + * This will be used to retrieve the appropriate + * FormSet and Form to be + * processed. + */ + public static final String LOCALE_PARAM = "java.util.Locale"; + + /** + * The Validator Resources. + */ + protected ValidatorResources resources = null; + + /** + * The name of the form to validate + */ + protected String formName = null; + + /** + * The name of the field on the form to validate + * @since 1.2.0 + */ + protected String fieldName = null; + + /** + * Maps validation method parameter class names to the objects to be passed + * into the method. + */ + protected Map parameters = new HashMap(); // + + /** + * The current page number to validate. + */ + protected int page = 0; + + /** + * 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; + + /** + * Whether or not to use the Context ClassLoader when loading classes + * for instantiating new objects. Default is false. + */ + protected boolean useContextClassLoader = false; + + /** + * Set this to true to not return Fields that pass validation. Only return failures. + */ + protected boolean onlyReturnErrors = false; + + /** + * Construct 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) { + this(resources, null); + } + + /** + * Construct 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) { + if (resources == null) { + throw new IllegalArgumentException("Resources cannot be null."); + } + + this.resources = resources; + this.formName = formName; + } + + /** + * Construct 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. + * @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) { + if (resources == null) { + throw new IllegalArgumentException("Resources cannot be null."); + } + + this.resources = resources; + this.formName = formName; + this.fieldName = fieldName; + } + + /** + * Set 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 setParameter(String parameterClassName, Object parameterValue) { + this.parameters.put(parameterClassName, parameterValue); + } + + /** + * Returns the value of the specified parameter that will be used during the + * processing of validations. + * + * @param parameterClassName The full class name of the parameter of the + * validation method that corresponds to the value/instance passed in with it. + * @return value of the specified parameter. + */ + public Object getParameterValue(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. + */ + public String getFormName() { + return formName; + } + + /** + * Sets the form name which is the key to a set of validation rules. + * @param formName the name of the form. + */ + public void setFormName(String formName) { + this.formName = formName; + } + + /** + * Sets the name of the field to validate in a form (optional) + * + * @param fieldName The name of the field in a form set + * @since 1.2.0 + */ + public void setFieldName(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. + */ + public int getPage() { + return page; + } + + /** + * Sets 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. + *

+ * + * @param page the page number. + */ + public void setPage(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. + */ + public void clear() { + this.formName = null; + this.fieldName = null; + this.parameters = new HashMap(); + this.page = 0; + } + + /** + * 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 + * using Context ClassLoader, then the class-loading defaults to + * using the calling-class' ClassLoader. + * + * @param use determines whether to use Context ClassLoader. + */ + public void setUseContextClassLoader(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 + * Field for the key and the value is the number of error the + * field had. + * @throws ValidatorException If an error occurs during validation + */ + public ValidatorResults validate() throws ValidatorException { + Locale locale = (Locale) this.getParameterValue(LOCALE_PARAM); + + if (locale == null) { + locale = Locale.getDefault(); + } + + this.setParameter(VALIDATOR_PARAM, this); + + Form form = this.resources.getForm(locale, this.formName); + if (form != null) { + this.setParameter(FORM_PARAM, form); + return form.validate( + this.parameters, + this.resources.getValidatorActions(), + this.page, + this.fieldName); + } + + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorAction.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorAction.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,796 @@ +/* + * 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; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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. + * + * Note: The validation method is assumed to be thread safe. + * + * @version $Revision: 1739361 $ + */ +public class ValidatorAction implements Serializable { + + private static final long serialVersionUID = 1339713700053204597L; + + /** + * Logger. + */ + private transient Log log = LogFactory.getLog(ValidatorAction.class); + + /** + * The name of the validation. + */ + private String name = null; + + /** + * The full class name of the class containing + * the validation method associated with this action. + */ + private String classname = null; + + /** + * The Class object loaded from the classname. + */ + private Class validationClass = null; + + /** + * The full method name of the validation to be performed. The method + * must be thread safe. + */ + private String method = null; + + /** + * The Method object loaded from the method name. + */ + private Method validationMethod = null; + + /** + *

+ * 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. + *

+ */ + 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; + + /** + * 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; + + /** + * The default error message associated with this action. + */ + private String msg = null; + + /** + * An optional field to contain the name to be used if JavaScript is + * generated. + */ + private String jsFunctionName = null; + + /** + * An optional field to contain the class path to be used to retrieve the + * JavaScript function. + */ + private String jsFunction = null; + + /** + * An optional field to containing a JavaScript representation of the + * java method assocated with this action. + */ + private String javascript = null; + + /** + * 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; + + /** + * 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()); + + /** + * An internal List representation of all the validation method's + * parameters defined in the methodParams String. + */ + private final List methodParameterList = new ArrayList(); + + /** + * Gets the name of the validator action. + * @return Validator Action name. + */ + public String getName() { + return name; + } + + /** + * Sets the name of the validator action. + * @param name Validator Action name. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the class of the validator action. + * @return Class name of the validator Action. + */ + public String getClassname() { + return classname; + } + + /** + * Sets the class of the validator action. + * @param classname Class name of the validator Action. + */ + public void setClassname(String classname) { + this.classname = classname; + } + + /** + * Gets the name of method being called for the validator action. + * @return The method name. + */ + public String getMethod() { + return method; + } + + /** + * Sets the name of method being called for the validator action. + * @param method The method name. + */ + public void setMethod(String method) { + this.method = method; + } + + /** + * Gets the method parameters for the method. + * @return Method's parameters. + */ + public String getMethodParams() { + return methodParams; + } + + /** + * Sets the method parameters for the method. + * @param methodParams A comma separated list of parameters. + */ + 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); + } + } + } + + /** + * Gets the dependencies of the validator action as a comma separated list + * of validator names. + * @return The validator action's dependencies. + */ + public String getDepends() { + return this.depends; + } + + /** + * Sets the dependencies of the validator action. + * @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); + } + } + } + + /** + * 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. + */ + public void setMsg(String msg) { + this.msg = msg; + } + + /** + * 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 getJsFunctionName() { + return jsFunctionName; + } + + /** + * 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. + */ + public void setJsFunctionName(String jsFunctionName) { + this.jsFunctionName = jsFunctionName; + } + + /** + * 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. + */ + public void setJsFunction(String jsFunction) { + if (javascript != null) { + throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()"); + } + + this.jsFunction = jsFunction; + } + + /** + * Gets the Javascript equivalent of the java class and method + * associated with this action. + * @return The Javascript validation. + */ + public String getJavascript() { + return javascript; + } + + /** + * Sets the Javascript equivalent of the java class and method + * associated with this action. + * @param javascript The Javascript validation. + */ + public void setJavascript(String javascript) { + if (jsFunction != null) { + throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()"); + } + + this.javascript = javascript; + } + + /** + * Initialize based on set. + */ + protected void init() { + this.loadJavascriptFunction(); + } + + /** + * 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'. + */ + protected synchronized void loadJavascriptFunction() { + + if (this.javascriptAlreadyLoaded()) { + return; + } + + if (getLog().isTraceEnabled()) { + getLog().trace(" Loading function begun"); + } + + if (this.jsFunction == null) { + this.jsFunction = this.generateJsFunction(); + } + + String javascriptFileName = this.formatJavascriptFileName(); + + if (getLog().isTraceEnabled()) { + getLog().trace(" Loading js function '" + javascriptFileName + "'"); + } + + this.javascript = this.readJavascriptFile(javascriptFileName); + + if (getLog().isTraceEnabled()) { + 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. + */ + private String readJavascriptFile(String javascriptFileName) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader == null) { + classLoader = this.getClass().getClassLoader(); + } + + InputStream is = classLoader.getResourceAsStream(javascriptFileName); + if (is == null) { + is = this.getClass().getResourceAsStream(javascriptFileName); + } + + if (is == null) { + getLog().debug(" Unable to read javascript name "+javascriptFileName); + return null; + } + + 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"); + } + + } 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); + } + } + + String function = buffer.toString(); + return function.equals("") ? null : function; + } + + /** + * @return A filename suitable for passing to a + * ClassLoader.getResourceAsStream() method. + */ + private String formatJavascriptFileName() { + String name = this.jsFunction.substring(1); + + if (!this.jsFunction.startsWith("/")) { + name = jsFunction.replace('.', '/') + ".js"; + } + + return name; + } + + /** + * @return true if the javascript for this action has already been loaded. + */ + private boolean javascriptAlreadyLoaded() { + return (this.javascript != null); + } + + /** + * Used to generate the javascript name when it is not specified. + */ + private String generateJsFunction() { + StringBuilder jsName = + new StringBuilder("org.apache.commons.validator.javascript"); + + jsName.append(".validate"); + jsName.append(name.substring(0, 1).toUpperCase()); + jsName.append(name.substring(1, name.length())); + + return jsName.toString(); + } + + /** + * 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 boolean isDependency(String validatorName) { + return this.dependencyList.contains(validatorName); + } + + /** + * Returns the dependent validator names as an unmodifiable + * List. + * @return List of the validator action's depedents. + */ + public List getDependencyList() { + return Collections.unmodifiableList(this.dependencyList); + } + + /** + * Returns a string representation of the object. + * @return a string representation. + */ + @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(); + } + } + + 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; + } + + /** + * Load the Method object for the configured validation method name. + * @throws ValidatorException + */ + 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()); + } + } + + /** + * Load the Class object for the configured validation class name. + * @param loader The ClassLoader used to load the Class object. + * @throws ValidatorException + */ + 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()); + } + } + + /** + * 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 void loadParameterClasses(ClassLoader loader) + throws ValidatorException { + + if (this.parameterClasses != null) { + return; + } + + Class[] parameterClasses = new Class[this.methodParameterList.size()]; + + 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()); + } + } + + 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. + */ + 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); + } + + return paramValue; + } + + /** + * Return an instance of the validation class or null if the validation + * method is static so does not require an instance to be executed. + */ + 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); + } + } + } + + return this.instance; + } + + /** + * Modifies the paramValue array with indexed fields. + * + * @param field + * @param pos + * @param paramValues + */ + private void handleIndexedField(Field field, int pos, Object[] paramValues) + throws ValidatorException { + + 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; + } + + /** + * 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. + */ + private boolean isValid(Object result) { + if (result instanceof Boolean) { + Boolean valid = (Boolean) result; + return valid.booleanValue(); + } + return result != null; + } + + /** + * Returns the ClassLoader set in the Validator contained in the parameter + * Map. + */ + private ClassLoader getClassLoader(Map params) { + Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); + return v.getClassLoader(); + } + + /** + * Returns the onlyReturnErrors setting in the Validator contained in the + * parameter Map. + */ + private boolean onlyReturnErrors(Map params) { + Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); + return v.getOnlyReturnErrors(); + } + + /** + * 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(ValidatorAction.class); + } + return log; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorException.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,46 @@ +/* + * 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; + +/** + * 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 { + + private static final long serialVersionUID = 1025759372615616964L; + + /** + * 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) { + super(message); + } + +} \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResources.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,662 @@ +/* + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URL; +import java.util.Collections; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.collections.FastHashMap; // DEPRECATED +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.Rule; +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; + +/** + *

+ * General purpose class for storing FormSet objects based + * on their associated Locale. Instances of this class are usually + * configured through a validation.xml file that is parsed in a constructor. + *

+ * + *

Note - Classes that extend this class + * must be Serializable so that instances may be used in distributable + * application server environments.

+ * + *

+ * 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 { + + private static final long serialVersionUID = -8203745881446239554L; + + /** Name of the digester validator rules file */ + private static final String VALIDATOR_RULES = "digester-rules.xml"; + + /** + * The set of public identifiers, and corresponding resource names, for + * 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[] = { + "-//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", + "/org/apache/commons/validator/resources/validator_1_0_1.dtd", + "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//EN", + "/org/apache/commons/validator/resources/validator_1_1.dtd", + "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN", + "/org/apache/commons/validator/resources/validator_1_1_3.dtd", + "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.2.0//EN", + "/org/apache/commons/validator/resources/validator_1_2_0.dtd", + "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN", + "/org/apache/commons/validator/resources/validator_1_3_0.dtd", + "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.4.0//EN", + "/org/apache/commons/validator/resources/validator_1_4_0.dtd" + }; + + private transient Log log = LogFactory.getLog(ValidatorResources.class); + + /** + * Map of FormSets stored under + * a Locale key (expressed as a String). + * @deprecated Subclasses should use getFormSets() instead. + */ + @Deprecated + protected FastHashMap hFormSets = new FastHashMap(); // + + /** + * Map of global constant values with + * the name of the constant as the key. + * @deprecated Subclasses should use getConstants() instead. + */ + @Deprecated + protected FastHashMap hConstants = new FastHashMap(); // + + /** + * Map of ValidatorActions with + * the name of the ValidatorAction as the key. + * @deprecated Subclasses should use getActions() instead. + */ + @Deprecated + protected FastHashMap hActions = new FastHashMap(); // + + /** + * The default locale on our server. + */ + protected static Locale defaultLocale = Locale.getDefault(); + + /** + * 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 + */ + public ValidatorResources(InputStream in) throws IOException, SAXException { + this(new InputStream[]{in}); + } + + /** + * Create a ValidatorResources object from an InputStream. + * + * @param streams An array of InputStreams to several validation.xml + * configuration files that will be read in order and merged into this object. + * It's the client's responsibility to close these streams. + * @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 + */ + public ValidatorResources(InputStream[] streams) + throws IOException, SAXException { + + super(); + + Digester digester = initDigester(); + for (int i = 0; i < streams.length; i++) { + if (streams[i] == null) { + throw new IllegalArgumentException("Stream[" + i + "] is null"); + } + digester.push(this); + digester.parse(streams[i]); + } + + this.process(); + } + + /** + * Create a ValidatorResources object from an uri + * + * @param uri The location of a validation.xml configuration file. + * @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 + */ + public ValidatorResources(String uri) throws IOException, SAXException { + this(new String[]{uri}); + } + + /** + * Create a ValidatorResources object from several uris + * + * @param uris An array of uris to several validation.xml + * configuration files that will be read in order and merged into this object. + * @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 + */ + public ValidatorResources(String[] uris) + throws IOException, SAXException { + + super(); + + Digester digester = initDigester(); + for (int i = 0; i < uris.length; i++) { + digester.push(this); + digester.parse(uris[i]); + } + + this.process(); + } + + /** + * Create a ValidatorResources object from a URL. + * + * @param url The URL for the validation.xml + * configuration file that will be read into this object. + * @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 + */ + public ValidatorResources(URL url) + throws IOException, SAXException { + this(new URL[]{url}); + } + + /** + * Create a ValidatorResources object from several URL. + * + * @param urls An array of URL to several validation.xml + * configuration files that will be read in order and merged into this object. + * @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 + */ + public ValidatorResources(URL[] urls) + throws IOException, SAXException { + + super(); + + Digester digester = initDigester(); + for (int i = 0; i < urls.length; i++) { + digester.push(this); + digester.parse(urls[i]); + } + + this.process(); + } + + /** + * Initialize the digester. + */ + 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 + "'"); + } + 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) { + URL url = this.getClass().getResource(REGISTRATIONS[i + 1]); + if (url != null) { + digester.register(REGISTRATIONS[i], url.toString()); + } + } + 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) { + + // Create a new rule to process args elements + Rule rule = new Rule() { + @Override + public void begin(String namespace, String name, + Attributes attributes) throws Exception { + // Create the Arg + Arg arg = new Arg(); + arg.setKey(attributes.getValue("key")); + arg.setName(attributes.getValue("name")); + if ("false".equalsIgnoreCase(attributes.getValue("resource"))) { + arg.setResource(false); + } + 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); + } + + // Add the arg to the parent field + ((Field)getDigester().peek(0)).addArg(arg); + } + }; + + // Add the rule for each of the arg elements + digester.addRule(ARGS_PATTERN + "0", rule); + digester.addRule(ARGS_PATTERN + "1", rule); + digester.addRule(ARGS_PATTERN + "2", rule); + digester.addRule(ARGS_PATTERN + "3", rule); + + } + + /** + * 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 + * in the ValidatorAction. + * @param va The validator action. + */ + public void addValidatorAction(ValidatorAction va) { + va.init(); + + getActions().put(va.getName(), va); + + if (getLog().isDebugEnabled()) { + getLog().debug("Add ValidatorAction: " + va.getName() + "," + va.getClassname()); + } + } + + /** + * 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) { + 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 : ""); + return key; + } + + /** + *

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:

+ *
    + *
  1. language + country + variant
  2. + *
  3. language + country
  4. + *
  5. language
  6. + *
  7. default locale
  8. + *
+ * @param locale The Locale. + * @param formKey The key for the Form. + * @return The validator Form. + * @since Validator 1.1 + */ + public Form getForm(Locale locale, String formKey) { + return this.getForm(locale.getLanguage(), locale.getCountry(), locale + .getVariant(), formKey); + } + + /** + *

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:

+ *
    + *
  1. language + country + variant
  2. + *
  3. language + country
  4. + *
  5. language
  6. + *
  7. default locale
  8. + *
+ * @param language The locale's language. + * @param country The locale's country. + * @param variant The locale's language variant. + * @param formKey The key for the Form. + * @return The validator Form. + * @since Validator 1.1 + */ + public Form getForm(String language, String country, String variant, + 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 (formSet != null) { + form = formSet.getForm(formKey); + } + } + String localeKey = key; + + + // Try language/country + if (form == null) { + key = buildLocale(language, country, null); + if (key.length() > 0) { + FormSet formSet = getFormSets().get(key); + if (formSet != null) { + form = formSet.getForm(formKey); + } + } + } + + // Try language + if (form == null) { + key = buildLocale(language, null, null); + if (key.length() > 0) { + FormSet formSet = getFormSets().get(key); + if (formSet != null) { + form = formSet.getForm(formKey); + } + } + } + + // Try default formset + if (form == null) { + form = defaultFormSet.getForm(formKey); + key = "default"; + } + + if (form == null) { + if (getLog().isWarnEnabled()) { + getLog().warn("Form '" + formKey + "' not found 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. + */ + public void process() { + hFormSets.setFast(true); + hConstants.setFast(true); + hActions.setFast(true); + + this.processForms(); + } + + /** + *

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

+ */ + private void processForms() { + if (defaultFormSet == null) {// it isn't mandatory to have a + // default formset + defaultFormSet = new FormSet(); + } + 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()); + } + } + } + + /** + * Finds the given formSet's parent. ex: A formSet with locale en_UK_TEST1 + * has a direct parent in the formSet with locale en_UK. If it doesn't + * exist, find the formSet with locale en, if no found get the + * defaultFormSet. + * + * @param fs + * the formSet we want to get the parent from + * @return fs's parent + */ + private FormSet getParent(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)); + if (parent == null) { + parent = defaultFormSet; + } + } else if (fs.getType() == FormSet.VARIANT_FORMSET) { + parent = getFormSets().get(buildLocale(fs.getLanguage(), fs + .getCountry(), null)); + if (parent == null) { + parent = getFormSets().get(buildLocale(fs.getLanguage(), + null, null)); + if (parent == null) { + parent = defaultFormSet; + } + } + } + return parent; + } + + /** + *

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 + */ + FormSet getFormSet(String language, String country, String variant) { + + String key = buildLocale(language, country, variant); + + if (key.length() == 0) { + return defaultFormSet; + } + + return getFormSets().get(key); + } + + /** + * Returns a Map of String locale keys to Lists of their FormSets. + * @return Map of Form sets + * @since Validator 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getFormSets() { + return hFormSets; + } + + /** + * Returns a Map of String constant names to their String values. + * @return Map of Constants + * @since Validator 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getConstants() { + return hConstants; + } + + /** + * Returns a Map of String ValidatorAction names to their ValidatorAction. + * @return Map of Validator Actions + * @since Validator 1.2.0 + */ + @SuppressWarnings("unchecked") // FastHashMap is not generic + protected Map getActions() { + return hActions; + } + + /** + * 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(ValidatorResources.class); + } + return log; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResult.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,205 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Iterator; + +/** + * 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 { + + 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(); + + /** + * Field being validated. + * TODO This variable is not used. Need to investigate removing it. + */ + protected Field field = null; + + /** + * Constructs a ValidatorResult with the associated field being + * validated. + * @param field Field that was validated. + */ + public ValidatorResult(Field field) { + this.field = field; + } + + /** + * Add the result of a validator action. + * @param validatorName Name of the validator. + * @param result Whether the validation passed or failed. + */ + public void add(String validatorName, boolean result) { + this.add(validatorName, result, null); + } + + /** + * Add the result of a validator action. + * @param validatorName Name of the validator. + * @param result Whether the validation passed or failed. + * @param value Value returned by the validator. + */ + public void add(String validatorName, boolean result, Object value) { + hAction.put(validatorName, new ResultStatus(result, value)); + } + + /** + * Indicate whether a specified validator is in the Result. + * @param validatorName Name of the validator. + * @return true if the validator is in the result. + */ + public boolean containsAction(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 + * the isValid(name) and getResult(name) methods + * to determine the contents of ResultStatus. + * + */ + @Deprecated + public Map getActionMap() { + return Collections.unmodifiableMap(hAction); + } + + /** + * Returns the Field that was validated. + * @return The Field associated with this result. + */ + public Field getField() { + return this.field; + } + + /** + * Contains the status of the validation. + */ + protected static class ResultStatus implements Serializable { + + 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; + } + + } + +} \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/ValidatorResults.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,152 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * 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 { + + private static final long serialVersionUID = -2709911078904924839L; + + /** + * Map of validation results. + */ + 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) { + this.add(field, validatorName, result, null); + } + + /** + * 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. + * @param value The value returned by the validator. + */ + public void add( + Field field, + String validatorName, + boolean result, + Object value) { + + ValidatorResult validatorResult = this.getValidatorResult(field.getKey()); + + if (validatorResult == null) { + validatorResult = new ValidatorResult(field); + this.hResults.put(field.getKey(), validatorResult); + } + + validatorResult.add(validatorName, result, value); + } + + /** + * Clear all results recorded by this object. + */ + public void clear() { + this.hResults.clear(); + } + + /** + * 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. + */ + public Set getPropertyNames() { + return Collections.unmodifiableSet(this.hResults.keySet()); + } + + /** + * Get a Map of any Objects returned from + * validation routines. + * + * @return Map of objections returned by validators. + */ + public Map getResultValueMap() { + Map results = new HashMap(); + + for (Iterator i = hResults.keySet().iterator(); i.hasNext();) { + String propertyKey = i.next(); + ValidatorResult vr = this.getValidatorResult(propertyKey); + + for (Iterator x = vr.getActions(); x.hasNext();) { + String actionKey = x.next(); + Object result = vr.getResult(actionKey); + + if (result != null && !(result instanceof Boolean)) { + results.put(propertyKey, result); + } + } + } + + return results; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/Var.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,218 @@ +/* + * 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; + +import java.io.Serializable; + +/** + * 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 { + + private static final long serialVersionUID = -684185211548420224L; + + /** + * Int Constant for JavaScript type. This can be used + * when auto-generating JavaScript. + */ + public static final String JSTYPE_INT = "int"; + + /** + * String Constant for JavaScript type. This can be used + * when auto-generating JavaScript. + */ + public static final String JSTYPE_STRING = "string"; + + /** + * Regular Expression Constant for JavaScript type. This can be used + * when auto-generating JavaScript. + */ + public static final String JSTYPE_REGEXP = "regexp"; + + /** + * The name of the variable. + */ + private String name = null; + + /** + * The key or value the variable. + */ + private String value = null; + + /** + * The optional JavaScript type of the variable. + */ + private String jsType = null; + + /** + * Whether the variable is a resource [false] + */ + private boolean resource = false; + + /** + * The bundle for a variable (when resource = 'true'). + */ + private String bundle = null; + + /** + * Default Constructor. + */ + public Var() { + super(); + } + + /** + * Constructs a variable with a specified name, value + * and Javascript type. + * @param name Variable name. + * @param value Variable value. + * @param jsType Variable Javascript type. + */ + public Var(String name, String value, String jsType) { + this.name = name; + this.value = value; + this.jsType = jsType; + } + + /** + * Gets the name of the variable. + * @return The name of the variable. + */ + public String getName() { + return this.name; + } + + /** + * Sets the name of the variable. + * @param name The name of the variable. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the value of the variable. + * @return The value of the variable. + */ + public String getValue() { + return this.value; + } + + /** + * Sets the value of the variable. + * @param value The value of the variable. + */ + public void setValue(String value) { + this.value = value; + } + + /** + * 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 + */ + public boolean isResource() { + return this.resource; + } + + /** + * Sets whether or not the value is a resource. + * @param resource If true indicates the value is a resource. + * @since Validator 1.2.0 + */ + public void setResource(boolean resource) { + this.resource = resource; + } + + /** + * Returns the resource bundle name. + * @return The bundle name. + * @since Validator 1.2.0 + */ + public String getBundle() { + return this.bundle; + } + + /** + * Sets the resource bundle name. + * @param bundle The new bundle name. + * @since Validator 1.2.0 + */ + public void setBundle(String bundle) { + this.bundle = bundle; + } + + /** + * Gets the JavaScript type of the variable. + * @return The Javascript type of the variable. + */ + public String getJsType() { + return this.jsType; + } + + /** + * Sets the JavaScript type of the variable. + * @param jsType The Javascript type of the variable. + */ + public void setJsType(String jsType) { + this.jsType = jsType; + } + + /** + * Creates and returns a copy of this object. + * @return A copy of the variable. + */ + @Override + public Object clone() { + try { + return super.clone(); + + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e.toString()); + } + } + + /** + * Returns a string representation of the object. + * @return A string representation of the variable. + */ + @Override + public String toString() { + StringBuilder results = new StringBuilder(); + + results.append("Var: name="); + results.append(name); + results.append(" value="); + results.append(value); + results.append(" resource="); + results.append(resource); + if (resource) { + results.append(" bundle="); + results.append(bundle); + } + results.append(" jsType="); + results.append(jsType); + results.append("\n"); + + return results.toString(); + } + +} \ No newline at end of file Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/package.html =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/package.html (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/package.html (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,244 @@ + + + + Package Documentation for org.apache.commons.validator + + +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). +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
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 = null;
+
+// 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);
+}
+
+ + Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractCalendarValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,427 @@ +/* + * 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.text.DateFormatSymbols; +import java.text.Format; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

Abstract class for Date/Time/Calendar validation.

+ * + *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public abstract class AbstractCalendarValidator extends AbstractFormatValidator { + + private static final long serialVersionUID = -1410008585975827379L; + + private final int dateStyle; + + private final int timeStyle; + + /** + * Construct an instance with the specified strict, + * time and date style parameters. + * + * @param strict 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) { + super(strict); + this.dateStyle = dateStyle; + this.timeStyle = timeStyle; + } + + /** + *

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 true if the value is valid. + */ + @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()); + } + 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(); + } + return formatter.format(value); + } + + /** + *

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, String pattern, Locale locale, TimeZone timeZone) { + + value = (value == null ? null : value.trim()); + if (value == null || value.length() == 0) { + return null; + } + 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); + + /** + *

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.

+ * + * @param value The Calendar value. + * @param compare The Calendar to check the value against. + * @param field The field level to compare to - e.g. specifying + * Calendar.MONTH will compare the year and month + * portions of the calendar. + * @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) { + + int result = 0; + + // Compare Year + result = calculateCompareResult(value, compare, Calendar.YEAR); + if (result != 0 || field == Calendar.YEAR) { + return result; + } + + // Compare Week of Year + if (field == Calendar.WEEK_OF_YEAR) { + return calculateCompareResult(value, compare, Calendar.WEEK_OF_YEAR); + } + + // Compare Day of the Year + if (field == Calendar.DAY_OF_YEAR) { + return calculateCompareResult(value, compare, Calendar.DAY_OF_YEAR); + } + + // Compare Month + result = calculateCompareResult(value, compare, Calendar.MONTH); + if (result != 0 || field == Calendar.MONTH) { + return result; + } + + // Compare Week of Month + if (field == Calendar.WEEK_OF_MONTH) { + return calculateCompareResult(value, compare, Calendar.WEEK_OF_MONTH); + } + + // Compare Date + result = calculateCompareResult(value, compare, Calendar.DATE); + if (result != 0 || (field == Calendar.DATE || + field == Calendar.DAY_OF_WEEK || + field == Calendar.DAY_OF_WEEK_IN_MONTH)) { + return result; + } + + // Compare Time fields + return compareTime(value, compare, field); + + } + + /** + *

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

+ * + * @param value The Calendar value. + * @param compare The Calendar to check the value against. + * @param field The field level to compare to - e.g. specifying + * Calendar.MINUTE will compare the hours and minutes + * portions of the calendar. + * @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) { + + int result = 0; + + // Compare Hour + result = calculateCompareResult(value, compare, Calendar.HOUR_OF_DAY); + if (result != 0 || (field == Calendar.HOUR || field == Calendar.HOUR_OF_DAY)) { + return result; + } + + // Compare Minute + result = calculateCompareResult(value, compare, Calendar.MINUTE); + if (result != 0 || field == Calendar.MINUTE) { + return result; + } + + // Compare Second + result = calculateCompareResult(value, compare, Calendar.SECOND); + if (result != 0 || field == Calendar.SECOND) { + return result; + } + + // Compare Milliseconds + if (field == Calendar.MILLISECOND) { + return calculateCompareResult(value, compare, Calendar.MILLISECOND); + } + + throw new IllegalArgumentException("Invalid field: " + field); + + } + + /** + *

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(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; + } + } + + /** + *

Calculate the quarter for the specified Calendar.

+ * + * @param calendar The Calendar value. + * @param monthOfFirstQuarter The month that the first quarter starts. + * @return The calculated quarter. + */ + private int calculateQuarter(Calendar calendar, int monthOfFirstQuarter) { + // Add Year + int year = calendar.get(Calendar.YEAR); + + 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; + } + return (year * 10) + quarter; // CHECKSTYLE IGNORE MagicNumber + } + + /** + *

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 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. + */ + 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; + } else { + return 0; + } + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractFormatValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,221 @@ +/* + * 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.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 + */ +public abstract class AbstractFormatValidator implements Serializable { + + private static final long serialVersionUID = -4690687565200568258L; + + private final boolean strict; + + /** + * Construct an instance with the specified strict setting. + * + * @param strict true if strict + * Format parsing should be used. + */ + public AbstractFormatValidator(boolean strict) { + this.strict = strict; + } + + /** + *

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 false, whereas setting strict + * to true will cause this value to fail + * validation.

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

Validate using the default Locale. + * + * @param value The value validation is being performed on. + * @return true if the value is valid. + */ + public boolean isValid(String value) { + return isValid(value, (String)null, (Locale)null); + } + + /** + *

Validate using the specified pattern. + * + * @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. + */ + public boolean isValid(String value, String pattern) { + return isValid(value, pattern, (Locale)null); + } + + /** + *

Validate using the specified Locale. + * + * @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. + */ + public boolean isValid(String value, Locale locale) { + return isValid(value, (String)null, locale); + } + + /** + *

Validate 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. + */ + public abstract boolean isValid(String value, String pattern, Locale locale); + + /** + *

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

+ * + * @param value The value validation is being performed on. + * @return The value formatted as a String. + */ + public String format(Object value) { + return format(value, (String)null, (Locale)null); + } + + /** + *

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. + * @return The value formatted as a String. + */ + public String format(Object value, String pattern) { + return format(value, pattern, (Locale)null); + } + + /** + *

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. + * @return The value formatted as a String. + */ + public String format(Object value, Locale locale) { + return format(value, (String)null, 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. + * @return The value formatted as a String. + */ + public String format(Object value, String pattern, Locale locale) { + Format formatter = getFormat(pattern, locale); + return format(value, formatter); + } + + /** + *

Format a value with the specified Format.

+ * + * @param value The value to be formatted. + * @param formatter The Format to use. + * @return The formatted value. + */ + protected String format(Object value, Format formatter) { + return formatter.format(value); + } + + /** + *

Parse the value with the specified Format.

+ * + * @param value The value to be parsed. + * @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) { + + ParsePosition pos = new ParsePosition(0); + Object parsedValue = formatter.parseObject(value, pos); + if (pos.getErrorIndex() > -1) { + return null; + } + + if (isStrict() && pos.getIndex() < value.length()) { + return null; + } + + if (parsedValue != null) { + parsedValue = processParsedValue(parsedValue, formatter); + } + + return parsedValue; + + } + + /** + *

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. + */ + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractNumberValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/AbstractNumberValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,274 @@ +/* + * 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.text.DecimalFormatSymbols; +import java.text.Format; +import java.text.NumberFormat; +import java.text.DecimalFormat; +import java.util.Locale; + +/** + *

Abstract class for Number Validation.

+ * + *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public abstract class AbstractNumberValidator extends AbstractFormatValidator { + + private static final long serialVersionUID = -3088817875906765463L; + + /** Standard NumberFormat type */ + public static final int STANDARD_FORMAT = 0; + + /** Currency NumberFormat type */ + public static final int CURRENCY_FORMAT = 1; + + /** Percent NumberFormat type */ + public static final int PERCENT_FORMAT = 2; + + private final boolean allowFractions; + private final int formatType; + + /** + * Construct an instance with specified strict + * and decimal parameters. + * + * @param strict 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. + */ + public AbstractNumberValidator(boolean strict, int formatType, boolean allowFractions) { + super(strict); + this.allowFractions = allowFractions; + this.formatType = formatType; + } + + /** + *

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

+ * + * @return true if decimals are allowed + * or false if the number is an integer. + */ + public boolean isAllowFractions() { + return allowFractions; + } + + /** + *

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

+ * + * @return the format type created. + */ + public int getFormatType() { + return formatType; + } + + /** + *

Validate using the specified 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 true if the value is valid. + */ + @Override + public boolean isValid(String value, String pattern, Locale locale) { + Object parsedValue = parse(value, pattern, locale); + return (parsedValue == null ? false : true); + } + + /** + * Check if the value is within a specified range. + * + * @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 + * specified range. + */ + public boolean isInRange(Number value, Number min, Number max) { + return (minValue(value, min) && maxValue(value, max)); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Number value, Number min) { + if (isAllowFractions()) { + return (value.doubleValue() >= min.doubleValue()); + } + return (value.longValue() >= min.longValue()); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Number value, Number max) { + if (isAllowFractions()) { + return (value.doubleValue() <= max.doubleValue()); + } + return (value.longValue() <= max.longValue()); + } + + /** + *

Parse the value 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. + * @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) { + return null; + } + Format formatter = getFormat(pattern, locale); + 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); + + /** + *

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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigDecimalValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigDecimalValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,240 @@ +/* + * 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.math.BigDecimal; +import java.text.Format; +import java.text.NumberFormat; +import java.util.Locale; + +/** + *

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

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a BigDecimal using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted BigDecimal value.

+ * + *

Fraction/decimal values are automatically trimmed to the appropriate length.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class BigDecimalValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = -670320911490506772L; + + private static final BigDecimalValidator VALIDATOR = new BigDecimalValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the BigDecimalValidator. + */ + public static BigDecimalValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public BigDecimalValidator() { + this(true); + } + + /** + *

Construct an instance with the specified strict setting.

+ * + * @param strict true if strict + * Format parsing should be used. + */ + public BigDecimalValidator(boolean strict) { + this(strict, STANDARD_FORMAT, true); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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. + */ + protected BigDecimalValidator(boolean strict, int formatType, + 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 + * specified range. + */ + public boolean isInRange(BigDecimal value, double min, double max) { + return (value.doubleValue() >= min && value.doubleValue() <= max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(BigDecimal value, double min) { + return (value.doubleValue() >= min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(BigDecimal value, double max) { + return (value.doubleValue() <= max); + } + + /** + * Convert the parsed value to a BigDecimal. + * + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * BigDecimal. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + BigDecimal decimal = null; + if (value instanceof Long) { + decimal = BigDecimal.valueOf(((Long)value).longValue()); + } else { + decimal = new BigDecimal(value.toString()); + } + + int scale = determineScale((NumberFormat)formatter); + if (scale >= 0) { + decimal = decimal.setScale(scale, BigDecimal.ROUND_DOWN); + } + + return decimal; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/BigIntegerValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,211 @@ +/* + * 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.math.BigInteger; +import java.text.Format; +import java.util.Locale; + +/** + *

BigInteger Validation and Conversion routines (java.math.BigInteger).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a BigInteger using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted BigInteger value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class BigIntegerValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = 6713144356347139988L; + + private static final BigIntegerValidator VALIDATOR = new BigIntegerValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the BigIntegerValidator. + */ + public static BigIntegerValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public BigIntegerValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + super(strict, formatType, false); + } + + /** + *

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

Validate/convert a BigInteger 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 BigInteger if valid or null if invalid. + */ + public BigInteger validate(String value, String pattern) { + return (BigInteger)parse(value, pattern, (Locale)null); + } + + /** + *

Validate/convert a BigInteger 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 BigInteger if valid or null if invalid. + */ + public BigInteger validate(String value, Locale locale) { + return (BigInteger)parse(value, (String)null, locale); + } + + /** + *

Validate/convert a BigInteger 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 BigInteger if valid or null if invalid. + */ + public BigInteger validate(String value, String pattern, Locale locale) { + return (BigInteger)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 + * specified range. + */ + public boolean isInRange(BigInteger value, long min, long max) { + return (value.longValue() >= min && value.longValue() <= max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(BigInteger value, long min) { + return (value.longValue() >= min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(BigInteger value, long max) { + return (value.longValue() <= max); + } + + /** + * Convert the parsed value to a BigInteger. + * + * @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. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + return BigInteger.valueOf(((Number)value).longValue()); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ByteValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,256 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Byte Validation and Conversion routines (java.lang.Byte).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Byte using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Byte value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class ByteValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = 7001640945881854649L; + + private static final ByteValidator VALIDATOR = new ByteValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the ByteValidator. + */ + public static ByteValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public ByteValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + super(strict, formatType, false); + } + + /** + *

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

Validate/convert a Byte 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 Byte if valid or null if invalid. + */ + public Byte validate(String value, String pattern) { + return (Byte)parse(value, pattern, (Locale)null); + } + + /** + *

Validate/convert a Byte 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 Byte if valid or null if invalid. + */ + public Byte validate(String value, Locale locale) { + return (Byte)parse(value, (String)null, locale); + } + + /** + *

Validate/convert a Byte 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 Byte if valid or null if invalid. + */ + public Byte validate(String value, String pattern, Locale locale) { + return (Byte)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 + * specified range. + */ + public boolean isInRange(byte value, byte min, byte max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Byte value, byte min, byte max) { + return isInRange(value.byteValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(byte value, byte min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Byte value, byte min) { + return minValue(value.byteValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(byte value, byte max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Byte value, byte max) { + return maxValue(value.byteValue(), max); + } + + /** + *

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

+ * + * @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. + */ + @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); + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CalendarValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,338 @@ +/* + * 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.text.DateFormat; +import java.text.Format; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

Calendar Validation and Conversion routines (java.util.Calendar).

+ * + *

This validator provides a number of methods for validating/converting + * a String date value to a java.util.Calendar using + * java.text.DateFormat to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

For each of the above mechanisms, conversion method (i.e the + * validate methods) implementations are provided which + * either use the default TimeZone or allow the + * TimeZone to be specified.

+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Calendar value.

+ * + *

Implementations of the validate() method are provided + * to create Calendar objects for different time zones + * if the system default is not appropriate.

+ * + *

Alternatively the CalendarValidator's adjustToTimeZone() method + * can be used to adjust the TimeZone of the Calendar + * object afterwards.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform various date comparison checks:

+ *
    + *
  • compareDates() compares the day, month and + * year of two calendars, returning 0, -1 or +1 indicating + * whether the first date is equal, before or after the second.
  • + *
  • compareWeeks() compares the week and + * year of two calendars, returning 0, -1 or +1 indicating + * whether the first week is equal, before or after the second.
  • + *
  • compareMonths() compares the month and + * year of two calendars, returning 0, -1 or +1 indicating + * whether the first month is equal, before or after the second.
  • + *
  • compareQuarters() compares the quarter and + * year of two calendars, returning 0, -1 or +1 indicating + * whether the first quarter is equal, before or after the second.
  • + *
  • compareYears() compares the + * year of two calendars, returning 0, -1 or +1 indicating + * whether the first year is equal, before or after the second.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using a specified pattern
  • + *
  • using the format for a specified Locale
  • + *
  • using the format for the default Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class CalendarValidator extends AbstractCalendarValidator { + + private static final long serialVersionUID = 9109652318762134167L; + + private static final CalendarValidator VALIDATOR = new CalendarValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the CalendarValidator. + */ + public static CalendarValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance with short + * date style. + */ + public CalendarValidator() { + this(true, DateFormat.SHORT); + } + + /** + * Construct an instance with the specified strict + * and date style parameters. + * + * @param strict true if strict + * Format parsing should be used. + * @param dateStyle the date style to use for Locale validation. + */ + public CalendarValidator(boolean strict, int dateStyle) { + super(strict, dateStyle, -1); + } + + /** + *

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

Validate/convert a Calendar 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 Calendar if valid or null + * if invalid. + */ + public Calendar validate(String value, TimeZone timeZone) { + return (Calendar)parse(value, (String)null, (Locale)null, 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(String value, String pattern) { + return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + } + + /** + *

Validate/convert a Calendar 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. + * @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, TimeZone timeZone) { + return (Calendar)parse(value, pattern, (Locale)null, timeZone); + } + + /** + *

Validate/convert a Calendar 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, Locale locale) { + return (Calendar)parse(value, (String)null, locale, (TimeZone)null); + } + + /** + *

Validate/convert a Calendar 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, Locale locale, TimeZone timeZone) { + return (Calendar)parse(value, (String)null, locale, timeZone); + } + + /** + *

Validate/convert a Calendar 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, String pattern, Locale locale) { + return (Calendar)parse(value, pattern, locale, (TimeZone)null); + } + + /** + *

Validate/convert a Calendar 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) { + return (Calendar)parse(value, pattern, locale, timeZone); + } + + /** + *

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(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); + } + } + + /** + *

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

+ * + * @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 int compareDates(Calendar value, Calendar compare) { + return compare(value, compare, Calendar.DATE); + } + + /** + *

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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CodeValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CodeValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,283 @@ +/* + * 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 org.apache.commons.validator.routines.checkdigit.CheckDigit; + +/** + * Generic Code Validation providing format, minimum/maximum + * length and {@link CheckDigit} validations. + *

+ * Performs the following validations on a code: + *

    + *
  • if the code is null, return null/false as appropriate
  • + *
  • trim the input. If the resulting code is empty, return null/false as appropriate
  • + *
  • Check the format of the code using a regular expression. (if specified)
  • + *
  • Check the minimum and maximum length (if specified) of the parsed code + * (i.e. parsed by the regular expression).
  • + *
  • Performs {@link CheckDigit} validation on the parsed code (if specified).
  • + *
  • The {@link #validate(String)} method returns the trimmed, parsed input (or null if validation failed)
  • + *
+ *

+ * Note + * The {@link #isValid(String)} method will return true if the input passes validation. + * Since this includes trimming as well as potentially dropping parts of the input, + * it is possible for a String to pass validation + * but fail the checkdigit test if passed directly to it (the check digit routines generally don't trim input + * 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); 
+ * if (valid != null) {
+ *    some_method(valid.toString());
+ * }
+ * 
+ *

+ * Configure the validator with the appropriate regular expression, minimum/maximum length + * and {@link CheckDigit} validator and then call one of the two validation + * methods provided:

+ *
    + *
  • boolean isValid(code)
  • + *
  • String validate(code)
  • + *
+ *

+ * Codes often include format characters - such as hyphens - to make them + * more easily human readable. These can be removed prior to length and check digit + * validation by specifying them as a non-capturing group in the regular + * 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 + */ +public final class CodeValidator implements Serializable { + + private static final long serialVersionUID = 446960910870938233L; + + private final RegexValidator regexValidator; + private final int minLength; + private final int maxLength; + 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 + * + * @param regex The format regular expression + * @param checkdigit The check digit validation routine + */ + public CodeValidator(String regex, CheckDigit checkdigit) { + this(regex, -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 + * + * @param regex The format regular expression. + * @param length The length of the code + * (sets the mimimum/maximum to the same) + * @param checkdigit The check digit validation routine + */ + public CodeValidator(String regex, int length, CheckDigit checkdigit) { + this(regex, 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 + * + * @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(String regex, int minLength, int maxLength, + CheckDigit checkdigit) { + if (regex != null && regex.length() > 0) { + this.regexValidator = new RegexValidator(regex); + } else { + this.regexValidator = null; + } + this.minLength = minLength; + this.maxLength = maxLength; + this.checkdigit = checkdigit; + } + + /** + * Construct a code validator with a specified regular expression, + * validator and {@link CheckDigit} validation. + * + * @param regexValidator The format regular expression validator + * @param checkdigit The check digit validation routine. + */ + public CodeValidator(RegexValidator regexValidator, CheckDigit checkdigit) { + this(regexValidator, -1, -1, checkdigit); + } + + /** + * Construct a code validator with a specified regular expression, + * validator, length and {@link CheckDigit} validation. + * + * @param regexValidator The format regular expression validator + * @param length The length of the code + * (sets the mimimum/maximum to the same value) + * @param checkdigit The check digit validation routine + */ + public CodeValidator(RegexValidator regexValidator, int length, CheckDigit checkdigit) { + this(regexValidator, length, length, checkdigit); + } + + /** + * Construct a code validator with a specified regular expression + * validator, minimum/maximum length and {@link CheckDigit} validation. + * + * @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(RegexValidator regexValidator, int minLength, int maxLength, + CheckDigit checkdigit) { + this.regexValidator = regexValidator; + this.minLength = minLength; + this.maxLength = maxLength; + this.checkdigit = checkdigit; + } + + /** + * Return the check digit validation routine. + *

+ * N.B. Optional, if not set no Check Digit + * validation will be performed on the code. + * + * @return The check digit validation routine + */ + public CheckDigit getCheckDigit() { + return checkdigit; + } + + /** + * Return the minimum length of the code. + *

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

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

+ * N.B. Optional, if not set no regular + * expression validation will be performed on the code. + * + * @return The regular expression validator + */ + public RegexValidator getRegexValidator() { + return regexValidator; + } + + /** + * Validate the code returning either true + * or false. + *

+ * This calls {@link #validate(String)} and returns false + * if the return value is null, true otherwise. + *

+ * Note that {@link #validate(String)} trims the input + * and if there is a {@link RegexValidator} it may also + * change the input as part of the validation. + * + * @param input The code to validate + * @return true if valid, otherwise + * false + */ + public boolean isValid(String input) { + return (validate(input) != null); + } + + /** + * Validate the code returning either the valid code or + * null if invalid. + *

+ * Note that this method trims the input + * and if there is a {@link RegexValidator} it may also + * change the input as part of the validation. + * + * @param input The code to validate + * @return The code if valid, otherwise null + * if invalid + */ + public Object validate(String input) { + + if (input == null) { + return null; + } + + String code = input.trim(); + if (code.length() == 0) { + return null; + } + + // validate/reformat using regular expression + if (regexValidator != null) { + code = regexValidator.validate(code); + if (code == null) { + return null; + } + } + + // 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)) { + return null; + } + + // validate the check digit + if (checkdigit != null && !checkdigit.isValid(code)) { + return null; + } + + return code; + + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CreditCardValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,517 @@ +/* + * 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 org.apache.commons.validator.routines.checkdigit.CheckDigit; +import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; + +/** + * Perform credit card validations. + * + *

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

+ * + *
+ * CreditCardValidator ccv = new CreditCardValidator(CreditCardValidator.AMEX + CreditCardValidator.VISA);
+ * 
+ * + *

+ * configures the validator to only pass American Express and Visa cards. + * If a card type is not directly supported by this class, you can create an + * instance of the {@link CodeValidator} class and pass it to a {@link CreditCardValidator} + * constructor along with any existing validators. For example: + *

+ * + *
+ * CreditCardValidator ccv = new CreditCardValidator(
+ *     new CodeValidator[] {
+ *         CreditCardValidator.AMEX_VALIDATOR,
+ *         CreditCardValidator.VISA_VALIDATOR,
+ *         new CodeValidator("^(4)(\\d{12,18})$", LUHN_VALIDATOR) // add VPAY
+ * };
+ * 
+ * + *

+ * Alternatively you can define a validator using the {@link CreditCardRange} class. + * For example: + *

+ * + *
+ * CreditCardValidator ccv = new CreditCardValidator(
+ *    new CreditCardRange[]{
+ *        new CreditCardRange("300", "305", 14, 14), // Diners
+ *        new CreditCardRange("3095", null, 14, 14), // Diners
+ *        new CreditCardRange("36",   null, 14, 14), // Diners
+ *        new CreditCardRange("38",   "39", 14, 14), // Diners
+ *        new CreditCardRange("4",    null, new int[] {13, 16}), // VISA
+ *    }
+ * );
+ * 
+ * 
+ *

+ * This can be combined with a list of {@code CodeValidator}s + *

+ *

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

+ * + * @version $Revision: 1782740 $ + * @since Validator 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 + */ + public static class CreditCardRange { + final String low; // e.g. 34 or 644 + final String high; // e.g. 34 or 65 + final int minLen; // e.g. 16 or -1 + final int maxLen; // e.g. 19 or -1 + final int lengths[]; // e.g. 16,18,19 + + /** + * Create a credit card range specifier for use in validation + * of the number syntax including the IIN range. + *

+ * 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 high the high digits of the IIN range + * @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) { + this.low = low; + this.high = high; + this.minLen = minLen; + this.maxLen = maxLen; + this.lengths = null; + } + + /** + * Create a credit card range specifier for use in validation + * of the number syntax including the IIN range. + *

+ * 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 high the high digits of the IIN range + * @param lengths array of valid lengths + */ + public CreditCardRange(String low, String high, int [] lengths) { + this.low = low; + this.high = high; + this.minLen = -1; + this.maxLen = -1; + this.lengths = lengths.clone(); + } + } + + /** + * 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. + * + *
+     * 
+     * CreditCardValidator v = new CreditCardValidator(CreditCardValidator.NONE);
+     * v.addAllowedCardType(customType);
+     * v.isValid(aCardNumber);
+     * 
+     * 
+ */ + public static final long NONE = 0; + + /** + * Option specifying that American Express cards are allowed. + */ + public static final long AMEX = 1 << 0; + + /** + * Option specifying that Visa cards are allowed. + */ + public static final long VISA = 1 << 1; + + /** + * Option specifying that Mastercard cards are allowed. + */ + public static final long MASTERCARD = 1 << 2; + + /** + * Option specifying that Discover cards are allowed. + */ + public static final long DISCOVER = 1 << 3; // CHECKSTYLE IGNORE MagicNumber + + /** + * Option specifying that Diners cards are allowed. + */ + public static final long DINERS = 1 << 4; // CHECKSTYLE IGNORE MagicNumber + + /** + * Option specifying that VPay (Visa) cards are allowed. + * @since 1.5.0 + */ + public static final long VPAY = 1 << 5; // CHECKSTYLE IGNORE MagicNumber + + /** + * Option specifying that Mastercard cards (pre Oct 2016 only) are allowed. + * @deprecated for use until Oct 2016 only + */ + @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)
+ */ + 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)
+ */ + 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)
+ */ + private static final RegexValidator DISCOVER_REGEX = new RegexValidator(new String[] {"^(6011\\d{12})$", "^(64[4-9]\\d{13})$", "^(65\\d{14})$"}); + + /** Discover Card Validator */ + public static final CodeValidator DISCOVER_VALIDATOR = new CodeValidator(DISCOVER_REGEX, LUHN_VALIDATOR); + + /** + * Mastercard regular expressions + *

+ * 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 + }); + + /** 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 + */ + @Deprecated + public static final CodeValidator MASTERCARD_VALIDATOR_PRE_OCT2016 = new CodeValidator("^(5[1-5]\\d{14})$", LUHN_VALIDATOR); + + /** + * 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 + *

+ * 4xxxxx (13-19) + * @since 1.5.0 + */ + public static final CodeValidator VPAY_VALIDATOR = new CodeValidator("^(4)(\\d{12,18})$", LUHN_VALIDATOR); + + /** + * Create 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 options. + * @param options Pass in + * CreditCardValidator.VISA + CreditCardValidator.AMEX to specify that + * those are the only valid card types. + */ + public CreditCardValidator(long options) { + super(); + + 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 CreditCardValidator with the specified {@link CodeValidator}s. + * @param creditCardValidators Set of valid code validators + */ + public CreditCardValidator(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 + * and {@link CreditCardRange}s. + *

+ * This can be used to combine predefined validators such as {@link #MASTERCARD_VALIDATOR} + * with additional validators using the simpler {@link CreditCardRange}s. + * @param creditCardValidators Set of valid code validators + * @param creditCardRanges Set of valid code validators + * @since 1.6 + */ + public CreditCardValidator(CodeValidator[] creditCardValidators, CreditCardRange[] creditCardRanges) { + if (creditCardValidators == null) { + throw new IllegalArgumentException("Card validators are missing"); + } + if (creditCardRanges == null) { + throw new IllegalArgumentException("Card ranges are missing"); + } + Collections.addAll(cardTypes, creditCardValidators); + 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 minLen minimum allowed length + * @param maxLen maximum allowed length + * @return the validator + * @since 1.6 + */ + public static CreditCardValidator genericCreditCardValidator(int minLen, int maxLen) { + return new CreditCardValidator(new CodeValidator[] {new CodeValidator("(\\d+)", minLen, maxLen, 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 + */ + public static CreditCardValidator genericCreditCardValidator(int length) { + return genericCreditCardValidator(length, length); + } + + /** + * Create 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 static CreditCardValidator genericCreditCardValidator() { + return genericCreditCardValidator(MIN_CC_LENGTH, MAX_CC_LENGTH); + } + + /** + * 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) { + return false; + } + for (CodeValidator cardType : cardTypes) { + if (cardType.isValid(card)) { + return true; + } + } + return false; + } + + /** + * Checks if the field is a valid credit card number. + * @param card The card number to validate. + * @return The card number if valid or null + * if invalid. + */ + public Object validate(String card) { + if (card == null || card.length() == 0) { + return null; + } + Object result = null; + for (CodeValidator cardType : cardTypes) { + result = cardType.validate(card); + if (result != null) { + return result; + } + } + return null; + + } + + // 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CurrencyValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/CurrencyValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,118 @@ +/* + * 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.text.DecimalFormat; +import java.text.Format; + +/** + *

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

+ * + *

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 converts the currency to a java.math.BigDecimal
  • + *
+ * + *

However any of the number validators can be used for currency validation. + * For example, if you wanted a currency validator that converts to a + * java.lang.Integer then you can simply instantiate an + * IntegerValidator with the appropriate format type:

+ * + *

... = new IntegerValidator(false, IntegerValidator.CURRENCY_FORMAT);

+ * + *

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.

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class CurrencyValidator extends BigDecimalValidator { + + private static final long serialVersionUID = -4201640771171486514L; + + private static final CurrencyValidator VALIDATOR = new CurrencyValidator(); + + /** DecimalFormat's currency symbol */ + private static final char CURRENCY_SYMBOL = '\u00A4'; + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the CurrencyValidator. + */ + public static BigDecimalValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public CurrencyValidator() { + this(true, true); + } + + /** + * Construct an instance with the specified strict setting. + * + * @param strict true if strict + * Format parsing should be used. + * @param allowFractions true if fractions are + * allowed or false if integers only. + */ + public CurrencyValidator(boolean strict, boolean allowFractions) { + super(strict, CURRENCY_FORMAT, allowFractions); + } + + /** + *

Parse the value with the specified Format.

+ * + *

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 + * symbol is missing. This method re-parses with a format + * without the currency symbol if it fails initially.

+ * + * @param value The value to be parsed. + * @param formatter The Format to parse the value with. + * @return The parsed value if valid or null if invalid. + */ + @Override + protected Object parse(String value, Format formatter) { + + // Initial parse of the value + Object parsedValue = super.parse(value, formatter); + if (parsedValue != null || !(formatter instanceof DecimalFormat)) { + return parsedValue; + } + + // Re-parse using a pattern without the currency symbol + DecimalFormat decimalFormat = (DecimalFormat)formatter; + String pattern = decimalFormat.toPattern(); + if (pattern.indexOf(CURRENCY_SYMBOL) >= 0) { + 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)); + } + } + decimalFormat.applyPattern(buffer.toString()); + parsedValue = super.parse(value, decimalFormat); + } + return parsedValue; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DateValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,350 @@ +/* + * 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.text.DateFormat; +import java.text.Format; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

Date Validation and Conversion routines (java.util.Date).

+ * + *

This validator provides a number of methods for validating/converting + * a String date value to a java.util.Date using + * java.text.DateFormat to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

For each of the above mechanisms, conversion method (i.e the + * validate methods) implementations are provided which + * either use the default TimeZone or allow the + * TimeZone to be specified.

+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Date value.

+ * + *

Implementations of the validate() method are provided + * to create Date objects for different time zones + * if the system default is not appropriate.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform various date comparison checks:

+ *
    + *
  • compareDates() compares the day, month and + * year of two dates, returning 0, -1 or +1 indicating + * whether the first date is equal, before or after the second.
  • + *
  • compareWeeks() compares the week and + * year of two dates, returning 0, -1 or +1 indicating + * whether the first week is equal, before or after the second.
  • + *
  • compareMonths() compares the month and + * year of two dates, returning 0, -1 or +1 indicating + * whether the first month is equal, before or after the second.
  • + *
  • compareQuarters() compares the quarter and + * year of two dates, returning 0, -1 or +1 indicating + * whether the first quarter is equal, before or after the second.
  • + *
  • compareYears() compares the + * year of two dates, returning 0, -1 or +1 indicating + * whether the first year is equal, before or after the second.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using a specified pattern
  • + *
  • using the format for a specified Locale
  • + *
  • using the format for the default Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class DateValidator extends AbstractCalendarValidator { + + private static final long serialVersionUID = -3966328400469953190L; + + private static final DateValidator VALIDATOR = new DateValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the DateValidator. + */ + public static DateValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance with short + * date style. + */ + public DateValidator() { + this(true, DateFormat.SHORT); + } + + /** + * Construct an instance with the specified strict + * and date style parameters. + * + * @param strict true if strict + * Format parsing should be used. + * @param dateStyle the date style to use for Locale validation. + */ + public DateValidator(boolean strict, 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. + * @param compare The Calendar to compare the value to. + * @param timeZone The Time Zone used to compare the dates, system default if null. + * @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 int compareDates(Date value, Date compare, TimeZone timeZone) { + Calendar calendarValue = getCalendar(value, timeZone); + 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. + * @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 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(Date value, Date compare, TimeZone timeZone) { + Calendar calendarValue = getCalendar(value, timeZone); + Calendar calendarCompare = getCalendar(compare, timeZone); + return compare(calendarValue, calendarCompare, Calendar.MONTH); + } + + /** + *

Compare Quarters (quarter 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 months 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(Date value, Date compare, TimeZone timeZone) { + return compareQuarters(value, compare, timeZone, 1); + } + + /** + *

Compare Quarters (quarter 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. + * @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. + */ + public int compareQuarters(Date value, Date compare, TimeZone timeZone, int monthOfFirstQuarter) { + Calendar calendarValue = getCalendar(value, timeZone); + Calendar calendarCompare = getCalendar(compare, timeZone); + return super.compareQuarters(calendarValue, calendarCompare, monthOfFirstQuarter); + } + + /** + *

Compare Years.

+ * + * @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 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(Date value, Date compare, TimeZone timeZone) { + Calendar calendarValue = getCalendar(value, timeZone); + Calendar calendarCompare = getCalendar(compare, timeZone); + return compare(calendarValue, calendarCompare, Calendar.YEAR); + } + + /** + *

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) { + return value; + } + + /** + *

Convert a Date to a Calendar.

+ * + * @param value The date value to be converted. + * @return The converted Calendar. + */ + private Calendar getCalendar(Date value, TimeZone timeZone) { + + Calendar calendar = null; + if (timeZone != null) { + calendar = Calendar.getInstance(timeZone); + } else { + calendar = Calendar.getInstance(); + } + calendar.setTime(value); + return calendar; + + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DomainValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,2065 @@ +/* + * 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.net.IDN; +import java.util.Arrays; +import java.util.Locale; + +/** + *

Domain name validation routines.

+ * + *

+ * This validator provides methods for validating Internet domain names + * and top-level domains. + *

+ * + *

Domain names are evaluated according + * to the standards RFC1034, + * section 3, and RFC1123, + * section 2.1. No accommodation is provided for the specialized needs of + * other applications; if the domain name has been URL-encoded, for example, + * validation will fail even though the equivalent plaintext version of the + * same name would have passed. + *

+ * + *

+ * Validation is also provided for top-level domains (TLDs) as defined and + * maintained by the Internet Assigned Numbers Authority (IANA): + *

+ * + *
    + *
  • {@link #isValidInfrastructureTld} - validates infrastructure TLDs + * (.arpa, etc.)
  • + *
  • {@link #isValidGenericTld} - validates generic TLDs + * (.com, .org, etc.)
  • + *
  • {@link #isValidCountryCodeTld} - validates country code TLDs + * (.us, .uk, .cn, etc.)
  • + *
+ * + *

+ * (NOTE: This class does not provide IP address lookup for domain names or + * methods to ensure that a given domain name matches a specific IP; see + * {@link java.net.InetAddress} for that functionality.) + *

+ * + * @version $Revision: 1781829 $ + * @since Validator 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. + */ + 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; + } + + /** + * 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; + } + 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 + */ + 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); + } + + // package protected for unit test access + // must agree with isValid() above + final boolean isValidDomainSyntax(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); + 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); + } + + /** + * 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); + } + + /** + * 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); + } + + /** + * 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); + } + + /** + * 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; + } + + // --------------------------------------------- + // ----- 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 + + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static final String[] INFRASTRUCTURE_TLDS = new String[] { + "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 + "aaa", // aaa American Automobile Association, Inc. + "aarp", // aarp AARP + "abarth", // abarth Fiat Chrysler Automobiles N.V. + "abb", // abb ABB Ltd + "abbott", // abbott Abbott Laboratories, Inc. + "abbvie", // abbvie AbbVie Inc. + "abc", // abc Disney Enterprises, Inc. + "able", // able Able Inc. + "abogado", // abogado Top Level Domain Holdings Limited + "abudhabi", // abudhabi Abu Dhabi Systems and Information Centre + "academy", // academy Half Oaks, LLC + "accenture", // accenture Accenture plc + "accountant", // accountant dot Accountant Limited + "accountants", // accountants Knob Town, LLC + "aco", // aco ACO Severin Ahlmann GmbH & Co. KG + "active", // active The Active Network, Inc + "actor", // actor United TLD Holdco Ltd. + "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. + "afl", // afl Australian Football League + "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. + "airbus", // airbus Airbus S.A.S. + "airforce", // airforce United TLD Holdco Ltd. + "airtel", // airtel Bharti Airtel Limited + "akdn", // akdn Fondation Aga Khan (Aga Khan Foundation) + "alfaromeo", // alfaromeo Fiat Chrysler Automobiles N.V. + "alibaba", // alibaba Alibaba Group Holding Limited + "alipay", // alipay Alibaba Group Holding Limited + "allfinanz", // allfinanz Allfinanz Deutsche Vermögensberatung Aktiengesellschaft + "allstate", // allstate Allstate Fire and Casualty Insurance Company + "ally", // ally Ally Financial Inc. + "alsace", // alsace REGION D ALSACE + "alstom", // alstom ALSTOM + "americanexpress", // americanexpress American Express Travel Related Services Company, Inc. + "americanfamily", // americanfamily AmFam, Inc. + "amex", // amex American Express Travel Related Services Company, Inc. + "amfam", // amfam AmFam, Inc. + "amica", // amica Amica Mutual Insurance Company + "amsterdam", // amsterdam Gemeente Amsterdam + "analytics", // analytics Campus IP LLC + "android", // android Charleston Road Registry Inc. + "anquan", // anquan QIHOO 360 TECHNOLOGY CO. LTD. + "anz", // anz Australia and New Zealand Banking Group Limited + "aol", // aol AOL Inc. + "apartments", // apartments June Maple, LLC + "app", // app Charleston Road Registry Inc. + "apple", // apple Apple Inc. + "aquarelle", // aquarelle Aquarelle.com + "aramco", // aramco Aramco Services Company + "archi", // archi STARTING DOT LIMITED + "army", // army United TLD Holdco Ltd. + "art", // art UK Creative Ideas Limited + "arte", // arte Association Relative à la Télévision Européenne G.E.I.E. + "asda", // asda Wal-Mart Stores, Inc. + "asia", // asia DotAsia Organisation Ltd. + "associates", // associates Baxter Hill, LLC + "athleta", // athleta The Gap, Inc. + "attorney", // attorney United TLD Holdco, Ltd + "auction", // auction United TLD HoldCo, Ltd. + "audi", // audi AUDI Aktiengesellschaft + "audible", // audible Amazon Registry Services, Inc. + "audio", // audio Uniregistry, Corp. + "auspost", // auspost Australian Postal Corporation + "author", // author Amazon Registry Services, Inc. + "auto", // auto Uniregistry, Corp. + "autos", // autos DERAutos, LLC + "avianca", // avianca Aerovias del Continente Americano S.A. Avianca + "aws", // aws Amazon Registry Services, Inc. + "axa", // axa AXA SA + "azure", // azure Microsoft Corporation + "baby", // baby Johnson & Johnson Services, Inc. + "baidu", // baidu Baidu, Inc. + "banamex", // banamex Citigroup Inc. + "bananarepublic", // bananarepublic The Gap, Inc. + "band", // band United TLD Holdco, Ltd + "bank", // bank fTLD Registry Services, LLC + "bar", // bar Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable + "barcelona", // barcelona Municipi de Barcelona + "barclaycard", // barclaycard Barclays Bank PLC + "barclays", // barclays Barclays Bank PLC + "barefoot", // barefoot Gallo Vineyards, Inc. + "bargains", // bargains Half Hallow, LLC + "baseball", // baseball MLB Advanced Media DH, LLC + "basketball", // basketball Fédération Internationale de Basketball (FIBA) + "bauhaus", // bauhaus Werkhaus GmbH + "bayern", // bayern Bayern Connect GmbH + "bbc", // bbc British Broadcasting Corporation + "bbt", // bbt BB&T Corporation + "bbva", // bbva BANCO BILBAO VIZCAYA ARGENTARIA, S.A. + "bcg", // bcg The Boston Consulting Group, Inc. + "bcn", // bcn Municipi de Barcelona + "beats", // beats Beats Electronics, LLC + "beauty", // beauty L'Oréal + "beer", // beer Top Level Domain Holdings Limited + "bentley", // bentley Bentley Motors Limited + "berlin", // berlin dotBERLIN GmbH & Co. KG + "best", // best BestTLD Pty Ltd + "bestbuy", // bestbuy BBY Solutions, Inc. + "bet", // bet Afilias plc + "bharti", // bharti Bharti Enterprises (Holding) Private Limited + "bible", // bible American Bible Society + "bid", // bid dot Bid Limited + "bike", // bike Grand Hollow, LLC + "bing", // bing Microsoft Corporation + "bingo", // bingo Sand Cedar, LLC + "bio", // bio STARTING DOT LIMITED + "biz", // biz Neustar, Inc. + "black", // black Afilias Limited + "blackfriday", // blackfriday Uniregistry, Corp. + "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 + "bnpparibas", // bnpparibas BNP Paribas + "boats", // boats DERBoats, LLC + "boehringer", // boehringer Boehringer Ingelheim International GmbH + "bofa", // bofa NMS Services, Inc. + "bom", // bom Núcleo de Informação e Coordenação do Ponto BR - NIC.br + "bond", // bond Bond University Limited + "boo", // boo Charleston Road Registry Inc. + "book", // book Amazon Registry Services, Inc. + "booking", // booking Booking.com B.V. + "boots", // boots THE BOOTS COMPANY PLC + "bosch", // bosch Robert Bosch GMBH + "bostik", // bostik Bostik SA + "boston", // boston Boston TLD Management, LLC + "bot", // bot Amazon Registry Services, Inc. + "boutique", // boutique Over Galley, LLC + "box", // box NS1 Limited + "bradesco", // bradesco Banco Bradesco S.A. + "bridgestone", // bridgestone Bridgestone Corporation + "broadway", // broadway Celebrate Broadway, Inc. + "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 + "build", // build Plan Bee LLC + "builders", // builders Atomic Madison, LLC + "business", // business Spring Cross, LLC + "buy", // buy Amazon Registry Services, INC + "buzz", // buzz DOTSTRATEGY CO. + "bzh", // bzh Association www.bzh + "cab", // cab Half Sunset, LLC + "cafe", // cafe Pioneer Canyon, LLC + "cal", // cal Charleston Road Registry Inc. + "call", // call Amazon Registry Services, Inc. + "calvinklein", // calvinklein PVH gTLD Holdings LLC + "cam", // cam AC Webconnecting Holding B.V. + "camera", // camera Atomic Maple, LLC + "camp", // camp Delta Dynamite, LLC + "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 + "capitalone", // capitalone Capital One Financial Corporation + "car", // car Cars Registry Limited + "caravan", // caravan Caravan International, Inc. + "cards", // cards Foggy Hollow, LLC + "care", // care Goose Cross, LLC + "career", // career dotCareer LLC + "careers", // careers Wild Corner, LLC + "cars", // cars Uniregistry, Corp. + "cartier", // cartier Richemont DNS Inc. + "casa", // casa Top Level Domain Holdings Limited + "case", // case CNH Industrial N.V. + "caseih", // caseih CNH Industrial N.V. + "cash", // cash Delta Lake, LLC + "casino", // casino Binky Sky, LLC + "cat", // cat Fundacio puntCAT + "catering", // catering New Falls. LLC + "catholic", // catholic Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) + "cba", // cba COMMONWEALTH BANK OF AUSTRALIA + "cbn", // cbn The Christian Broadcasting Network, Inc. + "cbre", // cbre CBRE, Inc. + "cbs", // cbs CBS Domains Inc. + "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. + "chase", // chase JPMorgan Chase & Co. + "chat", // chat Sand Fields, LLC + "cheap", // cheap Sand Cover, LLC + "chintai", // chintai CHINTAI Corporation + "chloe", // chloe Richemont DNS Inc. + "christmas", // christmas Uniregistry, Corp. + "chrome", // chrome Charleston Road Registry Inc. + "chrysler", // chrysler FCA US LLC. + "church", // church Holly Fileds, LLC + "cipriani", // cipriani Hotel Cipriani Srl + "circle", // circle Amazon Registry Services, Inc. + "cisco", // cisco Cisco Technology, Inc. + "citadel", // citadel Citadel Domain LLC + "citi", // citi Citigroup Inc. + "citic", // citic CITIC Group Corporation + "city", // city Snow Sky, LLC + "cityeats", // cityeats Lifestyle Domain Holdings, Inc. + "claims", // claims Black Corner, LLC + "cleaning", // cleaning Fox Shadow, LLC + "click", // click Uniregistry, Corp. + "clinic", // clinic Goose Park, LLC + "clinique", // clinique The Estée Lauder Companies Inc. + "clothing", // clothing Steel Lake, LLC + "cloud", // cloud ARUBA S.p.A. + "club", // club .CLUB DOMAINS, LLC + "clubmed", // clubmed Club Méditerranée S.A. + "coach", // coach Koko Island, LLC + "codes", // codes Puff Willow, LLC + "coffee", // coffee Trixy Cover, LLC + "college", // college XYZ.COM LLC + "cologne", // cologne NetCologne Gesellschaft für Telekommunikation mbH + "com", // com VeriSign Global Registry Services + "comcast", // comcast Comcast IP Holdings I, LLC + "commbank", // commbank COMMONWEALTH BANK OF AUSTRALIA + "community", // community Fox Orchard, LLC + "company", // company Silver Avenue, LLC + "compare", // compare iSelect Ltd + "computer", // computer Pine Mill, LLC + "comsec", // comsec VeriSign, Inc. + "condos", // condos Pine House, LLC + "construction", // construction Fox Dynamite, LLC + "consulting", // consulting United TLD Holdco, LTD. + "contact", // contact Top Level Spectrum, Inc. + "contractors", // contractors Magic Woods, LLC + "cooking", // cooking Top Level Domain Holdings Limited + "cookingchannel", // cookingchannel Lifestyle Domain Holdings, Inc. + "cool", // cool Koko Lake, LLC + "coop", // coop DotCooperation LLC + "corsica", // corsica Collectivité Territoriale de Corse + "country", // country Top Level Domain Holdings Limited + "coupon", // coupon Amazon Registry Services, Inc. + "coupons", // coupons Black Island, LLC + "courses", // courses OPEN UNIVERSITIES AUSTRALIA PTY LTD + "credit", // credit Snow Shadow, LLC + "creditcard", // creditcard Binky Frostbite, LLC + "creditunion", // creditunion CUNA Performance Resources, LLC + "cricket", // cricket dot Cricket Limited + "crown", // crown Crown Equipment Corporation + "crs", // crs Federated Co-operatives Limited + "cruise", // cruise Viking River Cruises (Bermuda) Ltd. + "cruises", // cruises Spring Way, LLC + "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. + "dabur", // dabur Dabur India Limited + "dad", // dad Charleston Road Registry Inc. + "dance", // dance United TLD Holdco Ltd. + "data", // data Dish DBS Corporation + "date", // date dot Date Limited + "dating", // dating Pine Fest, LLC + "datsun", // datsun NISSAN MOTOR CO., LTD. + "day", // day Charleston Road Registry Inc. + "dclk", // dclk Charleston Road Registry Inc. + "dds", // dds Minds + Machines Group Limited + "deal", // deal Amazon Registry Services, Inc. + "dealer", // dealer Dealer Dot Com, Inc. + "deals", // deals Sand Sunset, LLC + "degree", // degree United TLD Holdco, Ltd + "delivery", // delivery Steel Station, LLC + "dell", // dell Dell Inc. + "deloitte", // deloitte Deloitte Touche Tohmatsu + "delta", // delta Delta Air Lines, Inc. + "democrat", // democrat United TLD Holdco Ltd. + "dental", // dental Tin Birch, LLC + "dentist", // dentist United TLD Holdco, Ltd + "desi", // desi Desi Networks LLC + "design", // design Top Level Design, LLC + "dev", // dev Charleston Road Registry Inc. + "dhl", // dhl Deutsche Post AG + "diamonds", // diamonds John Edge, LLC + "diet", // diet Uniregistry, Corp. + "digital", // digital Dash Park, LLC + "direct", // direct Half Trail, LLC + "directory", // directory Extra Madison, LLC + "discount", // discount Holly Hill, LLC + "discover", // discover Discover Financial Services + "dish", // dish Dish DBS Corporation + "diy", // diy Lifestyle Domain Holdings, Inc. + "dnp", // dnp Dai Nippon Printing Co., Ltd. + "docs", // docs Charleston Road Registry Inc. + "doctor", // doctor Brice Trail, LLC + "dodge", // dodge FCA US LLC. + "dog", // dog Koko Mill, LLC + "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. + "dunlop", // dunlop The Goodyear Tire & Rubber Company + "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 + "dvr", // dvr Hughes Satellite Systems Corporation + "earth", // earth Interlink Co., Ltd. + "eat", // eat Charleston Road Registry Inc. + "eco", // eco Big Room Inc. + "edeka", // edeka EDEKA Verband kaufmännischer Genossenschaften e.V. + "edu", // edu EDUCAUSE + "education", // education Brice Way, LLC + "email", // email Spring Madison, LLC + "emerck", // emerck Merck KGaA + "energy", // energy Binky Birch, LLC + "engineer", // engineer United TLD Holdco Ltd. + "engineering", // engineering Romeo Canyon + "enterprises", // enterprises Snow Oaks, LLC + "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 + "eurovision", // eurovision European Broadcasting Union (EBU) + "eus", // eus Puntueus Fundazioa + "events", // events Pioneer Maple, LLC + "everbank", // everbank EverBank + "exchange", // exchange Spring Falls, LLC + "expert", // expert Magic Pass, LLC + "exposed", // exposed Victor Beach, LLC + "express", // express Sea Sunset, LLC + "extraspace", // extraspace Extra Space Storage LLC + "fage", // fage Fage International S.A. + "fail", // fail Atomic Pipe, LLC + "fairwinds", // fairwinds FairWinds Partners, LLC + "faith", // faith dot Faith Limited + "family", // family United TLD Holdco Ltd. + "fan", // fan Asiamix Digital Ltd + "fans", // fans Asiamix Digital Limited + "farm", // farm Just Maple, LLC + "farmers", // farmers Farmers Insurance Exchange + "fashion", // fashion Top Level Domain Holdings Limited + "fast", // fast Amazon Registry Services, Inc. + "fedex", // fedex Federal Express Corporation + "feedback", // feedback Top Level Spectrum, Inc. + "ferrari", // ferrari Fiat Chrysler Automobiles N.V. + "ferrero", // ferrero Ferrero Trading Lux S.A. + "fiat", // fiat Fiat Chrysler Automobiles N.V. + "fidelity", // fidelity Fidelity Brokerage Services LLC + "fido", // fido Rogers Communications Canada Inc. + "film", // film Motion Picture Domain Registry Pty Ltd + "final", // final Núcleo de Informação e Coordenação do Ponto BR - NIC.br + "finance", // finance Cotton Cypress, LLC + "financial", // financial Just Cover, LLC + "fire", // fire Amazon Registry Services, Inc. + "firestone", // firestone Bridgestone Corporation + "firmdale", // firmdale Firmdale Holdings Limited + "fish", // fish Fox Woods, LLC + "fishing", // fishing Top Level Domain Holdings Limited + "fit", // fit Minds + Machines Group Limited + "fitness", // fitness Brice Orchard, LLC + "flickr", // flickr Yahoo! Domain Services Inc. + "flights", // flights Fox Station, LLC + "flir", // flir FLIR Systems, Inc. + "florist", // florist Half Cypress, LLC + "flowers", // flowers Uniregistry, Corp. +// "flsmidth", // flsmidth FLSmidth A/S retired 2016-07-22 + "fly", // fly Charleston Road Registry Inc. + "foo", // foo Charleston Road Registry Inc. + "food", // food Lifestyle Domain Holdings, Inc. + "foodnetwork", // foodnetwork Lifestyle Domain Holdings, Inc. + "football", // football Foggy Farms, LLC + "ford", // ford Ford Motor Company + "forex", // forex DOTFOREX REGISTRY LTD + "forsale", // forsale United TLD Holdco, LLC + "forum", // forum Fegistry, LLC + "foundation", // foundation John Dale, LLC + "fox", // fox FOX Registry, LLC + "free", // free Amazon Registry Services, Inc. + "fresenius", // fresenius Fresenius Immobilien-Verwaltungs-GmbH + "frl", // frl FRLregistry B.V. + "frogans", // frogans OP3FT + "frontdoor", // frontdoor Lifestyle Domain Holdings, Inc. + "frontier", // frontier Frontier Communications Corporation + "ftr", // ftr Frontier Communications Corporation + "fujitsu", // fujitsu Fujitsu Limited + "fujixerox", // fujixerox Xerox DNHC LLC + "fun", // fun DotSpace, Inc. + "fund", // fund John Castle, LLC + "furniture", // furniture Lone Fields, LLC + "futbol", // futbol United TLD Holdco, Ltd. + "fyi", // fyi Silver Tigers, LLC + "gal", // gal Asociación puntoGAL + "gallery", // gallery Sugar House, LLC + "gallo", // gallo Gallo Vineyards, Inc. + "gallup", // gallup Gallup, Inc. + "game", // game Uniregistry, Corp. + "games", // games United TLD Holdco Ltd. + "gap", // gap The Gap, Inc. + "garden", // garden Top Level Domain Holdings Limited + "gbiz", // gbiz Charleston Road Registry Inc. + "gdn", // gdn Joint Stock Company "Navigation-information systems" + "gea", // gea GEA Group Aktiengesellschaft + "gent", // gent COMBELL GROUP NV/SA + "genting", // genting Resorts World Inc. Pte. Ltd. + "george", // george Wal-Mart Stores, Inc. + "ggee", // ggee GMO Internet, Inc. + "gift", // gift Uniregistry, Corp. + "gifts", // gifts Goose Sky, LLC + "gives", // gives United TLD Holdco Ltd. + "giving", // giving Giving Limited + "glade", // glade Johnson Shareholdings, Inc. + "glass", // glass Black Cover, LLC + "gle", // gle Charleston Road Registry Inc. + "global", // global Dot Global Domain Registry Limited + "globo", // globo Globo Comunicação e Participações S.A + "gmail", // gmail Charleston Road Registry Inc. + "gmbh", // gmbh Extra Dynamite, LLC + "gmo", // gmo GMO Internet, Inc. + "gmx", // gmx 1&1 Mail & Media GmbH + "godaddy", // godaddy Go Daddy East, LLC + "gold", // gold June Edge, LLC + "goldpoint", // goldpoint YODOBASHI CAMERA CO.,LTD. + "golf", // golf Lone Falls, LLC + "goo", // goo NTT Resonant Inc. + "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. + "gop", // gop Republican State Leadership Committee, Inc. + "got", // got Amazon Registry Services, Inc. + "gov", // gov General Services Administration Attn: QTDC, 2E08 (.gov Domain Registration) + "grainger", // grainger Grainger Registry Services, LLC + "graphics", // graphics Over Madison, LLC + "gratis", // gratis Pioneer Tigers, LLC + "green", // green Afilias Limited + "gripe", // gripe Corn Sunset, LLC + "group", // group Romeo Town, LLC + "guardian", // guardian The Guardian Life Insurance Company of America + "gucci", // gucci Guccio Gucci S.p.a. + "guge", // guge Charleston Road Registry Inc. + "guide", // guide Snow Moon, LLC + "guitars", // guitars Uniregistry, Corp. + "guru", // guru Pioneer Cypress, LLC + "hair", // hair L'Oreal + "hamburg", // hamburg Hamburg Top-Level-Domain GmbH + "hangout", // hangout Charleston Road Registry Inc. + "haus", // haus United TLD Holdco, LTD. + "hbo", // hbo HBO Registry Services, Inc. + "hdfc", // hdfc HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED + "hdfcbank", // hdfcbank HDFC Bank Limited + "health", // health DotHealth, LLC + "healthcare", // healthcare Silver Glen, LLC + "help", // help Uniregistry, Corp. + "helsinki", // helsinki City of Helsinki + "here", // here Charleston Road Registry Inc. + "hermes", // hermes Hermes International + "hgtv", // hgtv Lifestyle Domain Holdings, Inc. + "hiphop", // hiphop Uniregistry, Corp. + "hisamitsu", // hisamitsu Hisamitsu Pharmaceutical Co.,Inc. + "hitachi", // hitachi Hitachi, Ltd. + "hiv", // hiv dotHIV gemeinnuetziger e.V. + "hkt", // hkt PCCW-HKT DataCom Services Limited + "hockey", // hockey Half Willow, LLC + "holdings", // holdings John Madison, LLC + "holiday", // holiday Goose Woods, LLC + "homedepot", // homedepot Homer TLC, Inc. + "homegoods", // homegoods The TJX Companies, Inc. + "homes", // homes DERHomes, LLC + "homesense", // homesense The TJX Companies, Inc. + "honda", // honda Honda Motor Co., Ltd. + "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 + "hotmail", // hotmail Microsoft Corporation + "house", // house Sugar Park, LLC + "how", // how Charleston Road Registry Inc. + "hsbc", // hsbc HSBC Holdings PLC + "htc", // htc HTC corporation + "hughes", // hughes Hughes Satellite Systems Corporation + "hyatt", // hyatt Hyatt GTLD, L.L.C. + "hyundai", // hyundai Hyundai Motor Company + "ibm", // ibm International Business Machines Corporation + "icbc", // icbc Industrial and Commercial Bank of China Limited + "ice", // ice IntercontinentalExchange, Inc. + "icu", // icu One.com A/S + "ieee", // ieee IEEE Global LLC + "ifm", // ifm ifm electronic gmbh +// "iinet", // iinet Connect West Pty. Ltd. (Retired) + "ikano", // ikano Ikano S.A. + "imamat", // imamat Fondation Aga Khan (Aga Khan Foundation) + "imdb", // imdb Amazon Registry Services, Inc. + "immo", // immo Auburn Bloom, LLC + "immobilien", // immobilien United TLD Holdco Ltd. + "industries", // industries Outer House, LLC + "infiniti", // infiniti NISSAN MOTOR CO., LTD. + "info", // info Afilias Limited + "ing", // ing Charleston Road Registry Inc. + "ink", // ink Top Level Design, LLC + "institute", // institute Outer Maple, LLC + "insurance", // insurance fTLD Registry Services LLC + "insure", // insure Pioneer Willow, LLC + "int", // int Internet Assigned Numbers Authority + "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 + "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. + "jaguar", // jaguar Jaguar Land Rover Ltd + "java", // java Oracle Corporation + "jcb", // jcb JCB Co., Ltd. + "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. + "jll", // jll Jones Lang LaSalle Incorporated + "jmp", // jmp Matrix IP LLC + "jnj", // jnj Johnson & Johnson Services, Inc. + "jobs", // jobs Employ Media LLC + "joburg", // joburg ZA Central Registry NPC trading as ZA Central Registry + "jot", // jot Amazon Registry Services, Inc. + "joy", // joy Amazon Registry Services, Inc. + "jpmorgan", // jpmorgan JPMorgan Chase & Co. + "jprs", // jprs Japan Registry Services Co., Ltd. + "juegos", // juegos Uniregistry, Corp. + "juniper", // juniper JUNIPER NETWORKS, INC. + "kaufen", // kaufen United TLD Holdco Ltd. + "kddi", // kddi KDDI CORPORATION + "kerryhotels", // kerryhotels Kerry Trading Co. Limited + "kerrylogistics", // kerrylogistics Kerry Trading Co. Limited + "kerryproperties", // kerryproperties Kerry Trading Co. Limited + "kfh", // kfh Kuwait Finance House + "kia", // kia KIA MOTORS CORPORATION + "kim", // kim Afilias Limited + "kinder", // kinder Ferrero Trading Lux S.A. + "kindle", // kindle Amazon Registry Services, Inc. + "kitchen", // kitchen Just Goodbye, LLC + "kiwi", // kiwi DOT KIWI LIMITED + "koeln", // koeln NetCologne Gesellschaft für Telekommunikation mbH + "komatsu", // komatsu Komatsu Ltd. + "kosher", // kosher Kosher Marketing Assets LLC + "kpmg", // kpmg KPMG International Cooperative (KPMG International Genossenschaft) + "kpn", // kpn Koninklijke KPN N.V. + "krd", // krd KRG Department of Information Technology + "kred", // kred KredTLD Pty Ltd + "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 + "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 + "land", // land Pine Moon, LLC + "landrover", // landrover Jaguar Land Rover Ltd + "lanxess", // lanxess LANXESS Corporation + "lasalle", // lasalle Jones Lang LaSalle Incorporated + "lat", // lat ECOM-LAC Federación de Latinoamérica y el Caribe para Internet y el Comercio Electrónico + "latino", // latino Dish DBS Corporation + "latrobe", // latrobe La Trobe University + "law", // law Minds + Machines Group Limited + "lawyer", // lawyer United TLD Holdco, Ltd + "lds", // lds IRI Domain Management, LLC + "lease", // lease Victor Trail, LLC + "leclerc", // leclerc A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc + "lefrak", // lefrak LeFrak Organization, Inc. + "legal", // legal Blue Falls, LLC + "lego", // lego LEGO Juris A/S + "lexus", // lexus TOYOTA MOTOR CORPORATION + "lgbt", // lgbt Afilias Limited + "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 + "lifestyle", // lifestyle Lifestyle Domain Holdings, Inc. + "lighting", // lighting John McCook, LLC + "like", // like Amazon Registry Services, Inc. + "lilly", // lilly Eli Lilly and Company + "limited", // limited Big Fest, LLC + "limo", // limo Hidden Frostbite, LLC + "lincoln", // lincoln Ford Motor Company + "linde", // linde Linde Aktiengesellschaft + "link", // link Uniregistry, Corp. + "lipsy", // lipsy Lipsy Ltd + "live", // live United TLD Holdco Ltd. + "living", // living Lifestyle Domain Holdings, Inc. + "lixil", // lixil LIXIL Group Corporation + "loan", // loan dot Loan Limited + "loans", // loans June Woods, LLC + "locker", // locker Dish DBS Corporation + "locus", // locus Locus Analytics LLC + "loft", // loft Annco, Inc. + "lol", // lol Uniregistry, Corp. + "london", // london Dot London Domains Limited + "lotte", // lotte Lotte Holdings Co., Ltd. + "lotto", // lotto Afilias Limited + "love", // love Merchant Law Group LLP + "lpl", // lpl LPL Holdings, Inc. + "lplfinancial", // lplfinancial LPL Holdings, Inc. + "ltd", // ltd Over Corner, LLC + "ltda", // ltda InterNetX Corp. + "lundbeck", // lundbeck H. Lundbeck A/S + "lupin", // lupin LUPIN LIMITED + "luxe", // luxe Top Level Domain Holdings Limited + "luxury", // luxury Luxury Partners LLC + "macys", // macys Macys, Inc. + "madrid", // madrid Comunidad de Madrid + "maif", // maif Mutuelle Assurance Instituteur France (MAIF) + "maison", // maison Victor Frostbite, LLC + "makeup", // makeup L'Oréal + "man", // man MAN SE + "management", // management John Goodbye, LLC + "mango", // mango PUNTO FA S.L. + "market", // market Unitied TLD Holdco, Ltd + "marketing", // marketing Fern Pass, LLC + "markets", // markets DOTMARKETS REGISTRY LTD + "marriott", // marriott Marriott Worldwide Corporation + "marshalls", // marshalls The TJX Companies, Inc. + "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 + "mckinsey", // mckinsey McKinsey Holdings, Inc. + "med", // med Medistry LLC + "media", // media Grand Glen, LLC + "meet", // meet Afilias Limited + "melbourne", // melbourne The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation + "meme", // meme Charleston Road Registry Inc. + "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 + "miami", // miami Top Level Domain Holdings Limited + "microsoft", // microsoft Microsoft Corporation + "mil", // mil DoD Network Information Center + "mini", // mini Bayerische Motoren Werke Aktiengesellschaft + "mint", // mint Intuit Administrative Services, Inc. + "mit", // mit Massachusetts Institute of Technology + "mitsubishi", // mitsubishi Mitsubishi Corporation + "mlb", // mlb MLB Advanced Media DH, LLC + "mls", // mls The Canadian Real Estate Association + "mma", // mma MMA IARD + "mobi", // mobi Afilias Technologies Limited dba dotMobi + "mobile", // mobile Dish DBS Corporation + "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. + "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. + "msd", // msd MSD Registry Holdings, Inc. + "mtn", // mtn MTN Dubai Limited + "mtpc", // mtpc Mitsubishi Tanabe Pharma Corporation + "mtr", // mtr MTR Corporation Limited + "museum", // museum Museum Domain Management Association + "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 + "nagoya", // nagoya GMO Registry, Inc. + "name", // name VeriSign Information Services, Inc. + "nationwide", // nationwide Nationwide Mutual Insurance Company + "natura", // natura NATURA COSMÉTICOS S.A. + "navy", // navy United TLD Holdco Ltd. + "nba", // nba NBA REGISTRY, LLC + "nec", // nec NEC Corporation + "net", // net VeriSign Global Registry Services + "netbank", // netbank COMMONWEALTH BANK OF AUSTRALIA + "netflix", // netflix Netflix, Inc. + "network", // network Trixy Manor, LLC + "neustar", // neustar NeuStar, Inc. + "new", // new Charleston Road Registry Inc. + "newholland", // newholland CNH Industrial N.V. + "news", // news United TLD Holdco Ltd. + "next", // next Next plc + "nextdirect", // nextdirect Next plc + "nexus", // nexus Charleston Road Registry Inc. + "nfl", // nfl NFL Reg Ops LLC + "ngo", // ngo Public Interest Registry + "nhk", // nhk Japan Broadcasting Corporation (NHK) + "nico", // nico DWANGO Co., Ltd. + "nike", // nike NIKE, Inc. + "nikon", // nikon NIKON CORPORATION + "ninja", // ninja United TLD Holdco Ltd. + "nissan", // nissan NISSAN MOTOR CO., LTD. + "nissay", // nissay Nippon Life Insurance Company + "nokia", // nokia Nokia Corporation + "northwesternmutual", // northwesternmutual Northwestern Mutual Registry, LLC + "norton", // norton Symantec Corporation + "now", // now Amazon Registry Services, Inc. + "nowruz", // nowruz Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. + "nowtv", // nowtv Starbucks (HK) Limited + "nra", // nra NRA Holdings Company, INC. + "nrw", // nrw Minds + Machines GmbH + "ntt", // ntt NIPPON TELEGRAPH AND TELEPHONE CORPORATION + "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. + "office", // office Microsoft Corporation + "okinawa", // okinawa BusinessRalliart inc. + "olayan", // olayan Crescent Holding GmbH + "olayangroup", // olayangroup Crescent Holding GmbH + "oldnavy", // oldnavy The Gap, Inc. + "ollo", // ollo Dish DBS Corporation + "omega", // omega The Swatch Group Ltd + "one", // one One.com A/S + "ong", // ong Public Interest Registry + "onl", // onl I-REGISTRY Ltd., Niederlassung Deutschland + "online", // online DotOnline Inc. + "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 + "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. + "panasonic", // panasonic Panasonic Corporation + "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 + "parts", // parts Sea Goodbye, LLC + "party", // party Blue Sky Registry Limited + "passagens", // passagens Travel Reservations SRL + "pay", // pay Amazon Registry Services, Inc. + "pccw", // pccw PCCW Enterprises Limited + "pet", // pet Afilias plc + "pfizer", // pfizer Pfizer Inc. + "pharmacy", // pharmacy National Association of Boards of Pharmacy + "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. + "pics", // pics Uniregistry, Corp. + "pictet", // pictet Pictet Europe S.A. + "pictures", // pictures Foggy Sky, LLC + "pid", // pid Top Level Spectrum, Inc. + "pin", // pin Amazon Registry Services, Inc. + "ping", // ping Ping Registry Provider, Inc. + "pink", // pink Afilias Limited + "pioneer", // pioneer Pioneer Corporation + "pizza", // pizza Foggy Moon, LLC + "place", // place Snow Galley, LLC + "play", // play Charleston Road Registry Inc. + "playstation", // playstation Sony Computer Entertainment Inc. + "plumbing", // plumbing Spring Tigers, LLC + "plus", // plus Sugar Mill, LLC + "pnc", // pnc PNC Domain Co., LLC + "pohl", // pohl Deutsche Vermögensberatung Aktiengesellschaft DVAG + "poker", // poker Afilias Domains No. 5 Limited + "politie", // politie Politie Nederland + "porn", // porn ICM Registry PN LLC + "post", // post Universal Postal Union + "pramerica", // pramerica Prudential Financial, Inc. + "praxi", // praxi Praxi S.p.A. + "press", // press DotPress Inc. + "prime", // prime Amazon Registry Services, Inc. + "pro", // pro Registry Services Corporation dba RegistryPro + "prod", // prod Charleston Road Registry Inc. + "productions", // productions Magic Birch, LLC + "prof", // prof Charleston Road Registry Inc. + "progressive", // progressive Progressive Casualty Insurance Company + "promo", // promo Afilias plc + "properties", // properties Big Pass, LLC + "property", // property Uniregistry, Corp. + "protection", // protection XYZ.COM LLC + "pru", // pru Prudential Financial, Inc. + "prudential", // prudential Prudential Financial, Inc. + "pub", // pub United TLD Holdco Ltd. + "pwc", // pwc PricewaterhouseCoopers LLP + "qpon", // qpon dotCOOL, Inc. + "quebec", // quebec PointQuébec Inc + "quest", // quest Quest ION Limited + "qvc", // qvc QVC, Inc. + "racing", // racing Premier Registry Limited + "radio", // radio European Broadcasting Union (EBU) + "raid", // raid Johnson Shareholdings, Inc. + "read", // read Amazon Registry Services, Inc. + "realestate", // realestate dotRealEstate LLC + "realtor", // realtor Real Estate Domains LLC + "realty", // realty Fegistry, LLC + "recipes", // recipes Grand Island, LLC + "red", // red Afilias Limited + "redstone", // redstone Redstone Haute Couture Co., Ltd. + "redumbrella", // redumbrella Travelers TLD, LLC + "rehab", // rehab United TLD Holdco Ltd. + "reise", // reise Foggy Way, LLC + "reisen", // reisen New Cypress, LLC + "reit", // reit National Association of Real Estate Investment Trusts, Inc. + "reliance", // reliance Reliance Industries Limited + "ren", // ren Beijing Qianxiang Wangjing Technology Development Co., Ltd. + "rent", // rent XYZ.COM LLC + "rentals", // rentals Big Hollow,LLC + "repair", // repair Lone Sunset, LLC + "report", // report Binky Glen, LLC + "republican", // republican United TLD Holdco Ltd. + "rest", // rest Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable + "restaurant", // restaurant Snow Avenue, LLC + "review", // review dot Review Limited + "reviews", // reviews United TLD Holdco, Ltd. + "rexroth", // rexroth Robert Bosch GMBH + "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. + "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 + "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. + "ruhr", // ruhr regiodot GmbH & Co. KG + "run", // run Snow Park, LLC + "rwe", // rwe RWE AG + "ryukyu", // ryukyu BusinessRalliart inc. + "saarland", // saarland dotSaarland GmbH + "safe", // safe Amazon Registry Services, Inc. + "safety", // safety Safety Registry Services, LLC. + "sakura", // sakura SAKURA Internet Inc. + "sale", // sale United TLD Holdco, Ltd + "salon", // salon Outer Orchard, LLC + "samsclub", // samsclub Wal-Mart Stores, Inc. + "samsung", // samsung SAMSUNG SDS CO., LTD + "sandvik", // sandvik Sandvik AB + "sandvikcoromant", // sandvikcoromant Sandvik AB + "sanofi", // sanofi Sanofi + "sap", // sap SAP AG + "sapo", // sapo PT Comunicacoes S.A. + "sarl", // sarl Delta Orchard, LLC + "sas", // sas Research IP LLC + "save", // save Amazon Registry Services, Inc. + "saxo", // saxo Saxo Bank A/S + "sbi", // sbi STATE BANK OF INDIA + "sbs", // sbs SPECIAL BROADCASTING SERVICE CORPORATION + "sca", // sca SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ) + "scb", // scb The Siam Commercial Bank Public Company Limited ("SCB") + "schaeffler", // schaeffler Schaeffler Technologies AG & Co. KG + "schmidt", // schmidt SALM S.A.S. + "scholarships", // scholarships Scholarships.com, LLC + "school", // school Little Galley, LLC + "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 + "scot", // scot Dot Scot Registry Limited + "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 + "seven", // seven Seven West Media Ltd + "sew", // sew SEW-EURODRIVE GmbH & Co KG + "sex", // sex ICM Registry SX LLC + "sexy", // sexy Uniregistry, Corp. + "sfr", // sfr Societe Francaise du Radiotelephone - SFR + "shangrila", // shangrila Shangri‐La International Hotel Management Limited + "sharp", // sharp Sharp Corporation + "shaw", // shaw Shaw Cablesystems G.P. + "shell", // shell Shell Information Technology International Inc + "shia", // shia Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. + "shiksha", // shiksha Afilias Limited + "shoes", // shoes Binky Galley, LLC + "shop", // shop GMO Registry, Inc. + "shopping", // shopping Over Keep, LLC + "shouji", // shouji QIHOO 360 TECHNOLOGY CO. LTD. + "show", // show Snow Beach, LLC + "showtime", // showtime CBS Domains Inc. + "shriram", // shriram Shriram Capital Ltd. + "silk", // silk Amazon Registry Services, Inc. + "sina", // sina Sina Corporation + "singles", // singles Fern Madison, LLC + "site", // site DotSite Inc. + "ski", // ski STARTING DOT LIMITED + "skin", // skin L'Oréal + "sky", // sky Sky International AG + "skype", // skype Microsoft Corporation + "sling", // sling Hughes Satellite Systems Corporation + "smart", // smart Smart Communications, Inc. (SMART) + "smile", // smile Amazon Registry Services, Inc. + "sncf", // sncf SNCF (Société Nationale des Chemins de fer Francais) + "soccer", // soccer Foggy Shadow, LLC + "social", // social United TLD Holdco Ltd. + "softbank", // softbank SoftBank Group Corp. + "software", // software United TLD Holdco, Ltd + "sohu", // sohu Sohu.com Limited + "solar", // solar Ruby Town, LLC + "solutions", // solutions Silver Cover, LLC + "song", // song Amazon Registry Services, Inc. + "sony", // sony Sony Corporation + "soy", // soy Charleston Road Registry Inc. + "space", // space DotSpace Inc. + "spiegel", // spiegel SPIEGEL-Verlag Rudolf Augstein GmbH & Co. KG + "spot", // spot Amazon Registry Services, Inc. + "spreadbetting", // spreadbetting DOTSPREADBETTING REGISTRY LTD + "srl", // srl InterNetX Corp. + "srt", // srt FCA US LLC. + "stada", // stada STADA Arzneimittel AG + "staples", // staples Staples, Inc. + "star", // star Star India Private Limited + "starhub", // starhub StarHub Limited + "statebank", // statebank STATE BANK OF INDIA + "statefarm", // statefarm State Farm Mutual Automobile Insurance Company + "statoil", // statoil Statoil ASA + "stc", // stc Saudi Telecom Company + "stcgroup", // stcgroup Saudi Telecom Company + "stockholm", // stockholm Stockholms kommun + "storage", // storage Self Storage Company LLC + "store", // store DotStore Inc. + "stream", // stream dot Stream Limited + "studio", // studio United TLD Holdco Ltd. + "study", // study OPEN UNIVERSITIES AUSTRALIA PTY LTD + "style", // style Binky Moon, LLC + "sucks", // sucks Vox Populi Registry Ltd. + "supplies", // supplies Atomic Fields, LLC + "supply", // supply Half Falls, LLC + "support", // support Grand Orchard, LLC + "surf", // surf Top Level Domain Holdings Limited + "surgery", // surgery Tin Avenue, LLC + "suzuki", // suzuki SUZUKI MOTOR CORPORATION + "swatch", // swatch The Swatch Group Ltd + "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 + "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" + "tattoo", // tattoo Uniregistry, Corp. + "tax", // tax Storm Orchard, LLC + "taxi", // taxi Pine Falls, LLC + "tci", // tci Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. + "tdk", // tdk TDK Corporation + "team", // team Atomic Lake, LLC + "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. + "temasek", // temasek Temasek Holdings (Private) Limited + "tennis", // tennis Cotton Bloom, LLC + "teva", // teva Teva Pharmaceutical Industries Limited + "thd", // thd Homer TLC, Inc. + "theater", // theater Blue Tigers, LLC + "theatre", // theatre XYZ.COM LLC + "tiaa", // tiaa Teachers Insurance and Annuity Association of America + "tickets", // tickets Accent Media Limited + "tienda", // tienda Victor Manor, LLC + "tiffany", // tiffany Tiffany and Company + "tips", // tips Corn Willow, LLC + "tires", // tires Dog Edge, LLC + "tirol", // tirol punkt Tirol GmbH + "tjmaxx", // tjmaxx The TJX Companies, Inc. + "tjx", // tjx The TJX Companies, Inc. + "tkmaxx", // tkmaxx The TJX Companies, Inc. + "tmall", // tmall Alibaba Group Holding Limited + "today", // today Pearl Woods, LLC + "tokyo", // tokyo GMO Registry, Inc. + "tools", // tools Pioneer North, LLC + "top", // top Jiangsu Bangning Science & Technology Co.,Ltd. + "toray", // toray Toray Industries, Inc. + "toshiba", // toshiba TOSHIBA Corporation + "total", // total Total SA + "tours", // tours Sugar Station, LLC + "town", // town Koko Moon, LLC + "toyota", // toyota TOYOTA MOTOR CORPORATION + "toys", // toys Pioneer Orchard, LLC + "trade", // trade Elite Registry Limited + "trading", // trading DOTTRADING REGISTRY LTD + "training", // training Wild Willow, LLC + "travel", // travel Tralliance Registry Management Company, LLC. + "travelchannel", // travelchannel Lifestyle Domain Holdings, Inc. + "travelers", // travelers Travelers TLD, LLC + "travelersinsurance", // travelersinsurance Travelers TLD, LLC + "trust", // trust Artemis Internet Inc + "trv", // trv Travelers TLD, LLC + "tube", // tube Latin American Telecom LLC + "tui", // tui TUI AG + "tunes", // tunes Amazon Registry Services, Inc. + "tushu", // tushu Amazon Registry Services, Inc. + "tvs", // tvs T V SUNDRAM IYENGAR & SONS PRIVATE LIMITED + "ubank", // ubank National Australia Bank Limited + "ubs", // ubs UBS AG + "uconnect", // uconnect FCA US LLC. + "unicom", // unicom China United Network Communications Corporation Limited + "university", // university Little Station, LLC + "uno", // uno Dot Latin LLC + "uol", // uol UBN INTERNET LTDA. + "ups", // ups UPS Market Driver, Inc. + "vacations", // vacations Atomic Tigers, LLC + "vana", // vana Lifestyle Domain Holdings, Inc. + "vanguard", // vanguard The Vanguard Group, Inc. + "vegas", // vegas Dot Vegas, Inc. + "ventures", // ventures Binky Lake, LLC + "verisign", // verisign VeriSign, Inc. + "versicherung", // versicherung dotversicherung-registry GmbH + "vet", // vet United TLD Holdco, Ltd + "viajes", // viajes Black Madison, LLC + "video", // video United TLD Holdco, Ltd + "vig", // vig VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe + "viking", // viking Viking River Cruises (Bermuda) Ltd. + "villas", // villas New Sky, LLC + "vin", // vin Holly Shadow, LLC + "vip", // vip Minds + Machines Group Limited + "virgin", // virgin Virgin Enterprises Limited + "visa", // visa Visa Worldwide Pte. Limited + "vision", // vision Koko Station, LLC + "vista", // vista Vistaprint Limited + "vistaprint", // vistaprint Vistaprint Limited + "viva", // viva Saudi Telecom Company + "vivo", // vivo Telefonica Brasil S.A. + "vlaanderen", // vlaanderen DNS.be vzw + "vodka", // vodka Top Level Domain Holdings Limited + "volkswagen", // volkswagen Volkswagen Group of America Inc. + "volvo", // volvo Volvo Holding Sverige Aktiebolag + "vote", // vote Monolith Registry LLC + "voting", // voting Valuetainment Corp. + "voto", // voto Monolith Registry LLC + "voyage", // voyage Ruby House, LLC + "vuelos", // vuelos Travel Reservations SRL + "wales", // wales Nominet UK + "walmart", // walmart Wal-Mart Stores, Inc. + "walter", // walter Sandvik AB + "wang", // wang Zodiac Registry Limited + "wanggou", // wanggou Amazon Registry Services, Inc. + "warman", // warman Weir Group IP Limited + "watch", // watch Sand Shadow, LLC + "watches", // watches Richemont DNS Inc. + "weather", // weather The Weather Channel, LLC + "weatherchannel", // weatherchannel The Weather Channel, LLC + "webcam", // webcam dot Webcam Limited + "weber", // weber Saint-Gobain Weber SA + "website", // website DotWebsite Inc. + "wed", // wed Atgron, Inc. + "wedding", // wedding Top Level Domain Holdings Limited + "weibo", // weibo Sina Corporation + "weir", // weir Weir Group IP Limited + "whoswho", // whoswho Who's Who Registry + "wien", // wien punkt.wien GmbH + "wiki", // wiki Top Level Design, LLC + "williamhill", // williamhill William Hill Organization Limited + "win", // win First Registry Limited + "windows", // windows Microsoft Corporation + "wine", // wine June Station, LLC + "winners", // winners The TJX Companies, Inc. + "wme", // wme William Morris Endeavor Entertainment, LLC + "wolterskluwer", // wolterskluwer Wolters Kluwer N.V. + "woodside", // woodside Woodside Petroleum Limited + "work", // work Top Level Domain Holdings Limited + "works", // works Little Dynamite, LLC + "world", // world Bitter Fields, LLC + "wow", // wow Amazon Registry Services, Inc. + "wtc", // wtc World Trade Centers Association, Inc. + "wtf", // wtf Hidden Way, LLC + "xbox", // xbox Microsoft Corporation + "xerox", // xerox Xerox DNHC LLC + "xfinity", // xfinity Comcast IP Holdings I, LLC + "xihuan", // xihuan QIHOO 360 TECHNOLOGY CO. LTD. + "xin", // xin Elegant Leader Limited + "xn--11b4c3d", // कॉम VeriSign Sarl + "xn--1ck2e1b", // セール Amazon Registry Services, Inc. + "xn--1qqw23a", // 佛山 Guangzhou YU Wei Information Technology Co., Ltd. + "xn--30rr7y", // 慈善 Excellent First Limited + "xn--3bst00m", // 集团 Eagle Horizon Limited + "xn--3ds443g", // 在线 TLD REGISTRY LIMITED + "xn--3oq18vl8pn36a", // 大众汽车 Volkswagen (China) Investment Co., Ltd. + "xn--3pxu8k", // 点看 VeriSign Sarl + "xn--42c2d9a", // คอม VeriSign Sarl + "xn--45q11c", // 八卦 Zodiac Scorpio Limited + "xn--4gbrim", // موقع Suhub Electronic Establishment + "xn--55qw42g", // 公益 China Organizational Name Administration Center + "xn--55qx5d", // 公司 Computer Network Information Center of Chinese Academy of Sciences (China Internet Network Information Center) + "xn--5su34j936bgsg", // 香格里拉 Shangri‐La International Hotel Management Limited + "xn--5tzm5g", // 网站 Global Website TLD Asia Limited + "xn--6frz82g", // 移动 Afilias Limited + "xn--6qq986b3xl", // 我爱你 Tycoon Treasure Limited + "xn--80adxhks", // москва Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) + "xn--80aqecdr1a", // католик Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) + "xn--80asehdb", // онлайн CORE Association + "xn--80aswg", // сайт CORE Association + "xn--8y0a063a", // 联通 China United Network Communications Corporation Limited + "xn--90ae", // бг Imena.BG Plc (NAMES.BG Plc) + "xn--9dbq2a", // קום VeriSign Sarl + "xn--9et52u", // 时尚 RISE VICTORY LIMITED + "xn--9krt00a", // 微博 Sina Corporation + "xn--b4w605ferd", // 淡马锡 Temasek Holdings (Private) Limited + "xn--bck1b9a5dre4c", // ファッション Amazon Registry Services, Inc. + "xn--c1avg", // орг Public Interest Registry + "xn--c2br7g", // नेट VeriSign Sarl + "xn--cck2b3b", // ストア 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--fct429k", // 家電 Amazon Registry Services, Inc. + "xn--fhbei", // كوم VeriSign Sarl + "xn--fiq228c5hs", // 中文网 TLD REGISTRY LIMITED + "xn--fiq64b", // 中信 CITIC Group Corporation + "xn--fjq720a", // 娱乐 Will Bloom, LLC + "xn--flw351e", // 谷歌 Charleston Road Registry Inc. + "xn--fzys8d69uvgm", // 電訊盈科 PCCW Enterprises Limited + "xn--g2xx48c", // 购物 Minds + Machines Group Limited + "xn--gckr3f0f", // クラウド Amazon Registry Services, Inc. + "xn--gk3at1e", // 通販 Amazon Registry Services, Inc. + "xn--hxt814e", // 网店 Zodiac Libra Limited + "xn--i1b6b1a6a2e", // संगठन Public Interest Registry + "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--jvr189m", // 食品 Amazon Registry Services, Inc. + "xn--kcrx77d1x4a", // 飞利浦 Koninklijke Philips N.V. + "xn--kpu716f", // 手表 Richemont DNS Inc. + "xn--kput3i", // 手机 Beijing RITT-Net Technology Development Co., Ltd + "xn--mgba3a3ejt", // ارامكو Aramco Services Company + "xn--mgba7c0bbn0a", // العليان Crescent Holding GmbH + "xn--mgbab2bd", // بازار CORE Association + "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--nqv7f", // 机构 Public Interest Registry + "xn--nqv7fs00ema", // 组织机构 Public Interest Registry + "xn--nyqy26a", // 健康 Stable Tone Limited + "xn--p1acf", // рус Rusnames Limited + "xn--pbt977c", // 珠宝 Richemont DNS Inc. + "xn--pssy2u", // 大拿 VeriSign Sarl + "xn--q9jyb4c", // みんな Charleston Road Registry Inc. + "xn--qcka1pmc", // グーグル Charleston Road Registry Inc. + "xn--rhqv96g", // 世界 Stable Tone Limited + "xn--rovu88b", // 書籍 Amazon EU S.à r.l. + "xn--ses554g", // 网址 KNET Co., Ltd + "xn--t60b56a", // 닷넷 VeriSign Sarl + "xn--tckwe", // コム VeriSign Sarl + "xn--tiq49xqyj", // 天主教 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) + "xn--unup4y", // 游戏 Spring Fields, LLC + "xn--vermgensberater-ctb", // VERMöGENSBERATER Deutsche Vermögensberatung Aktiengesellschaft DVAG + "xn--vermgensberatung-pwb", // VERMöGENSBERATUNG Deutsche Vermögensberatung Aktiengesellschaft DVAG + "xn--vhquv", // 企业 Dash McCook, LLC + "xn--vuq861b", // 信息 Beijing Tele-info Network Technology Co., Ltd. + "xn--w4r85el8fhu5dnra", // 嘉里大酒店 Kerry Trading Co. Limited + "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 + "xxx", // xxx ICM Registry LLC + "xyz", // xyz XYZ.COM LLC + "yachts", // yachts DERYachts, LLC + "yahoo", // yahoo Yahoo! Domain Services Inc. + "yamaxun", // yamaxun Amazon Registry Services, Inc. + "yandex", // yandex YANDEX, LLC + "yodobashi", // yodobashi YODOBASHI CAMERA CO.,LTD. + "yoga", // yoga Top Level Domain Holdings Limited + "yokohama", // yokohama GMO Registry, Inc. + "you", // you Amazon Registry Services, Inc. + "youtube", // youtube Charleston Road Registry Inc. + "yun", // yun QIHOO 360 TECHNOLOGY CO. LTD. + "zappos", // zappos Amazon Registry Services, Inc. + "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 + "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[] { + "ac", // Ascension Island + "ad", // Andorra + "ae", // United Arab Emirates + "af", // Afghanistan + "ag", // Antigua and Barbuda + "ai", // Anguilla + "al", // Albania + "am", // Armenia +// "an", // Netherlands Antilles (retired) + "ao", // Angola + "aq", // Antarctica + "ar", // Argentina + "as", // American Samoa + "at", // Austria + "au", // Australia (includes Ashmore and Cartier Islands and Coral Sea Islands) + "aw", // Aruba + "ax", // Åland + "az", // Azerbaijan + "ba", // Bosnia and Herzegovina + "bb", // Barbados + "bd", // Bangladesh + "be", // Belgium + "bf", // Burkina Faso + "bg", // Bulgaria + "bh", // Bahrain + "bi", // Burundi + "bj", // Benin + "bm", // Bermuda + "bn", // Brunei Darussalam + "bo", // Bolivia + "br", // Brazil + "bs", // Bahamas + "bt", // Bhutan + "bv", // Bouvet Island + "bw", // Botswana + "by", // Belarus + "bz", // Belize + "ca", // Canada + "cc", // Cocos (Keeling) Islands + "cd", // Democratic Republic of the Congo (formerly Zaire) + "cf", // Central African Republic + "cg", // Republic of the Congo + "ch", // Switzerland + "ci", // Côte d'Ivoire + "ck", // Cook Islands + "cl", // Chile + "cm", // Cameroon + "cn", // China, mainland + "co", // Colombia + "cr", // Costa Rica + "cu", // Cuba + "cv", // Cape Verde + "cw", // Curaçao + "cx", // Christmas Island + "cy", // Cyprus + "cz", // Czech Republic + "de", // Germany + "dj", // Djibouti + "dk", // Denmark + "dm", // Dominica + "do", // Dominican Republic + "dz", // Algeria + "ec", // Ecuador + "ee", // Estonia + "eg", // Egypt + "er", // Eritrea + "es", // Spain + "et", // Ethiopia + "eu", // European Union + "fi", // Finland + "fj", // Fiji + "fk", // Falkland Islands + "fm", // Federated States of Micronesia + "fo", // Faroe Islands + "fr", // France + "ga", // Gabon + "gb", // Great Britain (United Kingdom) + "gd", // Grenada + "ge", // Georgia + "gf", // French Guiana + "gg", // Guernsey + "gh", // Ghana + "gi", // Gibraltar + "gl", // Greenland + "gm", // The Gambia + "gn", // Guinea + "gp", // Guadeloupe + "gq", // Equatorial Guinea + "gr", // Greece + "gs", // South Georgia and the South Sandwich Islands + "gt", // Guatemala + "gu", // Guam + "gw", // Guinea-Bissau + "gy", // Guyana + "hk", // Hong Kong + "hm", // Heard Island and McDonald Islands + "hn", // Honduras + "hr", // Croatia (Hrvatska) + "ht", // Haiti + "hu", // Hungary + "id", // Indonesia + "ie", // Ireland (Éire) + "il", // Israel + "im", // Isle of Man + "in", // India + "io", // British Indian Ocean Territory + "iq", // Iraq + "ir", // Iran + "is", // Iceland + "it", // Italy + "je", // Jersey + "jm", // Jamaica + "jo", // Jordan + "jp", // Japan + "ke", // Kenya + "kg", // Kyrgyzstan + "kh", // Cambodia (Khmer) + "ki", // Kiribati + "km", // Comoros + "kn", // Saint Kitts and Nevis + "kp", // North Korea + "kr", // South Korea + "kw", // Kuwait + "ky", // Cayman Islands + "kz", // Kazakhstan + "la", // Laos (currently being marketed as the official domain for Los Angeles) + "lb", // Lebanon + "lc", // Saint Lucia + "li", // Liechtenstein + "lk", // Sri Lanka + "lr", // Liberia + "ls", // Lesotho + "lt", // Lithuania + "lu", // Luxembourg + "lv", // Latvia + "ly", // Libya + "ma", // Morocco + "mc", // Monaco + "md", // Moldova + "me", // Montenegro + "mg", // Madagascar + "mh", // Marshall Islands + "mk", // Republic of Macedonia + "ml", // Mali + "mm", // Myanmar + "mn", // Mongolia + "mo", // Macau + "mp", // Northern Mariana Islands + "mq", // Martinique + "mr", // Mauritania + "ms", // Montserrat + "mt", // Malta + "mu", // Mauritius + "mv", // Maldives + "mw", // Malawi + "mx", // Mexico + "my", // Malaysia + "mz", // Mozambique + "na", // Namibia + "nc", // New Caledonia + "ne", // Niger + "nf", // Norfolk Island + "ng", // Nigeria + "ni", // Nicaragua + "nl", // Netherlands + "no", // Norway + "np", // Nepal + "nr", // Nauru + "nu", // Niue + "nz", // New Zealand + "om", // Oman + "pa", // Panama + "pe", // Peru + "pf", // French Polynesia With Clipperton Island + "pg", // Papua New Guinea + "ph", // Philippines + "pk", // Pakistan + "pl", // Poland + "pm", // Saint-Pierre and Miquelon + "pn", // Pitcairn Islands + "pr", // Puerto Rico + "ps", // Palestinian territories (PA-controlled West Bank and Gaza Strip) + "pt", // Portugal + "pw", // Palau + "py", // Paraguay + "qa", // Qatar + "re", // Réunion + "ro", // Romania + "rs", // Serbia + "ru", // Russia + "rw", // Rwanda + "sa", // Saudi Arabia + "sb", // Solomon Islands + "sc", // Seychelles + "sd", // Sudan + "se", // Sweden + "sg", // Singapore + "sh", // Saint Helena + "si", // Slovenia + "sj", // Svalbard and Jan Mayen Islands Not in use (Norwegian dependencies; see .no) + "sk", // Slovakia + "sl", // Sierra Leone + "sm", // San Marino + "sn", // Senegal + "so", // Somalia + "sr", // Suriname + "st", // São Tomé and Príncipe + "su", // Soviet Union (deprecated) + "sv", // El Salvador + "sx", // Sint Maarten + "sy", // Syria + "sz", // Swaziland + "tc", // Turks and Caicos Islands + "td", // Chad + "tf", // French Southern and Antarctic Lands + "tg", // Togo + "th", // Thailand + "tj", // Tajikistan + "tk", // Tokelau + "tl", // East Timor (deprecated old code) + "tm", // Turkmenistan + "tn", // Tunisia + "to", // Tonga +// "tp", // East Timor (Retired) + "tr", // Turkey + "tt", // Trinidad and Tobago + "tv", // Tuvalu + "tw", // Taiwan, Republic of China + "tz", // Tanzania + "ua", // Ukraine + "ug", // Uganda + "uk", // United Kingdom + "us", // United States of America + "uy", // Uruguay + "uz", // Uzbekistan + "va", // Vatican City State + "vc", // Saint Vincent and the Grenadines + "ve", // Venezuela + "vg", // British Virgin Islands + "vi", // U.S. Virgin Islands + "vn", // Vietnam + "vu", // Vanuatu + "wf", // Wallis and Futuna + "ws", // Samoa (formerly Western Samoa) + "xn--3e0b707e", // 한국 KISA (Korea Internet & Security Agency) + "xn--45brj9c", // ভারত National Internet Exchange of India + "xn--54b7fta0cc", // বাংলা Posts and Telecommunications Division + "xn--80ao21a", // қаз Association of IT Companies of Kazakhstan + "xn--90a3ac", // срб Serbian National Internet Domain Registry (RNIDS) + "xn--90ais", // ??? Reliable Software Inc. + "xn--clchc0ea0b2g2a9gcd", // சிங்கப்பூர் Singapore Network Information Centre (SGNIC) Pte Ltd + "xn--d1alf", // мкд Macedonian Academic Research Network Skopje + "xn--e1a4c", // ею EURid vzw/asbl + "xn--fiqs8s", // 中国 China Internet Network Information Center + "xn--fiqz9s", // 中國 China Internet Network Information Center + "xn--fpcrj9c3d", // భారత్ National Internet Exchange of India + "xn--fzc2c9e2c", // ලංකා LK Domain Registry + "xn--gecrj9c", // ભારત National Internet Exchange of India + "xn--h2brj9c", // भारत 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) + "xn--kpry57d", // 台灣 Taiwan Network Information Center (TWNIC) + "xn--l1acc", // мон Datacom Co.,Ltd + "xn--lgbbat1ad8j", // الجزائر CERIST + "xn--mgb9awbf", // عمان Telecommunications Regulatory Authority (TRA) + "xn--mgba3a4f16a", // ایران Institute for Research in Fundamental Sciences (IPM) + "xn--mgbaam7a8h", // امارات Telecommunications Regulatory Authority (TRA) + "xn--mgbayh7gpa", // الاردن National Information Technology Center (NITC) + "xn--mgbbh1a71e", // بھارت National Internet Exchange of India + "xn--mgbc0a9azcg", // المغرب Agence Nationale de Réglementation des Télécommunications (ANRT) + "xn--mgberp4a5d4ar", // السعودية Communications and Information Technology Commission + "xn--mgbpl2fh", // ????? Sudan Internet Society + "xn--mgbtx2b", // عراق Communications and Media Commission (CMC) + "xn--mgbx4cd0ab", // مليسيا MYNIC Berhad + "xn--mix891f", // 澳門 Bureau of Telecommunications Regulation (DSRT) + "xn--node", // გე Information Technologies Development Center (ITDC) + "xn--o3cw4h", // ไทย Thai Network Information Center Foundation + "xn--ogbpf8fl", // سورية National Agency for Network Services (NANS) + "xn--p1ai", // рф Coordination Center for TLD RU + "xn--pgbs0dh", // تونس Agence Tunisienne d'Internet + "xn--qxam", // ελ ICS-FORTH GR + "xn--s9brj9c", // ਭਾਰਤ National Internet Exchange of India + "xn--wgbh1c", // مصر National Telecommunication Regulatory Authority - NTRA + "xn--wgbl6a", // قطر Communications Regulatory Authority + "xn--xkc2al3hye2a", // இலங்கை LK Domain Registry + "xn--xkc2dl3a5ee0h", // இந்தியா National Internet Exchange of India + "xn--y9a3aq", // ??? Internet Society + "xn--yfro4i67o", // 新加坡 Singapore Network Information Centre (SGNIC) Pte Ltd + "xn--ygbi2ammx", // فلسطين Ministry of Telecom & Information Technology (MTIT) + "ye", // Yemen + "yt", // Mayotte + "za", // South Africa + "zm", // Zambia + "zw", // Zimbabwe + }; + + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static final String[] LOCAL_TLDS = new String[] { + "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. + */ + private static boolean inUse = false; + + /* + * 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. + */ + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static volatile 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; + + // WARNING: this array MUST be sorted, otherwise it cannot be searched reliably using binary search + private static volatile String[] countryCodeTLDsMinus = 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; + + /** + * 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 + */ + 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 + ; + }; + + // 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; + } + /** + * 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"})} + *

+ * To clear an override array, provide an empty array. + * + * @param table the table to update, see {@link DomainValidator.ArrayType} + * Must be one of the following + *

    + *
  • COUNTRY_CODE_MINUS
  • + *
  • COUNTRY_CODE_PLUS
  • + *
  • GENERIC_MINUS
  • + *
  • GENERIC_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) { + if (inUse) { + throw new IllegalStateException("Can only invoke this method before calling getInstance"); + } + 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) { + case COUNTRY_CODE_MINUS: + countryCodeTLDsMinus = copy; + break; + case COUNTRY_CODE_PLUS: + countryCodeTLDsPlus = copy; + break; + case GENERIC_MINUS: + genericTLDsMinus = copy; + break; + case GENERIC_PLUS: + genericTLDsPlus = 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); + } + } + + /** + * Get a copy of the 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 String [] getTLDEntries(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 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 + } + + /** + * 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(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; + } + } + + private static class IDNBUGHOLDER { + private static boolean keepsTrailingDot() { + final String input = "a."; // must be a valid name + return input.equals(IDN.toASCII(input)); + } + private static final boolean IDN_TOASCII_PRESERVES_TRAILING_DOTS = keepsTrailingDot(); + } + + /* + * Check if input contains only ASCII + * Treats null as all ASCII + */ + private static boolean isOnlyASCII(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; + } + + /** + * 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 + */ + private static boolean arrayContains(String[] sortedArray, String key) { + return Arrays.binarySearch(sortedArray, key) >= 0; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/DoubleValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,252 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Double Validation and Conversion routines (java.lang.Double).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Double using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Double value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class DoubleValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = 5867946581318211330L; + + private static final DoubleValidator VALIDATOR = new DoubleValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the DoubleValidator. + */ + public static DoubleValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public DoubleValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + 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 + * specified range. + */ + public boolean isInRange(double value, double min, double max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Double value, double min, double max) { + return isInRange(value.doubleValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(double value, double min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Double value, double min) { + return minValue(value.doubleValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(double value, double max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Double value, double max) { + return maxValue(value.doubleValue(), max); + } + + /** + * Convert the parsed value to a Double. + * + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The validated/converted Double value if valid + * or null if invalid. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + + if (value instanceof Double) { + return value; + } + return new Double(((Number)value).doubleValue()); + + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/EmailValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -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. + */ +package org.apache.commons.validator.routines; + +import java.io.Serializable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *

Perform email validations.

+ *

+ * Based on a script by Sandeep V. Tamhankar + * http://javascript.internet.com + *

+ *

+ * This implementation is not guaranteed to catch all possible errors in an email address. + *

. + * + * @version $Revision: 1723573 $ + * @since Validator 1.4 + */ +public class EmailValidator implements Serializable { + + private static final long serialVersionUID = 1705927040799295880L; + + private static final String SPECIAL_CHARS = "\\p{Cntrl}\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]"; + private static final String VALID_CHARS = "(\\\\.)|[^\\s" + SPECIAL_CHARS + "]"; + 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 IP_DOMAIN_REGEX = "^\\[(.*)\\]$"; + private static final String USER_REGEX = "^\\s*" + 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. + */ + private static final EmailValidator EMAIL_VALIDATOR = new EmailValidator(false, false); + + /** + * Singleton instance of this class, which + * doesn't consider local addresses as valid. + */ + private static final EmailValidator EMAIL_VALIDATOR_WITH_TLD = new EmailValidator(false, true); + + /** + * Singleton instance of this class, which does + * consider local addresses valid. + */ + private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL = new EmailValidator(true, false); + + + /** + * Singleton instance of this class, which does + * consider local addresses valid. + */ + private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL_WITH_TLD = new EmailValidator(true, true); + + /** + * Returns the Singleton instance of this validator. + * + * @return singleton instance of this validator. + */ + public static EmailValidator getInstance() { + return EMAIL_VALIDATOR; + } + + /** + * 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) { + 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; + } + } + } + + /** + * Returns the Singleton instance of this validator, + * with local validation as required. + * + * @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 constructor for subclasses to use. + * + * @param allowLocal Should local addresses be considered valid? + * @param allowTld Should TLDs be allowed? + */ + protected EmailValidator(boolean allowLocal, boolean allowTld) { + super(); + this.allowLocal = allowLocal; + this.allowTld = allowTld; + } + + /** + * Protected constructor for subclasses to use. + * + * @param allowLocal Should local addresses be considered valid? + */ + protected EmailValidator(boolean allowLocal) { + super(); + this.allowLocal = allowLocal; + this.allowTld = false; + } + + /** + *

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

+ * + * @param email The value validation is being performed on. A null + * value is considered invalid. + * @return true if the email address is valid. + */ + public boolean isValid(String email) { + if (email == null) { + return false; + } + + if (email.endsWith(".")) { // check this first - it's cheap! + return false; + } + + // Check the whole email address structure + Matcher emailMatcher = EMAIL_PATTERN.matcher(email); + if (!emailMatcher.matches()) { + return false; + } + + if (!isValidUser(emailMatcher.group(1))) { + return false; + } + + if (!isValidDomain(emailMatcher.group(2))) { + return false; + } + + return true; + } + + /** + * Returns true if the domain component of an email address is valid. + * + * @param domain being validated, may be in IDN format + * @return true if the email address's domain is valid. + */ + protected boolean isValidDomain(String domain) { + // see if domain is an IP address in brackets + Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); + + if (ipDomainMatcher.matches()) { + 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); + } + } + + /** + * 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) { + + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/FloatValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/FloatValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,270 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Float Validation and Conversion routines (java.lang.Float).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Float using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Float value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class FloatValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = -4513245432806414267L; + + private static final FloatValidator VALIDATOR = new FloatValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the FloatValidator. + */ + public static FloatValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public FloatValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + 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 + * specified range. + */ + public boolean isInRange(float value, float min, float max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Float value, float min, float max) { + return isInRange(value.floatValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(float value, float min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Float value, float min) { + return minValue(value.floatValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(float value, float max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Float value, float max) { + return maxValue(value.floatValue(), max); + } + + /** + *

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

+ * + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * Float if valid or null if invalid. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + + double doubleValue = ((Number)value).doubleValue(); + + if (doubleValue > 0) { + if (doubleValue < Float.MIN_VALUE) { + return null; + } + if (doubleValue > Float.MAX_VALUE) { + return null; + } + } else if (doubleValue < 0){ + double posDouble = doubleValue * -1; + if (posDouble < Float.MIN_VALUE) { + return null; + } + if (posDouble > Float.MAX_VALUE) { + return null; + } + } + + return new Float((float)doubleValue); + + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IBANValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,293 @@ +/* + * 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.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.validator.routines.RegexValidator; +import org.apache.commons.validator.routines.checkdigit.IBANCheckDigit; + +/** + * IBAN Validator. + * @since 1.5.0 + */ +public class IBANValidator { + + private final Map formatValidators; + + /** + * The validation class + */ + public static class Validator { + /* + * The minimum length does not appear to be defined by the standard. + * Norway is currently the shortest at 15. + * + * There is no standard for BBANs; they vary between countries. + * But a BBAN must consist of a branch id and account number. + * Each of these must be at least 2 chars (generally more) so an absolute minimum is + * 4 characters for the BBAN and 8 for the IBAN. + */ + 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 + + /** + * 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 + */ + public Validator(String cc, int len, String format) { + if (!(cc.length() == 2 && Character.isUpperCase(cc.charAt(0)) && Character.isUpperCase(cc.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 (!format.startsWith(cc)) { + throw new IllegalArgumentException("countryCode '"+cc+"' does not agree with format: " + format); + } + this.countryCode = cc; + this.lengthOfIBAN = len; + this.validator = new RegexValidator(format); + } + } + + /* + * Wikipedia [1] says that only uppercase is allowed. + * The SWIFT PDF file [2] implies that lower case is allowed. + * However there are no examples using lower-case. + * Unfortunately the relevant ISO documents (ISO 13616-1) are not available for free. + * The IBANCheckDigit code treats upper and lower case the same, + * so any case validation has to be done in this class. + * + * Note: the European Payments council has a document [3] which includes a description + * of the IBAN. Section 5 clearly states that only upper case is allowed. + * Also the maximum length is 34 characters (including the country code), + * and the length is fixed for each country. + * + * It looks like lower-case is permitted in BBANs, but they must be converted to + * 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 + * [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 + */ + public static IBANValidator getInstance() { + return DEFAULT_IBAN_VALIDATOR; + } + + /** + * Create a default IBAN validator. + */ + public IBANValidator() { + this(DEFAULT_FORMATS); + } + + /** + * Create an IBAN validator from the specified map of IBAN formats. + * + * @param formatMap map of IBAN formats + */ + public IBANValidator(Validator[] formatMap) { + this.formatValidators = createValidators(formatMap); + } + + private Map createValidators(Validator[] formatMap) { + Map m = new ConcurrentHashMap(); + for(Validator v : formatMap) { + m.put(v.countryCode, v); + } + return m; + } + + /** + * Validate an IBAN Code + * + * @param code The value validation is being performed on + * @return true if the value is valid + */ + public boolean isValid(String code) { + Validator formatValidator = getValidator(code); + if (formatValidator == null || code.length() != formatValidator.lengthOfIBAN || !formatValidator.validator.isValid(code)) { + return false; + } + return IBANCheckDigit.IBAN_CHECK_DIGIT.isValid(code); + } + + /** + * Does the class have the required validator? + * + * @param code the code to check + * @return true if there is a validator + */ + public boolean hasValidator(String code) { + return getValidator(code) != null; + } + + /** + * Gets a copy of the default Validators. + * + * @return a copy of the default Validator array + */ + 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; + } + String key = code.substring(0, 2); + return formatValidators.get(key); + } + + /** + * Installs a validator. + * 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 IllegalStateException if an attempt is made to modify the singleton validator + */ + public Validator setValidator(Validator validator) { + if (this == DEFAULT_IBAN_VALIDATOR) { + throw new IllegalStateException("The singleton validator cannot be modified"); + } + return formatValidators.put(validator.countryCode, validator); + } + + /** + * 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) + * @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) { + 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)); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISBNValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,260 @@ +/* + * 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 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. + *

+ * This validator validates the code is either a valid ISBN-10 + * (using a {@link CodeValidator} with the {@link ISBN10CheckDigit}) + * or a valid ISBN-13 code (using a {@link CodeValidator} with the + * the {@link EAN13CheckDigit} routine). + *

+ * The validate() methods return the ISBN code with formatting + * 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. + *

+ * 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 + * EAN + * codes, for more information see:

+ * + * + * + * @version $Revision: 1715435 $ + * @since Validator 1.4 + */ +public class ISBNValidator implements Serializable { + + private static final int ISBN_10_LEN = 10; + + private static final long serialVersionUID = 4319515687976420405L; + + private static final String SEP = "(?:\\-|\\s)"; + private static final String GROUP = "(\\d{1,5})"; + private static final String PUBLISHER = "(\\d{1,7})"; + private static final String TITLE = "(\\d{1,6})"; + + /** + * ISBN-10 consists of 4 groups of numbers separated by either dashes (-) + * 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])))$"; + + /** + * 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])))$"; + + /** 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. + * + * @return A singleton instance of the ISBN validator. + */ + public static ISBNValidator getInstance() { + return ISBN_VALIDATOR; + } + + /** + * 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 + * 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); + } + + /** + * Construct an ISBN validator which converts ISBN-10 codes + * to ISBN-13. + */ + public ISBNValidator() { + this(true); + } + + /** + * Construct 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 + * if valid ISBN-10 codes should be returned unchanged. + */ + public ISBNValidator(boolean convert) { + this.convert = convert; + } + + /** + * 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. + */ + public boolean isValid(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. + */ + public boolean isValidISBN10(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. + */ + public boolean isValidISBN13(String code) { + return isbn13Validator.isValid(code); + } + + /** + * Check the code is either a valid ISBN-10 or ISBN-13 code. + *

+ * If valid, this method returns the ISBN code with + * formatting characters removed (i.e. space or hyphen). + *

+ * Converts an ISBN-10 codes to ISBN-13 if + * convertToISBN13 is true. + * + * @param code The code to validate. + * @return A valid ISBN code if valid, otherwise null. + */ + public String validate(String code) { + String result = validateISBN13(code); + if (result == null) { + result = validateISBN10(code); + if (result != null && convert) { + result = convertToISBN13(result); + } + } + return result; + } + + /** + * Check the code is a valid ISBN-10 code. + *

+ * If valid, this method returns the ISBN-10 code with + * formatting characters removed (i.e. space or hyphen). + * + * @param code The code to validate. + * @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()); + } + + /** + * Check the code is a valid ISBN-13 code. + *

+ * If valid, this method returns the ISBN-13 code with + * formatting characters removed (i.e. space or hyphen). + * + * @param code The code to validate. + * @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()); + } + + /** + * 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/ISSNValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISSNValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ISSNValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,143 @@ +/* + * 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 org.apache.commons.validator.routines.checkdigit.CheckDigitException; +import org.apache.commons.validator.routines.checkdigit.EAN13CheckDigit; +import org.apache.commons.validator.routines.checkdigit.ISSNCheckDigit; + +/** + * 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.
+ * The check digit is modulus 11, where the value 10 is represented by 'X'
+ * For example:
+ * ISSN 0317-8471
+ * ISSN 1050-124X
+ *
+ * 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); 
+ * if (valid != null) {
+ *    some_method(valid.toString());
+ * }
+ * 
+ * @since 1.5.0 + */ +public class ISSNValidator implements Serializable { + + private static final long serialVersionUID = 4319515687976420405L; + + 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); + + /** ISSN Code Validator */ + private static final ISSNValidator ISSN_VALIDATOR = new ISSNValidator(); + + /** + * Return a singleton instance of the ISSN validator + * + * @return A singleton instance of the ISSN validator. + */ + public static ISSNValidator getInstance() { + return ISSN_VALIDATOR; + } + + /** + * 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. + * It may contain a leading 'ISSN ' prefix, + * as the input is passed through the {@link #validate(String)} + * method. + * + * @param issn The ISSN code to convert + * @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) { + + if (suffix == null || !suffix.matches("\\d\\d")) { + throw new IllegalArgumentException("Suffix must be two digits: '" + suffix + "'"); + } + + 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; + try { + String checkDigit = EAN13CheckDigit.EAN13_CHECK_DIGIT.calculate(ean13); + ean13 += checkDigit; + return ean13; + } catch (CheckDigitException e) { // Should not happen + throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage()); + } + + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/InetAddressValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,190 @@ +/* + * 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.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + *

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

+ * + *

This class provides methods to validate a candidate IP address. + * + *

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

+ * + * @version $Revision: 1783032 $ + * @since Validator 1.4 + */ +public class InetAddressValidator implements Serializable { + + private static final int IPV4_MAX_OCTET_VALUE = 255; + + private static final int MAX_UNSIGNED_SHORT = 0xffff; + + private static final int BASE_16 = 16; + + private static final long serialVersionUID = -919201640201914789L; + + private static final String IPV4_REGEX = + "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"; + + // Max number of hex groups (separated by :) in an IPV6 address + private static final int IPV6_MAX_HEX_GROUPS = 8; + + // Max hex digits in each IPv6 group + private static final int IPV6_MAX_HEX_DIGITS_PER_GROUP = 4; + + /** + * Singleton instance of this class. + */ + private static final InetAddressValidator VALIDATOR = new InetAddressValidator(); + + /** IPv4 RegexValidator */ + private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX); + + /** + * Returns the singleton instance of this validator. + * @return the singleton instance of this validator + */ + public static InetAddressValidator getInstance() { + return VALIDATOR; + } + + /** + * Checks if the specified string is a valid IP address. + * @param inetAddress the string to validate + * @return true if the string validates as an IP address + */ + public boolean isValid(String inetAddress) { + return isValidInet4Address(inetAddress) || isValidInet6Address(inetAddress); + } + + /** + * Validates an IPv4 address. Returns true if valid. + * @param inet4Address the IPv4 address to validate + * @return true if the argument contains a valid IPv4 address + */ + public boolean isValidInet4Address(String inet4Address) { + // verify that address conforms to generic IPv4 format + 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) { + return false; + } + + int iIpSegment = 0; + + try { + iIpSegment = Integer.parseInt(ipSegment); + } catch(NumberFormatException e) { + return false; + } + + if (iIpSegment > IPV4_MAX_OCTET_VALUE) { + return false; + } + + if (ipSegment.length() > 1 && ipSegment.startsWith("0")) { + return false; + } + + } + + return true; + } + + /** + * 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("::"))) { + 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)); + 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()]); + } + 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) { + emptyOctets++; + if (emptyOctets > 1) { + return false; + } + } else { + emptyOctets = 0; + // Is last chunk an IPv4 address? + if (index == octets.length - 1 && octet.contains(".")) { + if (!isValidInet4Address(octet)) { + return false; + } + validOctets += 2; + continue; + } + if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) { + return false; + } + int octetInt = 0; + try { + octetInt = Integer.parseInt(octet, BASE_16); + } catch (NumberFormatException e) { + return false; + } + if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) { + return false; + } + } + validOctets++; + } + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IntegerValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/IntegerValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,255 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Integer Validation and Conversion routines (java.lang.Integer).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Integer using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Integer value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1782756 $ + * @since Validator 1.3.0 + */ +public class IntegerValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = 422081746310306596L; + + private static final IntegerValidator VALIDATOR = new IntegerValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the IntegerValidator. + */ + public static IntegerValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public IntegerValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + super(strict, formatType, false); + } + + /** + *

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

Validate/convert an Integer 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 Integer if valid or null if invalid. + */ + public Integer validate(String value, String pattern) { + return (Integer)parse(value, pattern, (Locale)null); + } + + /** + *

Validate/convert an Integer 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 Integer if valid or null if invalid. + */ + public Integer validate(String value, Locale locale) { + return (Integer)parse(value, (String)null, locale); + } + + /** + *

Validate/convert a Integer 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 Integer if valid or null if invalid. + */ + public Integer validate(String value, String pattern, Locale locale) { + return (Integer)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 + * specified range. + */ + public boolean isInRange(int value, int min, int max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Integer value, int min, int max) { + return isInRange(value.intValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(int value, int min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Integer value, int min) { + return minValue(value.intValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(int value, int max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Integer value, int max) { + return maxValue(value.intValue(), max); + } + + /** + *

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

+ * + * @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. + */ + @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); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/LongValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,251 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Long Validation and Conversion routines (java.lang.Long).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Long using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Long value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using a specified pattern
  • + *
  • using the format for a specified Locale
  • + *
  • using the format for the default Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class LongValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = -5117231731027866098L; + + private static final LongValidator VALIDATOR = new LongValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the LongValidator. + */ + public static LongValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public LongValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + 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 + * specified range. + */ + public boolean isInRange(long value, long min, long max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Long value, long min, long max) { + return isInRange(value.longValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(long value, long min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Long value, long min) { + return minValue(value.longValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(long value, long max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Long value, long max) { + return maxValue(value.longValue(), max); + } + + /** + * Convert the parsed value to a Long. + * + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * Long. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + + if (value instanceof Long) { + return value; + } + return Long.valueOf(((Number)value).longValue()); + + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/PercentValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,127 @@ +/* + * 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.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 converts the percent to a java.math.BigDecimal
  • + *
+ * + *

However any of the number validators can be used for percent validation. + * For example, if you wanted a percent validator that converts to a + * java.lang.Float then you can simply instantiate an + * FloatValidator with the appropriate format type:

+ * + *

... = new FloatValidator(false, FloatValidator.PERCENT_FORMAT);

+ * + *

Pick the appropriate validator, depending on the type (i.e Float, Double or BigDecimal) + * you want the percent converted to. Please note, it makes no sense to use + * one of the validators that doesn't handle fractions (i.e. byte, short, integer, long + * and BigInteger) since percentages are converted to fractions (i.e 50% is + * converted to 0.5).

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class PercentValidator extends BigDecimalValidator { + + private static final long serialVersionUID = -3508241924961535772L; + + private static final PercentValidator VALIDATOR = new PercentValidator(); + + /** DecimalFormat's percent (thousand multiplier) symbol */ + private static final char PERCENT_SYMBOL = '%'; + + private static final BigDecimal POINT_ZERO_ONE = new BigDecimal("0.01"); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the PercentValidator. + */ + public static BigDecimalValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public PercentValidator() { + this(true); + } + + /** + * Construct an instance with the specified strict setting. + * + * @param strict true if strict + * Format parsing should be used. + */ + public PercentValidator(boolean strict) { + super(strict, PERCENT_FORMAT, true); + } + + /** + *

Parse the value with the specified Format.

+ * + *

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 + * symbol is missing. This method re-parses with a format + * without the currency symbol if it fails initially.

+ * + * @param value The value to be parsed. + * @param formatter The Format to parse the value with. + * @return The parsed value if valid or null if invalid. + */ + @Override + protected Object parse(String value, Format formatter) { + + // Initial parse of the value + BigDecimal parsedValue = (BigDecimal)super.parse(value, formatter); + if (parsedValue != null || !(formatter instanceof DecimalFormat)) { + return parsedValue; + } + + // Re-parse using a pattern without the percent symbol + DecimalFormat decimalFormat = (DecimalFormat)formatter; + String pattern = decimalFormat.toPattern(); + if (pattern.indexOf(PERCENT_SYMBOL) >= 0) { + 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)); + } + } + decimalFormat.applyPattern(buffer.toString()); + parsedValue = (BigDecimal)super.parse(value, decimalFormat); + + // If parsed OK, divide by 100 to get percent + if (parsedValue != null) { + parsedValue = parsedValue.multiply(POINT_ZERO_ONE); + } + + } + return parsedValue; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/RegexValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,230 @@ +/* + * 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.regex.Pattern; +import java.util.regex.Matcher; + +/** + * Regular Expression validation (using JDK 1.4+ regex support). + *

+ * Construct 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 + * expressions: + *

+ *
+ * 
+ * String[] regexs = new String[] {...};
+ * RegexValidator validator = new RegexValidator(regexs, false);
+ * 
+ * 
+ * + *
    + *
  • Validate true or false:
  • + *
  • + *
      + *
    • boolean valid = validator.isValid(value);
    • + *
    + *
  • + *
  • Validate returning an aggregated String of the matched groups:
  • + *
  • + *
      + *
    • String result = validator.validate(value);
    • + *
    + *
  • + *
  • Validate returning the matched groups:
  • + *
  • + *
      + *
    • String[] result = validator.match(value);
    • + *
    + *
  • + *
+ * + * Note that patterns are matched against the entire input. + * + *

+ * Cached instances pre-compile and re-use {@link Pattern}(s) - which according + * to the {@link Pattern} API are safe to use in a multi-threaded environment. + *

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public class RegexValidator implements Serializable { + + private static final long serialVersionUID = -8832409930574867162L; + + private final Pattern[] patterns; + + /** + * Construct a case sensitive validator for a single + * regular expression. + * + * @param regex The regular expression this validator will + * validate against + */ + public RegexValidator(String regex) { + this(regex, true); + } + + /** + * Construct 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 true matching is case + * sensitive, otherwise matching is case in-sensitive + */ + public RegexValidator(String regex, boolean caseSensitive) { + this(new String[] {regex}, caseSensitive); + } + + /** + * Construct a case sensitive validator that matches any one + * of the set of regular expressions. + * + * @param regexs The set of regular expressions this validator will + * validate against + */ + public RegexValidator(String[] regexs) { + this(regexs, true); + } + + /** + * Construct 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 + * sensitive, otherwise matching is case in-sensitive + */ + public RegexValidator(String[] regexs, 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); + for (int i = 0; i < regexs.length; i++) { + if (regexs[i] == null || regexs[i].length() == 0) { + throw new IllegalArgumentException("Regular expression[" + i + "] is missing"); + } + patterns[i] = Pattern.compile(regexs[i], flags); + } + } + + /** + * Validate a value against the set of regular expressions. + * + * @param value The value to validate. + * @return true if the value is valid + * otherwise false. + */ + public boolean isValid(String value) { + if (value == null) { + return false; + } + for (int i = 0; i < patterns.length; i++) { + if (patterns[i].matcher(value).matches()) { + return true; + } + } + return false; + } + + /** + * Validate 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) { + if (value == null) { + return null; + } + for (int i = 0; i < patterns.length; i++) { + Matcher matcher = patterns[i].matcher(value); + if (matcher.matches()) { + int count = matcher.groupCount(); + String[] groups = new String[count]; + for (int j = 0; j < count; j++) { + groups[j] = matcher.group(j+1); + } + return groups; + } + } + return null; + } + + + /** + * Validate 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) { + if (value == null) { + return null; + } + for (int i = 0; i < patterns.length; i++) { + Matcher matcher = patterns[i].matcher(value); + if (matcher.matches()) { + int count = matcher.groupCount(); + if (count == 1) { + return matcher.group(1); + } + StringBuilder buffer = new StringBuilder(); + for (int j = 0; j < count; j++) { + String component = matcher.group(j+1); + if (component != null) { + buffer.append(component); + } + } + return buffer.toString(); + } + } + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ShortValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/ShortValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,255 @@ +/* + * 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.text.Format; +import java.util.Locale; + +/** + *

Short Validation and Conversion routines (java.lang.Short).

+ * + *

This validator provides a number of methods for + * validating/converting a String value to + * a Short using java.text.NumberFormat + * to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Short value.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform minimum, maximum and range checks:

+ *
    + *
  • minValue() checks whether the value is greater + * than or equal to a specified minimum.
  • + *
  • maxValue() checks whether the value is less + * than or equal to a specified maximum.
  • + *
  • isInRange() checks whether the value is within + * a specified range of values.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class ShortValidator extends AbstractNumberValidator { + + private static final long serialVersionUID = -5227510699747787066L; + + private static final ShortValidator VALIDATOR = new ShortValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the ShortValidator. + */ + public static ShortValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance. + */ + public ShortValidator() { + this(true, STANDARD_FORMAT); + } + + /** + *

Construct an instance with the specified strict setting + * and format type.

+ * + *

The formatType specified what type of + * NumberFormat is created - valid types + * are:

+ *
    + *
  • AbstractNumberValidator.STANDARD_FORMAT -to create + * standard number formats (the default).
  • + *
  • AbstractNumberValidator.CURRENCY_FORMAT -to create + * currency number formats.
  • + *
  • AbstractNumberValidator.PERCENT_FORMAT -to create + * percent number formats (the default).
  • + *
+ * + * @param strict 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) { + 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 + * specified range. + */ + public boolean isInRange(short value, short min, short max) { + return (value >= min && value <= max); + } + + /** + * 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 + * specified range. + */ + public boolean isInRange(Short value, short min, short max) { + return isInRange(value.shortValue(), min, max); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(short value, short min) { + return (value >= min); + } + + /** + * 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 true if the value is greater than + * or equal to the minimum. + */ + public boolean minValue(Short value, short min) { + return minValue(value.shortValue(), min); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(short value, short max) { + return (value <= max); + } + + /** + * 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 + * or equal to the maximum. + */ + public boolean maxValue(Short value, short max) { + return maxValue(value.shortValue(), max); + } + + /** + *

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

+ * + * @param value The parsed Number object created. + * @param formatter The Format used to parse the value with. + * @return The parsed Number converted to a + * Short if valid or null if invalid. + */ + @Override + protected Object processParsedValue(Object value, Format formatter) { + + long longValue = ((Number)value).longValue(); + + if (longValue < Short.MIN_VALUE || + longValue > Short.MAX_VALUE) { + return null; + } + return Short.valueOf((short)longValue); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/TimeValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,285 @@ +/* + * 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.text.DateFormat; +import java.text.Format; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + *

Time Validation and Conversion routines (java.util.Calendar).

+ * + *

This validator provides a number of methods for validating/converting + * a String time value to a java.util.Calendar using + * java.text.DateFormat to parse either:

+ *
    + *
  • using the default format for the default Locale
  • + *
  • using a specified pattern with the default Locale
  • + *
  • using the default format for a specified Locale
  • + *
  • using a specified pattern with a specified Locale
  • + *
+ * + *

For each of the above mechanisms, conversion method (i.e the + * validate methods) implementations are provided which + * either use the default TimeZone or allow the + * TimeZone to be specified.

+ * + *

Use one of the isValid() methods to just validate or + * one of the validate() methods to validate and receive a + * converted Calendar value for the time.

+ * + *

Implementations of the validate() method are provided + * to create Calendar objects for different time zones + * if the system default is not appropriate.

+ * + *

Alternatively the CalendarValidator's adjustToTimeZone() method + * can be used to adjust the TimeZone of the Calendar + * object afterwards.

+ * + *

Once a value has been successfully converted the following + * methods can be used to perform various time comparison checks:

+ *
    + *
  • compareTime() compares the hours, minutes, seconds + * and milliseconds of two calendars, returning 0, -1 or +1 indicating + * whether the first time is equal, before or after the second.
  • + *
  • compareSeconds() compares the hours, minutes and + * seconds of two times, returning 0, -1 or +1 indicating + * whether the first is equal to, before or after the second.
  • + *
  • compareMinutes() compares the hours and minutes + * two times, returning 0, -1 or +1 indicating + * whether the first is equal to, before or after the second.
  • + *
  • compareHours() compares the hours + * of two times, returning 0, -1 or +1 indicating + * whether the first is equal to, before or after the second.
  • + *
+ * + *

So that the same mechanism used for parsing an input value + * for validation can be used to format output, corresponding + * format() methods are also provided. That is you can + * format either:

+ *
    + *
  • using a specified pattern
  • + *
  • using the format for a specified Locale
  • + *
  • using the format for the default Locale
  • + *
+ * + * @version $Revision: 1739356 $ + * @since Validator 1.3.0 + */ +public class TimeValidator extends AbstractCalendarValidator { + + private static final long serialVersionUID = 3494007492269691581L; + + private static final TimeValidator VALIDATOR = new TimeValidator(); + + /** + * Return a singleton instance of this validator. + * @return A singleton instance of the TimeValidator. + */ + public static TimeValidator getInstance() { + return VALIDATOR; + } + + /** + * Construct a strict instance with short + * time style. + */ + public TimeValidator() { + this(true, DateFormat.SHORT); + } + + /** + * Construct an instance with the specified strict + * and time style parameters. + * + * @param strict true if strict + * Format parsing should be used. + * @param timeStyle the time style to use for Locale validation. + */ + public TimeValidator(boolean strict, int timeStyle) { + super(strict, -1, timeStyle); + } + + /** + *

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

Validate/convert a time 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 time, system default if null. + * @return The parsed Calendar if valid or null if invalid. + */ + public Calendar validate(String value, TimeZone timeZone) { + return (Calendar)parse(value, (String)null, (Locale)null, 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(String value, String pattern) { + return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null); + } + + /** + *

Validate/convert a time 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. + * @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, String pattern, TimeZone timeZone) { + return (Calendar)parse(value, pattern, (Locale)null, timeZone); + } + + /** + *

Validate/convert a time using the specified Locale + * default TimeZone. + * + * @param value The value validation is being performed on. + * @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) { + return (Calendar)parse(value, (String)null, locale, (TimeZone)null); + } + + /** + *

Validate/convert a time using the specified 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) { + return (Calendar)parse(value, (String)null, locale, timeZone); + } + + /** + *

Validate/convert a time 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, String pattern, Locale locale) { + return (Calendar)parse(value, pattern, locale, (TimeZone)null); + } + + /** + *

Validate/convert a time using the specified pattern, 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 Calendar if valid or null if invalid. + */ + public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) { + return (Calendar)parse(value, pattern, locale, timeZone); + } + + /** + *

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(Calendar value, Calendar compare) { + return compareTime(value, compare, Calendar.MILLISECOND); + } + + /** + *

Compare Seconds (hours, minutes and seconds).

+ * + * @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 int compareSeconds(Calendar value, Calendar compare) { + return compareTime(value, compare, Calendar.SECOND); + } + + /** + *

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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/UrlValidator.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/UrlValidator.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,544 @@ +/* + * 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.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + *

URL Validation routines.

+ * Behavior of validation is modified by passing in options: + *
    + *
  • ALLOW_2_SLASHES - [FALSE] Allows double '/' characters in the path + * component.
  • + *
  • NO_FRAGMENT- [FALSE] By default fragments are allowed, if this option is + * included then fragments are flagged as illegal.
  • + *
  • ALLOW_ALL_SCHEMES - [FALSE] By default only http, https, and ftp are + * considered valid schemes. Enabling this option will let any scheme pass validation.
  • + *
+ * + *

Originally based in on php script by Debbie Dyer, validation.php v1.2b, Date: 03/07/02, + * http://javascript.internet.com. However, this validation now bears little resemblance + * to the php original.

+ *
+ *   Example of usage:
+ *   Construct a UrlValidator with valid schemes of "http", and "https".
+ *
+ *    String[] schemes = {"http","https"}.
+ *    UrlValidator urlValidator = new UrlValidator(schemes);
+ *    if (urlValidator.isValid("ftp://foo.bar.com/")) {
+ *       System.out.println("url is valid");
+ *    } else {
+ *       System.out.println("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");
+ *    } else {
+ *       System.out.println("url is invalid");
+ *    }
+ *
+ *   prints out "url is valid"
+ *  
+ * + * @see + * + * Uniform Resource Identifiers (URI): Generic Syntax + * + * + * @version $Revision: 1783203 $ + * @since Validator 1.4 + */ +public class UrlValidator implements Serializable { + + private static final long serialVersionUID = 7557161713937335013L; + + private static final int MAX_UNSIGNED_16_BIT_INT = 0xFFFF; // port max + + /** + * Allows all validly formatted schemes to pass validation instead of + * supplying a set of valid schemes. + */ + public static final long ALLOW_ALL_SCHEMES = 1 << 0; + + /** + * Allow two slashes in the path component of the URL. + */ + public static final long ALLOW_2_SLASHES = 1 << 1; + + /** + * Enabling this options disallows any URL fragments. + */ + public static final long NO_FRAGMENTS = 1 << 2; + + /** + * Allow local URLs, such as http://localhost/ or http://machine/ . + * This enables a broad-brush check, for complex local machine name + * validation requirements you should create your validator with + * a {@link RegexValidator} instead ({@link #UrlValidator(RegexValidator, long)}) + */ + 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. + // 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 + + // 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 + private static final Pattern AUTHORITY_PATTERN = Pattern.compile(AUTHORITY_REGEX); + + private static final int PARSE_AUTHORITY_IPV6 = 1; + + private static final int PARSE_AUTHORITY_HOST_IP = 2; // excludes userinfo, if present + + private static final int PARSE_AUTHORITY_PORT = 3; // excludes leading colon + + /** + * Should always be empty. The code currently allows spaces. + */ + private static final int PARSE_AUTHORITY_EXTRA = 4; + + private static final String PATH_REGEX = "^(/[-\\w:@&?=+,.!/~*'%$_;\\(\\)]*)?$"; + private static final Pattern PATH_PATTERN = Pattern.compile(PATH_REGEX); + + private static final String QUERY_REGEX = "^(\\S*)$"; + private static final Pattern QUERY_PATTERN = Pattern.compile(QUERY_REGEX); + + /** + * Holds the set of current validation options. + */ + private final long options; + + /** + * The set of schemes that are allowed to be in a URL. + */ + private final Set allowedSchemes; // Must be lower-case + + /** + * Regular expressions used to manually validate authorities if IANA + * domain name validation isn't desired. + */ + 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 + + /** + * 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; + } + + /** + * Create a UrlValidator with default properties. + */ + public UrlValidator() { + this(null); + } + + /** + * 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 + * 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) { + 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) { + this(schemes, null, options); + } + + /** + * 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(RegexValidator authorityValidator, long options) { + this(null, authorityValidator, options); + } + + /** + * Customizable constructor. Validation behavior is modifed 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. + */ + public UrlValidator(String[] schemes, RegexValidator authorityValidator, long options) { + this.options = options; + + 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)); + } + } + + this.authorityValidator = authorityValidator; + } + + /** + *

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. + */ + public boolean isValid(String value) { + if (value == null) { + return false; + } + + // Check the whole url address structure + Matcher urlMatcher = URL_PATTERN.matcher(value); + if (!urlMatcher.matches()) { + return false; + } + + String scheme = urlMatcher.group(PARSE_URL_SCHEME); + 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; + } + } + + if (!isValidPath(urlMatcher.group(PARSE_URL_PATH))) { + return false; + } + + if (!isValidQuery(urlMatcher.group(PARSE_URL_QUERY))) { + return false; + } + + if (!isValidFragment(urlMatcher.group(PARSE_URL_FRAGMENT))) { + 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) { + return false; + } + + // TODO could be removed if external schemes were checked in the ctor before being stored + if (!SCHEME_PATTERN.matcher(scheme).matches()) { + return false; + } + + if (isOff(ALLOW_ALL_SCHEMES) && !allowedSchemes.contains(scheme.toLowerCase(Locale.ENGLISH))) { + 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. + * Note: this implementation validates the domain unless a RegexValidator was provided. + * If a RegexValidator was supplied and it matches, then the authority is regarded + * as valid with no further checks, otherwise the method checks against the + * AUTHORITY_PATTERN and the DomainValidator (ALLOW_LOCAL_URLS) + * @param authority Authority value to validate, alllows IDN + * @return true if authority (hostname and port) is valid. + */ + protected boolean isValidAuthority(String authority) { + if (authority == null) { + return false; + } + + // check manual authority validation if specified + if (authorityValidator != null && authorityValidator.isValid(authority)) { + return true; + } + // convert to ASCII if possible + final String authorityASCII = DomainValidator.unicodeToASCII(authority); + + 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); + if (ipv6 != null) { + InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); + if (!inetAddressValidator.isValidInet6Address(ipv6)) { + return false; + } + } else { + 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)) { + // try an IPv4 address + 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) { + try { + int iPort = Integer.parseInt(port); + if (iPort < 0 || iPort > MAX_UNSIGNED_16_BIT_INT) { + return false; + } + } catch (NumberFormatException nfe) { + return false; // this can happen for big numbers + } + } + } + + String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA); + if (extra != null && extra.trim().length() > 0){ + return false; + } + + return true; + } + + /** + * 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) { + if (path == null) { + return false; + } + + if (!PATH_PATTERN.matcher(path).matches()) { + return false; + } + + try { + URI uri = new URI(null,null,path,null); + 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) { + return false; + } + + int slash2Count = countToken("//", path); + if (isOff(ALLOW_2_SLASHES) && (slash2Count > 0)) { + return false; + } + + return true; + } + + /** + * Returns true if the query is null or it's a properly formatted query string. + * @param query Query value to validate. + * @return true if query is valid. + */ + protected boolean isValidQuery(String query) { + if (query == null) { + return true; + } + + return QUERY_PATTERN.matcher(query).matches(); + } + + /** + * 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(String fragment) { + if (fragment == null) { + return true; + } + + return isOff(NO_FRAGMENTS); + } + + /** + * 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++; + } + } + 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; + } + + /** + * 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ABANumberCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ABANumberCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,85 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 ABA Number (or Routing Transit Number (RTN)) Check Digit + * calculation/validation. + * + *

+ * ABA Numbers (or Routing Transit Numbers) are a nine digit numeric code used + * to identify American financial institutions for things such as checks or deposits + * (ABA stands for the American Bankers Association). + *

+ * + * Check digit calculation is based on modulus 10 with digits being weighted + * based on their position (from right to left) as follows: + * + *
    + *
  • Digits 1, 4 and & 7 are weighted 1
  • + *
  • Digits 2, 5 and & 8 are weighted 7
  • + *
  • Digits 3, 6 and & 9 are weighted 3
  • + *
+ * + *

+ * For further information see + * Wikipedia - + * Routing transit number. + *

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class ABANumberCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = -8255937433810380145L; + + /** Singleton Routing Transit Number Check Digit instance */ + 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}; + + /** + * Construct a modulus 10 Check Digit routine for ABA Numbers. + */ + public ABANumberCheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + * Calculates the weighted value of a character in the + * code at a specified position. + *

+ * ABA Routing numbers are weighted in the following manner: + *


+     *     left position: 1  2  3  4  5  6  7  8  9
+     *            weight: 3  7  1  3  7  1  3  7  1
+     * 
+ * + * @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) { + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CUSIPCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CUSIPCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,100 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 CUSIP (North American Securities) Check Digit calculation/validation. + * + *

+ * CUSIP Numbers are 9 character alphanumeric codes used + * to identify North American Securities. + *

+ * + *

+ * Check digit calculation uses the Modulus 10 Double Add Double technique + * with every second digit being weighted by 2. Alphabetic characters are + * converted to numbers by their position in the alphabet starting with A being 10. + * Weighted numbers greater than ten are treated as two separate numbers. + *

+ * + *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class CUSIPCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = 666941918490152456L; + + /** Singleton CUSIP Check Digit instance */ + 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}; + + /** + * Construct an CUSIP Indetifier Check Digit routine. + */ + public CUSIPCheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + * Convert a character at a specified position to an integer value. + * + * @param character The character to convert + * @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 + */ + @Override + protected int toInt(char character, int leftPos, int rightPos) + throws CheckDigitException { + 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) { + throw new CheckDigitException("Invalid Character[" + + leftPos + "," + rightPos + "] = '" + charValue + "' out of range 0 to " + charMax); + } + return charValue; + } + + /** + *

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

+ * + *

For CUSIP (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

+ * + * @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) { + int weight = POSITION_WEIGHT[rightPos % 2]; + int weightedValue = (charValue * weight); + return ModulusCheckDigit.sumDigits(weightedValue); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,71 @@ +/* + * 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.checkdigit; + +/** + * Check Digit calculation and validation. + *

+ * The logic for validating check digits has previously been + * embedded within the logic for specific code validation, which + * includes other validations such as verifying the format + * or length of a code. {@link CheckDigit} provides for separating out + * the check digit calculation logic enabling it to be more easily + * tested and reused. + *

+ *

+ * Although Commons Validator is primarily concerned with validation, + * {@link CheckDigit} also defines behaviour 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. + *

+ * + *

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 + */ +public interface CheckDigit { + + /** + * Calculates the Check Digit for a code. + * + * @param code The code to calculate the Check Digit for. + * The string must not include the check digit + * @return The calculated Check Digit + * @throws CheckDigitException if an error occurs. + */ + String calculate(String code) throws CheckDigitException; + + /** + * 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. + */ + boolean isValid(String code); + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/CheckDigitException.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,55 @@ +/* + * 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.checkdigit; + +/** + * Check Digit calculation/validation error. + * + * @version $Revision: 1649191 $ + * @since Validator 1.4 + */ +public class CheckDigitException extends Exception { + + private static final long serialVersionUID = -3519894732624685477L; + + /** + * Construct an Exception with no message. + */ + public CheckDigitException() { + } + + /** + * Construct an Exception with a message. + * + * @param msg The error message. + */ + public CheckDigitException(String msg) { + super(msg); + } + + /** + * Construct 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) { + super(msg, cause); + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/EAN13CheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,78 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 EAN-13 / UPC / ISBN-13 Check Digit + * calculation/validation. + *

+ * Check digit calculation is based on modulus 10 with digits in + * an odd position (from right to left) being weighted 1 and even + * position digits being weighted 3. + *

+ * For further information see: + *

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class EAN13CheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = 1726347093230424107L; + + /** Singleton EAN-13 Check Digit instance */ + 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}; + + /** + * Construct a modulus 10 Check Digit routine for EAN/UPC. + */ + public EAN13CheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + *

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

+ * + *

For EAN-13 (from right to left) odd digits are weighted + * with a factor of one and even digits with a factor + * of three.

+ * + * @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) { + int weight = POSITION_WEIGHT[rightPos % 2]; + return charValue * weight; + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/IBANCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,137 @@ +/* + * 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.checkdigit; + +import java.io.Serializable; + +/** + * IBAN (International Bank Account Number) Check Digit calculation/validation. + *

+ * This routine is based on the ISO 7064 Mod 97,10 check digit calculation routine. + *

+ * The two check digit characters in a IBAN number are the third and fourth characters + * in the code. For check digit calculation/validation the first four characters are moved + * to the end of the code. + * So CCDDnnnnnnn becomes nnnnnnnCCDD (where + * CC is the country code and DD is the check digit). For + * check digit calculation the check digit value should be set to zero (i.e. + * CC00nnnnnnn in this example. + *

+ * Note: the class does not check the format of the IBAN number, only the check digits. + *

+ * For further information see + * Wikipedia - + * IBAN number. + * + * @version $Revision: 1739357 $ + * @since Validator 1.4 + */ +public final class IBANCheckDigit implements CheckDigit, Serializable { + + private static final int MIN_CODE_LEN = 5; + + private static final long serialVersionUID = -3600191725934382801L; + + private static final int MAX_ALPHANUMERIC_VALUE = 35; // Character.getNumericValue('Z') + + /** Singleton IBAN Number Check Digit instance */ + public static final CheckDigit IBAN_CHECK_DIGIT = new IBANCheckDigit(); + + private static final long MAX = 999999999; + + private static final long MODULUS = 97; + + /** + * Construct 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 + * characters and is set to the value "00". + * + * @param code The code to calculate the Check Digit for + * @return The calculated Check Digit as 2 numeric decimal characters, e.g. "42" + * @throws CheckDigitException if an error occurs calculating + * the check digit for the specified code + */ + @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())); + } + 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 + } + + /** + * Calculate the modulus for a code. + * + * @param code The code to calculate the modulus for. + * @return The modulus value + * @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 + long total = 0; + for (int i = 0; i < reformattedCode.length(); i++) { + int charValue = Character.getNumericValue(reformattedCode.charAt(i)); + if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { + 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); + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBN10CheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,115 @@ +/* + * 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.checkdigit; + +/** + * Modulus 11 ISBN-10 Check Digit calculation/validation. + *

+ * ISBN-10 Numbers are a numeric code except for the last (check) digit + * which can have a value of "X". + *

+ * Check digit calculation is based on modulus 11 with digits being weighted + * based by their position, from right to left with the first digit being weighted + * 1, the second 2 and so on. If the check digit is calculated as "10" it is converted + * to "X". + *

+ * N.B. From 1st January 2007 the book industry will start to use a new 13 digit + * ISBN number (rather than this 10 digit ISBN number) which uses the EAN-13 / UPC + * (see {@link EAN13CheckDigit}) standard. + *

+ * For further information see: + *

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class ISBN10CheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = 8000855044504864964L; + + /** Singleton ISBN-10 Check Digit instance */ + public static final CheckDigit ISBN10_CHECK_DIGIT = new ISBN10CheckDigit(); + + /** + * Construct a modulus 11 Check Digit routine for ISBN-10. + */ + public ISBN10CheckDigit() { + super(11); // CHECKSTYLE IGNORE MagicNumber + } + + /** + * Calculates the weighted value of a charcter in the + * code at a specified position. + * + *

For ISBN-10 (from right to left) digits are weighted + * by their 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 * rightPos; + } + + /** + *

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

+ * + *

Character 'X' check digit converted to 10.

+ * + * @param character The character to convert. + * @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 an error occurs. + */ + @Override + protected int toInt(char character, int leftPos, int rightPos) + throws CheckDigitException { + if (rightPos == 1 && character == 'X') { + return 10; // CHECKSTYLE IGNORE MagicNumber + } + return super.toInt(character, leftPos, rightPos); + } + + /** + *

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

+ * + *

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

+ * + * @param charValue The integer value of the character. + * @return The converted character. + * @throws CheckDigitException if an error occurs. + */ + @Override + protected String toCheckDigit(int charValue) + throws CheckDigitException { + if (charValue == 10) { // CHECKSTYLE IGNORE MagicNumber + return "X"; + } + return super.toCheckDigit(charValue); + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISBNCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,106 @@ +/* + * 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.checkdigit; + +import java.io.Serializable; + +/** + * Combined ISBN-10 / ISBN-13 Check Digit calculation/validation. + *

+ * This implementation validates/calculates ISBN check digits + * based on the length of the code passed to it - delegating + * either to the {@link ISBNCheckDigit#ISBN10_CHECK_DIGIT} or the + * {@link ISBNCheckDigit#ISBN13_CHECK_DIGIT} routines to perform the actual + * validation/calculation. + *

+ * N.B. From 1st January 2007 the book industry will start to use a new 13 digit + * ISBN number (rather than this 10 digit ISBN number) which uses the EAN-13 / UPC + * standard. + * + * @version $Revision: 1739357 $ + * @since Validator 1.4 + */ +public final class ISBNCheckDigit implements CheckDigit, Serializable { + + private static final long serialVersionUID = 1391849166205184558L; + + /** Singleton ISBN-10 Check Digit instance */ + public static final CheckDigit ISBN10_CHECK_DIGIT = ISBN10CheckDigit.ISBN10_CHECK_DIGIT; + + /** Singleton ISBN-13 Check Digit instance */ + 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(); + + /** + * Calculate an ISBN-10 or ISBN-13 check digit, depending + * on the length of the code. + *

+ * If the length of the code is 9, it is treated as an ISBN-10 + * code or if the length of the code is 12, it is treated as an ISBN-13 + * code. + * + * @param code The ISBN code to validate (should have a length of + * 9 or 12) + * @return The ISBN-10 check digit if the length is 9 or an ISBN-13 + * check digit if the length is 12. + * @throws CheckDigitException if the code is missing, or an invalid + * length (i.e. not 9 or 12) or if there is an error calculating the + * check digit. + */ + @Override + public String calculate(String code) throws CheckDigitException { + if (code == null || code.length() == 0) { + throw new CheckDigitException("ISBN Code is missing"); + } else if (code.length() == 9) { // CHECKSTYLE IGNORE MagicNumber + return ISBN10_CHECK_DIGIT.calculate(code); + } else if (code.length() == 12) { // CHECKSTYLE IGNORE MagicNumber + return ISBN13_CHECK_DIGIT.calculate(code); + } else { + throw new CheckDigitException("Invalid ISBN Length = " + code.length()); + } + } + + /** + *

Validate an ISBN-10 or ISBN-13 check digit, depending + * on the length of the code.

+ *

+ * If the length of the code is 10, it is treated as an ISBN-10 + * code or ff the length of the code is 13, it is treated as an ISBN-13 + * code. + * + * @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 + * a valid ISBN-10 check digit or the code has a length of 13 and is + * a valid ISBN-13 check digit - otherwise false. + */ + @Override + public boolean isValid(String code) { + if (code == null) { + return false; + } else if (code.length() == 10) { // CHECKSTYLE IGNORE MagicNumber + return ISBN10_CHECK_DIGIT.isValid(code); + } else if (code.length() == 13) { // CHECKSTYLE IGNORE MagicNumber + return ISBN13_CHECK_DIGIT.isValid(code); + } else { + return false; + } + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISINCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,111 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 ISIN (International Securities Identifying Number) Check Digit calculation/validation. + * + *

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

+ * + *

+ * Check digit calculation uses the Modulus 10 Double Add Double technique + * with every second digit being weighted by 2. Alphabetic characters are + * converted to numbers by their position in the alphabet starting with A being 10. + * Weighted numbers greater than ten are treated as two separate numbers. + *

+ * + *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class ISINCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = -1239211208101323599L; + + private static final int MAX_ALPHANUMERIC_VALUE = 35; // Character.getNumericValue('Z') + + /** Singleton ISIN Check Digit instance */ + 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}; + + /** + * Construct an ISIN Indetifier Check Digit routine. + */ + public ISINCheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + * Calculate the modulus for an ISIN code. + * + * @param code The code to calculate the modulus for. + * @param includesCheckDigit Whether the code includes the Check Digit or not. + * @return The modulus value + * @throws CheckDigitException if an error occurs calculating the modulus + * for the specified code + */ + @Override + protected int calculateModulus(String code, boolean includesCheckDigit) throws CheckDigitException { + StringBuilder transformed = new StringBuilder(code.length() * 2); + 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); + } + } + for (int i = 0; i < code.length(); i++) { + int charValue = Character.getNumericValue(code.charAt(i)); + if (charValue < 0 || charValue > MAX_ALPHANUMERIC_VALUE) { + throw new CheckDigitException("Invalid Character[" + + (i + 1) + "] = '" + charValue + "'"); + } + // 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 + * code at a specified position.

+ * + *

For Luhn (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

+ * + * @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) { + int weight = POSITION_WEIGHT[rightPos % 2]; + int weightedValue = (charValue * weight); + return ModulusCheckDigit.sumDigits(weightedValue); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ISSNCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,85 @@ +/* + * 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.checkdigit; + +/** + * 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.
+ * The check digit is modulus 11, where the value 10 is represented by 'X'
+ * For example:
+ * ISSN 0317-8471
+ * ISSN 1050-124X
+ * 
+ *

+ * Note: This class expects the input to be numeric only, + * with all formatting removed. + * For example: + *

+ * 03178471
+ * 1050124X
+ * 
+ * @since 1.5.0 + */ +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 + */ + public ISSNCheckDigit() { + super(11); // CHECKSTYLE IGNORE MagicNumber + } + + @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 { + if (charValue == 10) { // CHECKSTYLE IGNORE MagicNumber + return "X"; + } + return super.toCheckDigit(charValue); + } + + @Override + protected int toInt(char character, int leftPos, int rightPos) + throws CheckDigitException { + if (rightPos == 1 && character == 'X') { + return 10; // CHECKSTYLE IGNORE MagicNumber + } + return super.toInt(character, leftPos, rightPos); + } +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/LuhnCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,76 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 Luhn Check Digit calculation/validation. + * + * Luhn check digits are used, for example, by: + * + * Check digit calculation is based on modulus 10 with digits in + * an odd position (from right to left) being weighted 1 and even + * position digits being weighted 2 (weighted values greater than 9 have 9 subtracted). + * + *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class LuhnCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = -2976900113942875999L; + + /** Singleton Luhn Check Digit instance */ + 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}; + + /** + * Construct a modulus 10 Luhn Check Digit routine. + */ + public LuhnCheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + *

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

+ * + *

For Luhn (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

+ * + * @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) { + int weight = POSITION_WEIGHT[rightPos % 2]; // CHECKSTYLE IGNORE MagicNumber + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,204 @@ +/* + * 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.checkdigit; + +import java.io.Serializable; + +/** + * Abstract Modulus Check digit calculation/validation. + *

+ * 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. + *

+ * + * @version $Revision: 1739357 $ + * @since Validator 1.4 + */ +public abstract class ModulusCheckDigit implements CheckDigit, Serializable { + + 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. + * + * @param modulus The modulus value to use for the check digit calculation + */ + public ModulusCheckDigit(int modulus) { + this.modulus = modulus; + } + + /** + * Return the modulus value this check digit routine is based on. + * + * @return The modulus value this check digit routine is based on + */ + public int getModulus() { + return modulus; + } + + /** + * Validate a modulus 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 { + int modulusResult = calculateModulus(code, true); + return (modulusResult == 0); + } catch (CheckDigitException ex) { + return false; + } + } + + /** + * 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; + * 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) { + throw new CheckDigitException("Code is missing"); + } + int modulusResult = calculateModulus(code, false); + int charValue = (modulus - modulusResult) % modulus; + return toCheckDigit(charValue); + } + + /** + * Calculate the modulus for a code. + * + * @param code The code to calculate the modulus for. + * @param includesCheckDigit Whether the code includes the Check Digit or not. + * @return The modulus value + * @throws CheckDigitException if an error occurs calculating the modulus + * for the specified code + */ + protected int calculateModulus(String code, 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); + total += weightedValue(charValue, leftPos, rightPos); + } + if (total == 0) { + throw new CheckDigitException("Invalid code, sum is zero"); + } + return total % modulus; + } + + /** + * 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; + + + /** + * 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 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 + */ + protected int toInt(char character, int leftPos, int rightPos) + throws CheckDigitException { + if (Character.isDigit(character)) { + return Character.getNumericValue(character); + } + throw new CheckDigitException("Invalid Character[" + + leftPos + "] = '" + character + "'"); + } + + /** + * Convert an integer value to a check digit. + *

+ * Note: this implementation only handles single-digit numeric values + * For non-numeric characters, override this method to provide + * integer-->character conversion. + * + * @param charValue The integer value of the character + * @return The converted character + * @throws CheckDigitException if integer character value + * doesn't represent a numeric character + */ + protected String toCheckDigit(int charValue) + throws CheckDigitException { + if (charValue >= 0 && charValue <= 9) { // CHECKSTYLE IGNORE MagicNumber + return Integer.toString(charValue); + } + throw new CheckDigitException("Invalid Check Digit Value =" + + + charValue); + } + + /** + * Add together the individual digits in a number. + * + * @param number The number whose digits are to be added + * @return The sum of the digits + */ + 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 + } + return total; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/ModulusTenCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,243 @@ +/* + * 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.checkdigit; + +import java.util.Arrays; + +import org.apache.commons.validator.routines.CodeValidator; + +/** + * General Modulus 10 Check Digit calculation/validation. + * + *

How if Works

+ *

+ * This implementation calculates/validates the check digit in the following + * way: + *

    + *
  • Converting each character to an integer value using + * Character.getNumericValue(char) - negative integer values from + * that method are invalid.
  • + *
  • Calculating a weighted value by multiplying the character's + * integer value by a weighting factor. The weighting factor is + * selected from the configured postitionWeight array based on its + * position. The postitionWeight values are used either + * left-to-right (when useRightPos=false) or right-to-left (when + * useRightPos=true).
  • + *
  • If sumWeightedDigits=true, the weighted value is + * re-calculated by summing its digits.
  • + *
  • The weighted values of each character are totalled.
  • + *
  • The total modulo 10 will be zero for a code with a valid Check Digit.
  • + *
+ *

Limitations

+ *

+ * This implementation has the following limitations: + *

    + *
  • It assumes the last character in the code is the Check Digit and + * validates that it is a numeric character.
  • + *
  • The only limitation on valid characters are those that + * Character.getNumericValue(char) returns a positive value. If, + * for example, the code should only contain numbers, this implementation does + * not check that.
  • + *
  • There are no checks on code length.
  • + *
+ *

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

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);
+ * 
+ * + *

+ * 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);
+ * 
+ * + *

+ * 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);
+ * 
+ * + *

+ * 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 $ + */ +public final class ModulusTenCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = -3752929983453368497L; + + private final int[] postitionWeight; + private final boolean useRightPos; + private final boolean sumWeightedDigits; + + /** + * Construct 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) { + this(postitionWeight, false, false); + } + + /** + * Construct 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 + * left + */ + public ModulusTenCheckDigit(int[] postitionWeight, boolean useRightPos) { + this(postitionWeight, useRightPos, false); + } + + /** + * Construct 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 + * left + * @param sumWeightedDigits true if sum the digits of the + * weighted value + */ + public ModulusTenCheckDigit(int[] postitionWeight, boolean useRightPos, boolean sumWeightedDigits) { + super(10); // CHECKSTYLE IGNORE MagicNumber + this.postitionWeight = Arrays.copyOf(postitionWeight, postitionWeight.length); + this.useRightPos = useRightPos; + this.sumWeightedDigits = sumWeightedDigits; + } + + /** + * Validate a modulus check digit for a code. + *

+ * Note: assumes last digit is the check digit + * + * @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; + } + if (!Character.isDigit(code.charAt(code.length() - 1))) { + return false; + } + + return super.isValid(code); + } + + /** + * Convert a character at a specified position to an integer value. + *

+ * Note: this implementation only handlers values that + * Character.getNumericValue(char) returns a non-negative number. + * + * @param character The character to convert + * @param leftPos The position of the character in the code, counting from + * left to right (for identifying 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.getNumericValue(char) returns a + * negative number + */ + @Override + protected int toInt(char character, int leftPos, int rightPos) throws CheckDigitException { + int num = Character.getNumericValue(character); + if (num < 0) { + throw new CheckDigitException("Invalid Character[" + leftPos + "] = '" + character + "'"); + } + return num; + } + + /** + * 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 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 pos = useRightPos ? rightPos : leftPos; + 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 --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/SedolCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,114 @@ +/* + * 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.checkdigit; + +/** + * Modulus 10 SEDOL (UK Securities) Check Digit calculation/validation. + * + *

+ * SEDOL Numbers are 7 character alphanumeric codes used + * to identify UK Securities (SEDOL stands for Stock Exchange Daily Official List). + *

+ *

+ * Check digit calculation is based on modulus 10 with digits being weighted + * based on their position, from left to right, as follows: + *

+ *

+ *      position:  1  2  3  4  5  6  7
+ *     weighting:  1  3  1  7  3  9  1
+ * 
+ *

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

+ * + * @version $Revision: 1739356 $ + * @since Validator 1.4 + */ +public final class SedolCheckDigit extends ModulusCheckDigit { + + private static final long serialVersionUID = -8976881621148878443L; + + private static final int MAX_ALPHANUMERIC_VALUE = 35; // Character.getNumericValue('Z') + + /** Singleton SEDOL check digit instance */ + 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}; + + /** + * Construct a modulus 11 Check Digit routine for ISBN-10. + */ + public SedolCheckDigit() { + super(10); // CHECKSTYLE IGNORE MagicNumber + } + + /** + * Calculate the modulus for an SEDOL code. + * + * @param code The code to calculate the modulus for. + * @param includesCheckDigit Whether the code includes the Check Digit or not. + * @return The modulus value + * @throws CheckDigitException if an error occurs calculating the modulus + * for the specified code + */ + @Override + protected int calculateModulus(String code, 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 + * @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 integer value of the character + * @throws CheckDigitException if character is not alphanumeric + */ + @Override + protected int toInt(char character, int leftPos, int rightPos) + throws CheckDigitException { + 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) { + throw new CheckDigitException("Invalid Character[" + + leftPos + "," + rightPos + "] = '" + charValue + "' out of range 0 to " + charMax); + } + return charValue; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/VerhoeffCheckDigit.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,129 @@ +/* + * 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.checkdigit; + +import java.io.Serializable; + +/** + * Verhoeff (Dihedral) Check Digit calculation/validation. + *

+ * Check digit calculation for numeric codes using a + * Dihedral Group + * of order 10. + *

+ * See Wikipedia + * - Verhoeff algorithm for more details. + * + * @version $Revision: 1739357 $ + * @since Validator 1.4 + */ +public final class VerhoeffCheckDigit implements CheckDigit, Serializable { + + private static final long serialVersionUID = 4138993995483695178L; + + /** Singleton Verhoeff Check Digit instance */ + 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}}; + + /** 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}}; + + /** inv: inverse table */ + private static final int[] INV_TABLE = new int[] + {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 + * @return The calculated Check Digit + * @throws CheckDigitException if an error occurs calculating + * the check digit for the specified code + */ + @Override + public String calculate(String code) throws CheckDigitException { + if (code == null || code.length() == 0) { + throw new CheckDigitException("Code is missing"); + } + int checksum = calculateChecksum(code, false); + return Integer.toString(INV_TABLE[checksum]); + } + + /** + * Calculate the checksum. + * + * @param code The code to calculate the checksum for. + * @param includesCheckDigit Whether the code includes the Check Digit or not. + * @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 { + int checksum = 0; + for (int i = 0; i < code.length(); i++) { + int idx = code.length() - (i + 1); + 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)) + "'"); + } + int pos = includesCheckDigit ? i : i + 1; + checksum = D_TABLE[checksum][P_TABLE[pos % 8][num]]; // CHECKSTYLE IGNORE MagicNumber + } + return checksum; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package.html =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package.html (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/checkdigit/package.html (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,26 @@ + + + +Package Documentation for org.apache.commons.validator.routines.checkdigit Package + + + +

This package contains Check Digit validation/calculation routines.

+ + + Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package.html =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package.html (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/routines/package.html (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,827 @@ + + + +Package Documentation for org.apache.commons.validator.routines Package + + +

This package contains independant 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 flavours 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. +

+ + + +

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 flavours 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 true or false.
  • +
  • calculate(code) - calulates the check digit for a code + returning the check digit character.
  • +
+

+ The following implementations are provided: +

+ +

+ 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 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
+      }
+
+ + Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/Flags.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,206 @@ +/* + * 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.util; + +import java.io.Serializable; + +/** + * Represents a collection of 64 boolean (on/off) flags. Individual flags + * are represented by powers of 2. For example,
+ * Flag 1 = 1
+ * Flag 2 = 2
+ * Flag 3 = 4
+ * Flag 4 = 8

+ * or using shift operator to make numbering easier:
+ * Flag 1 = 1 << 0
+ * Flag 2 = 1 << 1
+ * Flag 3 = 1 << 2
+ * Flag 4 = 1 << 3
+ * + *

+ * 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 { + + private static final long serialVersionUID = 8481587558770237995L; + + /** + * Represents the current flag state. + */ + private long flags = 0; + + /** + * 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(); + 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 + */ + 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() + */ + @Override + public Object clone() { + try { + return super.clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException("Couldn't clone Flags object."); + } + } + + /** + * Tests if two Flags objects are in the same state. + * @param obj object being tested + * @see java.lang.Object#equals(java.lang.Object) + * + * @return whether the objects are equal. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Flags)) { + return false; + } + + if (obj == this) { + return true; + } + + Flags f = (Flags) obj; + + return this.flags == f.flags; + } + + /** + * The hash code is based on the current state of the flags. + * @see java.lang.Object#hashCode() + * + * @return the hash code for this object. + */ + @Override + public int hashCode() { + return (int) this.flags; + } + + /** + * 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. + * + * @return string representation of this object. + */ + @Override + public String toString() { + 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(); + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/ValidatorUtils.java (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,200 @@ +/* + * 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.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 +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.validator.Arg; +import org.apache.commons.validator.Msg; +import org.apache.commons.validator.Var; + +/** + * Basic utility methods. + *

+ * 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. + * @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(); + + @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(); + + if (value instanceof Msg) { + results.put(key, ((Msg) value).clone()); + } else if (value instanceof Arg) { + results.put(key, ((Arg) value).clone()); + } else if (value instanceof Var) { + results.put(key, ((Var) value).clone()); + } else { + results.put(key, value); + } + } + + results.setFast(true); + return results; + } + + /** + * Makes a deep copy of a Map if the values are + * Msg, Arg, or Var. Otherwise, + * it is a shallow copy. + * + * @param map The source Map to copy. + * + * @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(); + + if (value instanceof Msg) { + results.put(key, ((Msg) value).clone()); + } else if (value instanceof Arg) { + results.put(key, ((Arg) value).clone()); + } else if (value instanceof Var) { + results.put(key, ((Var) value).clone()); + } else { + results.put(key, value); + } + } + return results; + } + +} Index: 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package.html =================================================================== diff -u --- 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package.html (revision 0) +++ 3rdParty_sources/commons-validator/org/apache/commons/validator/util/package.html (revision 08255e7eeeaeba69421502fb648a1b6e98e92610) @@ -0,0 +1,26 @@ + + + +Package Documentation for org.apache.commons.validator.util Package + + +

+This package contains utility classes used by Commons Validator. +

+ +