commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mr...@apache.org
Subject svn commit: r264683 - in /jakarta/commons/proper/validator/trunk/src: share/org/apache/commons/validator/ test/org/apache/commons/validator/
Date Tue, 30 Aug 2005 03:03:18 GMT
Author: mrdon
Date: Mon Aug 29 20:03:15 2005
New Revision: 264683

URL: http://svn.apache.org/viewcvs?rev=264683&view=rev
Log:
 * Adding patch that improves form merging with locales
 * Adding javadocs, cleaned up formatting
 PR: 30955

Modified:
    jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/Form.java
    jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/FormSet.java
    jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ValidatorResources.java
    jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/LocaleTest.java
    jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/validator-locale.xml

Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/Form.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/Form.java?rev=264683&r1=264682&r2=264683&view=diff
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/Form.java
(original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/Form.java
Mon Aug 29 20:03:15 2005
@@ -18,7 +18,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.validator;
 
 import java.io.Serializable;
@@ -28,54 +27,54 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.collections.FastHashMap; // DEPRECATED
+import org.apache.commons.collections.FastHashMap;// DEPRECATED
 
 /**
  * <p>
- * This contains a set of validation rules for a form/JavaBean.  The information 
- * is contained in a list of <code>Field</code> objects.  Instances of this 
- * class are configured with a &lt;form&gt; xml element.
- * </p>
- * <p>
+ *
+ * This contains a set of validation rules for a form/JavaBean. The information
+ * is contained in a list of <code>Field</code> objects. Instances of this class
+ * are configured with a &lt;form&gt; xml element. </p> <p>
+ *
  * The use of FastHashMap is deprecated and will be replaced in a future
- * release.
- * </p>
+ * release. </p>
  */
 public class Form implements Serializable {
 
-    /**
-     * The name/key the set of validation rules is stored under.
-     */
+    /** The name/key the set of validation rules is stored under. */
     protected String name = null;
 
     /**
-     * List of <code>Field</code>s.  Used to maintain
-     * the order they were added in although individual
-     * <code>Field</code>s can be retrieved using
-     * <code>Map</code> of <code>Field</code>s.
+     * List of <code>Field</code>s. Used to maintain the order they were added
+     * in although individual <code>Field</code>s can be retrieved using <code>Map</code>
+     * of <code>Field</code>s.
      */
     protected List lFields = new ArrayList();
 
     /**
      * Map of <code>Field</code>s keyed on their property value.
-     * @deprecated Subclasses should use getFieldMap() instead.
+     *
+     * @deprecated   Subclasses should use getFieldMap() instead.
      */
     protected FastHashMap hFields = new FastHashMap();
 
     /**
      * The name/key of the form which this form extends from.
-     * @since Validator 1.2.0
+     *
+     * @since   Validator 1.2.0
      */
     protected String inherit = null;
 
     /**
-     * Whether or not the this <code>Form</code> was processed
-     * for replacing variables in strings with their values.
+     * Whether or not the this <code>Form</code> was processed for replacing
+     * variables in strings with their values.
      */
     private boolean processed = false;
 
     /**
      * Gets the name/key of the set of validation rules.
+     *
+     * @return   The name value
      */
     public String getName() {
         return name;
@@ -83,6 +82,8 @@
 
     /**
      * Sets the name/key of the set of validation rules.
+     *
+     * @param name  The new name value
      */
     public void setName(String name) {
         this.name = name;
@@ -90,6 +91,8 @@
 
     /**
      * Add a <code>Field</code> to the <code>Form</code>.
+     *
+     * @param f  The field
      */
     public void addField(Field f) {
         this.lFields.add(f);
@@ -97,8 +100,10 @@
     }
 
     /**
-     * A <code>List</code> of <code>Field</code>s is returned as
an
-     * unmodifiable <code>List</code>.
+     * A <code>List</code> of <code>Field</code>s is returned as
an unmodifiable
+     * <code>List</code>.
+     *
+     * @return   The fields value
      */
     public List getFields() {
         return Collections.unmodifiableList(lFields);
@@ -107,7 +112,10 @@
     /**
      * Returns the Field with the given name or null if this Form has no such
      * field.
-     * @since Validator 1.1
+     *
+     * @param fieldName  The field name
+     * @return           The field value
+     * @since            Validator 1.1
      */
     public Field getField(String fieldName) {
         return (Field) this.hFields.get(fieldName);
@@ -115,22 +123,63 @@
 
     /**
      * Returns true if this Form contains a Field with the given name.
-     * @since Validator 1.1
+     *
+     * @param fieldName  The field name
+     * @return           True if this form contains the field by the given name
+     * @since            Validator 1.1
      */
     public boolean containsField(String fieldName) {
         return this.hFields.containsKey(fieldName);
     }
 
     /**
+     * Merges the given form into this one. For any field in <code>depends</code>
+     * not present in this form, include it. <code>depends</code> has precedence
+     * in the way the fields are ordered.
+     *
+     * @param depends  the form we want to merge
+     * @since          Validator 1.2.0
+     */
+    protected void merge(Form depends) {
+
+        List templFields = new ArrayList();
+        Map temphFields = new FastHashMap();
+        Iterator dependsIt = depends.getFields().iterator();
+        while (dependsIt.hasNext()) {
+            Field defaultField = (Field) dependsIt.next();
+            if (defaultField != null) {
+                String fieldKey = defaultField.getKey();
+                if (!this.containsField(fieldKey)) {
+                    templFields.add(defaultField);
+                    temphFields.put(fieldKey, defaultField);
+                }
+                else {
+                    Field old = getField(fieldKey);
+                    hFields.remove(fieldKey);
+                    lFields.remove(old);
+                    templFields.add(old);
+                    temphFields.put(fieldKey, old);
+                }
+            }
+        }
+        lFields.addAll(0, templFields);
+        hFields.putAll(temphFields);
+    }
+
+    /**
      * Processes all of the <code>Form</code>'s <code>Field</code>s.
-     * @since Validator 1.2.0
+     *
+     * @param globalConstants  A map of global constants
+     * @param constants        Local constants
+     * @param forms            Map of forms
+     * @since                  Validator 1.2.0
      */
     protected void process(Map globalConstants, Map constants, Map forms) {
         if (isProcessed()) {
             return;
         }
 
-        int n = 0; //we want the fields from its parent first
+        int n = 0;//we want the fields from its parent first
         if (isExtending()) {
             Form parent = (Form) forms.get(inherit);
             if (parent != null) {
@@ -138,7 +187,7 @@
                     //we want to go all the way up the tree
                     parent.process(constants, globalConstants, forms);
                 }
-                for (Iterator i = parent.getFields().iterator(); i.hasNext();) {
+                for (Iterator i = parent.getFields().iterator(); i.hasNext(); ) {
                     Field f = (Field) i.next();
                     //we want to be able to override any fields we like
                     if (hFields.get(f.getKey()) == null) {
@@ -151,7 +200,7 @@
         }
         hFields.setFast(true);
         //no need to reprocess parent's fields, we iterate from 'n'
-        for (Iterator i = lFields.listIterator(n); i.hasNext();) {
+        for (Iterator i = lFields.listIterator(n); i.hasNext(); ) {
             Field f = (Field) i.next();
             f.process(globalConstants, constants);
         }
@@ -161,6 +210,8 @@
 
     /**
      * Returns a string representation of the object.
+     *
+     * @return
      */
     public String toString() {
         StringBuffer results = new StringBuffer();
@@ -169,7 +220,7 @@
         results.append(name);
         results.append("\n");
 
-        for (Iterator i = lFields.iterator(); i.hasNext();) {
+        for (Iterator i = lFields.iterator(); i.hasNext(); ) {
             results.append("\tField: \n");
             results.append(i.next());
             results.append("\n");
@@ -180,11 +231,15 @@
 
     /**
      * Validate all Fields in this Form on the given page and below.
-     * @param params A Map of parameter class names to parameter values to pass
-     * into validation methods.
-     * @param actions A Map of validator names to ValidatorAction objects.
-     * @param page Fields on pages higher than this will not be validated.
-     * @return A ValidatorResults object containing all validation messages.
+     *
+     * @param params               A Map of parameter class names to parameter
+     *      values to pass into validation methods.
+     * @param actions              A Map of validator names to ValidatorAction
+     *      objects.
+     * @param page                 Fields on pages higher than this will not be
+     *      validated.
+     * @return                     A ValidatorResults object containing all
+     *      validation messages.
      * @throws ValidatorException
      */
     ValidatorResults validate(Map params, Map actions, int page)
@@ -208,9 +263,11 @@
     }
 
     /**
-     * Whether or not the this <code>Form</code> was processed
-     * for replacing variables in strings with their values.
-     * @since Validator 1.2.0
+     * Whether or not the this <code>Form</code> was processed for replacing
+     * variables in strings with their values.
+     *
+     * @return   The processed value
+     * @since    Validator 1.2.0
      */
     public boolean isProcessed() {
         return processed;
@@ -218,7 +275,9 @@
 
     /**
      * Gets the name/key of the parent set of validation rules.
-     * @since Validator 1.2.0
+     *
+     * @return   The extends value
+     * @since    Validator 1.2.0
      */
     public String getExtends() {
         return inherit;
@@ -226,7 +285,9 @@
 
     /**
      * Sets the name/key of the parent set of validation rules.
-     * @since Validator 1.2.0
+     *
+     * @param inherit  The new extends value
+     * @since          Validator 1.2.0
      */
     public void setExtends(String inherit) {
         this.inherit = inherit;
@@ -234,7 +295,9 @@
 
     /**
      * Get extends flag.
-     * @since Validator 1.2.0
+     *
+     * @return   The extending value
+     * @since    Validator 1.2.0
      */
     public boolean isExtending() {
         return inherit != null;
@@ -242,9 +305,11 @@
 
     /**
      * Returns a Map of String field keys to Field objects.
-     * @since Validator 1.2.0
+     *
+     * @return   The fieldMap value
+     * @since    Validator 1.2.0
      */
     protected Map getFieldMap() {
         return hFields;
     }
-}
\ No newline at end of file
+}

Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/FormSet.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/FormSet.java?rev=264683&r1=264682&r2=264683&view=diff
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/FormSet.java
(original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/FormSet.java
Mon Aug 29 20:03:15 2005
@@ -18,7 +18,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.validator;
 
 import java.io.Serializable;
@@ -28,48 +27,143 @@
 import java.util.Map;
 
 /**
- * Holds a set of <code>Form</code>s stored associated with a
- * <code>Locale</code> based on the country, language, and variant specified.
- * Instances of this class are configured with a &lt;formset&gt; xml element.
+ * Holds a set of <code>Form</code>s stored associated with a <code>Locale</code>
+ * based on the country, language, and variant specified. Instances of this
+ * class are configured with a &lt;formset&gt; xml element.
  */
 public class FormSet implements Serializable {
 
     /**
-     * Whether or not the this <code>FormSet</code> was processed
-     * for replacing variables in strings with their values.
+     * Whether or not the this <code>FormSet</code> was processed for replacing
+     * variables in strings with their values.
      */
     private boolean processed = false;
 
+    /** Language component of <code>Locale</code> (required). */
+    private String language = null;
+
+    /** Country component of <code>Locale</code> (optional). */
+    private String country = null;
+
+    /** Variant component of <code>Locale</code> (optional). */
+    private String variant = null;
+
     /**
-     * Language component of <code>Locale</code> (required).
+     * A <code>Map</code> of <code>Form</code>s using the name field
of the
+     * <code>Form</code> as the key.
      */
-    private String language = null;
+    private Map forms = new HashMap();
 
     /**
-     * Country component of <code>Locale</code> (optional).
+     * A <code>Map</code> of <code>Constant</code>s using the name
field of the
+     * <code>Constant</code> as the key.
      */
-    private String country = null;
+    private Map constants = new HashMap();
 
     /**
-     * Variant component of <code>Locale</code> (optional).
+     * This is the type of <code>FormSet</code>s where no locale is specified.
      */
-    private String variant = null;
+    protected final static int GLOBAL_FORMSET = 1;
 
     /**
-     * A <code>Map</code> of <code>Form</code>s
-     * using the name field of the <code>Form</code> as the key.
+     * This is the type of <code>FormSet</code>s where only language locale is
+     * specified.
      */
-    private Map forms = new HashMap();
+    protected final static int LANGUAGE_FORMSET = 2;
 
     /**
-     * A <code>Map</code> of <code>Constant</code>s
-     * using the name field of the <code>Constant</code> as the key.
+     * This is the type of <code>FormSet</code>s where only language and country
+     * locale are specified.
      */
-    private Map constants = new HashMap();
+    protected final static int COUNTRY_FORMSET = 3;
+
+    /**
+     * This is the type of <code>FormSet</code>s where full locale has been set.
+     */
+    protected final static int VARIANT_FORMSET = 4;
+
+    /**
+     * Flag indicating if this formSet has been merged with its parent (higher
+     * rank in Locale hierarchy).
+     */
+    private boolean merged;
+
+    /**
+     * Has this formSet been merged?
+     *
+     * @return   true if it has been merged
+     * @since    Validator 1.2.0
+     */
+    protected boolean isMerged() {
+        return merged;
+    }
+
+    /**
+     * Returns the type of <code>FormSet</code>:<code>GLOBAL_FORMSET</code>,
+     * <code>LANGUAGE_FORMSET</code>,<code>COUNTRY_FORMSET</code>
or <code>VARIANT_FORMSET</code>
+     * .
+     *
+     * @return                       The type value
+     * @since                        Validator 1.2.0
+     * @throws NullPointerException  if there is inconsistency in the locale
+     *      definition (not sure about this)
+     */
+    protected int getType() {
+        if (getVariant() != null) {
+            if (getLanguage() == null || getCountry() == null) {
+                throw new NullPointerException(
+                    "When variant is specified, country and language must be specified.");
+            }
+            return VARIANT_FORMSET;
+        }
+        else if (getCountry() != null) {
+            if (getLanguage() == null) {
+                throw new NullPointerException(
+                    "When country is specified, language must be specified.");
+            }
+            return COUNTRY_FORMSET;
+        }
+        else if (getLanguage() != null) {
+            return LANGUAGE_FORMSET;
+        }
+        else {
+            return GLOBAL_FORMSET;
+        }
+    }
+
+    /**
+     * Merges the given <code>FormSet</code> into this one. If any of <code>depends</code>
+     * s <code>Forms</code> are not in this <code>FormSet</code>
then, include
+     * them, else merge both <code>Forms</code>. Theoretically we should only
+     * merge a "parent" formSet.
+     *
+     * @param depends  FormSet to be merged
+     * @since          Validator 1.2.0
+     */
+    protected void merge(FormSet depends) {
+        if (depends != null) {
+            Map pForms = getForms();
+            Map dForms = depends.getForms();
+            for (Iterator it = dForms.keySet().iterator(); it.hasNext(); ) {
+                Object key = it.next();
+                Form pForm = (Form) pForms.get(key);
+                if (pForm != null) {//merge, but principal 'rules', don't overwrite
+                    // anything
+                    pForm.merge((Form) dForms.get(key));
+                }
+                else {//just add
+                    addForm((Form) dForms.get(key));
+                }
+            }
+        }
+        merged = true;
+    }
 
     /**
-     * Whether or not the this <code>FormSet</code> was processed
-     * for replacing variables in strings with their values.
+     * Whether or not the this <code>FormSet</code> was processed for replacing
+     * variables in strings with their values.
+     *
+     * @return   The processed value
      */
     public boolean isProcessed() {
         return processed;
@@ -77,6 +171,8 @@
 
     /**
      * Gets the equivalent of the language component of <code>Locale</code>.
+     *
+     * @return   The language value
      */
     public String getLanguage() {
         return language;
@@ -84,6 +180,8 @@
 
     /**
      * Sets the equivalent of the language component of <code>Locale</code>.
+     *
+     * @param language  The new language value
      */
     public void setLanguage(String language) {
         this.language = language;
@@ -91,6 +189,8 @@
 
     /**
      * Gets the equivalent of the country component of <code>Locale</code>.
+     *
+     * @return   The country value
      */
     public String getCountry() {
         return country;
@@ -98,6 +198,8 @@
 
     /**
      * Sets the equivalent of the country component of <code>Locale</code>.
+     *
+     * @param country  The new country value
      */
     public void setCountry(String country) {
         this.country = country;
@@ -105,6 +207,8 @@
 
     /**
      * Gets the equivalent of the variant component of <code>Locale</code>.
+     *
+     * @return   The variant value
      */
     public String getVariant() {
         return variant;
@@ -112,6 +216,8 @@
 
     /**
      * Sets the equivalent of the variant component of <code>Locale</code>.
+     *
+     * @param variant  The new variant value
      */
     public void setVariant(String variant) {
         this.variant = variant;
@@ -119,6 +225,9 @@
 
     /**
      * Add a <code>Constant</code> to the locale level.
+     *
+     * @param name   The constant name
+     * @param value  The constant value
      */
     public void addConstant(String name, String value) {
         this.constants.put(name, value);
@@ -126,6 +235,8 @@
 
     /**
      * Add a <code>Form</code> to the <code>FormSet</code>.
+     *
+     * @param f  The form
      */
     public void addForm(Form f) {
         forms.put(f.getName(), f);
@@ -133,14 +244,19 @@
 
     /**
      * Retrieve a <code>Form</code> based on the form name.
+     *
+     * @param formName  The form name
+     * @return          The form
      */
     public Form getForm(String formName) {
         return (Form) this.forms.get(formName);
     }
 
     /**
-     * A <code>Map</code> of <code>Form</code>s is returned as an
-     * unmodifiable <code>Map</code> with the key based on the form name.
+     * A <code>Map</code> of <code>Form</code>s is returned as an
unmodifiable
+     * <code>Map</code> with the key based on the form name.
+     *
+     * @return   The forms map
      */
     public Map getForms() {
         return Collections.unmodifiableMap(forms);
@@ -148,9 +264,11 @@
 
     /**
      * Processes all of the <code>Form</code>s.
+     *
+     * @param globalConstants  Global constants
      */
     synchronized void process(Map globalConstants) {
-        for (Iterator i = forms.values().iterator(); i.hasNext();) {
+        for (Iterator i = forms.values().iterator(); i.hasNext(); ) {
             Form f = (Form) i.next();
             f.process(globalConstants, constants, forms);
         }
@@ -160,6 +278,8 @@
 
     /**
      * Returns a string representation of the object.
+     *
+     * @return   A string representation
      */
     public String toString() {
         StringBuffer results = new StringBuffer();
@@ -172,7 +292,7 @@
         results.append(variant);
         results.append("\n");
 
-        for (Iterator i = getForms().values().iterator(); i.hasNext();) {
+        for (Iterator i = getForms().values().iterator(); i.hasNext(); ) {
             results.append("   ");
             results.append(i.next());
             results.append("\n");
@@ -181,4 +301,4 @@
         return results.toString();
     }
 
-}
\ No newline at end of file
+}

Modified: jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ValidatorResources.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ValidatorResources.java?rev=264683&r1=264682&r2=264683&view=diff
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ValidatorResources.java
(original)
+++ jakarta/commons/proper/validator/trunk/src/share/org/apache/commons/validator/ValidatorResources.java
Mon Aug 29 20:03:15 2005
@@ -25,19 +25,16 @@
 import java.io.InputStream;
 import java.io.Serializable;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.commons.collections.FastHashMap; // DEPRECATED
+import org.apache.commons.collections.FastHashMap;
 import org.apache.commons.digester.Digester;
 import org.apache.commons.digester.xmlrules.DigesterLoader;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.xml.sax.SAXException;
 
 /**
@@ -108,7 +105,13 @@
     public ValidatorResources() {
         super();
     }
-
+    
+    /**
+     * This is the default <code>FormSet</code> (without locale). (We probably
don't need
+     * the defaultLocale anymore.)
+     */
+    protected FormSet defaultFormSet;
+    
     /**
      * Create a ValidatorResources object from an InputStream.
      *
@@ -169,18 +172,25 @@
      */
     public void addFormSet(FormSet fs) {
         String key = this.buildKey(fs);
-        List formsets = (List) hFormSets.get(key);
-
-        if (formsets == null) {
-            formsets = new ArrayList();
-            hFormSets.put(key, formsets);
-        }
-
-        if (!formsets.contains(fs)) {
-            if (log.isDebugEnabled()) {
-                log.debug("Adding FormSet '" + fs.toString() + "'.");
+        if (key.length() == 0) {// there can only be one default formset
+            if (log.isWarnEnabled() && defaultFormSet != null) {
+                // warn the user he might not get the expected results
+                log.warn("Overriding default FormSet definition.");
             }
-            formsets.add(fs);
+            defaultFormSet = fs;
+        } else {
+            FormSet formset = (FormSet) hFormSets.get(key);
+            if (formset == null) {// it hasn't been included yet
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding FormSet '" + fs.toString() + "'.");
+                }
+            } else if (log.isWarnEnabled()) {// warn the user he might not
+                                                // get the expected results
+                log
+                        .warn("Overriding FormSet definition. Duplicate for locale: "
+                                + key);
+            }
+            hFormSets.put(key, fs);
         }
     }
 
@@ -230,14 +240,8 @@
      * language, country, and variant values.
      */
     protected String buildKey(FormSet fs) {
-        String locale =
+        return
                 this.buildLocale(fs.getLanguage(), fs.getCountry(), fs.getVariant());
-
-        if (locale.length() == 0) {
-            locale = defaultLocale.toString();
-        }
-
-        return locale;
     }
 
     /**
@@ -283,47 +287,35 @@
             String formKey) {
 
         String key = this.buildLocale(language, country, variant);
-
-        List v = (List) hFormSets.get(key);
-
-        if (v == null) {
-            key = (language != null && language.length() > 0) ? language : "";
-            key += (country != null && country.length() > 0) ? "_" + country :
"";
-            v = (List) hFormSets.get(key);
+        if (key.length() == 0) {
+            return defaultFormSet.getForm(formKey);
         }
 
-        if (v == null) {
-            key = (language != null && language.length() > 0) ? language : "";
-            v = (List) hFormSets.get(key);
-        }
+        FormSet formSet = (FormSet) hFormSets.get(key);
 
-        if (v == null) {
-            key = defaultLocale.toString();
-            v = (List) hFormSets.get(key);
+        if (formSet == null) {
+            key = buildLocale(language, country, null);
+            formSet = (FormSet) hFormSets.get(key);
         }
 
-        if (v == null) {
-            return null;
+        if (formSet == null) {
+            key = buildLocale(language, null, null);
+            formSet = (FormSet) hFormSets.get(key);
         }
 
-        Iterator formsets = v.iterator();
-        while (formsets.hasNext()) {
-            FormSet set = (FormSet) formsets.next();
-
-            if ((set != null) && (set.getForm(formKey) != null)) {
-                return set.getForm(formKey);
-            }
-
+        if (formSet == null) {
+            formSet = defaultFormSet;
         }
-        return null;
+        return formSet.getForm(formKey);
     }
 
     /**
-     * Process the <code>ValidatorResources</code> object.  Currently sets the
-     * <code>FastHashMap</code>s to the 'fast' mode and call the processes all
-     * other resources.  <strong>Note</strong>: The framework calls this automatically
-     * when ValidatorResources is created from an XML file.  If you create an instance
-     * of this class by hand you <strong>must</strong> call this method when
finished.
+     * Process the <code>ValidatorResources</code> object. Currently sets the
+     * <code>FastHashMap</code> s to the 'fast' mode and call the processes
+     * all other resources. <strong>Note </strong>: The framework calls this
+     * automatically when ValidatorResources is created from an XML file. If you
+     * create an instance of this class by hand you <strong>must </strong> call
+     * this method when finished.
      */
     public void process() {
         hFormSets.setFast(true);
@@ -335,117 +327,64 @@
 
     /**
      * <p>Process the <code>Form</code> objects.  This clones the <code>Field</code>s
-     * that don't exist in a <code>FormSet</code> compared to the default
+     * that don't exist in a <code>FormSet</code> compared to its parent
      * <code>FormSet</code>.</p>
      */
     private void processForms() {
-        //hFormSets.put(buildKey(fs), fs);
-        String defaultKey = defaultLocale.toString();
-
-        // Loop through FormSets
+        if (defaultFormSet == null) {// it isn't mandatory to have a
+            // default formset
+            defaultFormSet = new FormSet();
+        }
+        defaultFormSet.process(hConstants);
+        // Loop through FormSets and merge if necessary
         for (Iterator i = hFormSets.keySet().iterator(); i.hasNext();) {
             String key = (String) i.next();
-            // Skip default FormSet
-            if (key.equals(defaultKey)) {
-                continue;
-            }
-            List formsets = (List) hFormSets.get(key);
-            Iterator formsetsIterator = formsets.iterator();
-            while (formsetsIterator.hasNext()) {
-                FormSet fs = (FormSet) formsetsIterator.next();
-
-                // Loop through Forms and copy/clone fields from default locale
-                for (Iterator x = fs.getForms().keySet().iterator(); x.hasNext();) {
-                    String formKey = (String) x.next();
-                    Form form = (Form) fs.getForms().get(formKey);
-                    // Create a new Form object so the order from the default is
-                    // maintained (very noticable in the JavaScript).
-                    Form newForm = new Form();
-                    newForm.setName(form.getName());
-
-                    // Loop through the default locale form's fields
-                    // If they don't exist in the current locale's form, then clone them.
-                    Form defaultForm = this.getForm(defaultLocale, formKey);
-
-                    Iterator defaultFields = defaultForm.getFields().iterator();
-                    while (defaultFields.hasNext()) {
-                        Field defaultField = (Field) defaultFields.next();
-                        String fieldKey = defaultField.getKey();
-
-                        if (form.containsField(fieldKey)) {
-                            newForm.addField(form.getField(fieldKey));
-
-                        } else {
-                            Field field =
-                                    getClosestLocaleField(fs, formKey, fieldKey);
-
-                            newForm.addField((Field) field.clone());
-                        }
-                    }
-
-                    fs.addForm(newForm);
-                }
-            }
+            FormSet fs = (FormSet) hFormSets.get(key);
+            fs.merge(getParent(fs));
         }
 
         // Process Fully Constructed FormSets
         for (Iterator i = hFormSets.values().iterator(); i.hasNext();) {
-            List formsets = (List) i.next();
-            Iterator formsetsIterator = formsets.iterator();
-            while (formsetsIterator.hasNext()) {
-                FormSet fs = (FormSet) formsetsIterator.next();
-
-                if (!fs.isProcessed()) {
-                    fs.process(hConstants);
-                }
+            FormSet fs = (FormSet) i.next();
+            if (!fs.isProcessed()) {
+                fs.process(hConstants);
             }
         }
     }
 
     /**
-     * Retrieves the closest matching <code>Field</code> based
-     * on <code>FormSet</code>'s locale.  This is used when
-     * constructing a clone, field by field, of partial
-     * <code>FormSet</code>.
-     */
-    protected Field getClosestLocaleField(FormSet fs, String formKey,
-            String fieldKey) {
-
-        Field field = null;
-        String language = fs.getLanguage();
-        String country = fs.getCountry();
-        String variant = fs.getVariant();
-
-        if (!GenericValidator.isBlankOrNull(language)
-                && !GenericValidator.isBlankOrNull(country)
-                && !GenericValidator.isBlankOrNull(variant)) {
-
-            Form form = this.getForm(language, country, variant, formKey);
-            field = form.getField(fieldKey);
-        }
-
-        if (field == null) {
-            if (!GenericValidator.isBlankOrNull(language)
-                    && !GenericValidator.isBlankOrNull(country)) {
-
-                Form form = this.getForm(language, country, null, formKey);
-                field = form.getField(fieldKey);
+     * Finds the given formSet's parent. ex: A formSet with locale en_UK_TEST1
+     * has a direct parent in the formSet with locale en_UK. If it doesn't
+     * exist, find the formSet with locale en, if no found get the
+     * defaultFormSet.
+     * 
+     * @param fs
+     *            the formSet we want to get the parent from
+     * @return fs's parent
+     */
+    private FormSet getParent(FormSet fs) {
+
+        FormSet parent = null;
+        if (fs.getType() == FormSet.LANGUAGE_FORMSET) {
+            parent = defaultFormSet;
+        } else if (fs.getType() == FormSet.COUNTRY_FORMSET) {
+            parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(),
+                    null, null));
+            if (parent == null) {
+                parent = defaultFormSet;
             }
-        }
-
-        if (field == null) {
-            if (!GenericValidator.isBlankOrNull(language)) {
-                Form form = this.getForm(language, null, null, formKey);
-                field = form.getField(fieldKey);
+        } else if (fs.getType() == FormSet.VARIANT_FORMSET) {
+            parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(), fs
+                    .getCountry(), null));
+            if (parent == null) {
+                parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(),
+                        null, null));
+                if (parent == null) {
+                    parent = defaultFormSet;
+                }
             }
         }
-
-        if (field == null) {
-            Form form = this.getForm(defaultLocale, formKey);
-            field = form.getField(fieldKey);
-        }
-
-        return field;
+        return parent;
     }
 
     /**

Modified: jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/LocaleTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/LocaleTest.java?rev=264683&r1=264682&r2=264683&view=diff
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/LocaleTest.java
(original)
+++ jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/LocaleTest.java
Mon Aug 29 20:03:15 2005
@@ -19,7 +19,6 @@
  * limitations under the License.
  */
 
-
 package org.apache.commons.validator;
 
 import java.io.IOException;
@@ -29,134 +28,198 @@
 import junit.framework.TestSuite;
 
 import org.xml.sax.SAXException;
-                                                          
-/**                                                       
+
+/**
  * Performs Validation Test for <code>long</code> validations.
- */                                                       
+ */
 public class LocaleTest extends TestCommon {
-   
-   /**
-    * The key used to retrieve the set of validation 
-    * rules from the xml file.
-    */
-   protected static String FORM_KEY = "nameForm";   
-
-   /**
-    * The key used to retrieve the validator action.
-    */
-   protected static String ACTION = "required";
-
-
-   public LocaleTest(String name) {                  
-       super(name);                                      
-   }                                                     
-
-   /**
-    * Start the tests.
-    *
-    * @param theArgs the arguments. Not used
-    */
-   public static void main(String[] theArgs) {
-       junit.awtui.TestRunner.main(new String[] {LocaleTest.class.getName()});
-   }
-
-   /**
-    * @return a test suite (<code>TestSuite</code>) that includes all methods
-    *         starting with "test"
-    */
-   public static Test suite() {
-       // All methods starting with "test" will be executed in the test suite.
-       return new TestSuite(LocaleTest.class);
-   }
-
-   /**
-    * Load <code>ValidatorResources</code> from 
-    * validator-locale.xml.
-    */
-   protected void setUp() throws IOException, SAXException {
-      // Load resources
-      loadResources("validator-locale.xml");
-   }
-
-   protected void tearDown() {
-   }
-
-   /**
-    * See what happens when we try to validate with a Locale, Country and variant
-    */
-   public void testLocale1() throws ValidatorException {
-      // Create bean to run test on.
-      NameBean name = new NameBean();
-      name.setFirstName("");
-      name.setLastName("");
-      
-      valueTest(name, new Locale("en", "US", "TEST1"), false, false);
-   }
-
-   /**
-    * See what happens when we try to validate with a Locale, Country and variant
-    */
-   public void testLocale2() throws ValidatorException {
-      // Create bean to run test on.
-      NameBean name = new NameBean();
-      name.setFirstName("");
-      name.setLastName("");
-      
-      valueTest(name, new Locale("en", "US", "TEST2"), true, false);
-   }
-
-   /**
-    * See what happens when we try to validate with a Locale, Country and variant
-    */
-   public void testLocale3() throws ValidatorException {
-      // Create bean to run test on.
-      NameBean name = new NameBean();
-      name.setFirstName("");
-      name.setLastName("");
-      
-      valueTest(name, new Locale("en", "UK"), false, true);
-   }
-
-   /**
-    * Utlity class to run a test on a value.
-    *
-    * @param info	Value to run test on.
-    * @param passed	Whether or not the test is expected to pass.
-    */
-    private void valueTest(Object name, Locale loc, boolean firstGood, boolean lastGood)
+
+    /**
+     * The key used to retrieve the set of validation rules from the xml file.
+     */
+    protected static String FORM_KEY = "nameForm";
+
+    /** The key used to retrieve the validator action.  */
+    protected static String ACTION = "required";
+
+    /**
+     * Constructor for the LocaleTest object
+     *
+     * @param name  param
+     */
+    public LocaleTest(String name) {
+        super(name);
+    }
+
+    /**
+     * Start the tests.
+     *
+     * @param theArgs  the arguments. Not used
+     */
+    public static void main(String[] theArgs) {
+        junit.awtui.TestRunner.main(new String[]{LocaleTest.class.getName()});
+    }
+
+    /**
+     * @return   a test suite (<code>TestSuite</code>) that includes all methods
+     *      starting with "test"
+     */
+    public static Test suite() {
+        // All methods starting with "test" will be executed in the test suite.
+        return new TestSuite(LocaleTest.class);
+    }
+
+    /**
+     * Load <code>ValidatorResources</code> from validator-locale.xml.
+     *
+     * @exception IOException   If something goes wrong
+     * @exception SAXException  If something goes wrong
+     */
+    protected void setUp()
+        throws IOException, SAXException {
+        // Load resources
+        loadResources("validator-locale.xml");
+    }
+
+    /** The teardown method for JUnit */
+    protected void tearDown() {
+    }
+
+    /**
+     * See what happens when we try to validate with a Locale, Country and
+     * variant. Also check if the added locale validation field is getting used.
+     *
+     * @exception ValidatorException  If something goes wrong
+     */
+    public void testLocale1()
+        throws ValidatorException {
+        // Create bean to run test on.
+        NameBean name = new NameBean();
+        name.setFirstName("");
+        name.setLastName("");
+
+        valueTest(name, new Locale("en", "US", "TEST1"), false, false, false);
+    }
+
+    /**
+     * See what happens when we try to validate with a Locale, Country and
+     * variant
+     *
+     * @exception ValidatorException  If something goes wrong
+     */
+    public void testLocale2()
         throws ValidatorException {
-            
-        // Construct validator based on the loaded resources 
+        // Create bean to run test on.
+        NameBean name = new NameBean();
+        name.setFirstName("");
+        name.setLastName("");
+
+        valueTest(name, new Locale("en", "US", "TEST2"), true, false, true);
+    }
+
+    /**
+     * See what happens when we try to validate with a Locale, Country and
+     * variant
+     *
+     * @exception ValidatorException  If something goes wrong
+     */
+    public void testLocale3()
+        throws ValidatorException {
+        // Create bean to run test on.
+        NameBean name = new NameBean();
+        name.setFirstName("");
+        name.setLastName("");
+
+        valueTest(name, new Locale("en", "UK"), false, true, true);
+    }
+
+    /**
+     * See if a locale of en_UK_TEST falls back to en_UK instead of default form
+     * set. Bug #16920 states that this isn't happening, even though it is
+     * passing this test. see #16920.
+     *
+     * @exception ValidatorException  If something goes wrong
+     */
+    public void testLocale4()
+        throws ValidatorException {
+        // Create bean to run test on.
+        NameBean name = new NameBean();
+        name.setFirstName("");
+        name.setLastName("");
+
+        valueTest(name, new Locale("en", "UK", "TEST"), false, true, true);
+    }
+
+    /**
+     * See if a locale of language=en falls back to default form set.
+     *
+     * @exception ValidatorException  If something goes wrong
+     */
+    public void testLocale5()
+        throws ValidatorException {
+        // Create bean to run test on.
+        NameBean name = new NameBean();
+        name.setFirstName("");
+        name.setLastName("");
+
+        valueTest(name, new Locale("en"), false, false, true);
+    }
+
+    /**
+     * Utlity class to run a test on a value.
+     *
+     * @param name                    param
+     * @param loc                     param
+     * @param firstGood               param
+     * @param lastGood                param
+     * @param middleGood              param
+     * @exception ValidatorException  If something goes wrong
+     */
+    private void valueTest(Object name, Locale loc, boolean firstGood, boolean lastGood,
boolean middleGood)
+        throws ValidatorException {
+
+        // Construct validator based on the loaded resources
         // and the form key
         Validator validator = new Validator(resources, FORM_KEY);
-        // add the name bean to the validator as a resource 
+        // add the name bean to the validator as a resource
         // for the validations to be performed on.
         validator.setParameter(Validator.BEAN_PARAM, name);
         validator.setParameter(Validator.LOCALE_PARAM, loc);
         // Get results of the validation.
         ValidatorResults results = null;
-    
-        // throws ValidatorException, 
-        // but we aren't catching for testing 
-        // since no validation methods we use 
+
+        // throws ValidatorException,
+        // but we aren't catching for testing
+        // since no validation methods we use
         // throw this
         results = validator.validate();
-    
+
         assertNotNull("Results are null.", results);
-    
+
         ValidatorResult resultlast = results.getValidatorResult("lastName");
         ValidatorResult resultfirst = results.getValidatorResult("firstName");
-    
+        ValidatorResult resultmiddle = results.getValidatorResult("middleName");
+
         if (firstGood) {
             assertNull(resultfirst);
-        } else {
+        }
+        else {
             assertNotNull(resultfirst);
         }
-        
+
+        if (middleGood) {
+            assertNull(resultmiddle);
+        }
+        else {
+            assertNotNull(resultmiddle);
+        }
+
         if (lastGood) {
             assertNull(resultlast);
-        } else {
+        }
+        else {
             assertNotNull(resultlast);
         }
     }
 }
+

Modified: jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/validator-locale.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/validator-locale.xml?rev=264683&r1=264682&r2=264683&view=diff
==============================================================================
--- jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/validator-locale.xml
(original)
+++ jakarta/commons/proper/validator/trunk/src/test/org/apache/commons/validator/validator-locale.xml
Mon Aug 29 20:03:15 2005
@@ -28,6 +28,9 @@
          <field property="lastName" depends="required">
              <arg key="nameForm.lastname.displayname"/>
          </field>
+         <field property="middleName" depends="required">
+             <arg key="nameForm.lastname.displayname"/>
+         </field>
       </form>
    </formset>   
    <formset language="en" country="US" variant="TEST2">
@@ -36,14 +39,14 @@
              <arg key="nameForm.firstname.displayname"/>
          </field>    
          <field property="lastName" depends="required">
-         	 <arg key="nameForm.lastname.displayname"/>
+           <arg key="nameForm.lastname.displayname"/>
          </field>
       </form>
    </formset>   
    <formset language="en" country="UK">
       <form name="nameForm">
          <field property="firstName" depends="required">
-         	 <arg key="nameForm.firstname.displayname"/>
+           <arg key="nameForm.firstname.displayname"/>
          </field>    
          <field property="lastName" depends="">
              <arg key="nameForm.lastname.displayname"/>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message