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/26 05:05:44 UTC

svn commit: r291520 - 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/ clay-plugin/src/java/org/apache/sha...

Author: gvanmatre
Date: Sun Sep 25 20:05:26 2005
New Revision: 291520

URL: http://svn.apache.org/viewcvs?rev=291520&view=rev
Log:
Introduced support for Clay full XML views.  Added the forth option to the rolodex use case.

Added:
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateComponentConfigBean.java
    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/address.xml
    struts/shale/trunk/use-cases/src/web/rolodex/rolodex.xml
Modified:
    struts/shale/trunk/clay-plugin/src/conf/faces-config.xml
    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/Clay.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayConfigureListener.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/Globals.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/TemplateConfigBean.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java
    struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandlerCommand.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/chain-config.xml
    struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
    struts/shale/trunk/use-cases/src/web/WEB-INF/web.xml
    struts/shale/trunk/use-cases/src/web/usecases.jsp

Modified: struts/shale/trunk/clay-plugin/src/conf/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/conf/faces-config.xml?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/faces-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/conf/faces-config.xml Sun Sep 25 20:05:26 2005
@@ -59,5 +59,14 @@
     <component-class>org.apache.shale.clay.component.LoadBundle</component-class>
   </component>
 
+  <managed-bean>
+    <description>
+       The utility class used by the "Clay" component for extending runtime
+       capabilities.
+    </description>
+    <managed-bean-name>ClayAmalgam</managed-bean-name>
+    <managed-bean-class>org.apache.shale.clay.utils.ClayAmalgam</managed-bean-class>
+    <managed-bean-scope>application</managed-bean-scope>
+  </managed-bean>
 
 </faces-config>

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=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/view-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/conf/view-config.xml Sun Sep 25 20:05:26 2005
@@ -1159,4 +1159,14 @@
     </attributes>
   </component>	
 
+  <!-- Inline HTML Tag -->    
+  <component jsfid="clayTag" extends="clay">
+    <attributes>
+      <set name="shapeValidator" useMethodLateBinding="true" value="#{ClayAmalgam.createHTMLTag}"/> 
+      <set name="tag" useMethodLateBinding="true"/>
+    </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=291520&r1=291519&r2=291520&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 Sun Sep 25 20:05:26 2005
@@ -101,7 +101,7 @@
 #org.apache.shale.clay.config.beans (ALL)
 missing.jsfid.error=Missing {0}, cannot add child element to parent {1}
 
-#org.apache.shale.clay.config.beans.ComponentConfigBean
+#org.apache.shale.clay.config.beans.ConfigBean (ALL)
 resolve.inheritance.begin=Begin resolving inheritance @:-<
 finding.parents=Finding parents ?:-[
 finding.parents.exception=Runtime exception caught assigning parents
@@ -115,6 +115,8 @@
 circular.composition.exception=Circular composition detected {0}
 circular.child.parent.same.exception=Circular association detected; an element ({0}) cannot be associated with ({1}).  A component cannot be an inherited and composition parent to the same child.
 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}.
 
 #org.apache.shale.clay.config.beans.TemplateConfigBean
 loading.template=Loading clay HTML template {0}

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/Clay.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/Clay.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/Clay.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/Clay.java Sun Sep 25 20:05:26 2005
@@ -250,8 +250,8 @@
         if (b == null)
             throw new NullPointerException(messages.getMessage(
                     "clay.jsfid.notfound", new Object[] { getJsfid() }));
-                    
-                    return b;
+        
+        return b;
     }
     
     /**

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayConfigureListener.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayConfigureListener.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayConfigureListener.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/ClayConfigureListener.java Sun Sep 25 20:05:26 2005
@@ -23,9 +23,10 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+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.ComponentConfigBean;
+import org.apache.shale.clay.config.beans.TemplateComponentConfigBean;
 import org.apache.shale.clay.config.beans.TemplateConfigBean;
 import org.apache.shale.util.Messages;
 
@@ -58,10 +59,14 @@
             ClayConfigureListener.class.getClassLoader());
     
     /**
-     * <p>Loads the configuration files on startup into an instance of {@link ComponentConfigBean}.
+     * <p>Loads the configuration files on startup into an instance of 
+     * {@link org.apache.shale.clay.config.beans.ComponentConfigBean}.
      * and registers it with the factory {@link ConfigBeanFactory}.  The HTML template style of
-     * clay configuration bean {@link TemplateConfigBean} is also registered with the factory
-     * {@link ConfigBeanFactory}.  Both configuration bean pools implement the {@link ConfigBean} interface
+     * {@link org.apache.shale.clay.component.Clay} configuration bean 
+     * {@link org.apache.shale.clay.config.beans.TemplateConfigBean} and the XML template style of configuration 
+     * bean is {@link org.apache.shale.clay.config.beans.TemplateComponentConfigBean}.  The are all registered
+     * with the factory {@link ConfigBeanFactory}.  All configuration bean pools implement the 
+     * {@link org.apache.shale.clay.config.beans.ConfigBean} interface.
      * </p>
      *
      * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
@@ -77,11 +82,18 @@
             config.init(event.getServletContext());      
             ConfigBeanFactory.register(config);
             
-            // load template config
+            // load HTML template config
             config = new TemplateConfigBean();            
             config.init(event.getServletContext());
             ConfigBeanFactory.register(config);
-             
+
+            // load XML template config
+            config = new TemplateComponentConfigBean();            
+            config.init(event.getServletContext());
+            ConfigBeanFactory.register(config);
+            
+            
+            
         } catch (RuntimeException e) {
             log.error(messages.getMessage("config.load.error"), e);
             throw e;

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/Globals.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/Globals.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/Globals.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/Globals.java Sun Sep 25 20:05:26 2005
@@ -45,12 +45,23 @@
     /**
      * <p>The name of the initialization parameter defined in the
      * web deployment descriptor that's value will define a suffix
-     * identifier used by the {@link org.apache.shale.clay.config.beans.ComponentConfigBean}.
-     * to identify a jsfid that uses HTML to define page composition.
+     * identifier used by the {@link org.apache.shale.clay.config.beans.TemplateConfigBean}.
+     * This suffix identifies a jsfid that uses HTML to define page composition.
      * </p>
      */
-    public static final String CLAY_TEMPLATE_SUFFIX = "clay-template-suffix";
+    public static final String CLAY_HTML_TEMPLATE_SUFFIX = "clay-html-template-suffix";
 
+    
+    /**
+     * <p>The name of the initialization parameter defined in the
+     * web deployment descriptor that's value will define a suffix
+     * identifier used by the {@link org.apache.shale.clay.config.beans.TemplateComponentConfigBean}.
+     * This suffix identifies a jsfid that uses full XML views to define page composition.
+     * </p>
+     */
+    public static final String CLAY_XML_TEMPLATE_SUFFIX = "clay-xml-template-suffix";
+    
+   
     /**
      * <p>The name of the initialization parameter defined in the
      * web deployment descriptor that's value will determine if the
@@ -64,10 +75,17 @@
     
     
     /**
-     * <p>The default template suffix identifier if one is not specified
-     * using the CLAY_TEMPLATE_SUFFIX parameter.</p>
+     * <p>The default full html view template suffix identifier if one is not specified.
+     * Override using the CLAY_HTML_TEMPLATE_SUFFIX web init param parameter.</p>
      */
-    public static final String CLAY_DEFAULT_TEMPLATE_SUFFIX = ".clay";
+    public static final String CLAY_DEFAULT_HTML_TEMPLATE_SUFFIX = ".html";
+
+    /**
+     * <p>The default full XML template view suffix identifier if one is not specified.
+     * Override using the CLAY_HTML_TEMPLATE_SUFFIX web init param parameter.</p>
+     */
+    public static final String CLAY_DEFAULT_XML_TEMPLATE_SUFFIX = ".xml";
+    
     
     /**
      * <p>The default subview configuration file containing the base supported

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=291520&r1=291519&r2=291520&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 Sep 25 20:05:26 2005
@@ -90,29 +90,42 @@
             .getClassLoader());
    
     /**
-     *  <p>The suffix used to identify that a jsfid is a template style of 
+     *  <p>The suffixes used to identify that a jsfid is a template style of 
      *  composition.  If it has a matching suffix, it will be handled
-     *  by the {@link TemplateConfigBean}.</p>
+     *  by the {@link TemplateConfigBean} or {@link TemplateComponentConfigBean};
+     *  Otherwise, it's handled by {@link ComponentConfigBean}.</p>
      */    
-    protected String suffix = null;
+    protected String[] suffixes = null;
     
     /**
      * <p>Reference to the <code>ServletContext</code>
      */
-    protected ServletContext context = null;
+    protected transient ServletContext context = null;
     
     /**
      * <p>Initialization method that is passed the <code>ServletContext</code>
-     * as a parameter.  Loads the <code>sufix</code> override for the ServletContext 
+     * as a parameter.  Loads the <code>sufixes</code> for the ServletContext 
      * initialization parameter.
      * </p>
      */
     public  void init(ServletContext context) {
         this.context = context;
         
-        suffix = (String) context.getInitParameter(Globals.CLAY_TEMPLATE_SUFFIX);
-        if (suffix == null) {
-            suffix = Globals.CLAY_DEFAULT_TEMPLATE_SUFFIX;
+        if (suffixes == null) {
+            suffixes = new String[2];
+            
+            suffixes[0] = (String) context.getInitParameter(
+                    Globals.CLAY_HTML_TEMPLATE_SUFFIX);
+            if (suffixes[0] == null) {
+                suffixes[0] = Globals.CLAY_DEFAULT_HTML_TEMPLATE_SUFFIX;
+            }
+            
+            suffixes[1] = (String) context.getInitParameter(
+                    Globals.CLAY_XML_TEMPLATE_SUFFIX);
+            if (suffixes[1] == null) {
+                suffixes[1] = Globals.CLAY_DEFAULT_XML_TEMPLATE_SUFFIX;
+            }
+            
         }
         
         String autoReloadClayFiles = (String) context.getInitParameter(Globals.AUTO_RELOAD_CLAY_FILES);
@@ -199,7 +212,11 @@
                 if (configFile.toString().startsWith("META-INF/")) {
                    for (Enumeration ui = classloader.getResources(configFile.toString()); ui.hasMoreElements(); urls.add(ui.nextElement()));
                 } else {
-                   urls.add(context.getResource(configFile.toString()));
+                   URL url = context.getResource(configFile.toString()); 
+                   if (url == null) {
+                      throw new RuntimeException("Unable to find file :" + configFile.toString());
+                   }
+                   urls.add(url);
                 }
             } catch (IOException e) {
                 log.error(e);
@@ -248,9 +265,9 @@
      */
     public ComponentBean getElement(String jsfid) {
         ComponentBean element = null;
-        synchronized (displayElements) {
+        //synchronized (displayElements) {
             element = (ComponentBean) displayElements.get(jsfid);            
-        }
+        //}
         return element;
     }
     
@@ -349,13 +366,31 @@
     }
     
     /**
+     * <p>Returns the root metadata component that is used to add to the component
+     * tree.  This method might be overridden to broaden the scope to search for
+     * components outside of the <code>displayElement</code> cache.</b>
+     */
+    protected ComponentBean getTopLevelElement(String jsfid) {
+                
+        // find the top-level display element associated with the subtree
+        ComponentBean b = (ComponentBean) displayElements.get(jsfid);
+        if (b == null)
+            throw new NullPointerException(messages.getMessage(
+                    "jsfid.notfound", new Object[] { jsfid }));
+        
+        return b;
+    }
+
+    
+    
+    /**
      * <p>Called to assign the IsA parent to the {@link ComponentBean} 
      * using the <code>extends</code> attribute.
      * </p>
      */
     public void assignParent(ComponentBean b) {
         
-        synchronized (displayElements) {
+       // synchronized (displayElements) {
             
             if (b instanceof InnerComponentBean) {
                 
@@ -371,8 +406,7 @@
             if (b.getExtends() != null) {
                 
                 // assign the parent to a top-level display element
-                b.setIsAParent(
-                        (ComponentBean) displayElements.get(b.getExtends()));
+                b.setIsAParent(getTopLevelElement(b.getExtends()));
             }
             
             // resolve inheritance of nested components
@@ -401,7 +435,7 @@
                 assignParent((ComponentBean) vi.next());
             vi = null;
             
-        }
+        //}
         
     }
     
@@ -859,7 +893,13 @@
      * from the <code>jsfid</code>.
      */
     public boolean validMoniker(String id) {
-        return !id.endsWith(suffix);
+        
+        for (int i = 0; i < suffixes.length; i++) {
+           if (id.endsWith(suffixes[i]))
+               return false;
+        }
+        
+        return true;
     }
     
     /**
@@ -1120,9 +1160,9 @@
         if (!ComponentConfigBean.this.isWatchDogOn || watchDog == null)
            return wasDirty;
         
-        synchronized (displayElements) {
+        //synchronized (displayElements) {
             wasDirty = watchDog.refresh(forceReload);
-        }
+        //}
         
         watchDog = null;
         

Added: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateComponentConfigBean.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateComponentConfigBean.java?rev=291520&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateComponentConfigBean.java (added)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateComponentConfigBean.java Sun Sep 25 20:05:26 2005
@@ -0,0 +1,69 @@
+/*
+ * 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.config.beans;
+
+import java.util.TreeMap;
+
+import org.apache.shale.clay.config.ClayXmlParser;
+
+/**
+ * <This ConfigBean is responsible for handling full XML views.  For full XML views, 
+ * the viewId will correspond to an XML file that defines meta-component declarations 
+ * specific for the page.  It's assumed that here will be a top-level component with a 
+ * jsfid matching the viewId.</p>
+ */
+public class TemplateComponentConfigBean extends TemplateConfigBean {
+    
+    /**
+     * <p>Returns an integer value use to order the registered {@link ConfigBean} instances 
+     * with the {@link ConfigBeanFactory}.
+     * </p>
+     */
+    public int getWeight() {
+        return 2;
+    }
+    
+    
+    /**
+     * <p>This is an overridden method called from the init method.
+     * It loads an instance of the {@link ClayXmlParser} and 
+     * establishes a Map collection to hold the resource 
+     * {@link org.apache.shale.clay.config.beans.ComponentConfigBean$WatchDog}'s.</p>
+     */
+    protected void loadConfigFiles() {
+        parser = new ClayXmlParser(); 
+        parser.setConfig(this);
+        
+        watchDogs = new TreeMap();
+    }
+    
+    
+    /**
+     * <p>Overrides the super call to change the condition of the filter.  This 
+     * {@link ConfigBean} can create components where the id end in the suffix
+     * defined in the web deployment descriptor as a initialization parameter with 
+     * the name defined by <code>Globals.CLAY_XML_TEMPLATE_SUFFIX</code>  Or, using 
+     * the default defined by <code>Globals.CLAY_DEFAULT_XML_TEMPLATE_SUFFIX</code>
+     */      
+    public boolean validMoniker(String id) {
+        return id.endsWith(suffixes[1]);
+    }
+    
+        
+}

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/config/beans/TemplateConfigBean.java Sun Sep 25 20:05:26 2005
@@ -28,7 +28,6 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.shale.clay.config.ClayTemplateParser;
 import org.apache.shale.clay.config.Globals;
-import org.apache.shale.clay.config.beans.ComponentConfigBean.WatchDog;
 
 /**
  * <p>The second type of top-level object pool.  This implementation
@@ -93,11 +92,11 @@
      * <p>Overrides the super call to change the condition of the filter.  This 
      * {@link ConfigBean} can create components where the id end in the suffix
      * defined in the web deployment descriptor as a initialization parameter with 
-     * the name defined by <code>Globals.CLAY_TEMPLATE_SUFFIX</code>  Or, using 
-     * the default defined by <code>Globals.CLAY_DEFAULT_TEMPLATE_SUFFIX</code>
+     * the name defined by <code>Globals.CLAY_HTML_TEMPLATE_SUFFIX</code>  Or, using 
+     * the default defined by <code>Globals.CLAY_DEFAULT_HTML_TEMPLATE_SUFFIX</code>
      */      
     public boolean validMoniker(String id) {
-        return id.endsWith(suffix);
+        return id.endsWith(suffixes[0]);
     }
 
     /**
@@ -158,7 +157,7 @@
      */
     public boolean refresh(boolean forceReload) {
         if (forceReload) {
-            synchronized (displayElements) {
+            //synchronized (displayElements) {
                 
                 //remove all old templates
                 Iterator wi = watchDogs.entrySet().iterator();
@@ -171,13 +170,44 @@
                     
                 }
                 watchDogs.clear();
-            } 
+            //} 
         }
         
         return forceReload;
     }
 
     
-    
+    /**
+     * <p>
+     * Returns the root metadata component that is used to add to the component
+     * tree. It locates the {@link ComponentBean} using the <code>jsfid</code>
+     * attribute as the key. A call to the {@link ConfigBeanFactory} locates the
+     * correct {@link ConfigBean} used to find the {@link ComponentBean}. </b>
+     */
+    protected ComponentBean getTopLevelElement(String jsfid) {
+        
+        if (validMoniker(jsfid))
+            return super.getTopLevelElement(jsfid);
+        
+        //broaden the search to the other ConfigBean's
+        ConfigBean config = ConfigBeanFactory.findConfig(jsfid);
+        
+        if (config == null)
+            throw new NullPointerException(messages
+                    .getMessage("config.notloaded", new Object[] { jsfid }));
+        
+        if (config == this)
+            throw new NullPointerException(messages.getMessage(
+                    "jsfid.notfound", new Object[] { jsfid }));   
+        
+        // find the top-level display element associated with the subtree
+        ComponentBean b = (ComponentBean) config.getElement(jsfid);
+        if (b == null)
+            throw new NullPointerException(messages.getMessage(
+                    "jsfid.notfound", new Object[] { jsfid }));
+        
+        return b;
+    }
+ 
     
 }

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java Sun Sep 25 20:05:26 2005
@@ -44,8 +44,8 @@
  * <p>This <code>ViewHandler</code> will handle full HTML template views using the 
  * {@link Clay} component as the single subtree under the view root.  Views will 
  * be intercepted having a suffix matching the registered clay template suffix 
- * in the web deployment descriptor.  The default suffix is ".clay".  All other 
- * view render requests that don't match the suffix will be delegated to the 
+ * in the web deployment descriptor.  The default suffixes are ".html" and "*.xml".  
+ * All other view render requests that don't match the suffixes will be delegated to the 
  * original decorated view handler.</p>
  */
 public class ClayViewHandler extends ViewHandler {
@@ -77,9 +77,9 @@
     private static final String CLAY_COMPONENT_TYPE = "org.apache.shale.clay.component.Clay";
 
     /**
-     * <p>Holds the suffix used to identify a Clay HTML full view template.</p>
+     * <p>Holds the suffixes used to identify a Clay HTML or XML full view template.</p>
      */
-    private String suffix = null;
+    private String[] suffixes = null;
 
     /**
      * <p>The cached {@link ViewControllerMapper} we will use to translate
@@ -107,26 +107,34 @@
         return original.calculateRenderKitId(context);
     }
 
-    // Specified by ViewHandler
+    /**
+     * <p>This method is overridden to check to see if the target view 
+     * is a clay html or xml template.  If it is, the view id is normalized 
+     * before the original implementation is invoked.
+     * </p>
+     */
     public UIViewRoot createView(FacesContext context, String viewId) {
         String id = viewId;
-        if (isClayTemplate(context, id))
-            id = this.normalizeViewId(id);
+        int index = -1;
+        
+        if ((index = indexOfClayTemplateSuffix(context, id)) != -1)
+            id = normalizeViewId(id, index);
             
         return original.createView(context, id);
     }
 
     /**
      * <p>Changes the suffix of the <code>viewId</code> to that of the 
-     * assumed suffix of a clay template. 
+     * suffix of a clay template defined by the <code>index</code> into
+     * the <code>suffixes</code> array. 
      */
-    private String normalizeViewId(String viewId) {
+    private String normalizeViewId(String viewId, int index) {
         
         StringBuffer buff = new StringBuffer(viewId);
         int i = buff.lastIndexOf(".");
         if (i > -1) {
             buff.setLength(i);
-            buff.append(suffix);
+            buff.append(suffixes[index]);
         }
                 
         return buff.toString();
@@ -145,9 +153,9 @@
      */
     public String getActionURL(FacesContext context, String viewId) {
         String actionURL = original.getActionURL(context, viewId);
-
-        if (isClayTemplate(context, viewId)) {
-           actionURL = normalizeViewId(actionURL);
+        int index = -1;
+        if ((index = indexOfClayTemplateSuffix(context, viewId)) != -1) {
+           actionURL = normalizeViewId(actionURL, index);
         }
         
         return actionURL;
@@ -159,28 +167,55 @@
     }
 
     /**
-     * <p>Returns <code>true</code> if the <code>viewId</code> has a
-     * matching <code>suffix</code> or a request parameter exists with
-     * the name of <code>Globals.CLAY_TEMPLATE_SUFFIX</code>.  This
-     * indicator will be cached in the request by the 
-     * {@link ClayViewHandlerCommand} preprocess shale chain (only with myfaces).  
-     * The <code>suffix</code> is determined by an initialization parameter 
-     * in the web deployment descriptor, <code>clay-template-suffix</code>.  
-     * The default suffix, if one is not specified, is ".clay".
-     * </p> 
-     */
-    protected boolean isClayTemplate(FacesContext context, String viewId) {
-        if (suffix == null) {
-            suffix = (String) context.getExternalContext().getInitParameter(
-                    Globals.CLAY_TEMPLATE_SUFFIX);
-            if (suffix == null) {
-                suffix = Globals.CLAY_DEFAULT_TEMPLATE_SUFFIX;
+     * This method looks to see if the target view identified by the viewId is a 
+     * {@link org.apache.shale.clay.component.Clay} HTML or XML full view.  
+     * This is determined by a value cached in request scope by the 
+     * {@link ClayViewHandlerCommand} or the suffix of the viewId.  If a match 
+     * is found, the index position into the suffixes array is returned; 
+     * Otherwise a -1 is returned.
+     */
+    protected int indexOfClayTemplateSuffix(FacesContext context, String viewId) {
+        
+        int index = -1;
+        
+        if (suffixes == null) {
+            suffixes = new String[2];
+            
+            suffixes[0] = (String) context.getExternalContext().getInitParameter(
+                    Globals.CLAY_HTML_TEMPLATE_SUFFIX);
+            if (suffixes[0] == null) {
+                suffixes[0] = Globals.CLAY_DEFAULT_HTML_TEMPLATE_SUFFIX;
+            }
+            
+            suffixes[1] = (String) context.getExternalContext().getInitParameter(
+                    Globals.CLAY_XML_TEMPLATE_SUFFIX);
+            if (suffixes[1] == null) {
+                suffixes[1] = Globals.CLAY_DEFAULT_XML_TEMPLATE_SUFFIX;
+            }
+            
+        }
+        
+        //looked for the original first set by the ClayViewHandlerCommand  
+        String originalSuffix = (String) context.getExternalContext().getRequestMap().get(Globals.CLAY_HTML_TEMPLATE_SUFFIX);
+        if (originalSuffix != null) {
+            for (int i =0; i < suffixes.length; i++) {
+                if (originalSuffix.equals(suffixes[i])) {
+                    return i;    
+                }
+            }
+        }
+        
+        //look at the path
+        for (int i =0; i < suffixes.length; i++) {
+            if (viewId.endsWith(suffixes[i])) {
+                return i;    
             }
         }
         
-        return (viewId.endsWith(suffix) 
-                || context.getExternalContext().getRequestMap().containsKey(Globals.CLAY_TEMPLATE_SUFFIX)) ;
+        return -1;
     }
+    
+    
 
     /**
      * <p>The default view handler implementation will try to
@@ -191,16 +226,18 @@
     public UIViewRoot restoreView(FacesContext context, String viewId) {
         UIViewRoot view = null;
         
-        if (isClayTemplate(context, viewId)) {
+        int index = -1;
+        if ((index = indexOfClayTemplateSuffix(context, viewId)) != -1) {
             
             if (log.isInfoEnabled())
                 log.info("Clay template restoreView for " + viewId);
-                        
+            
             StateManager stateManager = context.getApplication().getStateManager();
-            view = stateManager.restoreView(context, normalizeViewId(viewId), calculateRenderKitId(context));
+            view = stateManager.restoreView(context, normalizeViewId(viewId, index), calculateRenderKitId(context));
             
         } else
-           view = original.restoreView(context, viewId);
+            view = original.restoreView(context, viewId);
+        
         return view;
     }
 
@@ -219,7 +256,7 @@
      * <p>Returns an index into the <code>FORM_MAKKERS</code> array.  The index will be used to
      * get the form marker matching the JSF runtime. Only the myfaces and Sun RI are supported.
      * The form marker is determined by trying to load the myfaces view handler.  The default 
-     * is the marker for the Sun RI</p>
+     * is the marker for the Sun RI.</p>
      */
     protected int indexOfFormMarker() {
         int i = 0;
@@ -233,11 +270,12 @@
     }
     
     /**
-     * <p>The <code>viewId</code> of the view will be check to see if it ends with the 
-     * same suffix as the configured clay-template-suffix.  This match might be performed
+     * <p>The <code>viewId</code> is check to see if it ends with the 
+     * same suffix as the full HTML or XML views.  This match might be performed
      * by the {@link ClayViewHandlerCommand} when using the myfaces jsf implementation.  
      * If a match is not found, control is passed to the decorated view handler.  
-     * Otherwise, a {@link Clay} component is instantiated as a single subtree under the 
+     * Otherwise, a {@link org.apache.shale.clay.component.Clay} component is 
+     * instantiated as a single subtree under the 
      * view root. The component's <code>id</code> property is set with a constant, 
      * <code>CLAY_VIEW_ID</code>.  The <code>jsfid</code> 
      * property is set to the <code>viewId</code>.  The <code>managedBeanName</code> property 
@@ -249,8 +287,10 @@
     public void renderView(FacesContext context, UIViewRoot view)
             throws IOException, FacesException {
 
+        
+        int index = -1;
         //is this view a clay html template view
-        if (isClayTemplate(context, view.getViewId())) {
+        if ((index = indexOfClayTemplateSuffix(context, view.getViewId())) != -1) {
             
             if (log.isInfoEnabled())
                 log.info("Clay template renderView for " + view.getViewId());
@@ -259,7 +299,7 @@
             UIComponent component = view.findComponent(CLAY_VIEW_ID);
             if (component == null) {
                 
-              String viewId = normalizeViewId(view.getViewId()); 
+              String viewId = normalizeViewId(view.getViewId(), index); 
               component = context.getApplication().createComponent(CLAY_COMPONENT_TYPE);
               ((Clay) component).setId(CLAY_VIEW_ID);
               ((Clay) component).setJsfid(viewId);
@@ -359,7 +399,7 @@
     
     /**
      * <p>Returns the managed-bean-name the view controller is registered under.  The
-     * assumed mapping will be the same as in core Shale</p>
+     * assumed mapping will be the same as in core Shale.</p>
      */
     protected String getManagedBeanName(FacesContext context, String viewId) {
         if (mapper == null) {

Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandlerCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandlerCommand.java?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandlerCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandlerCommand.java Sun Sep 25 20:05:26 2005
@@ -24,34 +24,35 @@
 import org.apache.shale.faces.ShaleWebContext;
 
 /**
- * This is a Shale "preprocess" command that should be registered 
+ * <p>This is a Shale "preprocess" command that should be registered 
  * with the shale chains catalog.  It is only need for implementing 
- * full html Clay views with myfaces.  The myfaces implementation pays 
- * strict attention to the javax.faces.DEFAULT_SUFFIX, only allowing viewId's
- * with this suffix.  This command will place an indicator in request scope 
+ * full {@link org.apache.shale.clay.component.Clay} html or XML views with myfaces.  
+ * The myfaces implementation pays strict attention to the javax.faces.DEFAULT_SUFFIX setting, 
+ * only allowing viewId's with this suffix.  This command will place an indicator in request scope 
  * before the request is processed by the faces servlet.  The {@link ClayViewHandler} 
  * will use the indicator to determine that the view should be handled by the 
  * {@link ClayViewHandler}.
- *
+ * </p>
  */
 public class ClayViewHandlerCommand implements Command {
 
     /**
-     * <p>Holds the suffix used to identify a Clay HTML full view template.</p>
+     * <p>Holds the suffixes used to identify a Clay full HTML or XML view template.</p>
      */
-    private String suffix = null;
+    private String[] suffixes = null;
     
     /**
      * <p>Looks at the request uri to determine if the target page
      * is a clay template.  If the request's pathInfo matches the
-     * clay template suffix, a flag is added to the request attributes.
+     * clay template suffixes, a flag is added to the request attributes.
      * This is need for the MyFaces JSF implementation.
      */
     public boolean execute(Context context) throws Exception {
         
         ShaleWebContext webContext = (ShaleWebContext) context;
-        if (isClayTemplate(webContext)) {
-           webContext.getRequest().setAttribute(Globals.CLAY_TEMPLATE_SUFFIX, Boolean.TRUE);
+        int index = -1;
+        if ((index = indexOfClayTemplateSuffix(webContext)) !=-1) {
+           webContext.getRequest().setAttribute(Globals.CLAY_HTML_TEMPLATE_SUFFIX, suffixes[index]);
         }
 
         return false;
@@ -59,24 +60,42 @@
     
     
     /**
-     * <p>Returns <code>true</code> if the request's <code>uri</code> has a
-     * matching <code>suffix</code>.  The <code>suffix</code> is determined
-     * by an initialization parameter in the web deployment descriptor,
-     * <code>clay-template-suffix</code>.  The default suffix, if one
-     * is not specified, is ".clay".
-     * </p> 
+     * <p>Checks the <code>request.uri</code> to determine if it's suffix matches one of 
+     * the <code>suffixes</code>.  If a match is found, the index into the <code>suffixes</code>
+     * array is returned.  A value of -1 is returned if a match is not found.</p> 
      */
-    protected boolean isClayTemplate(ShaleWebContext context) {
-        if (suffix == null) {
-            suffix = (String) context.getContext().getInitParameter(
-                    Globals.CLAY_TEMPLATE_SUFFIX);
-            if (suffix == null) {
-                suffix = Globals.CLAY_DEFAULT_TEMPLATE_SUFFIX;
+    protected int indexOfClayTemplateSuffix(ShaleWebContext context) {
+        
+        int index = -1;
+        
+        if (suffixes == null) {
+            suffixes = new String[2];
+            
+            suffixes[0] = (String) context.getContext().getInitParameter(
+                    Globals.CLAY_HTML_TEMPLATE_SUFFIX);
+            if (suffixes[0] == null) {
+                suffixes[0] = Globals.CLAY_DEFAULT_HTML_TEMPLATE_SUFFIX;
             }
+            
+            suffixes[1] = (String) context.getContext().getInitParameter(
+                    Globals.CLAY_XML_TEMPLATE_SUFFIX);
+            if (suffixes[1] == null) {
+                suffixes[1] = Globals.CLAY_DEFAULT_XML_TEMPLATE_SUFFIX;
+            }
+            
         }
+        
         String uri = context.getRequest().getRequestURI();
-        return (uri != null) && (uri.endsWith(suffix));
+        if (uri != null) {
+            //look at the path
+            for (int i =0; i < suffixes.length; i++) {
+                if (uri.endsWith(suffixes[i])) {
+                    return i;    
+                }
+            }
+        }
+        
+        return -1;
     }
-
 
 }

Added: 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=291520&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java (added)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/ClayAmalgam.java Sun Sep 25 20:05:26 2005
@@ -0,0 +1,153 @@
+/*
+ * 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.utils;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.shale.clay.component.Clay;
+import org.apache.shale.clay.config.beans.AttributeBean;
+import org.apache.shale.clay.config.beans.ComponentBean;
+
+/**
+ * <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>  
+ */
+public class ClayAmalgam {
+
+    
+    /**
+     * <p>Replaces tokens in the <code>document</code> with 
+     * matching tokens in the <code>context</code>.</p>
+     */
+    protected void replace(StringBuffer document, Map context) {
+
+        Iterator di = context.entrySet().iterator();
+        while (di.hasNext()) {
+            Map.Entry e = (Map.Entry) di.next();
+
+            String name = (String) e.getKey();
+            String value = (String) e.getValue();
+
+            for (int i = 0; i <= (document.length() - name.length()); i++) {
+                String token = document.substring(i, i + name.length());
+                if (token.compareToIgnoreCase(name) == 0) {
+                    document.delete(i, i + name.length());
+                    document.insert(i, value);
+                }
+
+                token = null;
+            }
+
+            e = null;
+            name = null;
+            value = null;
+        }
+        di = null;
+
+    }
+
+    /**
+     * <p>Mapping used to encode special characters.</p>
+     */
+    private static TreeMap encodeMap = null;
+    static {
+        encodeMap = new TreeMap();
+        encodeMap.put("\"", "&quote;");
+        encodeMap.put("'", "&apos;");
+        encodeMap.put("&", "&amp;");
+        encodeMap.put("<", "&lt;");
+        encodeMap.put(">", "&gt;");
+    }
+
+    /**
+     * <p>Encodes a string value using the <code>encodeMap</code>.</p>
+     */
+    public String encode(String value) {
+        StringBuffer buff = new StringBuffer(value);
+        replace(buff, encodeMap);
+        return buff.toString();
+    }
+
+    /**
+     * <p>Mapping used to decode special characters.</p>
+     */
+    private static TreeMap decodeMap = null;
+    static {
+        decodeMap = new TreeMap();
+        decodeMap.put("&quote;", "\"");
+        decodeMap.put("&apos;", "'");
+        decodeMap.put("&amp;", "&");
+        decodeMap.put("&lt;", "<");
+        decodeMap.put("&gt;", ">");
+    }
+
+    /**
+     * <p>Decodes a string value using the <code>decodeMap</code>.</p>
+     */
+    public String decode(String value) {
+        StringBuffer buff = new StringBuffer(value);
+        replace(buff, decodeMap);
+        return buff.toString();
+    }
+    
+  
+    /**
+     * <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>   
+     */
+    public void createHTMLTag(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);
+               
+    }
+
+    
+}

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=291520&r1=291519&r2=291520&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 Sun Sep 25 20:05:26 2005
@@ -26,6 +26,7 @@
 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.TemplateComponentConfigBean;
 import org.apache.shale.clay.config.beans.TemplateConfigBean;
 import org.apache.shale.test.base.AbstractViewControllerTestCase;
 
@@ -45,7 +46,8 @@
     }
 
     protected ConfigBean standardConfigBean = null;
-    protected ConfigBean templateConfigBean = null;
+    protected ConfigBean htmlTemplateConfigBean = null;
+    protected ConfigBean xmlTemplateConfigBean = 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"},
@@ -119,20 +121,27 @@
         loadValidators();
         
         // sets the default html template suffix ".html"
-        servletContext.addInitParameter(Globals.CLAY_TEMPLATE_SUFFIX, ".html");
-        
+        servletContext.addInitParameter(Globals.CLAY_HTML_TEMPLATE_SUFFIX, ".html");
+
+        // sets the default html template suffix ".xml"
+        servletContext.addInitParameter(Globals.CLAY_XML_TEMPLATE_SUFFIX, ".xml");
+       
         // 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);
-                
+        htmlTemplateConfigBean = new TemplateConfigBean();
+        htmlTemplateConfigBean.init(servletContext);
+
+        xmlTemplateConfigBean = new TemplateComponentConfigBean();
+        xmlTemplateConfigBean.init(servletContext);
+
         // register with the factory
         ConfigBeanFactory.register(standardConfigBean);
-        ConfigBeanFactory.register(templateConfigBean);
+        ConfigBeanFactory.register(htmlTemplateConfigBean);
+        ConfigBeanFactory.register(xmlTemplateConfigBean);
 
     }
 
@@ -142,7 +151,8 @@
         // deregister
         ConfigBeanFactory.destroy();
         standardConfigBean = null;
-        templateConfigBean = null;
+        htmlTemplateConfigBean = null;
+        xmlTemplateConfigBean = null;
     }
 
     // loads the config files
@@ -151,7 +161,8 @@
         
         servletContext.addInitParameter(Globals.CLAY_CONFIG_FILES, configFiles);        
         standardConfigBean.init(servletContext);
-        templateConfigBean.init(servletContext);
+        htmlTemplateConfigBean.init(servletContext);
+        xmlTemplateConfigBean.init(servletContext);
 
     }
     public void testLoadConfigFile() {
@@ -359,7 +370,7 @@
         //loads the default and the custom address config file
         loadConfigFile("org/apache/shale/clay/config/address-config.xml");
 
-        ComponentBean bean = templateConfigBean.getElement("org/apache/shale/clay/config/address.html"); 
+        ComponentBean bean = htmlTemplateConfigBean.getElement("org/apache/shale/clay/config/address.html"); 
         assertNotNull(bean);
 
         Iterator ci = bean.getChildrenIterator();
@@ -371,6 +382,44 @@
         
     }
 
+    //test a full xml view including a html template
+    public void testLoadXMLFile() {
+        
+        //loads the default and the custom address config file
+        loadConfigFile("org/apache/shale/clay/config/address-config.xml");
+        
+        ComponentBean bean = xmlTemplateConfigBean.getElement("org/apache/shale/clay/config/address.xml"); 
+        assertNotNull(bean);
+        
+        Iterator ci = bean.getChildrenIterator();
+        while (ci.hasNext()) {
+            ElementBean child = (ElementBean) ci.next();
+            
+            AttributeBean attr = null;
+            if (child.getId().equals("htmlBegin")) {
+                attr = child.getAttribute("tag");
+                assertEquals(attr.getValue(), "<html>");
+            } else if (child.getId().equals("htmlEnd")) {
+                attr = child.getAttribute("tag");
+                assertEquals(attr.getValue(), "</html>");
+            } else if (child.getId().equals("header")) {
+                attr = child.getAttribute("tag");
+                assertEquals(attr.getValue(), "<head><title>Testing</title></head>");
+            } else if (child.getId().equals("bodyBegin")) {
+                attr = child.getAttribute("tag");
+                assertEquals(attr.getValue(), "<body>");
+            } else if (child.getId().equals("bodyEnd")) {
+                attr = child.getAttribute("tag");
+                assertEquals(attr.getValue(), "</body>");
+            } else if (child.getId().equals("content")) {
+                //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);

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=291520&r1=291519&r2=291520&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 Sun Sep 25 20:05:26 2005
@@ -197,5 +197,43 @@
         <element renderId="10" jsfid="saveCommand"/>  
 
 	</component>
-						
+	
+    <component jsfid="layout" extends="outputText">
+        <element id="htmlBegin" renderId="0" jsfid="clayTag"> 
+            <attributes>
+               <set name="tag" value="&lt;html&gt;"/>
+            </attributes>
+        </element>
+        <element id="header" renderId="2" jsfid="clayTag"> 
+            <attributes>
+               <set name="tag" value="&lt;head&gt;&lt;title&gt;Testing&lt;/title&gt;&lt;/head&gt;"/>
+            </attributes>
+        </element>
+        <element id="bodyBegin" renderId="4" jsfid="clayTag"> 
+            <attributes>
+               <set name="tag" value="&lt;body&gt;"/>
+            </attributes>
+        </element>
+     
+        <!--  override body content -->   
+        <element id="content" renderId="10" jsfid="outputText"> 
+            <attributes>
+               <set name="value" value="Hello World"/>
+            </attributes>
+        </element>
+        
+        <element id="bodyEnd" renderId="40" jsfid="clayTag"> 
+            <attributes>
+               <set name="tag" value="&lt;/body&gt;"/>
+            </attributes>
+        </element>
+        
+        
+         <element id="htmlEnd" renderId="100" jsfid="clayTag"> 
+            <attributes>
+               <set name="tag" value="&lt;/html&gt;"/>
+            </attributes>
+         </element>
+        
+    </component>						
 </view>

Added: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.xml?rev=291520&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.xml (added)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/config/address.xml Sun Sep 25 20:05:26 2005
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding="UTF-8"?>
+
+  <!DOCTYPE view PUBLIC
+      "-//Apache Software Foundation//DTD Shale Clay View Configuration 1.0//EN"
+      "http://struts.apache.org/dtds/shale-clay-config_1_0.dtd">
+
+<view>
+
+  <component jsfid="/org/apache/shale/clay/config/address.xml" extends="layout" >
+        <!--  override body content -->   
+        <element id="content" renderId="10" jsfid="clay"> 
+            <attributes>
+               <set name="clayJsfid" value="/org/apache/shale/clay/config/address.xml"/>
+            </attributes>
+        </element>     
+  </component> 
+
+</view>
\ No newline at end of file

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=291520&r1=291519&r2=291520&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 Sun Sep 25 20:05:26 2005
@@ -129,8 +129,10 @@
 usecases.tiles.simple=A Simple Tiles Example
 usecases.clay=Clay View Use Cases
 usecases.rolodex1=Rolodex Example (JSP View)
-usecases.rolodex2=Rolodex Example (HTML View)
-usecases.rolodex3=Rolodex Example (Extreme HTML View)
+usecases.rolodex2=Rolodex Example (Full HTML View)
+usecases.rolodex3=Rolodex Example (Full Extreme HTML View)
+usecases.rolodex4=Rolodex Example (Full XML View)
+
 
 # Validation
 validate.test.title=Shale Validation using Commons Validator

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/chain-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/chain-config.xml?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/chain-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/chain-config.xml Sun Sep 25 20:05:26 2005
@@ -36,14 +36,14 @@
 
 
       <!-- This filter command wakes up the watchdog monitoring the Clay configuration files for change. -->
-      <command      className="org.apache.shale.clay.config.beans.ConfigDefinitionsWatchdogFilter"
-                     includes="\S*\.faces,\S*\.html,/index\.jsp"/>
+      <command      className="org.apache.shale.clay.config.beans.ConfigDefinitionsWatchdogFilter"
+                     includes="\S*\.faces,\S*\.html,/index\.jsp,\S*\.xml"/>
  
 
       <!-- Disallow direct access to JSP and JSFP resources -->
-      <command      className="org.apache.shale.application.ContextRelativePathFilter"
-                     includes="\S*\.faces,\S*\.html,\S*\.gif,\S*\.jpg,/index\.jsp"
-                     excludes="\S*\.jsp,\S*\.jspf"/>
+      <command      className="org.apache.shale.application.ContextRelativePathFilter"
+                     includes="\S*\.xml,\S*\.faces,\S*\.html,\S*\.gif,\S*\.jpg,/index\.jsp"
+                     excludes="\S*\.jsp,\S*\.jspf"/>
     </chain>
   </catalog>
 

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=291520&r1=291519&r2=291520&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 Sun Sep 25 20:05:26 2005
@@ -169,104 +169,163 @@
   <!-- ============================ Rolodex Test =========================== -->
 
 
-  <navigation-rule>
-
-    <!-- JSP View -->
-    <navigation-case>
-      <from-outcome>rolodex$test1</from-outcome>
-      <to-view-id>/rolodex/rolodex.jsp</to-view-id>
-    </navigation-case>  
-    <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>
-
-    <!-- HTML View -->
-    <navigation-case>
-      <from-outcome>rolodex$test2</from-outcome>
-      <to-view-id>/rolodex/hrolodex.html</to-view-id>
-    </navigation-case>
-    <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>
-
-
-    <!-- Extreme HTML View -->
-    <navigation-case>
-      <from-outcome>rolodex$test3</from-outcome>
-      <to-view-id>/rolodex/xhrolodex.html</to-view-id>
-    </navigation-case>
-    <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>
+    <!-- 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>
     <navigation-case>

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/web.xml?rev=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/web.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/web.xml Sun Sep 25 20:05:26 2005
@@ -50,12 +50,6 @@
       <param-value>/WEB-INF/clay-config.xml</param-value>
    </context-param>
   
-   <!-- Clay template suffix override, default is .clay -->
-   <context-param>
-      <param-name>clay-template-suffix</param-name>
-      <param-value>.html</param-value>
-   </context-param>
-
   <!-- Shale Application Controller Filter -->
   <filter>
     <filter-name>shale</filter-name>
@@ -119,6 +113,12 @@
   <servlet-mapping>
     <servlet-name>faces</servlet-name>
     <url-pattern>*.html</url-pattern>
+  </servlet-mapping>
+
+  <!-- JavaServer Faces Servlet Mapping for Clay XML Full View --> 
+  <servlet-mapping>
+    <servlet-name>faces</servlet-name>
+    <url-pattern>*.xml</url-pattern>
   </servlet-mapping>
 
   <!-- Welcome File List -->

Added: struts/shale/trunk/use-cases/src/web/rolodex/rolodex.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/rolodex.xml?rev=291520&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/rolodex.xml (added)
+++ struts/shale/trunk/use-cases/src/web/rolodex/rolodex.xml Sun Sep 25 20:05:26 2005
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+ Copyright 2004-2005 The Apache Software Foundation.
+ 
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ 
+      http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+
+  <!DOCTYPE view PUBLIC
+      "-//Apache Software Foundation//DTD Shale Clay View Configuration 1.0//EN"
+      "http://struts.apache.org/dtds/shale-clay-config-1_0.dtd">
+
+<view>
+    <component jsfid="/rolodex/rolodex.xml" extends="clay">
+       <attributes>
+           <set name="clayJsfid" value="/rolodex/xhrolodex.html" />
+           <set name="managedBeanName" value="rolodex$xhrolodex" />
+       </attributes>
+    </component>
+</view>
\ No newline at end of file

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=291520&r1=291519&r2=291520&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/usecases.jsp (original)
+++ struts/shale/trunk/use-cases/src/web/usecases.jsp Sun Sep 25 20:05:26 2005
@@ -174,7 +174,14 @@
                        action="rolodex$test3">
       <h:outputText     value="#{messages['usecases.rolodex3']}"/>
     
-    </h:commandLink>
+    </h:commandLink>
+    
+    <h:commandLink         id="rolodex4"
+                       action="rolodex$test4">
+      <h:outputText     value="#{messages['usecases.rolodex4']}"/>
+    
+    </h:commandLink>
+    
 
   </h:panelGrid>
 



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