1 21 22 package org.apache.commons.validator; 23 24 import java.io.Serializable ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.StringTokenizer ; 34 35 import org.apache.commons.beanutils.PropertyUtils; 36 import org.apache.commons.collections.FastHashMap; import org.apache.commons.validator.util.ValidatorUtils; 38 39 50 public class Field implements Cloneable , Serializable { 51 52 56 private static final String DEFAULT_ARG = 57 "org.apache.commons.validator.Field.DEFAULT"; 58 59 62 public static final String TOKEN_INDEXED = "[]"; 63 64 protected static final String TOKEN_START = "${"; 65 protected static final String TOKEN_END = "}"; 66 protected static final String TOKEN_VAR = "var:"; 67 68 protected String property = null; 69 protected String indexedProperty = null; 70 protected String indexedListProperty = null; 71 protected String key = null; 72 73 76 protected String depends = null; 77 78 protected int page = 0; 79 80 protected int fieldOrder = 0; 81 82 88 private List dependencyList = Collections.synchronizedList(new ArrayList ()); 89 90 93 protected FastHashMap hVars = new FastHashMap(); 94 95 98 protected FastHashMap hMsgs = new FastHashMap(); 99 100 106 protected Map [] args = new Map [0]; 107 108 112 public int getPage() { 113 return this.page; 114 } 115 116 120 public void setPage(int page) { 121 this.page = page; 122 } 123 124 127 public int getFieldOrder() { 128 return this.fieldOrder; 129 } 130 131 134 public void setFieldOrder(int fieldOrder) { 135 this.fieldOrder = fieldOrder; 136 } 137 138 141 public String getProperty() { 142 return this.property; 143 } 144 145 148 public void setProperty(String property) { 149 this.property = property; 150 } 151 152 157 public String getIndexedProperty() { 158 return this.indexedProperty; 159 } 160 161 164 public void setIndexedProperty(String indexedProperty) { 165 this.indexedProperty = indexedProperty; 166 } 167 168 175 public String getIndexedListProperty() { 176 return this.indexedListProperty; 177 } 178 179 182 public void setIndexedListProperty(String indexedListProperty) { 183 this.indexedListProperty = indexedListProperty; 184 } 185 186 189 public String getDepends() { 190 return this.depends; 191 } 192 193 197 public void setDepends(String depends) { 198 this.depends = depends; 199 200 this.dependencyList.clear(); 201 202 StringTokenizer st = new StringTokenizer (depends, ","); 203 while (st.hasMoreTokens()) { 204 String depend = st.nextToken().trim(); 205 206 if (depend != null && depend.length() > 0) { 207 this.dependencyList.add(depend); 208 } 209 } 210 } 211 212 215 public void addMsg(Msg msg) { 216 hMsgs.put(msg.getName(), msg); 217 } 218 219 222 public String getMsg(String key) { 223 Msg msg = getMessage(key); 224 return (msg == null) ? null : msg.getKey(); 225 } 226 227 231 public Msg getMessage(String key) { 232 return (Msg) hMsgs.get(key); 233 } 234 235 240 public Map getMessages() { 241 return Collections.unmodifiableMap(hMsgs); 242 } 243 244 248 public void addArg(Arg arg) { 249 if (arg == null || arg.getKey() == null || arg.getKey().length() == 0) { 251 return; 252 } 253 254 determineArgPosition(arg); 255 ensureArgsCapacity(arg); 256 257 Map argMap = this.args[arg.getPosition()]; 258 if (argMap == null) { 259 argMap = new HashMap (); 260 this.args[arg.getPosition()] = argMap; 261 } 262 263 if (arg.getName() == null) { 264 argMap.put(DEFAULT_ARG, arg); 265 } else { 266 argMap.put(arg.getName(), arg); 267 } 268 269 } 270 271 274 private void determineArgPosition(Arg arg) { 275 276 int position = arg.getPosition(); 277 278 if (position >= 0) { 280 return; 281 } 282 283 if (args == null || args.length == 0) { 285 arg.setPosition(0); 286 return; 287 } 288 289 String key = arg.getName() == null ? DEFAULT_ARG : arg.getName(); 292 int lastPosition = -1; 293 int lastDefault = -1; 294 for (int i = 0; i < args.length; i++) { 295 if (args[i] != null && args[i].containsKey(key)) { 296 lastPosition = i; 297 } 298 if (args[i] != null && args[i].containsKey(DEFAULT_ARG)) { 299 lastDefault = i; 300 } 301 } 302 303 if (lastPosition < 0) { 304 lastPosition = lastDefault; 305 } 306 307 arg.setPosition(++lastPosition); 309 310 } 311 312 318 private void ensureArgsCapacity(Arg arg) { 319 if (arg.getPosition() >= this.args.length) { 320 Map [] newArgs = new Map [arg.getPosition() + 1]; 321 System.arraycopy(this.args, 0, newArgs, 0, this.args.length); 322 this.args = newArgs; 323 } 324 } 325 326 331 public Arg getArg(int position) { 332 return this.getArg(DEFAULT_ARG, position); 333 } 334 335 345 public Arg getArg(String key, int position) { 346 if ((position >= this.args.length) || (this.args[position] == null)) { 347 return null; 348 } 349 350 Arg arg = (Arg) args[position].get(key); 351 352 if ((arg == null) && key.equals(DEFAULT_ARG)) { 355 return null; 356 } 357 358 return (arg == null) ? this.getArg(position) : arg; 359 } 360 361 368 public Arg[] getArgs(String key){ 369 Arg[] args = new Arg[this.args.length]; 370 371 for (int i = 0; i < this.args.length; i++) { 372 args[i] = this.getArg(key, i); 373 } 374 375 return args; 376 } 377 378 381 public void addVar(Var v) { 382 this.hVars.put(v.getName(), v); 383 } 384 385 392 public void addVar(String name, String value, String jsType) { 393 this.addVar(new Var(name, value, jsType)); 394 } 395 396 400 public Var getVar(String mainKey) { 401 return (Var) hVars.get(mainKey); 402 } 403 404 408 public String getVarValue(String mainKey) { 409 String value = null; 410 411 Object o = hVars.get(mainKey); 412 if (o != null && o instanceof Var) { 413 Var v = (Var) o; 414 value = v.getValue(); 415 } 416 417 return value; 418 } 419 420 424 public Map getVars() { 425 return Collections.unmodifiableMap(hVars); 426 } 427 428 431 public String getKey() { 432 if (this.key == null) { 433 this.generateKey(); 434 } 435 436 return this.key; 437 } 438 439 444 public void setKey(String key) { 445 this.key = key; 446 } 447 448 453 public boolean isIndexed() { 454 return ((indexedListProperty != null && indexedListProperty.length() > 0)); 455 } 456 457 460 public void generateKey() { 461 if (this.isIndexed()) { 462 this.key = this.indexedListProperty + TOKEN_INDEXED + "." + this.property; 463 } else { 464 this.key = this.property; 465 } 466 } 467 468 472 void process(Map globalConstants, Map constants) { 473 this.hMsgs.setFast(false); 474 this.hVars.setFast(true); 475 476 this.generateKey(); 477 478 for (Iterator i = constants.keySet().iterator(); i.hasNext();) { 480 String key = (String ) i.next(); 481 String key2 = TOKEN_START + key + TOKEN_END; 482 String replaceValue = (String ) constants.get(key); 483 484 property = ValidatorUtils.replace(property, key2, replaceValue); 485 486 processVars(key2, replaceValue); 487 488 this.processMessageComponents(key2, replaceValue); 489 } 490 491 for (Iterator i = globalConstants.keySet().iterator(); i.hasNext();) { 493 String key = (String ) i.next(); 494 String key2 = TOKEN_START + key + TOKEN_END; 495 String replaceValue = (String ) globalConstants.get(key); 496 497 property = ValidatorUtils.replace(property, key2, replaceValue); 498 499 processVars(key2, replaceValue); 500 501 this.processMessageComponents(key2, replaceValue); 502 } 503 504 for (Iterator i = hVars.keySet().iterator(); i.hasNext();) { 506 String key = (String ) i.next(); 507 String key2 = TOKEN_START + TOKEN_VAR + key + TOKEN_END; 508 Var var = this.getVar(key); 509 String replaceValue = var.getValue(); 510 511 this.processMessageComponents(key2, replaceValue); 512 } 513 514 hMsgs.setFast(true); 515 } 516 517 520 private void processVars(String key, String replaceValue) { 521 Iterator i = this.hVars.keySet().iterator(); 522 while (i.hasNext()) { 523 String varKey = (String ) i.next(); 524 Var var = this.getVar(varKey); 525 526 var.setValue(ValidatorUtils.replace(var.getValue(), key, replaceValue)); 527 } 528 529 } 530 531 534 private void processMessageComponents(String key, String replaceValue) { 535 String varKey = TOKEN_START + TOKEN_VAR; 536 if (key != null && !key.startsWith(varKey)) { 538 for (Iterator i = hMsgs.values().iterator(); i.hasNext();) { 539 Msg msg = (Msg) i.next(); 540 msg.setKey(ValidatorUtils.replace(msg.getKey(), key, replaceValue)); 541 } 542 } 543 544 this.processArg(key, replaceValue); 545 } 546 547 551 private void processArg(String key, String replaceValue) { 552 for (int i = 0; i < this.args.length; i++) { 553 554 Map argMap = this.args[i]; 555 if (argMap == null) { 556 continue; 557 } 558 559 Iterator iter = argMap.values().iterator(); 560 while (iter.hasNext()) { 561 Arg arg = (Arg) iter.next(); 562 563 if (arg != null) { 564 arg.setKey( 565 ValidatorUtils.replace(arg.getKey(), key, replaceValue)); 566 } 567 } 568 } 569 } 570 571 574 public boolean isDependency(String validatorName) { 575 return this.dependencyList.contains(validatorName); 576 } 577 578 582 public List getDependencyList() { 583 return Collections.unmodifiableList(this.dependencyList); 584 } 585 586 589 public Object clone() { 590 Field field = null; 591 try { 592 field = (Field) super.clone(); 593 } catch(CloneNotSupportedException e) { 594 throw new RuntimeException (e.toString()); 595 } 596 597 field.args = new Map [this.args.length]; 598 for (int i = 0; i < this.args.length; i++) { 599 if (this.args[i] == null) { 600 continue; 601 } 602 603 Map argMap = new HashMap (this.args[i]); 604 Iterator iter = argMap.keySet().iterator(); 605 while (iter.hasNext()) { 606 String validatorName = (String ) iter.next(); 607 Arg arg = (Arg) argMap.get(validatorName); 608 argMap.put(validatorName, arg.clone()); 609 } 610 field.args[i] = argMap; 611 } 612 613 field.hVars = ValidatorUtils.copyFastHashMap(hVars); 614 field.hMsgs = ValidatorUtils.copyFastHashMap(hMsgs); 615 616 return field; 617 } 618 619 622 public String toString() { 623 StringBuffer results = new StringBuffer (); 624 625 results.append("\t\tkey = " + key + "\n"); 626 results.append("\t\tproperty = " + property + "\n"); 627 results.append("\t\tindexedProperty = " + indexedProperty + "\n"); 628 results.append("\t\tindexedListProperty = " + indexedListProperty + "\n"); 629 results.append("\t\tdepends = " + depends + "\n"); 630 results.append("\t\tpage = " + page + "\n"); 631 results.append("\t\tfieldOrder = " + fieldOrder + "\n"); 632 633 if (hVars != null) { 634 results.append("\t\tVars:\n"); 635 for (Iterator i = hVars.keySet().iterator(); i.hasNext();) { 636 Object key = i.next(); 637 results.append("\t\t\t"); 638 results.append(key); 639 results.append("="); 640 results.append(hVars.get(key)); 641 results.append("\n"); 642 } 643 } 644 645 return results.toString(); 646 } 647 648 655 Object [] getIndexedProperty(Object bean) throws ValidatorException { 656 Object indexedProperty = null; 657 658 try { 659 indexedProperty = 660 PropertyUtils.getProperty(bean, this.getIndexedListProperty()); 661 662 } catch(IllegalAccessException e) { 663 throw new ValidatorException(e.getMessage()); 664 } catch(InvocationTargetException e) { 665 throw new ValidatorException(e.getMessage()); 666 } catch(NoSuchMethodException e) { 667 throw new ValidatorException(e.getMessage()); 668 } 669 670 if (indexedProperty instanceof Collection ) { 671 return ((Collection ) indexedProperty).toArray(); 672 673 } else if (indexedProperty.getClass().isArray()) { 674 return (Object []) indexedProperty; 675 676 } else { 677 throw new ValidatorException(this.getKey() + " is not indexed"); 678 } 679 680 } 681 682 687 private boolean validateForRule( 688 ValidatorAction va, 689 ValidatorResults results, 690 Map actions, 691 Map params, 692 int pos) 693 throws ValidatorException { 694 695 ValidatorResult result = results.getValidatorResult(this.getKey()); 696 if (result != null && result.containsAction(va.getName())) { 697 return result.isValid(va.getName()); 698 } 699 700 if (!this.runDependentValidators(va, results, actions, params, pos)) { 701 return false; 702 } 703 704 return va.executeValidationMethod(this, params, results, pos); 705 } 706 707 717 private boolean runDependentValidators( 718 ValidatorAction va, 719 ValidatorResults results, 720 Map actions, 721 Map params, 722 int pos) 723 throws ValidatorException { 724 725 List dependentValidators = va.getDependencyList(); 726 727 if (dependentValidators.isEmpty()) { 728 return true; 729 } 730 731 Iterator iter = dependentValidators.iterator(); 732 while (iter.hasNext()) { 733 String depend = (String ) iter.next(); 734 735 ValidatorAction action = (ValidatorAction) actions.get(depend); 736 if (action == null) { 737 this.handleMissingAction(depend); 738 } 739 740 if (!this.validateForRule(action, results, actions, params, pos)) { 741 return false; 742 } 743 } 744 745 return true; 746 } 747 748 758 ValidatorResults validate(Map params, Map actions) 759 throws ValidatorException { 760 761 if (this.getDepends() == null) { 762 return new ValidatorResults(); 763 } 764 765 ValidatorResults allResults = new ValidatorResults(); 766 767 Object bean = params.get(Validator.BEAN_PARAM); 768 int numberOfFieldsToValidate = 769 this.isIndexed() ? this.getIndexedProperty(bean).length : 1; 770 771 for (int fieldNumber = 0; fieldNumber < numberOfFieldsToValidate; fieldNumber++) { 772 773 Iterator dependencies = this.dependencyList.iterator(); 774 while (dependencies.hasNext()) { 775 String depend = (String ) dependencies.next(); 776 777 ValidatorAction action = (ValidatorAction) actions.get(depend); 778 if (action == null) { 779 this.handleMissingAction(depend); 780 } 781 782 ValidatorResults results = new ValidatorResults(); 783 boolean good = 784 validateForRule(action, results, actions, params, fieldNumber); 785 786 allResults.merge(results); 787 788 if (!good) { 789 return allResults; 790 } 791 } 792 } 793 794 return allResults; 795 } 796 797 803 private void handleMissingAction(String name) throws ValidatorException { 804 throw new ValidatorException("No ValidatorAction named " + name 805 + " found for field " + this.getProperty()); 806 } 807 808 812 protected Map getMsgMap() { 813 return hMsgs; 814 } 815 816 820 protected Map getVarMap() { 821 return hVars; 822 } 823 824 } 825 826 | Popular Tags |