You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by dg...@apache.org on 2005/04/19 04:07:21 UTC

svn commit: r161825 [1/2] - in struts/shale/trunk: ./ core-library/ core-library/src/conf/ core-library/src/java/org/apache/shale/ core-library/src/java/org/apache/shale/component/ core-library/src/java/org/apache/shale/faces/ core-library/src/java/org/apache/shale/taglib/ core-library/src/java/org/apache/shale/util/ core-library/src/java/org/apache/shale/validator/ use-cases/ use-cases/src/java/org/apache/shale/usecases/validator/ use-cases/src/java/org/apache/shale/usecases/view/ use-cases/src/web/ use-cases/src/web/WEB-INF/ use-cases/src/web/validator/

Author: dgeary
Date: Mon Apr 18 19:07:17 2005
New Revision: 161825

URL: http://svn.apache.org/viewcvs?view=rev&rev=161825
Log:
This commit integrates Shale with Apache Commons Validator. The following were added to Shale:

1. A JSF validator that represents a Commons validator. (CommonsValidator)
2. A JSP tag (s:commonsValidator) that represents the validator. (CommonsValidatorTag)
3. A JSF component that generates JavaScript validation according to validators in the page. (ValidatorScript)
4. A JSP tag (s:validatorScript) that represents the component. (ValidatorScriptTag)
5. A utility class for implementing JSP tags that represent JSF components. (Tags)

To use Commons validators in your Shale application, you must have version 1.1.4 or later
of Apache Commons Validator and follow these steps:

a. Add commons-validators.jar to your WAR file.
b. Add validator-rules.xml to WEB-INF. (You can find a copy in use-cases/src/web/WEB-INF)
c. Add an onsubmit attribute to your h:form tag that calls your validation function
d. Add validators, with s:commonsValidator, to your input components
e. Add an s:validatorScript tag just before you close off your form. That tag must have a functionName attribute that corresponds to the function name from step a.

See the use-cases application for an example of client- and server-side validation.

Added:
    struts/shale/trunk/build.properties.sample
      - copied, changed from r161675, struts/shale/trunk/core-library/build.properties.sample
    struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/CommonsValidatorTag.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/ValidatorScriptTag.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/util/Tags.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/validator/CommonsValidator.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/validator/messages.properties
    struts/shale/trunk/core-library/src/java/org/apache/shale/validator/package.html
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/Test.java
    struts/shale/trunk/use-cases/src/web/WEB-INF/validator-rules.xml
    struts/shale/trunk/use-cases/src/web/validator/
    struts/shale/trunk/use-cases/src/web/validator/test.jsp
    struts/shale/trunk/use-cases/src/web/validator/thankYou.jsp
Removed:
    struts/shale/trunk/core-library/build.properties.sample
Modified:
    struts/shale/trunk/core-library/NOTICE.txt
    struts/shale/trunk/core-library/build.xml
    struts/shale/trunk/core-library/src/conf/faces-config.xml
    struts/shale/trunk/core-library/src/conf/taglib.tld
    struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
    struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleConstants.java
    struts/shale/trunk/use-cases/build.xml
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
    struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
    struts/shale/trunk/use-cases/src/web/usecases.jsp

Copied: struts/shale/trunk/build.properties.sample (from r161675, struts/shale/trunk/core-library/build.properties.sample)
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/build.properties.sample?view=diff&rev=161825&p1=struts/shale/trunk/core-library/build.properties.sample&r1=161675&p2=struts/shale/trunk/build.properties.sample&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/build.properties.sample (original)
+++ struts/shale/trunk/build.properties.sample Mon Apr 18 19:07:17 2005
@@ -44,6 +44,14 @@
 # The absolute or relative pathname of the JUnit 3.8.1 JAR
 junit.home = /usr/local/junit-3.8.1
 
+# The absolute or relative pathname of the JSTL install dir
+jstl.home = /Developer/Java/Tools/jakarta/jakarta-taglibs-standard-1.1.0
+
+# The absolute or relative pathname of the Commons Validator install dir
+commons-validator.home = /Developer/Java/Tools/jakarta/commons-validator-1.0.2
+
+# (OPTIONAL) The absolute or relative pathname to the "dist" directory
+
 # The absolute or relative pathname of the directory containing the
 # Jakarta Commons Logging library
 logging.home = /usr/local/commons-logging-1.0.4

Modified: struts/shale/trunk/core-library/NOTICE.txt
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/NOTICE.txt?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/NOTICE.txt (original)
+++ struts/shale/trunk/core-library/NOTICE.txt Mon Apr 18 19:07:17 2005
@@ -7,3 +7,6 @@
 redistributed in accordance with license terms found
 in LICENSE-JSF.txt.
 
+This product contains code written by David Geary and Cay Horstmann
+for the first edition of Core JavaServer Faces. 
+

Modified: struts/shale/trunk/core-library/build.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/build.xml?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/build.xml (original)
+++ struts/shale/trunk/core-library/build.xml Mon Apr 18 19:07:17 2005
@@ -48,10 +48,10 @@
 -->
   <property name="commons-logging.jar"
                                     value="${logging.home}/commons-logging.jar"/>
-<!--
+
   <property name="commons-validator.jar"
                                     value="${struts.home}/lib/commons-validator.jar"/>
--->
+
   <property name="jsf-api.jar"      value="${jsf.home}/lib/jsf-api.jar"/>
   <property name="jsf-impl.jar"     value="${jsf.home}/lib/jsf-impl.jar"/>
   <property name="jsp-api.jar"      value="${server.home}/common/lib/jsp-api.jar"/>
@@ -75,7 +75,7 @@
 
   <!-- Compile Defaults -->
   <property name="compile.debug"           value="true"/>
-  <property name="compile.deprecation"     value="false"/>
+  <property name="compile.deprecation"     value="true"/>
   <property name="compile.optimize"        value="true"/>
 
 
@@ -98,9 +98,8 @@
     <pathelement location="${commons-fileupload.jar}"/>
 -->
     <pathelement location="${commons-logging.jar}"/>
-<!--
+
     <pathelement location="${commons-validator.jar}"/>
--->
     <pathelement location="${jsf-api.jar}"/>
     <pathelement location="${jsp-api.jar}"/>
     <pathelement location="${servlet-api.jar}"/>

Modified: struts/shale/trunk/core-library/src/conf/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/faces-config.xml?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/src/conf/faces-config.xml (original)
+++ struts/shale/trunk/core-library/src/conf/faces-config.xml Mon Apr 18 19:07:17 2005
@@ -67,6 +67,29 @@
     <component-type>org.apache.shale.Token</component-type>
     <component-class>org.apache.shale.component.Token</component-class>
   </component>
+  <component>
+    <description>
+      The "ValidatorScript" component emits JavaScript for client-side
+      validations. 
+    </description>
+    <display-name>ValidatorScript</display-name>
+    <component-type>org.apache.shale.ValidatorScript</component-type>
+    <component-class>org.apache.shale.component.ValidatorScript</component-class>
+  </component>
+
+
+  <!-- Managed Beans -->
+
+  <managed-bean>
+    <description>
+      Utility object for implementing JSF tag classes. Perhaps this should
+      be a Spring bean, but at the time it was added to this config file,
+      Shale-Spring integration was just established. Revisit later on... -->
+    </description>
+    <managed-bean-name>org.apache.shale.TAG_UTILITY_BEAN</managed-bean-name>
+    <managed-bean-class>org.apache.shale.util.Tags</managed-bean-class>
+    <managed-bean-scope>application</managed-bean-scope>
+  </managed-bean>
 
   <!-- Custom Renderers -->
   <render-kit>
@@ -76,5 +99,11 @@
       <renderer-class>org.apache.shale.renderer.TokenRenderer</renderer-class>
     </renderer>
   </render-kit>
+
+  <!-- Custom Validators -->
+  <validator>
+    <validator-id>org.apache.shale.CommonsValidator</validator-id>
+    <validator-class>org.apache.shale.validator.CommonsValidator</validator-class>
+  </validator>
 
 </faces-config>

Modified: struts/shale/trunk/core-library/src/conf/taglib.tld
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/taglib.tld?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/src/conf/taglib.tld (original)
+++ struts/shale/trunk/core-library/src/conf/taglib.tld Mon Apr 18 19:07:17 2005
@@ -134,5 +134,138 @@
 
   </tag>
 
+  <tag>
+
+    <name>commonsValidator</name>
+    <tag-class>org.apache.shale.taglib.CommonsValidatorTag</tag-class>
+    <body-content>empty</body-content>
+    <display-name>Commons Validator</display-name>
+    <description>
+        Provides access to Commons Validators. 
+    </description>
+
+    <!-- Custom -->
+      
+    <attribute> 
+      <name>type</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The type of validator associated with this tag
+      </description>
+    </attribute> 
+
+    <attribute> 
+      <name>min</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The minimum valid value
+      </description>
+    </attribute> 
+
+    <attribute> 
+      <name>max</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The maximum valid value
+      </description>
+    </attribute>
+    
+    <attribute> 
+      <name>minlength</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The minimum valid length of the field
+      </description>
+    </attribute> 
+
+    <attribute> 
+      <name>maxlength</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The maximum valid length of the field
+      </description>
+    </attribute> 
+
+    <attribute> 
+      <name>mask</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        A regular expression to which the value must conform
+      </description>
+    </attribute> 
+    
+    <attribute> 
+      <name>datePatternStrict</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        A date pattern using syntax defined in java.text.SimpleDateFormat
+      </description>
+    </attribute> 
+    
+    <attribute> 
+      <name>message</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        A message displayed when validation fails 
+      </description>
+    </attribute> 
+    
+    <attribute> 
+      <name>arg</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        A value that's plugged into the message
+      </description>
+    </attribute>
+    
+    <attribute> 
+      <name>client</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        If true, validation is performed on the client
+      </description>
+    </attribute>
+    
+    <attribute> 
+      <name>server</name> 
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        If true, validation is performed on the server
+      </description>
+    </attribute>
+  </tag>
+
+  <tag>
+
+    <name>validatorScript</name>
+    <tag-class>org.apache.shale.taglib.ValidatorScriptTag</tag-class>
+    <body-content>empty</body-content>
+    <display-name>Validator Script</display-name>
+    <description>
+      Generates JavaScript for client-side validation      
+    </description>
+
+    <!-- Custom -->
+      
+    <attribute> 
+      <name>functionName</name> 
+      <required>true</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        The name of the function to generate.
+      </description>
+    </attribute> 
+  </tag>
 
 </taglib>

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties Mon Apr 18 19:07:17 2005
@@ -44,4 +44,3 @@
 
 # org.apache.shale.component.Token
 token.invalid=Invalid resubmit of the same form
-

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/component/ValidatorScript.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+package org.apache.shale.component;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.LinkedHashMap;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import org.apache.commons.validator.ValidatorAction;
+
+import org.apache.shale.validator.CommonsValidator;
+
+/**
+ * <p>A JSF component that encodes JavaScript for
+ *    all client-side validations specified in the same
+ *    JSP page (with <code>s:commonsValidator</code>.
+ *
+ * $Id$
+ */
+public class ValidatorScript extends UIComponentBase {
+    
+
+    // -------------------------------------------------------- Private Variables
+
+	 
+    /**
+     * <p>A map of validators, representing all of the Commons Validators
+	  *    attached to components in the current component hierarchy.
+	  *    The keys of the map are validator type names. The values are
+	  *    maps from IDs to CommonsValidator objects.</p>
+     */
+   private Map validators = new LinkedHashMap();   
+
+
+    /**
+     * <p>The component renders itself; therefore, this
+	  *    method returns null.
+     */
+   public String getRendererType() { 
+      return null; 
+   }
+
+
+    /**
+     * <p>Returns the component's family. In this case,
+	  *    the component is not associated with a family,
+	  *    so this method returns null.
+     */
+   public String getFamily() { 
+      return null; 
+   }
+
+
+    /**
+     * <p>Registers a validator according to type and id.
+	  *
+	  * @param type The type of the validator
+	  * @param id The validator's identifier
+	  * @param v The Commons validator associated with the id and type
+     */
+   private void addValidator(String type, String id, CommonsValidator v) {
+      Map map = (Map) validators.get(type);
+      if (map == null) {
+         map = new LinkedHashMap();
+         validators.put(type, map);
+      }
+      if (id != null) map.put(id, v);
+   }
+
+
+    /**
+     * <p>Finds all of the Commons validators for all of the components
+	  *    in a component hierarchy.
+	  *
+	  * @param c The component at the root of the component tree
+	  * @param context The FacesContext for this request
+     */
+   private void findCommonsValidators(UIComponent c, FacesContext context) {
+      if (c instanceof EditableValueHolder) {
+         EditableValueHolder h = (EditableValueHolder) c;
+         javax.faces.validator.Validator[] vs = h.getValidators();
+         for (int i = 0; i < vs.length; i++) {
+            if (vs[i] instanceof CommonsValidator) {
+               CommonsValidator v = (CommonsValidator) vs[i];
+               if (!Boolean.FALSE.equals(v.getClient())) {
+                  String id = c.getClientId(context);
+                  addValidator(v.getType(), id, v);
+                  ValidatorAction action = v.getValidatorAction();
+						List list = action.getDependencyList();
+                  Iterator iter = list.iterator();
+                  while (iter.hasNext()) {
+                     String type = (String) iter.next();
+                     addValidator(type, id, v);
+                  }
+               }
+            }
+         }
+      }
+
+      List children = c.getChildren();
+      for (int i = 0; i < children.size(); i++) {
+         UIComponent child = (UIComponent) children.get(i);
+         findCommonsValidators(child, context);
+      }      
+   }
+
+
+    /**
+     * <p>Write the start of the script for client-side validation.
+	  *
+	  * @param writer A response writer
+     */
+   private void writeScriptStart(ResponseWriter writer) throws IOException {
+      writer.startElement("script", this);
+      writer.writeAttribute("type", "text/javascript", null);
+      writer.writeAttribute("language", "Javascript1.1", null);
+      writer.write("\n<!--\n");
+    }
+
+
+    /**
+     * <p>Write the end of the script for client-side validation.
+	  *
+	  * @param writer A response writer
+     */
+   private void writeScriptEnd(ResponseWriter writer) throws IOException {
+      writer.write("\n-->\n");
+      writer.endElement("script");
+   }
+
+
+    /**
+     * <p>Returns the name of the JavaScript function, specified in
+	  *    the JSP page (presumably), that validates this JSP page's form.
+	  *
+	  * @param action A Validator action
+     */
+   private static String getJavaScriptFunctionName(ValidatorAction action) {
+      StringTokenizer tokenizer = new StringTokenizer(
+         action.getJavascript(),
+         " \n\r\t(");
+      tokenizer.nextToken(); // function
+      return tokenizer.nextToken();
+   }
+
+
+    /**
+     * <p>Returns the name of the JavaScript function, specified in
+	  *    the JSP page (presumably), that validates this JSP page's form.
+	  *
+	  * @param writer A response writer
+	  * @param context The FacesContext for this request
+     */
+   private void writeValidationFunctions(ResponseWriter writer, 
+      FacesContext context) throws IOException {
+      writer.write("var bCancel = false;\n");
+      writer.write("function " );
+      writer.write(getAttributes().get("functionName").toString());
+      writer.write("(form) { return bCancel || true\n");
+      // for each validator type, write "&& fun(form);
+
+      Iterator iter = validators.keySet().iterator();
+      while (iter.hasNext()) {
+         String type = (String) iter.next();
+         ValidatorAction a = CommonsValidator.getValidatorAction(type);
+         writer.write("&& ");
+         writer.write(getJavaScriptFunctionName(a));
+         writer.write("(form)\n");
+      }
+      writer.write(";}\n");
+
+      // for each validator type, write callback
+      iter = validators.keySet().iterator();
+      while (iter.hasNext()) {
+         String type = (String) iter.next();
+         ValidatorAction a = CommonsValidator.getValidatorAction(type);
+         writer.write("function " );
+         String callback = a.getJsFunctionName();
+         if (callback == null) callback = type;
+         writer.write(callback);
+         writer.write("() { \n");
+         // for each field validated by this type, add configuration object
+         Map map = (Map) validators.get(type);
+         Iterator iter2 = map.keySet().iterator();
+         int k = 0;
+         while (iter2.hasNext()) {
+            String id = (String) iter2.next();
+            CommonsValidator v = (CommonsValidator) map.get(id);
+            writer.write("this[" + k + "] = ");
+            k++;
+            writeJavaScriptParams(writer, context, id, v);
+            writer.write(";\n");
+         }
+         writer.write("}\n");         
+      }
+
+      // for each validator type, write code
+
+      // Must always include integer and required because
+      // they contain shared helper functions      
+      addValidator("integer", null, null);
+      addValidator("required", null, null);
+
+      iter = validators.keySet().iterator();
+      while (iter.hasNext()) {
+         String type = (String) iter.next();
+         ValidatorAction a = CommonsValidator.getValidatorAction(type);
+         writer.write(a.getJavascript());
+         writer.write("\n");
+      }
+   }
+
+
+    /**
+     * <p>Writes the JavaScript parameters for the client-side
+	  *    validation code.
+	  *
+	  * @param writer A response writer
+	  * @param context The FacesContext for this request
+	  * @param v The Commons validator
+     */
+   public void writeJavaScriptParams(ResponseWriter writer, 
+      FacesContext context, String id, CommonsValidator v) throws IOException {
+      writer.write("new Array(\"");
+      writer.write(id);
+      writer.write("\", \"");
+      writer.write(v.getErrorMessage(v.getArg(), context));
+      writer.write("\", new Function(\"x\", \"return {");
+      
+      String[] names = v.getParamNames();
+      Object[] params = v.getParams();
+
+      for (int i = 0; i < names.length; i++) {
+         if (i > 0) writer.write(",");
+         writer.write(names[i]);
+         writer.write(":");
+         // Ugh...mask validator doesn't construct RegExp
+         if (names[i].equals("mask"))
+            writer.write("/"); else writer.write("'");
+         writer.write(params[i].toString());
+         if (names[i].equals("mask")) 
+            writer.write("/"); else writer.write("'");
+      }
+      writer.write("}[x];\"))");
+   }
+
+
+    /**
+     * <p>Begin encoding for this component. This method
+	  *    finds all Commons validators attached to components
+	  *    in the current component hierarchy and writes out
+	  *    JavaScript code to invoke those validators, in turn.
+	  *
+	  * @param context The FacesContext for this request
+     */
+   public void encodeBegin(FacesContext context) throws IOException {   
+      String id = getClientId(context);
+      ResponseWriter writer = context.getResponseWriter();    
+
+      validators.clear();
+      findCommonsValidators(context.getViewRoot(), context);
+
+      writeScriptStart(writer);
+      writeValidationFunctions(writer, context);
+      writeScriptEnd(writer);
+   }   
+}

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleConstants.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleConstants.java?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleConstants.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShaleConstants.java Mon Apr 18 19:07:17 2005
@@ -29,6 +29,16 @@
  */
 public interface ShaleConstants {
     
+
+    /**
+     * <p>Application scope attribute that's an instance of
+	  * <code>org.apache.shale.util.Tags</code>. This managed
+	  * bean is defined in <code>faces-config.xml</code> and 
+	  * is used by custom tags.
+	  *
+	  */
+    public static final String TAG_UTILITY_BEAN =
+      "org.apache.shale.TAG_UTILITY_BEAN";
     
     /**
      * <p>Appication scope attribute key under which the

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/CommonsValidatorTag.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/CommonsValidatorTag.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/CommonsValidatorTag.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/CommonsValidatorTag.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+package org.apache.shale.taglib;
+
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.webapp.ValidatorTag;
+import javax.servlet.jsp.JspException;
+
+import org.apache.shale.validator.CommonsValidator;
+import org.apache.shale.faces.ShaleConstants;
+
+/**
+ * The tag class for the <code>s:commonsValidator</code> tag.
+ *
+ * $Id$
+ */
+public class CommonsValidatorTag extends ValidatorTag implements ShaleConstants {
+    
+
+    /**
+     * <p>The tag utility object. This tag class uses the
+	  *    utility object to store tag attribute values as
+	  *    component attributes.
+     */
+   private org.apache.shale.util.Tags tagUtils = null;
+    
+
+    /**
+     * <p>The <code>type</code> attribute.
+     */
+   private String type;
+    
+
+    /**
+     * <p>The <code>min</code> attribute.
+     */
+   private String min;
+    
+
+    /**
+     * <p>The <code>max</code> attribute.
+     */
+   private String max;
+    
+
+    /**
+     * <p>The <code>minlength</code> attribute.
+     */
+   private String minlength;
+    
+
+    /**
+     * <p>The <code>maxlength</code> attribute.
+     */
+   private String maxlength;
+    
+
+    /**
+     * <p>The <code>datePatternStrict</code> attribute.
+     */
+   private String datePatternStrict;
+    
+
+    /**
+     * <p>The <code>mask</code> attribute.
+     */
+   private String mask;
+    
+
+    /**
+     * <p>The <code>message</code> attribute.
+     */
+   private String message;
+    
+
+    /**
+     * <p>The <code>arg</code> attribute.
+     */
+   private String arg;
+    
+
+    /**
+     * <p>The <code>client</code> attribute.
+     */
+   private String client;
+    
+
+    /**
+     * <p>The <code>server</code> attribute.
+     */
+   private String server;
+    
+
+    /**
+     * <p>This constructor obtains a reference to the
+	  *    tag utility object, which is a JSF managed bean.
+     */
+   public CommonsValidatorTag() {
+      setValidatorId("org.apache.shale.CommonsValidator");
+      FacesContext context = FacesContext.getCurrentInstance();
+      tagUtils = (org.apache.shale.util.Tags)context
+                     .getApplication()
+                     .getVariableResolver()
+                     .resolveVariable(context, TAG_UTILITY_BEAN);
+   }
+    
+
+    /**
+     * <p>Setter method for the <code>type</code> attribute.
+     */
+   public void setType(String newValue) { 
+      type = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>min</code> attribute.
+     */
+   public void setMin(String newValue) { 
+      min = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>max</code> attribute.
+     */
+   public void setMax(String newValue) { 
+      max = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>minlength</code> attribute.
+     */
+   public void setMinlength(String newValue) { 
+      minlength = newValue;
+   } 
+
+
+    /**
+     * <p>Setter method for the <code>maxlength</code> attribute.
+     */
+   public void setMaxlength(String newValue) { 
+      maxlength = newValue;
+   } 
+
+
+    /**
+     * <p>Setter method for the <code>setDatePatternStrict</code> attribute.
+     */
+   public void setDatePatternStrict(String newValue) { 
+      datePatternStrict = newValue;
+   } 
+
+
+    /**
+     * <p>Setter method for the <code>mask</code> attribute.
+     */
+   public void setMask(String newValue) { 
+      mask = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>message</code> attribute.
+     */
+   public void setMessage(String newValue) { 
+      message = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>arg</code> attribute.
+     */
+   public void setArg(String newValue) { 
+      arg = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>client</code> attribute.
+     */
+   public void setClient(String newValue) { 
+      client = newValue;
+   } 
+    
+
+    /**
+     * <p>Setter method for the <code>server</code> attribute.
+     */
+   public void setServer(String newValue) { 
+      server = newValue;
+   } 
+    
+
+    /**
+     * <p>Create a validaotor by calling <code>super.createValidator()</code>.
+	  *    This method initializes that validator with the tag's attribute
+	  *    values.
+     */
+   public Validator createValidator() throws JspException {
+      CommonsValidator validator = (CommonsValidator) super.createValidator();
+
+      validator.setType(tagUtils.eval(type));
+      validator.setMin(tagUtils.evalDouble(min));
+      validator.setMax(tagUtils.evalDouble(max));
+      validator.setMinlength(tagUtils.evalInteger(minlength));
+      validator.setMaxlength(tagUtils.evalInteger(minlength));
+      validator.setDatePatternStrict(tagUtils.eval(
+         datePatternStrict));
+      validator.setMask(tagUtils.eval(mask));
+      validator.setMessage(tagUtils.eval(message));
+      validator.setArg(tagUtils.eval(arg));
+      validator.setClient(tagUtils.evalBoolean(client));
+      validator.setServer(tagUtils.evalBoolean(server));
+      
+      return validator;
+   }
+    
+
+    /**
+     * <p>Sets all instance objects representing tag attribute values
+	  *    to <code>null</code>.
+     */
+   public void release() {
+      type = null;
+      min = null;
+      max = null;
+      minlength = null;
+      maxlength = null;
+      datePatternStrict = null;
+      mask = null;
+      message = null;
+      arg = null;
+      client = null;
+      server = null;
+   }
+}

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/ValidatorScriptTag.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/ValidatorScriptTag.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/ValidatorScriptTag.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/ValidatorScriptTag.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+package org.apache.shale.taglib;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.faces.webapp.UIComponentTag;
+
+import org.apache.shale.faces.ShaleConstants;
+
+/**
+ * The tag class for the <code>s:validatorScript</code> tag.
+ *
+ * $Id$
+ */
+public class ValidatorScriptTag extends UIComponentTag implements ShaleConstants { 
+    
+
+    /**
+     * <p>The function name for validating the enclosing form.
+     */
+   private String functionName;
+    
+
+    /**
+     * <p>A Utility object to aid in developing JSF tags. See
+	  *    <code>org.apache.shale.util.Tags</code> for more
+	  *    information.
+     */
+   private org.apache.shale.util.Tags tagUtils = null;
+    
+
+    /**
+     * <p>This constructor retrieves a managed bean
+	  *    that has utility methods for implementing JSP
+	  *    custom tags for JSF components.
+     */
+   public ValidatorScriptTag() {
+      FacesContext context = FacesContext.getCurrentInstance();
+      tagUtils = (org.apache.shale.util.Tags)context
+                     .getApplication()
+                     .getVariableResolver()
+                     .resolveVariable(context, TAG_UTILITY_BEAN);
+   }
+    
+
+    /**
+     * <p>Setter method for the function name.
+	  *
+	  * @param newValue The new value for the function name.
+     */
+   public void setFunctionName(String newValue) { functionName = newValue; }
+    
+
+    /**
+     * <p>Sets properties for the component.
+	  *
+	  * @param component The component whose properties we're setting
+     */
+   public void setProperties(UIComponent component) { 
+      super.setProperties(component); 
+
+      tagUtils.setString(component, "functionName",
+         functionName);
+   } 
+    
+
+    /**
+     * <p>Sets the <code>functionName</code> property to null.
+     */
+   public void release() {
+      functionName = null;
+   }
+
+
+    /**
+     * <p>Returns the renderer type, which is null.
+     */
+   public String getRendererType() { return null; } 
+
+
+    /**
+     * <p>Returns the component type, which is 
+	  *    <code>org.apache.shale.ValidatorScript</code>.
+     */
+   public String getComponentType() { 
+      return "org.apache.shale.ValidatorScript"; 
+   }  
+}

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/util/Tags.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/util/Tags.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/util/Tags.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/util/Tags.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+package org.apache.shale.util;
+
+import java.io.Serializable;
+import javax.faces.application.Application;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.el.MethodBinding;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ValueChangeEvent;
+import javax.faces.webapp.UIComponentTag;
+
+/**
+ * <p>A utility class for JSF tags. An instance of this class is
+ *    specified as an application-scoped managed bean in <code>
+ *    faces-config.xml</code>, under the name 
+ *    <code>org.apache.shale.TAG_UTILITY_BEAN</code>.
+ *    The <code>org.apache.shale.taglib.CommonsValidatorTag</code>
+ *    uses that managed bean.
+ * <p>Nearly all of the methods of this class set a component attribute or
+ *    create a value- or method-binding, given a String representation 
+ *    of the value. The methods check to see whether the value is a value 
+ *    reference (ie. <code>#{...}</code>); if so, the methods set value 
+ *    bindings or method bindings, as appropriate, for the component.
+ *
+ * $Id$
+ */
+public class Tags {
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>String</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+   public void setString(UIComponent component, String attributeName,
+         String attributeValue) {
+      if (attributeValue == null)
+         return;
+      if (UIComponentTag.isValueReference(attributeValue))
+         setValueBinding(component, attributeName, attributeValue);
+      else
+         component.getAttributes().put(attributeName, attributeValue);
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>Integer</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+
+   public void setInteger(UIComponent component, 
+         String attributeName, String attributeValue) {
+      if (attributeValue == null) return;
+      if (UIComponentTag.isValueReference(attributeValue))
+         setValueBinding(component, attributeName, attributeValue);
+      else 
+         component.getAttributes().put(attributeName, 
+               new Integer(attributeValue));
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>Double</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+   public void setDouble(UIComponent component, 
+         String attributeName, String attributeValue) {
+      if (attributeValue == null) return;
+      if (UIComponentTag.isValueReference(attributeValue))
+         setValueBinding(component, attributeName, attributeValue);
+      else 
+         component.getAttributes().put(attributeName, 
+               new Double(attributeValue));
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>Boolean</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+   public void setBoolean(UIComponent component, 
+         String attributeName, String attributeValue) {
+      if (attributeValue == null) return;
+      if (UIComponentTag.isValueReference(attributeValue))
+         setValueBinding(component, attributeName, attributeValue);
+      else 
+         component.getAttributes().put(attributeName, 
+               new Boolean(attributeValue));
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>ValueBinding</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+   
+   public void setValueBinding(UIComponent component, String attributeName,
+         String attributeValue) {
+      FacesContext context = FacesContext.getCurrentInstance();
+      Application app = context.getApplication();
+      ValueBinding vb = app.createValueBinding(attributeValue);
+      component.setValueBinding(attributeName, vb);
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>ActionListener</code>
+	 *    by setting a method binding with the given attribute 
+	 *    value.
+	 *
+	 * @param component The JSF component
+	 * @param attributeValue The value of the attribute
+    */
+
+   public void setActionListener(UIComponent component, String attributeValue) {
+      setMethodBinding(component, "actionListener", attributeValue,
+            new Class[] { ActionEvent.class });      
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>ValueChangeListener</code>
+	 *    by setting a method binding with the given attribute 
+	 *    value.
+	 *
+	 * @param component The JSF component
+	 * @param attributeValue The value of the attribute
+    */
+
+   public void setValueChangeListener(UIComponent component, 
+         String attributeValue) {
+      setMethodBinding(component, "valueChangeListener", attributeValue,
+            new Class[] { ValueChangeEvent.class });      
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>Validator</code>
+	 *    by setting a method binding with the given attribute 
+	 *    value.
+	 *
+	 * @param component The JSF component
+	 * @param attributeValue The value of the attribute
+    */
+   public void setValidator(UIComponent component, 
+         String attributeValue) {
+      setMethodBinding(component, "validator", attributeValue,
+            new Class[] { FacesContext.class, UIComponent.class, Object.class });      
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>Action</code>
+	 *    by setting a method binding with the given attribute 
+	 *    value.
+	 *
+	 * @param component The JSF component
+	 * @param attributeValue The value of the attribute
+    */
+   public void setAction(UIComponent component, String attributeValue) {
+      if (attributeValue == null) return;
+      if (UIComponentTag.isValueReference(attributeValue)) 
+         setMethodBinding(component, "action", attributeValue,
+               new Class[] {});
+      else {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         MethodBinding mb = new ActionMethodBinding(attributeValue);
+         component.getAttributes().put("action", mb);         
+      }
+   }
+
+
+   /**
+	 * <p>Sets the component's <code>attributeName</code> with the
+	 *    given <code>attributeValue</code> as a <code>MethodBinding</code>.
+	 *
+    * <p>If the <code>attributeValue</code> is <code>null</code>, do
+	 *    nothing. If <code>attributeValue</code> is a value reference,
+	 *    set a value binding for the component. Otherwise, store the
+	 *    <code>attributeValue</code> in the component's attribute map.
+	 *
+	 * @param component The JSF component
+	 * @param attributeName The name of the attribute to set
+	 * @param attributeValue The value of the attribute
+    */
+      
+   public void setMethodBinding(UIComponent component, String attributeName,
+         String attributeValue, Class[] paramTypes) {
+      if (attributeValue == null)
+         return;
+      if (UIComponentTag.isValueReference(attributeValue)) {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         MethodBinding mb = app.createMethodBinding(attributeValue, paramTypes);
+         component.getAttributes().put(attributeName, mb);
+      }
+   }     
+
+
+   /**
+	 * <p>Evaluate the <code>expression</code>. If it's a value reference, 
+	 *    get the reference's value. Otherwise, return the <code>expression</code>.
+	 * 
+	 * @param expression The expression
+    */   
+   public String eval(String expression) {
+      if (expression == null) return null;
+      if (UIComponentTag.isValueReference(expression)) {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         return "" + app.createValueBinding(expression).getValue(context); 
+      }
+      else return expression;      
+   }   
+
+
+   /**
+	 * <p>Evaluate the <code>expression</code> and return an <code>Integer</code>.
+	 * 
+	 * @param expression The expression
+    */   
+   public Integer evalInteger(String expression) {
+      if (expression == null) return null;
+      if (UIComponentTag.isValueReference(expression)) {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         Object r = app.createValueBinding(expression).getValue(context); 
+         if (r == null) return null;
+         else if (r instanceof Integer) return (Integer) r;
+         else return new Integer(r.toString());
+      }
+      else return new Integer(expression);      
+   }   
+
+
+   /**
+	 * <p>Evaluate the <code>expression</code> and return a <code>Double</code>.
+	 * 
+	 * @param expression The expression
+    */   
+   public Double evalDouble(String expression) {
+      if (expression == null) return null;
+      if (UIComponentTag.isValueReference(expression)) {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         Object r = app.createValueBinding(expression).getValue(context); 
+         if (r == null) return null;
+         else if (r instanceof Double) return (Double) r;
+         else return new Double(r.toString());
+      }
+      else return new Double(expression);      
+   }   
+
+
+   /**
+	 * <p>Evaluate the <code>expression</code> and return a <code>Boolean</code>.
+	 * 
+	 * @param expression The expression
+    */   
+   public Boolean evalBoolean(String expression) {
+      if (expression == null) return null;
+      if (UIComponentTag.isValueReference(expression)) {
+         FacesContext context = FacesContext.getCurrentInstance();
+         Application app = context.getApplication();
+         Object r = app.createValueBinding(expression).getValue(context); 
+         if (r == null) return null;
+         else if (r instanceof Boolean) return (Boolean) r;
+         else return new Boolean(r.toString());
+      }
+      else return new Boolean(expression);      
+   }   
+
+
+   /**
+	 * <p>A method binding whose result is a canned string.
+	 * 
+    */   
+   private static class ActionMethodBinding 
+         extends MethodBinding implements Serializable {      
+      private String result;
+   
+      public ActionMethodBinding(String result) { this.result = result; }      
+      public Object invoke(FacesContext context, Object params[]) {
+         return result;
+      }
+      public String getExpressionString() { return result; }
+      public Class getType(FacesContext context) { return String.class; }
+   }
+}

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/validator/CommonsValidator.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/validator/CommonsValidator.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/validator/CommonsValidator.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/validator/CommonsValidator.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,590 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+package org.apache.shale.validator;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.faces.application.Application;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import org.apache.commons.validator.GenericValidator;
+import org.apache.commons.validator.ValidatorAction;
+import org.apache.commons.validator.ValidatorResources;
+import org.apache.commons.validator.ValidatorResourcesInitializer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>This is a JSF validator that uses
+ *    a Commons Validator to perform validation, either
+ *    client- or server-side.
+ * 
+ * $Id$
+ */
+
+public class CommonsValidator implements Validator, Serializable {
+
+    // -------------------------------------------------------- Static Variables
+
+
+    /**
+     * <p>Log instance for this class.</p>
+     */
+    private static Logger logger = Logger.getLogger("org.apache.shale.validator");
+
+
+    /**
+     * <p>Map of standard types: boolean, byte, char, etc.
+     *    and their corresponding classes.</p>
+     */
+    private static Map standardTypes;
+    
+
+    /**
+     * <p>Log instance for this class.</p>
+     */
+    private static final Log log = LogFactory.getLog(CommonsValidator.class);
+    
+
+
+    // -------------------------------------------------------- Instance Variables
+
+
+    /**
+     * <p>Validator type</p>
+     */
+    private String type;
+
+
+    /**
+     * <p>The <code>validate</code> method uses this
+     *    as the text of an error message it stores on the
+     *    FacesContext when validation fails.</p>
+     */
+    private String message;
+
+
+    /**
+     * <p>Parameter for the error message. This parameter
+     *    is passed through to the Commons validator.</p>
+     */
+    private String arg;
+
+
+    /**
+     * <p>Enable client-side validation?</p>
+     */
+    private Boolean client;
+
+
+    /**
+     * <p>Enable server-side validation?</p>
+     */
+    private Boolean server;
+
+
+    /**
+     * <p>Minimum value</p>
+     */
+
+    private Double min;
+
+
+    /**
+     * <p>Maximum value</p>
+     */
+    private Double max;
+
+
+    /**
+     * <p>Minimum length, in characters. Use with type="minlength".</p>
+     */
+    private Integer minlength;
+
+
+    /**
+     * <p>Maximum length, in characters. Use with type="minlength".</p>
+     */
+    private Integer maxlength;
+
+
+    /**
+     * <p>A regular expression that's applied to the value</p>
+     */
+    private String mask;
+
+
+    /**
+     * <p>Is date validation strict?</p>
+     */
+    private String datePatternStrict;
+
+
+
+    // -------------------------------------------------------- Transient Variables
+
+
+    /**
+     * <p>A Commons Validator action, that carries out the actual validation.</p>
+     */
+    private transient ValidatorAction validatorAction;
+    
+
+    /**
+     * <p>The Commons Validator method</p>
+     */
+    private transient Method validatorMethod;
+    
+
+    /**
+     * <p>An array of validator classes</p>
+     */
+    private transient Class[] paramTypes;
+    
+
+    /**
+     * <p>A Commons validator</p>
+     */
+    private transient Object validator;
+    
+
+    // ----------------------------------------------------- Property Accessors
+
+
+    /**
+     * <p>The setter method for the <code>type</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>type</code> property.
+     */
+   public void setType(String newValue) { type = newValue; } 
+    
+
+    /**
+     * <p>The getter method for the <code>type</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     */
+   public String getType() { return type; }
+    
+
+    /**
+     * <p>The setter method for the <code>client</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>client</code> property.
+     */
+   public void setClient(Boolean newValue) { client = newValue; } 
+    
+
+    /**
+     * <p>The getter method for the <code>client</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     */
+   public Boolean getClient() { return client; }
+    
+
+    /**
+     * <p>The setter method for the <code>server</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>server</code> property.
+     */
+   public void setServer(Boolean newValue) { server = newValue; } 
+    
+
+    /**
+     * <p>The getter method for the <code>server</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     */
+   public Boolean getServer() { return server; }
+    
+
+    /**
+     * <p>The setter method for the <code>message</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>message</code> property.
+     */
+   public void setMessage(String newValue) { message = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>arg</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>arg</code> property.
+     */
+   public void setArg(String newValue) { arg = newValue; } 
+    
+
+    /**
+     * <p>The getter method for the <code>arg</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     */
+   public String getArg() { return arg; }
+    
+
+    /**
+     * <p>The setter method for the <code>min</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>min</code> property.
+     */
+   public void setMin(Double newValue) { min = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>max</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>max</code> property.
+     */
+   public void setMax(Double newValue) { max = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>minlength</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>minlength</code> property.
+     */
+   public void setMinlength(Integer newValue) { minlength = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>maxlength</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>maxlength</code> property.
+     */
+   public void setMaxlength(Integer newValue) { maxlength = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>mask</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>mask</code> property.
+     */
+   public void setMask(String newValue) { mask = newValue; } 
+    
+
+    /**
+     * <p>The setter method for the <code>datePatternStrict</code> property. This property is 
+     *    passed through to the Commons Validator.</p>
+     *
+     * @param newValue The new value for the <code>datePatternStrict</code> property.
+     */
+   public void setDatePatternStrict(String newValue) { 
+       
+      datePatternStrict = newValue;
+   } 
+    
+
+    /**
+     * <p>The <code>Object[]</code> returned from this method represents 
+     *    parameters that were explicitly set for this validator. 
+     *    Typically, that happens in the <code>s:commonsValidator</code> 
+     *    tag. See the <code>CommonsValidatorTag</code>
+     *    class for more information about those parameters.
+     */
+   public Object[] getParams() { 
+      ArrayList r = new ArrayList();
+      if (min != null) r.add(min);
+      if (max != null) r.add(max);
+      if (minlength != null) r.add(minlength);
+      if (maxlength != null) r.add(maxlength);
+      if (mask != null) r.add(mask);
+      if (datePatternStrict != null) r.add(datePatternStrict);
+      return r.toArray();
+   }
+    
+
+    /**
+     * <p>The <code>String[]</code> returned from this method represents 
+     *    the names of parameters that were explicitly set for this validator. 
+     *    Typically, that happens in the <code>s:commonsValidator</code> 
+     *    tag. See the <code>CommonsValidatorTag</code>
+     *    class for more information about those parameters.
+     */
+   public String[] getParamNames() { 
+      ArrayList r = new ArrayList();
+      if (min != null) r.add("min");
+      if (max != null) r.add("max");
+      if (minlength != null) r.add("minlength");
+      if (maxlength != null) r.add("maxlength");
+      if (mask != null) r.add("mask");
+      if (datePatternStrict != null) r.add("datePatternStrict");
+      return (String[]) r.toArray(new String[r.size()]);
+   }
+
+
+    /**
+     * <p>Returns the Commons validator action that's appropriate
+     *    for the validator with the given <code>name</code>. This method 
+     *    lazily configures validator resources by reading 
+     *    <code>/WEB-INF/validator-rules.xml</code>.
+     *
+     * @param name The name of the validator
+     */
+   public static ValidatorAction getValidatorAction(String name) {
+      final String VALIDATOR_RESOURCES_KEY = 
+           "org.apache.shale.validator.resources";
+      FacesContext context = FacesContext.getCurrentInstance();
+      ExternalContext external = context.getExternalContext();
+      Map applicationMap = external.getApplicationMap();
+      ValidatorResources validatorResources 
+         = (ValidatorResources) applicationMap.get(VALIDATOR_RESOURCES_KEY);
+      if (validatorResources == null) { 
+         InputStream in = external.getResourceAsStream(
+                              "/WEB-INF/validator-rules.xml");
+         validatorResources = new ValidatorResources();
+         try {
+            ValidatorResourcesInitializer.initialize(validatorResources, in);
+            applicationMap.put(VALIDATOR_RESOURCES_KEY, validatorResources);
+         } catch (IOException ex) {
+            logger.log(Level.SEVERE, "can't initialize resources", ex);
+            return null;
+         }
+      }
+      return validatorResources.getValidatorAction(name);
+   }
+
+
+    /**
+     * <p>Returns the Commons validator action that's appropriate
+     *    for this validator. 
+     */
+   public ValidatorAction getValidatorAction() {
+      if (validatorAction == null) validatorAction = getValidatorAction(type);
+      return validatorAction;
+   }
+
+
+    /**
+     * <p>This <code>validate</code> method is called by JSF to verify
+     *    the component to which the validator is attached.
+     *
+     * @param context The faces context
+     * @param component The component to validate
+     */
+   public void validate(FacesContext context, UIComponent component, 
+      Object value) {
+      if (Boolean.FALSE.equals(server)) return;
+      initValidation();     
+      Object[] p = getParams();
+      Object[] params = new Object[p.length + 1];
+
+      params[0] = convert(value, paramTypes[0]);
+      for (int i = 1; i < params.length; i++) 
+         params[i] = convert(p[i - 1], paramTypes[i]);
+
+      try {
+         Boolean r = (Boolean) validatorMethod.invoke(validator, params);
+         
+         if (r.equals(Boolean.FALSE)) {
+            FacesMessage message = new FacesMessage(
+                                                FacesMessage.SEVERITY_ERROR,
+               getErrorMessage(value, context), null);
+            throw new ValidatorException(message);
+         }
+      } catch (IllegalAccessException ex) {
+         logger.log(Level.SEVERE, "can't invoke validator", ex);
+      } catch (InvocationTargetException ex) {
+         logger.log(Level.SEVERE, "can't invoke validator", ex);
+      }
+   }
+
+
+    /**
+     * <p>Initialize validation by invoking <code>getValidatorAction</code>
+     *    and setting up instance data.
+     */
+   public void initValidation() {
+      if (validatorMethod != null) return;     
+      getValidatorAction();      
+      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+      if (classLoader == null) classLoader = getClass().getClassLoader();
+      try {
+         List params = validatorAction.getMethodParamsList();
+         paramTypes = new Class[params.size()];
+         for (int i = 0; i < paramTypes.length; i++) {
+            String paramTypeName = (String) params.get(i);
+            paramTypes[i] = (Class) standardTypes.get(paramTypeName);
+            if (paramTypes[i] == null) 
+               paramTypes[i] = classLoader.loadClass(paramTypeName);
+         }      
+         Class c = classLoader.loadClass(validatorAction.getClassname());      
+         validatorMethod 
+            = c.getMethod(validatorAction.getMethod(), paramTypes);
+         if (!Modifier.isStatic(validatorMethod.getModifiers())) 
+            validator = c.newInstance();
+      } catch (ClassNotFoundException ex) {
+         logger.log(Level.SEVERE, "can't load validator or param class", ex);
+      } catch (NoSuchMethodException ex) {
+         logger.log(Level.SEVERE, "can't get validator method", ex);
+      } catch (InstantiationException ex) {
+         logger.log(Level.SEVERE, "can't instantiate validator", ex);
+      } catch (IllegalAccessException ex) {
+         logger.log(Level.SEVERE, "can't instantiate validator", ex);
+      }
+   }
+
+
+    /**
+     * <p>Retrieves an error message, using the validator's message combined
+     *    with the errant value.
+     */
+   public String getErrorMessage(Object value, FacesContext context) {
+      final String DEFAULT_BUNDLE_NAME = "org.apache.shale.validator.messages";
+
+      Locale locale = context.getViewRoot().getLocale();
+      String msg = message;
+      if (msg == null) { 
+         String msgkey = validatorAction.getMsg();
+         ClassLoader loader = Thread.currentThread().getContextClassLoader();
+         if (loader == null) loader = getClass().getClassLoader();
+         Application app = context.getApplication();
+         String appBundleName = app.getMessageBundle();
+         if (appBundleName != null) {
+            ResourceBundle bundle 
+               = ResourceBundle.getBundle(appBundleName, locale, loader);
+            if (bundle != null)
+               try {
+                  msg = bundle.getString(msgkey);
+               } catch (MissingResourceException ex) {
+               }
+         }
+         if (msg == null) {            
+            ResourceBundle bundle 
+               = ResourceBundle.getBundle(DEFAULT_BUNDLE_NAME, locale, loader);
+            if (bundle != null)
+               try {
+                  msg = bundle.getString(msgkey);
+               } catch (MissingResourceException ex) {
+               }
+         }
+      }
+      Object[] p = getParams();
+      Object[] params = new Object[p.length + 1];
+      params[0] = value;
+      for (int i = 1; i < params.length; i++) 
+         params[i] = p[i - 1];
+      msg = new MessageFormat(msg, locale).format(params);
+      return msg;
+   }
+    
+
+    // ----------------------------------------------------- Static Initialization
+
+
+    /**
+     * <p>A utility method that converts an object to an instance
+     *    of a given class, such as converting <code>"true"</code> 
+     *    for example, into <code>Boolean.TRUE</code>.
+     *
+     * @param obj The object to convert
+     * @param cl The type of object to convert to
+     */
+   private static Object convert(Object obj, Class cl) {
+      if (cl.isInstance(obj)) return obj;
+      if (cl == String.class) return "" + obj;
+      if (obj instanceof String) {
+         String str = (String) obj;
+         if (cl == boolean.class) return Boolean.valueOf(str);
+         if (cl == byte.class) return new Byte(str);
+         if (cl == char.class) return new Character(str.charAt(0));
+         if (cl == double.class) return new Double(str);
+         if (cl == float.class) return new Float(str);
+         if (cl == int.class) return new Integer(str);
+         if (cl == long.class) return new Long(str);
+         if (cl == short.class) return new Short(str);
+      } else if (obj instanceof Number) {
+         Number num = (Number) obj;
+         if (cl == byte.class) return new Byte(num.byteValue());
+         if (cl == double.class) return new Double(num.doubleValue());
+         if (cl == float.class) return new Float(num.floatValue());
+         if (cl == int.class) return new Integer(num.intValue());
+         if (cl == long.class) return new Long(num.longValue());
+         if (cl == short.class) return new Short(num.shortValue());         
+      }
+      return obj;
+   }
+
+
+    /**
+     * <p>A utility method that returns <code>true</code> if
+     *    the supplied string has a length greater than zero.
+     *
+     * @param str The string
+     */
+   // these two methods are referenced in validator-utils.xml
+   public static boolean isSupplied(String str) {
+      return str.trim().length() > 0;
+   }
+
+
+    /**
+     * <p>A utility method that returns <code>true</code> if
+     *    the supplied string represents a date.
+     *
+     * @param d The string representation of the date.
+     * @param datePatternStrict Commons validator property
+     */
+   public static boolean isDate(String d, String datePatternStrict) {
+      return GenericValidator.isDate(d, datePatternStrict, true);
+   }
+    
+
+    // ----------------------------------------------------- Static Initialization
+
+
+    /**
+     * <p>Standard types for conversions</p>
+     */
+   static {
+      standardTypes = new HashMap();
+      standardTypes.put("boolean", boolean.class);
+      standardTypes.put("byte", byte.class);
+      standardTypes.put("char", char.class);
+      standardTypes.put("double", double.class);
+      standardTypes.put("float", float.class);
+      standardTypes.put("int", int.class);
+      standardTypes.put("long", long.class);
+      standardTypes.put("short", short.class);
+      standardTypes.put("java.lang.String", String.class);
+   }
+
+}

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/validator/messages.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/validator/messages.properties?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/validator/messages.properties (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/validator/messages.properties Mon Apr 18 19:07:17 2005
@@ -0,0 +1,16 @@
+errors.required={0} is required.
+errors.minlength={0} can not be less than {1} characters.
+errors.maxlength={0} can not be greater than {1} characters.
+errors.invalid={0} is invalid.
+
+errors.byte={0} must be a byte.
+errors.short={0} must be a short.
+errors.integer={0} must be an integer.
+errors.long={0} must be a long.
+errors.float={0} must be a float.
+errors.double={0} must be a double.
+
+errors.date={0} is not a date.
+errors.range={0} is not in the range {1} through {2}.
+errors.creditcard={0} is an invalid credit card number.
+errors.email={0} is an invalid e-mail address.

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/validator/package.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/validator/package.html?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/validator/package.html (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/validator/package.html Mon Apr 18 19:07:17 2005
@@ -0,0 +1,25 @@
+<!--
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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.
+-->
+
+<!-- $Id$ -->
+
+<body>
+
+<p>This package contains a JSF validator that uses
+the Apache Commons Validator API to perform both
+client- and server-side validation.</p>
+
+</body>

Modified: struts/shale/trunk/use-cases/build.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/build.xml?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/use-cases/build.xml (original)
+++ struts/shale/trunk/use-cases/build.xml Mon Apr 18 19:07:17 2005
@@ -32,7 +32,6 @@
   <property file="../../../build.properties"/>
   <property file="${user.home}/build.properties"/>
 
-
   <!-- Dependency home directory defaults -->
   <property name="chain.home"       value="/usr/local/commons-chain-1.0"/>
   <property name="htmlunit.home"    value="/usr/local/htmlunit-1.4"/>
@@ -42,7 +41,6 @@
   <property name="server.home"      value="/usr/local/jakarta-tomcat-5.0.28"/>
   <property name="spring.home"      value="/usr/local/spring-framework-1.2-rc1"/>
 
-
   <!-- Dependency library defaults -->
   <property name="commons-beanutils.jar"
                                     value="${jsf.home}/lib/commons-beanutils.jar"/>
@@ -54,6 +52,9 @@
                                     value="${jsf.home}/lib/commons-digester.jar"/>
   <property name="commons-logging.jar"
                                     value="${jsf.home}/lib/commons-logging.jar"/>
+  <property name="commons-validator.jar"
+                                    value="${commons-validator.home}/commons-validator.jar"/>
+
   <property name="jsf-api.jar"      value="${jsf.home}/lib/jsf-api.jar"/>
   <property name="jsf-impl.jar"     value="${jsf.home}/lib/jsf-impl.jar"/>
   <property name="jsp-api.jar"      value="${server.home}/common/lib/jsp-api.jar"/>
@@ -81,7 +82,7 @@
 
   <!-- Compile Defaults -->
   <property name="compile.debug"           value="true"/>
-  <property name="compile.deprecation"     value="false"/>
+  <property name="compile.deprecation"     value="true"/>
   <property name="compile.optimize"        value="true"/>
 
 
@@ -195,6 +196,7 @@
     <echo  message="jsf-impl.jar =     ${jsf-impl.jar}"/>
     <echo  message="shale-core.jar =   ${shale-core.jar}"/>
     <echo  message="spring-core.jar =  ${spring-core.jar}"/>
+    <echo  message="commons-validator.jar =  ${commons-validator.jar}"/>
     <echo  message="jsfri.present =    ${jsfri.present}"/>
     <echo  message="myfaces.present =  ${myfaces.present}"/>
     <echo  message="spring.present =   ${spring.present}"/>
@@ -234,6 +236,8 @@
     <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
                   file="${commons-logging.jar}"/>
     <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
+                  file="${commons-validator.jar}"/>
+    <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
                   file="${shale-core.jar}"/>
     <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
                   file="${shale-spring.jar}"/>
@@ -245,6 +249,14 @@
                   file="${spring-core.jar}"/>
     <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
                   file="${spring-web.jar}"/>
+    <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
+                  file="${jsf-api.jar}"/>
+    <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
+                  file="${jsf-impl.jar}"/>
+    <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
+                  file="${jstl.jar}"/>
+    <copy        todir="${build.home}/${context.path}/WEB-INF/lib"
+                  file="${standard.jar}"/>
 
   </target>
 

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/Test.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/Test.java?view=auto&rev=161825
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/Test.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/validator/Test.java Mon Apr 18 19:07:17 2005
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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 languamount governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.usecases.validate;
+
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.view.AbstractViewController;
+
+/**
+ * <p>Backing bean for the validator use case.</p>
+ *
+ * $Id$
+ */
+public class Test extends AbstractViewController {
+    
+    
+    // -------------------------------------------------------- Static Variables
+
+
+    /**
+     * <p>The <code>Log</code> instance for this class.</p>
+     */
+    private static final Log log = LogFactory.getLog(Test.class);
+
+
+    // -------------------------------------------------------------- Properties
+
+    /**
+     * <p>The amount.</p>
+     */
+    private double amount = 0;
+
+
+    /**
+     * <p>Return the amount.</p>
+     */
+    public double getAmount() {
+
+        return amount;
+
+    }
+
+    /**
+     * <p>Set the amount.</p>
+     */
+    public void setAmount(double newValue) {
+
+        amount = newValue;
+
+    }
+
+    /**
+     * <p>The credit card.</p>
+     */
+    private String creditCard;
+
+
+    /**
+     * <p>Return the creditCard.</p>
+     */
+    public String getCreditCard() {
+
+        return creditCard;
+
+    }
+
+    /**
+     * <p>Set the creditCard.</p>
+     */
+    public void setCreditCard(String newValue) {
+
+        creditCard = newValue;
+
+    }
+
+    /**
+     * <p>The expiration date.</p>
+     */
+    private Date expirationDate;
+
+
+    /**
+     * <p>Return the expirationDate.</p>
+     */
+    public Date getExpirationDate() {
+
+        return expirationDate;
+
+    }
+
+    /**
+     * <p>Set the expirationDate.</p>
+     */
+    public void setExpirationDate(Date newValue) {
+
+        expirationDate = newValue;
+
+    }
+
+}

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties Mon Apr 18 19:07:17 2005
@@ -82,6 +82,8 @@
 prompt.password2=Password (Again):
 prompt.remember=Remember Me
 prompt.username=Username:
+prompt.creditCardNumber=Credit Card Number
+prompt.expirationDate=Expiration Date
 
 # Locale Selection Labels and Messages
 select.mismatch=You selected non-supported locale {0}, so no change was made
@@ -112,3 +114,16 @@
 usecases.primary=Primary Use Cases
 usecases.subview=Subview Processing
 usecases.title=Shale Framework Use Cases
+usecases.validator=Commons Validator Integration
+usecases.validate=Validation (client- and server-side)
+
+# Validation
+validate.test.title=Shale Validation using Commons Validator
+validate.test.thank.you.title=Thank You
+validate.test.payment.heading=Please enter your payment information
+validate.test.payment.thank.you.heading=Thank you for your payment!
+validate.test.amount=Amount
+validate.test.currency.symbol=$
+validate.test.unknown.credit.card.type=Unknown Credit Card Type
+validate.test.bad.expiration.date=Bad Expiration Date. Enter the date in this format: mm/dd/yyyy
+validate.test.description=This form has seven validators, all implemented with s:commonsValidator:<p><ul><li>Amount: <strong>required</strong> (client) and <strong>floatRange</strong> (server)<li>Credit Card Number: <strong>required</strong> (client) <strong>mask</strong> ([4-6].*) (client) and <strong>creditCard</strong> (server)<li>Expiration Date: <strong>required</strong> (client) <strong>date</strong> (server)</ul><p>Note: because of the Credit Card Number field's mix of client- and server-side validators, entering "33" in the field results in a JavaScript alert (because the mask validator catches it), but entering "55" results in server-side validation and a subsequent error message displayed in the form.<p>See the Apache Commons Validator documentation for more information about other available validators.

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml?view=diff&r1=161824&r2=161825
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml Mon Apr 18 19:07:17 2005
@@ -104,6 +104,19 @@
   </navigation-rule>
 
 
+  <!-- ============================ VALIDATE Test ========================== -->
+
+
+  <!-- ViewController Beans -->
+
+  <managed-bean>
+    <managed-bean-name>validate$test</managed-bean-name>
+    <managed-bean-class>
+      org.apache.shale.usecases.validate.Test
+    </managed-bean-class>
+    <managed-bean-scope>request</managed-bean-scope>
+  </managed-bean>
+
   <!-- =========================== Logon Dialog ============================ -->
 
 
@@ -181,6 +194,10 @@
   <navigation-rule>
     <from-view-id>*</from-view-id>
     <navigation-case>
+      <from-outcome>usecases$toplevel</from-outcome>
+      <to-view-id>/usecases.jsp</to-view-id>
+    </navigation-case>
+    <navigation-case>
       <from-outcome>logon$authenticated</from-outcome>
       <to-view-id>/usecases.jsp</to-view-id>
     </navigation-case>
@@ -204,6 +221,18 @@
       <from-outcome>logon$unauthenticated</from-outcome>
       <to-view-id>/usecases.jsp</to-view-id>
     </navigation-case>
+    <navigation-case>
+      <from-outcome>validate$test</from-outcome>
+      <to-view-id>/validator/test.jsp</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-outcome>validate$test</from-outcome>
+      <to-view-id>/validator/test.jsp</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-outcome>validate$thankYou</from-outcome>
+      <to-view-id>/validator/thankYou.jsp</to-view-id>
+    </navigation-case>
   </navigation-rule>
 
 
@@ -480,7 +509,5 @@
 
 
 </faces-config>
-
-
 
 



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