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

svn commit: r209369 - in /struts/shale/trunk/core-library: ./ src/java/org/apache/shale/ src/java/org/apache/shale/dialog/ src/java/org/apache/shale/tiles/

Author: dgeary
Date: Tue Jul  5 17:58:35 2005
New Revision: 209369

URL: http://svn.apache.org/viewcvs?rev=209369&view=rev
Log:
This commit contains an optional integration layer for working with standalone 
Tiles. That integration, like Shale's Spring integration, is optional. If you 
specify a property named tiles.home in build.properties, and build Shale's 
core library, Shale will create a shale-tiles.jar file in 
core-library/dist/lib. To use the Tiles integration, you include that JAR file 
in your WEB-INF/lib directory.

Shale's Tiles integration is pretty simple. There's a JSF view handler 
(org.apache.shale.tiles.TilesViewHandler) that preprocesses navigation view 
IDs and looks for a matching tile. See the package description for 
org.apache.shale.tiles for more information.

Added:
    struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/
    struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/TilesViewHandler.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/faces-config.xml
    struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/package.html
Modified:
    struts/shale/trunk/core-library/build.xml
    struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
    struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Dialog.java
    struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Globals.java

Modified: struts/shale/trunk/core-library/build.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/build.xml?rev=209369&r1=209368&r2=209369&view=diff
==============================================================================
--- struts/shale/trunk/core-library/build.xml (original)
+++ struts/shale/trunk/core-library/build.xml Tue Jul  5 17:58:35 2005
@@ -65,6 +65,7 @@
                                     value="${spring.home}/dist/spring-context.jar"/>
   <property name="spring-core.jar"  value="${spring.home}/dist/spring-core.jar"/>
   <property name="spring-web.jar"   value="${spring.home}/dist/spring-web.jar"/>
+  <property name="tiles.jar"        value="${tiles.home}/core-library/dist/lib/tiles-core.jar"/>
 
 
   <!-- Build Defaults -->
@@ -111,6 +112,7 @@
     <pathelement location="${spring-core.jar}"/>
     <pathelement location="${spring-web.jar}"/>
     <pathelement location="${build.home}/classes"/>
+    <pathelement location="${tiles.jar}"/>
   </path>
 
 
@@ -156,6 +158,7 @@
     <pathelement location="${spring-web.jar}"/>
     <pathelement location="${build.home}/classes"/>
     <pathelement location="${build.home}/test-classes"/>
+    <pathelement location="${tiles.jar}"/>
   </path>
 
   <!-- Conditional Processing Flags -->
@@ -165,6 +168,9 @@
   <available                     property="myfaces.present"
                                 classname="org.apache.myfaces.config.MyfacesConfig"
                                 classpath="${jsf-impl.jar}"/>
+  <available                     property="tiles.present"
+                                classname="org.apache.tiles.servlets.TilesServlet"
+                             classpathref="compile.classpath"/>
   <condition                     property="spring.present">
     <and>
       <available                classname="org.springframework.core.Constants"
@@ -250,6 +256,8 @@
       <classpath refid="compile.classpath" />
       <exclude    name="org/apache/shale/spring/**"
                 unless="spring.present"/>
+      <exclude    name="org/apache/shale/tiles/**"
+                unless="tiles.present"/>
     </javac>
 
     <!-- Copy non-Java Sources -->
@@ -285,7 +293,7 @@
     <jar       jarfile="${build.home}/lib/shale-core.jar"
                basedir="${build.home}/classes"
               manifest="${build.home}/conf/MANIFEST.MF"
-              excludes="org/apache/shale/spring/** **/package.html"/>
+              excludes="org/apache/shale/spring/** org/apache/shale/tiles/** **/package.html"/>
 
   </target>
 
@@ -305,8 +313,23 @@
     </jar>
   </target>
 
+  <target        name="library-tiles" depends="compile" if="tiles.present"
+          description="Package Tiles integration library">
+    <mkdir        dir="${build.home}/shale-tiles"/>
+    <mkdir        dir="${build.home}/shale-tiles/META-INF"/>
+    <copy       todir="${build.home}/shale-tiles/META-INF"
+                 file="src/java/org/apache/shale/tiles/faces-config.xml"/>
+    <jar      jarfile="${build.home}/lib/shale-tiles.jar"
+             manifest="${build.home}/conf/MANIFEST.MF">
+      <fileset    dir="${build.home}/shale-tiles"/>
+      <fileset    dir="${build.home}/classes"
+             includes="org/apache/shale/tiles/**"
+             excludes="**/faces-config.xml **/package.html"/>
+    </jar>
+  </target>
+
 
-  <target        name="library" depends="library-core,library-spring"
+  <target        name="library" depends="library-core, library-spring, library-tiles"
           description="Package all libraries"/>
 
 

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties?rev=209369&r1=209368&r2=209369&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties Tue Jul  5 17:58:35 2005
@@ -44,3 +44,9 @@
 
 # org.apache.shale.component.Token
 token.invalid=Invalid resubmit of the same form
+
+# org.apache.shale.tiles.TilesViewHandler
+tiles.renderingView=Rendering view {0}, looking for tile {1}
+tiles.dispatchingToTile=Dispatching to tile {0}
+tiles.dispatchingToViewHandler=Dispatching {0} to the default view handler
+

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Dialog.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Dialog.java?rev=209369&r1=209368&r2=209369&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Dialog.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Dialog.java Tue Jul  5 17:58:35 2005
@@ -18,7 +18,7 @@
 
 /**
  * <p>Overall configuration of an individual dialog.  During application
- * execution, this information is immutabe (so that simultaneous execution
+ * execution, this information is immutable (so that simultaneous execution
  * threads may be processing states or transitions through this dialog).
  * Therefore, access to configuration information is not synchronized.</p>
  *

Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Globals.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Globals.java?rev=209369&r1=209368&r2=209369&view=diff
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Globals.java (original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/dialog/Globals.java Tue Jul  5 17:58:35 2005
@@ -27,7 +27,7 @@
 
     /**
      * <p>Context initialization parameter used to specify a comma delimited
-     * list of context relative resource paths to resources continaing our
+     * list of context relative resource paths to resources containing our
      * dialog configuration information.</p>
      */
     public static final String CONFIGURATION_PARAM =

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/TilesViewHandler.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/TilesViewHandler.java?rev=209369&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/TilesViewHandler.java (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/TilesViewHandler.java Tue Jul  5 17:58:35 2005
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.tiles;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+import javax.faces.application.ViewHandler;
+
+import javax.faces.FacesException;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIOutput;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+
+import org.apache.tiles.*;
+
+import org.apache.shale.util.Messages;
+
+/**
+ * This view handler strips the suffix off of the view ID and looks
+ * for a tile whose name matches the resulting string. For example, if the
+ * view ID is /tiles/test.jsp, this view handler will look for a tile named
+ * /tiles/test. If the tile is found, it is rendered; otherwise, this view handler 
+ * delegates to the default JSF view handler.
+ * <p/>
+ * To render a tile, this view handler first locates the tile by name. Then it
+ * creates or accesses the Tile Context, and stores the tile's attributes
+ * in the context. Finally, it dispatches the request to the tile's layout
+ * by calling JSF's <code>ExternalContext.dispatch()</code>. Layouts typically
+ * contain &lt;tiles:insert&gt; tags that include dynamic content.
+ * <p/>
+ * If the request does not reference a tile, this view handler delegates
+ * view rendering to the default view handler. That means that URLs like this:
+ * <code>http://localhost:8080/example/index.faces</code> will work as 
+ * expected.
+ *<p/>
+ * Most of the methods in this class simply delegate to the default view
+ * handler, which JSF passes to this view handler's constructor. The only
+ * method that has a meaningful implementation is <code>void 
+ * renderView(FacesContext, UIViewRoot)</code>, which renders the current
+ * view in accordance with the algorithm discussed above.
+ *
+ * <strong>Note:</strong> This Tiles view handler is tied to the standalone 
+ * version of Tiles, which resides in the Struts sandbox. This view handler
+ * will not work with Struts Tiles.
+ */
+public class TilesViewHandler extends ViewHandler {
+
+
+   // ------------------------------------------------------------- Constructor
+
+
+   /**
+    * <p>Stores the reference to the default view handler for later use.</p>
+    * 
+    * @param defaultViewHandler The default view handler
+    */
+   public TilesViewHandler(ViewHandler defaultViewHandler) {
+      this.defaultViewHandler = defaultViewHandler;
+   }
+
+
+   // -------------------------------------------------------- Static Variables
+
+    
+   /**
+    * <p>Log instance for this class.</p>
+    */
+   private static final Log log = LogFactory.getLog(
+                                            TilesViewHandler.class.getName());
+   /**
+    * <p>Message resources for this class.</p>
+    */
+   private static Messages messages = 
+      new Messages("org.apache.shale.Bundle",
+                   TilesViewHandler.class.getClassLoader());
+
+    /**
+     * <p>The default JSF view handler.</p>
+     */
+   private ViewHandler defaultViewHandler = null;
+
+
+   // ----------------------------------------------------- ViewHandler Methods
+
+
+   /**
+    * <p>Render a view according to the algorithm described in this class's
+    * description: Based on the view Id of the <code>viewToRender</code>, 
+    * this method either renders a tile or delegates rendering to the default 
+    * view handler, which takes care of business as usual.</p>
+    *
+    * @param facesContext The faces context object for this request
+    * @param viewToRender The view that we're rendering
+    */
+   public void renderView(FacesContext facesContext, UIViewRoot viewToRender) 
+                                        throws IOException, FacesException {
+      String viewId = viewToRender.getViewId();
+      String tileName = getTileName(viewId);
+      ComponentDefinition tile = getTile(tileName);
+
+      if (log.isDebugEnabled()) {
+         log.debug(messages.getMessage("tiles.renderingView", 
+                                       new Object[] { viewId, tileName }));
+      }
+
+      if (tile != null) {
+         if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("tiles.dispatchingToTile", 
+                                          new Object[] { tileName }));
+         }
+         dispatchToTile(facesContext.getExternalContext(), tile);
+      }
+      else {
+         if (log.isDebugEnabled()) {
+            log.debug(messages.getMessage("tiles.dispatchingToViewHandler", 
+                                          new Object[] { viewId }));
+         }
+         defaultViewHandler.renderView(facesContext, viewToRender);
+      }
+   }
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public UIViewRoot createView(FacesContext context, String viewId) {
+      return defaultViewHandler.createView(context, viewId);
+   }
+
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public Locale calculateLocale(FacesContext context) {
+      return defaultViewHandler.calculateLocale(context);
+   }
+    
+
+   /**
+    * <p>Pass through to the default view handler
+    * 
+    */
+   public String calculateRenderKitId(FacesContext context) {
+      return defaultViewHandler.calculateRenderKitId(context);
+   }
+    
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public String getActionURL(FacesContext context, String viewId) {
+      return defaultViewHandler.getActionURL(context, viewId);
+   }
+    
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public String getResourceURL(FacesContext context, String path) {
+      return defaultViewHandler.getResourceURL(context, path);
+   }
+    
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public UIViewRoot restoreView(FacesContext context, String viewId) {
+      return defaultViewHandler.restoreView(context, viewId);
+   }
+    
+
+   /**
+    * <p>Pass through to the default view handler</p>
+    * 
+    */
+   public void writeState(FacesContext context) throws IOException {
+      defaultViewHandler.writeState(context);
+   }
+
+
+   // --------------------------------------------------------- Private Methods
+
+
+   /**
+    * <p>Looks up a tile, given a name. If the tile does not exist, and the
+    * <code>name</code> begins with a slash ('/'), look for a tile
+    * without the slash. If no tile is found, return <code>null</code>.</p>
+    * 
+    * @param name The tile to lookup
+    */
+   private ComponentDefinition getTile(String name) {
+      if (name == null) 
+         return null;
+
+      ExternalContext externalContext = FacesContext.getCurrentInstance()
+                                                    .getExternalContext();
+      ServletRequest request = (ServletRequest)externalContext.getRequest();
+      ServletContext servletContext = (ServletContext)externalContext.
+                                                            getContext();
+      DefinitionsFactory factory = TilesUtil.getDefinitionsFactory(request, 
+                                                            servletContext);
+      if (factory == null)
+        return null;
+
+      ComponentDefinition tile = null;
+      try {
+         tile = factory.getDefinition(name, request, servletContext);
+      }
+      catch(NoSuchDefinitionException  nsex) { /* not here */ }
+      catch(DefinitionsFactoryException dex) { /* not here */ }
+
+      if (tile == null && name.startsWith("/")) { // try again w/o slash...
+         try {
+            tile = factory.getDefinition(name.substring(1), 
+                                         request, servletContext);
+         }
+         catch(NoSuchDefinitionException  nsdex) { /* not here */ }
+         catch(DefinitionsFactoryException dfex) { /* not here */ }
+      }
+      return tile;
+   }
+
+   /**
+    * <p>Given a view ID, returns the name of the corresponding tile. For 
+    * example, for a view ID of /tiles/example/main.jsp, the tile name 
+    * returned by this method would be /tiles/example/main.</p>
+    * 
+    * @param viewId The view ID
+    */
+   private String getTileName(String viewId) {
+      int suffixIndex = viewId.lastIndexOf('.');
+      return suffixIndex != -1 ? viewId.substring(0, suffixIndex)
+                               : viewId;
+   }
+
+   /**
+    * <p>Dispatches to a tile's layout. Layouts typically contain
+    * &lt;tiles:insert&gt; tags that include content, so dispatching
+    * to the tile's layout will automatically build the tile.</p>
+    * <p>
+    * Before dispatching to the tile, this method sets up the Tile
+    * context.</p>
+    * 
+    * @param externalContext The JSF external context
+    * @param tile The tile definition
+    */
+   private void dispatchToTile(ExternalContext externalContext,
+                               ComponentDefinition tile) 
+                               throws java.io.IOException {
+      ServletRequest request = (ServletRequest)externalContext.getRequest();
+      ComponentContext tileContext = ComponentContext.getContext(request);
+      if (tileContext == null) {
+         tileContext = new ComponentContext(tile.getAttributes());
+         ComponentContext.setContext(tileContext, request);
+      }
+      else
+         tileContext.addMissing(tile.getAttributes());
+   
+      // dispatch to the tile's layout
+      externalContext.dispatch(tile.getPath());
+   }
+}

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/faces-config.xml?rev=209369&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/faces-config.xml (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/faces-config.xml Tue Jul  5 17:58:35 2005
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+
+
+<!DOCTYPE faces-config PUBLIC
+  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
+  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
+
+
+<!--
+
+ Copyright 2004-2005 The Apache Software Foundation.
+ 
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ 
+      http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ $Id$
+
+-->
+
+
+<faces-config>
+
+  <application>
+    <!-- Tiles Integration -->
+    <view-handler>
+      org.apache.shale.tiles.TilesViewHandler
+    </view-handler>
+  </application>
+
+</faces-config>

Added: struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/package.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/package.html?rev=209369&view=auto
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/package.html (added)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/tiles/package.html Tue Jul  5 17:58:35 2005
@@ -0,0 +1,33 @@
+<!--
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<!-- $Id$ -->
+
+<body>
+
+<p>This package contains an optional integration layer for working with standalone Tiles.
+<p>
+<strong>Note:</strong><i> Shale's Tiles integration works only with standalone Tiles, which currently resides in the Struts sandbox. Shale's Tiles integration does not work with Struts Tiles.</i>
+<p>
+Using Shale's Tiles integration is easy: you just include <code>shale-tiles.jar</code> in <code>WEB-INF/lib</code>. For your efforts, for every view ID that you specify for JSF navigation, Shale:
+<ol><li>Strips off the view ID's suffix (eg: "/tiles/test.jsp" becomes "/tiles/test")</li>
+<li>Searches for a tile with the resulting name, with or without the leading slash (eg: "/tiles/test" or "tiles/test")</li>
+<li>Loads the tile if found; otherwise, delegates to the default JSF navigation handler</li>
+</ol>
+<p>
+With Shale's Tiles integration, you can use a tile or a single JSP page to represent a JSF view and your view IDs for navigation are the same for both. For example, you could have a JSP page <code>/login.jsp</code>, that you specify as a view ID for navigation. Later on, you can replace that JSP page with a tile simply by specifying a tile named <code>login</code> in your Tiles definition file. Shale will strip off the <code>.jsp</code> suffix and load the tile instead of the JSP page.
+
+</body>



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