View Javadoc

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