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 <form> 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 <form> 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 <formset> 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 <formset> 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]