You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ni...@apache.org on 2006/12/13 18:35:25 UTC
svn commit: r486765 - in /jakarta/commons/proper/validator/trunk:
src/share/org/apache/commons/validator/
src/share/org/apache/commons/validator/routines/
src/test/org/apache/commons/validator/routines/ xdocs/
Author: niallp
Date: Wed Dec 13 09:35:23 2006
New Revision: 486765
URL: http://svn.apache.org/viewvc?view=rev&rev=486765
Log:
Re-write of the ISBNValidator using the new CodeValidator and CheckDigit routines. Removes the dependency on Jakarta ORO and now caters for the new ISBN-13 format. Existing ISBNValidator is now deprecated.
Fixes VALIDATOR-188 and VALIDATOR-191
Modified:
jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ISBNValidator.java
jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/ISBNValidator.java
jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/package.html
jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/ISBNValidatorTest.java
jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/RoutinesTestSuite.java
jakarta/commons/proper/validator/trunk/xdocs/changes.xml
Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ISBNValidator.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ISBNValidator.java?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ISBNValidator.java (original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ISBNValidator.java Wed Dec 13 09:35:23 2006
@@ -24,25 +24,15 @@
* <a href="http://www.isbn.org/standards/home/isbn/international/html/usm4.htm">
* algorithm</a>
*
+ * <b>NOTE:</b> This has been replaced by the new
+ * {@link org.apache.commons.validator.routines.ISBNValidator}.
+ *
* @version $Revision$ $Date$
* @since Validator 1.2.0
+ * @deprecated Use the new ISBNValidator in the routines package
*/
public class ISBNValidator {
- 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})";
- private static final String CHECK = "([0-9X])";
-
- /**
- * ISBN 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.
- */
- private static final String ISBN_PATTERN =
- "/^" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + CHECK + "$/";
-
/**
* Default Constructor.
*/
@@ -61,73 +51,7 @@
* @return true if the string is a valid ISBN code.
*/
public boolean isValid(String isbn) {
- if (isbn == null || isbn.length() < 10 || isbn.length() > 13) {
- return false;
- }
-
- if (isFormatted(isbn) && !isValidPattern(isbn)) {
- return false;
- }
-
- isbn = clean(isbn);
- if (isbn.length() != 10) {
- return false;
- }
-
- return (sum(isbn) % 11) == 0;
- }
-
- /**
- * Returns the sum of the weighted ISBN characters.
- */
- private int sum(String isbn) {
- int total = 0;
- for (int i = 0; i < 9; i++) {
- int weight = 10 - i;
- total += (weight * toInt(isbn.charAt(i)));
- }
- total += toInt(isbn.charAt(9)); // add check digit
- return total;
- }
-
- /**
- * Removes all non-digit characters except for 'X' which is a valid ISBN
- * character.
- */
- private String clean(String isbn) {
- StringBuffer buf = new StringBuffer(10);
-
- for (int i = 0; i < isbn.length(); i++) {
- char digit = isbn.charAt(i);
- if (Character.isDigit(digit) || (digit == 'X')) {
- buf.append(digit);
- }
- }
-
- return buf.toString();
- }
-
- /**
- * Returns the numeric value represented by the character. If the
- * character is not a digit but an 'X', 10 is returned.
- */
- private int toInt(char ch) {
- return (ch == 'X') ? 10 : Character.getNumericValue(ch);
- }
-
- /**
- * Returns true if the ISBN contains one of the separator characters space
- * or dash.
- */
- private boolean isFormatted(String isbn) {
- return ((isbn.indexOf('-') != -1) || (isbn.indexOf(' ') != -1));
- }
-
- /**
- * Returns true if the ISBN is formatted properly.
- */
- private boolean isValidPattern(String isbn) {
- return new Perl5Util().match(ISBN_PATTERN, isbn);
+ return org.apache.commons.validator.routines.ISBNValidator.getInstance().isValidISBN10(isbn);
}
}
Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/ISBNValidator.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/ISBNValidator.java?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/ISBNValidator.java (original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/ISBNValidator.java Wed Dec 13 09:35:23 2006
@@ -16,118 +16,241 @@
*/
package org.apache.commons.validator.routines;
-import org.apache.oro.text.perl.Perl5Util;
+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;
/**
- * A class for validating 10 digit ISBN codes.
- * Based on this
- * <a href="http://www.isbn.org/standards/home/isbn/international/html/usm4.htm">
- * algorithm</a>
+ * <b>ISBN-10</b> and <b>ISBN-13</b> Code Validation.
+ * <p>
+ * 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).
+ * <p>
+ * The <code>validate()</code> methods return the ISBN code with formatting
+ * characters removed if valid or <code>null</code> if invalid.
+ * <p>
+ * This validator also provides the facility to convert ISBN-10 codes to
+ * ISBN-13 if the <code>convert</code> property is <code>true</code>.
+ * <p>
+ * 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
+ * <a href="http://en.wikipedia.org/wiki/European_Article_Number">EAN</a>
+ * codes, for more information see:</p>
*
+ * <ul>
+ * <li><a href="http://en.wikipedia.org/wiki/ISBN">Wikipedia - International
+ * Standard Book Number (ISBN)</a>.</li>
+ * <li>EAN - see
+ * <a href="http://en.wikipedia.org/wiki/European_Article_Number">Wikipedia -
+ * European Article Number</a>.</li>
+ * <li><a href="http://www.isbn.org/standards/home/isbn/transition.asp">ISBN-13
+ * Transition details</a>.</li>
+ * </ul>
+ *
* @version $Revision$ $Date$
- * @since Validator 1.2.0
+ * @since Validator 1.4
*/
-public class ISBNValidator {
+public class ISBNValidator implements Serializable {
- private static final String SEP = "(\\-|\\s)";
+ 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})";
- private static final String CHECK = "([0-9X])";
/**
- * ISBN consists of 4 groups of numbers separated by either dashes (-)
+ * 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.
*/
- private static final String ISBN_PATTERN =
- "/^" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + CHECK + "$/";
+ static final String ISBN10_REGEX =
+ "^(?:(\\d{9}[0-9X])|(?:" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + "([0-9X])))$";
/**
- * Default Constructor.
+ * 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.
*/
- public ISBNValidator() {
- super();
- }
+ 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 CodeValidator isbn10Validator = new CodeValidator(ISBN10_REGEX, 10, ISBN10CheckDigit.INSTANCE);
+
+ /** ISBN-13 Code Validator */
+ private CodeValidator isbn13Validator = new CodeValidator(ISBN13_REGEX, 13, EAN13CheckDigit.INSTANCE);
+
+ private boolean convert = true;
/**
- * 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.
+ * Return a singleton instance of the ISBN validator which
+ * converts ISBN-10 codes to ISBN-13.
*
- * @param isbn Candidate ISBN number to be validated. <code>null</code> is
- * considered invalid.
- * @return true if the string is a valid ISBN code.
+ * @return A singleton instance of the ISBN validator.
*/
- public boolean isValid(String isbn) {
- if (isbn == null || isbn.length() < 10 || isbn.length() > 13) {
- return false;
- }
+ 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 <code>true</code> if valid ISBN-10 codes
+ * should be converted to ISBN-13 codes or <code>false</code>
+ * 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);
+ }
- if (isFormatted(isbn) && !isValidPattern(isbn)) {
- return false;
- }
+ /**
+ * Construct an ISBN validator which converts ISBN-10 codes
+ * to ISBN-13.
+ */
+ public ISBNValidator() {
+ this(true);
+ }
- isbn = clean(isbn);
- if (isbn.length() != 10) {
- return false;
- }
+ /**
+ * Construct an ISBN validator indicating whether
+ * ISBN-10 codes should be converted to ISBN-13.
+ *
+ * @param convert <code>true</code> if valid ISBN-10 codes
+ * should be converted to ISBN-13 codes or <code>false</code>
+ * if valid ISBN-10 codes should be returned unchanged.
+ */
+ public ISBNValidator(boolean convert) {
+ this.convert = convert;
+ }
- return (sum(isbn) % 11) == 0;
+ /**
+ * Check the code is either a valid ISBN-10 or ISBN-13 code.
+ *
+ * @param code The code to validate.
+ * @return <code>true</code> if a valid ISBN-10 or
+ * ISBN-13 code, otherwise <code>false</code>.
+ */
+ public boolean isValid(String code) {
+ return (isValidISBN13(code) || isValidISBN10(code));
}
-
+
/**
- * Returns the sum of the weighted ISBN characters.
+ * Check the code is a valid ISBN-10 code.
+ *
+ * @param code The code to validate.
+ * @return <code>true</code> if a valid ISBN-10
+ * code, otherwise <code>false</code>.
*/
- private int sum(String isbn) {
- int total = 0;
- for (int i = 0; i < 9; i++) {
- int weight = 10 - i;
- total += (weight * toInt(isbn.charAt(i)));
- }
- total += toInt(isbn.charAt(9)); // add check digit
- return total;
+ public boolean isValidISBN10(String code) {
+ return isbn10Validator.isValid(code);
}
/**
- * Removes all non-digit characters except for 'X' which is a valid ISBN
- * character.
+ * Check the code is a valid ISBN-13 code.
+ *
+ * @param code The code to validate.
+ * @return <code>true</code> if a valid ISBN-13
+ * code, otherwise <code>false</code>.
+ */
+ public boolean isValidISBN13(String code) {
+ return isbn13Validator.isValid(code);
+ }
+
+ /**
+ * Check the code is either a valid ISBN-10 or ISBN-13 code.
+ * <p>
+ * If valid, this method returns the ISBN code with
+ * formatting characters removed (i.e. space or hyphen).
+ * <p>
+ * Converts an ISBN-10 codes to ISBN-13 if
+ * <code>convertToISBN13</code> is <code>true</code>.
+ *
+ * @param code The code to validate.
+ * @return A valid ISBN code if valid, otherwise <code>null</code>.
*/
- private String clean(String isbn) {
- StringBuffer buf = new StringBuffer(10);
-
- for (int i = 0; i < isbn.length(); i++) {
- char digit = isbn.charAt(i);
- if (Character.isDigit(digit) || (digit == 'X')) {
- buf.append(digit);
+ public String validate(String code) {
+ String result = validateISBN13(code);
+ if (result == null) {
+ result = validateISBN10(code);
+ if (result != null && convert) {
+ result = convertToISBN13(result);
}
}
-
- return buf.toString();
+ return result;
}
/**
- * Returns the numeric value represented by the character. If the
- * character is not a digit but an 'X', 10 is returned.
+ * Check the code is a valid ISBN-10 code.
+ * <p>
+ * 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 <code>null</code>.
*/
- private int toInt(char ch) {
- return (ch == 'X') ? 10 : Character.getNumericValue(ch);
+ public String validateISBN10(String code) {
+ Object result = isbn10Validator.validate(code);
+ return (result == null ? null : result.toString());
}
-
+
/**
- * Returns true if the ISBN contains one of the separator characters space
- * or dash.
+ * Check the code is a valid ISBN-13 code.
+ * <p>
+ * 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 <code>null</code>.
*/
- private boolean isFormatted(String isbn) {
- return ((isbn.indexOf('-') != -1) || (isbn.indexOf(' ') != -1));
+ public String validateISBN13(String code) {
+ Object result = isbn13Validator.validate(code);
+ return (result == null ? null : result.toString());
}
/**
- * Returns true if the ISBN is formatted properly.
+ * Convert an ISBN-10 code to an ISBN-13 code.
+ * <p>
+ * 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 <code>null</code>
+ * if the ISBN-10 code is not valid
*/
- private boolean isValidPattern(String isbn) {
- return new Perl5Util().match(ISBN_PATTERN, isbn);
+ public String convertToISBN13(String isbn10) {
+
+ if (isbn10 == null) {
+ return null;
+ }
+
+ String input = isbn10.trim();
+ if (input.length() != 10) {
+ throw new IllegalArgumentException("Invalid length " + input.length() + " for '" + input + "'");
+ }
+
+ // Calculate the new ISBN-13 code
+ String isbn13 = "978" + input.substring(0, 9);
+ try {
+ char checkDigit = isbn13Validator.getCheckDigit().calculate(isbn13);
+ isbn13 += checkDigit;
+ return isbn13;
+ } catch (CheckDigitException e) {
+ throw new IllegalArgumentException("Check digit error for '" + input + "' - " + e.getMessage());
+ }
+
}
}
Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/package.html
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/package.html?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/package.html (original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/routines/package.html Wed Dec 13 09:35:23 2006
@@ -47,6 +47,7 @@
<li>4.2 <a href="#other.regex">Regular Expression validation</a></li>
<li>4.3 <a href="#other.checkdigit">Check Digit Validation/Calculation</a></li>
<li>4.4 <a href="#other.code">General Code Validation</a></li>
+ <li>4.5 <a href="#other.isbn">ISBN Validation</a></li>
</ul></li>
</ul>
@@ -422,6 +423,8 @@
check digits (i.e. EAN/UPC, credit card, ISBN).</li>
<li><a href="#other.code">Code Validation</a> - provides generic
code validation - format, minimum/maximum length and check digit.</li>
+ <li><a href="#other.isbn">ISBN Validation</a> - provides ISBN-10
+ and ISBN-13 validation.</li>
</ul>
<a name="other.regex"></a>
@@ -609,6 +612,56 @@
if (!validator.isValid(code)) {
... // invalid
}
+
+</pre>
+
+<a name="other.isbn"></a>
+<h3>4.5 ISBN validation</h3>
+<p>
+ <a href="ISBNValidator.html">ISBNValidator</a> provides ISBN-10
+ and ISBN-13 validation and can <i>optionally</i> convert
+ ISBN-10 codes to ISBN-13.
+</p>
+<ul>
+ <li><b>ISBN-10</b> - validates using a
+ <a href="CodeValidator.html">CodeValidator</a> with the
+ <a href="checkdigit/ISBN10CheckDigit.html">ISBN10CheckDigit</a>
+ routine.</li>
+ <ul>
+ <li><code>isValidISBN10(<i>value</i>)</code> - returns a boolean</li>
+ <li><code>validateISBN10(<i>value</i>)</code> - returns a reformatted ISBN-10 code</li>
+ </ul>
+ <li><b>ISBN-13</b> - validates using a
+ <a href="CodeValidator.html">CodeValidator</a> with the
+ <a href="checkdigit/EAN13CheckDigit.html">EAN13CheckDigit</a>
+ routine.</li>
+ <ul>
+ <li><code>isValidISBN13(<i>value</i>)</code> - returns a boolean</li>
+ <li><code>validateISBN13(<i>value</i>)</code> - returns a reformatted ISBN-13 code</li>
+ </ul>
+ <li><b>ISBN-10</b> and <b>ISBN-13</b> - validates codes are either
+ valid ISBN-10 or valid ISBN-13 - optionally can convert ISBN-10 codes to ISBN-13.</li>
+ <ul>
+ <li><code>isValid(<i>value</i>)</code> - returns a boolean</li>
+ <li><code>validate(<i>value</i>)</code> - returns a reformatted ISBN code
+ (converts ISBN-10 to ISBN-13 if the <i>convert</i> option is <code>true</code>).</li>
+ </ul>
+</ul>
+<p>
+ For example to validate
+</p>
+<pre>
+
+ // 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);
</pre>
Modified: jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/ISBNValidatorTest.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/ISBNValidatorTest.java?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/ISBNValidatorTest.java (original)
+++ jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/ISBNValidatorTest.java Wed Dec 13 09:35:23 2006
@@ -16,6 +16,7 @@
*/
package org.apache.commons.validator.routines;
+import java.util.regex.Pattern;
import junit.framework.TestCase;
/**
@@ -25,34 +26,301 @@
*/
public class ISBNValidatorTest extends TestCase {
- private static final String VALID_ISBN_RAW = "1930110995";
- private static final String VALID_ISBN_DASHES = "1-930110-99-5";
- private static final String VALID_ISBN_SPACES = "1 930110 99 5";
- private static final String VALID_ISBN_X = "0-201-63385-X";
- private static final String INVALID_ISBN = "068-556-98-45";
+ private String[] validISBN10Format = new String[] {
+ "1234567890",
+ "123456789X",
+ "12345-1234567-123456-X",
+ "12345 1234567 123456 X",
+ "1-2-3-4",
+ "1 2 3 4",
+ };
+ private String[] invalidISBN10Format = new String[] {
+ "", // empty
+ " ", // empty
+ "1", // too short
+ "123456789", // too short
+ "12345678901", // too long
+ "12345678X0", // X not at end
+ "123456-1234567-123456-X", // Group too long
+ "12345-12345678-123456-X", // Publisher too long
+ "12345-1234567-1234567-X", // Title too long
+ "12345-1234567-123456-X2", // Check Digit too long
+ "--1 930110 99 5", // format
+ "1 930110 99 5--", // format
+ "1 930110-99 5-", // format
+ "1.2.3.4", // Invalid Separator
+ "1=2=3=4", // Invalid Separator
+ "1_2_3_4", // Invalid Separator
+ "123456789Y", // Other character at the end
+ "dsasdsadsa", // invalid characters
+ "I love sparrows!", // invalid characters
+ "068-556-98-45" // format
+ };
+
+ private String[] validISBN13Format = new String[] {
+ "9781234567890",
+ "9791234567890",
+ "978-12345-1234567-123456-1",
+ "979-12345-1234567-123456-1",
+ "978 12345 1234567 123456 1",
+ "979 12345 1234567 123456 1",
+ "978-1-2-3-4",
+ "979-1-2-3-4",
+ "978 1 2 3 4",
+ "979 1 2 3 4",
+ };
+
+ private String[] invalidISBN13Format = new String[] {
+ "", // empty
+ " ", // empty
+ "1", // too short
+ "978123456789", // too short
+ "97812345678901", // too long
+ "978-123456-1234567-123456-1", // Group too long
+ "978-12345-12345678-123456-1", // Publisher too long
+ "978-12345-1234567-1234567-1", // Title too long
+ "978-12345-1234567-123456-12", // Check Digit too long
+ "--978 1 930110 99 1", // format
+ "978 1 930110 99 1--", // format
+ "978 1 930110-99 1-", // format
+ "123-4-567890-12-8", // format
+ "978.1.2.3.4", // Invalid Separator
+ "978=1=2=3=4", // Invalid Separator
+ "978_1_2_3_4", // Invalid Separator
+ "978123456789X", // invalid character
+ "978-0-201-63385-X", // invalid character
+ "dsasdsadsadsa", // invalid characters
+ "I love sparrows!", // invalid characters
+ "979-1-234-567-89-6" // format
+ };
+
+ /**
+ * Create a test case with the specified name.
+ * @param name The name of the test
+ */
public ISBNValidatorTest(String name) {
super(name);
}
- public void testIsValid() throws Exception {
- ISBNValidator validator = new ISBNValidator();
- assertFalse(validator.isValid(null));
- assertFalse(validator.isValid(""));
- assertFalse(validator.isValid("1"));
- assertFalse(validator.isValid("12345678901234"));
- assertFalse(validator.isValid("dsasdsadsads"));
- assertFalse(validator.isValid("535365"));
- assertFalse(validator.isValid("I love sparrows!"));
- assertFalse(validator.isValid("--1 930110 99 5"));
- assertFalse(validator.isValid("1 930110 99 5--"));
- assertFalse(validator.isValid("1 930110-99 5-"));
-
- assertTrue(validator.isValid(VALID_ISBN_RAW));
- assertTrue(validator.isValid(VALID_ISBN_DASHES));
- assertTrue(validator.isValid(VALID_ISBN_SPACES));
- assertTrue(validator.isValid(VALID_ISBN_X));
- assertFalse(validator.isValid(INVALID_ISBN));
+ /**
+ * Test Valid ISBN-10 formats.
+ */
+ public void testValidISBN10Format() {
+ Pattern pattern = Pattern.compile(ISBNValidator.ISBN10_REGEX);
+ for (int i = 0; i < validISBN10Format.length; i++) {
+ assertTrue("Pattern[" + i + "]=" + validISBN10Format[i], pattern.matcher(validISBN10Format[i]).matches());
+ }
+ }
+
+ /**
+ * Test Invalid ISBN-10 formats.
+ */
+ public void testInvalidISBN10Format() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ Pattern pattern = Pattern.compile(ISBNValidator.ISBN10_REGEX);
+ for (int i = 0; i < invalidISBN10Format.length; i++) {
+ assertFalse("Pattern[" + i + "]=" + invalidISBN10Format[i], pattern.matcher(invalidISBN10Format[i]).matches());
+ assertFalse("isValidISBN10[" + i + "]=" + invalidISBN10Format[i], validator.isValidISBN10(invalidISBN10Format[i]));
+ assertNull("validateISBN10[" + i + "]=" + invalidISBN10Format[i], validator.validateISBN10(invalidISBN10Format[i]));
+ }
+ }
+
+ /**
+ * Test Valid ISBN-13 formats.
+ */
+ public void testValidISBN13Format() {
+ Pattern pattern = Pattern.compile(ISBNValidator.ISBN13_REGEX);
+ for (int i = 0; i < validISBN13Format.length; i++) {
+ assertTrue("Pattern[" + i + "]=" + validISBN13Format[i], pattern.matcher(validISBN13Format[i]).matches());
+ }
+ }
+
+ /**
+ * Test Invalid ISBN-13 formats.
+ */
+ public void testInvalidISBN13Format() {
+ Pattern pattern = Pattern.compile(ISBNValidator.ISBN13_REGEX);
+ ISBNValidator validator = ISBNValidator.getInstance();
+ for (int i = 0; i < invalidISBN13Format.length; i++) {
+ assertFalse("Pattern[" + i + "]=" + invalidISBN13Format[i], pattern.matcher(invalidISBN13Format[i]).matches());
+ assertFalse("isValidISBN13[" + i + "]=" + invalidISBN13Format[i], validator.isValidISBN13(invalidISBN13Format[i]));
+ assertNull("validateISBN13[" + i + "]=" + invalidISBN13Format[i], validator.validateISBN13(invalidISBN13Format[i]));
+ }
+ }
+
+ /**
+ * Test isValid() ISBN-10 codes
+ */
+ public void testIsValidISBN10() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ assertTrue("isValidISBN10-1", validator.isValidISBN10("1930110995"));
+ assertTrue("isValidISBN10-2", validator.isValidISBN10("1-930110-99-5"));
+ assertTrue("isValidISBN10-3", validator.isValidISBN10("1 930110 99 5"));
+ assertTrue("isValidISBN10-4", validator.isValidISBN10("020163385X"));
+ assertTrue("isValidISBN10-5", validator.isValidISBN10("0-201-63385-X"));
+ assertTrue("isValidISBN10-6", validator.isValidISBN10("0 201 63385 X"));
+
+ assertTrue("isValid-1", validator.isValid("1930110995"));
+ assertTrue("isValid-2", validator.isValid("1-930110-99-5"));
+ assertTrue("isValid-3", validator.isValid("1 930110 99 5"));
+ assertTrue("isValid-4", validator.isValid("020163385X"));
+ assertTrue("isValid-5", validator.isValid("0-201-63385-X"));
+ assertTrue("isValid-6", validator.isValid("0 201 63385 X"));
+ }
+
+ /**
+ * Test isValid() ISBN-13 codes
+ */
+ public void testIsValidISBN13() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ assertTrue("isValidISBN13-1", validator.isValidISBN13("9781930110991"));
+ assertTrue("isValidISBN13-2", validator.isValidISBN13("978-1-930110-99-1"));
+ assertTrue("isValidISBN13-3", validator.isValidISBN13("978 1 930110 99 1"));
+ assertTrue("isValidISBN13-4", validator.isValidISBN13("9780201633856"));
+ assertTrue("isValidISBN13-5", validator.isValidISBN13("978-0-201-63385-6"));
+ assertTrue("isValidISBN13-6", validator.isValidISBN13("978 0 201 63385 6"));
+
+ assertTrue("isValid-1", validator.isValid("9781930110991"));
+ assertTrue("isValid-2", validator.isValid("978-1-930110-99-1"));
+ assertTrue("isValid-3", validator.isValid("978 1 930110 99 1"));
+ assertTrue("isValid-4", validator.isValid("9780201633856"));
+ assertTrue("isValid-5", validator.isValid("978-0-201-63385-6"));
+ assertTrue("isValid-6", validator.isValid("978 0 201 63385 6"));
+ }
+
+ /**
+ * Test validate() ISBN-10 codes (don't convert)
+ */
+ public void testValidateISBN10() {
+ ISBNValidator validator = ISBNValidator.getInstance(false);
+ assertEquals("validateISBN10-1", "1930110995", validator.validateISBN10("1930110995"));
+ assertEquals("validateISBN10-2", "1930110995", validator.validateISBN10("1-930110-99-5"));
+ assertEquals("validateISBN10-3", "1930110995", validator.validateISBN10("1 930110 99 5"));
+ assertEquals("validateISBN10-4", "020163385X", validator.validateISBN10("020163385X"));
+ assertEquals("validateISBN10-5", "020163385X", validator.validateISBN10("0-201-63385-X"));
+ assertEquals("validateISBN10-6", "020163385X", validator.validateISBN10("0 201 63385 X"));
+
+ assertEquals("validate-1", "1930110995", validator.validate("1930110995"));
+ assertEquals("validate-2", "1930110995", validator.validate("1-930110-99-5"));
+ assertEquals("validate-3", "1930110995", validator.validate("1 930110 99 5"));
+ assertEquals("validate-4", "020163385X", validator.validate("020163385X"));
+ assertEquals("validate-5", "020163385X", validator.validate("0-201-63385-X"));
+ assertEquals("validate-6", "020163385X", validator.validate("0 201 63385 X"));
+ }
+
+ /**
+ * Test validate() ISBN-10 codes (convert)
+ */
+ public void testValidateISBN10Convert() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ assertEquals("validate-1", "9781930110991", validator.validate("1930110995"));
+ assertEquals("validate-2", "9781930110991", validator.validate("1-930110-99-5"));
+ assertEquals("validate-3", "9781930110991", validator.validate("1 930110 99 5"));
+ assertEquals("validate-4", "9780201633856", validator.validate("020163385X"));
+ assertEquals("validate-5", "9780201633856", validator.validate("0-201-63385-X"));
+ assertEquals("validate-6", "9780201633856", validator.validate("0 201 63385 X"));
+ }
+
+ /**
+ * Test validate() ISBN-13 codes
+ */
+ public void testValidateISBN13() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ assertEquals("validateISBN13-1", "9781930110991", validator.validateISBN13("9781930110991"));
+ assertEquals("validateISBN13-2", "9781930110991", validator.validateISBN13("978-1-930110-99-1"));
+ assertEquals("validateISBN13-3", "9781930110991", validator.validateISBN13("978 1 930110 99 1"));
+ assertEquals("validateISBN13-4", "9780201633856", validator.validateISBN13("9780201633856"));
+ assertEquals("validateISBN13-5", "9780201633856", validator.validateISBN13("978-0-201-63385-6"));
+ assertEquals("validateISBN13-6", "9780201633856", validator.validateISBN13("978 0 201 63385 6"));
+
+ assertEquals("validate-1", "9781930110991", validator.validate("9781930110991"));
+ assertEquals("validate-2", "9781930110991", validator.validate("978-1-930110-99-1"));
+ assertEquals("validate-3", "9781930110991", validator.validate("978 1 930110 99 1"));
+ assertEquals("validate-4", "9780201633856", validator.validate("9780201633856"));
+ assertEquals("validate-5", "9780201633856", validator.validate("978-0-201-63385-6"));
+ assertEquals("validate-6", "9780201633856", validator.validate("978 0 201 63385 6"));
+ }
+
+ /**
+ * Test null values
+ */
+ public void testNull() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ assertFalse("isValid", validator.isValid(null));
+ assertFalse("isValidISBN10", validator.isValidISBN10(null));
+ assertFalse("isValidISBN13", validator.isValidISBN13(null));
+ assertNull("validate", validator.validate(null));
+ assertNull("validateISBN10", validator.validateISBN10(null));
+ assertNull("validateISBN13", validator.validateISBN13(null));
+ assertNull("convertToISBN13", validator.convertToISBN13(null));
+ }
+
+ /**
+ * Test Invalid ISBN-10 codes
+ */
+ public void testInvalid() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ String baseCode = "193011099";
+ assertFalse("ISBN10-0", validator.isValid(baseCode + "0"));
+ assertFalse("ISBN10-1", validator.isValid(baseCode + "1"));
+ assertFalse("ISBN10-2", validator.isValid(baseCode + "2"));
+ assertFalse("ISBN10-3", validator.isValid(baseCode + "3"));
+ assertFalse("ISBN10-4", validator.isValid(baseCode + "4"));
+ assertTrue("ISBN10-5", validator.isValid(baseCode + "5")); // valid check digit
+ assertFalse("ISBN10-6", validator.isValid(baseCode + "6"));
+ assertFalse("ISBN10-7", validator.isValid(baseCode + "7"));
+ assertFalse("ISBN10-8", validator.isValid(baseCode + "8"));
+ assertFalse("ISBN10-9", validator.isValid(baseCode + "9"));
+ assertFalse("ISBN10-X", validator.isValid(baseCode + "X"));
+
+ baseCode = "978193011099";
+ assertFalse("ISBN13-0", validator.isValid(baseCode + "0"));
+ assertTrue("ISBN13-1", validator.isValid(baseCode + "1")); // valid check digit
+ assertFalse("ISBN13-2", validator.isValid(baseCode + "2"));
+ assertFalse("ISBN13-3", validator.isValid(baseCode + "3"));
+ assertFalse("ISBN13-4", validator.isValid(baseCode + "4"));
+ assertFalse("ISBN13-5", validator.isValid(baseCode + "5"));
+ assertFalse("ISBN13-6", validator.isValid(baseCode + "6"));
+ assertFalse("ISBN13-7", validator.isValid(baseCode + "7"));
+ assertFalse("ISBN13-8", validator.isValid(baseCode + "8"));
+ assertFalse("ISBN13-9", validator.isValid(baseCode + "9"));
+ }
+
+ /**
+ * Test method for {@link org.apache.commons.validator.routines.ISBNValidator#convertToISBN13(java.lang.String)}.
+ */
+ public void testConversionErrors() {
+ ISBNValidator validator = ISBNValidator.getInstance();
+ String input = null;
+ try {
+ input = "123456789 ";
+ validator.convertToISBN13(input);
+ fail("Expected IllegalArgumentException for '" + input + "'");
+ } catch (IllegalArgumentException e) {
+ // expected result
+ }
+ try {
+ input = "12345678901";
+ validator.convertToISBN13(input);
+ fail("Expected IllegalArgumentException for '" + input + "'");
+ } catch (IllegalArgumentException e) {
+ // expected result
+ }
+ try {
+ input = "";
+ validator.convertToISBN13(input);
+ fail("Expected IllegalArgumentException for '" + input + "'");
+ } catch (IllegalArgumentException e) {
+ // expected result
+ }
+ try {
+ input = "X234567890";
+ validator.convertToISBN13(input);
+ fail("Expected IllegalArgumentException for '" + input + "'");
+ } catch (IllegalArgumentException e) {
+ // expected result
+ }
}
}
Modified: jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/RoutinesTestSuite.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/RoutinesTestSuite.java?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/RoutinesTestSuite.java (original)
+++ jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/routines/RoutinesTestSuite.java Wed Dec 13 09:35:23 2006
@@ -49,6 +49,7 @@
suite.addTestSuite(DateValidatorTest.class);
suite.addTestSuite(DoubleValidatorTest.class);
suite.addTestSuite(FloatValidatorTest.class);
+ suite.addTestSuite(ISBNValidatorTest.class);
suite.addTestSuite(IntegerValidatorTest.class);
suite.addTestSuite(LongValidatorTest.class);
suite.addTestSuite(PercentValidatorTest.class);
Modified: jakarta/commons/proper/validator/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/validator/trunk/xdocs/changes.xml?view=diff&rev=486765&r1=486764&r2=486765
==============================================================================
--- jakarta/commons/proper/validator/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/validator/trunk/xdocs/changes.xml Wed Dec 13 09:35:23 2006
@@ -40,6 +40,23 @@
<body>
<release version="1.4-SNAPSHOT" date="in SVN" description="JDK 1.4 (minimum)">
+ <action dev="niallp" type="update">
+ <a href="apidocs/org/apache/commons/validator/routines/ISBNValidator.html">ISBN Validator</a>
+ <ul>
+ <li>Moved to the new
+ <a href="apidocs/org/apache/commons/validator/routines/package-summary.html">routines</a> package.</li>
+ <li>Re-written to use the new
+ <a href="apidocs/org/apache/commons/validator/routines/CodeValidator.html">CodeValidator</a> and
+ <a href="apidocs/org/apache/commons/validator/routines/checkdigit/package-summary.html">Check Digit</a> routines.</li>
+ <li>Enhanced for the new <a href="http://issues.apache.org/jira/browse/VALIDATOR-188">ISBN-13 format</a>.</li>
+ <li><a href="http://jakarta.apache.org/oro/">Jakarta ORO</a> dependency removed.</li>
+ </ul>
+ <fixes issue="VALIDATOR-197"/>
+ <fixes issue="VALIDATOR-188"/>
+ <fixes issue="VALIDATOR-191"/>
+ <dueto name="Gabriel Belingueres"/>
+ <dueto name="Matthias Wessendorf"/>
+ </action>
<action dev="niallp" type="add" issue="VALIDATOR-215">
<b>Code Validator</b> - new generic code validator that validates format,
length and Check Digit for a code, see
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org