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 <tiles:insert> 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
+ * <tiles:insert> 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