You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/05/05 01:03:42 UTC
cvs commit: jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/mock/app PrivateAssetTemplate.page
hlship 2005/05/04 16:03:42
Modified: portlet/src/java/org/apache/tapestry/portlet
PortletConstants.java PortletMessages.java
PortletStrings.properties
PortletConfigStrategy.java
framework/src/java/org/apache/tapestry/html Shell.jwc
portlet/src/descriptor/META-INF
tapestry.portlet.services.xml hivemodule.xml
framework/src/documentation/content/xdocs/tapestry/ComponentReference
Shell.xml FieldLabel.xml
framework/src/java/org/apache/tapestry/valid FieldLabel.jwc
framework/src/java/org/apache/tapestry/util/exception
ExceptionAnalyzer.java
framework/src/test/org/apache/tapestry/junit/mock/lib
Border.jwc
framework/src/test/org/apache/tapestry/junit/mock/app
PrivateAssetTemplate.page
Added: portlet/src/java/org/apache/tapestry/portlet
PortletExceptionPresenter.java
ExceptionService.java
Removed: doc/src/ComponentReference Shell.html FieldLabel.html
Insert.html
Log:
Add support for exception reporting inside the Portlet action or render requests.
Revision Changes Path
1.3 +14 -1 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletConstants.java
Index: PortletConstants.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletConstants.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PortletConstants.java 18 Apr 2005 17:08:37 -0000 1.2
+++ PortletConstants.java 4 May 2005 23:03:42 -0000 1.3
@@ -22,10 +22,23 @@
{
/**
* Name of the render service, whose job is to render a page. The page to render is identified
- * in the {@link org.apache.tapestry.services.ServiceConstants#PAGE}parameter.
+ * in the {@link org.apache.tapestry.services.ServiceConstants#PAGE} parameter.
*/
public static final String RENDER_SERVICE = "render";
+ /**
+ * Name of the exception service, which renders stored exception markup.
+ */
+
+ public static final String EXCEPTION_SERVICE = "exception";
+
+ /**
+ * Session attribute key used to store markup generated during an action request, so that it can
+ * be displayed during a later render request.
+ */
+
+ public static final String PORTLET_EXCEPTION_MARKUP_ATTRIBUTE = "org.apache.tapestry.portlet.PortletExceptionMarkup";
+
private PortletConstants()
{
// Prevent instantiation
1.5 +9 -4 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletMessages.java
Index: PortletMessages.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletMessages.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- PortletMessages.java 18 Apr 2005 17:08:37 -0000 1.4
+++ PortletMessages.java 4 May 2005 23:03:42 -0000 1.5
@@ -27,23 +27,28 @@
private static final MessageFormatter _formatter = new MessageFormatter(PortletMessages.class,
"PortletStrings");
- public static String unsupportedMethod(String methodName)
+ static String unsupportedMethod(String methodName)
{
return _formatter.format("unsupported-method", methodName);
}
- public static String errorGettingResource(String path, Throwable cause)
+ static String errorGettingResource(String path, Throwable cause)
{
return _formatter.format("error-getting-resource", path, cause);
}
- public static String errorProcessingAction(Throwable cause)
+ static String errorProcessingAction(Throwable cause)
{
return _formatter.format("error-processing-action", cause);
}
- public static String errorProcessingRender(Throwable cause)
+ static String errorProcessingRender(Throwable cause)
{
return _formatter.format("error-processing-render", cause);
}
+
+ static String errorReportingException(Throwable cause)
+ {
+ return _formatter.format("error-reporting-exception", cause);
+ }
}
\ No newline at end of file
1.4 +2 -1 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletStrings.properties
Index: PortletStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletStrings.properties,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- PortletStrings.properties 18 Mar 2005 23:43:19 -0000 1.3
+++ PortletStrings.properties 4 May 2005 23:03:42 -0000 1.4
@@ -15,4 +15,5 @@
unsupported-method=Method {0}() is not supported for portlet requests.
error-getting-resource=Error getting portlet context resource ''{0}'': {1}
error-processing-action=Error processing action request: {0}
-error-processing-render=Error processing render request: {0}
\ No newline at end of file
+error-processing-render=Error processing render request: {0}
+error-reporting-exception=Error producing exception report: {0}
\ No newline at end of file
1.3 +14 -0 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletConfigStrategy.java
Index: PortletConfigStrategy.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletConfigStrategy.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PortletConfigStrategy.java 18 Apr 2005 17:08:38 -0000 1.2
+++ PortletConfigStrategy.java 4 May 2005 23:03:42 -0000 1.3
@@ -1,3 +1,17 @@
+// 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.
+
package org.apache.tapestry.portlet;
import java.util.Iterator;
1.1 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/PortletExceptionPresenter.java
Index: PortletExceptionPresenter.java
===================================================================
// 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.
package org.apache.tapestry.portlet;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.ActionResponse;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.describe.RenderStrategy;
import org.apache.tapestry.error.ErrorMessages;
import org.apache.tapestry.error.ExceptionPresenter;
import org.apache.tapestry.error.RequestExceptionReporter;
import org.apache.tapestry.markup.AsciiMarkupFilter;
import org.apache.tapestry.markup.MarkupWriterImpl;
import org.apache.tapestry.services.ServiceConstants;
import org.apache.tapestry.util.ContentType;
import org.apache.tapestry.util.exception.ExceptionAnalyzer;
import org.apache.tapestry.util.exception.ExceptionDescription;
import org.apache.tapestry.util.exception.ExceptionProperty;
import org.apache.tapestry.web.WebRequest;
import org.apache.tapestry.web.WebResponse;
/**
* Service used to present a runtime exception to the user. This is very tricky in the Portlet world
* because of the split between the action and render requests (much more likely to get an error
* during the action request than during the render request, but both are possible).
* <p>
* During an action request, this code will render the HTML markup for the exception into a buffer
* that is stored as persistent attribute in the portal session.
*
* @author Howard M. Lewis Ship
* @since 4.0
*/
public class PortletExceptionPresenter implements ExceptionPresenter
{
private PortletRequestGlobals _globals;
private RenderStrategy _renderStrategy;
private WebRequest _request;
private RequestExceptionReporter _requestExceptionReporter;
private WebResponse _response;
public void presentException(IRequestCycle cycle, Throwable cause)
{
try
{
if (_globals.isRenderRequest())
reportRenderRequestException(cycle, cause);
else
reportActionRequestException(cycle, cause);
}
catch (Exception ex)
{
// Worst case scenario. The exception page itself is broken, leaving
// us with no option but to write the cause to the output.
// Also, write the exception thrown when redendering the exception
// page, so that can get fixed as well.
_requestExceptionReporter.reportRequestException(PortletMessages
.errorReportingException(ex), ex);
// And throw the exception.
throw new ApplicationRuntimeException(ex.getMessage(), ex);
}
_requestExceptionReporter.reportRequestException(ErrorMessages
.unableToProcessClientRequest(cause), cause);
}
private void reportActionRequestException(IRequestCycle cycle, Throwable cause)
{
CharArrayWriter caw = new CharArrayWriter();
PrintWriter pw = new PrintWriter(caw);
IMarkupWriter writer = new MarkupWriterImpl("text/html", pw, new AsciiMarkupFilter());
writeException(writer, cycle, cause);
writer.close();
String markup = caw.toString();
_request.getSession(true).setAttribute(
PortletConstants.PORTLET_EXCEPTION_MARKUP_ATTRIBUTE,
markup);
ActionResponse response = _globals.getActionResponse();
response.setRenderParameter(ServiceConstants.SERVICE, PortletConstants.EXCEPTION_SERVICE);
}
private void reportRenderRequestException(IRequestCycle cycle, Throwable cause)
throws IOException
{
PrintWriter pw = _response.getPrintWriter(new ContentType("text/html"));
IMarkupWriter writer = new MarkupWriterImpl("text/html", pw, new AsciiMarkupFilter());
writeException(writer, cycle, cause);
}
public void setGlobals(PortletRequestGlobals globals)
{
_globals = globals;
}
public void setRenderStrategy(RenderStrategy renderStrategy)
{
_renderStrategy = renderStrategy;
}
public void setRequest(WebRequest request)
{
_request = request;
}
public void setRequestExceptionReporter(RequestExceptionReporter requestExceptionReporter)
{
_requestExceptionReporter = requestExceptionReporter;
}
public void setResponse(WebResponse response)
{
_response = response;
}
private void writeException(IMarkupWriter writer, IRequestCycle cycle,
ExceptionDescription exception, boolean showStackTrace)
{
writer.begin("div");
writer.attribute("class", "portlet-section-header");
writer.print(exception.getExceptionClassName());
writer.end();
writer.println();
writer.begin("div");
writer.attribute("class", "portlet-msg-error");
writer.print(exception.getMessage());
writer.end();
writer.println();
ExceptionProperty[] properties = exception.getProperties();
if (properties.length > 0)
{
writer.begin("table");
writer.attribute("class", "portlet-section-subheader");
for (int i = 0; i < properties.length; i++)
{
writer.begin("tr");
writer.attribute("class", i % 2 == 0 ? "portlet-section-body"
: "portlet-section-alternate");
writer.begin("th");
writer.print(properties[i].getName());
writer.end();
writer.println();
writer.begin("td");
_renderStrategy.renderObject(properties[i].getValue(), writer, cycle);
writer.end("tr");
writer.println();
}
writer.end();
writer.println();
}
if (!showStackTrace)
return;
writer.begin("ul");
String[] trace = exception.getStackTrace();
for (int i = 0; i < trace.length; i++)
{
writer.begin("li");
writer.print(trace[i]);
writer.end();
writer.println();
}
writer.end();
writer.println();
}
private void writeException(IMarkupWriter writer, IRequestCycle cycle, Throwable cause)
{
ExceptionDescription[] exceptions = new ExceptionAnalyzer().analyze(cause);
for (int i = 0; i < exceptions.length; i++)
writeException(writer, cycle, exceptions[i], i + 1 == exceptions.length);
}
}
1.1 jakarta-tapestry/portlet/src/java/org/apache/tapestry/portlet/ExceptionService.java
Index: ExceptionService.java
===================================================================
// 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.
package org.apache.tapestry.portlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.PortletURL;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.util.ContentType;
import org.apache.tapestry.web.WebRequest;
import org.apache.tapestry.web.WebResponse;
import org.apache.tapestry.web.WebSession;
/**
* @author Howard M. Lewis Ship
* @since 4.0
* @see org.apache.tapestry.portlet.PortletConstants#PORTLET_EXCEPTION_MARKUP_ATTRIBUTE
*/
public class ExceptionService implements IEngineService
{
private WebRequest _request;
private WebResponse _response;
private PortletRequestGlobals _globals;
public ILink getLink(IRequestCycle cycle, Object parameter)
{
throw new UnsupportedOperationException(PortletMessages.unsupportedMethod("getLink"));
}
public void service(IRequestCycle cycle) throws IOException
{
WebSession session = _request.getSession(true);
String markup = (String) session
.getAttribute(PortletConstants.PORTLET_EXCEPTION_MARKUP_ATTRIBUTE);
PrintWriter writer = _response.getPrintWriter(new ContentType("text/html"));
PortletURL url = _globals.getRenderResponse().createActionURL();
writer.println("<span class=\"portlet-msg-error\">An exception has occured.</span>");
writer.println("<br/>");
writer.println("<a href=\"" + url.toString() + "\">Click here to continue</a>");
writer.print("<br/><hr/>");
writer.println();
writer.print(markup);
}
public String getName()
{
return PortletConstants.EXCEPTION_SERVICE;
}
public void setRequest(WebRequest request)
{
_request = request;
}
public void setResponse(WebResponse response)
{
_response = response;
}
public void setGlobals(PortletRequestGlobals globals)
{
_globals = globals;
}
}
1.9 +7 -2 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Shell.jwc
Index: Shell.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Shell.jwc,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Shell.jwc 18 Apr 2005 17:06:41 -0000 1.8
+++ Shell.jwc 4 May 2005 23:03:42 -0000 1.9
@@ -26,6 +26,7 @@
</description>
<parameter name="title"
+ default-binding="literal"
required="yes">
<description>
The title for the page.
@@ -45,6 +46,7 @@
</parameter>
<parameter name="doctype"
+ default-binding="literal"
default-value='HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"'>
<description>
Used to specify the full definition of the DOCTYPE element in the response page,
@@ -61,6 +63,7 @@
<parameter
name="renderContentType"
+ default-binding="ognl"
default-value="true">
<description>
Determines whether to render an http-equiv element with the Content Type of this response.
@@ -68,14 +71,16 @@
</parameter>
<parameter
- name="refresh">
+ name="refresh"
+ default-binding="ognl">
<description>
If specified, the page will refresh itself after the specified delay (in seconds).
</description>
</parameter>
<parameter
- name="delegate">
+ name="delegate"
+ default-binding="ognl">
<description>
If specified, the delegate is rendered before the close of the <head>
tag (typically used to provide <meta> tags).
1.10 +16 -1 jakarta-tapestry/portlet/src/descriptor/META-INF/tapestry.portlet.services.xml
Index: tapestry.portlet.services.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/descriptor/META-INF/tapestry.portlet.services.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- tapestry.portlet.services.xml 29 Apr 2005 14:46:14 -0000 1.9
+++ tapestry.portlet.services.xml 4 May 2005 23:03:42 -0000 1.10
@@ -35,12 +35,27 @@
<service name="restart" object="service:tapestry.services.Restart"/>
<service name="asset" object="service:PortletAsset"/>
<service name="external" object="service:tapestry.services.External"/>
+ <service name="exception" object="service:Exception"/>
<!-- Special one used for handling Portal RenderRequests -->
<service name="render" object="service:Render"/>
</contribution>
+ <service-point id="Exception" interface="org.apache.tapestry.engine.IEngineService">
+
+ Renders a pre-generated exception, stored in the session.
+
+ <invoke-factory model="primitive">
+ <construct class="ExceptionService">
+ <set-object property="request" value="infrastructure:request"/>
+ <set-object property="response" value="infrastructure:response"/>
+ <set-service property="globals" service-id="tapestry.portlet.PortletRequestGlobals"/>
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
<service-point id="PortletAsset" interface="org.apache.tapestry.engine.IEngineService">
Specially wired version of the asset service that routes through the application servlet
@@ -115,4 +130,4 @@
<contribution configuration-id="hivemind.FactoryDefaults">
<default symbol="org.apache.tapestry.portlet.home-page" value="View"/>
</contribution>
-</module>
\ No newline at end of file
+</module>
1.12 +20 -0 jakarta-tapestry/portlet/src/descriptor/META-INF/hivemodule.xml
Index: hivemodule.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/portlet/src/descriptor/META-INF/hivemodule.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- hivemodule.xml 18 Apr 2005 17:08:38 -0000 1.11
+++ hivemodule.xml 4 May 2005 23:03:42 -0000 1.12
@@ -209,6 +209,7 @@
<contribution configuration-id="tapestry.Infrastructure">
<property name="linkFactory" mode="portlet" object="service:PortletLinkFactory"/>
<property name="HTMLDescriber" mode="portlet" object="service:PortletHTMLDescriber"/>
+ <property name="exceptionPresenter" mode="portlet" object="service:PortletExceptionPresenter" />
</contribution>
<contribution configuration-id="PortletApplicationInitializers">
@@ -229,6 +230,25 @@
</invoke-factory>
</service-point>
+ <service-point id="PortletExceptionPresenter" interface="org.apache.tapestry.error.ExceptionPresenter">
+
+ Displays stack trace and other information when a runtime exception is thrown.
+ If the exception occurs during an action request, the markup rendered and stored
+ in the session until a later render request (using the exception service).
+
+ <invoke-factory>
+ <construct class="PortletExceptionPresenter">
+ <set-service property="globals" service-id="PortletRequestGlobals"/>
+ <set-object property="request" value="infrastructure:request"/>
+ <set-object property="response" value="infrastructure:response"/>
+ <set-object property="requestExceptionReporter"
+ value="infrastructure:requestExceptionReporter"/>
+ <set-object property="renderStrategy" value="service:tapestry.describe.RenderStrategy"/>
+ </construct>
+ </invoke-factory>
+
+ </service-point>
+
<contribution configuration-id="tapestry.describe.DescribableStrategies">
<strategy class="javax.portlet.PortletSession" object="instance:PortletSessionDescribableStrategy"/>
<strategy class="javax.portlet.PortletConfig" object="instance:PortletConfigStrategy"/>
1.5 +18 -10 jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/Shell.xml
Index: Shell.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/Shell.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Shell.xml 18 Apr 2005 17:07:54 -0000 1.4
+++ Shell.xml 4 May 2005 23:03:42 -0000 1.5
@@ -36,8 +36,8 @@
provided by a &Body; component).
</p>
<p>
- Most Tapestry pages will include a Shell component followed by a Body
- component. The Shell is used to resolve the page's HTML stylesheet and the Body
+ Most Tapestry pages will include a Shell component enclosing a &Body;
+ component. The Shell is used to resolve the page's HTML stylesheet and the &Body;
component manages dynamically generated JavaScript.
</p>
<p>
@@ -61,6 +61,7 @@
<th>Direction</th>
<th>Required</th>
<th>Default</th>
+ <th>Default Binding</th>
<th>Description</th>
</tr>
@@ -69,7 +70,8 @@
<td>String</td>
<td>in</td>
<td>yes</td>
- <td></td>
+ <td> </td>
+ <td>literal</td>
<td>The title for the page, used to render the <title> tag.</td>
</tr>
@@ -78,7 +80,8 @@
<td>&IAsset;</td>
<td>in</td>
<td>no</td>
- <td></td>
+ <td> </td>
+ <td>asset</td>
<td>If provided, then a <link> to the stylesheet is generated.</td>
</tr>
@@ -87,7 +90,8 @@
<td>Array or collection of &IAsset;</td>
<td>in</td>
<td>no</td>
- <td></td>
+ <td> </td>
+ <td>ognl</td>
<td>
If provided, then <link> elements are created for each stylesheet asset.
</td>
@@ -99,6 +103,7 @@
<td>in</td>
<td>no</td>
<td>HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"</td>
+ <td>literal</td>
<td>Used to specify the full definition of the DOCTYPE element in the response page.</td>
</tr>
@@ -108,7 +113,8 @@
<td>in</td>
<td>no</td>
<td>true</td>
- <td>If true (the default), then an &meta; tag will be written to set the content
+ <td>ognl</td>
+ <td>If true (the default), then a &meta; tag will be written to set the content
type of the page.</td>
</tr>
@@ -117,7 +123,8 @@
<td>int</td>
<td>in</td>
<td>no</td>
- <td></td>
+ <td> </td>
+ <td>ognl</td>
<td>If provided, then a &meta; tag will be written to cause a page refresh. The parameter value is
the number of seconds before the refresh.</td>
</tr>
@@ -127,7 +134,8 @@
<td>&IRender;</td>
<td>in</td>
<td>no</td>
- <td></td>
+ <td> </td>
+ <td>ognl</td>
<td>If specified, the delegate is rendered before the close of the <head>
tag. Typically, this is used to provide additional &meta; tags.</td>
</tr>
@@ -196,7 +204,7 @@
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
-<page-specification class="com.mycorp.web.Login">
+<page-specification>
. . .
@@ -208,7 +216,7 @@
<p>
Note that for page and component specifications stored in the web application context (even under WEB-INF),
-relative assets paths are computed from the <em>root application context directory</em>.
+relative asset paths are computed from the <em>root application context directory</em>.
</p>
</section>
1.3 +80 -4 jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/FieldLabel.xml
Index: FieldLabel.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/documentation/content/xdocs/tapestry/ComponentReference/FieldLabel.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- FieldLabel.xml 6 Jan 2005 02:17:15 -0000 1.2
+++ FieldLabel.xml 4 May 2005 23:03:42 -0000 1.3
@@ -28,11 +28,20 @@
<body>
-<p> <strong>THIS PAGE UNDER CONSTRUCTION</strong>
+<p> A FieldLabel works with a &ValidField; or other form element component (such as &TextField;, &TextArea;,
+ &Checkbox;, etc.), labeling the field with the <code>displayName</code> property of the field. The FieldLabel
+ may also be <em>decorated</em> by the validation delegate (to highlight when the corresponding field
+ is in error).
</p>
<p>
- <strong>See also:</strong>
+ The body of the component is discarded, but often has a provisional label (for WYSIWYG). The actual value
+ is typically provided by the field (so that it may be localized just once).
+</p>
+
+<p>
+ <strong>See also: <link href="&apiroot;/valid/FieldLabel.html">org.apache.tapestry.valid.FieldLabel</link>,
+ &IValidationDelegate;</strong>
</p>
<section>
@@ -45,17 +54,59 @@
<th>Direction</th>
<th>Required</th>
<th>Default</th>
+ <th>Default Binding</th>
<th>Description</th>
</tr>
+
+ <tr>
+ <td>field</td>
+ <td>&IFormComponent;</td>
+ <td>in</td>
+ <td>yes</td>
+ <td> </td>
+ <td>component</td>
+ <td>
+ The component to be labeled. The component will be <em>pre-rendered</em> by the FieldLabel, and
+ its displayName property used as the label string (note that most form element components return null
+ for displayName).
+ </td>
+ </tr>
+
+ <tr>
+ <td>displayName</td>
+ <td>String</td>
+ <td>in</td>
+ <td>no</td>
+ <td> </td>
+ <td>literal</td>
+ <td>
+ Overrides the displayName provided by the component (if a &ValidField;), or supplies a displayName for components
+ (such as &TextField;, etc.) that don't provide one. A runtime exception occurs if displayName is null
+ and not supplied by the component.
+ </td>
+ </tr>
+
+ <tr>
+ <td>raw</td>
+ <td>boolean</td>
+ <td>in</td>
+ <td>no</td>
+ <td>false</td>
+ <td> </td>
+ <td>
+ If true, then the displayName is printed "raw" (without filtering), which is appropriate when
+ the displayName includes markup text.
+ </td>
+ </tr>
</table>
<p>
- Body: <strong>removed / allowed</strong>
+ Body: <strong>removed</strong>
</p>
<p>
- Informal parameters: <strong>allowed / forbidden</strong>
+ Informal parameters: <strong>forbidden</strong>
</p>
<p>
@@ -67,6 +118,31 @@
<section>
<title>Examples</title>
+<p>
+FieldLabel components are simple, and generally expressed entirely in the HTML template. Here we see a
+&TextField; being labeled (and the displayName being provided as a FieldLabel parameter), and
+a &ValidField; being labeled (with the displayName being provided by the ValidField, from its parameter).
+</p>
+
+<source><![CDATA[
+<tr>
+ <th>
+ <span jwcid="@FieldLabel" field="textField" displayName="message:textfield-label">Text Field</span>:
+ </th>
+ <td>
+ <input jwcid="textField@TextField" . . . />
+ </td>
+</tr>
+<tr>
+ <th>
+ <span jwcid="@FieldLabel" field="validField">Valid Field</span>:
+ </th>
+ <td>
+ <input jwcid="validField@ValidField" displayName="message:validfield-label" . . . />
+ </td>
+</tr>
+]]></source>
+
</section>
</body>
</document>
\ No newline at end of file
1.6 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/FieldLabel.jwc
Index: FieldLabel.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/FieldLabel.jwc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- FieldLabel.jwc 18 Apr 2005 17:06:43 -0000 1.5
+++ FieldLabel.jwc 4 May 2005 23:03:42 -0000 1.6
@@ -24,7 +24,7 @@
allow-informal-parameters="no">
<description>
- Labels a ValidField.
+ Labels a ValidField of other form element component.
</description>
<parameter name="field" required="yes" default-binding="component"/>
1.5 +70 -95 jakarta-tapestry/framework/src/java/org/apache/tapestry/util/exception/ExceptionAnalyzer.java
Index: ExceptionAnalyzer.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/util/exception/ExceptionAnalyzer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ExceptionAnalyzer.java 7 Mar 2005 19:51:57 -0000 1.4
+++ ExceptionAnalyzer.java 4 May 2005 23:03:42 -0000 1.5
@@ -29,29 +29,25 @@
import java.util.List;
/**
- * Analyzes an exception, creating one or more
- * {@link ExceptionDescription}s
- * from it.
- *
- * @author Howard Lewis Ship
+ * Analyzes an exception, creating one or more {@link ExceptionDescription}s from it.
*
- **/
+ * @author Howard Lewis Ship
+ */
public class ExceptionAnalyzer
{
- private List exceptionDescriptions;
- private List propertyDescriptions;
- private CharArrayWriter writer;
+ private final List exceptionDescriptions = new ArrayList();
- private static final int LIST_SIZE = 3;
+ private final List propertyDescriptions = new ArrayList();
+
+ private final CharArrayWriter writer = new CharArrayWriter();
private boolean exhaustive = false;
/**
- * If true, then stack trace is extracted for each exception. If false,
- * the default, then stack trace is extracted for only the deepest exception.
- *
- **/
+ * If true, then stack trace is extracted for each exception. If false, the default, then stack
+ * trace is extracted for only the deepest exception.
+ */
public boolean isExhaustive()
{
@@ -64,54 +60,43 @@
}
/**
- * Analyzes the exceptions. This builds an {@link ExceptionDescription} for the
- * exception. It also looks for a non-null {@link Throwable}
- * property. If one exists, then a second {@link ExceptionDescription}
- * is created. This continues until no more nested exceptions can be found.
- *
- * <p>The description includes a set of name/value properties
- * (as {@link ExceptionProperty}) object. This list contains all
- * non-null properties that are not, themselves, {@link Throwable}.
- *
- * <p>The name is the display name (not the logical name) of the property. The value
- * is the <code>toString()</code> value of the property.
- *
- * Only properties defined in subclasses of {@link Throwable} are included.
- *
- * <p>A future enhancement will be to alphabetically sort the properties by name.
- **/
+ * Analyzes the exceptions. This builds an {@link ExceptionDescription}for the exception. It
+ * also looks for a non-null {@link Throwable}property. If one exists, then a second
+ * {@link ExceptionDescription}is created. This continues until no more nested exceptions can
+ * be found.
+ * <p>
+ * The description includes a set of name/value properties (as {@link ExceptionProperty})
+ * object. This list contains all non-null properties that are not, themselves,
+ * {@link Throwable}.
+ * <p>
+ * The name is the display name (not the logical name) of the property. The value is the
+ * <code>toString()</code> value of the property. Only properties defined in subclasses of
+ * {@link Throwable}are included.
+ * <p>
+ * A future enhancement will be to alphabetically sort the properties by name.
+ */
public ExceptionDescription[] analyze(Throwable exception)
{
- ExceptionDescription[] result;
-
- if (writer == null)
- writer = new CharArrayWriter();
-
- if (propertyDescriptions == null)
- propertyDescriptions = new ArrayList(LIST_SIZE);
-
- if (exceptionDescriptions == null)
- exceptionDescriptions = new ArrayList(LIST_SIZE);
-
- while (exception != null)
+ try
{
- exception = buildDescription(exception);
- }
- result = new ExceptionDescription[exceptionDescriptions.size()];
- result = (ExceptionDescription[]) exceptionDescriptions.toArray(result);
-
- exceptionDescriptions.clear();
- propertyDescriptions.clear();
+ while (exception != null)
+ {
+ exception = buildDescription(exception);
+ }
- writer.reset();
+ ExceptionDescription[] result = new ExceptionDescription[exceptionDescriptions.size()];
- // We never actually close() the writer which is bad ... I'm expecting that
- // the finalize() method will close them, or that they don't need to
- // close.
+ return (ExceptionDescription[]) exceptionDescriptions.toArray(result);
+ }
+ finally
+ {
+ exceptionDescriptions.clear();
+ propertyDescriptions.clear();
- return result;
+ writer.reset();
+ }
}
protected Throwable buildDescription(Throwable exception)
@@ -177,7 +162,7 @@
continue;
// Skip Throwables ... but the first non-null
- // found is the next exception. We kind of count
+ // found is the next exception. We kind of count
// on there being no more than one Throwable
// property per Exception.
@@ -209,14 +194,10 @@
properties = new ExceptionProperty[propertyDescriptions.size()];
- ExceptionProperty[] propArray =
- (ExceptionProperty[]) propertyDescriptions.toArray(properties);
+ ExceptionProperty[] propArray = (ExceptionProperty[]) propertyDescriptions
+ .toArray(properties);
- description =
- new ExceptionDescription(
- exceptionClass.getName(),
- message,
- propArray,
+ description = new ExceptionDescription(exceptionClass.getName(), message, propArray,
stackTrace);
exceptionDescriptions.add(description);
@@ -225,21 +206,17 @@
}
/**
- * Gets the stack trace for the exception, and converts it into an array of strings.
- *
- * <p>This involves parsing the
- * string generated indirectly from
- * <code>Throwable.printStackTrace(PrintWriter)</code>. This method can get confused
- * if the message (presumably, the first line emitted by printStackTrace())
- * spans multiple lines.
- *
- * <p>Different JVMs format the exception in different ways.
- *
- * <p>A possible expansion would be more flexibility in defining the pattern
- * used. Hopefully all 'mainstream' JVMs are close enough for this to continue
- * working.
- *
- **/
+ * Gets the stack trace for the exception, and converts it into an array of strings.
+ * <p>
+ * This involves parsing the string generated indirectly from
+ * <code>Throwable.printStackTrace(PrintWriter)</code>. This method can get confused if the
+ * message (presumably, the first line emitted by printStackTrace()) spans multiple lines.
+ * <p>
+ * Different JVMs format the exception in different ways.
+ * <p>
+ * A possible expansion would be more flexibility in defining the pattern used. Hopefully all
+ * 'mainstream' JVMs are close enough for this to continue working.
+ */
protected String[] getStackTrace(Throwable exception)
{
@@ -293,15 +270,15 @@
}
private static final int SKIP_LEADING_WHITESPACE = 0;
+
private static final int SKIP_T = 1;
+
private static final int SKIP_OTHER_WHITESPACE = 2;
/**
- * Sun's JVM prefixes each line in the stack trace
- * with "<tab>at ", other JVMs don't. This method
- * looks for and strips such stuff.
- *
- **/
+ * Sun's JVM prefixes each line in the stack trace with " <tab>at ", other JVMs don't. This
+ * method looks for and strips such stuff.
+ */
private String stripFrame(String frame)
{
@@ -313,7 +290,7 @@
while (more)
{
- // Ran out of characters to skip? Return the empty string.
+ // Ran out of characters to skip? Return the empty string.
if (i == array.length)
return "";
@@ -324,7 +301,7 @@
{
// Ignore whitespace at the start of the line.
- case SKIP_LEADING_WHITESPACE :
+ case SKIP_LEADING_WHITESPACE:
if (Character.isWhitespace(ch))
{
@@ -343,9 +320,9 @@
more = false;
break;
- // Skip over the 't' after an 'a'
+ // Skip over the 't' after an 'a'
- case SKIP_T :
+ case SKIP_T:
if (ch == 't')
{
@@ -360,9 +337,9 @@
more = false;
break;
- // Skip whitespace between 'at' and the name of the class
+ // Skip whitespace between 'at' and the name of the class
- case SKIP_OTHER_WHITESPACE :
+ case SKIP_OTHER_WHITESPACE:
if (Character.isWhitespace(ch))
{
@@ -386,9 +363,8 @@
}
/**
- * Produces a text based exception report to the provided stream.
- *
- **/
+ * Produces a text based exception report to the provided stream.
+ */
public void reportException(Throwable exception, PrintStream stream)
{
@@ -408,14 +384,13 @@
if (message == null)
stream.println(descriptions[i].getExceptionClassName());
else
- stream.println(
- descriptions[i].getExceptionClassName() + ": " + descriptions[i].getMessage());
+ stream.println(descriptions[i].getExceptionClassName() + ": "
+ + descriptions[i].getMessage());
properties = descriptions[i].getProperties();
for (j = 0; j < properties.length; j++)
- stream.println(
- " " + properties[j].getName() + ": " + properties[j].getValue());
+ stream.println(" " + properties[j].getName() + ": " + properties[j].getValue());
// Just show the stack trace on the deepest exception.
1.5 +1 -1 jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/mock/lib/Border.jwc
Index: Border.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/mock/lib/Border.jwc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Border.jwc 18 Apr 2005 17:07:53 -0000 1.4
+++ Border.jwc 4 May 2005 23:03:42 -0000 1.5
@@ -24,7 +24,7 @@
<parameter name="title" required="yes" default-binding="literal"/>
<component id="shell" type="Shell">
- <binding name="title" value="title"/>
+ <binding name="title" value="ognl:title"/>
<binding name="stylesheet" value="asset:style"/>
</component>
1.3 +4 -4 jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/mock/app/PrivateAssetTemplate.page
Index: PrivateAssetTemplate.page
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/mock/app/PrivateAssetTemplate.page,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PrivateAssetTemplate.page 5 Jan 2005 23:17:14 -0000 1.2
+++ PrivateAssetTemplate.page 4 May 2005 23:03:42 -0000 1.3
@@ -16,15 +16,15 @@
-->
<!DOCTYPE page-specification PUBLIC
- "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
+ "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<page-specification class="org.apache.tapestry.html.BasePage">
<component id="border" type="lib:Border">
- <static-binding name="title">Private Asset Template</static-binding>
+ <binding name="title" value="Private Asset Template"/>
</component>
- <private-asset name="$template" resource-path="/pages/PrivateAssetTemplate.html"/>
+ <asset name="$template" path="/pages/PrivateAssetTemplate.html"/>
</page-specification>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org