View Javadoc

    1   /*
    2    * $Id: Form.java 280974 2005-09-15 00:06:59Z niallp $
    3    * $Rev: 280974 $
    4    * $Date: 2005-09-15 01:06:59 +0100 (Thu, 15 Sep 2005) $
    5    *
    6    * ====================================================================
    7    * Copyright 2001-2005 The Apache Software Foundation
    8    *
    9    * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *     http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   */
    21  package org.apache.commons.validator;
    22
    23  import java.io.Serializable;
    24  import java.util.ArrayList;
    25  import java.util.Collections;
    26  import java.util.Iterator;
    27  import java.util.List;
    28  import java.util.Map;
    29
    30  import org.apache.commons.collections.FastHashMap;// DEPRECATED
    31
    32  /***
    33   * <p>
    34   *
    35   * This contains a set of validation rules for a form/JavaBean. The information
    36   * is contained in a list of <code>Field</code> objects. Instances of this class
    37   * are configured with a &lt;form&gt; xml element. </p> <p>
    38   *
    39   * The use of FastHashMap is deprecated and will be replaced in a future
    40   * release. </p>
    41   */
    42  public class Form implements Serializable {
    43
    44      /*** The name/key the set of validation rules is stored under. */
    45      protected String name = null;
    46
    47      /***
    48       * List of <code>Field</code>s. Used to maintain the order they were added
    49       * in although individual <code>Field</code>s can be retrieved using <code>Map</code>
    50       * of <code>Field</code>s.
    51       */
    52      protected List lFields = new ArrayList();
    53
    54      /***
    55       * Map of <code>Field</code>s keyed on their property value.
    56       *
    57       * @deprecated   Subclasses should use getFieldMap() instead.
    58       */
    59      protected FastHashMap hFields = new FastHashMap();
    60
    61      /***
    62       * The name/key of the form which this form extends from.
    63       *
    64       * @since   Validator 1.2.0
    65       */
    66      protected String inherit = null;
    67
    68      /***
    69       * Whether or not the this <code>Form</code> was processed for replacing
    70       * variables in strings with their values.
    71       */
    72      private boolean processed = false;
    73
    74      /***
    75       * Gets the name/key of the set of validation rules.
    76       *
    77       * @return   The name value
    78       */
    79      public String getName() {
    80          return name;
    81      }
    82
    83      /***
    84       * Sets the name/key of the set of validation rules.
    85       *
    86       * @param name  The new name value
    87       */
    88      public void setName(String name) {
    89          this.name = name;
    90      }
    91
    92      /***
    93       * Add a <code>Field</code> to the <code>Form</code>.
    94       *
    95       * @param f  The field
    96       */
    97      public void addField(Field f) {
    98          this.lFields.add(f);
    99          this.hFields.put(f.getKey(), f);
    100     }
    101
    102     /***
    103      * A <code>List</code> of <code>Field</code>s is returned as an unmodifiable
    104      * <code>List</code>.
    105      *
    106      * @return   The fields value
    107      */
    108     public List getFields() {
    109         return Collections.unmodifiableList(lFields);
    110     }
    111
    112     /***
    113      * Returns the Field with the given name or null if this Form has no such
    114      * field.
    115      *
    116      * @param fieldName  The field name
    117      * @return           The field value
    118      * @since            Validator 1.1
    119      */
    120     public Field getField(String fieldName) {
    121         return (Field) this.hFields.get(fieldName);
    122     }
    123
    124     /***
    125      * Returns true if this Form contains a Field with the given name.
    126      *
    127      * @param fieldName  The field name
    128      * @return           True if this form contains the field by the given name
    129      * @since            Validator 1.1
    130      */
    131     public boolean containsField(String fieldName) {
    132         return this.hFields.containsKey(fieldName);
    133     }
    134
    135     /***
    136      * Merges the given form into this one. For any field in <code>depends</code>
    137      * not present in this form, include it. <code>depends</code> has precedence
    138      * in the way the fields are ordered.
    139      *
    140      * @param depends  the form we want to merge
    141      * @since          Validator 1.2.0
    142      */
    143     protected void merge(Form depends) {
    144
    145         List templFields = new ArrayList();
    146         Map temphFields = new FastHashMap();
    147         Iterator dependsIt = depends.getFields().iterator();
    148         while (dependsIt.hasNext()) {
    149             Field defaultField = (Field) dependsIt.next();
    150             if (defaultField != null) {
    151                 String fieldKey = defaultField.getKey();
    152                 if (!this.containsField(fieldKey)) {
    153                     templFields.add(defaultField);
    154                     temphFields.put(fieldKey, defaultField);
    155                 }
    156                 else {
    157                     Field old = getField(fieldKey);
    158                     hFields.remove(fieldKey);
    159                     lFields.remove(old);
    160                     templFields.add(old);
    161                     temphFields.put(fieldKey, old);
    162                 }
    163             }
    164         }
    165         lFields.addAll(0, templFields);
    166         hFields.putAll(temphFields);
    167     }
    168
    169     /***
    170      * Processes all of the <code>Form</code>'s <code>Field</code>s.
    171      *
    172      * @param globalConstants  A map of global constants
    173      * @param constants        Local constants
    174      * @param forms            Map of forms
    175      * @since                  Validator 1.2.0
    176      */
    177     protected void process(Map globalConstants, Map constants, Map forms) {
    178         if (isProcessed()) {
    179             return;
    180         }
    181
    182         int n = 0;//we want the fields from its parent first
    183         if (isExtending()) {
    184             Form parent = (Form) forms.get(inherit);
    185             if (parent != null) {
    186                 if (!parent.isProcessed()) {
    187                     //we want to go all the way up the tree
    188                     parent.process(constants, globalConstants, forms);
    189                 }
    190                 for (Iterator i = parent.getFields().iterator(); i.hasNext(); ) {
    191                     Field f = (Field) i.next();
    192                     //we want to be able to override any fields we like
    193                     if (hFields.get(f.getKey()) == null) {
    194                         lFields.add(n, f);
    195                         hFields.put(f.getKey(), f);
    196                         n++;
    197                     }
    198                 }
    199             }
    200         }
    201         hFields.setFast(true);
    202         //no need to reprocess parent's fields, we iterate from 'n'
    203         for (Iterator i = lFields.listIterator(n); i.hasNext(); ) {
    204             Field f = (Field) i.next();
    205             f.process(globalConstants, constants);
    206         }
    207
    208         processed = true;
    209     }
    210
    211     /***
    212      * Returns a string representation of the object.
    213      *
    214      * @return string representation
    215      */
    216     public String toString() {
    217         StringBuffer results = new StringBuffer();
    218
    219         results.append("Form: ");
    220         results.append(name);
    221         results.append("\n");
    222
    223         for (Iterator i = lFields.iterator(); i.hasNext(); ) {
    224             results.append("\tField: \n");
    225             results.append(i.next());
    226             results.append("\n");
    227         }
    228
    229         return results.toString();
    230     }
    231
    232     /***
    233      * Validate all Fields in this Form on the given page and below.
    234      *
    235      * @param params               A Map of parameter class names to parameter
    236      *      values to pass into validation methods.
    237      * @param actions              A Map of validator names to ValidatorAction
    238      *      objects.
    239      * @param page                 Fields on pages higher than this will not be
    240      *      validated.
    241      * @return                     A ValidatorResults object containing all
    242      *      validation messages.
    243      * @throws ValidatorException
    244      */
    245     ValidatorResults validate(Map params, Map actions, int page)
    246         throws ValidatorException {
    247         return validate(params, actions, page, null);
    248     }
    249
    250     /***
    251      * Validate all Fields in this Form on the given page and below.
    252      *
    253      * @param params               A Map of parameter class names to parameter
    254      *      values to pass into validation methods.
    255      * @param actions              A Map of validator names to ValidatorAction
    256      *      objects.
    257      * @param page                 Fields on pages higher than this will not be
    258      *      validated.
    259      * @return                     A ValidatorResults object containing all
    260      *      validation messages.
    261      * @throws ValidatorException
    262      * @since 1.2.0
    263      */
    264     ValidatorResults validate(Map params, Map actions, int page, String fieldName)
    265         throws ValidatorException {
    266
    267         ValidatorResults results = new ValidatorResults();
    268         params.put(Validator.VALIDATOR_RESULTS_PARAM, results);
    269
    270         // Only validate a single field if specified
    271         if (fieldName != null) {
    272             Field field = (Field) this.hFields.get(fieldName);
    273
    274             if (field == null) {
    275                throw new ValidatorException("Unknown field "+fieldName+" in form "+getName());
    276             }
    277             params.put(Validator.FIELD_PARAM, field);
    278
    279             if (field.getPage() <= page) {
    280                results.merge(field.validate(params, actions));
    281             }
    282         } else {
    283             Iterator fields = this.lFields.iterator();
    284             while (fields.hasNext()) {
    285                 Field field = (Field) fields.next();
    286
    287                 params.put(Validator.FIELD_PARAM, field);
    288
    289                 if (field.getPage() <= page) {
    290                     results.merge(field.validate(params, actions));
    291                 }
    292             }
    293         }
    294
    295         return results;
    296     }
    297
    298     /***
    299      * Whether or not the this <code>Form</code> was processed for replacing
    300      * variables in strings with their values.
    301      *
    302      * @return   The processed value
    303      * @since    Validator 1.2.0
    304      */
    305     public boolean isProcessed() {
    306         return processed;
    307     }
    308
    309     /***
    310      * Gets the name/key of the parent set of validation rules.
    311      *
    312      * @return   The extends value
    313      * @since    Validator 1.2.0
    314      */
    315     public String getExtends() {
    316         return inherit;
    317     }
    318
    319     /***
    320      * Sets the name/key of the parent set of validation rules.
    321      *
    322      * @param inherit  The new extends value
    323      * @since          Validator 1.2.0
    324      */
    325     public void setExtends(String inherit) {
    326         this.inherit = inherit;
    327     }
    328
    329     /***
    330      * Get extends flag.
    331      *
    332      * @return   The extending value
    333      * @since    Validator 1.2.0
    334      */
    335     public boolean isExtending() {
    336         return inherit != null;
    337     }
    338
    339     /***
    340      * Returns a Map of String field keys to Field objects.
    341      *
    342      * @return   The fieldMap value
    343      * @since    Validator 1.2.0
    344      */
    345     protected Map getFieldMap() {
    346         return hFields;
    347     }
    348 }