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; 018 019 import java.io.Serializable; 020 import java.util.Date; 021 import java.util.Locale; 022 import java.text.DateFormat; 023 import java.text.SimpleDateFormat; 024 import java.text.NumberFormat; 025 import java.text.ParseException; 026 import java.text.ParsePosition; 027 import org.apache.commons.logging.Log; 028 import org.apache.commons.logging.LogFactory; 029 030 /** 031 * This class contains basic methods for performing validations that return the 032 * correctly typed class based on the validation performed. 033 * 034 * @version $Revision: 493905 $ $Date: 2007-01-08 03:11:38 +0100 (Mo, 08. Jan 2007) $ 035 */ 036 public class GenericTypeValidator implements Serializable { 037 038 /** 039 * Checks if the value can safely be converted to a byte primitive. 040 * 041 *@param value The value validation is being performed on. 042 *@return the converted Byte value. 043 */ 044 public static Byte formatByte(String value) { 045 if (value == null) { 046 return null; 047 } 048 049 try { 050 return new Byte(value); 051 } catch (NumberFormatException e) { 052 return null; 053 } 054 055 } 056 057 /** 058 * Checks if the value can safely be converted to a byte primitive. 059 * 060 *@param value The value validation is being performed on. 061 *@param locale The locale to use to parse the number (system default if 062 * null) 063 *@return the converted Byte value. 064 */ 065 public static Byte formatByte(String value, Locale locale) { 066 Byte result = null; 067 068 if (value != null) { 069 NumberFormat formatter = null; 070 if (locale != null) { 071 formatter = NumberFormat.getNumberInstance(locale); 072 } else { 073 formatter = NumberFormat.getNumberInstance(Locale.getDefault()); 074 } 075 formatter.setParseIntegerOnly(true); 076 ParsePosition pos = new ParsePosition(0); 077 Number num = formatter.parse(value, pos); 078 079 // If there was no error and we used the whole string 080 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 081 if (num.doubleValue() >= Byte.MIN_VALUE && 082 num.doubleValue() <= Byte.MAX_VALUE) { 083 result = new Byte(num.byteValue()); 084 } 085 } 086 } 087 088 return result; 089 } 090 091 /** 092 * Checks if the value can safely be converted to a short primitive. 093 * 094 *@param value The value validation is being performed on. 095 *@return the converted Short value. 096 */ 097 public static Short formatShort(String value) { 098 if (value == null) { 099 return null; 100 } 101 102 try { 103 return new Short(value); 104 } catch (NumberFormatException e) { 105 return null; 106 } 107 108 } 109 110 /** 111 * Checks if the value can safely be converted to a short primitive. 112 * 113 *@param value The value validation is being performed on. 114 *@param locale The locale to use to parse the number (system default if 115 * null)vv 116 *@return the converted Short value. 117 */ 118 public static Short formatShort(String value, Locale locale) { 119 Short result = null; 120 121 if (value != null) { 122 NumberFormat formatter = null; 123 if (locale != null) { 124 formatter = NumberFormat.getNumberInstance(locale); 125 } else { 126 formatter = NumberFormat.getNumberInstance(Locale.getDefault()); 127 } 128 formatter.setParseIntegerOnly(true); 129 ParsePosition pos = new ParsePosition(0); 130 Number num = formatter.parse(value, pos); 131 132 // If there was no error and we used the whole string 133 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 134 if (num.doubleValue() >= Short.MIN_VALUE && 135 num.doubleValue() <= Short.MAX_VALUE) { 136 result = new Short(num.shortValue()); 137 } 138 } 139 } 140 141 return result; 142 } 143 144 /** 145 * Checks if the value can safely be converted to a int primitive. 146 * 147 *@param value The value validation is being performed on. 148 *@return the converted Integer value. 149 */ 150 public static Integer formatInt(String value) { 151 if (value == null) { 152 return null; 153 } 154 155 try { 156 return new Integer(value); 157 } catch (NumberFormatException e) { 158 return null; 159 } 160 161 } 162 163 /** 164 * Checks if the value can safely be converted to an int primitive. 165 * 166 *@param value The value validation is being performed on. 167 *@param locale The locale to use to parse the number (system default if 168 * null) 169 *@return the converted Integer value. 170 */ 171 public static Integer formatInt(String value, Locale locale) { 172 Integer result = null; 173 174 if (value != null) { 175 NumberFormat formatter = null; 176 if (locale != null) { 177 formatter = NumberFormat.getNumberInstance(locale); 178 } else { 179 formatter = NumberFormat.getNumberInstance(Locale.getDefault()); 180 } 181 formatter.setParseIntegerOnly(true); 182 ParsePosition pos = new ParsePosition(0); 183 Number num = formatter.parse(value, pos); 184 185 // If there was no error and we used the whole string 186 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 187 if (num.doubleValue() >= Integer.MIN_VALUE && 188 num.doubleValue() <= Integer.MAX_VALUE) { 189 result = new Integer(num.intValue()); 190 } 191 } 192 } 193 194 return result; 195 } 196 197 /** 198 * Checks if the value can safely be converted to a long primitive. 199 * 200 *@param value The value validation is being performed on. 201 *@return the converted Long value. 202 */ 203 public static Long formatLong(String value) { 204 if (value == null) { 205 return null; 206 } 207 208 try { 209 return new Long(value); 210 } catch (NumberFormatException e) { 211 return null; 212 } 213 214 } 215 216 /** 217 * Checks if the value can safely be converted to a long primitive. 218 * 219 *@param value The value validation is being performed on. 220 *@param locale The locale to use to parse the number (system default if 221 * null) 222 *@return the converted Long value. 223 */ 224 public static Long formatLong(String value, Locale locale) { 225 Long result = null; 226 227 if (value != null) { 228 NumberFormat formatter = null; 229 if (locale != null) { 230 formatter = NumberFormat.getNumberInstance(locale); 231 } else { 232 formatter = NumberFormat.getNumberInstance(Locale.getDefault()); 233 } 234 formatter.setParseIntegerOnly(true); 235 ParsePosition pos = new ParsePosition(0); 236 Number num = formatter.parse(value, pos); 237 238 // If there was no error and we used the whole string 239 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 240 if (num.doubleValue() >= Long.MIN_VALUE && 241 num.doubleValue() <= Long.MAX_VALUE) { 242 result = new Long(num.longValue()); 243 } 244 } 245 } 246 247 return result; 248 } 249 250 /** 251 * Checks if the value can safely be converted to a float primitive. 252 * 253 *@param value The value validation is being performed on. 254 *@return the converted Float value. 255 */ 256 public static Float formatFloat(String value) { 257 if (value == null) { 258 return null; 259 } 260 261 try { 262 return new Float(value); 263 } catch (NumberFormatException e) { 264 return null; 265 } 266 267 } 268 269 /** 270 * Checks if the value can safely be converted to a float primitive. 271 * 272 *@param value The value validation is being performed on. 273 *@param locale The locale to use to parse the number (system default if 274 * null) 275 *@return the converted Float value. 276 */ 277 public static Float formatFloat(String value, Locale locale) { 278 Float result = null; 279 280 if (value != null) { 281 NumberFormat formatter = null; 282 if (locale != null) { 283 formatter = NumberFormat.getInstance(locale); 284 } else { 285 formatter = NumberFormat.getInstance(Locale.getDefault()); 286 } 287 ParsePosition pos = new ParsePosition(0); 288 Number num = formatter.parse(value, pos); 289 290 // If there was no error and we used the whole string 291 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 292 if (num.doubleValue() >= (Float.MAX_VALUE * -1) && 293 num.doubleValue() <= Float.MAX_VALUE) { 294 result = new Float(num.floatValue()); 295 } 296 } 297 } 298 299 return result; 300 } 301 302 /** 303 * Checks if the value can safely be converted to a double primitive. 304 * 305 *@param value The value validation is being performed on. 306 *@return the converted Double value. 307 */ 308 public static Double formatDouble(String value) { 309 if (value == null) { 310 return null; 311 } 312 313 try { 314 return new Double(value); 315 } catch (NumberFormatException e) { 316 return null; 317 } 318 319 } 320 321 /** 322 * Checks if the value can safely be converted to a double primitive. 323 * 324 *@param value The value validation is being performed on. 325 *@param locale The locale to use to parse the number (system default if 326 * null) 327 *@return the converted Double value. 328 */ 329 public static Double formatDouble(String value, Locale locale) { 330 Double result = null; 331 332 if (value != null) { 333 NumberFormat formatter = null; 334 if (locale != null) { 335 formatter = NumberFormat.getInstance(locale); 336 } else { 337 formatter = NumberFormat.getInstance(Locale.getDefault()); 338 } 339 ParsePosition pos = new ParsePosition(0); 340 Number num = formatter.parse(value, pos); 341 342 // If there was no error and we used the whole string 343 if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length()) { 344 if (num.doubleValue() >= (Double.MAX_VALUE * -1) && 345 num.doubleValue() <= Double.MAX_VALUE) { 346 result = new Double(num.doubleValue()); 347 } 348 } 349 } 350 351 return result; 352 } 353 354 /** 355 * <p> 356 * 357 * Checks if the field is a valid date. The <code>Locale</code> is used 358 * with <code>java.text.DateFormat</code>. The setLenient method is set to 359 * <code>false</code> for all.</p> 360 * 361 *@param value The value validation is being performed on. 362 *@param locale The Locale to use to parse the date (system default if 363 * null) 364 *@return the converted Date value. 365 */ 366 public static Date formatDate(String value, Locale locale) { 367 Date date = null; 368 369 if (value == null) { 370 return null; 371 } 372 373 try { 374 DateFormat formatter = null; 375 if (locale != null) { 376 formatter = 377 DateFormat.getDateInstance(DateFormat.SHORT, locale); 378 } else { 379 formatter = 380 DateFormat.getDateInstance( 381 DateFormat.SHORT, 382 Locale.getDefault()); 383 } 384 385 formatter.setLenient(false); 386 387 date = formatter.parse(value); 388 } catch (ParseException e) { 389 // Bad date so return null 390 Log log = LogFactory.getLog(GenericTypeValidator.class); 391 if (log.isDebugEnabled()) { 392 log.debug("Date parse failed value=[" + value + "], " + 393 "locale=[" + locale + "] " + e); 394 } 395 } 396 397 return date; 398 } 399 400 /** 401 * <p> 402 * Checks if the field is a valid date. The pattern is used with <code>java.text.SimpleDateFormat</code> 403 * . If strict is true, then the length will be checked so '2/12/1999' will 404 * not pass validation with the format 'MM/dd/yyyy' because the month isn't 405 * two digits. The setLenient method is set to <code>false</code> for all. 406 * </p> 407 * 408 *@param value The value validation is being performed on. 409 *@param datePattern The pattern passed to <code>SimpleDateFormat</code>. 410 *@param strict Whether or not to have an exact match of the 411 * datePattern. 412 *@return the converted Date value. 413 */ 414 public static Date formatDate(String value, String datePattern, boolean strict) { 415 Date date = null; 416 417 if (value == null 418 || datePattern == null 419 || datePattern.length() == 0) { 420 return null; 421 } 422 423 try { 424 SimpleDateFormat formatter = new SimpleDateFormat(datePattern); 425 formatter.setLenient(false); 426 427 date = formatter.parse(value); 428 429 if (strict) { 430 if (datePattern.length() != value.length()) { 431 date = null; 432 } 433 } 434 } catch (ParseException e) { 435 // Bad date so return null 436 Log log = LogFactory.getLog(GenericTypeValidator.class); 437 if (log.isDebugEnabled()) { 438 log.debug("Date parse failed value=[" + value + "], " + 439 "pattern=[" + datePattern + "], " + 440 "strict=[" + strict + "] " + e); 441 } 442 } 443 444 return date; 445 } 446 447 /** 448 * <p> 449 * Checks if the field is a valid credit card number.</p> <p> 450 * 451 * Reference Sean M. Burke's <a href="http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl"> 452 * script</a> .</p> 453 * 454 *@param value The value validation is being performed on. 455 *@return the converted Credit Card number. 456 */ 457 public static Long formatCreditCard(String value) { 458 return GenericValidator.isCreditCard(value) ? new Long(value) : null; 459 } 460 461 } 462