1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.validator.routines.checkdigit;
18
19 import java.io.Serializable;
20
21 /**
22 * Combined <b>ISBN-10</b> / <b>ISBN-13</b> Check Digit calculation/validation.
23 * <p>
24 * This implementation validates/calculates ISBN check digits
25 * based on the length of the code passed to it - delegating
26 * either to the {@link ISBNCheckDigit#ISBN10_CHECK_DIGIT} or the
27 * {@link ISBNCheckDigit#ISBN13_CHECK_DIGIT} routines to perform the actual
28 * validation/calculation.
29 * <p>
30 * <b>N.B.</b> From 1st January 2007 the book industry will start to use a new 13 digit
31 * ISBN number (rather than this 10 digit ISBN number) which uses the EAN-13 / UPC
32 * standard.
33 *
34 * @version $Revision: 1227719 $ $Date: 2012-01-05 12:45:51 -0500 (Thu, 05 Jan 2012) $
35 * @since Validator 1.4
36 */
37 public final class ISBNCheckDigit implements CheckDigit, Serializable {
38
39 private static final long serialVersionUID = 1391849166205184558L;
40
41 /** Singleton ISBN-10 Check Digit instance */
42 public static final CheckDigit ISBN10_CHECK_DIGIT = ISBN10CheckDigit.ISBN10_CHECK_DIGIT;
43
44 /** Singleton ISBN-13 Check Digit instance */
45 public static final CheckDigit ISBN13_CHECK_DIGIT = EAN13CheckDigit.EAN13_CHECK_DIGIT;
46
47 /** Singleton combined ISBN-10 / ISBN-13 Check Digit instance */
48 public static final CheckDigit ISBN_CHECK_DIGIT = new ISBNCheckDigit();
49
50 /**
51 * Calculate an ISBN-10 or ISBN-13 check digit, depending
52 * on the length of the code.
53 * <p>
54 * If the length of the code is 9, it is treated as an ISBN-10
55 * code or if the length of the code is 12, it is treated as an ISBN-13
56 * code.
57 *
58 * @param code The ISBN code to validate (should have a length of
59 * 9 or 12)
60 * @return The ISBN-10 check digit if the length is 9 or an ISBN-13
61 * check digit if the length is 12.
62 * @throws CheckDigitException if the code is missing, or an invalid
63 * length (i.e. not 9 or 12) or if there is an error calculating the
64 * check digit.
65 */
66 public String calculate(String code) throws CheckDigitException {
67 if (code == null || code.length() == 0) {
68 throw new CheckDigitException("ISBN Code is missing");
69 } else if (code.length() == 9) {
70 return ISBN10_CHECK_DIGIT.calculate(code);
71 } else if (code.length() == 12) {
72 return ISBN13_CHECK_DIGIT.calculate(code);
73 } else {
74 throw new CheckDigitException("Invalid ISBN Length = " + code.length());
75 }
76 }
77
78 /**
79 * <p>Validate an ISBN-10 or ISBN-13 check digit, depending
80 * on the length of the code.</p>
81 * <p>
82 * If the length of the code is 10, it is treated as an ISBN-10
83 * code or ff the length of the code is 13, it is treated as an ISBN-13
84 * code.
85 *
86 * @param code The ISBN code to validate (should have a length of
87 * 10 or 13)
88 * @return <code>true</code> if the code has a length of 10 and is
89 * a valid ISBN-10 check digit or the code has a length of 13 and is
90 * a valid ISBN-13 check digit - otherwise <code>false</code>.
91 */
92 public boolean isValid(String code) {
93 if (code == null) {
94 return false;
95 } else if (code.length() == 10) {
96 return ISBN10_CHECK_DIGIT.isValid(code);
97 } else if (code.length() == 13) {
98 return ISBN13_CHECK_DIGIT.isValid(code);
99 } else {
100 return false;
101 }
102 }
103
104 }