Coverage Report - org.apache.commons.validator.FormSet
 
Classes in this File Line Coverage Branch Coverage Complexity
FormSet
58%
54/93
36%
17/46
2.556
 
 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.Collections;
 21  
 import java.util.HashMap;
 22  
 import java.util.Iterator;
 23  
 import java.util.Map;
 24  
 import java.util.Map.Entry;
 25  
 
 26  
 import org.apache.commons.logging.Log;
 27  
 import org.apache.commons.logging.LogFactory;
 28  
 
 29  
 /**
 30  
  * Holds a set of <code>Form</code>s stored associated with a <code>Locale</code>
 31  
  * based on the country, language, and variant specified. Instances of this
 32  
  * class are configured with a &lt;formset&gt; xml element.
 33  
  *
 34  
  * @version $Revision: 1739361 $
 35  
  */
 36  151
 public class FormSet implements Serializable {
 37  
 
 38  
     private static final long serialVersionUID = -8936513232763306055L;
 39  
 
 40  
     /** Logging */
 41  151
     private transient Log log = LogFactory.getLog(FormSet.class);
 42  
 
 43  
     /**
 44  
      * Whether or not the this <code>FormSet</code> was processed for replacing
 45  
      * variables in strings with their values.
 46  
      */
 47  151
     private boolean processed = false;
 48  
 
 49  
     /** Language component of <code>Locale</code> (required). */
 50  151
     private String language = null;
 51  
 
 52  
     /** Country component of <code>Locale</code> (optional). */
 53  151
     private String country = null;
 54  
 
 55  
     /** Variant component of <code>Locale</code> (optional). */
 56  151
     private String variant = null;
 57  
 
 58  
     /**
 59  
      * A <code>Map</code> of <code>Form</code>s using the name field of the
 60  
      * <code>Form</code> as the key.
 61  
      */
 62  151
     private final Map<String, Form> forms = new HashMap<String, Form>();
 63  
 
 64  
     /**
 65  
      * A <code>Map</code> of <code>Constant</code>s using the name field of the
 66  
      * <code>Constant</code> as the key.
 67  
      */
 68  151
     private final Map<String, String> constants = new HashMap<String, String>();
 69  
 
 70  
     /**
 71  
      * This is the type of <code>FormSet</code>s where no locale is specified.
 72  
      */
 73  
     protected final static int GLOBAL_FORMSET = 1;
 74  
 
 75  
     /**
 76  
      * This is the type of <code>FormSet</code>s where only language locale is
 77  
      * specified.
 78  
      */
 79  
     protected final static int LANGUAGE_FORMSET = 2;
 80  
 
 81  
     /**
 82  
      * This is the type of <code>FormSet</code>s where only language and country
 83  
      * locale are specified.
 84  
      */
 85  
     protected final static int COUNTRY_FORMSET = 3;
 86  
 
 87  
     /**
 88  
      * This is the type of <code>FormSet</code>s where full locale has been set.
 89  
      */
 90  
     protected final static int VARIANT_FORMSET = 4;
 91  
 
 92  
     /**
 93  
      * Flag indicating if this formSet has been merged with its parent (higher
 94  
      * rank in Locale hierarchy).
 95  
      */
 96  
     private boolean merged;
 97  
 
 98  
     /**
 99  
      * Has this formSet been merged?
 100  
      *
 101  
      * @return   true if it has been merged
 102  
      * @since    Validator 1.2.0
 103  
      */
 104  
     protected boolean isMerged() {
 105  0
         return merged;
 106  
     }
 107  
 
 108  
     /**
 109  
      * Returns the type of <code>FormSet</code>:<code>GLOBAL_FORMSET</code>,
 110  
      * <code>LANGUAGE_FORMSET</code>,<code>COUNTRY_FORMSET</code> or <code>VARIANT_FORMSET</code>
 111  
      * .
 112  
      *
 113  
      * @return                       The type value
 114  
      * @since                        Validator 1.2.0
 115  
      * @throws NullPointerException  if there is inconsistency in the locale
 116  
      *      definition (not sure about this)
 117  
      */
 118  
     protected int getType() {
 119  85
         if (getVariant() != null) {
 120  45
             if (getLanguage() == null || getCountry() == null) {
 121  0
                 throw new NullPointerException(
 122  
                     "When variant is specified, country and language must be specified.");
 123  
             }
 124  45
             return VARIANT_FORMSET;
 125  
         }
 126  40
         else if (getCountry() != null) {
 127  30
             if (getLanguage() == null) {
 128  0
                 throw new NullPointerException(
 129  
                     "When country is specified, language must be specified.");
 130  
             }
 131  30
             return COUNTRY_FORMSET;
 132  
         }
 133  10
         else if (getLanguage() != null) {
 134  10
             return LANGUAGE_FORMSET;
 135  
         }
 136  
         else {
 137  0
             return GLOBAL_FORMSET;
 138  
         }
 139  
     }
 140  
 
 141  
     /**
 142  
      * Merges the given <code>FormSet</code> into this one. If any of <code>depends</code>
 143  
      * s <code>Forms</code> are not in this <code>FormSet</code> then, include
 144  
      * them, else merge both <code>Forms</code>. Theoretically we should only
 145  
      * merge a "parent" formSet.
 146  
      *
 147  
      * @param depends  FormSet to be merged
 148  
      * @since          Validator 1.2.0
 149  
      */
 150  
     protected void merge(FormSet depends) {
 151  40
         if (depends != null) {
 152  40
             Map<String, Form> pForms = getForms();
 153  40
             Map<String, Form> dForms = depends.getForms();
 154  40
             for (Iterator<Entry<String, Form>> it = dForms.entrySet().iterator(); it.hasNext(); ) {
 155  110
                 Entry<String, Form> entry = it.next();
 156  110
                 String key = entry.getKey();
 157  110
                 Form pForm = pForms.get(key);
 158  110
                 if (pForm != null) {//merge, but principal 'rules', don't overwrite
 159  
                     // anything
 160  55
                     pForm.merge(entry.getValue());
 161  
                 }
 162  
                 else {//just add
 163  55
                     addForm(entry.getValue());
 164  
                 }
 165  110
             }
 166  
         }
 167  40
         merged = true;
 168  40
     }
 169  
 
 170  
     /**
 171  
      * Whether or not the this <code>FormSet</code> was processed for replacing
 172  
      * variables in strings with their values.
 173  
      *
 174  
      * @return   The processed value
 175  
      */
 176  
     public boolean isProcessed() {
 177  40
         return processed;
 178  
     }
 179  
 
 180  
     /**
 181  
      * Gets the equivalent of the language component of <code>Locale</code>.
 182  
      *
 183  
      * @return   The language value
 184  
      */
 185  
     public String getLanguage() {
 186  276
         return language;
 187  
     }
 188  
 
 189  
     /**
 190  
      * Sets the equivalent of the language component of <code>Locale</code>.
 191  
      *
 192  
      * @param language  The new language value
 193  
      */
 194  
     public void setLanguage(String language) {
 195  147
         this.language = language;
 196  147
     }
 197  
 
 198  
     /**
 199  
      * Gets the equivalent of the country component of <code>Locale</code>.
 200  
      *
 201  
      * @return   The country value
 202  
      */
 203  
     public String getCountry() {
 204  251
         return country;
 205  
     }
 206  
 
 207  
     /**
 208  
      * Sets the equivalent of the country component of <code>Locale</code>.
 209  
      *
 210  
      * @param country  The new country value
 211  
      */
 212  
     public void setCountry(String country) {
 213  147
         this.country = country;
 214  147
     }
 215  
 
 216  
     /**
 217  
      * Gets the equivalent of the variant component of <code>Locale</code>.
 218  
      *
 219  
      * @return   The variant value
 220  
      */
 221  
     public String getVariant() {
 222  236
         return variant;
 223  
     }
 224  
 
 225  
     /**
 226  
      * Sets the equivalent of the variant component of <code>Locale</code>.
 227  
      *
 228  
      * @param variant  The new variant value
 229  
      */
 230  
     public void setVariant(String variant) {
 231  147
         this.variant = variant;
 232  147
     }
 233  
 
 234  
     /**
 235  
      * Add a <code>Constant</code> to the locale level.
 236  
      *
 237  
      * @param name   The constant name
 238  
      * @param value  The constant value
 239  
      */
 240  
     public void addConstant(String name, String value) {
 241  
 
 242  20
         if (constants.containsKey(name)) {
 243  0
             getLog().error("Constant '" + name +  "' already exists in FormSet["
 244  
                       + this.displayKey() + "] - ignoring.");
 245  
 
 246  
         } else {
 247  20
             constants.put(name, value);
 248  
         }
 249  
 
 250  20
     }
 251  
 
 252  
     /**
 253  
      * Add a <code>Form</code> to the <code>FormSet</code>.
 254  
      *
 255  
      * @param f  The form
 256  
      */
 257  
     public void addForm(Form f) {
 258  
 
 259  485
         String formName = f.getName();
 260  485
         if (forms.containsKey(formName)) {
 261  0
             getLog().error("Form '" + formName + "' already exists in FormSet["
 262  
                       + this.displayKey() + "] - ignoring.");
 263  
 
 264  
         } else {
 265  485
             forms.put(f.getName(), f);
 266  
         }
 267  
 
 268  485
     }
 269  
 
 270  
     /**
 271  
      * Retrieve a <code>Form</code> based on the form name.
 272  
      *
 273  
      * @param formName  The form name
 274  
      * @return          The form
 275  
      */
 276  
     public Form getForm(String formName) {
 277  176
         return this.forms.get(formName);
 278  
     }
 279  
 
 280  
     /**
 281  
      * A <code>Map</code> of <code>Form</code>s is returned as an unmodifiable
 282  
      * <code>Map</code> with the key based on the form name.
 283  
      *
 284  
      * @return   The forms map
 285  
      */
 286  
     public Map<String, Form> getForms() {
 287  80
         return Collections.unmodifiableMap(forms);
 288  
     }
 289  
 
 290  
     /**
 291  
      * Processes all of the <code>Form</code>s.
 292  
      *
 293  
      * @param globalConstants  Global constants
 294  
      */
 295  
     synchronized void process(Map<String, String> globalConstants) {
 296  151
         for (Iterator<Form> i = forms.values().iterator(); i.hasNext(); ) {
 297  485
             Form f = i.next();
 298  485
             f.process(globalConstants, constants, forms);
 299  485
         }
 300  
 
 301  151
         processed = true;
 302  151
     }
 303  
 
 304  
     /**
 305  
      * Returns a string representation of the object's key.
 306  
      *
 307  
      * @return   A string representation of the key
 308  
      */
 309  
     public String displayKey() {
 310  0
         StringBuilder results = new StringBuilder();
 311  0
         if (language != null && language.length() > 0) {
 312  0
             results.append("language=");
 313  0
             results.append(language);
 314  
         }
 315  0
         if (country != null && country.length() > 0) {
 316  0
             if (results.length() > 0) {
 317  0
                results.append(", ");
 318  
             }
 319  0
             results.append("country=");
 320  0
             results.append(country);
 321  
         }
 322  0
         if (variant != null && variant.length() > 0) {
 323  0
             if (results.length() > 0) {
 324  0
                results.append(", ");
 325  
             }
 326  0
             results.append("variant=");
 327  0
             results.append(variant );
 328  
         }
 329  0
         if (results.length() == 0) {
 330  0
            results.append("default");
 331  
         }
 332  
 
 333  0
         return results.toString();
 334  
     }
 335  
 
 336  
     /**
 337  
      * Returns a string representation of the object.
 338  
      *
 339  
      * @return   A string representation
 340  
      */
 341  
     @Override
 342  
     public String toString() {
 343  0
         StringBuilder results = new StringBuilder();
 344  
 
 345  0
         results.append("FormSet: language=");
 346  0
         results.append(language);
 347  0
         results.append("  country=");
 348  0
         results.append(country);
 349  0
         results.append("  variant=");
 350  0
         results.append(variant);
 351  0
         results.append("\n");
 352  
 
 353  0
         for (Iterator<?> i = getForms().values().iterator(); i.hasNext(); ) {
 354  0
             results.append("   ");
 355  0
             results.append(i.next());
 356  0
             results.append("\n");
 357  
         }
 358  
 
 359  0
         return results.toString();
 360  
     }
 361  
 
 362  
     /**
 363  
      * Accessor method for Log instance.
 364  
      *
 365  
      * The Log instance variable is transient and
 366  
      * accessing it through this method ensures it
 367  
      * is re-initialized when this instance is
 368  
      * de-serialized.
 369  
      *
 370  
      * @return The Log instance.
 371  
      */
 372  
     private Log getLog() {
 373  0
         if (log == null) {
 374  0
             log =  LogFactory.getLog(FormSet.class);
 375  
         }
 376  0
         return log;
 377  
     }
 378  
 }