Coverage report

  %line %branch
org.apache.commons.validator.ValidatorAction
70% 
91% 

 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.BufferedReader;
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.io.InputStreamReader;
 23  
 import java.io.Serializable;
 24  
 import java.lang.reflect.InvocationTargetException;
 25  
 import java.lang.reflect.Method;
 26  
 import java.lang.reflect.Modifier;
 27  
 import java.util.ArrayList;
 28  
 import java.util.Collections;
 29  
 import java.util.List;
 30  
 import java.util.Map;
 31  
 import java.util.StringTokenizer;
 32  
 
 33  
 import org.apache.commons.logging.Log;
 34  
 import org.apache.commons.logging.LogFactory;
 35  
 import org.apache.commons.validator.util.ValidatorUtils;
 36  
 
 37  
 /**
 38  
  * Contains the information to dynamically create and run a validation
 39  
  * method.  This is the class representation of a pluggable validator that can 
 40  
  * be defined in an xml file with the <validator> element.
 41  
  *
 42  
  * <strong>Note</strong>: The validation method is assumed to be thread safe.
 43  
  *
 44  
  * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
 45  
  */
 46  750
 public class ValidatorAction implements Serializable {
 47  
     
 48  
     /**
 49  
      * Logger.
 50  
      */
 51  364
     private transient Log log = LogFactory.getLog(ValidatorAction.class);
 52  
 
 53  
     /**
 54  
      * The name of the validation.
 55  
      */
 56  364
     private String name = null;
 57  
 
 58  
     /**
 59  
      * The full class name of the class containing
 60  
      * the validation method associated with this action.
 61  
      */
 62  364
     private String classname = null;
 63  
     
 64  
     /**
 65  
      * The Class object loaded from the classname.
 66  
      */
 67  364
     private Class validationClass = null;
 68  
 
 69  
     /**
 70  
      * The full method name of the validation to be performed.  The method
 71  
      * must be thread safe.
 72  
      */
 73  364
     private String method = null;
 74  
     
 75  
     /**
 76  
      * The Method object loaded from the method name.
 77  
      */
 78  364
     private Method validationMethod = null;
 79  
 
 80  
     /**
 81  
      * <p>
 82  
      * The method signature of the validation method.  This should be a comma
 83  
      * delimited list of the full class names of each parameter in the correct 
 84  
      * order that the method takes.
 85  
      * </p>
 86  
      * <p>
 87  
      * Note: <code>java.lang.Object</code> is reserved for the
 88  
      * JavaBean that is being validated.  The <code>ValidatorAction</code>
 89  
      * and <code>Field</code> that are associated with a field's
 90  
      * validation will automatically be populated if they are
 91  
      * specified in the method signature.
 92  
      * </p>
 93  
      */
 94  364
     private String methodParams =
 95  
             Validator.BEAN_PARAM
 96  
             + ","
 97  
             + Validator.VALIDATOR_ACTION_PARAM
 98  
             + ","
 99  
             + Validator.FIELD_PARAM;
 100  
             
 101  
     /**
 102  
      * The Class objects for each entry in methodParameterList.
 103  
      */        
 104  364
     private Class[] parameterClasses = null;
 105  
 
 106  
     /**
 107  
      * The other <code>ValidatorAction</code>s that this one depends on.  If 
 108  
      * any errors occur in an action that this one depends on, this action will 
 109  
      * not be processsed.
 110  
      */
 111  364
     private String depends = null;
 112  
 
 113  
     /**
 114  
      * The default error message associated with this action.
 115  
      */
 116  364
     private String msg = null;
 117  
 
 118  
     /**
 119  
      * An optional field to contain the name to be used if JavaScript is 
 120  
      * generated.
 121  
      */
 122  364
     private String jsFunctionName = null;
 123  
 
 124  
     /**
 125  
      * An optional field to contain the class path to be used to retrieve the
 126  
      * JavaScript function.
 127  
      */
 128  364
     private String jsFunction = null;
 129  
 
 130  
     /**
 131  
      * An optional field to containing a JavaScript representation of the
 132  
      * java method assocated with this action.
 133  
      */
 134  364
     private String javascript = null;
 135  
 
 136  
     /**
 137  
      * If the java method matching the correct signature isn't static, the 
 138  
      * instance is stored in the action.  This assumes the method is thread 
 139  
      * safe.
 140  
      */
 141  364
     private Object instance = null;
 142  
 
 143  
     /**
 144  
      * An internal List representation of the other <code>ValidatorAction</code>s
 145  
      * this one depends on (if any).  This List gets updated
 146  
      * whenever setDepends() gets called.  This is synchronized so a call to
 147  
      * setDepends() (which clears the List) won't interfere with a call to
 148  
      * isDependency().
 149  
      */
 150  364
     private List dependencyList = Collections.synchronizedList(new ArrayList());
 151  
 
 152  
     /**
 153  
      * An internal List representation of all the validation method's 
 154  
      * parameters defined in the methodParams String.
 155  
      */
 156  364
     private List methodParameterList = new ArrayList();
 157  
 
 158  
     /**
 159  
      * Gets the name of the validator action.
 160  
      * @return Validator Action name.
 161  
      */
 162  
     public String getName() {
 163  372
         return name;
 164  
     }
 165  
 
 166  
     /**
 167  
      * Sets the name of the validator action.
 168  
      * @param name Validator Action name.
 169  
      */
 170  
     public void setName(String name) {
 171  364
         this.name = name;
 172  364
     }
 173  
 
 174  
     /**
 175  
      * Gets the class of the validator action.
 176  
      * @return Class name of the validator Action.
 177  
      */
 178  
     public String getClassname() {
 179  0
         return classname;
 180  
     }
 181  
 
 182  
     /**
 183  
      * Sets the class of the validator action.
 184  
      * @param classname Class name of the validator Action.
 185  
      */
 186  
     public void setClassname(String classname) {
 187  364
         this.classname = classname;
 188  364
     }
 189  
 
 190  
     /**
 191  
      * Gets the name of method being called for the validator action.
 192  
      * @return The method name.
 193  
      */
 194  
     public String getMethod() {
 195  0
         return method;
 196  
     }
 197  
 
 198  
     /**
 199  
      * Sets the name of method being called for the validator action.
 200  
      * @param method The method name.
 201  
      */
 202  
     public void setMethod(String method) {
 203  364
         this.method = method;
 204  364
     }
 205  
 
 206  
     /**
 207  
      * Gets the method parameters for the method.
 208  
      * @return Method's parameters.
 209  
      */
 210  
     public String getMethodParams() {
 211  0
         return methodParams;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Sets the method parameters for the method.
 216  
      * @param methodParams A comma separated list of parameters.
 217  
      */
 218  
     public void setMethodParams(String methodParams) {
 219  364
         this.methodParams = methodParams;
 220  
 
 221  364
         this.methodParameterList.clear();
 222  
 
 223  364
         StringTokenizer st = new StringTokenizer(methodParams, ",");
 224  1490
         while (st.hasMoreTokens()) {
 225  762
             String value = st.nextToken().trim();
 226  
 
 227  762
             if (value != null && value.length() > 0) {
 228  762
                 this.methodParameterList.add(value);
 229  
             }
 230  
         }
 231  364
     }
 232  
 
 233  
     /**
 234  
      * Gets the dependencies of the validator action as a comma separated list 
 235  
      * of validator names.
 236  
      * @return The validator action's dependencies.
 237  
      */
 238  
     public String getDepends() {
 239  0
         return this.depends;
 240  
     }
 241  
 
 242  
     /**
 243  
      * Sets the dependencies of the validator action.
 244  
      * @param depends A comma separated list of validator names.
 245  
      */
 246  
     public void setDepends(String depends) {
 247  2
         this.depends = depends;
 248  
 
 249  2
         this.dependencyList.clear();
 250  
 
 251  2
         StringTokenizer st = new StringTokenizer(depends, ",");
 252  6
         while (st.hasMoreTokens()) {
 253  2
             String depend = st.nextToken().trim();
 254  
 
 255  2
             if (depend != null && depend.length() > 0) {
 256  2
                 this.dependencyList.add(depend);
 257  
             }
 258  
         }
 259  2
     }
 260  
 
 261  
     /**
 262  
      * Gets the message associated with the validator action.
 263  
      * @return The message for the validator action.
 264  
      */
 265  
     public String getMsg() {
 266  0
         return msg;
 267  
     }
 268  
 
 269  
     /**
 270  
      * Sets the message associated with the validator action.
 271  
      * @param msg The message for the validator action.
 272  
      */
 273  
     public void setMsg(String msg) {
 274  360
         this.msg = msg;
 275  360
     }
 276  
 
 277  
     /**
 278  
      * Gets the Javascript function name.  This is optional and can
 279  
      * be used instead of validator action name for the name of the
 280  
      * Javascript function/object.
 281  
      * @return The Javascript function name.
 282  
      */
 283  
     public String getJsFunctionName() {
 284  0
         return jsFunctionName;
 285  
     }
 286  
 
 287  
     /**
 288  
      * Sets the Javascript function name.  This is optional and can
 289  
      * be used instead of validator action name for the name of the
 290  
      * Javascript function/object.
 291  
      * @param jsFunctionName The Javascript function name.
 292  
      */
 293  
     public void setJsFunctionName(String jsFunctionName) {
 294  0
         this.jsFunctionName = jsFunctionName;
 295  0
     }
 296  
 
 297  
     /**
 298  
      * Sets the fully qualified class path of the Javascript function.
 299  
      * <p>
 300  
      * This is optional and can be used <strong>instead</strong> of the setJavascript().
 301  
      * Attempting to call both <code>setJsFunction</code> and <code>setJavascript</code>
 302  
      * will result in an <code>IllegalStateException</code> being thrown. </p>
 303  
      * <p>
 304  
      * If <strong>neither</strong> setJsFunction or setJavascript is set then 
 305  
      * validator will attempt to load the default javascript definition.
 306  
      * </p>
 307  
      * <pre>
 308  
      * <b>Examples</b>
 309  
      *   If in the validator.xml :
 310  
      * #1:
 311  
      *      &lt;validator name="tire"
 312  
      *            jsFunction="com.yourcompany.project.tireFuncion"&gt;
 313  
      *     Validator will attempt to load com.yourcompany.project.validateTireFunction.js from
 314  
      *     its class path.
 315  
      * #2:
 316  
      *    &lt;validator name="tire"&gt;
 317  
      *      Validator will use the name attribute to try and load
 318  
      *         org.apache.commons.validator.javascript.validateTire.js
 319  
      *      which is the default javascript definition.
 320  
      * </pre>
 321  
      * @param jsFunction The Javascript function's fully qualified class path.
 322  
      */
 323  
     public void setJsFunction(String jsFunction) {
 324  0
         if (javascript != null) {
 325  0
             throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()");
 326  
         }
 327  
 
 328  0
         this.jsFunction = jsFunction;
 329  0
     }
 330  
 
 331  
     /**
 332  
      * Gets the Javascript equivalent of the java class and method
 333  
      * associated with this action.
 334  
      * @return The Javascript validation.
 335  
      */
 336  
     public String getJavascript() {
 337  0
         return javascript;
 338  
     }
 339  
 
 340  
     /**
 341  
      * Sets the Javascript equivalent of the java class and method
 342  
      * associated with this action.
 343  
      * @param javascript The Javascript validation.
 344  
      */
 345  
     public void setJavascript(String javascript) {
 346  0
         if (jsFunction != null) {
 347  0
             throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()");
 348  
         }
 349  
 
 350  0
         this.javascript = javascript;
 351  0
     }
 352  
 
 353  
     /**
 354  
      * Initialize based on set.
 355  
      */
 356  
     protected void init() {
 357  364
         this.loadJavascriptFunction();
 358  364
     }
 359  
 
 360  
     /**
 361  
      * Load the javascript function specified by the given path.  For this
 362  
      * implementation, the <code>jsFunction</code> property should contain a 
 363  
      * fully qualified package and script name, separated by periods, to be 
 364  
      * loaded from the class loader that created this instance.
 365  
      *
 366  
      * TODO if the path begins with a '/' the path will be intepreted as 
 367  
      * absolute, and remain unchanged.  If this fails then it will attempt to 
 368  
      * treat the path as a file path.  It is assumed the script ends with a 
 369  
      * '.js'.
 370  
      */
 371  
     protected synchronized void loadJavascriptFunction() {
 372  
 
 373  364
         if (this.javascriptAlreadyLoaded()) {
 374  0
             return;
 375  
         }
 376  
 
 377  364
         if (getLog().isTraceEnabled()) {
 378  0
             getLog().trace("  Loading function begun");
 379  
         }
 380  
 
 381  364
         if (this.jsFunction == null) {
 382  364
             this.jsFunction = class="keyword">this.generateJsFunction();
 383  
         }
 384  
 
 385  364
         String javascriptFileName = this.formatJavascriptFileName();
 386  
 
 387  364
         if (getLog().isTraceEnabled()) {
 388  0
             getLog().trace("  Loading js function '" + javascriptFileName + "'");
 389  
         }
 390  
 
 391  364
         this.javascript = class="keyword">this.readJavascriptFile(javascriptFileName);
 392  
 
 393  364
         if (getLog().isTraceEnabled()) {
 394  0
             getLog().trace("  Loading javascript function completed");
 395  
         }
 396  
 
 397  364
     }
 398  
 
 399  
     /**
 400  
      * Read a javascript function from a file.
 401  
      * @param javascriptFileName The file containing the javascript.
 402  
      * @return The javascript function or null if it could not be loaded.
 403  
      */
 404  
     private String readJavascriptFile(String javascriptFileName) {
 405  364
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 406  364
         if (classLoader == null) {
 407  0
             classLoader = this.getClass().getClassLoader();
 408  
         }
 409  
 
 410  364
         InputStream is = classLoader.getResourceAsStream(javascriptFileName);
 411  364
         if (is == null) {
 412  174
             is = this.getClass().getResourceAsStream(javascriptFileName);
 413  
         }
 414  
 
 415  364
         if (is == null) {
 416  174
             getLog().debug("  Unable to read javascript name "+javascriptFileName);
 417  174
             return null;
 418  
         }
 419  
 
 420  190
         StringBuffer buffer = new StringBuffer();
 421  190
         BufferedReader reader = new BufferedReader(class="keyword">new InputStreamReader(is));
 422  
         try {
 423  190
             String line = null;
 424  19028
             while ((line = reader.readLine()) != null) {
 425  18648
                 buffer.append(line + "\n");
 426  
             }
 427  
 
 428  190
         } catch(IOException e) {
 429  0
             getLog().error("Error reading javascript file.", e);
 430  
 
 431  0
         } finally {
 432  0
             try {
 433  190
                 reader.close();
 434  190
             } catch(IOException e) {
 435  0
                 getLog().error("Error closing stream to javascript file.", e);
 436  190
             }
 437  
         }
 438  
         
 439  190
         String function = buffer.toString();
 440  190
         return function.equals("") ? null : function;
 441  
     }
 442  
 
 443  
     /**
 444  
      * @return A filename suitable for passing to a 
 445  
      * ClassLoader.getResourceAsStream() method.
 446  
      */
 447  
     private String formatJavascriptFileName() {
 448  364
         String name = this.jsFunction.substring(1);
 449  
 
 450  364
         if (!this.jsFunction.startsWith("/")) {
 451  364
             name = jsFunction.replace('.', '/') + ".js";
 452  
         }
 453  
 
 454  364
         return name;
 455  
     }
 456  
 
 457  
     /**
 458  
      * @return true if the javascript for this action has already been loaded.
 459  
      */
 460  
     private boolean javascriptAlreadyLoaded() {
 461  364
         return (this.javascript != null);
 462  
     }
 463  
 
 464  
     /**
 465  
      * Used to generate the javascript name when it is not specified.
 466  
      */
 467  
     private String generateJsFunction() {
 468  364
         StringBuffer jsName =
 469  
                 new StringBuffer("org.apache.commons.validator.javascript");
 470  
 
 471  364
         jsName.append(".validate");
 472  364
         jsName.append(name.substring(0, 1).toUpperCase());
 473  364
         jsName.append(name.substring(1, name.length()));
 474  
 
 475  364
         return jsName.toString();
 476  
     }
 477  
 
 478  
     /**
 479  
      * Checks whether or not the value passed in is in the depends field.
 480  
      * @param validatorName Name of the dependency to check.
 481  
      * @return Whether the named validator is a dependant.
 482  
      */
 483  
     public boolean isDependency(String validatorName) {
 484  0
         return this.dependencyList.contains(validatorName);
 485  
     }
 486  
 
 487  
     /**
 488  
      * Returns the dependent validator names as an unmodifiable
 489  
      * <code>List</code>.
 490  
      * @return List of the validator action's depedents.
 491  
      */
 492  
     public List getDependencyList() {
 493  167
         return Collections.unmodifiableList(this.dependencyList);
 494  
     }
 495  
 
 496  
     /**
 497  
      * Returns a string representation of the object.
 498  
      * @return a string representation.
 499  
      */
 500  
     public String toString() {
 501  0
         StringBuffer results = new StringBuffer("ValidatorAction: ");
 502  0
         results.append(name);
 503  0
         results.append("\n");
 504  
 
 505  0
         return results.toString();
 506  
     }
 507  
     
 508  
     /**
 509  
      * Dynamically runs the validation method for this validator and returns 
 510  
      * true if the data is valid.
 511  
      * @param field
 512  
      * @param params A Map of class names to parameter values.
 513  
      * @param results
 514  
      * @param pos The index of the list property to validate if it's indexed.
 515  
      * @throws ValidatorException
 516  
      */
 517  
     boolean executeValidationMethod(
 518  
         Field field,
 519  
         Map params,
 520  
         ValidatorResults results,
 521  
         int pos)
 522  
         throws ValidatorException {
 523  
 
 524  166
         params.put(Validator.VALIDATOR_ACTION_PARAM, this);
 525  
 
 526  
         try {
 527  166
             if (this.validationMethod == null) {
 528  113
                 synchronized(this) {
 529  113
                     ClassLoader loader = this.getClassLoader(params);
 530  113
                     this.loadValidationClass(loader);
 531  113
                     this.loadParameterClasses(loader);
 532  113
                     this.loadValidationMethod();
 533  113
                 }
 534  
             }
 535  
 
 536  166
             Object[] paramValues = this.getParameterValues(params);
 537  
             
 538  166
             if (field.isIndexed()) {
 539  0
                 this.handleIndexedField(field, pos, paramValues);
 540  
             }
 541  
 
 542  166
             Object result = null;
 543  
             try {
 544  166
                 result =
 545  
                     validationMethod.invoke(
 546  
                         getValidationClassInstance(),
 547  
                         paramValues);
 548  
 
 549  165
             } catch (IllegalArgumentException e) {
 550  0
                 throw new ValidatorException(e.getMessage());
 551  
             } catch (IllegalAccessException e) {
 552  0
                 throw new ValidatorException(e.getMessage());
 553  
             } catch (InvocationTargetException e) {
 554  
 
 555  1
                 if (e.getTargetException() instanceof Exception) {
 556  1
                     throw (Exception) e.getTargetException();
 557  
 
 558  0
                 } else if (e.getTargetException() instanceof Error) {
 559  0
                     throw (Error) e.getTargetException();
 560  
                 }
 561  
             }
 562  
 
 563  165
             boolean valid = this.isValid(result);
 564  165
             if (!valid || (valid && !onlyReturnErrors(params))) {
 565  164
                 results.add(field, this.name, valid, result);
 566  
             }
 567  
 
 568  165
             if (!valid) {
 569  74
                 return false;
 570  
             }
 571  
 
 572  
             // TODO This catch block remains for backward compatibility.  Remove
 573  
             // this for Validator 2.0 when exception scheme changes.
 574  91
         } catch (Exception e) {
 575  1
             if (e instanceof ValidatorException) {
 576  1
                 throw (ValidatorException) e;
 577  
             }
 578  
 
 579  0
             getLog().error(
 580  
                 "Unhandled exception thrown during validation: " + e.getMessage(),
 581  
                 e);
 582  
 
 583  0
             results.add(field, this.name, false);
 584  0
             return false;
 585  
         }
 586  
 
 587  91
         return true;
 588  
     }
 589  
     
 590  
     /**
 591  
      * Load the Method object for the configured validation method name.
 592  
      * @throws ValidatorException
 593  
      */
 594  
     private void loadValidationMethod() throws ValidatorException {
 595  113
         if (this.validationMethod != null) {
 596  0
             return;
 597  
         }
 598  
      
 599  
         try {
 600  113
             this.validationMethod =
 601  
                 this.validationClass.getMethod(class="keyword">this.method, class="keyword">this.parameterClasses);
 602  
      
 603  113
         } catch (NoSuchMethodException e) {
 604  0
             throw new ValidatorException("No such validation method: " + 
 605  
                 e.getMessage());
 606  
         }
 607  113
     }
 608  
     
 609  
     /**
 610  
      * Load the Class object for the configured validation class name.
 611  
      * @param loader The ClassLoader used to load the Class object.
 612  
      * @throws ValidatorException
 613  
      */
 614  
     private void loadValidationClass(ClassLoader loader) 
 615  
         throws ValidatorException {
 616  
         
 617  113
         if (this.validationClass != null) {
 618  0
             return;
 619  
         }
 620  
         
 621  
         try {
 622  113
             this.validationClass = loader.loadClass(class="keyword">this.classname);
 623  113
         } catch (ClassNotFoundException e) {
 624  0
             throw new ValidatorException(e.toString());
 625  
         }
 626  113
     }
 627  
     
 628  
     /**
 629  
      * Converts a List of parameter class names into their Class objects.
 630  
      * @return An array containing the Class object for each parameter.  This 
 631  
      * array is in the same order as the given List and is suitable for passing 
 632  
      * to the validation method.
 633  
      * @throws ValidatorException if a class cannot be loaded.
 634  
      */
 635  
     private void loadParameterClasses(ClassLoader loader)
 636  
         throws ValidatorException {
 637  
 
 638  113
         if (this.parameterClasses != null) {
 639  0
             return;
 640  
         }
 641  
         
 642  113
         Class[] parameterClasses = new Class[this.methodParameterList.size()];
 643  
 
 644  364
         for (int i = 0; i < this.methodParameterList.size(); i++) {
 645  251
             String paramClassName = (String) this.methodParameterList.get(i);
 646  
 
 647  
             try {
 648  251
                 parameterClasses[i] = loader.loadClass(paramClassName);
 649  
                     
 650  251
             } catch (ClassNotFoundException e) {
 651  0
                 throw new ValidatorException(e.getMessage());
 652  
             }
 653  
         }
 654  
 
 655  113
         this.parameterClasses = parameterClasses;
 656  113
     }
 657  
     
 658  
     /**
 659  
      * Converts a List of parameter class names into their values contained in 
 660  
      * the parameters Map.
 661  
      * @param params A Map of class names to parameter values.
 662  
      * @return An array containing the value object for each parameter.  This 
 663  
      * array is in the same order as the given List and is suitable for passing 
 664  
      * to the validation method.
 665  
      */
 666  
     private Object[] getParameterValues(Map params) {
 667  
 
 668  166
         Object[] paramValue = new Object[this.methodParameterList.size()];
 669  
 
 670  529
         for (int i = 0; i < this.methodParameterList.size(); i++) {
 671  363
             String paramClassName = (String) this.methodParameterList.get(i);
 672  363
             paramValue[i] = params.get(paramClassName);
 673  
         }
 674  
 
 675  166
         return paramValue;
 676  
     }
 677  
     
 678  
     /**
 679  
      * Return an instance of the validation class or null if the validation 
 680  
      * method is static so does not require an instance to be executed.
 681  
      */
 682  
     private Object getValidationClassInstance() throws ValidatorException {
 683  166
         if (Modclass="keyword">ifier.isStatic(this.validationMethod.getModclass="keyword">ifiers())) {
 684  166
             this.instance = null;
 685  
 
 686  
         } else {
 687  0
             if (this.instance == null) {
 688  
                 try {
 689  0
                     this.instance = class="keyword">this.validationClass.newInstance();
 690  0
                 } catch (InstantiationException e) {
 691  0
                     String msg =
 692  
                         "Couldn't create instance of "
 693  
                             + this.classname
 694  
                             + ".  "
 695  
                             + e.getMessage();
 696  
 
 697  0
                     throw new ValidatorException(msg);
 698  
 
 699  
                 } catch (IllegalAccessException e) {
 700  0
                     String msg =
 701  
                         "Couldn't create instance of "
 702  
                             + this.classname
 703  
                             + ".  "
 704  
                             + e.getMessage();
 705  
 
 706  0
                     throw new ValidatorException(msg);
 707  
                 }
 708  
             }
 709  
         }
 710  
 
 711  166
         return this.instance;
 712  
     }
 713  
     
 714  
     /**
 715  
      * Modifies the paramValue array with indexed fields.
 716  
      *
 717  
      * @param field
 718  
      * @param pos
 719  
      * @param paramValues
 720  
      */
 721  
     private void handleIndexedField(Field field, int pos, Object[] paramValues)
 722  
         throws ValidatorException {
 723  
 
 724  0
         int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM);
 725  0
         int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM);
 726  
 
 727  0
         Object indexedList[] = field.getIndexedProperty(paramValues[beanIndex]);
 728  
 
 729  
         // Set current iteration object to the parameter array
 730  0
         paramValues[beanIndex] = indexedList[pos];
 731  
 
 732  
         // Set field clone with the key modified to represent
 733  
         // the current field
 734  0
         Field indexedField = (Field) field.clone();
 735  0
         indexedField.setKey(
 736  
             ValidatorUtils.replace(
 737  
                 indexedField.getKey(),
 738  
                 Field.TOKEN_INDEXED,
 739  
                 "[" + pos + "]"));
 740  
 
 741  0
         paramValues[fieldIndex] = indexedField;
 742  0
     }
 743  
     
 744  
     /**
 745  
      * If the result object is a <code>Boolean</code>, it will return its 
 746  
      * value.  If not it will return <code>false</code> if the object is 
 747  
      * <code>null</code> and <code>true</code> if it isn't.
 748  
      */
 749  
     private boolean isValid(Object result) {
 750  165
         if (result instanceof Boolean) {
 751  138
             Boolean valid = (Boolean) result;
 752  138
             return valid.booleanValue();
 753  
         } else {
 754  27
             return (result != null);
 755  
         }
 756  
     }
 757  
 
 758  
     /**
 759  
      * Returns the ClassLoader set in the Validator contained in the parameter
 760  
      * Map.
 761  
      */
 762  
     private ClassLoader getClassLoader(Map params) {
 763  113
         Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM);
 764  113
         return v.getClassLoader();
 765  
     }
 766  
     
 767  
     /**
 768  
      * Returns the onlyReturnErrors setting in the Validator contained in the 
 769  
      * parameter Map.
 770  
      */
 771  
     private boolean onlyReturnErrors(Map params) {
 772  91
         Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM);
 773  91
         return v.getOnlyReturnErrors();
 774  
     }
 775  
 
 776  
     /**
 777  
      * Accessor method for Log instance.
 778  
      *
 779  
      * The Log instance variable is transient and
 780  
      * accessing it through this method ensures it
 781  
      * is re-initialized when this instance is
 782  
      * de-serialized.
 783  
      *
 784  
      * @return The Log instance.
 785  
      */
 786  
     private Log getLog() {
 787  1266
         if (log == null) {
 788  0
             log =  LogFactory.getLog(ValidatorAction.class);
 789  
         }
 790  1266
         return log;
 791  
     }
 792  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.