You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by gv...@apache.org on 2005/09/27 06:34:14 UTC

svn commit: r291820 - in /struts/shale/trunk: clay-plugin/src/conf/ clay-plugin/src/java/org/apache/shale/clay/ clay-plugin/src/java/org/apache/shale/clay/component/ clay-plugin/src/java/org/apache/shale/clay/config/beans/ clay-plugin/src/java/org/apac...

Author: gvanmatre
Date: Mon Sep 26 21:33:57 2005
New Revision: 291820

URL: http://svn.apache.org/viewcvs?rev=291820&view=rev
Log:
Added an assumed ignore jsfid handler for creating a html block that is excluded from further processing.  In effect it acts like a comment block.

Added a "view source" page to the rolodex use-case examples for comparing the four clay view techniques.

Added:
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/IgnoreBuilder.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/IgnoreBuilderRule.java
    struts/shale/trunk/use-cases/src/web/rolodex/viewsource.html
Modified:
    struts/shale/trunk/clay-plugin/src/conf/view-config.xml
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/Bundle.properties
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/LoadBundle.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/beans/ConfigDefinitionsWatchdogFilter.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/shale-builder-config.xml
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java
    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/address-config.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

Modified: struts/shale/trunk/clay-plugin/src/conf/view-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/conf/view-config.xml?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/view-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/conf/view-config.xml Mon Sep 26 21:33:57 2005
@@ -135,6 +135,8 @@
       <set name="value" useValueLateBinding="true" />       
     </attributes>
   </component>
+  <!-- acts like a comment tag treating child nodes as verbatim -->
+  <component jsfid="ignore" componentType="javax.faces.HtmlOutputText" />
   
   
   
@@ -1160,13 +1162,22 @@
   </component>	
 
   <!-- Inline HTML Tag -->    
-  <component jsfid="clayTag" extends="clay">
+  <component jsfid="clayOut" extends="clay">
     <attributes>
-      <set name="shapeValidator" useMethodLateBinding="true" value="#{ClayAmalgam.createHTMLTag}"/> 
-      <set name="tag" useMethodLateBinding="true"/>
+      <set name="shapeValidator" useMethodLateBinding="true" value="#{ClayAmalgam.clayOut}"/> 
+      <set name="value" useValueLateBinding="false"/>
+      <set name="excapeXml" useValueLateBinding="false" value="true"/>
     </attributes>
   </component>	
 
+  <!-- Inline Import Tag -->    
+  <component jsfid="clayImport" extends="clay">
+    <attributes>
+      <set name="shapeValidator" useMethodLateBinding="true" value="#{ClayAmalgam.clayImport}"/> 
+      <set name="url" useValueLateBinding="false"/>
+      <set name="excapeXml" useValueLateBinding="false" value="false"/>
+    </attributes>
+  </component>	
 
 
 </view>

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/Bundle.properties?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/Bundle.properties (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/Bundle.properties Mon Sep 26 21:33:57 2005
@@ -117,6 +117,7 @@
 circular.child.extends.same.parent.exception=Circular composition detected; contained element ({0}) cannot inherit from owning parent component ({1}).
 jsfid.notfound=The component identified by jsfid {0} could not be found.
 config.notloaded=ConfigBean is not loaded to handle a component identified by jsfid {0}.
+file.notfound=Unable to find file {0}.  If this is a full HTML or XML view, check your navigation rules.
 
 #org.apache.shale.clay.config.beans.TemplateConfigBean
 loading.template=Loading clay HTML template {0}
@@ -129,3 +130,7 @@
 #org.apache.shale.clay.utils.PropUtils
 unable.to.set.property.error="Could not set property {0} in bean {1}
 
+#org.apache.shale.clay.utils.ClayAmalgam
+missing.attribute=The "{0}" attribute is required when using the ClayAmalgam.{1}() validator method binding event.
+invalid.binding=Invalid use of the Amalgam.{0}() validator method binding event.  This method assume the use of the Clay component's "shapeValidator" property binding.
+invalid.attribute=The "{0}" attribute is required when using the ClayAmalgam.{1}() validator method binding event.

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/LoadBundle.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/LoadBundle.java?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/LoadBundle.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/LoadBundle.java Mon Sep 26 21:33:57 2005
@@ -30,7 +30,6 @@
 
 import javax.faces.component.UIComponentBase;
 import javax.faces.context.FacesContext;
-import javax.faces.el.ValueBinding;
 
 import org.apache.shale.faces.ShaleConstants;
 import org.apache.shale.util.Tags;

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=291820&r1=291819&r2=291820&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 Mon Sep 26 21:33:57 2005
@@ -214,7 +214,7 @@
                 } else {
                    URL url = context.getResource(configFile.toString()); 
                    if (url == null) {
-                      throw new RuntimeException("Unable to find file :" + configFile.toString());
+                      throw new RuntimeException(messages.getMessage("file.notfound", new Object[] {configFile.toString()}));
                    }
                    urls.add(url);
                 }
@@ -265,9 +265,9 @@
      */
     public ComponentBean getElement(String jsfid) {
         ComponentBean element = null;
-        //synchronized (displayElements) {
+        synchronized (displayElements) {
             element = (ComponentBean) displayElements.get(jsfid);            
-        //}
+        }
         return element;
     }
     
@@ -390,7 +390,7 @@
      */
     public void assignParent(ComponentBean b) {
         
-       // synchronized (displayElements) {
+        synchronized (displayElements) {
             
             if (b instanceof InnerComponentBean) {
                 
@@ -435,7 +435,7 @@
                 assignParent((ComponentBean) vi.next());
             vi = null;
             
-        //}
+        }
         
     }
     
@@ -1160,9 +1160,9 @@
         if (!ComponentConfigBean.this.isWatchDogOn || watchDog == null)
            return wasDirty;
         
-        //synchronized (displayElements) {
+        synchronized (displayElements) {
             wasDirty = watchDog.refresh(forceReload);
-        //}
+        }
         
         watchDog = null;
         

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ConfigDefinitionsWatchdogFilter.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ConfigDefinitionsWatchdogFilter.java?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ConfigDefinitionsWatchdogFilter.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/ConfigDefinitionsWatchdogFilter.java Mon Sep 26 21:33:57 2005
@@ -19,7 +19,6 @@
 package org.apache.shale.clay.config.beans;
 
 import org.apache.shale.application.AbstractRegExpFilter;
-import org.apache.shale.clay.config.Globals;
 import org.apache.shale.faces.ShaleWebContext;
 
 public class ConfigDefinitionsWatchdogFilter extends AbstractRegExpFilter {

Added: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/IgnoreBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/IgnoreBuilder.java?rev=291820&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/IgnoreBuilder.java (added)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/IgnoreBuilder.java Mon Sep 26 21:33:57 2005
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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$
+ */
+package org.apache.shale.clay.parser.builder;
+
+import java.util.Iterator;
+
+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;
+
+/**
+ * <p>This {@link Builder} is designed to ignore processing on a 
+ * block of HTML.  If the jsfid attribute of the HTML node is 
+ * "ignore", all of the child nodes under the marked nodes are
+ * excluded from further processing.  The are treated like a
+ * verbatim block.  The outer node is removed from the output.
+ * </p> 
+ *
+ */
+public class IgnoreBuilder extends CommentBuilder {
+
+    /**
+     * <p>Returns the <code>jsfid</code> for the target {@link ElementBean}.</p>
+     */    
+    protected String getJsfid(Node node) {
+        return "ignore";
+    }
+     
+    /**
+     * <p>Builds a outputText component.  The attribute value is the content of the 
+     * child nodes.  The root HTML {@link Node} is not included in the content
+     * of the <code>target</code> {@link ElementBean} node.
+     * </p>
+     */
+    protected void encodeBegin(Node node, ElementBean target, ComponentBean root) {
+        StringBuffer value = new StringBuffer();
+        captureComment(node, value);
+        
+        AttributeBean attr = createAttribute("value", value.toString(), target);
+        
+        attr.setUseMethodLateBinding(Boolean.FALSE.toString());
+        attr.setUseValueLateBinding(Boolean.TRUE.toString());        
+        createAttribute("escape", Boolean.FALSE.toString(), target);
+        createAttribute("isTransient", Boolean.TRUE.toString(), target);
+    
+    }
+    
+    /**
+     * <p>Recursively traverses the children of the HTML 
+     * {@link org.apache.shale.clay.parser.Node} concatenating 
+     * the raw text of each {@link org.apache.shale.clay.parser.Token} 
+     * into the <code>commentBody</code>.  Ending nodes are not kept
+     * with the parser.  If a start node is found that is not self 
+     * terminated, a matching ending node is created.</p>
+     */
+    protected void captureComment(Node node, StringBuffer commentBody) {
+        Iterator ni = node.getChildren().iterator();
+        while (ni.hasNext()) {
+           Node child = (Node) ni.next();
+           commentBody.append(child.getToken().getRawText());
+           captureComment(child, commentBody);
+           if (child.isStart() && !child.isEnd() && child.isWellFormed()) {
+              commentBody.append("</").append(child.getName()).append(">");    
+           }
+        }
+    }
+    
+}

Added: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/IgnoreBuilderRule.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/IgnoreBuilderRule.java?rev=291820&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/IgnoreBuilderRule.java (added)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/IgnoreBuilderRule.java Mon Sep 26 21:33:57 2005
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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$
+ */
+
+package org.apache.shale.clay.parser.builder.chain;
+
+import org.apache.commons.chain.Command;
+import org.apache.commons.chain.Context;
+import org.apache.shale.clay.parser.Node;
+import org.apache.shale.clay.parser.builder.Builder;
+import org.apache.shale.clay.parser.builder.IgnoreBuilder;
+
+/**
+ * <p>This builder will be ordered first in the rule registration list.
+ * If the node has a <code>jsfid</code> attribute, and its value is
+ * "ignore", child elements will be rendered as comment/verbatim
+ * content.</p>
+ */
+public class IgnoreBuilderRule implements Command {
+ 
+    /**
+     * <p>The builder that will ignore a block similar to the 
+     * CommentBuilder.
+     * <p>
+     */    
+    private static final Builder[] builders = {new IgnoreBuilder()};
+  
+    /**
+     * <p>If the node has a <code>jsfid</code> attribute, and its value is
+     * "ignore", child elements will be rendered as comment/verbatim
+     * content.  The enclosing tag will not be rendered in the document,
+     * only it's children.</p>
+     */
+    public boolean execute(Context context) throws Exception {
+        boolean isFinal = false;
+        
+        BuilderRuleContext builderRuleContext = (BuilderRuleContext) context;
+        Node node = builderRuleContext.getNode();
+        if (!node.isComment() && node.isStart() && node.getName() != null) {
+            String jsfid = null;
+            if ((jsfid = (String) node.getAttributes().get("jsfid")) != null) {
+               if (jsfid.equals("ignore")) {
+                   builderRuleContext.setBuilder(builders[0]);
+                   isFinal = true;
+               }
+            }
+        } 
+        
+        return isFinal;
+    }
+    
+}

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/shale-builder-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/shale-builder-config.xml?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/shale-builder-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/chain/shale-builder-config.xml Mon Sep 26 21:33:57 2005
@@ -23,7 +23,8 @@
 <catalog           name="builder">
 
   <chain           name="findBuilder">
-
+
+    <command  className="org.apache.shale.clay.parser.builder.chain.IgnoreBuilderRule"/>
     <command  className="org.apache.shale.clay.parser.builder.chain.InputBuilderRule"/>
     <command  className="org.apache.shale.clay.parser.builder.chain.FormBuilderRule"/>
     <command  className="org.apache.shale.clay.parser.builder.chain.SelectBuilderRule"/>

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java Mon Sep 26 21:33:57 2005
@@ -18,22 +18,43 @@
 
 package org.apache.shale.clay.utils;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.shale.clay.component.Clay;
+import org.apache.shale.clay.config.ClayConfigureListener;
 import org.apache.shale.clay.config.beans.AttributeBean;
 import org.apache.shale.clay.config.beans.ComponentBean;
+import org.apache.shale.faces.ShaleConstants;
+import org.apache.shale.util.Messages;
+import org.apache.shale.util.Tags;
 
 /**
  * <p>This class is a mix of runtime utilities for the 
- * {@link org.apache.shale.clay.component.Clay}.  It is
- * loaded as a managed bean in application scope by the
- * clay component's registration.</p>  
+ * {@link org.apache.shale.clay.component.Clay} component.  
+ * It is loaded as a managed bean in application scope by 
+ * the clay component's registration.</p>  
  */
 public class ClayAmalgam {
 
+    /**
+     * <p>Commons logging utility object static instance.</p>
+     */
+    private static Log log;
+    static {
+        log = LogFactory.getLog(ClayAmalgam.class);
+    }
+    
+    /**
+     * <p>Message resources for this class.</p>
+     */
+    private static Messages messages = new Messages("org.apache.shale.clay.Bundle",
+            ClayConfigureListener.class.getClassLoader());
     
     /**
      * <p>Replaces tokens in the <code>document</code> with 
@@ -72,11 +93,13 @@
     private static TreeMap encodeMap = null;
     static {
         encodeMap = new TreeMap();
-        encodeMap.put("\"", "&quote;");
-        encodeMap.put("'", "&apos;");
+        encodeMap.put("\"", "&quot;");
+        encodeMap.put("'", "&#39;");
         encodeMap.put("&", "&amp;");
         encodeMap.put("<", "&lt;");
         encodeMap.put(">", "&gt;");
+        encodeMap.put("}", "&#125;");
+        encodeMap.put("{", "&#123;");  
     }
 
     /**
@@ -94,11 +117,13 @@
     private static TreeMap decodeMap = null;
     static {
         decodeMap = new TreeMap();
-        decodeMap.put("&quote;", "\"");
-        decodeMap.put("&apos;", "'");
+        decodeMap.put("&quot;", "\"");
+        decodeMap.put("&#39;", "'");
         decodeMap.put("&amp;", "&");
         decodeMap.put("&lt;", "<");
         decodeMap.put("&gt;", ">");
+        decodeMap.put("&#125;", "}");
+        decodeMap.put("&#123;", "{");        
     }
 
     /**
@@ -114,40 +139,145 @@
     /**
      * <p>This is a method binding "validator" signature that can be bound to the 
      * <code>shapeValidator</code> attribute of the {@link org.apache.shale.clay.component.Clay}
-     * component.  It expects that the <code>tag</code> attribute will contain an html string that
-     * represents an HTML node.  The tag value should be encoded.  The resulting component will be
-     * a verbatim tag that contains the html decode.</p>   
+     * component.  It expects that the <code>value</code> attribute will contain an html string that
+     * represents an HTML node.  The value will be encode or decode depending on the value of the
+     * <code>escapeXml</code> optional attribute.  The default is "false". </p>   
      */
-    public void createHTMLTag(javax.faces.context.FacesContext context,
+    public void clayOut(javax.faces.context.FacesContext context,
             javax.faces.component.UIComponent component,
             java.lang.Object displayElementRoot) {
-     
-         ComponentBean text = (ComponentBean) displayElementRoot;
-         Clay clay = (Clay) component;
-         String html = decode((String) clay.getAttributes().get("tag")); 
-             
-         text.setJsfid("outputText");
-         text.setComponentType("javax.faces.HtmlOutputText");
-
-         // add a value attribute
-         AttributeBean attr = new AttributeBean();
-         attr.setName("value");
-         attr.setValue(html);
-         text.addAttribute(attr);
-
-         // add a escape attribute
-         attr = new AttributeBean();
-         attr.setName("escape");
-         attr.setValue(Boolean.FALSE.toString());
-         text.addAttribute(attr);
-         
-         // add a isTransient attribute
-         attr = new AttributeBean();
-         attr.setName("isTransient");
-         attr.setValue(Boolean.TRUE.toString());
-         text.addAttribute(attr);
-               
+       
+        Tags tagUtils = (Tags) context.getApplication().getVariableResolver()
+                                      .resolveVariable(context, ShaleConstants.TAG_UTILITY_BEAN);
+        
+        if (!(displayElementRoot instanceof ComponentBean) ||
+                !(component instanceof Clay)) {
+            throw new RuntimeException(messages.getMessage("invalid.binding", new Object[] {"clayOut"}));    
+        }
+        
+        ComponentBean text = (ComponentBean) displayElementRoot;
+        Clay clay = (Clay) component;
+        String value = (String) clay.getAttributes().get("value");
+        if (value == null) {
+            throw new RuntimeException(messages.getMessage("missing.attribute", new Object[] {"value", "clayOut"}));    
+        }
+        
+        boolean escapeXml = false;
+        String tmp = (String) clay.getAttributes().get("escapeXml");
+        if (tmp != null) {
+           escapeXml =  tagUtils.evalBoolean(tmp).booleanValue();
+        }
+        
+        if (!escapeXml)
+            value = decode(value);
+        else 
+            value = encode(value);
+        
+        text.setJsfid("outputText");
+        text.setComponentType("javax.faces.HtmlOutputText");
+        
+        // add a value attribute
+        AttributeBean attr = new AttributeBean();
+        attr.setName("value");
+        attr.setValue(value);
+        text.addAttribute(attr);
+        
+        // add a escape attribute
+        attr = new AttributeBean();
+        attr.setName("escape");
+        attr.setValue(Boolean.FALSE.toString());
+        text.addAttribute(attr);
+        
+        // add a isTransient attribute
+        attr = new AttributeBean();
+        attr.setName("isTransient");
+        attr.setValue(Boolean.TRUE.toString());
+        text.addAttribute(attr);
+        
     }
 
-    
+    /**
+     * <p>This is a method binding "validator" signature that can be bound to the 
+     * <code>shapeValidator</code> attribute of the {@link org.apache.shale.clay.component.Clay}
+     * component.  It expects that the <code>url</code> attribute will contain the file to import
+     * relative to the web context root. The content of the file will be encode or decode depending 
+     * on the value of the <code>escapeXml</code> optional attribute.  The default is "true". </p>   
+     */
+    public void clayImport(javax.faces.context.FacesContext context,
+            javax.faces.component.UIComponent component,
+            java.lang.Object displayElementRoot) {
+        
+        Tags tagUtils = (Tags) context.getApplication().getVariableResolver()
+                                      .resolveVariable(context, ShaleConstants.TAG_UTILITY_BEAN);
+        
+        if (!(displayElementRoot instanceof ComponentBean) ||
+                !(component instanceof Clay)) {
+            throw new RuntimeException(messages.getMessage("invalid.binding", new Object[] {"clayImport"}));    
+        }
+        
+        ComponentBean text = (ComponentBean) displayElementRoot;
+        Clay clay = (Clay) component;
+        String url = (String) clay.getAttributes().get("url");
+        if (url == null) {
+            throw new RuntimeException(messages.getMessage("missing.attribute", new Object[] {"url", "clayImport"}));    
+        }
+        url = tagUtils.eval(url);
+        
+        boolean escapeXml = true;
+        String tmp = (String) clay.getAttributes().get("escapeXml");
+        if (tmp != null) {
+           escapeXml =  tagUtils.evalBoolean(tmp).booleanValue();
+        }
+                
+        StringBuffer value = new StringBuffer();
+        
+        InputStream in = null;
+        try {
+            in = context.getExternalContext().getResourceAsStream(url);
+            int c = 0;
+            done: while (true) {
+                c = in.read();
+                if (c > -1)
+                    value.append((char) c);
+                else
+                    break done;
+                
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(messages.getMessage("invalid.attribute", new Object[] {"url", "clayImport"}));
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {}
+            }   
+            
+        }
+        
+        if (!escapeXml)
+            replace(value, decodeMap);
+        else 
+            replace(value, encodeMap);
+           
+        text.setJsfid("outputText");
+        text.setComponentType("javax.faces.HtmlOutputText");
+        
+        // add a value attribute
+        AttributeBean attr = new AttributeBean();
+        attr.setName("value");
+        attr.setValue(value.toString());
+        text.addAttribute(attr);
+        
+        // add a escape attribute
+        attr = new AttributeBean();
+        attr.setName("escape");
+        attr.setValue(Boolean.FALSE.toString());
+        text.addAttribute(attr);
+        
+        // add a isTransient attribute
+        attr = new AttributeBean();
+        attr.setName("isTransient");
+        attr.setValue(Boolean.TRUE.toString());
+        text.addAttribute(attr);
+    }   
 }

Modified: 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=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java (original)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/ConfigTestCase.java Mon Sep 26 21:33:57 2005
@@ -397,19 +397,19 @@
             
             AttributeBean attr = null;
             if (child.getId().equals("htmlBegin")) {
-                attr = child.getAttribute("tag");
+                attr = child.getAttribute("value");
                 assertEquals(attr.getValue(), "<html>");
             } else if (child.getId().equals("htmlEnd")) {
-                attr = child.getAttribute("tag");
+                attr = child.getAttribute("value");
                 assertEquals(attr.getValue(), "</html>");
             } else if (child.getId().equals("header")) {
-                attr = child.getAttribute("tag");
+                attr = child.getAttribute("value");
                 assertEquals(attr.getValue(), "<head><title>Testing</title></head>");
             } else if (child.getId().equals("bodyBegin")) {
-                attr = child.getAttribute("tag");
+                attr = child.getAttribute("value");
                 assertEquals(attr.getValue(), "<body>");
             } else if (child.getId().equals("bodyEnd")) {
-                attr = child.getAttribute("tag");
+                attr = child.getAttribute("value");
                 assertEquals(attr.getValue(), "</body>");
             } else if (child.getId().equals("content")) {
                 //look for a component that we have setup to test

Modified: 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=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address-config.xml Mon Sep 26 21:33:57 2005
@@ -199,19 +199,19 @@
 	</component>
 	
     <component jsfid="layout" extends="outputText">
-        <element id="htmlBegin" renderId="0" jsfid="clayTag"> 
+        <element id="htmlBegin" renderId="0" jsfid="clayOut"> 
             <attributes>
-               <set name="tag" value="&lt;html&gt;"/>
+               <set name="value" value="&lt;html&gt;"/>
             </attributes>
         </element>
-        <element id="header" renderId="2" jsfid="clayTag"> 
+        <element id="header" renderId="2" jsfid="clayOut"> 
             <attributes>
-               <set name="tag" value="&lt;head&gt;&lt;title&gt;Testing&lt;/title&gt;&lt;/head&gt;"/>
+               <set name="value" value="&lt;head&gt;&lt;title&gt;Testing&lt;/title&gt;&lt;/head&gt;"/>
             </attributes>
         </element>
-        <element id="bodyBegin" renderId="4" jsfid="clayTag"> 
+        <element id="bodyBegin" renderId="4" jsfid="clayOut"> 
             <attributes>
-               <set name="tag" value="&lt;body&gt;"/>
+               <set name="value" value="&lt;body&gt;"/>
             </attributes>
         </element>
      
@@ -222,16 +222,16 @@
             </attributes>
         </element>
         
-        <element id="bodyEnd" renderId="40" jsfid="clayTag"> 
+        <element id="bodyEnd" renderId="40" jsfid="clayOut"> 
             <attributes>
-               <set name="tag" value="&lt;/body&gt;"/>
+               <set name="value" value="&lt;/body&gt;"/>
             </attributes>
         </element>
         
         
-         <element id="htmlEnd" renderId="100" jsfid="clayTag"> 
+         <element id="htmlEnd" renderId="100" jsfid="clayOut"> 
             <attributes>
-               <set name="tag" value="&lt;/html&gt;"/>
+               <set name="value" value="&lt;/html&gt;"/>
             </attributes>
          </element>
         

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?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- 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 Sep 26 21:33:57 2005
@@ -132,6 +132,7 @@
 usecases.rolodex2=Rolodex Example (Full HTML View)
 usecases.rolodex3=Rolodex Example (Full Extreme HTML View)
 usecases.rolodex4=Rolodex Example (Full XML View)
+usecases.rolodex.viewsource=View Source
 
 
 # Validation

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?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- 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 Sep 26 21:33:57 2005
@@ -169,163 +169,170 @@
   <!-- ============================ Rolodex Test =========================== -->
 
 
-
-  <navigation-rule>
-    <!-- JSP View -->
-    <from-view-id>/usecases*</from-view-id>
-    <navigation-case>
-      <from-outcome>rolodex$test1</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-
-    <!-- HTML View -->
-    <navigation-case>
-      <from-outcome>rolodex$test2</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-
-    <!-- Extreme HTML View -->
-    <navigation-case>
-      <from-outcome>rolodex$test3</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-
-    <!-- Full XML View -->
-    <navigation-case>
-      <from-outcome>rolodex$test4</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>
-  </navigation-rule>
-
-  <navigation-rule>
-
-    <!-- JSP View -->
-    <from-view-id>/rolodex/rolodex.jsp</from-view-id>
-    <navigation-case>
-      <from-action>#{rolodex.selectContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex.saveContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex.deleteContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex.newContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex.changeTab}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>
-
-  </navigation-rule>
-
-  <navigation-rule>
-    <!-- HTML View -->    
-    <from-view-id>/rolodex/hrolodex.html</from-view-id>
-    
-    <navigation-case>
-      <from-action>#{rolodex$hrolodex.selectContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex$hrolodex.saveContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$hrolodex.deleteContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$hrolodex.newContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$hrolodex.changeTab}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-
-  </navigation-rule>
-
-  <navigation-rule>
-    <!-- Extreme HTML View -->
-    <from-view-id>/rolodex/xhrolodex.html</from-view-id>
-   
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.selectContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.saveContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.deleteContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.newContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.changeTab}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-
-  </navigation-rule>
-
-
-  <navigation-rule>
-    <!-- Full XML View -->
-    <from-view-id>/rolodex/rolodex.xml</from-view-id>
-   
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.selectContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>  
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.saveContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.deleteContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.newContact}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>
-    <navigation-case>
-      <from-action>#{rolodex$xhrolodex.changeTab}</from-action>
-      <from-outcome>rolodex$test</from-outcome>
-      <to-view-id>/rolodex/rolodex.xml</to-view-id>
-    </navigation-case>
-
-  </navigation-rule>
-
+
+  <navigation-rule>
+    <!-- JSP View -->
+    <from-view-id>/usecases*</from-view-id>
+    <navigation-case>
+      <from-outcome>rolodex$test1</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>  
+
+    <!-- HTML View -->
+    <navigation-case>
+      <from-outcome>rolodex$test2</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>
+
+    <!-- Extreme HTML View -->
+    <navigation-case>
+      <from-outcome>rolodex$test3</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>
+
+    <!-- Full XML View -->
+    <navigation-case>
+      <from-outcome>rolodex$test4</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>
+    
+    <!-- Full HTML View -->
+    <navigation-case>
+      <from-outcome>rolodex$viewsource</from-outcome>
+      <to-view-id>/rolodex/viewsource.html</to-view-id>
+    </navigation-case>
+    
+  </navigation-rule>
+
+  <navigation-rule>
+
+    <!-- JSP View -->
+    <from-view-id>/rolodex/rolodex.jsp</from-view-id>
+    <navigation-case>
+      <from-action>#{rolodex.selectContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex.saveContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex.deleteContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex.newContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex.changeTab}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
+    </navigation-case>
+
+  </navigation-rule>
+
+  <navigation-rule>
+    <!-- HTML View -->    
+    <from-view-id>/rolodex/hrolodex.html</from-view-id>
+    
+    <navigation-case>
+      <from-action>#{rolodex$hrolodex.selectContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex$hrolodex.saveContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$hrolodex.deleteContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$hrolodex.newContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$hrolodex.changeTab}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/hrolodex.html</to-view-id>
+    </navigation-case>
+
+  </navigation-rule>
+
+  <navigation-rule>
+    <!-- Extreme HTML View -->
+    <from-view-id>/rolodex/xhrolodex.html</from-view-id>
+   
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.selectContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.saveContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.deleteContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.newContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.changeTab}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
+    </navigation-case>
+
+  </navigation-rule>
+
+
+  <navigation-rule>
+    <!-- Full XML View -->
+    <from-view-id>/rolodex/rolodex.xml</from-view-id>
+   
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.selectContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>  
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.saveContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.deleteContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.newContact}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>
+    <navigation-case>
+      <from-action>#{rolodex$xhrolodex.changeTab}</from-action>
+      <from-outcome>rolodex$test</from-outcome>
+      <to-view-id>/rolodex/rolodex.xml</to-view-id>
+    </navigation-case>
+
+  </navigation-rule>
+
 
   <navigation-rule>
     <navigation-case>

Added: struts/shale/trunk/use-cases/src/web/rolodex/viewsource.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/viewsource.html?rev=291820&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/viewsource.html (added)
+++ struts/shale/trunk/use-cases/src/web/rolodex/viewsource.html Mon Sep 26 21:33:57 2005
@@ -0,0 +1,10 @@
+<html>
+<head><title>View Rolodex Example Source ("#{param['url']})</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+</head>
+<body>
+<h1>#{param['url']}</h1><a value="usecases.faces">Back</a>
+<hr><br>
+<pre><span jsfid="clayImport" url="#{param['url']}" escapeXml="true"/></pre>
+</body>
+</html>  

Modified: struts/shale/trunk/use-cases/src/web/usecases.jsp
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/usecases.jsp?rev=291820&r1=291819&r2=291820&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/usecases.jsp (original)
+++ struts/shale/trunk/use-cases/src/web/usecases.jsp Mon Sep 26 21:33:57 2005
@@ -156,34 +156,51 @@
   </h:panelGrid>
 
   <h1><h:outputText     value="#{messages['usecases.clay']}"/></h1>
-  <h:panelGrid        columns="1">
-
-    <h:commandLink         id="rolodex1"
-                       action="rolodex$test1">
-      <h:outputText     value="#{messages['usecases.rolodex1']}"/>
-    
-    </h:commandLink>
-
-    <h:commandLink         id="rolodex2"
-                       action="rolodex$test2">
-      <h:outputText     value="#{messages['usecases.rolodex2']}"/>
-    
-    </h:commandLink>
-
-    <h:commandLink         id="rolodex3"
-                       action="rolodex$test3">
-      <h:outputText     value="#{messages['usecases.rolodex3']}"/>
-    
+  <h:panelGrid        columns="2">
+
+    <h:commandLink         id="rolodex1"
+                       action="rolodex$test1">
+      <h:outputText     value="#{messages['usecases.rolodex1']}"/>
+    
+    </h:commandLink>
+    <h:commandLink action="rolodex$viewsource">
+       <f:param name="url" value="/rolodex/rolodex.jsp"/>
+       <h:outputText     value="#{messages['usecases.rolodex.viewsource']}"/>
+    </h:commandLink>
+
+
+    <h:commandLink         id="rolodex2"
+                       action="rolodex$test2">
+      <h:outputText     value="#{messages['usecases.rolodex2']}"/>
+    
     </h:commandLink>
+    <h:commandLink action="rolodex$viewsource">
+       <f:param name="url" value="/rolodex/hrolodex.html"/>
+       <h:outputText     value="#{messages['usecases.rolodex.viewsource']}"/>
+    </h:commandLink>
+
+    <h:commandLink         id="rolodex3"
+                       action="rolodex$test3">
+      <h:outputText     value="#{messages['usecases.rolodex3']}"/>
     
+    </h:commandLink>
+    <h:commandLink action="rolodex$viewsource">
+       <f:param name="url" value="/rolodex/xhrolodex.html"/>
+       <h:outputText     value="#{messages['usecases.rolodex.viewsource']}"/>
+    </h:commandLink>
+
     <h:commandLink         id="rolodex4"
                        action="rolodex$test4">
       <h:outputText     value="#{messages['usecases.rolodex4']}"/>
     
     </h:commandLink>
-    
-
-  </h:panelGrid>
+    <h:commandLink action="rolodex$viewsource">
+       <f:param name="url" value="/rolodex/rolodex.xml"/>
+       <h:outputText     value="#{messages['usecases.rolodex.viewsource']}"/>
+    </h:commandLink>
+
+
+  </h:panelGrid>
 
 
  </h:form>



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