View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/validator/src/share/org/apache/commons/validator/Field.java,v 1.31.2.1 2004/06/22 02:24:38 husted Exp $ 3 * $Revision: 1.31.2.1 $ 4 * $Date: 2004/06/22 02:24:38 $ 5 * 6 * ==================================================================== 7 * Copyright 2001-2004 The Apache Software Foundation 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 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; // DEPRECATED 37 import org.apache.commons.validator.util.ValidatorUtils; 38 39 /*** 40 * This contains the list of pluggable validators to run on a field and any 41 * message information and variables to perform the validations and generate 42 * error messages. Instances of this class are configured with a 43 * <field> xml element. 44 * 45 * The use of FastHashMap is deprecated and will be replaced in a future 46 * release. 47 * 48 * @see org.apache.commons.validator.Form 49 */ 50 public class Field implements Cloneable, Serializable { 51 52 /*** 53 * This is the value that will be used as a key if the <code>Arg</code> 54 * name field has no value. 55 */ 56 private static final String DEFAULT_ARG = 57 "org.apache.commons.validator.Field.DEFAULT"; 58 59 /*** 60 * This is the value that will be used as a key if the <code>Arg</code> 61 * name field has no value. 62 * @deprecated 63 */ 64 public static final String ARG_DEFAULT = DEFAULT_ARG; 65 66 /*** 67 * This indicates an indexed property is being referenced. 68 */ 69 public static final String TOKEN_INDEXED = "[]"; 70 71 protected static final String TOKEN_START = "${"; 72 protected static final String TOKEN_END = "}"; 73 protected static final String TOKEN_VAR = "var:"; 74 75 protected String property = null; 76 protected String indexedProperty = null; 77 protected String indexedListProperty = null; 78 protected String key = null; 79 80 /*** 81 * A comma separated list of validator's this field depends on. 82 */ 83 protected String depends = null; 84 85 protected int page = 0; 86 87 protected int fieldOrder = 0; 88 89 /*** 90 * @deprecated This is no longer used. 91 */ 92 protected FastHashMap hDependencies = new FastHashMap(); 93 94 /*** 95 * Internal representation of this.depends String as a List. This List 96 * gets updated whenever setDepends() gets called. This List is 97 * synchronized so a call to setDepends() (which clears the List) won't 98 * interfere with a call to isDependency(). 99 */ 100 private List dependencyList = Collections.synchronizedList(new ArrayList()); 101 102 protected FastHashMap hVars = new FastHashMap(); 103 104 protected FastHashMap hMsgs = new FastHashMap(); 105 106 /*** 107 * Holds Maps of arguments. args[0] returns the Map for the first 108 * replacement argument. Start with a 0 length array so that it will 109 * only grow to the size of the highest argument position. 110 * @since Validator 1.1 111 */ 112 protected Map[] args = new Map[0]; 113 114 /*** 115 * @deprecated This variable is no longer used, use args instead. 116 */ 117 protected FastHashMap hArg0 = new FastHashMap(); 118 119 /*** 120 * @deprecated This variable is no longer used, use args instead. 121 */ 122 protected FastHashMap hArg1 = new FastHashMap(); 123 124 /*** 125 * @deprecated This variable is no longer used, use args instead. 126 */ 127 protected FastHashMap hArg2 = new FastHashMap(); 128 129 /*** 130 * @deprecated This variable is no longer used, use args instead. 131 */ 132 protected FastHashMap hArg3 = new FastHashMap(); 133 134 /*** 135 * Gets the page value that the Field is associated with for 136 * validation. 137 */ 138 public int getPage() { 139 return this.page; 140 } 141 142 /*** 143 * Sets the page value that the Field is associated with for 144 * validation. 145 */ 146 public void setPage(int page) { 147 this.page = page; 148 } 149 150 /*** 151 * Gets the position of the <code>Field</code> in the validation list. 152 */ 153 public int getFieldOrder() { 154 return this.fieldOrder; 155 } 156 157 /*** 158 * Sets the position of the <code>Field</code> in the validation list. 159 */ 160 public void setFieldOrder(int fieldOrder) { 161 this.fieldOrder = fieldOrder; 162 } 163 164 /*** 165 * Gets the property name of the field. 166 */ 167 public String getProperty() { 168 return this.property; 169 } 170 171 /*** 172 * Sets the property name of the field. 173 */ 174 public void setProperty(String property) { 175 this.property = property; 176 } 177 178 /*** 179 * Gets the indexed property name of the field. This 180 * is the method name that can take an <code>int</code> as 181 * a parameter for indexed property value retrieval. 182 */ 183 public String getIndexedProperty() { 184 return this.indexedProperty; 185 } 186 187 /*** 188 * Sets the indexed property name of the field. 189 */ 190 public void setIndexedProperty(String indexedProperty) { 191 this.indexedProperty = indexedProperty; 192 } 193 194 /*** 195 * Gets the indexed property name of the field. This 196 * is the method name that will return an array or a 197 * <code>Collection</code> used to retrieve the 198 * list and then loop through the list performing the specified 199 * validations. 200 */ 201 public String getIndexedListProperty() { 202 return this.indexedListProperty; 203 } 204 205 /*** 206 * Sets the indexed property name of the field. 207 */ 208 public void setIndexedListProperty(String indexedListProperty) { 209 this.indexedListProperty = indexedListProperty; 210 } 211 212 /*** 213 * Gets the validation rules for this field as a comma separated list. 214 */ 215 public String getDepends() { 216 return this.depends; 217 } 218 219 /*** 220 * Sets the validation rules for this field as a comma separated list. 221 * @param depends A comma separated list of validator names. 222 */ 223 public void setDepends(String depends) { 224 this.depends = depends; 225 226 this.dependencyList.clear(); 227 228 StringTokenizer st = new StringTokenizer(depends, ","); 229 while (st.hasMoreTokens()) { 230 String depend = st.nextToken().trim(); 231 232 if (depend != null && depend.length() > 0) { 233 this.dependencyList.add(depend); 234 } 235 } 236 } 237 238 /*** 239 * Add a <code>Msg</code> to the <code>Field</code>. 240 */ 241 public void addMsg(Msg msg) { 242 hMsgs.put(msg.getName(), msg.getKey()); 243 } 244 245 /*** 246 * Retrieve a message value. 247 */ 248 public String getMsg(String key) { 249 return (String) hMsgs.get(key); 250 } 251 252 /*** 253 * Add an <code>Arg</code> to the replacement argument list. 254 * @since Validator 1.1 255 */ 256 public void addArg(Arg arg) { 257 // TODO this first if check can go away after arg0, etc. are removed from dtd 258 if (arg == null || arg.getKey() == null || arg.getKey().length() == 0) { 259 return; 260 } 261 262 this.ensureArgsCapacity(arg); 263 264 Map argMap = this.args[arg.getPosition()]; 265 if (argMap == null) { 266 argMap = new HashMap(); 267 this.args[arg.getPosition()] = argMap; 268 } 269 270 if (arg.getName() == null) { 271 argMap.put(DEFAULT_ARG, arg); 272 } else { 273 argMap.put(arg.getName(), arg); 274 } 275 276 } 277 278 /*** 279 * Ensures that the args array can hold the given arg. Resizes the array as 280 * necessary. 281 * @param arg Determine if the args array is long enough to store this arg's 282 * position. 283 */ 284 private void ensureArgsCapacity(Arg arg) { 285 if (arg.getPosition() >= this.args.length) { 286 Map[] newArgs = new Map[arg.getPosition() + 1]; 287 System.arraycopy(this.args, 0, newArgs, 0, this.args.length); 288 this.args = newArgs; 289 } 290 } 291 292 /*** 293 * Gets the default <code>Arg</code> object at the given position. 294 * @return The default Arg or null if not found. 295 * @since Validator 1.1 296 */ 297 public Arg getArg(int position) { 298 return this.getArg(DEFAULT_ARG, position); 299 } 300 301 /*** 302 * Gets the <code>Arg</code> object at the given position. If the key 303 * finds a <code>null</code> value then the default value will be 304 * retrieved. 305 * @param key The name the Arg is stored under. If not found, the default 306 * Arg for the given position (if any) will be retrieved. 307 * @param position The Arg number to find. 308 * @return The Arg with the given name and position or null if not found. 309 * @since Validator 1.1 310 */ 311 public Arg getArg(String key, int position) { 312 if ((position >= this.args.length) || (this.args[position] == null)) { 313 return null; 314 } 315 316 Arg arg = (Arg) args[position].get(key); 317 318 // Didn't find default arg so exit, otherwise we would get into 319 // infinite recursion 320 if ((arg == null) && key.equals(DEFAULT_ARG)) { 321 return null; 322 } 323 324 return (arg == null) ? this.getArg(position) : arg; 325 } 326 327 /*** 328 * Retrieves the Args for the given validator name. 329 * @param key The validator's args to retrieve. 330 * @return An Arg[] sorted by the Args' positions (i.e. the Arg at index 0 331 * has a position of 0). 332 * @since Validator 1.1.1 333 */ 334 public Arg[] getArgs(String key){ 335 Arg[] args = new Arg[this.args.length]; 336 337 for (int i = 0; i < this.args.length; i++) { 338 args[i] = this.getArg(key, i); 339 } 340 341 return args; 342 } 343 344 /*** 345 * Add a <code>Arg</code> to the arg0 list. 346 * @deprecated Use addArg(Arg) instead. 347 */ 348 public void addArg0(Arg arg) { 349 arg.setPosition(0); 350 this.addArg(arg); 351 } 352 353 /*** 354 * Gets the default arg0 <code>Arg</code> object. 355 * @deprecated Use getArg(0) instead. 356 */ 357 public Arg getArg0() { 358 return this.getArg(0); 359 } 360 361 /*** 362 * Gets the arg0 <code>Arg</code> object based on the key passed in. If 363 * the key finds a <code>null</code> value then the default value will 364 * be retrieved. 365 * @deprecated Use getArg(String, 0) instead. 366 */ 367 public Arg getArg0(String key) { 368 return this.getArg(key, 0); 369 } 370 371 /*** 372 * Add a <code>Arg</code> to the arg1 list. 373 * @deprecated Use addArg(Arg) instead. 374 */ 375 public void addArg1(Arg arg) { 376 arg.setPosition(1); 377 this.addArg(arg); 378 } 379 380 /*** 381 * Gets the default arg1 <code>Arg</code> object. 382 * @deprecated Use getArg(1) instead. 383 */ 384 public Arg getArg1() { 385 return this.getArg(1); 386 } 387 388 /*** 389 * Gets the arg1 <code>Arg</code> object based on the key passed in. If the key 390 * finds a <code>null</code> value then the default value will try to be retrieved. 391 * @deprecated Use getArg(String, 1) instead. 392 */ 393 public Arg getArg1(String key) { 394 return this.getArg(key, 1); 395 } 396 397 /*** 398 * Add a <code>Arg</code> to the arg2 list. 399 * @deprecated Use addArg(Arg) instead. 400 */ 401 public void addArg2(Arg arg) { 402 arg.setPosition(2); 403 this.addArg(arg); 404 } 405 406 /*** 407 * Gets the default arg2 <code>Arg</code> object. 408 * @deprecated Use getArg(2) instead. 409 */ 410 public Arg getArg2() { 411 return this.getArg(2); 412 } 413 414 /*** 415 * Gets the arg2 <code>Arg</code> object based on the key passed in. If the key 416 * finds a <code>null</code> value then the default value will try to be retrieved. 417 * @deprecated Use getArg(String, 2) instead. 418 */ 419 public Arg getArg2(String key) { 420 return this.getArg(key, 2); 421 } 422 423 /*** 424 * Add a <code>Arg</code> to the arg3 list. 425 * @deprecated Use addArg(Arg) instead. 426 */ 427 public void addArg3(Arg arg) { 428 arg.setPosition(3); 429 this.addArg(arg); 430 } 431 432 /*** 433 * Gets the default arg3 <code>Arg</code> object. 434 * @deprecated Use getArg(3) instead. 435 */ 436 public Arg getArg3() { 437 return this.getArg(3); 438 } 439 440 /*** 441 * Gets the arg3 <code>Arg</code> object based on the key passed in. If the key 442 * finds a <code>null</code> value then the default value will try to be retrieved. 443 * @deprecated Use getArg(String, 3) instead. 444 */ 445 public Arg getArg3(String key) { 446 return this.getArg(key, 3); 447 } 448 449 /*** 450 * Add a <code>Var</code> to the <code>Field</code>. 451 */ 452 public void addVar(Var v) { 453 this.hVars.put(v.getName(), v); 454 } 455 456 /*** 457 * Add a <code>Var</code>, based on the values passed in, to the 458 * <code>Field</code>. 459 * @deprecated Use addVar(String, String, String) instead. 460 */ 461 public void addVarParam(String name, String value, String jsType) { 462 this.addVar(new Var(name, value, jsType)); 463 } 464 465 /*** 466 * Add a <code>Var</code>, based on the values passed in, to the 467 * <code>Field</code>. 468 * @param name 469 * @param value 470 * @param jsType 471 */ 472 public void addVar(String name, String value, String jsType) { 473 this.addVar(new Var(name, value, jsType)); 474 } 475 476 /*** 477 * Retrieve a variable. 478 * @param mainKey 479 */ 480 public Var getVar(String mainKey) { 481 return (Var) hVars.get(mainKey); 482 } 483 484 /*** 485 * Retrieve a variable's value. 486 * @param mainKey 487 */ 488 public String getVarValue(String mainKey) { 489 String value = null; 490 491 Object o = hVars.get(mainKey); 492 if (o != null && o instanceof Var) { 493 Var v = (Var) o; 494 value = v.getValue(); 495 } 496 497 return value; 498 } 499 500 /*** 501 * The <code>Field</code>'s variables are returned as an 502 * unmodifiable <code>Map</code>. 503 */ 504 public Map getVars() { 505 return Collections.unmodifiableMap(hVars); 506 } 507 508 /*** 509 * Gets a unique key based on the property and indexedProperty fields. 510 */ 511 public String getKey() { 512 if (this.key == null) { 513 this.generateKey(); 514 } 515 516 return this.key; 517 } 518 519 /*** 520 * Sets a unique key for the field. This can be used to change 521 * the key temporarily to have a unique key for an indexed field. 522 * @param key 523 */ 524 public void setKey(String key) { 525 this.key = key; 526 } 527 528 /*** 529 * If there is a value specified for the indexedProperty field then 530 * <code>true</code> will be returned. Otherwise it will be 531 * <code>false</code>. 532 */ 533 public boolean isIndexed() { 534 return ((indexedListProperty != null && indexedListProperty.length() > 0)); 535 } 536 537 /*** 538 * Generate correct <code>key</code> value. 539 */ 540 public void generateKey() { 541 if (this.isIndexed()) { 542 this.key = this.indexedListProperty + TOKEN_INDEXED + "." + this.property; 543 } else { 544 this.key = this.property; 545 } 546 } 547 548 /*** 549 * Replace constants with values in fields and process the depends field 550 * to create the dependency <code>Map</code>. 551 * @deprecated This method is called by the framework. It will be made protected 552 * in a future release. TODO 553 */ 554 public void process(Map globalConstants, Map constants) { 555 this.hMsgs.setFast(false); 556 this.hVars.setFast(true); 557 558 this.generateKey(); 559 560 // Process FormSet Constants 561 for (Iterator i = constants.keySet().iterator(); i.hasNext();) { 562 String key = (String) i.next(); 563 String key2 = TOKEN_START + key + TOKEN_END; 564 String replaceValue = (String) constants.get(key); 565 566 property = ValidatorUtils.replace(property, key2, replaceValue); 567 568 processVars(key2, replaceValue); 569 570 this.processMessageComponents(key2, replaceValue); 571 } 572 573 // Process Global Constants 574 for (Iterator i = globalConstants.keySet().iterator(); i.hasNext();) { 575 String key = (String) i.next(); 576 String key2 = TOKEN_START + key + TOKEN_END; 577 String replaceValue = (String) globalConstants.get(key); 578 579 property = ValidatorUtils.replace(property, key2, replaceValue); 580 581 processVars(key2, replaceValue); 582 583 this.processMessageComponents(key2, replaceValue); 584 } 585 586 // Process Var Constant Replacement 587 for (Iterator i = hVars.keySet().iterator(); i.hasNext();) { 588 String key = (String) i.next(); 589 String key2 = TOKEN_START + TOKEN_VAR + key + TOKEN_END; 590 Var var = this.getVar(key); 591 String replaceValue = var.getValue(); 592 593 this.processMessageComponents(key2, replaceValue); 594 } 595 596 hMsgs.setFast(true); 597 } 598 599 /*** 600 * Replace the vars value with the key/value pairs passed in. 601 */ 602 private void processVars(String key, String replaceValue) { 603 Iterator i = this.hVars.keySet().iterator(); 604 while (i.hasNext()) { 605 String varKey = (String) i.next(); 606 Var var = this.getVar(varKey); 607 608 var.setValue(ValidatorUtils.replace(var.getValue(), key, replaceValue)); 609 } 610 611 } 612 613 /*** 614 * Replace the args key value with the key/value pairs passed in. 615 * @deprecated This is an internal setup method that clients don't need to call. 616 */ 617 public void processMessageComponents(String key, String replaceValue) { 618 this.internalProcessMessageComponents(key, replaceValue); 619 } 620 621 /*** 622 * Replace the args key value with the key/value pairs passed in. 623 * TODO When processMessageComponents() is removed from the public API we 624 * should rename this private method to "processMessageComponents". 625 */ 626 private void internalProcessMessageComponents(String key, String replaceValue) { 627 String varKey = TOKEN_START + TOKEN_VAR; 628 // Process Messages 629 if (key != null && !key.startsWith(varKey)) { 630 for (Iterator i = hMsgs.keySet().iterator(); i.hasNext();) { 631 String msgKey = (String) i.next(); 632 String value = this.getMsg(msgKey); 633 634 hMsgs.put(msgKey, ValidatorUtils.replace(value, key, replaceValue)); 635 } 636 } 637 638 this.processArg(key, replaceValue); 639 } 640 641 /*** 642 * Replace the arg <code>Collection</code> key value with the key/value 643 * pairs passed in. 644 */ 645 private void processArg(String key, String replaceValue) { 646 for (int i = 0; i < this.args.length; i++) { 647 648 Map argMap = this.args[i]; 649 if (argMap == null) { 650 continue; 651 } 652 653 Iterator iter = argMap.values().iterator(); 654 while (iter.hasNext()) { 655 Arg arg = (Arg) iter.next(); 656 657 if (arg != null) { 658 arg.setKey( 659 ValidatorUtils.replace(arg.getKey(), key, replaceValue)); 660 } 661 } 662 } 663 } 664 665 /*** 666 * Checks if the validator is listed as a dependency. 667 */ 668 public boolean isDependency(String validatorName) { 669 return this.dependencyList.contains(validatorName); 670 } 671 672 /*** 673 * Gets an unmodifiable <code>Set</code> of the dependencies. 674 * @deprecated Use getDependencyList() instead. 675 */ 676 public Collection getDependencies() { 677 return this.getDependencyList(); 678 } 679 680 /*** 681 * Gets an unmodifiable <code>List</code> of the dependencies in the same 682 * order they were defined in parameter passed to the setDepends() method. 683 */ 684 public List getDependencyList() { 685 return Collections.unmodifiableList(this.dependencyList); 686 } 687 688 689 /*** 690 * Creates and returns a copy of this object. 691 */ 692 public Object clone() { 693 Field field = null; 694 try { 695 field = (Field) super.clone(); 696 } catch(CloneNotSupportedException e) { 697 throw new RuntimeException(e.toString()); 698 } 699 700 field.args = new Map[this.args.length]; 701 for (int i = 0; i < this.args.length; i++) { 702 if (this.args[i] == null) { 703 continue; 704 } 705 706 Map argMap = new HashMap(this.args[i]); 707 Iterator iter = argMap.keySet().iterator(); 708 while (iter.hasNext()) { 709 String validatorName = (String) iter.next(); 710 Arg arg = (Arg) argMap.get(validatorName); 711 argMap.put(validatorName, arg.clone()); 712 } 713 field.args[i] = argMap; 714 } 715 716 field.hVars = ValidatorUtils.copyFastHashMap(hVars); 717 field.hMsgs = ValidatorUtils.copyFastHashMap(hMsgs); 718 field.hArg0 = ValidatorUtils.copyFastHashMap(hArg0); 719 field.hArg1 = ValidatorUtils.copyFastHashMap(hArg1); 720 field.hArg2 = ValidatorUtils.copyFastHashMap(hArg2); 721 field.hArg3 = ValidatorUtils.copyFastHashMap(hArg3); 722 723 return field; 724 } 725 726 /*** 727 * Returns a string representation of the object. 728 */ 729 public String toString() { 730 StringBuffer results = new StringBuffer(); 731 732 results.append("\t\tkey = " + key + "\n"); 733 results.append("\t\tproperty = " + property + "\n"); 734 results.append("\t\tindexedProperty = " + indexedProperty + "\n"); 735 results.append("\t\tindexedListProperty = " + indexedListProperty + "\n"); 736 results.append("\t\tdepends = " + depends + "\n"); 737 results.append("\t\tpage = " + page + "\n"); 738 results.append("\t\tfieldOrder = " + fieldOrder + "\n"); 739 740 if (hVars != null) { 741 results.append("\t\tVars:\n"); 742 for (Iterator i = hVars.keySet().iterator(); i.hasNext();) { 743 Object key = i.next(); 744 results.append("\t\t\t"); 745 results.append(key); 746 results.append("="); 747 results.append(hVars.get(key)); 748 results.append("\n"); 749 } 750 } 751 752 return results.toString(); 753 } 754 755 /*** 756 * Returns an indexed property from the object we're validating. 757 * 758 * @param bean The bean to extract the indexed values from. 759 * @throws ValidatorException If there's an error looking up the property 760 * or, the property found is not indexed. 761 */ 762 Object[] getIndexedProperty(Object bean) throws ValidatorException { 763 Object indexedProperty = null; 764 765 try { 766 indexedProperty = 767 PropertyUtils.getProperty(bean, this.getIndexedListProperty()); 768 769 } catch(IllegalAccessException e) { 770 throw new ValidatorException(e.getMessage()); 771 } catch(InvocationTargetException e) { 772 throw new ValidatorException(e.getMessage()); 773 } catch(NoSuchMethodException e) { 774 throw new ValidatorException(e.getMessage()); 775 } 776 777 if (indexedProperty instanceof Collection) { 778 return ((Collection) indexedProperty).toArray(); 779 780 } else if (indexedProperty.getClass().isArray()) { 781 return (Object[]) indexedProperty; 782 783 } else { 784 throw new ValidatorException(this.getKey() + " is not indexed"); 785 } 786 787 } 788 789 /*** 790 * Executes the given ValidatorAction and all ValidatorActions that it 791 * depends on. 792 * @return true if the validation succeeded. 793 */ 794 private boolean validateForRule( 795 ValidatorAction va, 796 ValidatorResults results, 797 Map actions, 798 Map params, 799 int pos) 800 throws ValidatorException { 801 802 ValidatorResult result = results.getValidatorResult(this.getKey()); 803 if (result != null && result.containsAction(va.getName())) { 804 return result.isValid(va.getName()); 805 } 806 807 if (!this.runDependentValidators(va, results, actions, params, pos)) { 808 return false; 809 } 810 811 return va.executeValidationMethod(this, params, results, pos); 812 } 813 814 /*** 815 * Calls all of the validators that this validator depends on. 816 * TODO ValidatorAction should know how to run its own dependencies. 817 * @param va Run dependent validators for this action. 818 * @param results 819 * @param actions 820 * @param pos 821 * @return true if all of the dependent validations passed. 822 * @throws ValidatorException 823 */ 824 private boolean runDependentValidators( 825 ValidatorAction va, 826 ValidatorResults results, 827 Map actions, 828 Map params, 829 int pos) 830 throws ValidatorException { 831 832 List dependentValidators = va.getDependencyList(); 833 834 if (dependentValidators.isEmpty()) { 835 return true; 836 } 837 838 Iterator iter = dependentValidators.iterator(); 839 while (iter.hasNext()) { 840 String depend = (String) iter.next(); 841 842 ValidatorAction action = (ValidatorAction) actions.get(depend); 843 if (action == null) { 844 this.handleMissingAction(depend); 845 } 846 847 if (!this.validateForRule(action, results, actions, params, pos)) { 848 return false; 849 } 850 } 851 852 return true; 853 } 854 855 /*** 856 * Run the configured validations on this field. Run all validations 857 * in the depends clause over each item in turn, returning when the first 858 * one fails. 859 * @param params A Map of parameter class names to parameter values to pass 860 * into validation methods. 861 * @param actions A Map of validator names to ValidatorAction objects. 862 * @return A ValidatorResults object containing validation messages for 863 * this field. 864 */ 865 ValidatorResults validate(Map params, Map actions) 866 throws ValidatorException { 867 868 if (this.getDepends() == null) { 869 return new ValidatorResults(); 870 } 871 872 ValidatorResults allResults = new ValidatorResults(); 873 874 Object bean = params.get(Validator.BEAN_PARAM); 875 int numberOfFieldsToValidate = 876 this.isIndexed() ? this.getIndexedProperty(bean).length : 1; 877 878 for (int fieldNumber = 0; fieldNumber < numberOfFieldsToValidate; fieldNumber++) { 879 880 Iterator dependencies = this.dependencyList.iterator(); 881 while (dependencies.hasNext()) { 882 String depend = (String) dependencies.next(); 883 884 ValidatorAction action = (ValidatorAction) actions.get(depend); 885 if (action == null) { 886 this.handleMissingAction(depend); 887 } 888 889 ValidatorResults results = new ValidatorResults(); 890 boolean good = 891 validateForRule(action, results, actions, params, fieldNumber); 892 893 allResults.merge(results); 894 895 if (!good) { 896 return allResults; 897 } 898 } 899 } 900 901 return allResults; 902 } 903 904 /*** 905 * Called when a validator name is used in a depends clause but there is 906 * no know ValidatorAction configured for that name. 907 * @param name The name of the validator in the depends list. 908 * @throws ValidatorException 909 */ 910 private void handleMissingAction(String name) throws ValidatorException { 911 throw new ValidatorException( 912 "No ValidatorAction named " 913 + name 914 + " found for field " 915 + this.getProperty()); 916 } 917 918 }

This page was automatically generated by Maven