Coverage Report - org.apache.commons.validator.Form
 
Classes in this File Line Coverage Branch Coverage Complexity
Form
84%
76/90
76%
26/34
2.125
 
 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: 1739361 $
 39  
  */
 40  
 //TODO mutable non-private fields
 41  430
 public class Form implements Serializable {
 42  
 
 43  
     private static final long serialVersionUID = 6445211789563796371L;
 44  
 
 45  
     /** The name/key the set of validation rules is stored under. */
 46  430
     protected String name = null;
 47  
 
 48  
     /**
 49  
      * List of <code>Field</code>s. Used to maintain the order they were added
 50  
      * in although individual <code>Field</code>s can be retrieved using <code>Map</code>
 51  
      * of <code>Field</code>s.
 52  
      */
 53  430
     protected List<Field> lFields = new ArrayList<Field>();
 54  
 
 55  
     /**
 56  
      * Map of <code>Field</code>s keyed on their property value.
 57  
      *
 58  
      * @deprecated   Subclasses should use getFieldMap() instead.
 59  
      */
 60  430
     @Deprecated
 61  
     protected FastHashMap hFields = new FastHashMap(); // <String, Field>
 62  
 
 63  
     /**
 64  
      * The name/key of the form which this form extends from.
 65  
      *
 66  
      * @since   Validator 1.2.0
 67  
      */
 68  430
     protected String inherit = null;
 69  
 
 70  
     /**
 71  
      * Whether or not the this <code>Form</code> was processed for replacing
 72  
      * variables in strings with their values.
 73  
      */
 74  430
     private boolean processed = false;
 75  
 
 76  
     /**
 77  
      * Gets the name/key of the set of validation rules.
 78  
      *
 79  
      * @return   The name value
 80  
      */
 81  
     public String getName() {
 82  970
         return name;
 83  
     }
 84  
 
 85  
     /**
 86  
      * Sets the name/key of the set of validation rules.
 87  
      *
 88  
      * @param name  The new name value
 89  
      */
 90  
     public void setName(String name) {
 91  430
         this.name = name;
 92  430
     }
 93  
 
 94  
     /**
 95  
      * Add a <code>Field</code> to the <code>Form</code>.
 96  
      *
 97  
      * @param f  The field
 98  
      */
 99  
     public void addField(Field f) {
 100  533
         this.lFields.add(f);
 101  533
         getFieldMap().put(f.getKey(), f);
 102  533
     }
 103  
 
 104  
     /**
 105  
      * A <code>List</code> of <code>Field</code>s is returned as an unmodifiable
 106  
      * <code>List</code>.
 107  
      *
 108  
      * @return   The fields value
 109  
      */
 110  
     public List<Field> getFields() {
 111  77
         return Collections.unmodifiableList(lFields);
 112  
     }
 113  
 
 114  
     /**
 115  
      * Returns the Field with the given name or null if this Form has no such
 116  
      * field.
 117  
      *
 118  
      * @param fieldName  The field name
 119  
      * @return           The field value
 120  
      * @since            Validator 1.1
 121  
      */
 122  
     public Field getField(String fieldName) {
 123  100
         return getFieldMap().get(fieldName);
 124  
     }
 125  
 
 126  
     /**
 127  
      * Returns true if this Form contains a Field with the given name.
 128  
      *
 129  
      * @param fieldName  The field name
 130  
      * @return           True if this form contains the field by the given name
 131  
      * @since            Validator 1.1
 132  
      */
 133  
     public boolean containsField(String fieldName) {
 134  70
         return getFieldMap().containsKey(fieldName);
 135  
     }
 136  
 
 137  
     /**
 138  
      * Merges the given form into this one. For any field in <code>depends</code>
 139  
      * not present in this form, include it. <code>depends</code> has precedence
 140  
      * in the way the fields are ordered.
 141  
      *
 142  
      * @param depends  the form we want to merge
 143  
      * @since          Validator 1.2.0
 144  
      */
 145  
     protected void merge(Form depends) {
 146  
 
 147  55
         List<Field> templFields = new ArrayList<Field>();
 148  
         @SuppressWarnings("unchecked") // FastHashMap is not generic
 149  55
         Map<String, Field> temphFields = new FastHashMap();
 150  55
         Iterator<Field> dependsIt = depends.getFields().iterator();
 151  125
         while (dependsIt.hasNext()) {
 152  70
             Field defaultField = dependsIt.next();
 153  70
             if (defaultField != null) {
 154  70
                 String fieldKey = defaultField.getKey();
 155  70
                 if (!this.containsField(fieldKey)) {
 156  0
                     templFields.add(defaultField);
 157  0
                     temphFields.put(fieldKey, defaultField);
 158  
                 }
 159  
                 else {
 160  70
                     Field old = getField(fieldKey);
 161  70
                     getFieldMap().remove(fieldKey);
 162  70
                     lFields.remove(old);
 163  70
                     templFields.add(old);
 164  70
                     temphFields.put(fieldKey, old);
 165  
                 }
 166  
             }
 167  70
         }
 168  55
         lFields.addAll(0, templFields);
 169  55
         getFieldMap().putAll(temphFields);
 170  55
     }
 171  
 
 172  
     /**
 173  
      * Processes all of the <code>Form</code>'s <code>Field</code>s.
 174  
      *
 175  
      * @param globalConstants  A map of global constants
 176  
      * @param constants        Local constants
 177  
      * @param forms            Map of forms
 178  
      * @since                  Validator 1.2.0
 179  
      */
 180  
     protected void process(Map<String, String> globalConstants, Map<String, String> constants, Map<String, Form> forms) {
 181  493
         if (isProcessed()) {
 182  63
             return;
 183  
         }
 184  
 
 185  430
         int n = 0;//we want the fields from its parent first
 186  430
         if (isExtending()) {
 187  16
             Form parent = forms.get(inherit);
 188  16
             if (parent != null) {
 189  16
                 if (!parent.isProcessed()) {
 190  
                     //we want to go all the way up the tree
 191  8
                     parent.process(constants, globalConstants, forms);
 192  
                 }
 193  16
                 for (Iterator<Field> i = parent.getFields().iterator(); i.hasNext(); ) {
 194  24
                     Field f = i.next();
 195  
                     //we want to be able to override any fields we like
 196  24
                     if (getFieldMap().get(f.getKey()) == null) {
 197  8
                         lFields.add(n, f);
 198  8
                         getFieldMap().put(f.getKey(), f);
 199  8
                         n++;
 200  
                     }
 201  24
                 }
 202  
             }
 203  
         }
 204  430
         hFields.setFast(true);
 205  
         //no need to reprocess parent's fields, we iterate from 'n'
 206  430
         for (Iterator<Field> i = lFields.listIterator(n); i.hasNext(); ) {
 207  533
             Field f = i.next();
 208  533
             f.process(globalConstants, constants);
 209  533
         }
 210  
 
 211  430
         processed = true;
 212  430
     }
 213  
 
 214  
     /**
 215  
      * Returns a string representation of the object.
 216  
      *
 217  
      * @return string representation
 218  
      */
 219  
     @Override
 220  
     public String toString() {
 221  0
         StringBuilder results = new StringBuilder();
 222  
 
 223  0
         results.append("Form: ");
 224  0
         results.append(name);
 225  0
         results.append("\n");
 226  
 
 227  0
         for (Iterator<Field> i = lFields.iterator(); i.hasNext(); ) {
 228  0
             results.append("\tField: \n");
 229  0
             results.append(i.next());
 230  0
             results.append("\n");
 231  
         }
 232  
 
 233  0
         return results.toString();
 234  
     }
 235  
 
 236  
     /**
 237  
      * Validate all Fields in this Form on the given page and below.
 238  
      *
 239  
      * @param params               A Map of parameter class names to parameter
 240  
      *      values to pass into validation methods.
 241  
      * @param actions              A Map of validator names to ValidatorAction
 242  
      *      objects.
 243  
      * @param page                 Fields on pages higher than this will not be
 244  
      *      validated.
 245  
      * @return                     A ValidatorResults object containing all
 246  
      *      validation messages.
 247  
      * @throws ValidatorException
 248  
      */
 249  
     ValidatorResults validate(Map<String, Object> params, Map<String, ValidatorAction> actions, int page)
 250  
         throws ValidatorException {
 251  0
         return validate(params, actions, page, null);
 252  
     }
 253  
 
 254  
     /**
 255  
      * Validate all Fields in this Form on the given page and below.
 256  
      *
 257  
      * @param params               A Map of parameter class names to parameter
 258  
      *      values to pass into validation methods.
 259  
      * @param actions              A Map of validator names to ValidatorAction
 260  
      *      objects.
 261  
      * @param page                 Fields on pages higher than this will not be
 262  
      *      validated.
 263  
      * @return                     A ValidatorResults object containing all
 264  
      *      validation messages.
 265  
      * @throws ValidatorException
 266  
      * @since 1.2.0
 267  
      */
 268  
     ValidatorResults validate(Map<String, Object> params, Map<String, ValidatorAction> actions, int page, String fieldName)
 269  
         throws ValidatorException {
 270  125
         ValidatorResults results = new ValidatorResults();
 271  125
         params.put(Validator.VALIDATOR_RESULTS_PARAM, results);
 272  
 
 273  
         // Only validate a single field if specified
 274  125
         if (fieldName != null) {
 275  1
             Field field = getFieldMap().get(fieldName);
 276  
 
 277  1
             if (field == null) {
 278  0
                throw new ValidatorException("Unknown field "+fieldName+" in form "+getName());
 279  
             }
 280  1
             params.put(Validator.FIELD_PARAM, field);
 281  
 
 282  1
             if (field.getPage() <= page) {
 283  1
                results.merge(field.validate(params, actions));
 284  
             }
 285  1
         } else {
 286  124
             Iterator<Field> fields = this.lFields.iterator();
 287  312
             while (fields.hasNext()) {
 288  189
                 Field field = fields.next();
 289  
 
 290  189
                 params.put(Validator.FIELD_PARAM, field);
 291  
 
 292  189
                 if (field.getPage() <= page) {
 293  189
                     results.merge(field.validate(params, actions));
 294  
                 }
 295  188
             }
 296  
         }
 297  
 
 298  124
         return results;
 299  
     }
 300  
 
 301  
     /**
 302  
      * Whether or not the this <code>Form</code> was processed for replacing
 303  
      * variables in strings with their values.
 304  
      *
 305  
      * @return   The processed value
 306  
      * @since    Validator 1.2.0
 307  
      */
 308  
     public boolean isProcessed() {
 309  509
         return processed;
 310  
     }
 311  
 
 312  
     /**
 313  
      * Gets the name/key of the parent set of validation rules.
 314  
      *
 315  
      * @return   The extends value
 316  
      * @since    Validator 1.2.0
 317  
      */
 318  
     public String getExtends() {
 319  0
         return inherit;
 320  
     }
 321  
 
 322  
     /**
 323  
      * Sets the name/key of the parent set of validation rules.
 324  
      *
 325  
      * @param inherit  The new extends value
 326  
      * @since          Validator 1.2.0
 327  
      */
 328  
     public void setExtends(String inherit) {
 329  16
         this.inherit = inherit;
 330  16
     }
 331  
 
 332  
     /**
 333  
      * Get extends flag.
 334  
      *
 335  
      * @return   The extending value
 336  
      * @since    Validator 1.2.0
 337  
      */
 338  
     public boolean isExtending() {
 339  430
         return inherit != null;
 340  
     }
 341  
 
 342  
     /**
 343  
      * Returns a Map of String field keys to Field objects.
 344  
      *
 345  
      * @return   The fieldMap value
 346  
      * @since    Validator 1.2.0
 347  
      */
 348  
     @SuppressWarnings("unchecked") // FastHashMap is not generic
 349  
     protected Map<String, Field> getFieldMap() {
 350  861
         return hFields;
 351  
     }
 352  
 }