001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.validator.routines; 018 019 import java.io.Serializable; 020 021 import org.apache.commons.validator.routines.checkdigit.CheckDigit; 022 023 /** 024 * Generic <b>Code Validation</b> providing format, minimum/maximum 025 * length and {@link CheckDigit} validations. 026 * <p> 027 * Performs the following validations on a code: 028 * <ul> 029 * <li>Check the <i>format</i> of the code using a <i>regular expression.</i> (if specified)</li> 030 * <li>Check the <i>minimum</i> and <i>maximum</i> length (if specified) of the <i>parsed</i> code 031 * (i.e. parsed by the <i>regular expression</i>).</li> 032 * <li>Performs {@link CheckDigit} validation on the parsed code (if specified).</li> 033 * </ul> 034 * <p> 035 * Configure the validator with the appropriate regular expression, minimum/maximum length 036 * and {@link CheckDigit} validator and then call one of the two validation 037 * methods provided:</p> 038 * <ul> 039 * <li><code>boolean isValid(code)</code></li> 040 * <li><code>String validate(code)</code></li> 041 * </ul> 042 * <p> 043 * Codes often include <i>format</i> characters - such as hyphens - to make them 044 * more easily human readable. These can be removed prior to length and check digit 045 * validation by specifying them as a <i>non-capturing</i> group in the regular 046 * expression (i.e. use the <code>(?: )</code> notation). 047 * 048 * @version $Revision: 591497 $ $Date: 2007-11-02 23:25:16 +0100 (Fr, 02. Nov 2007) $ 049 * @since Validator 1.4 050 */ 051 public final class CodeValidator implements Serializable { 052 053 private final RegexValidator regexValidator; 054 private final int minLength; 055 private final int maxLength; 056 private final CheckDigit checkdigit; 057 058 /** 059 * Construct a code validator with a specified regular 060 * expression and {@link CheckDigit}. 061 * 062 * @param regex The format regular expression 063 * @param checkdigit The check digit validation routine 064 */ 065 public CodeValidator(String regex, CheckDigit checkdigit) { 066 this(regex, -1, -1, checkdigit); 067 } 068 069 /** 070 * Construct a code validator with a specified regular 071 * expression, length and {@link CheckDigit}. 072 * 073 * @param regex The format regular expression. 074 * @param length The length of the code 075 * (sets the mimimum/maximum to the same) 076 * @param checkdigit The check digit validation routine 077 */ 078 public CodeValidator(String regex, int length, CheckDigit checkdigit) { 079 this(regex, length, length, checkdigit); 080 } 081 082 /** 083 * Construct a code validator with a specified regular 084 * expression, minimum/maximum length and {@link CheckDigit} validation. 085 * 086 * @param regex The regular expression validator 087 * @param minLength The minimum length of the code 088 * @param maxLength The maximum length of the code 089 * @param checkdigit The check digit validation routine 090 */ 091 public CodeValidator(String regex, int minLength, int maxLength, 092 CheckDigit checkdigit) { 093 if (regex != null && regex.length() > 0) { 094 this.regexValidator = new RegexValidator(regex); 095 } else { 096 this.regexValidator = null; 097 } 098 this.minLength = minLength; 099 this.maxLength = maxLength; 100 this.checkdigit = checkdigit; 101 } 102 103 /** 104 * Construct a code validator with a specified regular expression, 105 * validator and {@link CheckDigit} validation. 106 * 107 * @param regexValidator The format regular expression validator 108 * @param checkdigit The check digit validation routine. 109 */ 110 public CodeValidator(RegexValidator regexValidator, CheckDigit checkdigit) { 111 this(regexValidator, -1, -1, checkdigit); 112 } 113 114 /** 115 * Construct a code validator with a specified regular expression, 116 * validator, length and {@link CheckDigit} validation. 117 * 118 * @param regexValidator The format regular expression validator 119 * @param length The length of the code 120 * (sets the mimimum/maximum to the same value) 121 * @param checkdigit The check digit validation routine 122 */ 123 public CodeValidator(RegexValidator regexValidator, int length, CheckDigit checkdigit) { 124 this(regexValidator, length, length, checkdigit); 125 } 126 127 /** 128 * Construct a code validator with a specified regular expression 129 * validator, minimum/maximum length and {@link CheckDigit} validation. 130 * 131 * @param regexValidator The format regular expression validator 132 * @param minLength The minimum length of the code 133 * @param maxLength The maximum length of the code 134 * @param checkdigit The check digit validation routine 135 */ 136 public CodeValidator(RegexValidator regexValidator, int minLength, int maxLength, 137 CheckDigit checkdigit) { 138 this.regexValidator = regexValidator; 139 this.minLength = minLength; 140 this.maxLength = maxLength; 141 this.checkdigit = checkdigit; 142 } 143 144 /** 145 * Return the check digit validation routine. 146 * <p> 147 * <b>N.B.</b> Optional, if not set no Check Digit 148 * validation will be performed on the code. 149 * 150 * @return The check digit validation routine 151 */ 152 public CheckDigit getCheckDigit() { 153 return checkdigit; 154 } 155 156 /** 157 * Return the minimum length of the code. 158 * <p> 159 * <b>N.B.</b> Optional, if less than zero the 160 * minimum length will not be checked. 161 * 162 * @return The minimum length of the code or 163 * <code>-1</code> if the code has no minimum length 164 */ 165 public int getMinLength() { 166 return minLength; 167 } 168 169 /** 170 * Return the maximum length of the code. 171 * <p> 172 * <b>N.B.</b> Optional, if less than zero the 173 * maximum length will not be checked. 174 * 175 * @return The maximum length of the code or 176 * <code>-1</code> if the code has no maximum length 177 */ 178 public int getMaxLength() { 179 return maxLength; 180 } 181 182 /** 183 * Return the <i>regular expression</i> validator. 184 * <p> 185 * <b>N.B.</b> Optional, if not set no regular 186 * expression validation will be performed on the code. 187 * 188 * @return The regular expression validator 189 */ 190 public RegexValidator getRegexValidator() { 191 return regexValidator; 192 } 193 194 /** 195 * Validate the code returning either <code>true</code> 196 * or <code>false</code>. 197 * 198 * @param input The code to validate 199 * @return <code>true</code> if valid, otherwise 200 * <code>false</code> 201 */ 202 public boolean isValid(String input) { 203 return (validate(input) != null); 204 } 205 206 /** 207 * Validate the code returning either the valid code or 208 * <code>null</code> if invalid. 209 * 210 * @param input The code to validate 211 * @return The code if valid, otherwise <code>null</code> 212 * if invalid 213 */ 214 public Object validate(String input) { 215 216 String code = (input == null ? null : input.trim()); 217 if (code != null && code.length() == 0) { 218 return null; 219 } 220 221 // validate/reformat using regular expression 222 if (regexValidator != null) { 223 code = regexValidator.validate(code); 224 if (code == null) { 225 return null; 226 } 227 } 228 229 // check the length 230 if ((minLength >= 0 && code.length() < minLength) || 231 (maxLength >= 0 && code.length() > maxLength)) { 232 return null; 233 } 234 235 // validate the check digit 236 if (checkdigit != null && !checkdigit.isValid(code)) { 237 return null; 238 } 239 240 return code; 241 242 } 243 244 }