Coverage Report - org.apache.commons.validator.routines.ISSNValidator
 
Classes in this File Line Coverage Branch Coverage Complexity
ISSNValidator
88%
16/18
100%
6/6
3
 
 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;
 18  
 
 19  
 import java.io.Serializable;
 20  
 
 21  
 import org.apache.commons.validator.routines.checkdigit.CheckDigitException;
 22  
 import org.apache.commons.validator.routines.checkdigit.EAN13CheckDigit;
 23  
 import org.apache.commons.validator.routines.checkdigit.ISSNCheckDigit;
 24  
 
 25  
 /**
 26  
  * International Standard Serial Number (ISSN)
 27  
  * is an eight-digit serial number used to
 28  
  * uniquely identify a serial publication.
 29  
  * <pre>
 30  
  * The format is:
 31  
  * 
 32  
  * ISSN dddd-dddC
 33  
  * where:
 34  
  * d = decimal digit (0-9)
 35  
  * C = checksum (0-9 or X)
 36  
  * 
 37  
  * The checksum is formed by adding the first 7 digits multiplied by
 38  
  * the position in the entire number (counting from the right).
 39  
  * 
 40  
  * For example, abcd-efg would be 8a + 7b + 6c + 5d + 4e +3f +2g.
 41  
  * The check digit is modulus 11, where the value 10 is represented by 'X'
 42  
  * For example:
 43  
  * ISSN 0317-8471
 44  
  * ISSN 1050-124X
 45  
  *
 46  
  * This class strips off the 'ISSN ' prefix if it is present before passing
 47  
  * the remainder to the checksum routine.
 48  
  * 
 49  
  * </pre>
 50  
  * <p>
 51  
  * Note: the {@link #isValid(String)} and {@link #validate(String)} methods strip off any leading
 52  
  * or trailing spaces before doing the validation.
 53  
  * To ensure that only a valid code (without 'ISSN ' prefix) is passed to a method,
 54  
  * use the following code:
 55  
  * <pre>
 56  
  * Object valid = validator.validate(input); 
 57  
  * if (valid != null) {
 58  
  *    some_method(valid.toString());
 59  
  * }
 60  
  * </pre>
 61  
  * @since 1.5.0
 62  
  */
 63  1
 public class ISSNValidator implements Serializable {
 64  
 
 65  
     private static final long serialVersionUID = 4319515687976420405L;
 66  
 
 67  
     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
 68  
 
 69  1
     private static final CodeValidator VALIDATOR = new CodeValidator(ISSN_REGEX, 8, ISSNCheckDigit.ISSN_CHECK_DIGIT);
 70  
 
 71  
     /** ISSN Code Validator */
 72  1
     private static final ISSNValidator ISSN_VALIDATOR = new ISSNValidator();
 73  
 
 74  
     /**
 75  
      * Return a singleton instance of the ISSN validator
 76  
      *
 77  
      * @return A singleton instance of the ISSN validator.
 78  
      */
 79  
     public static ISSNValidator getInstance() {
 80  1
         return ISSN_VALIDATOR;
 81  
     }
 82  
 
 83  
     /**
 84  
      * Check the code is a valid ISSN code after any transformation
 85  
      * by the validate routine.
 86  
      * @param code The code to validate.
 87  
      * @return <code>true</code> if a valid ISSN
 88  
      * code, otherwise <code>false</code>.
 89  
      */
 90  
     public boolean isValid(String code) {
 91  26
         return VALIDATOR.isValid(code);
 92  
     }
 93  
 
 94  
     /**
 95  
      * Check the code is valid ISSN code.
 96  
      * <p>
 97  
      * If valid, this method returns the ISSN code with
 98  
      * the 'ISSN ' prefix removed (if it was present)
 99  
      *
 100  
      * @param code The code to validate.
 101  
      * @return A valid ISSN code if valid, otherwise <code>null</code>.
 102  
      */
 103  
     public Object validate(String code) {
 104  18
         return VALIDATOR.validate(code);
 105  
     }
 106  
 
 107  
     /**
 108  
      * Convert an ISSN code to an EAN-13 code.
 109  
      * <p>
 110  
      * This method requires a valid ISSN code.
 111  
      * It may contain a leading 'ISSN ' prefix,
 112  
      * as the input is passed through the {@link #validate(String)}
 113  
      * method.
 114  
      *
 115  
      * @param issn The ISSN code to convert
 116  
      * @param suffix the two digit suffix, e.g. "00" 
 117  
      * @return A converted EAN-13 code or <code>null</code>
 118  
      * if the input ISSN code is not valid
 119  
      */
 120  
     public String convertToEAN13(String issn, String suffix) {
 121  
 
 122  24
         if (suffix == null || !suffix.matches("\\d\\d")) {
 123  6
             throw new IllegalArgumentException("Suffix must be two digits: '" + suffix + "'");            
 124  
         }
 125  
 
 126  18
         Object result = validate(issn);
 127  18
         if (result == null) {
 128  1
             return null;
 129  
         }
 130  
 
 131  
         // Calculate the new EAN-13 code
 132  17
         final String input = result.toString();
 133  17
         String ean13 = "977" + input.substring(0, input.length() -1) + suffix;
 134  
         try {
 135  17
             String checkDigit = EAN13CheckDigit.EAN13_CHECK_DIGIT.calculate(ean13);
 136  17
             ean13 += checkDigit;
 137  17
             return ean13;
 138  0
         } catch (CheckDigitException e) { // Should not happen
 139  0
             throw new IllegalArgumentException("Check digit error for '" + ean13 + "' - " + e.getMessage());
 140  
         }
 141  
 
 142  
     }
 143  
 }