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 &lt;head&gt;
       tag (typically used to provide &lt;meta&gt; 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>&nbsp;</td>
  +    <td>literal</td>
       <td>The title for the page, used to render the &lt;title&gt; tag.</td>
     </tr>
     
  @@ -78,7 +80,8 @@
       <td>&IAsset;</td>
       <td>in</td>
       <td>no</td>
  -    <td></td>
  +    <td>&nbsp;</td>
  +    <td>asset</td>    
       <td>If provided, then a &lt;link&gt; 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>&nbsp;</td>
  +    <td>ognl</td>
       <td>
         If provided, then &lt;link&gt; 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>&nbsp;</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>&nbsp;</td>
  +    <td>ognl</td>
       <td>If specified, the delegate is rendered before the close of the &lt;head&gt;
         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>&nbsp;</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>&nbsp;</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>&nbsp;</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