Validator.java

  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. import java.io.Serializable;
  19. import java.util.HashMap;
  20. import java.util.Locale;
  21. import java.util.Map;

  22. /**
  23.  * Validations are processed by the validate method. An instance of
  24.  * <code>ValidatorResources</code> is used to define the validators
  25.  * (validation methods) and the validation rules for a JavaBean.
  26.  */
  27. // TODO mutable fields should be made private and accessed via suitable methods only
  28. public class Validator implements Serializable {

  29.     private static final long serialVersionUID = -7119418755208731611L;

  30.     /**
  31.      * Resources key the JavaBean is stored to perform validation on.
  32.      */
  33.     public static final String BEAN_PARAM = "java.lang.Object";

  34.     /**
  35.      * Resources key the <code>ValidatorAction</code> is stored under.
  36.      * This will be automatically passed into a validation method
  37.      * with the current <code>ValidatorAction</code> if it is
  38.      * specified in the method signature.
  39.      */
  40.     public static final String VALIDATOR_ACTION_PARAM =
  41.             "org.apache.commons.validator.ValidatorAction";

  42.     /**
  43.      * Resources key the <code>ValidatorResults</code> is stored under.
  44.      * This will be automatically passed into a validation method
  45.      * with the current <code>ValidatorResults</code> if it is
  46.      * specified in the method signature.
  47.      */
  48.     public static final String VALIDATOR_RESULTS_PARAM =
  49.             "org.apache.commons.validator.ValidatorResults";

  50.     /**
  51.      * Resources key the <code>Form</code> is stored under.
  52.      * This will be automatically passed into a validation method
  53.      * with the current <code>Form</code> if it is
  54.      * specified in the method signature.
  55.      */
  56.     public static final String FORM_PARAM = "org.apache.commons.validator.Form";

  57.     /**
  58.      * Resources key the <code>Field</code> is stored under.
  59.      * This will be automatically passed into a validation method
  60.      * with the current <code>Field</code> if it is
  61.      * specified in the method signature.
  62.      */
  63.     public static final String FIELD_PARAM = "org.apache.commons.validator.Field";

  64.     /**
  65.      * Resources key the <code>Validator</code> is stored under.
  66.      * This will be automatically passed into a validation method
  67.      * with the current <code>Validator</code> if it is
  68.      * specified in the method signature.
  69.      */
  70.     public static final String VALIDATOR_PARAM =
  71.             "org.apache.commons.validator.Validator";

  72.     /**
  73.      * Resources key the <code>Locale</code> is stored.
  74.      * This will be used to retrieve the appropriate
  75.      * <code>FormSet</code> and <code>Form</code> to be
  76.      * processed.
  77.      */
  78.     public static final String LOCALE_PARAM = "java.util.Locale";

  79.     /**
  80.      * The Validator Resources.
  81.      */
  82.     protected ValidatorResources resources;

  83.     /**
  84.      * The name of the form to validate
  85.      */
  86.     protected String formName;

  87.     /**
  88.      * The name of the field on the form to validate
  89.      * @since 1.2.0
  90.      */
  91.     protected String fieldName;

  92.     /**
  93.      * Maps validation method parameter class names to the objects to be passed
  94.      * into the method.
  95.      */
  96.     protected Map<String, Object> parameters = new HashMap<>(); // <String, Object>

  97.     /**
  98.      * The current page number to validate.
  99.      */
  100.     protected int page;

  101.     /**
  102.      * The class loader to use for instantiating application objects.
  103.      * If not specified, the context class loader, or the class loader
  104.      * used to load Digester itself, is used, based on the value of the
  105.      * <code>useContextClassLoader</code> variable.
  106.      */
  107.     protected transient ClassLoader classLoader;

  108.     /**
  109.      * Whether or not to use the Context ClassLoader when loading classes
  110.      * for instantiating new objects.  Default is {@code false}.
  111.      */
  112.     protected boolean useContextClassLoader;

  113.     /**
  114.      * Sets this to true to not return Fields that pass validation.  Only return failures.
  115.      */
  116.     protected boolean onlyReturnErrors;

  117.     /**
  118.      * Constructs a <code>Validator</code> that will
  119.      * use the <code>ValidatorResources</code>
  120.      * passed in to retrieve pluggable validators
  121.      * the different sets of validation rules.
  122.      *
  123.      * @param resources <code>ValidatorResources</code> to use during validation.
  124.      */
  125.     public Validator(final ValidatorResources resources) {
  126.         this(resources, null);
  127.     }

  128.     /**
  129.      * Constructs a <code>Validator</code> that will
  130.      * use the <code>ValidatorResources</code>
  131.      * passed in to retrieve pluggable validators
  132.      * the different sets of validation rules.
  133.      *
  134.      * @param resources <code>ValidatorResources</code> to use during validation.
  135.      * @param formName Key used for retrieving the set of validation rules.
  136.      */
  137.     public Validator(final ValidatorResources resources, final String formName) {
  138.         if (resources == null) {
  139.             throw new IllegalArgumentException("Resources cannot be null.");
  140.         }

  141.         this.resources = resources;
  142.         this.formName = formName;
  143.     }

  144.     /**
  145.      * Constructs a <code>Validator</code> that will
  146.      * use the <code>ValidatorResources</code>
  147.      * passed in to retrieve pluggable validators
  148.      * the different sets of validation rules.
  149.      *
  150.      * @param resources <code>ValidatorResources</code> to use during validation.
  151.      * @param formName Key used for retrieving the set of validation rules.
  152.      * @param fieldName Key used for retrieving the set of validation rules for a field
  153.      * @since 1.2.0
  154.      */
  155.     public Validator(final ValidatorResources resources, final String formName, final String fieldName) {
  156.         if (resources == null) {
  157.             throw new IllegalArgumentException("Resources cannot be null.");
  158.         }

  159.         this.resources = resources;
  160.         this.formName = formName;
  161.         this.fieldName = fieldName;
  162.     }

  163.     /**
  164.      * Clears the form name, resources that were added, and the page that was
  165.      * set (if any).  This can be called to reinitialize the Validator instance
  166.      * so it can be reused.  The form name (key to set of validation rules) and any
  167.      * resources needed, like the JavaBean being validated, will need to
  168.      * set and/or added to this instance again.  The
  169.      * <code>ValidatorResources</code> will not be removed since it can be used
  170.      * again and is thread safe.
  171.      */
  172.     public void clear() {
  173.         this.formName = null;
  174.         this.fieldName = null;
  175.         this.parameters = new HashMap<>();
  176.         this.page = 0;
  177.     }

  178.     /**
  179.      * Gets the class loader to be used for instantiating application objects
  180.      * when required.  This is determined based upon the following rules:
  181.      * <ul>
  182.      * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
  183.      * <li>The thread context class loader, if it exists and the
  184.      *     <code>useContextClassLoader</code> property is set to true</li>
  185.      * <li>The class loader used to load the Digester class itself.
  186.      * </ul>
  187.      * @return the class loader.
  188.      */
  189.     public ClassLoader getClassLoader() {
  190.         if (this.classLoader != null) {
  191.             return this.classLoader;
  192.         }

  193.         if (this.useContextClassLoader) {
  194.             final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
  195.             if (contextLoader != null) {
  196.                 return contextLoader;
  197.             }
  198.         }

  199.         return this.getClass().getClassLoader();
  200.     }

  201.     /**
  202.      * Gets the form name which is the key to a set of validation rules.
  203.      * @return the name of the form.
  204.      */
  205.     public String getFormName() {
  206.         return formName;
  207.     }

  208.     /**
  209.      * Returns true if the Validator is only returning Fields that fail validation.
  210.      * @return whether only failed fields are returned.
  211.      */
  212.     public boolean getOnlyReturnErrors() {
  213.         return onlyReturnErrors;
  214.     }

  215.     /**
  216.      * Gets the page.
  217.      *
  218.      * <p>
  219.      * This in conjunction with the page property of
  220.      * a {@code Field} can control the processing of fields. If the field's
  221.      * page is less than or equal to this page value, it will be processed.
  222.      * </p>
  223.      *
  224.      * @return the page number.
  225.      */
  226.     public int getPage() {
  227.         return page;
  228.     }

  229.     /**
  230.      * Returns the value of the specified parameter that will be used during the
  231.      * processing of validations.
  232.      *
  233.      * @param parameterClassName The full class name of the parameter of the
  234.      * validation method that corresponds to the value/instance passed in with it.
  235.      * @return value of the specified parameter.
  236.      */
  237.     public Object getParameterValue(final String parameterClassName) {
  238.         return this.parameters.get(parameterClassName);
  239.     }

  240.     /**
  241.      * Gets the boolean as to whether the context classloader should be used.
  242.      * @return whether the context classloader should be used.
  243.      */
  244.     public boolean getUseContextClassLoader() {
  245.         return this.useContextClassLoader;
  246.     }

  247.     /**
  248.      * Sets the class loader to be used for instantiating application objects
  249.      * when required.
  250.      *
  251.      * @param classLoader The new class loader to use, or {@code null}
  252.      *  to revert to the standard rules
  253.      */
  254.     public void setClassLoader(final ClassLoader classLoader) {
  255.         this.classLoader = classLoader;
  256.     }

  257.     /**
  258.      * Sets the name of the field to validate in a form (optional)
  259.      *
  260.      * @param fieldName The name of the field in a form set
  261.      * @since 1.2.0
  262.      */
  263.     public void setFieldName(final String fieldName) {
  264.         this.fieldName = fieldName;
  265.     }

  266.     /**
  267.      * Sets the form name which is the key to a set of validation rules.
  268.      * @param formName the name of the form.
  269.      */
  270.     public void setFormName(final String formName) {
  271.         this.formName = formName;
  272.     }

  273.     /**
  274.      * Configures which Fields the Validator returns from the validate() method.  Set this
  275.      * to true to only return Fields that failed validation.  By default, validate() returns
  276.      * all fields.
  277.      * @param onlyReturnErrors whether only failed fields are returned.
  278.      */
  279.     public void setOnlyReturnErrors(final boolean onlyReturnErrors) {
  280.         this.onlyReturnErrors = onlyReturnErrors;
  281.     }

  282.     /**
  283.      * Sets the page.
  284.      * <p>
  285.      * This in conjunction with the page property of
  286.      * a {@code Field} can control the processing of fields. If the field's page
  287.      * is less than or equal to this page value, it will be processed.
  288.      * </p>
  289.      *
  290.      * @param page the page number.
  291.      */
  292.     public void setPage(final int page) {
  293.         this.page = page;
  294.     }

  295.     /**
  296.      * Sets a parameter of a pluggable validation method.
  297.      *
  298.      * @param parameterClassName The full class name of the parameter of the
  299.      * validation method that corresponds to the value/instance passed in with it.
  300.      *
  301.      * @param parameterValue The instance that will be passed into the
  302.      * validation method.
  303.      */
  304.     public void setParameter(final String parameterClassName, final Object parameterValue) {
  305.         this.parameters.put(parameterClassName, parameterValue);
  306.     }

  307.     /**
  308.      * Determine whether to use the Context ClassLoader (the one found by
  309.      * calling <code>Thread.currentThread().getContextClassLoader()</code>)
  310.      * to resolve/load classes that are defined in various rules.  If not
  311.      * using Context ClassLoader, then the class-loading defaults to
  312.      * using the calling-class' ClassLoader.
  313.      *
  314.      * @param use determines whether to use Context ClassLoader.
  315.      */
  316.     public void setUseContextClassLoader(final boolean use) {
  317.         this.useContextClassLoader = use;
  318.     }

  319.     /**
  320.      * Performs validations based on the configured resources.
  321.      *
  322.      * @return The <code>Map</code> returned uses the property of the
  323.      * <code>Field</code> for the key and the value is the number of error the
  324.      * field had.
  325.      * @throws ValidatorException If an error occurs during validation
  326.      */
  327.     public ValidatorResults validate() throws ValidatorException {
  328.         Locale locale = (Locale) this.getParameterValue(LOCALE_PARAM);

  329.         if (locale == null) {
  330.             locale = Locale.getDefault();
  331.         }

  332.         this.setParameter(VALIDATOR_PARAM, this);

  333.         final Form form = this.resources.getForm(locale, this.formName);
  334.         if (form != null) {
  335.             this.setParameter(FORM_PARAM, form);
  336.             return form.validate(
  337.                 this.parameters,
  338.                 this.resources.getValidatorActions(),
  339.                 this.page,
  340.                 this.fieldName);
  341.         }

  342.         return new ValidatorResults();
  343.     }

  344. }