1 21 22 package org.apache.commons.validator; 23 24 import java.io.BufferedReader ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.InputStreamReader ; 28 import java.io.Serializable ; 29 import java.lang.reflect.InvocationTargetException ; 30 import java.lang.reflect.Method ; 31 import java.lang.reflect.Modifier ; 32 import java.util.ArrayList ; 33 import java.util.Collections ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.StringTokenizer ; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.apache.commons.validator.util.ValidatorUtils; 41 42 49 public class ValidatorAction implements Serializable { 50 51 54 private static final Log log = LogFactory.getLog(ValidatorAction.class); 55 56 59 private String name = null; 60 61 65 private String classname = null; 66 67 70 private Class validationClass = null; 71 72 76 private String method = null; 77 78 81 private Method validationMethod = null; 82 83 97 private String methodParams = 98 Validator.BEAN_PARAM 99 + "," 100 + Validator.VALIDATOR_ACTION_PARAM 101 + "," 102 + Validator.FIELD_PARAM; 103 104 107 private Class [] parameterClasses = null; 108 109 114 private String depends = null; 115 116 119 private String msg = null; 120 121 125 private String jsFunctionName = null; 126 127 131 private String jsFunction = null; 132 133 137 private String javascript = null; 138 139 144 private Object instance = null; 145 146 153 private List dependencyList = Collections.synchronizedList(new ArrayList ()); 154 155 159 private List methodParameterList = new ArrayList (); 160 161 164 public String getName() { 165 return name; 166 } 167 168 171 public void setName(String name) { 172 this.name = name; 173 } 174 175 178 public String getClassname() { 179 return classname; 180 } 181 182 185 public void setClassname(String classname) { 186 this.classname = classname; 187 } 188 189 192 public String getMethod() { 193 return method; 194 } 195 196 199 public void setMethod(String method) { 200 this.method = method; 201 } 202 203 206 public String getMethodParams() { 207 return methodParams; 208 } 209 210 214 public void setMethodParams(String methodParams) { 215 this.methodParams = methodParams; 216 217 this.methodParameterList.clear(); 218 219 StringTokenizer st = new StringTokenizer (methodParams, ","); 220 while (st.hasMoreTokens()) { 221 String value = st.nextToken().trim(); 222 223 if (value != null && value.length() > 0) { 224 this.methodParameterList.add(value); 225 } 226 } 227 } 228 229 233 public String getDepends() { 234 return this.depends; 235 } 236 237 241 public void setDepends(String depends) { 242 this.depends = depends; 243 244 this.dependencyList.clear(); 245 246 StringTokenizer st = new StringTokenizer (depends, ","); 247 while (st.hasMoreTokens()) { 248 String depend = st.nextToken().trim(); 249 250 if (depend != null && depend.length() > 0) { 251 this.dependencyList.add(depend); 252 } 253 } 254 } 255 256 259 public String getMsg() { 260 return msg; 261 } 262 263 266 public void setMsg(String msg) { 267 this.msg = msg; 268 } 269 270 275 public String getJsFunctionName() { 276 return jsFunctionName; 277 } 278 279 284 public void setJsFunctionName(String jsFunctionName) { 285 this.jsFunctionName = jsFunctionName; 286 } 287 288 313 public void setJsFunction(String jsFunction) { 314 if (javascript != null) { 315 throw new IllegalStateException ("Cannot call setJsFunction() after calling setJavascript()"); 316 } 317 318 this.jsFunction = jsFunction; 319 } 320 321 325 public String getJavascript() { 326 return javascript; 327 } 328 329 333 public void setJavascript(String javascript) { 334 if (jsFunction != null) { 335 throw new IllegalStateException ("Cannot call setJavascript() after calling setJsFunction()"); 336 } 337 338 this.javascript = javascript; 339 } 340 341 344 protected void init() { 345 this.loadJavascriptFunction(); 346 } 347 348 359 protected synchronized void loadJavascriptFunction() { 360 361 if (this.javascriptAlreadyLoaded()) { 362 return; 363 } 364 365 if (log.isTraceEnabled()) { 366 log.trace(" Loading function begun"); 367 } 368 369 if (this.jsFunction == null) { 370 this.jsFunction = this.generateJsFunction(); 371 } 372 373 String javascriptFileName = this.formatJavascriptFileName(); 374 375 if (log.isTraceEnabled()) { 376 log.trace(" Loading js function '" + javascriptFileName + "'"); 377 } 378 379 this.javascript = this.readJavascriptFile(javascriptFileName); 380 381 if (log.isTraceEnabled()) { 382 log.trace(" Loading javascript function completed"); 383 } 384 385 } 386 387 392 private String readJavascriptFile(String javascriptFileName) { 393 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 394 if (classLoader == null) { 395 classLoader = this.getClass().getClassLoader(); 396 } 397 398 InputStream is = classLoader.getResourceAsStream(javascriptFileName); 399 if (is == null) { 400 is = this.getClass().getResourceAsStream(javascriptFileName); 401 } 402 403 if (is == null) { 404 log.debug(" Unable to read javascript name "+javascriptFileName); 405 return null; 406 } 407 408 StringBuffer buffer = new StringBuffer (); 409 BufferedReader reader = new BufferedReader (new InputStreamReader (is)); 410 try { 411 String line = null; 412 while ((line = reader.readLine()) != null) { 413 buffer.append(line + "\n"); 414 } 415 416 } catch(IOException e) { 417 log.error("Error reading javascript file.", e); 418 419 } finally { 420 try { 421 reader.close(); 422 } catch(IOException e) { 423 log.error("Error closing stream to javascript file.", e); 424 } 425 } 426 427 String function = buffer.toString(); 428 return function.equals("") ? null : function; 429 } 430 431 435 private String formatJavascriptFileName() { 436 String name = this.jsFunction.substring(1); 437 438 if (!this.jsFunction.startsWith("/")) { 439 name = jsFunction.replace('.', '/') + ".js"; 440 } 441 442 return name; 443 } 444 445 448 private boolean javascriptAlreadyLoaded() { 449 return (this.javascript != null); 450 } 451 452 455 private String generateJsFunction() { 456 StringBuffer jsName = 457 new StringBuffer ("org.apache.commons.validator.javascript"); 458 459 jsName.append(".validate"); 460 jsName.append(name.substring(0, 1).toUpperCase()); 461 jsName.append(name.substring(1, name.length())); 462 463 return jsName.toString(); 464 } 465 466 469 public boolean isDependency(String validatorName) { 470 return this.dependencyList.contains(validatorName); 471 } 472 473 477 public List getDependencyList() { 478 return Collections.unmodifiableList(this.dependencyList); 479 } 480 481 484 public String toString() { 485 StringBuffer results = new StringBuffer ("ValidatorAction: "); 486 results.append(name); 487 results.append("\n"); 488 489 return results.toString(); 490 } 491 492 501 boolean executeValidationMethod( 502 Field field, 503 Map params, 504 ValidatorResults results, 505 int pos) 506 throws ValidatorException { 507 508 params.put(Validator.VALIDATOR_ACTION_PARAM, this); 509 510 try { 511 ClassLoader loader = this.getClassLoader(params); 512 this.loadValidationClass(loader); 513 this.loadParameterClasses(loader); 514 this.loadValidationMethod(); 515 516 Object [] paramValues = this.getParameterValues(params); 517 518 if (field.isIndexed()) { 519 this.handleIndexedField(field, pos, paramValues); 520 } 521 522 Object result = null; 523 try { 524 result = 525 validationMethod.invoke( 526 getValidationClassInstance(), 527 paramValues); 528 529 } catch (IllegalArgumentException e) { 530 throw new ValidatorException(e.getMessage()); 531 } catch (IllegalAccessException e) { 532 throw new ValidatorException(e.getMessage()); 533 } catch (InvocationTargetException e) { 534 535 if (e.getTargetException() instanceof Exception ) { 536 throw (Exception ) e.getTargetException(); 537 538 } else if (e.getTargetException() instanceof Error ) { 539 throw (Error ) e.getTargetException(); 540 } 541 } 542 543 boolean valid = this.isValid(result); 544 if (!valid || (valid && !onlyReturnErrors(params))) { 545 results.add(field, this.name, valid, result); 546 } 547 548 if (!valid) { 549 return false; 550 } 551 552 } catch (Exception e) { 555 if (e instanceof ValidatorException) { 556 throw (ValidatorException) e; 557 } 558 559 log.error( 560 "Unhandled exception thrown during validation: " + e.getMessage(), 561 e); 562 563 results.add(field, this.name, false); 564 return false; 565 } 566 567 return true; 568 } 569 570 574 private void loadValidationMethod() throws ValidatorException { 575 if (this.validationMethod != null) { 576 return; 577 } 578 579 try { 580 this.validationMethod = 581 this.validationClass.getMethod(this.method, this.parameterClasses); 582 583 } catch (NoSuchMethodException e) { 584 throw new ValidatorException("No such validation method: " + 585 e.getMessage()); 586 } 587 } 588 589 594 private void loadValidationClass(ClassLoader loader) 595 throws ValidatorException { 596 597 if (this.validationClass != null) { 598 return; 599 } 600 601 try { 602 this.validationClass = loader.loadClass(this.classname); 603 } catch (ClassNotFoundException e) { 604 throw new ValidatorException(e.getMessage()); 605 } 606 } 607 608 615 private void loadParameterClasses(ClassLoader loader) 616 throws ValidatorException { 617 618 if (this.parameterClasses != null) { 619 return; 620 } 621 622 this.parameterClasses = new Class [this.methodParameterList.size()]; 623 624 for (int i = 0; i < this.methodParameterList.size(); i++) { 625 String paramClassName = (String ) this.methodParameterList.get(i); 626 627 try { 628 this.parameterClasses[i] = loader.loadClass(paramClassName); 629 630 } catch (ClassNotFoundException e) { 631 throw new ValidatorException(e.getMessage()); 632 } 633 } 634 } 635 636 644 private Object [] getParameterValues(Map params) { 645 646 Object [] paramValue = new Object [this.methodParameterList.size()]; 647 648 for (int i = 0; i < this.methodParameterList.size(); i++) { 649 String paramClassName = (String ) this.methodParameterList.get(i); 650 paramValue[i] = params.get(paramClassName); 651 } 652 653 return paramValue; 654 } 655 656 660 private Object getValidationClassInstance() throws ValidatorException { 661 if (Modifier.isStatic(this.validationMethod.getModifiers())) { 662 this.instance = null; 663 664 } else { 665 if (this.instance == null) { 666 try { 667 this.instance = this.validationClass.newInstance(); 668 } catch (InstantiationException e) { 669 String msg = 670 "Couldn't create instance of " 671 + this.classname 672 + ". " 673 + e.getMessage(); 674 675 throw new ValidatorException(msg); 676 677 } catch (IllegalAccessException e) { 678 String msg = 679 "Couldn't create instance of " 680 + this.classname 681 + ". " 682 + e.getMessage(); 683 684 throw new ValidatorException(msg); 685 } 686 } 687 } 688 689 return this.instance; 690 } 691 692 699 private void handleIndexedField(Field field, int pos, Object [] paramValues) 700 throws ValidatorException { 701 702 int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM); 703 int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM); 704 705 Object indexedList[] = field.getIndexedProperty(paramValues[beanIndex]); 706 707 paramValues[beanIndex] = indexedList[pos]; 709 710 Field indexedField = (Field) field.clone(); 713 indexedField.setKey( 714 ValidatorUtils.replace( 715 indexedField.getKey(), 716 Field.TOKEN_INDEXED, 717 "[" + pos + "]")); 718 719 paramValues[fieldIndex] = indexedField; 720 } 721 722 727 private boolean isValid(Object result) { 728 if (result instanceof Boolean ) { 729 Boolean valid = (Boolean ) result; 730 return valid.booleanValue(); 731 } else { 732 return (result != null); 733 } 734 } 735 736 740 private ClassLoader getClassLoader(Map params) { 741 Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); 742 return v.getClassLoader(); 743 } 744 745 749 private boolean onlyReturnErrors(Map params) { 750 Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM); 751 return v.getOnlyReturnErrors(); 752 } 753 754 } 755 | Popular Tags |