You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Saul Qunming Yuan <yu...@dataanvil.com> on 2005/10/19 16:47:33 UTC

Conditional validation for mask, date, integer etc

Hi All,


I'm wondering if there is a way to define conditional validation for mask,
date, integer etc in validation.xml. I know there is a "validwhen", but it
only checks for the condition as defined by the "test" variable. What I
want is to perform the mask, date validation only some conditions are met.
I wonder if there is a way to do that? Any points are welcome.

thanks,
Saul


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Conditional validation for mask, date, integer etc

Posted by Saul Qunming Yuan <yu...@dataanvil.com>.
Saul Qunming Yuan <yuan <at> dataanvil.com> writes:
> 
> That's simlar to what I need, except that it's not an indexd property. Can
> some of your code or send it to me offline.
> 
> thanks,
> Saul
> 
> > On my current project I've written a validation method that
> > dynamically invokes other validation rules depending on the String
> > returned by bean.getDepends()
> >
> > It's used with indexed properties where the fields for the form to
> > fill in are configurable and come from a database.
> >
> > Is that what you're after?
> >
> > Stew
> >
> > On 19/10/05, Saul Qunming Yuan <yuan <at> dataanvil.com> wrote:
> >> Hi All,
> >>
> >>
> >> I'm wondering if there is a way to define conditional validation for
> >> mask,
> >> date, integer etc in validation.xml. I know there is a "validwhen", but
> >> it
> >> only checks for the condition as defined by the "test" variable. What I
> >> want is to perform the mask, date validation only some conditions are
> >> met.
> >> I wonder if there is a way to do that? Any points are welcome.
> >>
> >> thanks,
> >> Saul


Well, it's been a while since I posted this question. Here is what I ended up
with, thought it might be helpful to others.

1. I modified the ValidWhen class from the Struts source distribution to create
a new class named ValidIf with a validateValidIf method. The only difference is
no error is added to the error collection when the boolean condition evaluates
to false. The only purpose of this validateValidIf method is to evaluate a
boolean condition to return true or false. This class is used to define a new
validation rule as defined in step 2.


package validation;

import java.io.StringReader;

import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.validator.Resources;
import org.apache.struts.validator.validwhen.ValidWhen;
import org.apache.struts.validator.validwhen.ValidWhenLexer;
import org.apache.struts.validator.validwhen.ValidWhenParser;

/**
 * This class if modified from the ValidWhen class in the Struts 1.2.7 source
distribution. 
 *
 */
public class ValidIf {

    /**
     * Returns true if <code>obj</code> is null or a String.
     */
    private static boolean isString(Object obj) {
        return (obj == null) ? true : String.class.isInstance(obj);
    }

    /**
     * Checks if the boolean expression as specified in <code>check</code> parameter
     * evaluates to true or false. If true, continue to the validation of the rule 
     * which depends on this rule. The primary difference between this and
validwhen 
     * is no error is added to the error collection when the boolean expression
evaluates
     * to false.
     *
     * @param bean The bean validation is being performed on.
     * 
     * @param va The <code>ValidatorAction</code> that is currently being 
     *      performed.
     * 
     * @param field The <code>Field</code> object associated with the current
     *      field being validated.
     * 
     * @return <code>true</code> if meets stated requirements, 
     *      <code>false</code> otherwise.
     */
    public static boolean validateValidIf(
        Object bean,
        ValidatorAction va,
        Field field,
        Validator validator) {
            
        Object form = validator.getParameterValue(Validator.BEAN_PARAM);
        String value = null;
        boolean valid = false;
        int index = -1;
        
        if (field.isIndexed()) {
            String key = field.getKey();

            final int leftBracket = key.indexOf("[");
            final int rightBracket = key.indexOf("]");

            if ((leftBracket > -1) && (rightBracket > -1)) {
                index =
                    Integer.parseInt(key.substring(leftBracket + 1, rightBracket));
            }
        }
        
        if (isString(bean)) {
            value = (String) bean;
        } else {
            value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        }
        
        String test = field.getVarValue("check");
        if (test == null) {
        	// log message
            return false;
        }
        
        // Create the Lexer
        ValidWhenLexer lexer= null;
        try {
            lexer = new ValidWhenLexer(new StringReader(test));
        } catch (Exception ex) {
        	// log message
            return false;
        }

        // Create the Parser
        ValidWhenParser parser = null;
        try {
            parser = new ValidWhenParser(lexer);
        } catch (Exception ex) {
        	// log message
            return false;
        }

        parser.setForm(form);
        parser.setIndex(index);
        parser.setValue(value);

        try {
            parser.expression();
            valid = parser.getResult();
            
        } catch (Exception ex) {
        	// log message
            return false;
        }
        
        if (!valid) {
        	// log message
            return false;
        }
        
        return true;
    }
}


2. Define a validif rule in validation-rule.xml

      <validator name="validif"
                 classname="validation.ValidIf"
                 method="validateValidIf"
                 methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.commons.validator.Validator"/>

This rule is only useful when used as a dependent rule of other rules.

3. Define new rules that need to do conditional validtion, and set these rules
to depend on the above "validif" rule. Take the mask rule for an example, define
a new "maskif" rule as below:

      <validator name="maskif"
            classname="org.apache.struts.validator.FieldChecks"
               method="validateMask"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionMessages,
                       org.apache.commons.validator.Validator,
                       javax.servlet.http.HttpServletRequest"
              depends="validif"
                  msg="errors.invalid"/>

4. Use the new rules in the validation.xml file. Take a zipcode validation for
an example, it valids the zipcode against the mask only if country is 'US'.

      <field property="zipcode" depends="maskif">
        <arg key="validWhenForm.lastName" />
        <var>
          <var-name>mask</var-name>
          <var-value>^\d{5}$</var-value>
        </var>
        <var>
          <var-name>check</var-name>
          <var-value>(country=='US')</var-value>
        </var>
      </field>


The above code are slightly modified from what I used in my projects.

Saul



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Conditional validation for mask, date, integer etc

Posted by Saul Qunming Yuan <yu...@dataanvil.com>.
That's simlar to what I need, except that it's not an indexd property. Can
some of your code or send it to me offline.

thanks,
Saul

> On my current project I've written a validation method that
> dynamically invokes other validation rules depending on the String
> returned by bean.getDepends()
>
> It's used with indexed properties where the fields for the form to
> fill in are configurable and come from a database.
>
> Is that what you're after?
>
> Stew
>
> On 19/10/05, Saul Qunming Yuan <yu...@dataanvil.com> wrote:
>> Hi All,
>>
>>
>> I'm wondering if there is a way to define conditional validation for
>> mask,
>> date, integer etc in validation.xml. I know there is a "validwhen", but
>> it
>> only checks for the condition as defined by the "test" variable. What I
>> want is to perform the mask, date validation only some conditions are
>> met.
>> I wonder if there is a way to do that? Any points are welcome.
>>
>> thanks,
>> Saul
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Conditional validation for mask, date, integer etc

Posted by Stewart Cambridge <st...@gmail.com>.
On my current project I've written a validation method that
dynamically invokes other validation rules depending on the String
returned by bean.getDepends()

It's used with indexed properties where the fields for the form to
fill in are configurable and come from a database.

Is that what you're after?

Stew

On 19/10/05, Saul Qunming Yuan <yu...@dataanvil.com> wrote:
> Hi All,
>
>
> I'm wondering if there is a way to define conditional validation for mask,
> date, integer etc in validation.xml. I know there is a "validwhen", but it
> only checks for the condition as defined by the "test" variable. What I
> want is to perform the mask, date validation only some conditions are met.
> I wonder if there is a way to do that? Any points are welcome.
>
> thanks,
> Saul
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org