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

Save This Page
Home » commons-validator-1.3.1-src » org.apache.commons » validator » [javadoc | source]