KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > validator > ISBNValidator


1 /*
2  * $Id: ISBNValidator.java 155434 2005-02-26 13:16:41Z dirkv $
3  * $Rev$
4  * $Date: 2005-02-26 05:16:41 -0800 (Sat, 26 Feb 2005) $
5  *
6  * ====================================================================
7  * Copyright 2004-2005 The Apache Software Foundation
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package org.apache.commons.validator;
23
24 import org.apache.oro.text.perl.Perl5Util;
25
26 /**
27  * A class for validating 10 digit ISBN codes.
28  * Based on this
29  * <a HREF="http://www.isbn.org/standards/home/isbn/international/html/usm4.htm">
30  * algorithm</a>
31  *
32  * @since Validator 1.2.0
33  */

34 public class ISBNValidator {
35
36     private static final String JavaDoc SEP = "(\\-|\\s)";
37     private static final String JavaDoc GROUP = "(\\d{1,5})";
38     private static final String JavaDoc PUBLISHER = "(\\d{1,7})";
39     private static final String JavaDoc TITLE = "(\\d{1,6})";
40     private static final String JavaDoc CHECK = "([0-9X])";
41
42     /**
43      * ISBN consists of 4 groups of numbers separated by either dashes (-)
44      * or spaces. The first group is 1-5 characters, second 1-7, third 1-6,
45      * and fourth is 1 digit or an X.
46      */

47     private static final String JavaDoc ISBN_PATTERN =
48         "/^" + GROUP + SEP + PUBLISHER + SEP + TITLE + SEP + CHECK + "$/";
49
50     public ISBNValidator() {
51         super();
52     }
53
54     /**
55      * If the ISBN is formatted with space or dash separators its format is
56      * validated. Then the digits in the number are weighted, summed, and
57      * divided by 11 according to the ISBN algorithm. If the result is zero,
58      * the ISBN is valid. This method accepts formatted or raw ISBN codes.
59      *
60      * @param isbn Candidate ISBN number to be validated. <code>null</code> is
61      * considered invalid.
62      * @return true if the string is a valid ISBN code.
63      */

64     public boolean isValid(String JavaDoc isbn) {
65         if (isbn == null || isbn.length() < 10 || isbn.length() > 13) {
66             return false;
67         }
68
69         if (isFormatted(isbn) && !isValidPattern(isbn)) {
70             return false;
71         }
72
73         isbn = clean(isbn);
74         if (isbn.length() != 10) {
75             return false;
76         }
77
78         return (sum(isbn) % 11) == 0;
79     }
80     
81     /**
82      * Returns the sum of the weighted ISBN characters.
83      */

84     private int sum(String JavaDoc isbn) {
85         int total = 0;
86         for (int i = 0; i < 9; i++) {
87             int weight = 10 - i;
88             total += (weight * toInt(isbn.charAt(i)));
89         }
90         total += toInt(isbn.charAt(9)); // add check digit
91
return total;
92     }
93
94     /**
95      * Removes all non-digit characters except for 'X' which is a valid ISBN
96      * character.
97      */

98     private String JavaDoc clean(String JavaDoc isbn) {
99         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(10);
100         
101         for (int i = 0; i < isbn.length(); i++) {
102             char digit = isbn.charAt(i);
103             if (Character.isDigit(digit) || (digit == 'X')) {
104                 buf.append(digit);
105             }
106         }
107
108         return buf.toString();
109     }
110
111     /**
112      * Returns the numeric value represented by the character. If the
113      * character is not a digit but an 'X', 10 is returned.
114      */

115     private int toInt(char ch) {
116         return (ch == 'X') ? 10 : Character.getNumericValue(ch);
117     }
118     
119     /**
120      * Returns true if the ISBN contains one of the separator characters space
121      * or dash.
122      */

123     private boolean isFormatted(String JavaDoc isbn) {
124         return ((isbn.indexOf('-') != -1) || (isbn.indexOf(' ') != -1));
125     }
126
127     /**
128      * Returns true if the ISBN is formatted properly.
129      */

130     private boolean isValidPattern(String JavaDoc isbn) {
131         return new Perl5Util().match(ISBN_PATTERN, isbn);
132     }
133
134 }
135
Popular Tags