Hi,

  We have found the a wee problem with the struts validator and now 
validator-commons. Problem is that when you have a required field 
missing, and an error in another field, *all* errors are reported as 
"Required field missing", masking other errors.

  To solve this, a wee patch. Unfortunately some of the tabbing changed, 
so Diff made the 7 or 8 lines of code into a 12Kb Diff file.

  The issue is that the validator drops out when a required field is 
missing. This patch changes it so the validation status of each field is 
stored and we only drop out if all fail.

  Cheers, James
--- Validator.java.orig Mon Jan 28 00:15:46 2002
+++ Validator.java      Mon Jan 28 10:01:57 2002
@@ -112,19 +112,19 @@
    }
    
    public void setPage(int page) {
-      this.page = page;        
+      this.page = page; 
    }
 
    public int getPage() {
-      return page;     
+      return page;  
    }
    
    /**
     * Performs validations based on the configured resources.  
     * 
-    * @return  The <code>Map</code> returned uses the property 
-    *          of the <code>Field</code> for the key and the value 
-    *          is the number of error the field had.
+    * @return   The <code>Map</code> returned uses the property 
+    *       of the <code>Field</code> for the key and the value 
+    *       is the number of error the field had.
    */ 
    public Map validate() throws ValidatorException {
       Map hResults = new HashMap();
@@ -137,10 +137,11 @@
          locale = Locale.getDefault();
          
       Form form = null;
-      if ((form = resources.get(locale, formName)) != null) {      
+      if ((form = resources.get(locale, formName)) != null) {       
          Map hActions = resources.getValidatorActions();
          List lActions = new ArrayList();
          Map hActionsRun = new HashMap();
+         Map hFieldActionsRun = new HashMap();
          boolean bMoreActions = true;
          boolean bErrors = false;
       
@@ -150,6 +151,7 @@
          while (bMoreActions) {
             ValidatorAction va = null;
             int iErrorCount = 0;
+            int iSuccessCount = 0;
             
             // FIX ME - These sorts will not work for all variations.
             // Sort by number dependencies
@@ -168,9 +170,9 @@
                   Object o = hActionsRun.get(depend);
       
                   if (log.isDebugEnabled()) {
-                    log.debug("Validator::validate - ValidatorAction name=" + 
va.getName() + "  depends=" + va.getDepends());
-                 }
-                              
+                     log.debug("Validator::validate - ValidatorAction name=" + 
+va.getName() + "  depends=" + va.getDepends());
+                  }
+                               
                   if (o == null) {
                      lActions.clear();
                      va = null;
@@ -180,8 +182,8 @@
                      boolean bContinue = ((Boolean)o).booleanValue();
 
                      if (log.isDebugEnabled()) {
-                       log.debug("Validator::validate - ValidatorAction name=" + 
va.getName() + "  depend=" + depend + "  bContinue=" + bContinue);
-                    }
+                        log.debug("Validator::validate - ValidatorAction name=" + 
+va.getName() + "  depend=" + depend + "  bContinue=" + bContinue);
+                     }
                      
                      if (!bContinue) {
                         lActions.clear();
@@ -197,7 +199,7 @@
 
             if (log.isDebugEnabled()) {
                StringBuffer sbLog = new StringBuffer();
-              sbLog.append("Validator::validate - Order \n");
+               sbLog.append("Validator::validate - Order \n");
                
                for (Iterator actions = lActions.iterator(); actions.hasNext(); ) {
                   ValidatorAction tmp = (ValidatorAction)actions.next();
@@ -205,48 +207,56 @@
                }
 
                log.debug(sbLog.toString());
-           }
+            }
             
             if (va != null) {
                for (Iterator i = form.getFields().iterator(); i.hasNext(); ) {
-                  Field field = (Field)i.next();         
+                  Field field = (Field)i.next();
+
+                  // now check if a test on this field has failed (==false)
+                  Object of = null;
+                  if (hFieldActionsRun.containsKey(field.getKey())) {
+                    of = hFieldActionsRun.get(field.getKey());
+                  }
+
+                  if (of == null || (of != null && ((Boolean)of).booleanValue() == 
+true)) {
       
                   if (field.getPage() <= page && (field.getDepends() != null && 
field.isDependency(va.getName()))) {
                      try {
-                         // Add these two Objects to the resources since they 
reference 
-                         // the current validator action and field
-                         hResources.put(VALIDATOR_ACTION_KEY, va);
-                         hResources.put(FIELD_KEY, field);
-      
-                         Class c = Class.forName(va.getClassname(), true, 
this.getClass().getClassLoader());
-                         
-                         List lParams = va.getMethodParamsList();
-                         int size = lParams.size();
-                         int beanIndexPos = -1;
-                         int fieldIndexPos = -1;
-                         Class[] paramClass = new Class[size];
-                         Object[] paramValue = new Object[size];
-      
-                         for (int x = 0; x < size; x++) {
-                            String paramKey = (String)lParams.get(x);
-                            
-                            if (BEAN_KEY.equals(paramKey)) {
-                               beanIndexPos = x;
-                            }
-                               
-                            if (FIELD_KEY.equals(paramKey)) {
-                               fieldIndexPos = x;
-                            }
-                            
-                            // There were problems calling getClass on paramValue[]
-                            paramClass[x] = Class.forName(paramKey, true, 
this.getClass().getClassLoader());
-                            paramValue[x] = hResources.get(paramKey);
-                         }
+                          // Add these two Objects to the resources since they 
+reference 
+                          // the current validator action and field
+                          hResources.put(VALIDATOR_ACTION_KEY, va);
+                          hResources.put(FIELD_KEY, field);
+      
+                          Class c = Class.forName(va.getClassname(), true, 
+this.getClass().getClassLoader());
+                          
+                          List lParams = va.getMethodParamsList();
+                          int size = lParams.size();
+                          int beanIndexPos = -1;
+                          int fieldIndexPos = -1;
+                          Class[] paramClass = new Class[size];
+                          Object[] paramValue = new Object[size];
+      
+                          for (int x = 0; x < size; x++) {
+                             String paramKey = (String)lParams.get(x);
+                             
+                             if (BEAN_KEY.equals(paramKey)) {
+                                beanIndexPos = x;
+                             }
+                                
+                             if (FIELD_KEY.equals(paramKey)) {
+                                fieldIndexPos = x;
+                             }
+                             
+                             // There were problems calling getClass on paramValue[]
+                             paramClass[x] = Class.forName(paramKey, true, 
+this.getClass().getClassLoader());
+                             paramValue[x] = hResources.get(paramKey);
+                          }
       
                         Method m = c.getMethod(va.getMethod(), paramClass);
-                 
-                       // If the method is static we don't need an instance of the 
class 
-                       // to call the method.  If it isn't, we do.
+              
+                    // If the method is static we don't need an instance of the class 
+                    // to call the method.  If it isn't, we do.
                         if (!Modifier.isStatic(m.getModifiers())) {
                            try {
                               if (va.getClassnameInstance() == null) {
@@ -288,41 +298,45 @@
                                  
                                  if (hResults.containsKey(field.getKey())) {
                                     Integer currentCount = 
(Integer)hResults.get(field.getKey());
-                                    hResults.put(field.getKey(), new 
Integer(currentCount.intValue() + iCount));       
+                                    hResults.put(field.getKey(), new 
+Integer(currentCount.intValue() + iCount));    
                                  } else {
-                                    hResults.put(field.getKey(), new 
Integer(iCount)); 
+                                    hResults.put(field.getKey(), new 
+Integer(iCount));  
                                  }
+                              } else {
+                                  iSuccessCount += 1;
                               }
                            }
                         } else {
                            result = m.invoke(va.getClassnameInstance(), paramValue);
 
                            int iCount = getErrorCount(result);
-                           
+
                            if (iCount != 0) {
                               iErrorCount += iCount;
-                              
+
                               if (hResults.containsKey(field.getKey())) {
                                  Integer currentCount = 
(Integer)hResults.get(field.getKey());
-                                 hResults.put(field.getKey(), new 
Integer(currentCount.intValue() + iCount));  
+                                 hResults.put(field.getKey(), new 
+Integer(currentCount.intValue() + iCount));
                               } else {
-                                 hResults.put(field.getKey(), new Integer(iCount));   
 
+                                 hResults.put(field.getKey(), new Integer(iCount));
                               }
+                           } else {
+                               iSuccessCount += 1;
                            }
                         }
-              } catch (Exception e) {
-                 bErrors = true;
-                 log.error("Validator::validate - reflection: " + e.getMessage(), e);
-                 
-                 if (e instanceof ValidatorException) {
-                    throw ((ValidatorException)e);
-                 }
-              }
-               
+                      } catch (Exception e) {
+                        bErrors = true;
+                        log.error("Validator::validate - reflection: " + 
+e.getMessage(), e);
+
+                        if (e instanceof ValidatorException) {
+                           throw ((ValidatorException)e);
+                        }
+                      }
+                    }
                   }
                }
                
-               if (iErrorCount == 0) {
+               if (iSuccessCount > 0) {
                   hActionsRun.put(va.getName(), new Boolean(true));
                } else {
                   hActionsRun.put(va.getName(), new Boolean(false));
@@ -441,7 +455,7 @@
                if (o != null) {
                   if (((Boolean)o).booleanValue())
                     iVA2++;
-               }       
+               }    
             }
             
             return iVA1 - iVA2;

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to