You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2005/07/16 06:37:50 UTC
svn commit: r219287 - in /struts/shale/trunk: ./ clay-plugin/src/conf/
clay-plugin/src/java/org/apache/shale/clay/component/
clay-plugin/src/java/org/apache/shale/clay/component/chain/
clay-plugin/src/java/org/apache/shale/clay/faces/ clay-plugin/src/j...
Author: craigmcc
Date: Fri Jul 15 21:37:46 2005
New Revision: 219287
URL: http://svn.apache.org/viewcvs?rev=219287&view=rev
Log:
Commit the changes for the full HTML templating update to the Clay plugin,
including an update to the use cases example.
PR: Bugzilla #35762
Submitted By: Gary VanMatre <gvanmatre AT comcast.net>
Added:
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java
struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html
Modified:
struts/shale/trunk/build.xml
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/component/Clay.java
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/CommandButtonBuilder.java
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
struts/shale/trunk/default.properties
struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
struts/shale/trunk/use-cases/src/web/WEB-INF/clay-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/build.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/build.xml?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/build.xml (original)
+++ struts/shale/trunk/build.xml Fri Jul 15 21:37:46 2005
@@ -17,7 +17,7 @@
-->
-<project name="Shale Framework Global Build" basedir=".">
+<project name="global" basedir=".">
<!-- ===================== Initialize Property Values ==================== -->
@@ -217,9 +217,93 @@
</path>
- <!-- ====================== Download Dependencies ======================== -->
+ <!-- ====================== Common Class Path References ================= -->
+ <!-- External dependencies *without* a JSF implementation -->
+ <path id="external.path">
+ <path refid="commons-beanutils.path"/>
+ <path refid="commons-chain.path"/>
+ <path refid="commons-digester.path"/>
+ <path refid="commons-logging.path"/>
+ <path refid="commons-validator.path"/>
+ <path refid="jsp-api.path"/>
+ <path refid="jstl-ri-api.path"/>
+ <path refid="portlet-api.path"/>
+ <path refid="servlet-api.path"/>
+ <path refid="spring-beans.path"/>
+ <path refid="spring-context.path"/>
+ <path refid="spring-core.path"/>
+ <path refid="spring-web.path"/>
+ <path refid="tiles.path"/>
+ </path>
+
+
+ <!-- External dependencies plus JSF RI -->
+ <path id="external-jsfri.path">
+ <path refid="external.path"/>
+ <path refid="jsf-ri-api.path"/>
+ </path>
+
+
+ <!-- External dependencies plus MyFaces -->
+ <path id="external-myfaces.path">
+ <path refid="external.path"/>
+ <path refid="myfaces-api.path"/>
+ </path>
+
+
+ <!-- External plus test dependencies *without* a JSF implementation -->
+ <path id="test.path">
+ <path refid="external.path"/>
+ <path refid="junit.path"/>
+ <path refid="shale-test.path"/>
+ </path>
+
+
+ <!-- External plus test dependencies plus JSF RI -->
+ <path id="test-jsfri.path">
+ <path refid="test.path"/>
+ <path refid="jsf-ri-api.path"/>
+ </path>
+
+
+ <!-- External plus test dependencies plus MyFaces -->
+ <path id="test-myfaces.path">
+ <path refid="test.path"/>
+ <path refid="myfaces-api.path"/>
+ </path>
+
+
+ <!-- ======================== Pass Through Targets ======================= -->
+
+
+ <!-- These targets execute the corresponding target for all modules. -->
+
+
+ <target name="clean"
+ description="Execute 'clean' all all modules">
+
+ <antcall target="execute">
+ <param name="target"
+ value="clean"/>
+ </antcall>
+
+ </target>
+
+
+
+ <!-- =================== Initialize Local Repository ===================== -->
+
+
+ <!-- These targets are used to load all dependencies into the local repository
+ (by default, the "lib" directory. Generally, they should be executed
+ once when the source configuration is initially configured, but they
+ may be repeated to ensure that the loaded dependencies are current. -->
+
+
+ <!-- Download freely available dependencies from the ${maven.repo}
+ Maven repository into directory ${lib.dir}. -->
<target name="download-dependencies"
description="Download freely available dependencies">
@@ -366,9 +450,8 @@
</target>
- <!-- ======= Copy JavaServer Faces Reference Implementation ============== -->
-
-
+ <!-- Copy relevant artifacts from the JavaServer Faces reference
+ implementation installed at ${jsfri.dir} to ${lib.dir}. -->
<target name="copy-jsf-ri"
description="Copy artifacts from JSF Reference Implementation">
@@ -381,9 +464,8 @@
</target>
- <!-- ============= Copy Standalone Tiles ================================= -->
-
-
+ <!-- Copy relevant artifacts from the compiled standalone Tiles implementation
+ (currently in the Struts sandbox) from ${tiles.dir} into ${lib.dir}. -->
<target name="copy-tiles"
description="Copy standalone Tiles artifacts">
@@ -392,5 +474,36 @@
file="${tiles.dir}/lib/tiles-core.jar"/>
</target>
+
+
+ <!-- ==================== Internal Targets =============================== -->
+
+
+
+ <!-- These targets are not intended for direct use. They are used internally
+ by other targets. -->
+
+
+ <!-- Recursively execute ${target} across all modules -->
+ <target name="execute">
+
+ <echo message="Executing ${target} on module core-library"/>
+ <ant dir="${root.dir}/core-library"
+ target="${target}"/>
+
+ <echo message="Executing ${target} on module clay-plugin"/>
+ <ant dir="${root.dir}/clay-plugin"
+ target="${target}"/>
+
+ <echo message="Executing ${target} on module test-framework"/>
+ <ant dir="${root.dir}/test-framework"
+ target="${target}"/>
+
+ <echo message="Executing ${target} on module use-cases"/>
+ <ant dir="${root.dir}/use-cases"
+ target="${target}"/>
+
+ </target>
+
</project>
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=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/faces-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/conf/faces-config.xml Fri Jul 15 21:37:46 2005
@@ -32,6 +32,12 @@
<faces-config>
+ <application>
+ <view-handler>
+ org.apache.shale.clay.faces.ClayViewHandler
+ </view-handler>
+ </application>
+
<component>
<description>
The "Clay" component dynamically composes a tree of child components
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=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/conf/view-config.xml (original)
+++ struts/shale/trunk/clay-plugin/src/conf/view-config.xml Fri Jul 15 21:37:46 2005
@@ -205,4 +205,15 @@
</attributes>
</component>
+
+ <!-- Nested Clay Component -->
+ <component jsfid="clay" componentType="org.apache.shale.clay.component.Clay"
+ allowBody="false">
+ <attributes>
+ <set name="jsfid" value="RUNTIME"/>
+ <set name="managedBeanName" useValueLateBinding="false"/>
+ <set name="shapeValidator" useMethodLateBinding="true"/>
+ </attributes>
+ </component>
+
</view>
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=219287&r1=219286&r2=219287&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 Fri Jul 15 21:37:46 2005
@@ -315,7 +315,7 @@
try {
catalog = getCatalog();
} catch (Exception e) {
- System.out.println(e);
+ log.error(e);
}
Command command = catalog
.getCommand(Globals.ADD_COMPONENT_COMMAND_NAME);
@@ -331,7 +331,6 @@
}
- super.encodeBegin(context);
}
/**
@@ -342,7 +341,7 @@
protected void recursiveRenderChildren(UIComponent child,
FacesContext context) throws IOException {
- if (!child.getRendersChildren()) {
+ if (!child.getRendersChildren() || child == this) {
Iterator ci = child.getChildren().iterator();
while (ci.hasNext()) {
UIComponent c = (UIComponent) ci.next();
@@ -368,11 +367,12 @@
* </p>
*/
public void encodeChildren(FacesContext context) throws IOException {
- super.encodeChildren(context);
if (log.isTraceEnabled())
log.trace("encodeChildren(FacesContext)");
-
+
+ recursiveRenderChildren(this, context);
+
}
/**
@@ -386,11 +386,6 @@
if (log.isTraceEnabled())
log.trace("encodeEnd(FacesContext)");
- // if the parents, parent handles the renderering, like a pannelGrid, it
- // will take care of the rendering of the root subview node.
- if (!getParent().getRendersChildren()) {
- recursiveRenderChildren(this, context);
- }
}
/**
@@ -452,5 +447,17 @@
return aobj;
}
+
+ /**
+ * <p>Returns <code>true</code> indicating that this
+ * component will render it's children. This will
+ * indicate to a parent component that renders children
+ * not to recursively render Clay's children -
+ * simply invoke encodeChildren(FacesContext).</p>
+ */
+ public boolean getRendersChildren() {
+ return true;
+ }
+
}
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java Fri Jul 15 21:37:46 2005
@@ -75,9 +75,21 @@
FacesContext facesContext = clayContext.getFacesContext();
if (facesContext == null)
throw new NullPointerException(messages.getMessage("clay.null.facesContext"));
- if (attributeBean.getValue() != null
- && (attributeBean.getValue().indexOf('{') > -1 && attributeBean
- .getValue().indexOf('}') > -1)) {
+
+ //when using the html templating, javascript and css will have matching curly braces {}.
+ //and pound sign # too.
+ int pound = -1;
+ int leftCurly = -1;
+ int rightCurly = -1;
+
+ if (attributeBean.getValue() != null) {
+ pound = attributeBean.getValue().indexOf('#');
+ leftCurly = attributeBean.getValue().indexOf('{');
+ rightCurly = attributeBean.getValue().indexOf('}');
+ }
+ if ((pound > -1 && leftCurly > -1 && rightCurly > -1)
+ && (rightCurly > leftCurly) && ((leftCurly - pound) == 1)) {
+
String expr = replaceMnemonic(clayContext);
ValueBinding binding = facesContext.getApplication()
.createValueBinding(expr);
@@ -90,7 +102,9 @@
// Should pass a method value binding expressions to the components
// that use non-standard names like the clay component's shapValidator
// method binding expression. Standard method binding properties will
- // be handled by the other property commands
+ // be handled by the other property commands (PropertyActionCommand,
+ // PropertyActionListenerCommand, PropertyValidatorCommand, and
+ // PropertyValueChangeListenerCommand)
((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
@@ -100,15 +114,11 @@
PropUtils.setProperty(child, attributeBean.getName(), value);
} catch (Exception e) {
- // catch the exception and check to see if the attribute name is in the
- // components attributes Map. If it is, set the value as a string.
- if (((UIComponent) child).getAttributes().containsKey(attributeBean.getName())) {
- ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
- } else {
- // not a valid attribute, throw the exception
- log.error(e);
- throw e;
- }
+ // Catch the exception logging it. Assume that the value is for
+ // an attribute that has no corresponding component property.
+ // After all, clay can be shaped into anything - it's all good.
+ log.error(e);
+ ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
}
}
Added: 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=219287&view=auto
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java (added)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/faces/ClayViewHandler.java Fri Jul 15 21:37:46 2005
@@ -0,0 +1,295 @@
+/*
+ * 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.faces;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Locale;
+
+import javax.faces.FacesException;
+import javax.faces.application.StateManager;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.servlet.ServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.ViewController;
+import org.apache.shale.ViewControllerMapper;
+import org.apache.shale.clay.component.Clay;
+import org.apache.shale.clay.config.Globals;
+import org.apache.shale.faces.ShaleConstants;
+import org.apache.shale.view.DefaultViewControllerMapper;
+
+/**
+ * <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
+ * original decorated view handler.</p>
+ */
+public class ClayViewHandler extends ViewHandler {
+
+ /**
+ * <p>
+ * Commons logger utility class instance
+ * </p>
+ */
+ private static Log log;
+ static {
+ log = LogFactory.getLog(ClayViewHandler.class);
+ }
+
+ /**
+ * <p>The decorated view handler.</p>
+ */
+ private ViewHandler original = null;
+
+ /**
+ * <p>The {@link Clay} component <code>id</code> property value.</p>
+ */
+ private static final String CLAY_VIEW_ID = "clayView";
+
+ /**
+ * <p>{@link Clay} <code>componentType</code> that is used to create a instance using
+ * the faces Application object.</p>
+ */
+ 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>
+ */
+ private String suffix = null;
+
+ /**
+ * <p>Cached {@link ViewControllerMapper} we will use to translate
+ * view identifiers to the class name of a {@link ViewController}.
+ * This code is borrowed from {@link ShaleViewController}.</p>
+ */
+ private ViewControllerMapper mapper = null;
+
+
+ // Specified by ViewHandler
+ public ClayViewHandler(ViewHandler original) {
+ this.original = original;
+
+ if (log.isInfoEnabled())
+ log.info("Loading Clay View Handler");
+ }
+
+ // Specified by ViewHandler
+ public Locale calculateLocale(FacesContext context) {
+ return original.calculateLocale(context);
+ }
+
+ // Specified by ViewHandler
+ public String calculateRenderKitId(FacesContext context) {
+ return original.calculateRenderKitId(context);
+ }
+
+ // Specified by ViewHandler
+ public UIViewRoot createView(FacesContext context, String viewId) {
+ return original.createView(context, viewId);
+ }
+
+ /**
+ * <p>If the <code>viewId</code> is suffixed with the Clay template suffix,
+ * rewrite the returned actionUrl with a clay suffix. The super implementation
+ * will assume ".jsp" or whatever the <code>javax.faces.DEFAULT_SUFFIX</code> is
+ * set to in the web deployment descriptor.</p>
+ */
+ public String getActionURL(FacesContext context, String viewId) {
+ StringBuffer actionUrl = new StringBuffer(original.getActionURL(context, viewId));
+
+ if (this.isClayTemplate(context, viewId)) {
+ int i = actionUrl.lastIndexOf(".");
+ if (i > -1) {
+ actionUrl.setLength(i);
+ actionUrl.append(suffix);
+ }
+ }
+
+ return actionUrl.toString();
+ }
+
+ // Specified by ViewHandler
+ public String getResourceURL(FacesContext context, String path) {
+ return original.getResourceURL(context, path);
+ }
+
+ /**
+ * <p>Returns <code>true</code> if the <code>viewId</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>
+ */
+ 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;
+ }
+ }
+
+ return viewId.endsWith(suffix);
+ }
+
+ /**
+ * <p>The default view handler implementation will try to
+ * make the viewId end with ".jsp". If the viewId ends
+ * in the clay template suffix, use the state manager
+ * to restore the view.</p>
+ */
+ public UIViewRoot restoreView(FacesContext context, String viewId) {
+ UIViewRoot view = null;
+
+ if (this.isClayTemplate(context, viewId)) {
+
+ if (log.isInfoEnabled())
+ log.info("Clay template restoreView for " + viewId);
+
+ StateManager stateManager = context.getApplication().getStateManager();
+ view = stateManager.restoreView(context, viewId, calculateRenderKitId(context));
+ } else
+ view = original.restoreView(context, viewId);
+ return view;
+ }
+
+ // Specified by ViewHandler
+ public void writeState(FacesContext context) throws IOException {
+ original.writeState(context);
+ }
+
+ /**
+ * <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. 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 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
+ * is set with the Shale <code>ViewControllerMapper</code>. A <code>ResponseWriter</code>
+ * is created and rendering is invoked on the component. This differs from the base implementation.
+ * The base implementation would dispatch to a JSP that would assemble the component tree
+ * and invoke rendering to the response writer.</p>
+ */
+ public void renderView(FacesContext context, UIViewRoot view)
+ throws IOException, FacesException {
+
+ //is this view a clay html template view
+ if (isClayTemplate(context, view.getViewId())) {
+
+ if (log.isInfoEnabled())
+ log.info("Clay template renderView for " + view.getViewId());
+
+ //look to see if it already exists
+ UIComponent component = view.findComponent(CLAY_VIEW_ID);
+ if (component == null) {
+ component = context.getApplication().createComponent(CLAY_COMPONENT_TYPE);
+ ((Clay) component).setId(CLAY_VIEW_ID);
+ ((Clay) component).setJsfid(view.getViewId());
+ ((Clay) component).setManagedBeanName(getManagedBeanName(context, view.getViewId()));
+ view.getChildren().add(view.getChildren().size(), component);
+ }
+
+ //get the response
+ ServletResponse response = (ServletResponse) context.getExternalContext().getResponse();
+ //set the locale
+ (response).setLocale(context.getViewRoot().getLocale());
+
+ //create a response writer
+ ResponseWriter responsewriter = context.getRenderKit().createResponseWriter(response.getWriter(), null, response.getCharacterEncoding());
+ //push it to the faces context
+ context.setResponseWriter(responsewriter);
+ //start a document
+ responsewriter.startDocument();
+
+ recursiveRender(view, context);
+
+ //end the document
+ responsewriter.endDocument();
+
+ //save the view
+ StateManager stateManager = context.getApplication().getStateManager();
+ StateManager.SerializedView serializedview = stateManager.saveSerializedView(context);
+
+
+ } else {
+ //dispatch (forward) to the jsp
+ original.renderView(context, view);
+ }
+ }
+
+
+ /**
+ * <p>
+ * Recursively invokes the rendering of the sub component tree.
+ * </p>
+ */
+ protected void recursiveRender(UIComponent child,
+ FacesContext context) throws IOException {
+
+ if (!child.getRendersChildren()) {
+ child.encodeBegin(context);
+ Iterator ci = child.getChildren().iterator();
+ while (ci.hasNext()) {
+ UIComponent c = (UIComponent) ci.next();
+ c.encodeBegin(context);
+
+ if (!c.getRendersChildren())
+ recursiveRender(c, context);
+ else
+ c.encodeChildren(context);
+
+ c.encodeEnd(context);
+ c = null;
+ }
+ child.encodeEnd(context);
+ } else {
+ // let the component handle iterating over the children
+ child.encodeBegin(context);
+ child.encodeChildren(context);
+ child.encodeEnd(context);
+ }
+ }
+
+ /**
+ * <p>Returns the managed-bean-name the view controller is registered under. The
+ * assumed mapping will be the same as in core Shale</p>
+ */
+ protected String getManagedBeanName(FacesContext context, String viewId) {
+ if (mapper == null) {
+ mapper = (ViewControllerMapper)
+ context.getExternalContext().getApplicationMap().
+ get(ShaleConstants.VIEW_MAPPER);
+
+ if (mapper == null)
+ mapper = new DefaultViewControllerMapper();
+ }
+ return mapper.mapViewId(viewId);
+ }
+
+
+
+}
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/Parser.java Fri Jul 15 21:37:46 2005
@@ -254,7 +254,8 @@
} else {
// the current node is a optional and the new node is it's parent
// simulate having ending nodes
- if (this.isValidOptionalEndingTagParent(current.getName(), node.getName())) {
+
+ if (isOptionalEndingTag(node.getName()) && isValidOptionalEndingTagParent(current.getName(), node.getName())) {
pop: while (true) {
if (current == null)
@@ -283,6 +284,7 @@
}
} else {
+
// adding a new node to the current making it current
current.addChild(node);
current = node;
@@ -432,7 +434,7 @@
// find the node name delimiter
int e = token.getDocument().indexOf(" ", token.getBeginOffset() + 2);
// end of token is the delimiter
- if (e == -1 || e > token.getEndOffset())
+ if (e == -1 || e >= token.getEndOffset())
e = (isBeginTag && isEndTag) ? (token.getEndOffset() - 2)
: (token.getEndOffset() - 1);
// find the start of the node attribute body
Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/CommandButtonBuilder.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/CommandButtonBuilder.java?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/CommandButtonBuilder.java (original)
+++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/parser/builder/CommandButtonBuilder.java Fri Jul 15 21:37:46 2005
@@ -60,6 +60,20 @@
protected String getComponentType(Node node) {
return "javax.faces.HtmlCommandButton";
}
+
+ /**
+ * <p>Add the <code>value</code> attribute as a "HTML" attribute. For the
+ * commandButton, the value holds the label.</p>
+ */
+ protected String[] getHtmlAttributes() {
+
+ String[] tmp = super.getHtmlAttributes();
+ String[] attrs = new String[tmp.length + 1];
+ System.arraycopy(tmp, 0, attrs, 0, tmp.length);
+ attrs[attrs.length - 1] = "value";
+
+ return attrs;
+ }
}
Modified: struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java (original)
+++ struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/parser/ParserTestCase.java Fri Jul 15 21:37:46 2005
@@ -23,63 +23,62 @@
public class ParserTestCase extends TestCase {
-
/**
- * <p>Tests to see if we can parse a document fragment
- * that has multiple root nodes</p>
+ * <p>
+ * Tests to see if we can parse a document fragment that has multiple root
+ * nodes
+ * </p>
*/
public void testManyRootNodes() {
Parser p = new Parser();
StringBuffer doc1 = new StringBuffer();
- doc1.append("<p>")
- .append("<input type=text size=10 maxsize=10 id=username>")
- .append("<input type=text size=10 maxsize=10 id=password>")
- .append("</p>")
- .append("<p>")
- .append("This is a test. Just a test")
- .append("</p>")
- .append("<p></p>");
-
+ doc1.append("<p>").append(
+ "<input type=text size=10 maxsize=10 id=username>").append(
+ "<input type=text size=10 maxsize=10 id=password>").append(
+ "</p>").append("<p>").append("This is a test. Just a test")
+ .append("</p>").append("<p></p>");
+
List nodes1 = p.parse(doc1);
assertTrue("Has 3 root nodes", nodes1.size() == 3);
-
+
}
-
+
/**
- * <p>Test a couple comment block scenarios</p>
+ * <p>
+ * Test a couple comment block scenarios
+ * </p>
*/
public void testCommentBlocks() {
Parser p = new Parser();
StringBuffer doc1 = new StringBuffer();
-
- doc1.append("<p>")
- .append("<!--<input type=text size=10 maxsize=10 id=username>")
- .append("<input type=text size=10 maxsize=10 id=password>-->")
- .append("</p>")
- .append("<!--This is a test. Just a test-->")
- .append("<!--<p>Testing <b>123</b></p>-->");
-
+ doc1.append("<p>").append(
+ "<!--<input type=text size=10 maxsize=10 id=username>").append(
+ "<input type=text size=10 maxsize=10 id=password>-->").append(
+ "</p>").append("<!--This is a test. Just a test-->").append(
+ "<!--<p>Testing <b>123</b></p>-->");
+
List nodes1 = p.parse(doc1);
- assertTrue("Has 3 root nodes", nodes1.size() == 3);
-
+ assertTrue("Has 3 root nodes", nodes1.size() == 3);
+
Node node = (Node) nodes1.get(0);
- assertTrue("first paragraph has 1 node", node.getChildren().size() == 1);
+ assertTrue("first paragraph has 1 node", node.getChildren().size() == 1);
node = (Node) node.getChildren().get(0);
- assertTrue("first comment block has 2 nodes", node.getChildren().size() == 2);
+ assertTrue("first comment block has 2 nodes",
+ node.getChildren().size() == 2);
node = (Node) nodes1.get(1);
- assertTrue("second root has 0 child nodes", node.getChildren().size() == 0);
+ assertTrue("second root has 0 child nodes",
+ node.getChildren().size() == 0);
node = (Node) nodes1.get(2);
- assertTrue("third root has 1 child node", node.getChildren().size() == 1);
-
-
+ assertTrue("third root has 1 child node",
+ node.getChildren().size() == 1);
+
}
-
-
+
/**
* <p>
* Tests case insensitivity in parsing the document.
@@ -213,6 +212,52 @@
}
+ /**
+ * Checks to see if nested tables parse correctly
+ */
+public void testNestedTables() {
+ Parser p = new Parser();
+ StringBuffer doc = new StringBuffer();
+ doc
+ .append("<table>")
+ .append("<tr><td><table><tr><td></td></tr></table></td>")
+ .append("<td><span jsfid=\"tabs\"><ul id=\"menu\"><li id=\"nav\"><a href=\"#\">Tab 1</a></li><li id=\"nav-sel\"><a href=\"#\">Tab 2</a></li><li id=\"nav\"><a href=\"#\">Tab 3</a></li></ul></span>")
+ .append("</td></tr>").append("</table>")
+ .append("<div id=\"contents\">")
+ .append("<table border=\"0\">")
+ .append("<tr><td rowspan=\"3\">")
+ .append("<span jsfid=\"contactTable\">")
+ .append("<table class=\"contacts\">")
+ .append("<tr class=\"contactsHeader\"> ")
+ .append("<td>")
+ .append("Contacts")
+ .append("</td>")
+ .append("</tr> ")
+ .append("<tr class=\"contactsRow1\">")
+ .append("<td>")
+ .append("<a href=\"#\">ABC Company</a>")
+ .append("</td>")
+ .append("</tr>")
+ .append("<tr class=\"contactsRow2\">")
+ .append("<td>")
+ .append("<a href=\"#\">XYZ Company</a>")
+ .append("</td>")
+ .append("</tr>")
+ .append("</table>")
+ .append("</span>")
+ .append("</td></tr>")
+ .append("<tr><td>")
+ .append("<table>")
+ .append("<tr><td><label style=\"color:#99CC66\" jsfid=\"contactNameLabel\">Name:</label></td><td><input jsfid=\"contactName\" type=text size=40 maxlength=\"50\"/></td><td><span style=\"color:red\" jsfid=\"contactNameMessage\">Mock Error Name</span></td></tr></table></td></tr>")
+ .append("</table>")
+ .append("</div>");
+
+
+ List nodes = p.parse(doc);
+ assertTrue("Well-formed nested table has 1 root node", nodes.size() == 2);
+
+
+ }
/**
* <p>
* Aserts that two trees of parsed HTML have the same number children and
Modified: struts/shale/trunk/default.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/default.properties?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/default.properties (original)
+++ struts/shale/trunk/default.properties Fri Jul 15 21:37:46 2005
@@ -29,11 +29,24 @@
# a binary distribution of the JavaServer Faces Reference Implementation
jsfri.dir=/usr/local/jsf-1_1_01
+# Version Identifier to append to artifact filenames, and embed in
+# JavaDoc comments
+project.version=0.2
+
+# Location in which state saving should take place (client or server)
+state.saving=client
+
+
# Fully qualified pathname of the directory containing the "dist" output
# of a build of the standalone version of Tiles (currently in the Struts
# Sandbox).
tiles.dir=${root.dir}/../sandbox/tiles/core-library/dist
+# Uncomment the following to compile and execute with MyFaces
+# rather than the JSF Reference Implementation
+#use.myfaces=true
+
+
# ------------------------ Optional Customizations -----------------------
@@ -46,8 +59,28 @@
# ----------------------- Standard Values --------------------------------
+# State for the "debug" attribute of the "javac" task
+compile.debug=true
+
+# State for the "deprecation" attribute of the "javac" task
+compile.deprecation=true
+
+# State for the "optimize" attribute of the "javac" task
+compile.optimize=true
+
+# FindBugs Output File
+findbugs.outputFile=${root.dir}/find-bugs.html
+
# Name of the library repository directory into which we will download
# our dependencies
lib.dir=${root.dir}/lib
+# State for the "halt on error" attribute for JUnit tests
+test.haltonerror=true
+
+# State for the "halt on failure" attribute for JUnit tests
+test.haltonfailure=true
+
+# JUnit test execution engine
+test.runner=junit.textui.TestRunner
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=219287&r1=219286&r2=219287&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 Fri Jul 15 21:37:46 2005
@@ -128,7 +128,8 @@
usecases.tiles=Tiles
usecases.tiles.simple=A Simple Tiles Example
usecases.clay=Clay View Use Cases
-usecases.rolodex=Rolodex Example
+usecases.rolodex1=Rolodex Example (JSP View)
+usecases.rolodex2=Rolodex Example (HTML View)
# Validation
validate.test.title=Shale Validation using Commons Validator
Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml?rev=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml Fri Jul 15 21:37:46 2005
@@ -25,7 +25,7 @@
</element>
</component>
- <component jsfid="contactTable" extends="dataTable">
+ <component jsfid="contactTable" extends="dataTable" allowBody="false">
<attributes>
<set name="value" useValueLateBinding="true" value="#{managed-bean-name.contactsForTab}"/>
<set name="var" value="e"/>
@@ -240,7 +240,7 @@
- <!-- Concat Name -->
+ <!-- Contact Name -->
<component jsfid="nameLabel" extends="baseLabel">
<attributes>
<set name="value" value="Name:" />
@@ -292,8 +292,6 @@
<component jsfid="residentialPhone" extends="inputText" id="residentialPhone">
<attributes>
<set name="value" useValueLateBinding="true" value="#{managed-bean-name.residentialPhone}" />
- <set name="size" value="20" />
- <set name="maxlength" value="50" />
<set name="required" value="false" />
</attributes>
</component>
@@ -313,8 +311,6 @@
<component jsfid="businessPhone" extends="inputText" id="businessPhone">
<attributes>
<set name="value" useValueLateBinding="true" value="#{managed-bean-name.businessPhone}" />
- <set name="size" value="20" />
- <set name="maxlength" value="50" />
<set name="required" value="false" />
</attributes>
</component>
@@ -435,5 +431,358 @@
</component>
-
+
+<!-- HTML hroledex.html template -->
+
+ <!-- Nested Clay Component -->
+ <component jsfid="tabs" extends="clay" id="tabs" allowBody="false">
+ <attributes>
+ <set name="jsfid" value="RUNTIME"/>
+ <set name="managedBeanName" value="rolodex$hrolodex"/>
+ <set name="shapeValidator" useMethodLateBinding="true" value="#{managed-bean-name.createTabs}"/>
+ </attributes>
+ </component>
+
+ <!-- submit button to save a contact -->
+ <component jsfid="contactSaveCommand" extends="commandButton">
+ <attributes>
+ <set name="action" value="#{managed-bean-name.saveContact}"/>
+ <set name="rendered" useValueLateBinding="true" value="#{!empty managed-bean-name.selectedContact}"/>
+ </attributes>
+ </component>
+
+ <!-- submit button to delete a contact -->
+ <component jsfid="contactDeleteCommand" extends="commandButton">
+ <attributes>
+ <set name="action" value="#{managed-bean-name.deleteContact}"/>
+ <set name="rendered" useValueLateBinding="true" value="#{!empty managed-bean-name.selectedContact}"/>
+ </attributes>
+ </component>
+
+ <!-- submit button to new a contact -->
+ <component jsfid="contactNewCommand" extends="commandButton">
+ <attributes>
+ <set name="action" value="#{managed-bean-name.newContact}" />
+ <set name="immediate" value="true"/>
+ </attributes>
+ </component>
+
+
+ <!-- Contact Name -->
+ <component jsfid="contactNameLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="contactName" />
+ </attributes>
+ </component>
+ <component jsfid="contactName" extends="inputText" id="contactName">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.name}" />
+ <set name="required" value="true" />
+ </attributes>
+ </component>
+ <component jsfid="contactNameMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="contactName" />
+ </attributes>
+ </component>
+
+ <!-- Contact email address -->
+ <component jsfid="contactEmailLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="contactEmail" />
+ </attributes>
+ </component>
+ <component jsfid="contactEmail" extends="inputText" id="contactEmail">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.email}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="contactEmailMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="contactEmail" />
+ </attributes>
+ </component>
+
+ <!-- residential city -->
+ <component jsfid="residentialCityLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="residentialCity" />
+ </attributes>
+ </component>
+ <component jsfid="residentialCity" extends="inputText" id="residentialCity">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.residentialAddress.city}" />
+ <set name="required" value="true" />
+ </attributes>
+ </component>
+ <component jsfid="residentialCityMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="residentialCity" />
+ </attributes>
+ </component>
+
+
+ <!-- business city -->
+ <component jsfid="businessCityLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessCity" />
+ </attributes>
+ </component>
+ <component jsfid="businessCity" extends="inputText" id="businessCity">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessAddress.city}" />
+ <set name="required" value="true" />
+ </attributes>
+ </component>
+ <component jsfid="businessCityMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessCity" />
+ </attributes>
+ </component>
+
+
+ <!-- residential street 1 label, input field and message -->
+ <component jsfid="residentialStreet1Label" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="residentialStreet1" />
+ </attributes>
+ </component>
+ <component jsfid="residentialStreet1" extends="inputText" id="residentialStreet1">
+ <attributes>
+ <set name="value" value="#{managed-bean-name.selectedContact.residentialAddress.street1}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="residentialStreet1Message" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="residentialStreet1" />
+ </attributes>
+ </component>
+
+ <!-- business street 1 label, input field and message -->
+ <component jsfid="businessStreet1Label" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessStreet1" />
+ </attributes>
+ </component>
+ <component jsfid="businessStreet1" extends="inputText" id="businessStreet1">
+ <attributes>
+ <set name="value" value="#{managed-bean-name.selectedContact.businessAddress.street1}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="businessStreet1Message" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessStreet1" />
+ </attributes>
+ </component>
+
+
+ <!-- residential street 2 label, input field and message -->
+ <component jsfid="residentialStreet2Label" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="residentialStreet2" />
+ </attributes>
+ </component>
+ <component jsfid="residentialStreet2" extends="inputText" id="residentialStreet2">
+ <attributes>
+ <set name="value" value="#{managed-bean-name.selectedContact.residentialAddress.street2}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="residentialStreet2Message" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="residentialStreet2" />
+ </attributes>
+ </component>
+
+ <!-- business street 2 label, input field and message -->
+ <component jsfid="businessStreet2Label" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessStreet2" />
+ </attributes>
+ </component>
+ <component jsfid="businessStreet2" extends="inputText" id="businessStreet2">
+ <attributes>
+ <set name="value" value="#{managed-bean-name.selectedContact.businessAddress.street2}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="businessStreet2Message" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessStreet2" />
+ </attributes>
+ </component>
+
+
+ <!-- residential state label, input field and message -->
+ <component jsfid="residentialStateLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="residentialState" />
+ </attributes>
+ </component>
+ <component jsfid="residentialState" extends="selectOneMenu" id="residentialState" allowBody="false">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.residentialAddress.state}" />
+ <set name="required" value="true" />
+ </attributes>
+
+ <element renderId="0" jsfid="selectItems">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{rolodexDao.states}" />
+ </attributes>
+ </element>
+ </component>
+ <component jsfid="residentialStateMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="residentialState" />
+ </attributes>
+ </component>
+
+
+ <!-- business state label, input field and message -->
+ <component jsfid="businessStateLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessState" />
+ </attributes>
+ </component>
+ <component jsfid="businessState" extends="selectOneMenu" id="businessState" allowBody="false">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessAddress.state}" />
+ <set name="required" value="true" />
+ </attributes>
+
+ <element renderId="0" jsfid="selectItems">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{rolodexDao.states}" />
+ </attributes>
+ </element>
+ </component>
+ <component jsfid="businessStateMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessState" />
+ </attributes>
+ </component>
+
+
+ <!-- residential zip code label, input field and message -->
+ <component jsfid="residentialZipLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="residentialZip" />
+ </attributes>
+ </component>
+ <component jsfid="residentialZip" id="residentialZip" extends="inputText">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.residentialAddress.zip}" />
+ </attributes>
+ <converter jsfid="integerConverter" />
+ </component>
+ <component jsfid="residentialZipMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="residentialZip" />
+ </attributes>
+ </component>
+
+ <!-- business zip code label, input field and message -->
+ <component jsfid="businessZipLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessZip" />
+ </attributes>
+ </component>
+ <component jsfid="businessZip" id="businessZip" extends="inputText">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessAddress.zip}" />
+ </attributes>
+ <converter jsfid="integerConverter" />
+ </component>
+ <component jsfid="businessZipMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessZip" />
+ </attributes>
+ </component>
+
+
+
+ <!-- Contact residential Phone -->
+ <component jsfid="contactResidentialPhoneLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="contactResidentialPhone" />
+ </attributes>
+ </component>
+ <component jsfid="contactResidentialPhone" extends="inputText" id="contactResidentialPhone">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.residentialPhone}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="contactResidentialPhoneMessage" extends="message" allowBody="false" >
+ <attributes>
+ <set name="for" value="contactResidentialPhone" />
+ </attributes>
+ </component>
+
+ <!-- Contact business Phone -->
+ <component jsfid="contactBusinessPhoneLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="contactBusinessPhone" />
+ </attributes>
+ </component>
+ <component jsfid="contactBusinessPhone" extends="inputText" id="contactBusinessPhone">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessPhone}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="contactBusinessPhoneMessage" extends="message" allowBody="false" >
+ <attributes>
+ <set name="for" value="contactBusinessPhone" />
+ </attributes>
+ </component>
+
+
+ <!-- business province label, input field and message -->
+ <component jsfid="businessProvinceLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessProvince" />
+ </attributes>
+ </component>
+ <component jsfid="businessProvince" extends="inputText" id="businessProvince">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessAddress.province}" />
+ <set name="required" value="false" />
+ </attributes>
+ </component>
+ <component jsfid="businessProvinceMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessProvince" />
+ </attributes>
+ </component>
+
+
+ <!-- business country label, input field and message -->
+ <component jsfid="businessCountryLabel" extends="outputLabel" allowBody="true">
+ <attributes>
+ <set name="for" value="businessCountry" />
+ </attributes>
+ </component>
+ <component jsfid="businessCountry" extends="selectOneMenu" id="businessCountry" allowBody="false">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{managed-bean-name.selectedContact.businessAddress.country}" />
+ <set name="required" value="true" />
+ </attributes>
+
+ <element renderId="0" jsfid="selectItems">
+ <attributes>
+ <set name="value" useValueLateBinding="true" value="#{rolodexDao.countries}" />
+ </attributes>
+ </element>
+ </component>
+ <component jsfid="businessCountryMessage" extends="message" allowBody="false">
+ <attributes>
+ <set name="for" value="businessCountry" />
+ </attributes>
+ </component>
+
+
</view>
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=219287&r1=219286&r2=219287&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 Fri Jul 15 21:37:46 2005
@@ -268,15 +268,59 @@
<to-view-id>/usecases.jsp</to-view-id>
</navigation-case>
+ <!-- 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>
+ <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>
+
+ <!-- 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-rule>
<navigation-rule>
@@ -507,6 +551,17 @@
View controller for the rolodex usecase
</description>
<managed-bean-name>rolodex</managed-bean-name>
+ <managed-bean-class>
+ org.apache.shale.usecases.rolodex.Rolodex
+ </managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
+
+ <managed-bean>
+ <description>
+ View controller for the rolodex usecase
+ </description>
+ <managed-bean-name>rolodex$hrolodex</managed-bean-name>
<managed-bean-class>
org.apache.shale.usecases.rolodex.Rolodex
</managed-bean-class>
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=219287&r1=219286&r2=219287&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 Fri Jul 15 21:37:46 2005
@@ -119,6 +119,12 @@
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
+ <!-- JavaServer Faces Servlet Mapping for Clay HTML Full View -->
+ <servlet-mapping>
+ <servlet-name>faces</servlet-name>
+ <url-pattern>*.html</url-pattern>
+ </servlet-mapping>
+
<!-- Welcome File List -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
Added: struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html?rev=219287&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html (added)
+++ struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html Fri Jul 15 21:37:46 2005
@@ -0,0 +1,272 @@
+<html>
+<head>
+<title>Rolodex Example Using Clay HTML Full-view Composition</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<style type="text/css" media="screen">
+body {
+ margin : 10px;
+ font: Verdana, Helvetica, Arial;
+ padding: 0px;
+ background: #fff;
+}
+
+#menu {
+ border-bottom : 1px solid #ccc;
+ margin : 0;
+ padding-bottom : 19px;
+ padding-left : 10px;
+}
+
+#menu ul, #menu li {
+ display : inline;
+ list-style-type : none;
+ margin : 0;
+ padding : 0;
+}
+
+
+#menu a:link, #menu a:visited {
+ background : #E8EBF0;
+ border : 1px solid #ccc;
+ color : #666;
+ float : left;
+ font-size : small;
+ font-weight : normal;
+ line-height : 14px;
+ margin-right : 8px;
+ padding : 2px 10px 2px 10px;
+ text-decoration : none;
+}
+
+#menu a:link.active, #menu a:visited.active {
+ background : #fff;
+ border-bottom : 1px solid #fff;
+ color : #000;
+}
+
+#menu a:hover {
+ color : #f00;
+}
+
+.contacts {
+ border: 1px solid #fff;
+}
+
+.contactsHeader {
+ text-align: center;
+ color: #99CC66;
+ background: #E5F2D9;
+}
+
+.contactsRow2 {
+ text-align: left;
+ color: #99CC66;
+ background: #D9EEF2;
+}
+
+.contactsRow1 {
+ text-align: left;
+ color: #99CC66;
+ background: #F1F7D4;
+}
+
+body.section-1 #menu li#nav-sel a {
+ background : #fff;
+ border-bottom : 1px solid #fff;
+ color : #000;
+}
+
+li#nav {
+ background : #red;
+ border-bottom : 1px solid #000;
+ color : #000;
+}
+
+#menu ul a:hover {
+ color : #f00 !important;
+}
+
+#contents {
+ background : #fff;
+ border : 1px solid #ccc;
+ border-top : none;
+ clear : both;
+ margin : 0px;
+ padding : 15px;
+}
+
+input.button {
+ width: 1in;
+ text-align: center;
+ color: #99CC66;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: bold
+}
+</style>
+</head>
+<body class="section-1">
+<form>
+<span jsfid="tabs">
+<ul id="menu">
+ <li id="nav"><a href="#">Tab 1</a></li>
+ <li id="nav-sel"><a href="#">Tab 2</a></li>
+ <li id="nav"><a href="#">Tab 3</a></li>
+</ul>
+</span>
+<div id="contents">
+<table border="0">
+ <tr>
+ <td rowspan="3">
+ <span jsfid="contactTable">
+ <table class="contacts">
+ <tr class="contactsHeader">
+ <td>
+ Contacts
+ </td>
+ </tr>
+ <tr class="contactsRow1">
+ <td>
+ <a href="#">ABC Company</a>
+ </td>
+ </tr>
+ <tr class="contactsRow2">
+ <td>
+ <a href="#">XYZ Company</a>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border="0">
+ <tr>
+ <td><label style="color:#99CC66" jsfid="contactNameLabel">Name:</label></td>
+ <td><input jsfid="contactName" type=text size="40" maxlength="50"></td>
+ <td><span style="color:red" jsfid="contactNameMessage">Mock Error Name</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="contactEmailLabel">Email:</label></td>
+ <td><input jsfid="contactEmail" type=text size="30" maxlength="50"></td>
+ <td><span style="color:red" jsfid="contactEmailMessage">Mock Error Email</span></td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <input styleClass="button" class="button" class="button" type="submit" value="Save Contact" jsfid="contactSaveCommand"><br>
+ <input styleClass="button" class="button" type="submit" value="Delete Contact" jsfid="contactDeleteCommand"><br>
+ <input styleClass="button" class="button" type="submit" value="New Contact" jsfid="contactNewCommand"><br>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table border=0>
+ <tr class="contactsHeader">
+ <td colspan="3">Residential Address:</td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid=residentialStreet1Label>Address 1:</label></td>
+ <td><input jsfid="residentialStreet1" type=text size="35" maxlength="50"></td>
+ <td><span style="color:red" jsfid="residentialStreet1Message">Mock Error Address 1</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid=residentialStreet2Label>Address 2:</label></td>
+ <td><input jsfid="residentialStreet2" type=text size="35" maxlength="50"></td>
+ <td><span style="color:red" jsfid="residentialStreet2Message">Mock Error Address 2</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="residentialCityLabel">City:</label></td>
+ <td><input jsfid="residentialCity" type=text size="20" maxlength="30"></td>
+ <td><span style="color:red" jsfid="residentialCityMessage">Mock Error City</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="residentialStateLabel">State:</label></td>
+ <td><select jsfid="residentialState">
+ <option>Mock State 1
+ <option>Mock State 2
+ </select>
+ </td>
+ <td><span style="color:red" jsfid="residentialStateMessage">Mock Error State</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="residentialZipLabel">Zip:</label></td>
+ <td><input jsfid="residentialZip" type=text size="5" maxlength="9"/></td>
+ <td><span style="color:red" jsfid="residentialZipMessage">Mock Error Zip</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="contactResidentialPhoneLabel">Phone:</label></td>
+ <td><input jsfid="contactResidentialPhone" type=text size="20" maxlength="50"/></td>
+ <td><span style="color:red" jsfid="contactResidentialPhoneMessage">Mock Error Phone</span></td>
+ </tr>
+ <tr>
+ <td colspan="2"> </td>
+ </tr>
+ <tr>
+ <td colspan="2"> </td>
+ </tr>
+ </table>
+ </td>
+ <td>
+ <table border=0>
+ <tr class="contactsHeader">
+ <td colspan="3">Business Address:</td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid=businessStreet1Label>Address 1:</label></td>
+ <td><input jsfid="businessStreet1" type=text size="35" maxlength="50"></td>
+ <td><span style="color:red" jsfid="businessStreet1Message">Mock Error Address 1</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid=businessStreet2Label>Address 2:</label></td>
+ <td><input jsfid="businessStreet2" type=text size="35" maxlength="50"></td>
+ <td><span style="color:red" jsfid="businessStreet2Message">Mock Error Address 2</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="businessCityLabel">City:</label></td>
+ <td><input jsfid="businessCity" type=text size="20" maxlength="30"></td>
+ <td><span style="color:red" jsfid="businessCityMessage">Mock Error City</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="businessStateLabel">State:</label></td>
+ <td><select jsfid="businessState">
+ <option>Mock State 1
+ <option>Mock State 2
+ </select>
+ </td>
+ <td><span style="color:red" jsfid="businessStateMessage">Mock Error State</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="businessProvinceLabel">Province:</label></td>
+ <td><input jsfid="businessProvince" type=text size="20" maxlength="30"></td>
+ <td><span style="color:red" jsfid="businessProvinceMessage">Mock Error Province</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="businessZipLabel">Zip:</label></td>
+ <td><input jsfid="businessZip" type=text size="5" maxlength="9"/></td>
+ <td><span style="color:red" jsfid="businessZipMessage">Mock Error Zip</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="businessCountryLabel">Country:</label></td>
+ <td><select jsfid="businessCountry">
+ <option>Mock Country 1
+ <option>Mock Country 2
+ </select>
+ </td>
+ <td><span jsfid="businessCountryMessage">Mock Error Country</span></td>
+ </tr>
+ <tr>
+ <td><label style="color:#99CC66" jsfid="contactBusinessPhoneLabel">Phone:</label></td>
+ <td><input jsfid="contactBusinessPhone" type="text" size="20" maxlength="50"/></td>
+ <td><span style="color:red" jsfid="contactBusinessPhoneMessage">Mock Error Phone</span></td>
+ </tr>
+ </table>
+ </td>
+ <tr>
+</table>
+</div>
+</form>
+</body>
+</html>
\ 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=219287&r1=219286&r2=219287&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/usecases.jsp (original)
+++ struts/shale/trunk/use-cases/src/web/usecases.jsp Fri Jul 15 21:37:46 2005
@@ -5,7 +5,7 @@
<%--
- Copyright 2004-2005 The Apache Software Foundation.
+ 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.
@@ -109,27 +109,10 @@
</h:panelGrid>
- <h1><h:outputText value="#{messages['usecases.ajax']}"/></h1>
-
- <h:panelGrid columns="1">
-
- <h:commandLink id="ajaxCodeCompletion"
- action="ajax$completion">
- <h:outputText value="#{messages['usecases.completion']}"/>
- </h:commandLink>
-
- </h:panelGrid>
-
<h1><h:outputText value="#{messages['usecases.java']}"/></h1>
<h:panelGrid columns="1">
- <h:outputLink id="javaStateNames"
- value="list/stateNames.remote"
- target="_new">
- <h:outputText value="#{messages['usecases.states']}"/>
- </h:outputLink>
-
<h:outputLink id="javaCategories"
value="list/supportedCategories.remote"
target="_new">
@@ -175,9 +158,15 @@
<h1><h:outputText value="#{messages['usecases.clay']}"/></h1>
<h:panelGrid columns="1">
- <h:commandLink id="rolodex"
- action="rolodex$test">
- <h:outputText value="#{messages['usecases.rolodex']}"/>
+ <h:commandLink id="rolodex1"
+ action="rolodex$test1">
+ <h:outputText value="#{messages['usecases.rolodex1']}"/>
+
+ </h:commandLink>
+
+ <h:commandLink id="rolodex2"
+ action="rolodex$test2">
+ <h:outputText value="#{messages['usecases.rolodex2']}"/>
</h:commandLink>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org