You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2005/06/13 02:30:24 UTC

svn commit: r190330 - in /struts/shale/trunk/clay-plugin: ./ src/conf/ src/java/org/apache/shale/clay/component/chain/ src/java/org/apache/shale/clay/config/beans/ src/java/org/apache/shale/clay/config/resources/ src/java/org/apache/shale/clay/parser/ src/java/org/apache/shale/clay/parser/builder/ src/test/org/apache/shale/clay/config/

Author: craigmcc
Date: Sun Jun 12 17:30:23 2005
New Revision: 190330

URL: http://svn.apache.org/viewcvs?rev=190330&view=rev
Log:
Apply the revised patch for Bugzilla issue #35008, related to missing
component inheritances.

Submitted by:  Gary VanMatre <gvanmatre AT comcast.net>

Added:
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestActionListener.java
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestValueChangeListener.java
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.html
Modified:
    struts/shale/trunk/clay-plugin/build.xml
    struts/shale/trunk/clay-plugin/src/conf/view-config.dtd
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/AbstractCommand.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateComponentCommand.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateConverterCommand.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyActionCommand.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentBean.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentConfigBean.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/resources/clay-config_1_0.dtd
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/NodeTokenizer.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/InputTextareaBuilder.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/OutputLabelBuilder.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectBooleanCheckboxBuilder.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemBuilder.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemsBuilder.java

Modified: struts/shale/trunk/clay-plugin/build.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/build.xml?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/build.xml (original)
+++ struts/shale/trunk/clay-plugin/build.xml Sun Jun 12 17:30:23 2005
@@ -60,6 +60,8 @@
   <property name="shale-core.jar"    value="${shale.home}/lib/shale-core.jar"/>
   <property name="standard.jar"      value="${jstl.home}/lib/standard.jar"/>
   <property name="commons-chain.jar" value="${chain.home}/commons-chain-1.0.jar"/>
+  <property name="shale-test.jar"    value="../test-framework/target/lib/shale-test.jar"/>
+
   
 
 
@@ -120,6 +122,7 @@
     <pathelement location="${junit.jar}"/>
     <pathelement location="${servlet-api.jar}"/>
     <pathelement location="${shale-core.jar}"/>
+    <pathelement location="${shale-test.jar}"/>
     <pathelement location="${build.home}/classes"/>
     <pathelement location="${build.home}/test-classes"/>
   </path>

Modified: struts/shale/trunk/clay-plugin/src/conf/view-config.dtd
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/conf/view-config.dtd?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/view-config.dtd (original)
+++ struts/shale/trunk/clay-plugin/src/conf/view-config.dtd Sun Jun 12 17:30:23 2005
@@ -104,7 +104,8 @@
       ValueChangeListeners, the component type will be the fully qualified class name.  The
       componentType will be required when the extends attribute is not specified.  If the 
       extends attribute is specified it will inherit the attribute value from the parent
-      component. 
+      component. It can also override a extended component's type morphing it into
+      another type of component. 
       
    allowBody - This attribute only applies when using the Clay template features and it 
       is optional.  A "true" value is returned if the HTML child nodes under the node that 
@@ -168,6 +169,15 @@
 
    facetName - Use this attribute to register the component in the facets collection rather 
       than the children collection.  
+      
+   componentType - The component type will be the JSF registered logical name for Components,
+      Validators and Converters in the faces-config.xml file.  For ActionListeners and 
+      ValueChangeListeners, the component type will be the fully qualified class name.  The
+      componentType will be required when the extends attribute is not specified.  If the 
+      extends attribute is specified it will inherit the attribute value from the parent
+      component. It can also override a extended component's type morphing it into
+      another type of component. 
+
      
 -->
 <!ELEMENT element (attributes?, converter?, validator*, actionListener*, valueChangeListener*, element*)>
@@ -175,7 +185,8 @@
 	renderId CDATA #REQUIRED
 	jsfid CDATA #REQUIRED
 	id CDATA #IMPLIED
-	facetName CDATA #IMPLIED	
+	facetName CDATA #IMPLIED
+	componentType CDATA #IMPLIED	
 >
 <!--
   A "converter" node is the meta component definition for a JSF converter.  This 

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/AbstractCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/AbstractCommand.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/AbstractCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/AbstractCommand.java Sun Jun 12 17:30:23 2005
@@ -25,7 +25,6 @@
 import org.apache.commons.chain.Command;
 import org.apache.commons.chain.Context;
 import org.apache.commons.chain.config.ConfigParser;
-import org.apache.shale.clay.component.Clay;
 import org.apache.shale.clay.config.Globals;
 import org.apache.shale.util.Messages;
 

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateComponentCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateComponentCommand.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateComponentCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateComponentCommand.java Sun Jun 12 17:30:23 2005
@@ -24,8 +24,6 @@
 import org.apache.commons.chain.Context;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.Globals;
-import org.apache.shale.clay.config.beans.AttributeBean;
 import org.apache.shale.clay.config.beans.ComponentBean;
 
 /**

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateConverterCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateConverterCommand.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateConverterCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/CreateConverterCommand.java Sun Jun 12 17:30:23 2005
@@ -18,8 +18,6 @@
 
 package org.apache.shale.clay.component.chain;
 
-import java.util.Locale;
-
 import javax.faces.component.UIComponent;
 import javax.faces.component.ValueHolder;
 import javax.faces.context.FacesContext;
@@ -29,7 +27,6 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.shale.clay.config.beans.ComponentBean;
-import org.apache.shale.clay.utils.PropUtils;
 
 /**
  * <p>

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyActionCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyActionCommand.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyActionCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyActionCommand.java Sun Jun 12 17:30:23 2005
@@ -79,11 +79,12 @@
         if (facesContext == null)
             throw new NullPointerException(messages.getMessage("clay.null.facesContext"));
 
-        Tags tagUtils = (org.apache.shale.util.Tags)facesContext
-                            .getApplication()
-                            .getVariableResolver()
-                            .resolveVariable(facesContext,
-                                    ShaleConstants.TAG_UTILITY_BEAN);
+        Tags tagUtils = (Tags) facesContext
+                                .getApplication()
+                                .getVariableResolver()
+                                .resolveVariable(facesContext,
+                                        ShaleConstants.TAG_UTILITY_BEAN);
+        
         if (tagUtils == null)
             throw new NullPointerException(messages.getMessage("clay.null.tagUtils"));
 

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java Sun Jun 12 17:30:23 2005
@@ -80,19 +80,35 @@
                 .getValue().indexOf('}') > -1)) {
             String expr = replaceMnemonic(clayContext);
             ValueBinding binding = facesContext.getApplication()
-            .createValueBinding(expr);
+                                                   .createValueBinding(expr);
             
-            if (attributeBean.useValueLateBinding()
-            && child instanceof UIComponent) {
-                ((UIComponent) child).setValueBinding(attributeBean.getName(),
-                        binding);
+            if (attributeBean.useValueLateBinding() && child instanceof UIComponent) {
+                
+                ((UIComponent) child).setValueBinding(attributeBean.getName(), binding);
+                
+            } else if (attributeBean.useMethodLateBinding()) {
+                // Should pass a method value binding expressions to the components 
+                // that use non-standard names like the clay component's shapValidator 
+                // method binding expression.  Standard method binding properties will
+                // be handled by the other property commands
+
+                ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);       
+                   
             } else {
                 Object value = binding.getValue(facesContext);
                 try {
-                    PropUtils
-                            .setProperty(child, attributeBean.getName(), value);
+                    PropUtils.setProperty(child, attributeBean.getName(), value);
                 } catch (Exception e) {
-                    log.error(e);
+                    
+                    // catch the exception and check to see if the attribute name is in the 
+                    // components attributes Map.  If it is, set the value as a string.  
+                    if (((UIComponent) child).getAttributes().containsKey(attributeBean.getName())) {
+                        ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);       
+                    } else {
+                        // not a valid attribute, throw the exception
+                        log.error(e);
+                        throw e;
+                    }
                 }
                 
             }

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentBean.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentBean.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentBean.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentBean.java Sun Jun 12 17:30:23 2005
@@ -223,6 +223,7 @@
                 "\" componentType=\"").append(componentType).append(
                 "\" extends=\"").append(extendsElementId).append("\"")
                 .append(" allowBody=\"").append(allowBody)
+                .append("\" ").append("facetName=\"").append(facetName)
                 .append("\"");
         
         return buff.toString();

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentConfigBean.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentConfigBean.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentConfigBean.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ComponentConfigBean.java Sun Jun 12 17:30:23 2005
@@ -405,10 +405,28 @@
         }
         ci = null;
         
+        // inherit converter from parent
+        if (b.getConverter() == null && b.getIsAParent() != null && b.getIsAParent().getConverter() != null) {
+            b.addConverter((ConverterBean) b.getIsAParent().getConverter());
+        }
+               
         // resolve the inheritance of a nested converter
         if (b.getConverter() != null)
             realizingInheritance(b.getConverter());
         
+        // inheritance of all parent validators
+        if (b.getIsAParent() != null) {
+           Iterator vi = b.getIsAParent().getValidatorIterator();
+           while (vi.hasNext()) {
+               ComponentBean c = (ComponentBean) vi.next();
+               // check to make sure the child doesn't have one
+               if (!b.getValidators().contains(c)) 
+                  b.addValidator((ValidatorBean) c);
+               c = null;
+           }
+           vi = null;
+        }
+               
         // resovle inheritance of all nested validators
         Iterator vi = b.getValidatorIterator();
         while (vi.hasNext()) {
@@ -418,16 +436,39 @@
         }
         vi = null;
         
+        // inheritance of all value change listeners        
+        if (b.getIsAParent() != null) {
+           vi = b.getIsAParent().getValueChangeListenerIterator();
+           while (vi.hasNext()) {
+              ComponentBean c = (ComponentBean) vi.next();
+              if (!b.getValueChangeListeners().contains(c))
+                 b.addValueChangeListener((ValueChangeListenerBean) c);              
+              c = null;
+           }
+           vi = null;
+        }
+               
         // resolve inheritance of all nested value change listeners
         vi = b.getValueChangeListenerIterator();
         while (vi.hasNext()) {
             ComponentBean c = (ComponentBean) vi.next();
             realizingInheritance(c);
             c = null;
-            ci = null;
         }
         vi = null;
         
+        // inheritance of all action listeners        
+        if (b.getIsAParent() != null) {
+           vi = b.getIsAParent().getActionListenerIterator();
+           while (vi.hasNext()) {
+              ComponentBean c = (ComponentBean) vi.next();
+              if (!b.getActionListeners().contains(c))
+                 b.addActionListener((ActionListenerBean) c);              
+              c = null;
+           }
+           vi = null;
+        }
+               
         // resolve inheritance of all nested action listeners
         vi = b.getActionListenerIterator();
         while (vi.hasNext()) {

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/resources/clay-config_1_0.dtd
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/resources/clay-config_1_0.dtd?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/resources/clay-config_1_0.dtd (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/resources/clay-config_1_0.dtd Sun Jun 12 17:30:23 2005
@@ -105,7 +105,8 @@
       ValueChangeListeners, the component type will be the fully qualified class name.  The
       componentType will be required when the extends attribute is not specified.  If the 
       extends attribute is specified it will inherit the attribute value from the parent
-      component. 
+      component.  It can also override a extended component's type morphing it into
+      another type of component. 
       
    allowBody - This attribute only applies when using the Clay template features and it 
       is optional.  A "true" value is returned if the HTML child nodes under the node that 
@@ -168,7 +169,16 @@
       the client id value within the HTML id attribute.
       
    facetName - Use this attribute to register the component in the facets collection rather 
-      than the children collection.       
+      than the children collection. 
+     
+   componentType - The component type will be the JSF registered logical name for Components,
+      Validators and Converters in the faces-config.xml file.  For ActionListeners and 
+      ValueChangeListeners, the component type will be the fully qualified class name.  The
+      componentType will be required when the extends attribute is not specified.  If the 
+      extends attribute is specified it will inherit the attribute value from the parent
+      component.  It can also override a extended component's type morphing it into
+      another type of component. 
+      
 -->
 <!ELEMENT element (attributes?, converter?, validator*, actionListener*, valueChangeListener*, element*)>
 <!ATTLIST element
@@ -176,6 +186,7 @@
 	jsfid CDATA #REQUIRED
 	id CDATA #IMPLIED
 	facetName CDATA #IMPLIED
+	componentType CDATA #IMPLIED
 >
 
 <!--

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/NodeTokenizer.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/NodeTokenizer.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/NodeTokenizer.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/NodeTokenizer.java Sun Jun 12 17:30:23 2005
@@ -23,7 +23,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.component.Clay;
 import org.apache.shale.util.Messages;
 
 /**

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java Sun Jun 12 17:30:23 2005
@@ -21,13 +21,10 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Stack;
 import java.util.TreeMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.ClayConfigureListener;
-import org.apache.shale.util.Messages;
 
 /**
  * <p>Parses the document into a tree of nodes using the

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/InputTextareaBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/InputTextareaBuilder.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/InputTextareaBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/InputTextareaBuilder.java Sun Jun 12 17:30:23 2005
@@ -20,7 +20,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.Globals;
 import org.apache.shale.clay.config.beans.ElementBean;
 import org.apache.shale.clay.parser.Node;
 

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/OutputLabelBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/OutputLabelBuilder.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/OutputLabelBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/OutputLabelBuilder.java Sun Jun 12 17:30:23 2005
@@ -20,7 +20,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.beans.ComponentBean;
 import org.apache.shale.clay.config.beans.ElementBean;
 import org.apache.shale.clay.parser.Node;
 

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectBooleanCheckboxBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectBooleanCheckboxBuilder.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectBooleanCheckboxBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectBooleanCheckboxBuilder.java Sun Jun 12 17:30:23 2005
@@ -20,10 +20,9 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.beans.AttributeBean;
-import org.apache.shale.clay.config.beans.ComponentBean;
 import org.apache.shale.clay.config.beans.ElementBean;
 import org.apache.shale.clay.parser.Node;
+import org.apache.shale.clay.parser.builder.chain.InputBuilderRule;
 
 
 /**

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemBuilder.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemBuilder.java Sun Jun 12 17:30:23 2005
@@ -20,11 +20,11 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.Globals;
 import org.apache.shale.clay.config.beans.AttributeBean;
 import org.apache.shale.clay.config.beans.ComponentBean;
 import org.apache.shale.clay.config.beans.ElementBean;
 import org.apache.shale.clay.parser.Node;
+import org.apache.shale.clay.parser.builder.chain.OptionBuilderRule;
 
 /**
  * <p>

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemsBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemsBuilder.java?rev=190330&r1=190329&r2=190330&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemsBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/SelectItemsBuilder.java Sun Jun 12 17:30:23 2005
@@ -20,7 +20,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.shale.clay.config.Globals;
 import org.apache.shale.clay.config.beans.ElementBean;
 import org.apache.shale.clay.parser.Node;
 import org.apache.shale.clay.parser.builder.chain.OptionBuilderRule;

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java?rev=190330&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java Sun Jun 12 17:30:23 2005
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2004 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.clay.config;
+
+import java.io.InputStream;
+import java.util.Iterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.shale.clay.config.beans.AttributeBean;
+import org.apache.shale.clay.config.beans.ComponentBean;
+import org.apache.shale.clay.config.beans.ComponentConfigBean;
+import org.apache.shale.clay.config.beans.ConfigBean;
+import org.apache.shale.clay.config.beans.ConfigBeanFactory;
+import org.apache.shale.clay.config.beans.ElementBean;
+import org.apache.shale.clay.config.beans.TemplateConfigBean;
+import org.apache.shale.test.base.AbstractViewControllerTestCase;
+import org.apache.shale.test.mock.MockServletContext;
+
+// Tests that the clay component metadata can be loaded and inheritance resolved.
+public class ConfigTestCase extends AbstractViewControllerTestCase {
+
+    // Construct a new instance of this test case.
+    public ConfigTestCase(String name) {
+        super(name);
+    }
+
+    // Return the tests included in this test case.
+    public static Test suite() {
+
+        return (new TestSuite(ConfigTestCase.class));
+
+    }
+
+    protected ConfigBean standardConfigBean = null;
+    protected ConfigBean templateConfigBean = null;
+
+    //COMPONENTS[0] = jsfid, COMPONENTS[1] = componentType, COMPONENT[2] = className
+    protected static final Object[] COMPONENTS = {new String[] {"token", "org.apache.shale.Token", "org.apache.shale.component.Token"},
+                          new String[] {"outputText", "javax.faces.HtmlOutputText", "javax.faces.component.html.HtmlOutputText"}, 
+                          new String[] {"selectItem", "javax.faces.SelectItem", "javax.faces.component.UISelectItem"},
+                          new String[] {"selectItems", "javax.faces.SelectItems", "javax.faces.component.UISelectItems"},
+                          new String[] {"selectOneRadio", "javax.faces.HtmlSelectOneRadio", "javax.faces.component.html.HtmlSelectOneRadio"},
+                          new String[] {"selectOneMenu", "javax.faces.HtmlSelectOneMenu", "javax.faces.component.html.HtmlSelectOneMenu"},
+                          new String[] {"selectManyMenu", "javax.faces.HtmlSelectManyMenu", "javax.faces.component.html.HtmlSelectManyMenu"},
+                          new String[] {"manyCheckbox", "javax.faces.HtmlSelectManyCheckbox", "javax.faces.component.html.HtmlSelectManyCheckbox"},
+                          new String[] {"selectBooleanCheckbox", "javax.faces.HtmlSelectBooleanCheckbox", "javax.faces.component.html.HtmlSelectBooleanCheckbox"},
+                          new String[] {"panelGroup", "javax.faces.HtmlPanelGroup", "javax.faces.component.html.HtmlPanelGroup"},
+                          new String[] {"outputLink", "javax.faces.HtmlOutputLink", "javax.faces.component.html.HtmlOutputLink"},
+                          new String[] {"outputLabel", "javax.faces.HtmlOutputLabel", "javax.faces.component.html.HtmlOutputLabel"},
+                          new String[] {"inputTextarea", "javax.faces.HtmlInputTextarea","javax.faces.component.html.HtmlInputTextarea"},
+                          new String[] {"inputSecret", "javax.faces.HtmlInputSecret","javax.faces.component.html.HtmlInputSecret"},
+                          new String[] {"inputHidden", "javax.faces.HtmlInputHidden", "javax.faces.component.html.HtmlInputText"},
+                          new String[] {"image", "javax.faces.HtmlGraphicImage", "javax.faces.component.html.HtmlGraphicImage"},
+                          new String[] {"form", "javax.faces.HtmlForm", "javax.faces.component.html.HtmlForm"},
+                          new String[] {"dataTable", "javax.faces.HtmlDataTable", "javax.faces.component.html.HtmlDataTable"},
+                          new String[] {"commandLink", "javax.faces.HtmlCommandLink", "javax.faces.component.html.HtmlCommandLink"},
+                          new String[] {"column", "javax.faces.Column", "javax.faces.component.UIColumn"},
+                          new String[] {"inputText", "javax.faces.HtmlInputText", "javax.faces.component.html.HtmlInputHidden"},
+                          new String[] {"outputFormat", "javax.faces.HtmlOutputFormat", "javax.faces.component.html.HtmlOutputFormat"},
+                          new String[] {"messages", "javax.faces.HtmlMessages", "javax.faces.component.html.HtmlMessages"},
+                          new String[] {"message", "javax.faces.HtmlMessage", "javax.faces.component.html.HtmlMessage"},
+                          new String[] {"commandButton", "javax.faces.HtmlCommandButton", "javax.faces.component.html.HtmlCommandButton"},
+                          new String[] {"panelGrid", "javax.faces.HtmlPanelGrid", "javax.faces.component.html.HtmlPanelGrid"},
+                          new String[] {"namingContainer", "javax.faces.NamingContainer", "javax.faces.component.UINamingContainer"}
+    };
+
+    // load the mock component config data
+    protected void loadComponents() {
+       for (int i = 0; i < COMPONENTS.length; i++) {
+          application.addComponent(((String[])COMPONENTS[i])[1], ((String[])COMPONENTS[i])[2]);
+       }
+    }
+    
+    //CONVERTERS[0] = jsfid, CONVERTERS[1] = componentType, CONVERTERS[2] = className
+    protected static final Object[] CONVERTERS = {
+               new String[] {"integerConverter", "javax.faces.Integer", "javax.faces.convert.IntegerConverter"},
+               new String[] {"dateTimeConverter", "javax.faces.DateTime", "javax.faces.convert.DateTimeConverter"}
+    };    
+    
+    // load the mock converter config data
+    protected void loadConverters() {
+        for (int i = 0; i < CONVERTERS.length; i++) {
+           application.addComponent(((String[])CONVERTERS[i])[1], ((String[])CONVERTERS[i])[2]);
+        }
+     }
+    
+    //VALIDATORS[0] = jsfid, VALIDATORS[1] = componentType, VALIDATORS[2] = className
+    public static final Object[] VALIDATORS = {
+               new String[] {"validateLongRange","javax.faces.LongRange", "javax.faces.validator.LongRangeValidator"}
+    };     
+
+    // load the mock validator config
+    protected void loadValidators() {
+        for (int i = 0; i < VALIDATORS.length; i++) {
+           application.addComponent(((String[])VALIDATORS[i])[1], ((String[])VALIDATORS[i])[2]);
+        }
+    }
+
+    // setup the testcase   
+    public void setUp() {
+        super.setUp();
+
+        //load the mock config data
+        loadComponents();
+        loadConverters();
+        loadValidators();
+
+        // create an anonymous extension
+        servletContext = new MockServletContext() {
+            private String contextRoot = "org/apache/shale/clay/config/";
+            public InputStream getResourceAsStream(String path) {
+
+                // Return a corresponding class loader resource
+                ClassLoader classloader = Thread.currentThread()
+                        .getContextClassLoader();
+                if (classloader == null)
+                    classloader = this.getClass().getClassLoader();
+
+                return classloader.getResourceAsStream(contextRoot + path);
+
+            };
+        };
+        
+        // sets the default html template suffix ".html"
+        servletContext.addInitParameter(Globals.CLAY_TEMPLATE_SUFFIX, ".html");
+        
+        // creates the component metadata container from the xml config files
+        standardConfigBean = new ComponentConfigBean();
+        standardConfigBean.init(servletContext);
+        
+        // creates a container that builds the component metadata from an HTML  
+        // template configuration.
+        templateConfigBean = new TemplateConfigBean();
+        templateConfigBean.init(servletContext);
+                
+        // register with the factory
+        ConfigBeanFactory.register(standardConfigBean);
+        ConfigBeanFactory.register(templateConfigBean);
+
+    }
+
+    public void tearDown() {
+        super.tearDown();
+
+        // deregister
+        ConfigBeanFactory.destroy();
+        standardConfigBean = null;
+        templateConfigBean = null;
+    }
+
+    // loads the config files
+    protected void loadConfigFile(String configFiles) {
+        // this would be done in the ClayConfigureListener
+        
+        ClayXmlParser parser = new ClayXmlParser();
+        parser.setConfig((ComponentConfigBean) standardConfigBean);
+
+        parser.load(configFiles);
+
+    }
+    public void testLoadConfigFile() {
+
+        // loads the default config from the META-INF jar folder
+        loadConfigFile(Globals.DEFAULT_CLAY_CONFIG_FILE);
+        
+        //verify the components where loaded
+        for (int i = 0; i < COMPONENTS.length; i++) {
+            ComponentBean bean = standardConfigBean.getElement(((String[])COMPONENTS[i])[0]);
+            assertNotNull("component", bean);
+            assertEquals("component.jsfid", bean.getJsfid(), ((String[])COMPONENTS[i])[0]); 
+            assertEquals("component.componentType", bean.getComponentType(), ((String[])COMPONENTS[i])[1]);
+        }
+
+        //verify converters where loaded
+        for (int i = 0; i < CONVERTERS.length; i++) {
+            ComponentBean bean = standardConfigBean.getElement(((String[])CONVERTERS[i])[0]);
+            assertNotNull("converter", bean);
+            assertEquals("converter.jsfid", bean.getJsfid(), ((String[])CONVERTERS[i])[0]); 
+            assertEquals("converter.componentType", bean.getComponentType(), ((String[])CONVERTERS[i])[1]);
+        }
+
+        //verify validators where loaded 
+        for (int i = 0; i < VALIDATORS.length; i++) {
+            ComponentBean bean = standardConfigBean.getElement(((String[])VALIDATORS[i])[0]);
+            assertNotNull("validator", bean);
+            assertEquals("validator.jsfid", bean.getJsfid(), ((String[])VALIDATORS[i])[0]); 
+            assertEquals("validator.componentType", bean.getComponentType(), ((String[])VALIDATORS[i])[1]);
+        }
+
+    }
+
+    //data that is used to verify the inheritance is working from the XML file.
+    //jsfid, componentType, facetName, allowBody, attributes[], 
+    //aggregates (converters, children, validators, actionListeners, valueChangeListeners)
+    protected static final Object[] CUSTOM_XML_COMPONENTS =  {
+             new Object[] {"street1Label","javax.faces.HtmlOutputLabel", null, "false", 
+                                new Object[] {new String[] {"style", "color:blue"}, 
+                                              new String[] {"value", "Street 1:"},
+                                              new String[] {"for", "street1"}}
+              , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+             },
+             new Object[] {"street1","javax.faces.HtmlOutputText", null, null, 
+                     new Object[] {new String[] {"size", "35"}, 
+                                   new String[] {"maxlength", "50"},
+                                   new String[] {"value", "#{managed-bean-name.address1}"},  
+                                   new String[] {"required", "true"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+             },  
+             new Object[] {"street1Message","javax.faces.HtmlMessage", null, "false", 
+                     new Object[] {new String[] {"style", "color:red"}, 
+                                   new String[] {"for", "street1"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+             },   
+             new Object[] {"street2Label","javax.faces.HtmlOutputLabel", null, "false", 
+                     new Object[] {new String[] {"style", "color:blue"}, 
+                                   new String[] {"value", "Street 2:"},
+                                   new String[] {"for", "street2"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+             },
+             new Object[] {"street2","javax.faces.HtmlInputText", null, null, 
+                     new Object[] {new String[] {"size", "35"}, 
+                        new String[] {"maxlength", "50"},
+                        new String[] {"value", "#{managed-bean-name.address2}"},  
+                        new String[] {"required", "true"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+             },  
+            new Object[] {"street2Message","javax.faces.HtmlMessage", null, "false", 
+                     new Object[] {new String[] {"style", "color:red"}, 
+                        new String[] {"for", "street2"}}
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                                  
+            },  
+            new Object[] {"zip","javax.faces.HtmlInputText", null, null, 
+                     new Object[] {new String[] {"size", "5"}, 
+                        new String[] {"maxlength", "9"},
+                        new String[] {"value", "#{managed-bean-name.zip}"},  
+                        new String[] {"valueChangeListener", "#{managed-bean-name.zipValueChange}"}}
+            , new Integer[] {new Integer(1), new Integer(0), new Integer(1), new Integer(0), new Integer(1)}                      
+            }, 
+            new Object[] {"integerConverter","javax.faces.Integer", null, null, 
+                     new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+            },  
+            new Object[] {"validateLongRange","javax.faces.LongRange", null, null, 
+                     new Object[] {new String[] {"minimum", "80000"}, 
+                        new String[] {"maximum", "80125"}}
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+            },
+            new Object[] {"testValueChangeListener","org.apache.shale.clay.config.TestValueChangeListener", null, null, 
+                     new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                                         
+            },
+            new Object[] {"saveCommand","javax.faces.HtmlCommandButton", null, null, 
+                     new Object[] {new String[] {"value", "Save"}, 
+                        new String[] {"action", "#{managed-bean-name.save}"},
+                        new String[] {"actionListener", "#{managed-bean-name.saveAction}"}}  
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(1), new Integer(0)}                      
+             },
+            new Object[] {"testActionListener","org.apache.shale.clay.config.TestActionListener", null, null, 
+                     new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}                      
+            }  
+    };
+
+    
+    //Data that is used to verify the inheritance is working from the HTML file.
+    //jsfid, componentType, facetName, allowBody, attributes[]
+    //aggregates (converters, children, validators, actionListeners, valueChangeListeners)
+    protected static final Object[] CUSTOM_HTML_COMPONENTS =  {
+             new Object[] {"street1Label","javax.faces.HtmlOutputLabel", null, "false", 
+                                new Object[] {new String[] {"style", "color:blue"}, 
+                                              new String[] {"value", "Street 1:"},
+                                              new String[] {"for", "street1"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+             },
+             new Object[] {"street1","javax.faces.HtmlInputText", null, null, 
+                     new Object[] {new String[] {"size", "45"}, 
+                                   new String[] {"maxlength", "50"},
+                                   new String[] {"value", "#{managed-bean-name.address1}"},  
+                                   new String[] {"required", "true"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+             },  
+             new Object[] {"street1Message","javax.faces.HtmlMessage", null, "false", 
+                     new Object[] {new String[] {"style", "color:red"}, 
+                                   new String[] {"for", "street1"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+             },   
+             new Object[] {"street2Label","javax.faces.HtmlOutputLabel", null, "false", 
+                     new Object[] {new String[] {"style", "color:blue"}, 
+                                   new String[] {"value", "Street 2:"},
+                                   new String[] {"for", "street2"}}
+             , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },
+            new Object[] {"street2","javax.faces.HtmlInputText", null, null, 
+                     new Object[] {new String[] {"size", "45"}, 
+                        new String[] {"maxlength", "50"},
+                        new String[] {"value", "#{managed-bean-name.address2}"},  
+                        new String[] {"required", "true"}}
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },  
+            new Object[] {"street2Message","javax.faces.HtmlMessage", null, "false", 
+                     new Object[] {new String[] {"style", "color:red"}, 
+                        new String[] {"for", "street2"}}
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },  
+            new Object[] {"zip","javax.faces.HtmlInputText", null, null, 
+                     new Object[] {new String[] {"size", "9"}, 
+                        new String[] {"maxlength", "9"},
+                        new String[] {"value", "#{managed-bean-name.zip}"},  
+                        new String[] {"valueChangeListener", "#{managed-bean-name.zipValueChange}"}}
+            , new Integer[] {new Integer(1), new Integer(0), new Integer(1), new Integer(0), new Integer(1)}
+            }, 
+            new Object[] {"integerConverter","javax.faces.Integer", null, null, 
+                     new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },  
+            new Object[] {"validateLongRange","javax.faces.LongRange", null, null, 
+                     new Object[] {new String[] {"minimum", "80000"}, 
+                        new String[] {"maximum", "80125"}}
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },
+            new Object[] {"testValueChangeListener","org.apache.shale.clay.config.TestValueChangeListener", null, null, 
+                     new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            },
+            new Object[] {"saveCommand","javax.faces.HtmlCommandButton", null, null, 
+                     new Object[] {new String[] {"value", "Save"}, 
+                        new String[] {"action", "#{managed-bean-name.save}"},
+                        new String[] {"actionListener", "#{managed-bean-name.saveAction}"}}  
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(1), new Integer(0)}
+            },
+            new Object[] {"testActionListener","org.apache.shale.clay.config.TestActionListener", null, null, 
+              new Object[0]
+            , new Integer[] {new Integer(0), new Integer(0), new Integer(0), new Integer(0), new Integer(0)}
+            }  
+    };
+    
+    
+    
+    // loads the xml config files and validates a sample of 
+    // components state to the know good state.
+    public void testCustomConfigFile() {
+
+        //loads the default and the custom address config files
+        loadConfigFile(Globals.DEFAULT_CLAY_CONFIG_FILE + ", address-config.xml");
+       
+        ComponentBean bean = standardConfigBean.getElement("agentAddressForm");
+        assertNotNull(bean);
+        
+        Iterator ci = bean.getChildrenIterator();
+        while (ci.hasNext()) {
+           ElementBean child = (ElementBean) ci.next();
+           //look for a component that we have setup to test
+           checkComponent(child, CUSTOM_XML_COMPONENTS);    
+        }
+    }
+    
+    
+    // loads the HTML document fragment into a graph of
+    // shale meta component data and validates the select
+    // sample to the known good state
+    public void testLoadHTMLFile() {
+
+        //loads the default and the custom address config file
+        loadConfigFile(Globals.DEFAULT_CLAY_CONFIG_FILE + ", address-config.xml");
+
+        ComponentBean bean = templateConfigBean.getElement("address.html"); 
+        assertNotNull(bean);
+
+        Iterator ci = bean.getChildrenIterator();
+        while (ci.hasNext()) {
+           ElementBean child = (ElementBean) ci.next();
+           //look for a component that we have setup to test
+           checkComponent(child, CUSTOM_HTML_COMPONENTS);    
+        } 
+        
+    }
+
+    // checks a meta components realized state against the assumed values
+    protected void checkComponent(ComponentBean bean, Object[] knownGoodStates) {
+       int indx = indexOf(bean.getJsfid(), knownGoodStates);
+       System.out.println(bean);
+       
+       int converterCnt = -1;
+       int childrenCnt = -1;
+       int validatorCnt = -1;
+       int actionListenerCnt = -1;
+       int valueChangeListenerCnt = -1;
+       
+       
+       if (indx > -1) {
+            Object[] compData = (Object[]) knownGoodStates[indx];
+            
+            String jsfid = (String) compData[0];
+            assertEquals("check.jsfid", jsfid, bean.getJsfid());
+
+            String componentType = (String) compData[1];
+            assertEquals("chekc.componentType", componentType, bean.getComponentType());
+
+            String facetName = (String) compData[2];
+            assertEquals("check.facetName", facetName, bean.getFacetName());
+
+            String allowBody = (String) compData[3];
+            assertEquals("check.allowBody", allowBody, bean.getAllowBody());
+
+            Object[] attributes = (Object[]) compData[4];
+            assertEquals("check.attribute.length", attributes.length, bean.getAttributes().size());
+            for (int i = 0; i < attributes.length; i++) {
+                String[] valuepair = (String[]) attributes[i];
+
+                AttributeBean attr = bean.getAttribute(valuepair[0]);
+                assertNotNull("check.attribute", attr);
+                System.out.println("\t" + attr.toString());
+                assertEquals("check.attribute.value", attr.getValue(), valuepair[1]);
+            }
+            
+            // the know aggregate object counts
+            Integer[] aggregateCnts = (Integer[]) compData[5];
+            converterCnt = aggregateCnts[0].intValue();
+            childrenCnt = aggregateCnts[1].intValue();
+            validatorCnt = aggregateCnts[2].intValue();
+            actionListenerCnt = aggregateCnts[3].intValue();
+            valueChangeListenerCnt = aggregateCnts[4].intValue();
+
+        }
+       
+        if (bean.getConverter() !=  null) {
+            if (converterCnt > -1)
+               assertEquals("check.converter.cnt", converterCnt, 1);
+            
+            checkComponent(bean.getConverter(), knownGoodStates);    
+        }
+        
+        if (childrenCnt > -1) {
+           assertEquals("check.children.cnt", childrenCnt, bean.getChildren().size());    
+        }
+        
+        Iterator ci = bean.getChildrenIterator();
+        while (ci.hasNext()) {
+           ComponentBean child = (ComponentBean) ci.next();
+           checkComponent(child, knownGoodStates);
+        }
+
+        if (validatorCnt > -1) {
+            assertEquals("check.validator.cnt", validatorCnt, bean.getValidators().size());    
+        }
+        
+        ci = bean.getValidatorIterator();
+        while (ci.hasNext()) {
+           ComponentBean child = (ComponentBean) ci.next();
+           checkComponent(child, knownGoodStates);
+        }
+
+        if (actionListenerCnt > -1) {
+            assertEquals("check.actionListener.cnt", actionListenerCnt, bean.getActionListeners().size());    
+        }
+        
+        ci = bean.getActionListenerIterator();
+        while (ci.hasNext()) {
+           ComponentBean child = (ComponentBean) ci.next();
+           checkComponent(child, knownGoodStates);
+        }
+
+        if (valueChangeListenerCnt > -1) {
+            assertEquals("check.valueChangeListener.cnt", valueChangeListenerCnt, bean.getValueChangeListeners().size());    
+        }
+               
+        ci = bean.getValueChangeListenerIterator();
+        while (ci.hasNext()) {
+           ComponentBean child = (ComponentBean) ci.next();
+           checkComponent(child, knownGoodStates);
+        }
+
+    }
+    
+    // looks to see if there is a state check for the components
+    protected int indexOf(String jsfid, Object[] knownGoodStates) {
+         for (int i = 0; i < knownGoodStates.length; i++) {
+             Object[] compData = (Object[]) knownGoodStates[i];
+             String id = (String) compData[0];
+             if (id.equals(jsfid)) {
+                return i;   
+             }
+         }
+        return -1;
+    }
+   
+    
+}

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestActionListener.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestActionListener.java?rev=190330&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestActionListener.java (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestActionListener.java Sun Jun 12 17:30:23 2005
@@ -0,0 +1,24 @@
+package org.apache.shale.clay.config;
+
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class TestActionListener implements ActionListener {
+
+	private static Log log;
+	static {
+		log = LogFactory.getLog(TestActionListener.class);   
+	}
+
+
+	/* (non-Javadoc)
+	 * @see javax.faces.event.ActionListener#processAction(javax.faces.event.ActionEvent)
+	 */
+	public void processAction(ActionEvent arg0) {
+		log.info("processAction invoked");
+	}
+
+}

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestValueChangeListener.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestValueChangeListener.java?rev=190330&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestValueChangeListener.java (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/TestValueChangeListener.java Sun Jun 12 17:30:23 2005
@@ -0,0 +1,22 @@
+package org.apache.shale.clay.config;
+
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ValueChangeEvent;
+import javax.faces.event.ValueChangeListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class TestValueChangeListener implements ValueChangeListener {
+
+	private static Log log;
+	static {
+		log = LogFactory.getLog(TestActionListener.class);   
+	}
+
+	public void processValueChange(ValueChangeEvent event)
+		throws AbortProcessingException {
+		log.info("processValueChange invoked");
+	}
+
+}

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml?rev=190330&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml Sun Jun 12 17:30:23 2005
@@ -0,0 +1,196 @@
+<!DOCTYPE view PUBLIC "-//Apache Software Foundation//DTD Shale Clay View//EN" "http://jakarta.apache.org/struts/dtds/clay-config_1_1.dtd">
+<view>
+		
+	<component jsfid="testActionListener" componentType="org.apache.shale.clay.config.TestActionListener"/>
+	<component jsfid="testValueChangeListener" componentType="org.apache.shale.clay.config.TestValueChangeListener"/>
+		
+	<component jsfid="baseLabel" extends="outputLabel" allowBody="false">
+	   <attributes>
+	       <set name="style" value="color:blue"/>
+	   </attributes>
+	</component>
+	<component jsfid="baseMessage" extends="message" allowBody="false">
+	   <attributes>
+	       <set name="style" value="color:red"/>
+	   </attributes>
+	</component>
+	
+	<component jsfid="cityLabel" extends="baseLabel"> 
+		   <attributes>
+			  <set name="value" value="City:" />		
+			  <set name="for"   value="city" />
+		   </attributes>
+	</component>				
+	<component jsfid="city" extends="inputText" id="city"> 
+		   <attributes>
+		      <set name="value" value="#{managed-bean-name.city}" />		
+			  <set name="size" value="20" />
+			  <set name="maxlength" value="30" />
+			  <set name="required" value="true" />
+		   </attributes>
+	</component>
+	<component jsfid="cityMessage" extends="baseMessage" > 
+		   <attributes>
+		      <set name="for" value="city" />		
+		   </attributes>
+	</component>
+	
+	<!-- state label, input field and message -->	
+	<component jsfid="stateLabel" extends="baseLabel"> 
+		   <attributes>
+			  <set name="value" value="State:" />		
+			  <set name="for"   value="state" />
+		   </attributes>
+	</component>				
+	<component jsfid="state" extends="selectOneMenu" id="state"> 
+       <attributes>
+	      <set name="value" value="#{managed-bean-name.state}" />
+		  <set name="required" value="true" />	      
+ 	   </attributes>
+ 
+	   <element renderId="0" jsfid="selectItem"> 
+		   <attributes>
+		      <set name="itemLabel" value="Colorado" />
+			  <set name="itemValue" value="CO" />
+ 	       </attributes>
+	   </element>
+	   <element renderId="1" jsfid="selectItem"> 
+		   <attributes>
+		      <set name="itemLabel" value="Illinois" />
+			  <set name="itemValue" value="IL" />
+ 	       </attributes>
+	   </element>	
+	</component>
+	<component jsfid="stateMessage" extends="baseMessage"> 
+		   <attributes>
+		      <set name="for" value="state" />		
+		   </attributes>
+	</component>
+
+	<!-- zip code label, input field and message -->
+	<component jsfid="zipLabel" extends="baseLabel"> 
+		   <attributes>
+			  <set name="value" value="Zip:" />		
+			  <set name="for"   value="zip" />
+		   </attributes>
+	</component>					
+	<component jsfid="zip" id="zip" extends="inputText"> 
+       <attributes>
+	      <set name="value" useValueLateBinding="true" value="#{managed-bean-name.zip}" />
+		  <set name="maxlength" value="9" />
+		  <set name="size" value="5"/>
+		  <set name="valueChangeListener" useMethodLateBinding="true" value="#{managed-bean-name.zipValueChange}" />
+		</attributes>
+	
+		<converter jsfid="integerConverter" />
+	    <validator jsfid="validateLongRange">
+		   <attributes>
+		      <set name="minimum" value="80000" />
+			  <set name="maximum" value="80125" />
+		    </attributes>	
+	     </validator>
+		 <valueChangeListener jsfid="testValueChangeListener" />
+	</component> 
+	<component jsfid="zipMessage" extends="baseMessage"> 
+		   <attributes>
+		      <set name="for" value="zip" />		
+		   </attributes>
+	</component>
+
+    <!-- defines a field template type def for street address -->
+	<component jsfid="streetInput" extends="inputText">
+		<attributes>
+			<set name="size" value="35" />
+			<set name="maxlength" value="50" />
+			<set name="value" useValueLateBinding="true"/>
+		</attributes>
+    </component>
+
+	<!-- street 1 label, input field and message -->
+	<component jsfid="street1Label" extends="baseLabel"> 
+		   <attributes>
+			  <set name="value" value="Street 1:" />		
+			  <set name="for"   value="street1" />
+		   </attributes>
+	</component>				
+	<component jsfid="street1" extends="streetInput" id="street1"> 
+        <attributes>
+		   <set name="value" value="#{managed-bean-name.address1}" />		
+		   <set name="required" value="true"  />		
+		</attributes>
+	</component>
+	<component jsfid="street1Message" extends="baseMessage"> 
+		   <attributes>
+		      <set name="for" value="street1" />		
+		   </attributes>
+	</component>
+	
+	<!-- street 2 label, input field and message -->
+	<component jsfid="street2Label" extends="baseLabel"> 
+		   <attributes>
+			  <set name="value" value="Street 2:" />		
+			  <set name="for"   value="street2" />
+		   </attributes>
+	</component>				
+	<component jsfid="street2" extends="streetInput" id="street2"> 
+        <attributes>
+		   <set name="value" value="#{managed-bean-name.address2}" />		
+		   <set name="required" value="true"  />		
+		</attributes>
+	</component>
+	<component jsfid="street2Message" extends="baseMessage"> 
+		   <attributes>
+		      <set name="for" value="street2" />		
+		   </attributes>
+	</component>
+
+    <!-- submit button to save the form -->
+    <component jsfid="saveCommand" extends="commandButton"> 
+	   <attributes>
+	      <set name="value" value="Save" />		
+		  <set name="action" useValueLateBinding="true" value="#{managed-bean-name.save}"  />	
+		  <set name="actionListener" useMethodLateBinding="true" value="#{managed-bean-name.saveAction}"  />			   	
+	   </attributes>
+	   <actionListener jsfid="testActionListener" />
+    </component>
+
+    <!-- address table contains 5 rows of three columns -->    
+	<component jsfid="addressPanel" extends="panelGrid">
+		<attributes>
+			<set name="columns" value="3" />
+		</attributes>
+
+		<element renderId="1" jsfid="street1Label"/>
+		<element renderId="2" jsfid="street1" componentType="javax.faces.HtmlOutputText"/>
+		<element renderId="3" jsfid="street1Message"/>
+
+		<element renderId="11" jsfid="street2Label"/>
+		<element renderId="12" jsfid="street2"/>
+		<element renderId="13" jsfid="street2Message"/>
+
+		<element renderId="21" jsfid="cityLabel"/>
+		<element renderId="22" jsfid="city"/>
+		<element renderId="23" jsfid="cityMessage"/>
+		 
+		<element renderId="31" jsfid="stateLabel"/>
+		<element renderId="32" jsfid="state"/>
+		<element renderId="33" jsfid="stateMessage"/>
+
+		<element renderId="41" jsfid="zipLabel"/>
+		<element renderId="42" jsfid="zip"/>
+		<element renderId="43" jsfid="zipMessage"/>
+		
+    </component>
+
+    <!-- address contains address table and save submit button -->    
+	<component jsfid="agentAddressForm" extends="form" id="address1">
+		<attributes>
+			<set name="style" value="border-style: inset; background-color: red;" />
+		</attributes>
+		
+        <element renderId="1" jsfid="addressPanel"/> 
+        <element renderId="10" jsfid="saveCommand"/>  
+
+	</component>
+						
+</view>

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.html?rev=190330&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.html (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.html Sun Jun 12 17:30:23 2005
@@ -0,0 +1,37 @@
+<form>
+  <table>
+     <tr>
+        <td><label jsfid=street1Label>Mock Address 1:</label></td>
+        <td><input jsfid=street1 type=text size=45></td>
+        <td><span jsfid="street1Message>Mock Error Message</span></td>
+     </tr>
+     <tr>
+        <td><label jsfid=street2Label>Mock Address 2:</label></td>
+        <td><input jsfid=street2 type=text size=45></td>
+        <td><span jsfid="street2Message">Mock Error Message</span></td>
+     </tr>
+     <tr>
+        <td><label jsfid=cityLabel>Mock City:</label></td>
+        <td><input jsfid=city type=text size=25></td>
+        <td><span jsfid="cityMessage">Mock Error Message</span></td>
+     </tr>
+     <tr>
+        <td><label jsfid=stateLabel>Mock State:</label></td>
+        <td>
+            <select jsfid=state> 
+               <option value=M1>Mock 1</option>
+               <option value=M1>Mock 1</option>
+            </select>
+        </td>
+        <td><span jsfid=stateMessage>Mock Error Message</span></td>
+     </tr>
+     <tr>
+        <td><label jsfid=zipLabel>Mock Zip:</label></td>
+        <td><input jsfid=zip type=text size=9></td>
+        <td><span jsfid="zipMessage">Mock Error Message</span></td>
+     </tr>
+     <tr>
+        <td colspan=3><input jsfid=saveCommand type=submit value=Save></td> 
+     </tr>
+  </table>
+</form>
\ No newline at end of file



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