You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/12/01 14:28:36 UTC

(commons-validator) 08/23: Refactor

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-validator.git

commit ea743f97b99d0feea892c7a6ee8a3dbe9e4a968d
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Dec 1 08:10:06 2023 -0500

    Refactor
    
    Sort members
---
 .../apache/commons/validator/ValidatorAction.java  | 796 +++++++++++----------
 1 file changed, 400 insertions(+), 396 deletions(-)

diff --git a/src/main/java/org/apache/commons/validator/ValidatorAction.java b/src/main/java/org/apache/commons/validator/ValidatorAction.java
index 4d3f5655..be58ceea 100644
--- a/src/main/java/org/apache/commons/validator/ValidatorAction.java
+++ b/src/main/java/org/apache/commons/validator/ValidatorAction.java
@@ -135,126 +135,188 @@ public class ValidatorAction implements Serializable {
     private final List<String> methodParameterList = new ArrayList<>();
 
     /**
-     * Gets the name of the validator action.
+     * Dynamically runs the validation method for this validator and returns true if the data is valid.
      * 
-     * @return Validator Action name.
+     * @param field
+     * @param params  A Map of class names to parameter values.
+     * @param results
+     * @param pos     The index of the list property to validate if it's indexed.
+     * @throws ValidatorException
      */
-    public String getName() {
-        return name;
+    boolean executeValidationMethod(final Field field,
+            // TODO What is this the correct value type?
+            // both ValidatorAction and Validator are added as parameters
+            final Map<String, Object> params, final ValidatorResults results, final int pos) throws ValidatorException {
+
+        params.put(Validator.VALIDATOR_ACTION_PARAM, this);
+
+        try {
+            if (this.validationMethod == null) {
+                synchronized (this) {
+                    final ClassLoader loader = this.getClassLoader(params);
+                    this.loadValidationClass(loader);
+                    this.loadParameterClasses(loader);
+                    this.loadValidationMethod();
+                }
+            }
+
+            final Object[] paramValues = this.getParameterValues(params);
+
+            if (field.isIndexed()) {
+                this.handleIndexedField(field, pos, paramValues);
+            }
+
+            Object result = null;
+            try {
+                result = validationMethod.invoke(getValidationClassInstance(), paramValues);
+
+            } catch (IllegalArgumentException | IllegalAccessException e) {
+                throw new ValidatorException(e.getMessage());
+            } catch (final InvocationTargetException e) {
+
+                if (e.getTargetException() instanceof Exception) {
+                    throw (Exception) e.getTargetException();
+
+                }
+                if (e.getTargetException() instanceof Error) {
+                    throw (Error) e.getTargetException();
+                }
+            }
+
+            final boolean valid = this.isValid(result);
+            if (!valid || valid && !onlyReturnErrors(params)) {
+                results.add(field, this.name, valid, result);
+            }
+
+            if (!valid) {
+                return false;
+            }
+
+            // TODO This catch block remains for backward compatibility. Remove
+            // this for Validator 2.0 when exception scheme changes.
+        } catch (final Exception e) {
+            if (e instanceof ValidatorException) {
+                throw (ValidatorException) e;
+            }
+
+            getLog().error("Unhandled exception thrown during validation: " + e.getMessage(), e);
+
+            results.add(field, this.name, false);
+            return false;
+        }
+
+        return true;
     }
 
     /**
-     * Sets the name of the validator action.
-     * 
-     * @param name Validator Action name.
+     * @return A file name suitable for passing to a {@link ClassLoader#getResourceAsStream(String)} method.
      */
-    public void setName(final String name) {
-        this.name = name;
+    private String formatJavascriptFileName() {
+        String fname = this.jsFunction.substring(1);
+
+        if (!this.jsFunction.startsWith("/")) {
+            fname = jsFunction.replace('.', '/') + ".js";
+        }
+
+        return fname;
     }
 
     /**
-     * Gets the class of the validator action.
-     * 
-     * @return Class name of the validator Action.
+     * Used to generate the javascript name when it is not specified.
      */
-    public String getClassname() {
-        return className;
+    private String generateJsFunction() {
+        final StringBuilder jsName = new StringBuilder("org.apache.commons.validator.javascript");
+
+        jsName.append(".validate");
+        jsName.append(name.substring(0, 1).toUpperCase());
+        jsName.append(name.substring(1));
+
+        return jsName.toString();
     }
 
     /**
-     * Sets the class of the validator action.
-     * 
-     * @param className Class name of the validator Action.
-     * @deprecated Use {@link #setClassName(String)}.
+     * Returns the ClassLoader set in the Validator contained in the parameter Map.
      */
-    @Deprecated
-    public void setClassname(final String className) {
-        this.className = className;
+    private ClassLoader getClassLoader(final Map<String, Object> params) {
+        final Validator v = getValidator(params);
+        return v.getClassLoader();
     }
 
     /**
-     * Sets the class of the validator action.
+     * Gets the class of the validator action.
      * 
-     * @param className Class name of the validator Action.
+     * @return Class name of the validator Action.
      */
-    public void setClassName(final String className) {
-        this.className = className;
+    public String getClassname() {
+        return className;
     }
 
     /**
-     * Gets the name of method being called for the validator action.
+     * Returns the dependent validator names as an unmodifiable <code>List</code>.
      * 
-     * @return The method name.
+     * @return List of the validator action's depedents.
      */
-    public String getMethod() {
-        return method;
+    public List<String> getDependencyList() {
+        return Collections.unmodifiableList(this.dependencyList);
     }
 
     /**
-     * Sets the name of method being called for the validator action.
+     * Gets the dependencies of the validator action as a comma separated list of validator names.
      * 
-     * @param method The method name.
+     * @return The validator action's dependencies.
      */
-    public void setMethod(final String method) {
-        this.method = method;
+    public String getDepends() {
+        return this.depends;
     }
 
     /**
-     * Gets the method parameters for the method.
+     * Gets the Javascript equivalent of the Java class and method associated with this action.
      * 
-     * @return Method's parameters.
+     * @return The Javascript validation.
      */
-    public String getMethodParams() {
-        return methodParams;
+    public synchronized String getJavascript() {
+        return javascript;
     }
 
     /**
-     * Sets the method parameters for the method.
+     * Gets the Javascript function name. This is optional and can be used instead of validator action name for the name of the Javascript function/object.
      * 
-     * @param methodParams A comma separated list of parameters.
+     * @return The Javascript function name.
      */
-    public void setMethodParams(final String methodParams) {
-        this.methodParams = methodParams;
-
-        this.methodParameterList.clear();
-
-        final StringTokenizer st = new StringTokenizer(methodParams, ",");
-        while (st.hasMoreTokens()) {
-            final String value = st.nextToken().trim();
+    public String getJsFunctionName() {
+        return jsFunctionName;
+    }
 
-            if (value != null && !value.isEmpty()) {
-                this.methodParameterList.add(value);
-            }
+    /**
+     * Accessor method for Log instance.
+     *
+     * The Log instance variable is transient and accessing it through this method ensures it is re-initialized when this instance is de-serialized.
+     *
+     * @return The Log instance.
+     */
+    private Log getLog() {
+        if (log == null) {
+            log = LogFactory.getLog(ValidatorAction.class);
         }
+        return log;
     }
 
     /**
-     * Gets the dependencies of the validator action as a comma separated list of validator names.
+     * Gets the name of method being called for the validator action.
      * 
-     * @return The validator action's dependencies.
+     * @return The method name.
      */
-    public String getDepends() {
-        return this.depends;
+    public String getMethod() {
+        return method;
     }
 
     /**
-     * Sets the dependencies of the validator action.
+     * Gets the method parameters for the method.
      * 
-     * @param depends A comma separated list of validator names.
+     * @return Method's parameters.
      */
-    public void setDepends(final String depends) {
-        this.depends = depends;
-
-        this.dependencyList.clear();
-
-        final StringTokenizer st = new StringTokenizer(depends, ",");
-        while (st.hasMoreTokens()) {
-            final String depend = st.nextToken().trim();
-
-            if (depend != null && !depend.isEmpty()) {
-                this.dependencyList.add(depend);
-            }
-        }
+    public String getMethodParams() {
+        return methodParams;
     }
 
     /**
@@ -267,94 +329,116 @@ public class ValidatorAction implements Serializable {
     }
 
     /**
-     * Sets the message associated with the validator action.
+     * Gets the name of the validator action.
      * 
-     * @param msg The message for the validator action.
+     * @return Validator Action name.
      */
-    public void setMsg(final String msg) {
-        this.msg = msg;
+    public String getName() {
+        return name;
     }
 
     /**
-     * Gets the Javascript function name. This is optional and can be used instead of validator action name for the name of the Javascript function/object.
+     * Converts a List of parameter class names into their values contained in the parameters Map.
      * 
-     * @return The Javascript function name.
+     * @param params A Map of class names to parameter values.
+     * @return An array containing the value object for each parameter. This array is in the same order as the given List and is suitable for passing to the
+     *         validation method.
      */
-    public String getJsFunctionName() {
-        return jsFunctionName;
+    private Object[] getParameterValues(final Map<String, ? super Object> params) {
+
+        final Object[] paramValue = new Object[this.methodParameterList.size()];
+
+        for (int i = 0; i < this.methodParameterList.size(); i++) {
+            final String paramClassName = this.methodParameterList.get(i);
+            paramValue[i] = params.get(paramClassName);
+        }
+
+        return paramValue;
     }
 
     /**
-     * Sets the Javascript function name. This is optional and can be used instead of validator action name for the name of the Javascript function/object.
-     * 
-     * @param jsFunctionName The Javascript function name.
+     * Return an instance of the validation class or null if the validation method is static so does not require an instance to be executed.
      */
-    public void setJsFunctionName(final String jsFunctionName) {
-        this.jsFunctionName = jsFunctionName;
+    private Object getValidationClassInstance() throws ValidatorException {
+        if (Modifier.isStatic(this.validationMethod.getModifiers())) {
+            this.instance = null;
+
+        } else if (this.instance == null) {
+            try {
+                this.instance = this.validationClass.getConstructor().newInstance();
+            } catch (ReflectiveOperationException e) {
+                final String msg1 = "Couldn't create instance of " + this.className + ".  " + e.getMessage();
+
+                throw new ValidatorException(msg1);
+            }
+        }
+
+        return this.instance;
+    }
+
+    private Validator getValidator(final Map<String, Object> params) {
+        return (Validator) params.get(Validator.VALIDATOR_PARAM);
     }
 
     /**
-     * Sets the fully qualified class path of the Javascript function.
-     * <p>
-     * This is optional and can be used <strong>instead</strong> of the setJavascript(). Attempting to call both <code>setJsFunction</code> and
-     * <code>setJavascript</code> will result in an <code>IllegalStateException</code> being thrown.
-     * </p>
-     * <p>
-     * If <strong>neither</strong> setJsFunction or setJavascript is set then validator will attempt to load the default javascript definition.
-     * </p>
-     * 
-     * <pre>
-     * <b>Examples</b>
-     *   If in the validator.xml :
-     * #1:
-     *      &lt;validator name="tire"
-     *            jsFunction="com.yourcompany.project.tireFuncion"&gt;
-     *     Validator will attempt to load com.yourcompany.project.validateTireFunction.js from
-     *     its class path.
-     * #2:
-     *    &lt;validator name="tire"&gt;
-     *      Validator will use the name attribute to try and load
-     *         org.apache.commons.validator.javascript.validateTire.js
-     *      which is the default javascript definition.
-     * </pre>
-     * 
-     * @param jsFunction The Javascript function's fully qualified class path.
+     * Modifies the paramValue array with indexed fields.
+     *
+     * @param field
+     * @param pos
+     * @param paramValues
      */
-    public synchronized void setJsFunction(final String jsFunction) {
-        if (javascript != null) {
-            throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()");
-        }
+    private void handleIndexedField(final Field field, final int pos, final Object[] paramValues) throws ValidatorException {
 
-        this.jsFunction = jsFunction;
+        final int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM);
+        final int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM);
+
+        final Object[] indexedList = field.getIndexedProperty(paramValues[beanIndex]);
+
+        // Set current iteration object to the parameter array
+        paramValues[beanIndex] = indexedList[pos];
+
+        // Set field clone with the key modified to represent
+        // the current field
+        final Field indexedField = (Field) field.clone();
+        indexedField.setKey(ValidatorUtils.replace(indexedField.getKey(), Field.TOKEN_INDEXED, "[" + pos + "]"));
+
+        paramValues[fieldIndex] = indexedField;
     }
 
     /**
-     * Gets the Javascript equivalent of the Java class and method associated with this action.
-     * 
-     * @return The Javascript validation.
+     * Initialize based on set.
      */
-    public synchronized String getJavascript() {
-        return javascript;
+    protected void init() {
+        this.loadJavascriptFunction();
     }
 
     /**
-     * Sets the Javascript equivalent of the Java class and method associated with this action.
+     * Checks whether or not the value passed in is in the depends field.
      * 
-     * @param javascript The Javascript validation.
+     * @param validatorName Name of the dependency to check.
+     * @return Whether the named validator is a dependant.
      */
-    public synchronized void setJavascript(final String javascript) {
-        if (jsFunction != null) {
-            throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()");
-        }
+    public boolean isDependency(final String validatorName) {
+        return this.dependencyList.contains(validatorName);
+    }
 
-        this.javascript = javascript;
+    /**
+     * If the result object is a <code>Boolean</code>, it will return its value. If not it will return {@code false} if the object is <code>null</code> and
+     * {@code true} if it isn't.
+     */
+    private boolean isValid(final Object result) {
+        if (result instanceof Boolean) {
+            final Boolean valid = (Boolean) result;
+            return valid.booleanValue();
+        }
+        return result != null;
     }
 
     /**
-     * Initialize based on set.
+     * @return true if the javascript for this action has already been loaded.
      */
-    protected void init() {
-        this.loadJavascriptFunction();
+    private boolean javascriptAlreadyLoaded() {
+        return this.javascript != null;
     }
 
     /**
@@ -392,6 +476,99 @@ public class ValidatorAction implements Serializable {
 
     }
 
+    /**
+     * Converts a List of parameter class names into their Class objects. Stores the output in {@link #parameterClasses}. This array is in the same order as the
+     * given List and is suitable for passing to the validation method.
+     * 
+     * @throws ValidatorException if a class cannot be loaded.
+     */
+    private void loadParameterClasses(final ClassLoader loader) throws ValidatorException {
+
+        if (this.parameterClasses != null) {
+            return;
+        }
+
+        final Class<?>[] parameterClasses = new Class[this.methodParameterList.size()];
+
+        for (int i = 0; i < this.methodParameterList.size(); i++) {
+            final String paramClassName = this.methodParameterList.get(i);
+
+            try {
+                parameterClasses[i] = loader.loadClass(paramClassName);
+
+            } catch (final ClassNotFoundException e) {
+                throw new ValidatorException(e.getMessage());
+            }
+        }
+
+        this.parameterClasses = parameterClasses;
+    }
+
+    /**
+     * Load the Class object for the configured validation class name.
+     * 
+     * @param loader The ClassLoader used to load the Class object.
+     * @throws ValidatorException
+     */
+    private void loadValidationClass(final ClassLoader loader) throws ValidatorException {
+
+        if (this.validationClass != null) {
+            return;
+        }
+
+        try {
+            this.validationClass = loader.loadClass(this.className);
+        } catch (final ClassNotFoundException e) {
+            throw new ValidatorException(e.toString());
+        }
+    }
+
+    /**
+     * Load the Method object for the configured validation method name.
+     * 
+     * @throws ValidatorException
+     */
+    private void loadValidationMethod() throws ValidatorException {
+        if (this.validationMethod != null) {
+            return;
+        }
+
+        try {
+            this.validationMethod = this.validationClass.getMethod(this.method, this.parameterClasses);
+
+        } catch (final NoSuchMethodException e) {
+            throw new ValidatorException("No such validation method: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the onlyReturnErrors setting in the Validator contained in the parameter Map.
+     */
+    private boolean onlyReturnErrors(final Map<String, Object> params) {
+        final Validator v = getValidator(params);
+        return v.getOnlyReturnErrors();
+    }
+
+    /**
+     * Opens an input stream for reading the specified resource.
+     * <p>
+     * The search order is described in the documentation for {@link ClassLoader#getResource(String)}.
+     * </p>
+     *
+     * @param name The resource name
+     * @return An input stream for reading the resource, or {@code null} if the resource could not be found
+     */
+    private InputStream openInputStream(final String javaScriptFileName, ClassLoader classLoader) {
+        InputStream is = null;
+        if (classLoader != null) {
+            is = classLoader.getResourceAsStream(javaScriptFileName);
+        }
+        if (is == null) {
+            return getClass().getResourceAsStream(javaScriptFileName);
+        }
+        return is;
+    }
+
     /**
      * Reads a javascript function from a file.
      *
@@ -428,333 +605,160 @@ public class ValidatorAction implements Serializable {
     }
 
     /**
-     * Opens an input stream for reading the specified resource.
-     * <p>
-     * The search order is described in the documentation for {@link ClassLoader#getResource(String)}.
-     * </p>
-     *
-     * @param name The resource name
-     * @return An input stream for reading the resource, or {@code null} if the resource could not be found
+     * Sets the class of the validator action.
+     * 
+     * @param className Class name of the validator Action.
+     * @deprecated Use {@link #setClassName(String)}.
      */
-    private InputStream openInputStream(final String javaScriptFileName, ClassLoader classLoader) {
-        InputStream is = null;
-        if (classLoader != null) {
-            is = classLoader.getResourceAsStream(javaScriptFileName);
-        }
-        if (is == null) {
-            return getClass().getResourceAsStream(javaScriptFileName);
-        }
-        return is;
+    @Deprecated
+    public void setClassname(final String className) {
+        this.className = className;
     }
 
     /**
-     * @return A file name suitable for passing to a {@link ClassLoader#getResourceAsStream(String)} method.
+     * Sets the class of the validator action.
+     * 
+     * @param className Class name of the validator Action.
      */
-    private String formatJavascriptFileName() {
-        String fname = this.jsFunction.substring(1);
-
-        if (!this.jsFunction.startsWith("/")) {
-            fname = jsFunction.replace('.', '/') + ".js";
-        }
-
-        return fname;
+    public void setClassName(final String className) {
+        this.className = className;
     }
 
     /**
-     * @return true if the javascript for this action has already been loaded.
+     * Sets the dependencies of the validator action.
+     * 
+     * @param depends A comma separated list of validator names.
      */
-    private boolean javascriptAlreadyLoaded() {
-        return this.javascript != null;
-    }
+    public void setDepends(final String depends) {
+        this.depends = depends;
 
-    /**
-     * Used to generate the javascript name when it is not specified.
-     */
-    private String generateJsFunction() {
-        final StringBuilder jsName = new StringBuilder("org.apache.commons.validator.javascript");
+        this.dependencyList.clear();
 
-        jsName.append(".validate");
-        jsName.append(name.substring(0, 1).toUpperCase());
-        jsName.append(name.substring(1));
+        final StringTokenizer st = new StringTokenizer(depends, ",");
+        while (st.hasMoreTokens()) {
+            final String depend = st.nextToken().trim();
 
-        return jsName.toString();
+            if (depend != null && !depend.isEmpty()) {
+                this.dependencyList.add(depend);
+            }
+        }
     }
 
     /**
-     * Checks whether or not the value passed in is in the depends field.
+     * Sets the Javascript equivalent of the Java class and method associated with this action.
      * 
-     * @param validatorName Name of the dependency to check.
-     * @return Whether the named validator is a dependant.
+     * @param javascript The Javascript validation.
      */
-    public boolean isDependency(final String validatorName) {
-        return this.dependencyList.contains(validatorName);
-    }
+    public synchronized void setJavascript(final String javascript) {
+        if (jsFunction != null) {
+            throw new IllegalStateException("Cannot call setJavascript() after calling setJsFunction()");
+        }
 
-    /**
-     * Returns the dependent validator names as an unmodifiable <code>List</code>.
-     * 
-     * @return List of the validator action's depedents.
-     */
-    public List<String> getDependencyList() {
-        return Collections.unmodifiableList(this.dependencyList);
+        this.javascript = javascript;
     }
 
     /**
-     * Returns a string representation of the object.
-     * 
-     * @return a string representation.
-     */
-    @Override
-    public String toString() {
-        final StringBuilder results = new StringBuilder("ValidatorAction: ");
-        results.append(name);
-        results.append("\n");
-
-        return results.toString();
-    }
-
-    /**
-     * Dynamically runs the validation method for this validator and returns true if the data is valid.
+     * Sets the fully qualified class path of the Javascript function.
+     * <p>
+     * This is optional and can be used <strong>instead</strong> of the setJavascript(). Attempting to call both <code>setJsFunction</code> and
+     * <code>setJavascript</code> will result in an <code>IllegalStateException</code> being thrown.
+     * </p>
+     * <p>
+     * If <strong>neither</strong> setJsFunction or setJavascript is set then validator will attempt to load the default javascript definition.
+     * </p>
      * 
-     * @param field
-     * @param params  A Map of class names to parameter values.
-     * @param results
-     * @param pos     The index of the list property to validate if it's indexed.
-     * @throws ValidatorException
-     */
-    boolean executeValidationMethod(final Field field,
-            // TODO What is this the correct value type?
-            // both ValidatorAction and Validator are added as parameters
-            final Map<String, Object> params, final ValidatorResults results, final int pos) throws ValidatorException {
-
-        params.put(Validator.VALIDATOR_ACTION_PARAM, this);
-
-        try {
-            if (this.validationMethod == null) {
-                synchronized (this) {
-                    final ClassLoader loader = this.getClassLoader(params);
-                    this.loadValidationClass(loader);
-                    this.loadParameterClasses(loader);
-                    this.loadValidationMethod();
-                }
-            }
-
-            final Object[] paramValues = this.getParameterValues(params);
-
-            if (field.isIndexed()) {
-                this.handleIndexedField(field, pos, paramValues);
-            }
-
-            Object result = null;
-            try {
-                result = validationMethod.invoke(getValidationClassInstance(), paramValues);
-
-            } catch (IllegalArgumentException | IllegalAccessException e) {
-                throw new ValidatorException(e.getMessage());
-            } catch (final InvocationTargetException e) {
-
-                if (e.getTargetException() instanceof Exception) {
-                    throw (Exception) e.getTargetException();
-
-                }
-                if (e.getTargetException() instanceof Error) {
-                    throw (Error) e.getTargetException();
-                }
-            }
-
-            final boolean valid = this.isValid(result);
-            if (!valid || valid && !onlyReturnErrors(params)) {
-                results.add(field, this.name, valid, result);
-            }
-
-            if (!valid) {
-                return false;
-            }
-
-            // TODO This catch block remains for backward compatibility. Remove
-            // this for Validator 2.0 when exception scheme changes.
-        } catch (final Exception e) {
-            if (e instanceof ValidatorException) {
-                throw (ValidatorException) e;
-            }
-
-            getLog().error("Unhandled exception thrown during validation: " + e.getMessage(), e);
-
-            results.add(field, this.name, false);
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Load the Method object for the configured validation method name.
+     * <pre>
+     * <b>Examples</b>
+     *   If in the validator.xml :
+     * #1:
+     *      &lt;validator name="tire"
+     *            jsFunction="com.yourcompany.project.tireFuncion"&gt;
+     *     Validator will attempt to load com.yourcompany.project.validateTireFunction.js from
+     *     its class path.
+     * #2:
+     *    &lt;validator name="tire"&gt;
+     *      Validator will use the name attribute to try and load
+     *         org.apache.commons.validator.javascript.validateTire.js
+     *      which is the default javascript definition.
+     * </pre>
      * 
-     * @throws ValidatorException
+     * @param jsFunction The Javascript function's fully qualified class path.
      */
-    private void loadValidationMethod() throws ValidatorException {
-        if (this.validationMethod != null) {
-            return;
+    public synchronized void setJsFunction(final String jsFunction) {
+        if (javascript != null) {
+            throw new IllegalStateException("Cannot call setJsFunction() after calling setJavascript()");
         }
 
-        try {
-            this.validationMethod = this.validationClass.getMethod(this.method, this.parameterClasses);
-
-        } catch (final NoSuchMethodException e) {
-            throw new ValidatorException("No such validation method: " + e.getMessage());
-        }
+        this.jsFunction = jsFunction;
     }
 
     /**
-     * Load the Class object for the configured validation class name.
+     * Sets the Javascript function name. This is optional and can be used instead of validator action name for the name of the Javascript function/object.
      * 
-     * @param loader The ClassLoader used to load the Class object.
-     * @throws ValidatorException
+     * @param jsFunctionName The Javascript function name.
      */
-    private void loadValidationClass(final ClassLoader loader) throws ValidatorException {
-
-        if (this.validationClass != null) {
-            return;
-        }
-
-        try {
-            this.validationClass = loader.loadClass(this.className);
-        } catch (final ClassNotFoundException e) {
-            throw new ValidatorException(e.toString());
-        }
+    public void setJsFunctionName(final String jsFunctionName) {
+        this.jsFunctionName = jsFunctionName;
     }
 
     /**
-     * Converts a List of parameter class names into their Class objects. Stores the output in {@link #parameterClasses}. This array is in the same order as the
-     * given List and is suitable for passing to the validation method.
+     * Sets the name of method being called for the validator action.
      * 
-     * @throws ValidatorException if a class cannot be loaded.
+     * @param method The method name.
      */
-    private void loadParameterClasses(final ClassLoader loader) throws ValidatorException {
-
-        if (this.parameterClasses != null) {
-            return;
-        }
-
-        final Class<?>[] parameterClasses = new Class[this.methodParameterList.size()];
-
-        for (int i = 0; i < this.methodParameterList.size(); i++) {
-            final String paramClassName = this.methodParameterList.get(i);
-
-            try {
-                parameterClasses[i] = loader.loadClass(paramClassName);
-
-            } catch (final ClassNotFoundException e) {
-                throw new ValidatorException(e.getMessage());
-            }
-        }
-
-        this.parameterClasses = parameterClasses;
+    public void setMethod(final String method) {
+        this.method = method;
     }
 
     /**
-     * Converts a List of parameter class names into their values contained in the parameters Map.
+     * Sets the method parameters for the method.
      * 
-     * @param params A Map of class names to parameter values.
-     * @return An array containing the value object for each parameter. This array is in the same order as the given List and is suitable for passing to the
-     *         validation method.
+     * @param methodParams A comma separated list of parameters.
      */
-    private Object[] getParameterValues(final Map<String, ? super Object> params) {
-
-        final Object[] paramValue = new Object[this.methodParameterList.size()];
-
-        for (int i = 0; i < this.methodParameterList.size(); i++) {
-            final String paramClassName = this.methodParameterList.get(i);
-            paramValue[i] = params.get(paramClassName);
-        }
-
-        return paramValue;
-    }
+    public void setMethodParams(final String methodParams) {
+        this.methodParams = methodParams;
 
-    /**
-     * Return an instance of the validation class or null if the validation method is static so does not require an instance to be executed.
-     */
-    private Object getValidationClassInstance() throws ValidatorException {
-        if (Modifier.isStatic(this.validationMethod.getModifiers())) {
-            this.instance = null;
+        this.methodParameterList.clear();
 
-        } else if (this.instance == null) {
-            try {
-                this.instance = this.validationClass.getConstructor().newInstance();
-            } catch (ReflectiveOperationException e) {
-                final String msg1 = "Couldn't create instance of " + this.className + ".  " + e.getMessage();
+        final StringTokenizer st = new StringTokenizer(methodParams, ",");
+        while (st.hasMoreTokens()) {
+            final String value = st.nextToken().trim();
 
-                throw new ValidatorException(msg1);
+            if (value != null && !value.isEmpty()) {
+                this.methodParameterList.add(value);
             }
         }
-
-        return this.instance;
     }
 
     /**
-     * Modifies the paramValue array with indexed fields.
-     *
-     * @param field
-     * @param pos
-     * @param paramValues
-     */
-    private void handleIndexedField(final Field field, final int pos, final Object[] paramValues) throws ValidatorException {
-
-        final int beanIndex = this.methodParameterList.indexOf(Validator.BEAN_PARAM);
-        final int fieldIndex = this.methodParameterList.indexOf(Validator.FIELD_PARAM);
-
-        final Object[] indexedList = field.getIndexedProperty(paramValues[beanIndex]);
-
-        // Set current iteration object to the parameter array
-        paramValues[beanIndex] = indexedList[pos];
-
-        // Set field clone with the key modified to represent
-        // the current field
-        final Field indexedField = (Field) field.clone();
-        indexedField.setKey(ValidatorUtils.replace(indexedField.getKey(), Field.TOKEN_INDEXED, "[" + pos + "]"));
-
-        paramValues[fieldIndex] = indexedField;
-    }
-
-    /**
-     * If the result object is a <code>Boolean</code>, it will return its value. If not it will return {@code false} if the object is <code>null</code> and
-     * {@code true} if it isn't.
+     * Sets the message associated with the validator action.
+     * 
+     * @param msg The message for the validator action.
      */
-    private boolean isValid(final Object result) {
-        if (result instanceof Boolean) {
-            final Boolean valid = (Boolean) result;
-            return valid.booleanValue();
-        }
-        return result != null;
+    public void setMsg(final String msg) {
+        this.msg = msg;
     }
 
     /**
-     * Returns the ClassLoader set in the Validator contained in the parameter Map.
+     * Sets the name of the validator action.
+     * 
+     * @param name Validator Action name.
      */
-    private ClassLoader getClassLoader(final Map<String, Object> params) {
-        final Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM);
-        return v.getClassLoader();
+    public void setName(final String name) {
+        this.name = name;
     }
 
     /**
-     * Returns the onlyReturnErrors setting in the Validator contained in the parameter Map.
+     * Returns a string representation of the object.
+     * 
+     * @return a string representation.
      */
-    private boolean onlyReturnErrors(final Map<String, Object> params) {
-        final Validator v = (Validator) params.get(Validator.VALIDATOR_PARAM);
-        return v.getOnlyReturnErrors();
-    }
+    @Override
+    public String toString() {
+        final StringBuilder results = new StringBuilder("ValidatorAction: ");
+        results.append(name);
+        results.append("\n");
 
-    /**
-     * Accessor method for Log instance.
-     *
-     * The Log instance variable is transient and accessing it through this method ensures it is re-initialized when this instance is de-serialized.
-     *
-     * @return The Log instance.
-     */
-    private Log getLog() {
-        if (log == null) {
-            log = LogFactory.getLog(ValidatorAction.class);
-        }
-        return log;
+        return results.toString();
     }
 }