You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ri...@apache.org on 2004/08/23 01:39:27 UTC

svn commit: rev 36711 - in incubator/beehive/trunk/netui: ant src/compiler/org/apache/beehive/netui/compiler src/compiler/org/apache/beehive/netui/compiler/genmodel src/compiler/org/apache/beehive/netui/compiler/grammar src/compiler/org/apache/beehive/netui/compiler/model src/compiler/org/apache/beehive/netui/compiler/model/validation src/compiler/schema/struts-validator src/pageflow/org/apache/beehive/netui/pageflow src/pageflow/org/apache/beehive/netui/pageflow/annotations src/pageflow/org/apache/beehive/netui/pageflow/internal src/pageflow/org/apache/beehive/netui/pageflow/validation src/tags-html/org/apache/beehive/netui/tags/html src/webapp-template/validator

Author: rich
Date: Sun Aug 22 16:39:26 2004
New Revision: 36711

Added:
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateCustomGrammar.java   (contents, props changed)
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateValidWhenGrammar.java   (contents, props changed)
   incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/validation/ValidatorRules.java   (contents, props changed)
   incubator/beehive/trunk/netui/src/webapp-template/validator/
   incubator/beehive/trunk/netui/src/webapp-template/validator/netui-validator-rules.xml
      - copied unchanged from rev 36672, incubator/beehive/trunk/netui/external/struts/validator-rules.xml
Modified:
   incubator/beehive/trunk/netui/ant/common.properties
   incubator/beehive/trunk/netui/ant/webappTemplate.xml
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/AnnotationGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FacesBackingChecker.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FormBeanChecker.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/DefaultValidatorRuleFactory.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenValidationModel.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/BaseValidationRuleGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/CatchGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ControllerGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ExceptionHandlerGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ForwardGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/SimpleActionGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationFieldGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationLocaleRulesGrammar.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/StrutsApp.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatableField.java
   incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatorConstants.java
   incubator/beehive/trunk/netui/src/compiler/schema/struts-validator/struts-validator_1_1.xsd
   incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
   incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FormData.java
   incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java
   incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalExpressionUtils.java
   incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/ErrorBaseTag.java
Log:
- Enabled the @Jpf.ValidateCustom declarative validation rule.  This annotation causes a custom rule in a ValidatorPlugIn file to be applied on the associated property.  It accepts the name of the rule and an array of its variables/values (@Jpf.ValidateCustomVariable[]).

- Enabled the @Jpf.ValidateValidWhen declarative validation rule.  This annotation causes validation failure when the given expression evaluates to false at runtime.  This is hooked in to the new expression evaluation APIs, which is currently stubbed out.

- added a warning that occurs when a declarative validation rule annotation does not specify a custom message (i.e., uses the default), and it doesn't provide a first argument to the default message, and its parent @Jpf.ValidatableProperty annotation doesn't specify a display name... in which case a default display name will be used in the error message.

- Fixed generation of empty <arg0>, <arg1>, etc. elements in generated ValidatorPlugIn files when declarative validation annotations did not specify the message arguments.

- Fixed incorrect "duplicate action" errors that occured on Jpf.SimpleAction annotations when the validationErrorForward annotation member was set.

- Enabled the validatorMerge attribute on the @Jpf.Controller annotation.  The ValidatorPlugIn XML file referenced by this attribute is merged with the generated XML from declarative validation annotations in the page flow.  Elements/attributes in the referenced XML override those in the generated XML.

- Moved Simple Action expression evaluation (for evaluating conditions in @Jpf.ConditionalForward annotations within @Jpf.SimpleAction annotations) to the new (stubbed-out) expression evaluation APIs.

DRT: netui (WinXP)
BB: self (linux)



Modified: incubator/beehive/trunk/netui/ant/common.properties
==============================================================================
--- incubator/beehive/trunk/netui/ant/common.properties	(original)
+++ incubator/beehive/trunk/netui/ant/common.properties	Sun Aug 22 16:39:26 2004
@@ -164,9 +164,6 @@
 deployed.commons-fileupload.jar=${webappTemplate.webinf.lib}/commons-fileupload.jar
 deployed.commons-validator.jar=${webappTemplate.webinf.lib}/commons-validator.jar
 
-# Deployed Struts file resources
-deployed.validator-rules.xml=${webappTemplate.webinf}/validator-rules.xml
-
 deployed.netuiconfig.xml=${webappTemplate.webinf}/netui-config.xml
 deployed.javascript.dir=${webapp.dist.dir}/resources/javascript
 

Modified: incubator/beehive/trunk/netui/ant/webappTemplate.xml
==============================================================================
--- incubator/beehive/trunk/netui/ant/webappTemplate.xml	(original)
+++ incubator/beehive/trunk/netui/ant/webappTemplate.xml	Sun Aug 22 16:39:26 2004
@@ -68,7 +68,7 @@
         <copy todir="${webinf.lib}" file="${controls.jar}"/>
   
         <!-- copy the validation files -->
-        <copy todir="${webinf.dir}" file="${struts.dir}/validator-rules.xml"/>
+        <copy todir="${webinf.dir}" file="${template.root.dir}/validator/netui-validator-rules.xml"/>
 
         <!-- scoping -->
         <copy todir="${webinf.lib}" file="${scoping.jar}"/>
@@ -169,7 +169,6 @@
         <include name="WEB-INF/lib/commons-collections.jar"/>
         <include name="WEB-INF/lib/commons-validator.jar"/>
         <include name="WEB-INF/lib/commons-fileupload.jar"/>
-        <include name="WEB-INF/validator-rules.xml"/>
     </patternset>
 
     <target name="deploy.netui.runtime" description="Deploy the NetUI server runtime to a webapp root directory.">

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/AnnotationGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/AnnotationGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/AnnotationGrammar.java	Sun Aug 22 16:39:26 2004
@@ -30,6 +30,9 @@
 import java.util.Map;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.PAGEFLOW_RUNTIME_JAR;
 
@@ -57,8 +60,8 @@
      * @param requiredRuntimeVersion causes an error to be produced if the version in the manifest of beehive-netui-pageflow.jar
      *            is not high enough.
      */ 
-    public AnnotationGrammar( AnnotationProcessorEnvironment env, Diagnostics diags, String requiredRuntimeVersion,
-                              RuntimeVersionChecker runtimeVersionChecker )
+    protected AnnotationGrammar( AnnotationProcessorEnvironment env, Diagnostics diags, String requiredRuntimeVersion,
+                                 RuntimeVersionChecker runtimeVersionChecker )
     {
         _env = env;
         _diagnostics = diags;
@@ -76,9 +79,10 @@
         return _diagnostics;
     }
 
-    public final Object check( AnnotationMirror annotation, MemberDeclaration classMember )
+    public final Object check( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                               MemberDeclaration classMember )
     {
-        if ( ! beginCheck( annotation, classMember ) )
+        if ( ! beginCheck( annotation, parentAnnotations, classMember ) )
         {
             return null;
         }
@@ -87,6 +91,12 @@
         HashSet wasPresent = new HashSet();
         HashMap checkResults = new HashMap();
         
+        if ( parentAnnotations == null ) parentAnnotations = new AnnotationMirror[0];
+        int oldLen = parentAnnotations.length;
+        AnnotationMirror[] parentsIncludingMe = new AnnotationMirror[oldLen + 1];
+        System.arraycopy( parentAnnotations, 0, parentsIncludingMe, 0, oldLen );
+        parentsIncludingMe[oldLen] = annotation;
+        
         for ( Map.Entry< AnnotationTypeElementDeclaration, AnnotationValue > i : valuesPresent.entrySet() )
         {
             AnnotationTypeElementDeclaration decl = i.getKey();
@@ -94,7 +104,7 @@
             String memberName = decl.getSimpleName();
             
             wasPresent.add( memberName );
-            onCheckMember( decl, value, annotation, classMember );
+            onCheckMember( decl, value, annotation, parentAnnotations, classMember );
             Object grammarOrType = null;
             
             if ( ( grammarOrType = _memberGrammars.get( memberName ) ) != null )
@@ -103,7 +113,8 @@
                 
                 if ( childGrammar != null )   // it will be non-null unless there are other, more basic, errors
                 {
-                    Object result = childGrammar.check( ( AnnotationMirror ) value.getValue(), classMember );
+                    Object result =
+                        childGrammar.check( ( AnnotationMirror ) value.getValue(), parentsIncludingMe, classMember );
                     
                     if ( result != null )
                     {
@@ -121,7 +132,7 @@
                 
                     for ( AnnotationMirror ann : annotations )
                     {
-                        arrayGrammar.check( ann, classMember );
+                        arrayGrammar.check( ann, parentsIncludingMe, classMember );
                     }
                 }
             }
@@ -141,10 +152,11 @@
             }
         }
         
-        return endCheck( annotation, classMember, wasPresent, checkResults );
+        return endCheck( annotation, parentAnnotations, classMember, wasPresent, checkResults );
     }
     
-    public final boolean beginCheck( AnnotationMirror annotation, MemberDeclaration classMember )
+    public final boolean beginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                     MemberDeclaration classMember )
     {
         //
         // First check to see if there's a required runtime version.
@@ -156,7 +168,7 @@
             return false;
         }
         
-        return onBeginCheck( annotation, classMember );  // for derived classes
+        return onBeginCheck( annotation, parentAnnotations, classMember );  // for derived classes
     }
 
     protected void addError( Declaration element, String key, Object ... args )
@@ -192,7 +204,8 @@
     /**
      * @return a result (any Object) that will be passed back to the parent checker.  May be <code>null</code>.
      */ 
-    public final Object endCheck( AnnotationMirror annotation, MemberDeclaration classMember, Set wasPresent, Map checkResults )
+    public final Object endCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                  MemberDeclaration classMember, Set wasPresent, Map checkResults )
     {
         //
         // Check mutually-exclusive attributes and child annotations.
@@ -276,10 +289,11 @@
             }
         }
         
-        return onEndCheck( annotation, classMember, checkResults );   // for derived classes
+        return onEndCheck( annotation, parentAnnotations, classMember, checkResults );   // for derived classes
     }
 
-    protected boolean onBeginCheck( AnnotationMirror annotation, MemberDeclaration classMember )
+    protected boolean onBeginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                    MemberDeclaration classMember )
     {
         return true;
     }
@@ -288,13 +302,15 @@
      * @param checkResults map of member-name (String) -> result-from-checking (Object)
      * @return a result (any Object) that will be passed back to the parent checker.  May be <code>null</code>.
      */ 
-    protected Object onEndCheck( AnnotationMirror annotation, MemberDeclaration classMember, Map checkResults )
+    protected Object onEndCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                 MemberDeclaration classMember, Map checkResults )
     {
         return null;
     }
     
     protected void onCheckMember( AnnotationTypeElementDeclaration memberDecl, AnnotationValue member,
-                                  AnnotationMirror annotation, MemberDeclaration classMember )
+                                  AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                  MemberDeclaration classMember )
     {
     }
     

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java	Sun Aug 22 16:39:26 2004
@@ -764,6 +764,11 @@
                     }
                 }
             }
+            else if ( val1 instanceof AnnotationMirror )
+            {
+                if ( ! ( val2 instanceof AnnotationMirror ) ) return false;
+                if ( ! annotationsAreEqual( ( AnnotationMirror ) val1, ( AnnotationMirror ) val2 ) ) return false;
+            }
             else if ( ! val1.equals( val2 ) )
             {
                 return false;

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FacesBackingChecker.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FacesBackingChecker.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FacesBackingChecker.java	Sun Aug 22 16:39:26 2004
@@ -74,7 +74,7 @@
 
         for ( MethodDeclaration method : methods )
         {
-            chg.check( CompilerUtils.getAnnotation( method, COMMAND_HANDLER_TAG_NAME ), method );
+            chg.check( CompilerUtils.getAnnotation( method, COMMAND_HANDLER_TAG_NAME ), null, method );
         }
         
         return null;

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java	Sun Aug 22 16:39:26 2004
@@ -223,7 +223,7 @@
         {
             if ( annotation.getAnnotationType().getDeclaration().getSimpleName().equals( CONTROLLER_TAG_NAME ) )
             {
-                _controllerGrammar.check( annotation, jclass );
+                _controllerGrammar.check( annotation, null, jclass );
             }
         }
     }
@@ -257,12 +257,12 @@
             
             if ( annotationName.equals( ACTION_TAG_NAME ) )
             {
-                _actionGrammar.check( annotation, method );
+                _actionGrammar.check( annotation, null, method );
                 checkActionMethod( method, jclass, annotation );
             }
             else if ( annotationName.equals( EXCEPTION_HANDLER_TAG_NAME ) )
             {
-                _exceptionHandlerGrammar.check( annotation, method );
+                _exceptionHandlerGrammar.check( annotation, null, method );
                 checkExceptionHandlerMethod( method );
             }
         }

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FormBeanChecker.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FormBeanChecker.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FormBeanChecker.java	Sun Aug 22 16:39:26 2004
@@ -29,6 +29,7 @@
 
 import java.util.Collection;
 import java.util.Map;
+import java.util.List;
 
 import org.apache.beehive.netui.compiler.grammar.ValidationFieldGrammar;
 
@@ -122,7 +123,7 @@
                 getDiagnostics().addError( annotation, "error.validation-field-on-non-getter" );
             }
             
-            grammar.check( annotation, method );
+            grammar.check( annotation, null, method );
             
             return true;
         }
@@ -145,7 +146,8 @@
         }
         
         protected void onCheckMember( AnnotationTypeElementDeclaration memberDecl, AnnotationValue member,
-                                      AnnotationMirror annotation, MemberDeclaration classMember )
+                                      AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                      MemberDeclaration classMember )
         {
             if ( memberDecl.getSimpleName().equals( PROPERTY_NAME_ATTR ) )
             {

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/JpfLanguageConstants.java	Sun Aug 22 16:39:26 2004
@@ -96,6 +96,7 @@
     public static final String NESTED_ATTR = "nested";
     public static final String SINGLETON_ATTR = "singleton";
     public static final String STRUTSMERGE_ATTR = "strutsMerge";
+    public static final String VALIDATOR_MERGE_ATTR = "validatorMerge";
     public static final String LOGIN_REQUIRED_ATTR = "loginRequired";
     public static final String ROLES_ALLOWED_ATTR = "rolesAllowed";
     public static final String NAME_ATTR = "name";
@@ -125,7 +126,7 @@
     public static final String USE_FORM_BEAN_ATTR = "useFormBean";
     public static final String READONLY_ATTR = "readOnly";
     public static final String RESTORE_QUERY_STRING_ATTR = "restoreQueryString";
-    public static final String VALUE_ATTR = "value";    // this is the default annotation member
+    public static final String VALUE_ATTR = "value";
     public static final String MESSAGE_RESOURCES_ATTR = "messageResources";
     public static final String FORWARDS_ATTR = "forwards";
     public static final String CATCHES_ATTR = "catches";
@@ -167,6 +168,8 @@
     public static final String SIMPLE_ACTIONS_ATTR = "simpleActions";
     public static final String CONDITION_ATTR = "condition";
     public static final String CONDITIONAL_FORWARDS_ATTR = "conditionalForwards";
+    public static final String RULE_ATTR = "rule";
+    public static final String VARIABLES_ATTR = "variables";
     
     public static final String FORWARD_CLASS_NAME = PAGEFLOW_PACKAGE + ".Forward";
     public static final String FORM_CLASS_NAME = "org.apache.struts.action.ActionForm";

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties	Sun Aug 22 16:39:26 2004
@@ -138,3 +138,6 @@
 warning.no-controller-annotation = This class extends {0}, but it does not have the {1} annotation and is not abstract.
 
 warning.no-such-action = There is no action "{0}" in page flow {1}.
+warning.using-default-display-name = \
+This rule uses the default message and does not provide a first argument, and the parent {0} annotation does not
+specify a display name.  A default display name will be used.

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/DefaultValidatorRuleFactory.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/DefaultValidatorRuleFactory.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/DefaultValidatorRuleFactory.java	Sun Aug 22 16:39:26 2004
@@ -25,26 +25,11 @@
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.List;
 
 // Constants
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_REQUIRED_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_CREDIT_CARD_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_EMAIL_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_RANGE_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_MIN_LENGTH_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_MAX_LENGTH_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_MASK_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_DATE_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_TYPE_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MIN_FLOAT_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MAX_FLOAT_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MIN_INT_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MAX_INT_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.CHARS_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.REGEX_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.STRICT_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.PATTERN_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.TYPE_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.*;
+
 import com.sun.mirror.declaration.AnnotationMirror;
 import com.sun.mirror.declaration.AnnotationValue;
 import com.sun.mirror.type.PrimitiveType;
@@ -116,7 +101,7 @@
         }
         else if ( annName.equals( VALIDATE_DATE_TAG_NAME ) )
         {
-            boolean strict = CompilerUtils.getBoolean( ruleAnnotation, STRICT_ATTR, false ).booleanValue();
+            boolean strict = CompilerUtils.getBoolean( ruleAnnotation, STRICT_ATTR, false );
             String pattern = CompilerUtils.getString( ruleAnnotation, PATTERN_ATTR, true );
             assert pattern != null;
             rule = new ValidatorRule( RULENAME_DATE );
@@ -131,6 +116,23 @@
             String typeName = VALIDATE_TYPE_RULES.get( ( ( PrimitiveType ) value ).getKind() );
             assert typeName != null : ( ( PrimitiveType ) value ).getKind().toString();  // TODO: checker enforces this
             rule = new ValidatorRule( typeName );
+        }
+        else if ( annName.equals( VALIDATE_VALID_WHEN_TAG_NAME ) )
+        {
+            rule = new ValidatorRule( RULENAME_VALID_WHEN );
+            rule.setVar( VARNAME_VALID_WHEN, CompilerUtils.getString( ruleAnnotation, CONDITION_ATTR, true ) );
+        }
+        else if ( annName.equals( VALIDATE_CUSTOM_TAG_NAME ) )
+        {
+            String ruleName = CompilerUtils.getString( ruleAnnotation, RULE_ATTR, false );
+            rule = new ValidatorRule( ruleName );
+            List< AnnotationMirror > ruleVars = CompilerUtils.getAnnotationArray( ruleAnnotation, VARIABLES_ATTR, false );
+            
+            for ( AnnotationMirror ruleVar : ruleVars )
+            {
+                rule.setVar( CompilerUtils.getString( ruleVar, NAME_ATTR, false ),
+                             CompilerUtils.getString( ruleVar, VALUE_ATTR, false ) );
+            }
         }
  
         return rule;

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenValidationModel.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenValidationModel.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenValidationModel.java	Sun Aug 22 16:39:26 2004
@@ -21,8 +21,8 @@
 import org.apache.beehive.netui.compiler.model.validation.ValidationModel;
 import org.apache.beehive.netui.compiler.model.validation.ValidatorRule;
 import org.apache.beehive.netui.compiler.model.validation.ValidatorConstants;
-import org.apache.beehive.netui.compiler.model.validation.ValidationModel.RuleInfo;
 import org.apache.beehive.netui.compiler.model.FormBeanModel;
+import org.apache.beehive.netui.compiler.model.NoWebInfDirectoryException;
 import org.apache.beehive.netui.compiler.CompilerUtils;
 import org.apache.beehive.netui.compiler.JpfLanguageConstants;
 import org.apache.xmlbeans.XmlException;
@@ -52,14 +52,18 @@
     private static final ValidatorRuleFactory VALIDATOR_RULE_FACTORY = new DefaultValidatorRuleFactory();
     
     private GenStrutsApp _strutsApp;
+    private File _mergeFile;
 
 
     public GenValidationModel( ClassDeclaration jclass, GenStrutsApp strutsApp )
+        throws NoWebInfDirectoryException
     {
         _strutsApp = strutsApp;
         addRulesFromBeans( jclass );
         addRulesFromActions( jclass );
         addRulesFromClass( jclass );
+        String mergeFileName = CompilerUtils.getStringValue( jclass, CONTROLLER_TAG_NAME, VALIDATOR_MERGE_ATTR, true );
+        _mergeFile = strutsApp.getMergeFile( mergeFileName );
     }
     
     private void addRulesFromBeans( ClassDeclaration jclass )
@@ -381,7 +385,7 @@
         throws FileNotFoundException, XmlException, IOException
     {
         String outputFile = _strutsApp.getWebappRoot() + _strutsApp.getOutputFileURI( STRUTS_VALIDATION_PREFIX );
-        writeXml( new PrintStream( new FileOutputStream( outputFile ) ), null );    // @TODO need to pass in the merge file
+        writeXml( new PrintStream( new FileOutputStream( outputFile ) ), _mergeFile );
     }
 
     public String getOutputFileURI()

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/BaseValidationRuleGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/BaseValidationRuleGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/BaseValidationRuleGrammar.java	Sun Aug 22 16:39:26 2004
@@ -21,7 +21,10 @@
 import org.apache.beehive.netui.compiler.AnnotationGrammar;
 import org.apache.beehive.netui.compiler.RuntimeVersionChecker;
 import org.apache.beehive.netui.compiler.Diagnostics;
+import org.apache.beehive.netui.compiler.CompilerUtils;
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.declaration.AnnotationMirror;
+import com.sun.mirror.declaration.MemberDeclaration;
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VERSION_9_0_STRING;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_KEY_ATTR;
@@ -34,6 +37,9 @@
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.ARG2_KEY_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.ARG3_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.ARG3_KEY_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.DISPLAY_NAME_ATTR;
+
+import java.util.List;
 
 
 public class BaseValidationRuleGrammar
@@ -64,5 +70,28 @@
     public String[][] getMutuallyExclusiveAttrs()
     {
         return MUTUALLY_EXCLUSIVE_ATTRS;
+    }
+
+    protected boolean onBeginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations, 
+                                    MemberDeclaration classMember )
+    {
+        //
+        // Check to make sure that either the parent ValidatableProperty annotation has a displayName property,
+        // or this rule specifies a first argument to the default message, or this rule specifies its own message.
+        // If none of these are true, output a warning.
+        //
+        assert parentAnnotations.length > 0;
+        
+        if ( CompilerUtils.getString( parentAnnotations[0], DISPLAY_NAME_ATTR, true ) == null
+             && CompilerUtils.getString( annotation, ARG0_ATTR, true ) == null
+             && CompilerUtils.getString( annotation, ARG0_KEY_ATTR, true ) == null
+             && CompilerUtils.getString( annotation, MESSAGE_ATTR, true ) == null
+             && CompilerUtils.getString( annotation, MESSAGE_ATTR, true ) == null )
+        {
+            addWarning( annotation, "warning.using-default-display-name",
+                        parentAnnotations[0].getAnnotationType().getDeclaration().getSimpleName() );
+        }
+        
+        return super.onBeginCheck( annotation, parentAnnotations, classMember );
     }
 }

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/CatchGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/CatchGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/CatchGrammar.java	Sun Aug 22 16:39:26 2004
@@ -36,6 +36,7 @@
 
 import java.util.Map;
 import java.util.Collection;
+import java.util.List;
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.*;
 
@@ -77,7 +78,8 @@
      * @param checkResults map of member-name (String) -> result-from-checking (Object)
      * @return a result (any Object) that will be passed back to the parent checker.  May be <code>null</code>.
      */
-    protected Object onEndCheck( AnnotationMirror annotation, MemberDeclaration classMember, Map checkResults )
+    protected Object onEndCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                 MemberDeclaration classMember, Map checkResults )
     {
         MethodDeclaration handlerMethod = ( MethodDeclaration ) checkResults.get( METHOD_ATTR );
         ClassType exceptionType = ( ClassType ) checkResults.get( TYPE_ATTR );

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ControllerGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ControllerGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ControllerGrammar.java	Sun Aug 22 16:39:26 2004
@@ -24,19 +24,10 @@
 import org.apache.beehive.netui.compiler.FlowControllerInfo;
 import org.apache.beehive.netui.compiler.Diagnostics;
 import org.apache.beehive.netui.compiler.model.schema.struts11.StrutsConfigDocument;
+import org.apache.beehive.netui.compiler.model.schema.struts11.validator.FormValidationDocument;
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
 
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.LOGIN_REQUIRED_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.ROLES_ALLOWED_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.READONLY_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.STRUTSMERGE_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.FORWARDS_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.CATCHES_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_RESOURCES_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.SIMPLE_ACTIONS_ATTR;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.CONTROLLER_TAG_NAME;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VERSION_8_SP2_STRING;
-import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATABLE_BEANS_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.*;
 
 
 public class ControllerGrammar
@@ -53,6 +44,7 @@
         addMemberType( ROLES_ALLOWED_ATTR, new AnnotationMemberType( null, this ) );
         addMemberType( READONLY_ATTR, new AnnotationMemberType( VERSION_8_SP2_STRING, this ) );
         addMemberType( STRUTSMERGE_ATTR, new ValidXmlFileType( StrutsConfigDocument.type, null, this ) );
+        addMemberType( VALIDATOR_MERGE_ATTR, new ValidXmlFileType( FormValidationDocument.type, null, this ) );
         
         addMemberArrayGrammar( FORWARDS_ATTR, new ForwardGrammar( env, diags, null, rvc, fcInfo ) );
         addMemberArrayGrammar( CATCHES_ATTR, new CatchGrammar( env, diags, null, rvc, CONTROLLER_TAG_NAME, fcInfo ) );

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ExceptionHandlerGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ExceptionHandlerGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ExceptionHandlerGrammar.java	Sun Aug 22 16:39:26 2004
@@ -31,6 +31,7 @@
 import com.sun.mirror.declaration.TypeDeclaration;
 
 import java.util.Collection;
+import java.util.List;
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.READONLY_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VERSION_8_SP2_STRING;
@@ -50,7 +51,8 @@
         addMemberArrayGrammar( FORWARDS_ATTR, new ExceptionHandlerForwardGrammar( fcInfo ) );
     }
 
-    protected boolean onBeginCheck( AnnotationMirror annotation, MemberDeclaration classMember )
+    protected boolean onBeginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                    MemberDeclaration classMember )
     {
         TypeDeclaration outerType = CompilerUtils.getOuterClass( classMember );
         String thisMethodName = classMember.getSimpleName();
@@ -65,7 +67,7 @@
             }
         }
 
-        return super.onBeginCheck( annotation, classMember );
+        return super.onBeginCheck( annotation, parentAnnotations, classMember );
     }
     
     private class ExceptionHandlerForwardGrammar

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ForwardGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ForwardGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ForwardGrammar.java	Sun Aug 22 16:39:26 2004
@@ -117,7 +117,8 @@
     }
 
     protected void onCheckMember( AnnotationTypeElementDeclaration memberDecl, AnnotationValue value,
-                                  AnnotationMirror annotation, MemberDeclaration classMember )
+                                  AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                  MemberDeclaration classMember )
     {
         String valueName = memberDecl.getSimpleName();
         boolean isReturnAction = valueName.equals( RETURN_ACTION_ATTR );

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/SimpleActionGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/SimpleActionGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/SimpleActionGrammar.java	Sun Aug 22 16:39:26 2004
@@ -30,6 +30,8 @@
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.*;
 
+import java.util.List;
+
 
 public class SimpleActionGrammar
         extends AnnotationGrammar
@@ -59,7 +61,8 @@
         _forwardGrammar = new ForwardGrammar( env, diags, null, rvc, fcInfo );
     }
     
-    protected boolean onBeginCheck( AnnotationMirror annotation, MemberDeclaration classMember )
+    protected boolean onBeginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                    MemberDeclaration classMember )
     {
         String name = CompilerUtils.getString( annotation, NAME_ATTR, false );
         
@@ -72,9 +75,9 @@
         // A simple action is really like a combination of an action and a forward.  We extend ActionGrammar and
         // then delegate to a ForwardGrammar here.
         //
-        _forwardGrammar.check( annotation, classMember );
+        _forwardGrammar.check( annotation, parentAnnotations, classMember );
         
-        return super.onBeginCheck( annotation, classMember );
+        return super.onBeginCheck( annotation, parentAnnotations, classMember );
     }
     
     public String[][] getMutuallyExclusiveAttrs()

Added: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateCustomGrammar.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateCustomGrammar.java	Sun Aug 22 16:39:26 2004
@@ -0,0 +1,44 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.compiler.grammar;
+
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_KEY_ATTR;
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import org.apache.beehive.netui.compiler.Diagnostics;
+import org.apache.beehive.netui.compiler.RuntimeVersionChecker;
+
+public class ValidateCustomGrammar
+        extends BaseValidationRuleGrammar
+{
+    private static final String[][] REQUIRED_ATTRS = { { MESSAGE_ATTR, MESSAGE_KEY_ATTR } };
+    
+    public ValidateCustomGrammar( AnnotationProcessorEnvironment env, Diagnostics diagnostics,
+                                  RuntimeVersionChecker rvc )
+    {
+        super( env, diagnostics, rvc );
+    }
+
+    public String[][] getRequiredAttrs()
+    {
+        return REQUIRED_ATTRS;
+    }
+}
+
+

Added: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateValidWhenGrammar.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidateValidWhenGrammar.java	Sun Aug 22 16:39:26 2004
@@ -0,0 +1,44 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.compiler.grammar;
+
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import org.apache.beehive.netui.compiler.Diagnostics;
+import org.apache.beehive.netui.compiler.RuntimeVersionChecker;
+
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.MESSAGE_KEY_ATTR;
+
+
+public class ValidateValidWhenGrammar
+        extends BaseValidationRuleGrammar
+{
+    private static final String[][] REQUIRED_ATTRS = { { MESSAGE_ATTR, MESSAGE_KEY_ATTR } };
+    
+    public ValidateValidWhenGrammar( AnnotationProcessorEnvironment env, Diagnostics diagnostics,
+                                     RuntimeVersionChecker rvc )
+    {
+        super( env, diagnostics, rvc );
+    }
+
+    public String[][] getRequiredAttrs()
+    {
+        return REQUIRED_ATTRS;
+    }
+}

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationFieldGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationFieldGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationFieldGrammar.java	Sun Aug 22 16:39:26 2004
@@ -29,6 +29,8 @@
 
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.*;
 
+import java.util.List;
+
 
 public class ValidationFieldGrammar
         extends AnnotationGrammar
@@ -54,6 +56,8 @@
         addMemberGrammar( VALIDATE_MASK_ATTR, new BaseValidationRuleGrammar( env, diags, rvc ) );
         addMemberGrammar( VALIDATE_DATE_ATTR, new BaseValidationRuleGrammar( env, diags, rvc ) );
         addMemberGrammar( VALIDATE_TYPE_ATTR, new ValidateTypeGrammar( env, diags, rvc ) );
+        addMemberGrammar( VALIDATE_CUSTOM_ATTR, new ValidateCustomGrammar( env, diags, rvc ) );
+        addMemberGrammar( VALIDATE_VALID_WHEN_ATTR, new ValidateValidWhenGrammar( env, diags, rvc ) );
     }
 
     /**
@@ -65,7 +69,8 @@
         return REQUIRED_ATTRS;
     }
 
-    protected boolean onBeginCheck( AnnotationMirror annotation, MemberDeclaration classMember )
+    protected boolean onBeginCheck( AnnotationMirror annotation, AnnotationMirror[] parentAnnotations,
+                                    MemberDeclaration classMember )
     {
         AnnotationMirror actionAnnotation = CompilerUtils.getAnnotation( classMember, ACTION_TAG_NAME );
         

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationLocaleRulesGrammar.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationLocaleRulesGrammar.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/ValidationLocaleRulesGrammar.java	Sun Aug 22 16:39:26 2004
@@ -38,6 +38,8 @@
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_MASK_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_DATE_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_TYPE_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_VALID_WHEN_ATTR;
+import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VALIDATE_CUSTOM_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.VERSION_9_0_STRING;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.LANGUAGE_ATTR;
 import static org.apache.beehive.netui.compiler.JpfLanguageConstants.COUNTRY_ATTR;
@@ -74,6 +76,8 @@
         addMemberGrammar( VALIDATE_MASK_ATTR, new BaseValidationRuleGrammar( env, diags, rvc ) );
         addMemberGrammar( VALIDATE_DATE_ATTR, new BaseValidationRuleGrammar( env, diags, rvc ) );
         addMemberGrammar( VALIDATE_TYPE_ATTR, new ValidateTypeGrammar( env, diags, rvc ) );
+        addMemberGrammar( VALIDATE_CUSTOM_ATTR, new ValidateCustomGrammar( env, diags, rvc ) );
+        addMemberGrammar( VALIDATE_VALID_WHEN_ATTR, new ValidateValidWhenGrammar( env, diags, rvc ) );
         
         addMemberType( LANGUAGE_ATTR, new AnnotationMemberType( null, this ) );
         addMemberType( COUNTRY_ATTR, new AnnotationMemberType( null, this ) );

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/StrutsApp.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/StrutsApp.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/StrutsApp.java	Sun Aug 22 16:39:26 2004
@@ -80,7 +80,7 @@
     protected static final String STRUTSCONFIG_OUTPUT_DIR = "/" + WEBINF_DIR_NAME + "/.pageflow-struts-generated";
     protected static final String VALIDATOR_PLUG_IN_CLASSNAME = "org.apache.struts.validator.ValidatorPlugIn";
     protected static final String VALIDATOR_PATHNAMES_PROPERTY = "pathnames";
-    protected static final String DEFAULT_VALIDATOR_RULES_URI = "/" + WEBINF_DIR_NAME + "/validator-rules.xml";
+    protected static final String DEFAULT_VALIDATOR_RULES_URI = "/" + WEBINF_DIR_NAME + "/netui-validator-rules.xml";
 
     
     public StrutsApp( String controllerClassName )

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatableField.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatableField.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatableField.java	Sun Aug 22 16:39:26 2004
@@ -244,27 +244,30 @@
                 }
             }
             
-            if ( argElementToUse == null )
+            if ( arg != null || altMessageVar != null )
             {
-                argElementToUse = fieldElementClass.getMethod( "addNewArg" + argNum ).invoke( fieldElement );
-            }
-            
-            Class argElementToUseClass = argElementToUse.getClass();
-            
-            if ( arg != null )
-            {
-                String key = ValidatorConstants.EXPRESSION_KEY_PREFIX + arg.getMessage();
-                argElementToUseClass.getMethod( "setKey", String.class ).invoke( argElementToUse, key );
-                String isResource = Boolean.toString( arg.isKey() );
-                argElementToUseClass.getMethod( "setResource", String.class ).invoke( argElementToUse, isResource );
-                argElementToUseClass.getMethod( "setName", String.class ).invoke( argElementToUse, ruleName );
-            }
-            else if ( altMessageVar != null ) 
-            {
-                altMessageVar = "${var:" + altMessageVar + "}";
-                argElementToUseClass.getMethod( "setKey", String.class ).invoke( argElementToUse, altMessageVar );
-                argElementToUseClass.getMethod( "setResource", String.class ).invoke( argElementToUse, "false" );
-                argElementToUseClass.getMethod( "setName", String.class ).invoke( argElementToUse, ruleName );
+                if ( argElementToUse == null )
+                {
+                    argElementToUse = fieldElementClass.getMethod( "addNewArg" + argNum ).invoke( fieldElement );
+                }
+                
+                Class argElementToUseClass = argElementToUse.getClass();
+                
+                if ( arg != null )
+                {
+                    String key = ValidatorConstants.EXPRESSION_KEY_PREFIX + arg.getMessage();
+                    argElementToUseClass.getMethod( "setKey", String.class ).invoke( argElementToUse, key );
+                    String isResource = Boolean.toString( arg.isKey() );
+                    argElementToUseClass.getMethod( "setResource", String.class ).invoke( argElementToUse, isResource );
+                    argElementToUseClass.getMethod( "setName", String.class ).invoke( argElementToUse, ruleName );
+                }
+                else if ( altMessageVar != null ) 
+                {
+                    altMessageVar = "${var:" + altMessageVar + "}";
+                    argElementToUseClass.getMethod( "setKey", String.class ).invoke( argElementToUse, altMessageVar );
+                    argElementToUseClass.getMethod( "setResource", String.class ).invoke( argElementToUse, "false" );
+                    argElementToUseClass.getMethod( "setName", String.class ).invoke( argElementToUse, ruleName );
+                }
             }
         }
         catch ( NoSuchMethodException e )

Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatorConstants.java
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatorConstants.java	(original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/model/validation/ValidatorConstants.java	Sun Aug 22 16:39:26 2004
@@ -35,6 +35,7 @@
     String RULENAME_FLOAT = "float";
     String RULENAME_DOUBLE = "double";
     String RULENAME_DATE = "date";
+    String RULENAME_VALID_WHEN = "netui_validwhen";
     
     String VARNAME_MIN = "min";
     String VARNAME_MAX = "max";
@@ -43,6 +44,7 @@
     String VARNAME_MASK = "mask";
     String VARNAME_DATE_PATTERN = "datePattern";
     String VARNAME_DATE_PATTERN_STRICT = "datePatternStrict";
+    String VARNAME_VALID_WHEN = RULENAME_VALID_WHEN;
     
     String EXPRESSION_KEY_PREFIX = "NETUI-EXPRESSION:";
 }

Modified: incubator/beehive/trunk/netui/src/compiler/schema/struts-validator/struts-validator_1_1.xsd
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/schema/struts-validator/struts-validator_1_1.xsd	(original)
+++ incubator/beehive/trunk/netui/src/compiler/schema/struts-validator/struts-validator_1_1.xsd	Sun Aug 22 16:39:26 2004
@@ -1,6 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- edited with XMLSPY v5 rel. 4 U (http://www.xmlspy.com) by XMLSPY WebLogic Edition (-) -->
-<!--W3C Schema generated by XMLSPY v5 rel. 4 U (http://www.xmlspy.com)-->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
 	<xs:element name="arg0">
 		<xs:complexType>
@@ -67,8 +65,8 @@
 	<xs:element name="form-validation">
 		<xs:complexType>
 			<xs:sequence>
-				<xs:element ref="global" maxOccurs="unbounded"/>
-				<xs:element ref="formset" maxOccurs="unbounded"/>
+				<xs:element ref="global" minOccurs="0" maxOccurs="unbounded"/>
+				<xs:element ref="formset" minOccurs="0" maxOccurs="unbounded"/>
 			</xs:sequence>
 		</xs:complexType>
 	</xs:element>

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java	(original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowController.java	Sun Aug 22 16:39:26 2004
@@ -23,6 +23,7 @@
 import org.apache.beehive.netui.pageflow.scoping.ScopedRequest;
 import org.apache.beehive.netui.util.FileUtils;
 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
+import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils;
 import org.apache.beehive.netui.pageflow.handler.LoginHandler;
 import org.apache.beehive.netui.pageflow.handler.ExceptionsHandler;
 import org.apache.beehive.netui.util.cache.ClassLevelCache;
@@ -447,7 +448,7 @@
             ActionForward retVal;
             if ( pfActionMapping != null && pfActionMapping.isSimpleAction() )
             {
-                retVal = handleSimpleAction( pfActionMapping, form, request, response );
+                retVal = handleSimpleAction( pfActionMapping, form, request, response, servletContext );
             }
             else
             {
@@ -1449,24 +1450,23 @@
     }
 
     private static ActionForward handleSimpleAction( PageFlowActionMapping mapping, ActionForm wrappedFormBean,
-                                                     HttpServletRequest request, HttpServletResponse response )
-        throws ExpressionEvaluationException
+                                                     HttpServletRequest request, HttpServletResponse response,
+                                                     ServletContext servletContext )
     {
         
         Map< String, String > conditionalForwards = mapping.getConditionalForwardsMap();
         
         if ( ! conditionalForwards.isEmpty() )
         {
-            ImplicitObjectBean bean = ImplicitObjectUtil.getImplicitObjects( request, response, wrappedFormBean );
-            ExpressionEvaluator ee = ExpressionEvaluatorFactory.getInstance();
+            Object formBean = InternalUtils.unwrapFormBean( wrappedFormBean );
             
             for ( Iterator< Map.Entry< String, String > > i = conditionalForwards.entrySet().iterator(); i.hasNext(); )
             {
                 Map.Entry< String, String > entry = i.next();
                 String expression = entry.getKey();
                 String forwardName = entry.getValue();
-                Object result = ee.evaluateStrict(expression, bean);
-                if ( result instanceof Boolean && ( ( Boolean ) result ).booleanValue() )
+                
+                if ( InternalExpressionUtils.evaluateCondition( expression, formBean, request, servletContext ) )
                 {
                     if ( _log.isTraceEnabled() )
                     {

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FormData.java
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FormData.java	(original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FormData.java	Sun Aug 22 16:39:26 2004
@@ -55,26 +55,27 @@
     protected ActionErrors validateBean( Object bean, String beanName, ActionMapping mapping, HttpServletRequest request )
     {
 
-        ServletContext application = getServlet().getServletContext();
+        ServletContext servletContext = getServlet().getServletContext();
         ActionErrors errors = new ActionErrors();
 
         //
         // If the ValidatorPlugIn was initialized for this module, run it.
         //
-        if ( Resources.getValidatorResources( application, request ) != null )
+        if ( Resources.getValidatorResources( servletContext, request ) != null )
         {
             try
             {
                 //
                 // Run validations associated with the bean.
                 //
-                Validator beanV = Resources.initValidator( beanName, bean, application, request, errors, page );
+                Validator beanV = Resources.initValidator( beanName, bean, servletContext, request, errors, page );
                 validatorResults = beanV.validate();
                 
                 //
                 // Run validations associated with the action.
                 //
-                Validator actionV = Resources.initValidator( mapping.getPath(), bean, application, request, errors, page );
+                Validator actionV =
+                        Resources.initValidator( mapping.getPath(), bean, servletContext, request, errors, page );
                 validatorResults.merge( actionV.validate() );
             }
             catch ( ValidatorException e )

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java	(original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/annotations/Jpf.java	Sun Aug 22 16:39:26 2004
@@ -34,10 +34,15 @@
     public @interface Controller
     {
         /**
-         * location of the struts merge file; relative to the page flow, or a path from
-         * the webapp root (optional )
+         * Location of the Struts merge file; relative to the page flow, or a path from the webapp root.  Optional.
          */
         String strutsMerge() default "";
+        
+        /**
+         * Location of the ValidatorPlugIn merge file; relative to the page flow, or a path from the webapp root.
+         * Optional.
+         */
+        String validatorMerge() default "";
 
         /**
          * is pageflow nested (optional )
@@ -615,6 +620,14 @@
         String arg3Key() default "";
     }
 
+    @Target( ElementType.ANNOTATION_TYPE )
+    @Retention( RetentionPolicy.RUNTIME )
+    public @interface ValidateCustomVariable
+    {
+        String name();
+        String value();
+    }
+    
     /**
      * Validation rule: Custom.
      */
@@ -624,6 +637,7 @@
     {
         boolean enabled() default true;
         String rule();  // required
+        ValidateCustomVariable[] variables() default {};
         String message() default "";
         String messageKey() default "";
         String arg0() default "";

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalExpressionUtils.java
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalExpressionUtils.java	(original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalExpressionUtils.java	Sun Aug 22 16:39:26 2004
@@ -39,22 +39,20 @@
     public static final boolean evaluateCondition(String expression, 
                                                   Object actionForm,
                                                   HttpServletRequest request, 
-                                                  HttpServletResponse response, 
                                                   ServletContext servletContext)
     {
         // todo: implementation
 
-        return true;
+        return expression.equals( "true" );
     }
 
     public static final String evaluateMessage(String expression, 
                                                 Object actionForm,
                                                 HttpServletRequest request, 
-                                                HttpServletResponse response, 
                                                 ServletContext servletContext)
     {
         // todo: implementation
 
-        return "";
+        return expression;
     }
 }

Added: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/validation/ValidatorRules.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/validation/ValidatorRules.java	Sun Aug 22 16:39:26 2004
@@ -0,0 +1,72 @@
+/*
+ * B E A   S Y S T E M S
+ * Copyright 2002-2004  BEA Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.pageflow.validation;
+
+import org.apache.commons.validator.ValidatorAction;
+import org.apache.commons.validator.Field;
+import org.apache.commons.validator.ValidatorUtil;
+import org.apache.commons.validator.GenericValidator;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.validator.Resources;
+import org.apache.struts.validator.FieldChecks;
+import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletContext;
+
+public class ValidatorRules
+        extends FieldChecks
+{
+    public static boolean validateValidWhen( Object bean, ValidatorAction va, Field field, ActionErrors errors,
+                                             HttpServletRequest request, ServletContext servletContext )
+    {
+
+        String value = null;
+        
+        if ( isString( bean ) )
+        {
+            value = ( String ) bean;
+        }
+        else
+        {
+            value = ValidatorUtil.getValueAsString( bean, field.getProperty() );
+        }
+
+        if ( ! GenericValidator.isBlankOrNull( value ) )
+        {
+            try
+            {
+                String condition = field.getVarValue( "netui_validwhen" );
+
+                if ( ! InternalExpressionUtils.evaluateCondition( condition, bean, request, servletContext ) )
+                {
+                    errors.add( field.getKey(), Resources.getActionError( request, va, field ) );
+                    return false;
+                }
+            }
+            catch ( Exception e )
+            {
+                errors.add( field.getKey(), Resources.getActionError( request, va, field ) );
+                return false;
+            }
+        }
+
+        return true;
+    } 
+}

Modified: incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/ErrorBaseTag.java
==============================================================================
--- incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/ErrorBaseTag.java	(original)
+++ incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/ErrorBaseTag.java	Sun Aug 22 16:39:26 2004
@@ -21,9 +21,11 @@
 import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping;
 import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig;
 import org.apache.beehive.netui.pageflow.internal.InternalConstants;
+import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils;
 import org.apache.beehive.netui.tags.AbstractSimpleTag;
 import org.apache.beehive.netui.tags.ExpressionHandling;
 import org.apache.struts.Globals;
+import org.apache.struts.taglib.html.Constants;
 import org.apache.struts.action.ActionError;
 import org.apache.struts.action.ActionMapping;
 import org.apache.struts.config.ControllerConfig;
@@ -32,6 +34,7 @@
 
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.PageContext;
+import javax.servlet.http.HttpServletRequest;
 import java.util.Locale;
 
 abstract public class ErrorBaseTag extends AbstractSimpleTag
@@ -130,7 +133,10 @@
                     if ( strArg.startsWith( InternalConstants.MESSAGE_IS_EXPRESSION_PREFIX ) )
                     {
                         String argExpr= strArg.substring( InternalConstants.MESSAGE_IS_EXPRESSION_PREFIX_LENGTH );
-                        messageArgs[i] = eh.evaluateExpression( argExpr, argExpr, pageContext);
+                        Object formBean = pageContext.getAttribute( Constants.BEAN_KEY, PageContext.REQUEST_SCOPE );
+                        HttpServletRequest request = ( HttpServletRequest ) pageContext.getRequest();
+                        messageArgs[i] = InternalExpressionUtils.evaluateMessage( argExpr, formBean, request,
+                                                                                  pageContext.getServletContext() );
                     }
                 }
             }
@@ -146,7 +152,9 @@
         else if (key.startsWith(InternalConstants.MESSAGE_IS_EXPRESSION_PREFIX)) {
             // @todo misuse of this api
             String expression = key.substring(InternalConstants.MESSAGE_IS_EXPRESSION_PREFIX_LENGTH);
-            message = (String) eh.evaluateExpression(expression, expression, pageContext);
+            Object formBean = pageContext.getAttribute( Constants.BEAN_KEY, PageContext.REQUEST_SCOPE );
+            HttpServletRequest request = ( HttpServletRequest ) pageContext.getRequest();
+            message = InternalExpressionUtils.evaluateMessage( expression, formBean, request, pageContext.getServletContext() );
         }
         else {
             boolean requestedSpecificBundle = (bundle != null);