Modified: websites/production/tapestry/content/page-life-cycle.html
==============================================================================
--- websites/production/tapestry/content/page-life-cycle.html (original)
+++ websites/production/tapestry/content/page-life-cycle.html Sun Feb 25 
23:20:05 2018
@@ -67,7 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><div class="aui-label" 
style="float:right" title="Related Articles">
+                <div id="ConfluenceContent"><div 
class="confluence-information-macro confluence-information-macro-note"><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This is an advanced topic. Most 
users won't ever need to know anything about the page life 
cycle.</p></div></div><p>In Tapestry, you are free to develop your presentation 
objects, page and components classes, as ordinary objects, complete with 
instance variables and so forth.</p><p>This is somewhat revolutionary in terms 
of web development in Java. By comparison, using traditional servlets, or 
Struts, your presentation objects (Servlets, or Struts Actions, or the 
equivalent in other frameworks) are <em>stateless singletons</em>. That is, a 
<em>single</em> instance is created, and all incoming requests are threaded 
through that single instance. Because multiple requests are handled by many 
different threads, this means
  that the singleton's instance variables are useless ... any value written 
into an instance variable would immediately be overwritten by a different 
thread. Thus, it is necessary to use the Servlet API's HttpServletRequest 
object to store per-request data, and the HttpSession object to store data 
between requests.</p><div class="aui-label" style="float:right" title="Related 
Articles">
 
 
 
@@ -136,7 +136,7 @@
 </div>
 
 
-<div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This is an advanced topic. Most 
users won't ever need to know anything about the page life 
cycle.</p></div></div><p>&#160;</p><p>In Tapestry, you are free to develop your 
presentation objects, page and components classes, as ordinary objects, 
complete with instance variables and so forth.</p><p>This is somewhat 
revolutionary in terms of web development in Java. By comparison, using 
traditional servlets, or Struts, your presentation objects (Servlets, or Struts 
Actions, or the equivalent in other frameworks) are <em>stateless 
singletons</em>. That is, a <em>single</em> instance is created, and all 
incoming requests are threaded through that single instance. Because multiple 
requests are handled by many different threads, this means that the singleton's 
instance 
 variables are useless ... any value written into an instance variable would 
immediately be overwritten by a different thread. Thus, it is necessary to use 
the Servlet API's HttpServletRequest object to store per-request data, and the 
HttpSession object to store data between requests.</p><p>Tapestry takes a very 
different approach.</p><p>In Tapestry, each page is a singleton, but with a 
<em>per thread</em> map of field names &amp; values that Tapestry invisibly 
manages for you.</p><p>With this approach, all the difficult, ugly issues 
related to multi-threading go by the wayside. Instead, familiar, simple coding 
practices (using ordinary methods and fields) can be used.</p><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Tapestry 5.0 and 5.1 used page 
pooling, rather than a singleton page with a per-thread 
 map, to achieve the same effect.</p></div></div><p>The page life cycle is 
quite simple:</p><ol><li>When first needed, a page is loaded. Loading a page 
involves instantiating the components of the page and connecting them 
together.</li><li>Once a page is loaded, it is <em>attached</em> to the current 
request. Remember that there will be many threads, each handling its own 
request to the same page.</li><li>At the end of a request, after a response has 
been sent to the client, the page is <em>detached</em> from the request. This 
is a chance to perform any cleanup needed for the page.</li></ol><h2 
id="PageLifeCycle-PageLifeCycleMethods">Page Life Cycle Methods</h2><p>There 
are rare occasions where it is useful for a component to perform some 
operations, usually some kind of initialization or caching, based on the life 
cycle of the page.</p><p>As with <a  href="component-rendering.html">component 
rendering</a>, you have the ability to make your components "aware" of these 
events by telli
 ng Tapestry what methods to invoke for each.</p><p>Page life cycle methods 
should take no parameters and return void.</p><p>You have the choice of 
attaching an annotation to a method, or simply using the method naming 
conventions:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Method Name</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>When Called</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageLoaded.html";>PageLoaded</a></p></td><td
 colspan="1" rowspan="1" class="confluenceTd"><p>pageLoaded()</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>After the page is fully 
loaded</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a 
 class="external-link" href="http://tapestr
 
y.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageAttached.html">PageAttached</a></p></td><td
 colspan="1" rowspan="1" class="confluenceTd"><p>pageAttached()</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>After the page is attached to 
the request.</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd">@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageReset.html";>PageReset</a></td><td
 colspan="1" rowspan="1" class="confluenceTd">pageReset()</td><td colspan="1" 
rowspan="1" class="confluenceTd">After the page is <em>activated</em>, except 
when requesting the same page</td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageDetached.html";>PageDetached</a></p></td><td
 colspan="1" rowspan="1" class="confluenceTd"><p>pageDetached()</p></td><td 
colspan="1" rowspan="1" cl
 ass="confluenceTd"><p>AFter the page is detached from the 
request.</p></td></tr></tbody></table></div><p>The @PageReset life cycle (only 
for Tapestry 5.2 and later) is invoked on a page render request when the page 
is linked to from some <em>other</em> page of the application (but <em>not</em> 
on a link to the same page), or upon a reload of the page in the browser. This 
is to allow the page to reset its state, if any, when a user returns to the 
page from some other part of the application.</p><h2 
id="PageLifeCycle-ComparisontoJavaServerPages">Comparison to JavaServer 
Pages</h2><p>JSPs also act as singletons. However, the individual JSP tags are 
pooled.</p><p>This is one of the areas where Tapestry can significantly 
outperform JSPs. Much of the code inside a compiled JSP class concerns getting 
tags from a tag pool, configuring the properties of the tag instance, using the 
tag instance, then cleaning up the tag instance and putting it back in the 
pool.</p><p>The operations Tapestry d
 oes once per request are instead executed dozens or potentially hundreds of 
times (depending the complexity of the page, and if any nested loops 
occur).</p><p>Pooling JSP tags is simply the wrong granularity.</p><p>Tapestry 
can also take advantage of its more coarse grained caching to optimize how data 
moves, via parameters, between components. This means that Tapestry pages will 
actually speed up after they render the first time.</p><h2 
id="PageLifeCycle-PagePoolConfiguration">Page Pool Configuration</h2><div 
class="confluence-information-macro confluence-information-macro-note"><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This section is related to 
versions of Tapestry prior to 5.2. Modern Tapestry uses an alternate approach 
that allows a single page instance to be shared across many request processing 
threads.</p></div></div><p>In Tapestry 5.0 and 5.1, a page pool is used to s
 tore page instances. The pool is "keyed" on the name of the page (such as 
"start") and the <em>locale</em> for the page (such as "en" or 
"fr").</p><p>Within each key, Tapestry tracks the number of page instances that 
have been created, as well as the number that are in use (currently attached to 
a request).</p><p>When a page is first accessed in a request, it is taken from 
the pool. Tapestry has some <a  href="configuration.html">configuration 
values</a> that control the details of how and when page instances are 
created.</p><ul><li>If a free page instance is available, the page is marked in 
use and attached to the request.</li><li>If there are fewer page instances than 
the <em>soft limit</em>, then a new page instance is simply created and 
attached to the request.</li><li>If the soft limit has been reached, Tapestry 
will wait for a short period of time for a page instance to become available 
before creating a new page instance.</li><li>If the hard limit has been 
reached, Tapestry w
 ill throw an exception rather than create a new page 
instance.</li><li>Otherwise, Tapestry will create a new page instance.<br 
clear="none"> Thus a busy application will initially create pages up-to the 
soft limit (which defaults to five page instances). If the application 
continues to be pounded with requests, it will slow its request processing, 
using the soft wait time in an attempt to reuse an existing page 
instance.</li></ul><p>A truly busy application will continue to create new page 
instances as needed until the hard limit is reached.</p><p>Remember that all 
these configuration values are per key: the combination of page name and 
locale. Thus even with a hard limit of 20, you may eventually find that 
Tapestry has created 20 start page instances for locale "en" <em>and</em> 20 
start page instances for locale "fr" (if your application is configured to 
support both English and French). Likewise, you may have 20 instances for the 
start page, and 20 instances for the newaccount pa
 ge.</p><p>Tapestry periodically checks its cache for page instances that have 
not been used recently (within a configurable window). Unused page instances 
are release to the garbage collector.</p><p>The end result is that you have 
quite a degree of tuning control over the process. If memory is a limitation 
and throughput can be sacrificed, try lowering the soft and hard limit and 
increasing the soft wait.</p><p>If performance is absolute and you have lots of 
memory, then increase the soft and hard limit and reduce the soft wait. This 
encourages Tapestry to create more page instances and not wait as long to 
re-use existing instances.</p></div>
+<p>Tapestry takes a very different approach.</p><p>In Tapestry, each page is a 
singleton, but with a <em>per thread</em> map of field names &amp; values that 
Tapestry invisibly manages for you.</p><p>With this approach, all the 
difficult, ugly issues related to multi-threading go by the wayside. Instead, 
familiar, simple coding practices (using ordinary methods and fields) can be 
used.</p><div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Tapestry 5.0 and 5.1 used page 
pooling, rather than a singleton page with a per-thread map, to achieve the 
same effect.</p></div></div><p>The page life cycle is quite 
simple:</p><ol><li>When first needed, a page is loaded. Loading a page involves 
instantiating the components of the page and connecting them 
together.</li><li>Once a page is loaded, it is <em>attached</em> to
  the current request. Remember that there will be many threads, each handling 
its own request to the same page.</li><li>At the end of a request, after a 
response has been sent to the client, the page is <em>detached</em> from the 
request. This is a chance to perform any cleanup needed for the 
page.</li></ol><h2 id="PageLifeCycle-PageLifeCycleMethods">Page Life Cycle 
Methods</h2><p>There are rare occasions where it is useful for a component to 
perform some operations, usually some kind of initialization or caching, based 
on the life cycle of the page.</p><p>As with <a  
href="component-rendering.html">component rendering</a>, you have the ability 
to make your components "aware" of these events by telling Tapestry what 
methods to invoke for each.</p><p>Page life cycle methods should take no 
parameters and return void.</p><p>You have the choice of attaching an 
annotation to a method, or simply using the method naming conventions:</p><div 
class="table-wrap"><table class="confluenceTable"
 ><tbody><tr><th colspan="1" rowspan="1" 
 >class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" 
 >class="confluenceTh"><p>Method Name</p></th><th colspan="1" rowspan="1" 
 >class="confluenceTh"><p>When Called</p></th></tr><tr><td colspan="1" 
 >rowspan="1" class="confluenceTd"><p>@<a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageLoaded.html";>PageLoaded</a></p></td><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>pageLoaded()</p></td><td 
 >colspan="1" rowspan="1" class="confluenceTd"><p>After the page is fully 
 >loaded</p></td></tr><tr><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>@<a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageAttached.html";>PageAttached</a></p></td><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>pageAttached()</p></td><td 
 >colspan="1" rowspan="1" class="confluenceTd"><p>After the page is attached to 
 >the request.</p></td></tr
 ><tr><td colspan="1" rowspan="1" class="confluenceTd">@<a  
 >class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageReset.html";>PageReset</a></td><td
 > colspan="1" rowspan="1" class="confluenceTd">pageReset()</td><td colspan="1" 
 >rowspan="1" class="confluenceTd">After the page is <em>activated</em>, except 
 >when requesting the same page</td></tr><tr><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>@<a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageDetached.html";>PageDetached</a></p></td><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>pageDetached()</p></td><td 
 >colspan="1" rowspan="1" class="confluenceTd"><p>AFter the page is detached 
 >from the request.</p></td></tr></tbody></table></div><p>The @PageReset life 
 >cycle (only for Tapestry 5.2 and later) is invoked on a page render request 
 >when the page is linked to from some <em>other</em> page of the application 
 >(but <em>no
 t</em> on a link to the same page), or upon a reload of the page in the 
browser. This is to allow the page to reset its state, if any, when a user 
returns to the page from some other part of the application.</p><h2 
id="PageLifeCycle-ComparisontoJavaServerPages">Comparison to JavaServer 
Pages</h2><p>JSPs also act as singletons. However, the individual JSP tags are 
pooled.</p><p>This is one of the areas where Tapestry can significantly 
outperform JSPs. Much of the code inside a compiled JSP class concerns getting 
tags from a tag pool, configuring the properties of the tag instance, using the 
tag instance, then cleaning up the tag instance and putting it back in the 
pool.</p><p>The operations Tapestry does once per request are instead executed 
dozens or potentially hundreds of times (depending the complexity of the page, 
and if any nested loops occur).</p><p>Pooling JSP tags is simply the wrong 
granularity.</p><p>Tapestry can also take advantage of its more coarse grained 
caching to op
 timize how data moves, via parameters, between components. This means that 
Tapestry pages will actually speed up after they render the first time.</p><h2 
id="PageLifeCycle-PagePoolConfiguration">Page Pool Configuration</h2><div 
class="confluence-information-macro confluence-information-macro-note"><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This section is related to 
versions of Tapestry prior to 5.2. Modern Tapestry uses an alternate approach 
that allows a single page instance to be shared across many request processing 
threads.</p></div></div><p>In Tapestry 5.0 and 5.1, a page pool is used to 
store page instances. The pool is "keyed" on the name of the page (such as 
"start") and the <em>locale</em> for the page (such as "en" or 
"fr").</p><p>Within each key, Tapestry tracks the number of page instances that 
have been created, as well as the number that are in use (currently att
 ached to a request).</p><p>When a page is first accessed in a request, it is 
taken from the pool. Tapestry has some <a  
href="configuration.html">configuration values</a> that control the details of 
how and when page instances are created.</p><ul><li>If a free page instance is 
available, the page is marked in use and attached to the request.</li><li>If 
there are fewer page instances than the <em>soft limit</em>, then a new page 
instance is simply created and attached to the request.</li><li>If the soft 
limit has been reached, Tapestry will wait for a short period of time for a 
page instance to become available before creating a new page 
instance.</li><li>If the hard limit has been reached, Tapestry will throw an 
exception rather than create a new page instance.</li><li>Otherwise, Tapestry 
will create a new page instance.<br clear="none"> Thus a busy application will 
initially create pages up-to the soft limit (which defaults to five page 
instances). If the application continues to b
 e pounded with requests, it will slow its request processing, using the soft 
wait time in an attempt to reuse an existing page instance.</li></ul><p>A truly 
busy application will continue to create new page instances as needed until the 
hard limit is reached.</p><p>Remember that all these configuration values are 
per key: the combination of page name and locale. Thus even with a hard limit 
of 20, you may eventually find that Tapestry has created 20 start page 
instances for locale "en" <em>and</em> 20 start page instances for locale "fr" 
(if your application is configured to support both English and French). 
Likewise, you may have 20 instances for the start page, and 20 instances for 
the newaccount page.</p><p>Tapestry periodically checks its cache for page 
instances that have not been used recently (within a configurable window). 
Unused page instances are release to the garbage collector.</p><p>The end 
result is that you have quite a degree of tuning control over the process. If 
mem
 ory is a limitation and throughput can be sacrificed, try lowering the soft 
and hard limit and increasing the soft wait.</p><p>If performance is absolute 
and you have lots of memory, then increase the soft and hard limit and reduce 
the soft wait. This encourages Tapestry to create more page instances and not 
wait as long to re-use existing instances.</p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/page-navigation.html
==============================================================================
--- websites/production/tapestry/content/page-navigation.html (original)
+++ websites/production/tapestry/content/page-navigation.html Sun Feb 25 
23:20:05 2018
@@ -156,11 +156,11 @@
 
 
 <p>In essence, a Tapestry application is a number of related pages, working 
together. To some degree, each page is like an application unto 
itself.</p><p>Any individual request will be targeted at a single page. 
Requests come in two forms:&#160;</p><ul><li><em>component event</em> requests 
target a specific component on a specific page, triggering an event within that 
component</li><li><em>render</em> requests target a specific page, and stream 
the HTML markup for that page back to the client</li></ul><p>This dichotomy 
between component event requests and render requests alleviates a number of 
problems in traditional web applications related to the browser back button, or 
to the user hitting the refresh button in their browser.</p><h3 
id="PageNavigation-Contents">Contents</h3><h2 
id="PageNavigation-Contents|RelatedArticlesLogicalPageNameShortening"><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1519597210782 {padding: 0px;}
-div.rbtoc1519597210782 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1519597210782 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1519600774367 {padding: 0px;}
+div.rbtoc1519600774367 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519600774367 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></h2><div class="toc-macro rbtoc1519597210782">
+/*]]>*/</style></h2><div class="toc-macro rbtoc1519600774367">
 <ul class="toc-indentation"><li><a  
href="#PageNavigation-Contents|RelatedArticlesLogicalPageNameShortening">Logical
 Page Name Shortening</a></li><li><a  
href="#PageNavigation-ComponentEventRequests&amp;Responses">Component Event 
Requests &amp; Responses</a>
 <ul class="toc-indentation"><li><a  href="#PageNavigation-1.Nullresponse">1. 
Null response</a></li><li><a  href="#PageNavigation-2.Stringresponse">2. String 
response</a></li><li><a  href="#PageNavigation-3.Classresponse">3. Class 
response</a></li><li><a  href="#PageNavigation-4.Pageresponse">4. Page 
response</a></li><li><a  href="#PageNavigation-5.HttpError">5. 
HttpError</a></li><li><a  href="#PageNavigation-6.Linkresponse">6. Link 
response</a></li><li><a  href="#PageNavigation-7.Streamresponse">7. Stream 
response</a></li><li><a  href="#PageNavigation-8.URLresponse">8. URL 
response</a></li><li><a  href="#PageNavigation-9.Objectresponse">9. Object 
response</a></li></ul>
 </li><li><a  href="#PageNavigation-PageRenderRequests">Page Render 
Requests</a></li><li><a  href="#PageNavigation-PageActivation">Page 
Activation</a></li><li><a  href="#PageNavigation-PageNavigationPatterns">Page 
Navigation Patterns</a>
@@ -323,7 +323,7 @@ public Object onAction(){
 
   long onPassivate() { return productId; }
 </pre>
-</div></div><p>The setProductId() method is no longer needed.</p><h3 
id="PageNavigation-Limitations">Limitations</h3><p>As your application's 
workflow expands, you may find that there is not a reasonable way to avoid 
storing some data persistently between requests, outside of the page activation 
context. For example, if from the ProductDetails page, the user is allowed to 
navigate to related pages and then back to ProductDetails, it starts to become 
necessary to keep passing that product id around from page to page to 
page.</p><p>At some point, persistent values make more sense. Tapestry has 
several persistence strategies available, including one that stores data in URL 
query parameters. See&#160;<a  href="persistent-page-data.html">Persistent Page 
Data</a> for details.</p></div>
+</div></div><p>The setProductId() method is no longer needed.</p><h3 
id="PageNavigation-Limitations">Limitations</h3><p>As your application's 
workflow expands, you may find that there is not a reasonable way to avoid 
storing some data persistently between requests, outside of the page activation 
context. For example, if from the ProductDetails page, the user is allowed to 
navigate to related pages and then back to ProductDetails, it starts to become 
necessary to keep passing that product id around from page to page to 
page.</p><p>At some point, persistent values make more sense. Tapestry has 
several persistence strategies available, including one that stores data in URL 
query parameters. See&#160;<a  href="persistent-page-data.html">Persistent Page 
Data</a> for details.</p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/parameter-type-coercion.html
==============================================================================
--- websites/production/tapestry/content/parameter-type-coercion.html (original)
+++ websites/production/tapestry/content/parameter-type-coercion.html Sun Feb 
25 23:20:05 2018
@@ -161,7 +161,7 @@
 </div></div><p>&#160;</p><p>Here, the type of all three parameters is 
<code>int</code>.</p><p>However, it is likely that the component will be used 
as so:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  Merry Christmas: &lt;t:count end="3"&gt; Ho! 
&lt;/t:count&gt;
 </pre>
-</div></div><p>A bare whole number is interpreted by the prop binding prefix 
as a <code>long</code>. So this is the <em>long</em> value 3.</p><p>Tapestry 
will automatically coerce the bound value, a <code>long</code>, to the 
parameter's type, <code>int</code>. This may be a lossy coercion (if the 
<code>long</code> represents a number larger than can be stored in an 
<code>int</code>).</p><h2 
id="ParameterTypeCoercion-TypeCoercerService">TypeCoercer Service</h2><p>Main 
Article: <a  href="type-coercion.html">Type Coercion</a></p><p>The TypeCoercer 
service is responsible for this type coercion. This service is part of the <a  
href="ioc.html">tapestry-ioc</a> module. The service is quite extensible, 
allowing for new types and coercions to be added easily. The TapestryModule 
contributes a few additional coercions into the TypeCoercer service.</p></div>
+</div></div><p>A bare whole number is interpreted by the prop binding prefix 
as a <code>long</code>. So this is the <em>long</em> value 3.</p><p>Tapestry 
will automatically coerce the bound value, a <code>long</code>, to the 
parameter's type, <code>int</code>. This may be a lossy coercion (if the 
<code>long</code> represents a number larger than can be stored in an 
<code>int</code>).</p><h2 
id="ParameterTypeCoercion-TypeCoercerService">TypeCoercer Service</h2><p>Main 
Article: <a  href="type-coercion.html">Type Coercion</a></p><p>The TypeCoercer 
service is responsible for this type coercion. This service is part of the <a  
href="ioc.html">tapestry-ioc</a> module. The service is quite extensible, 
allowing for new types and coercions to be added easily. The TapestryModule 
contributes a few additional coercions into the TypeCoercer 
service.</p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/project-layout.html
==============================================================================
--- websites/production/tapestry/content/project-layout.html (original)
+++ websites/production/tapestry/content/project-layout.html Sun Feb 25 
23:20:05 2018
@@ -67,7 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h1 
id="ProjectLayout-ProjectLayout">Project Layout</h1><p>This is the 
<em>suggested</em> layout for your Tapestry project; it is the layout of 
folders and files created by the <a  href="getting-started.html">Tapestry 
Quickstart Archetype</a>. If you are creating your own build using Ant, you may 
use whatever conventions work for you ... as long as everything gets packaged 
up into the right place in the target WAR.</p><p>Parts of this project layout 
mimics the format of an <em>exploded WAR</em> (a WAR file unpackaged onto the 
file system). This will often enable you to run your application directly from 
your workspace, without any special build or packaging process, while 
developing. Each of the major IDEs has plugins to allow you to accomplish this 
task ... and it's one of the factors (combined with <a  
href="class-reloading.html">live class reloading</a>) that makes working with 
Tapestry a breeze.</p><p>Below is a sample project, whose r
 oot package is <code>com.example.myapp</code>:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="project-layout.data/projectlayout.png"></span></p><h2 
id="ProjectLayout-Mainsourcefiles-src/main/java">Main source files - 
src/main/java</h2><p>Main Java source files, the files that will be compiled 
into the WAR file, are in <code>src/main/java</code>. This is <em>only</em> 
Java source files. You can see the <code>Index.java</code> source file inside 
the <code>pages</code> subpackage, and the <code>Layout.java</code> source file 
inside the <code>components</code> subpackage. The package names demonstrated 
here are required, dictated by the rules for <a  
href="component-classes.html">component classes</a></p><p>.</p><p>Compiled Java 
classes will ultimately be packaged in the WAR inside the 
<code>WEB-INF/classes</code> folder.</p><h2 
id="ProjectLayout-ClasspathResources-src/main/resources">Classpath Resources - 
src/main/resources</h2><p>Resou
 rce files are under <code>src/main/resources</code>. This includes the <a  
href="localization.html">message catalog</a> for the Index page 
(<code>Index.properties</code>), as well as the message catalog and <a  
href="component-templates.html">component template</a> for the Layout component 
(<code>Layout.tml</code>). These files will also be packaged into the 
<code>WEB-INF/classes</code> folder of the WAR.</p><p>Component templates will 
always be stored in the resources folder. Templates for pages may be packaged 
in the WAR proper instead.</p><h2 
id="ProjectLayout-ContextResources-src/main/webapp">Context Resources - 
src/main/webapp</h2><p>The WAR is built primarily from the 
<code>src/main/webapp</code> folder; this is where ordinary files are stored 
(such as images and stylesheets). Page templates may also be stored here 
(<code>Index.tml</code>). The file <code>src/main/webapp/WEB-INF/web.xml</code> 
is the servlet container deployment descriptor, which has a very specific <a  
href="
 configuration.html">configuration</a> for Tapestry.</p><p>The build tool 
(usually Maven) will be responsible for putting compiled classes and resources 
into the <code>WEB-INF/classes</code> folder of the WAR, and for putting the 
Tapestry library, and its dependencies (as well as any additional libraries 
defined by your application) into the <code>WEB-INF/lib</code> folder.</p><h2 
id="ProjectLayout-Testing-src/test">Testing - src/test</h2><p>The folders 
<code>src/test/java</code> and <code>src/test/resources</code> are used when 
compiling and executing tests. Files in these folders are <em>not</em> packaged 
into the final WAR.</p></div>
+                <div id="ConfluenceContent"><h1 
id="ProjectLayout-ProjectLayout">Project Layout</h1><p>This is the 
<em>suggested</em> layout for your Tapestry project; it is the layout of 
folders and files created by the <a  href="getting-started.html">Tapestry 
Quickstart Archetype</a>. If you are creating your own build using Ant, you may 
use whatever conventions work for you ... as long as everything gets packaged 
up into the right place in the target WAR.</p><p>Parts of this project layout 
mimics the format of an <em>exploded WAR</em> (a WAR file unpackaged onto the 
file system). This will often enable you to run your application directly from 
your workspace, without any special build or packaging process, while 
developing. Each of the major IDEs has plugins to allow you to accomplish this 
task ... and it's one of the factors (combined with <a  
href="class-reloading.html">live class reloading</a>) that makes working with 
Tapestry a breeze.</p><p>Below is a sample project, whose r
 oot package is <code>com.example.myapp</code>:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="project-layout.data/projectlayout.png"></span></p><h2 
id="ProjectLayout-Mainsourcefiles-src/main/java">Main source files - 
src/main/java</h2><p>Main Java source files, the files that will be compiled 
into the WAR file, are in <code>src/main/java</code>. This is <em>only</em> 
Java source files. You can see the <code>Index.java</code> source file inside 
the <code>pages</code> subpackage, and the <code>Layout.java</code> source file 
inside the <code>components</code> subpackage. The package names demonstrated 
here are required, dictated by the rules for <a  
href="component-classes.html">component classes</a></p><p>.</p><p>Compiled Java 
classes will ultimately be packaged in the WAR inside the 
<code>WEB-INF/classes</code> folder.</p><h2 
id="ProjectLayout-ClasspathResources-src/main/resources">Classpath Resources - 
src/main/resources</h2><p>Resou
 rce files are under <code>src/main/resources</code>. This includes the <a  
href="localization.html">message catalog</a> for the Index page 
(<code>Index.properties</code>), as well as the message catalog and <a  
href="component-templates.html">component template</a> for the Layout component 
(<code>Layout.tml</code>). These files will also be packaged into the 
<code>WEB-INF/classes</code> folder of the WAR.</p><p>Component templates will 
always be stored in the resources folder. Templates for pages may be packaged 
in the WAR proper instead.</p><h2 
id="ProjectLayout-ContextResources-src/main/webapp">Context Resources - 
src/main/webapp</h2><p>The WAR is built primarily from the 
<code>src/main/webapp</code> folder; this is where ordinary files are stored 
(such as images and stylesheets). Page templates may also be stored here 
(<code>Index.tml</code>). The file <code>src/main/webapp/WEB-INF/web.xml</code> 
is the servlet container deployment descriptor, which has a very specific <a  
href="
 configuration.html">configuration</a> for Tapestry.</p><p>The build tool 
(usually Maven) will be responsible for putting compiled classes and resources 
into the <code>WEB-INF/classes</code> folder of the WAR, and for putting the 
Tapestry library, and its dependencies (as well as any additional libraries 
defined by your application) into the <code>WEB-INF/lib</code> folder.</p><h2 
id="ProjectLayout-Testing-src/test">Testing - src/test</h2><p>The folders 
<code>src/test/java</code> and <code>src/test/resources</code> are used when 
compiling and executing tests. Files in these folders are <em>not</em> packaged 
into the final WAR.</p><p>&#160;</p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/property-expressions.html
==============================================================================
--- websites/production/tapestry/content/property-expressions.html (original)
+++ websites/production/tapestry/content/property-expressions.html Sun Feb 25 
23:20:05 2018
@@ -140,7 +140,7 @@ mapKey : keyword | constant | propertyCh
 
     <div class="param-body">Support for map literals was added in Tapestry 
5.3.</div>
 
-</div>Notes:<ul><li>Whitespace is ignored.</li><li>Integers and decimals may 
have a leading sign ('+' or '-').</li><li>Constants are in base 10 (octal and 
hex notation is not yet supported). Decimals may contain a decimal point 
(exponent notation not yet supported).</li><li>Literal strings are enclosed in 
single quotes.</li><li>The <code>rangeOp</code> creates a range object that 
will iterate between the two values. The upper and lower bounds may be literal 
integers, or property expressions.</li><li>An identifier by itself is a 
property name. An identifier with parenthesis is a method 
invocation.</li><li>Property names, method names, and keywords are 
case-insensitive.</li><li>'this' is the root object (i.e., the containing 
component).</li><li>The <code>not</code> operator coerces the expression to a 
<code>boolean</code> (so it can be used on strings, numbers, 
etc.).</li><li>Method matching is based on method name and number of 
parameters, but not parameter types. The <a  href="type-
 coercion.html">TypeCoercer</a> service is used to convert parameters to the 
correct type to be passed into the method.</li></ul><h2 
id="PropertyExpressions-Examples">Examples</h2><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>&#160;</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Example</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Notes</p></th></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>this</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>null</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Property Name</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><
 p>userName</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls 
getUserName() or setUserName, depending on context</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Property Chain</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>user.address.city</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Calls 
getUser().getAddress().getCity() or getUser().getAddress().setCity(), depending 
on context</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Property Chain</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>user?.name</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Calls getUser() and, if the result is not null, calls 
getName() on the result</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Method Invocation</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>groupList.size()</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>calls getGroupList().size()</p></
 td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Method 
Invocation</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>members.findById(user.id)?.name</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Calls 
getMembers().findById(getUser().getId()).getName() (unless findById returns 
null)</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Range</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>1..10</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Iterates between integers 1 and 10</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Range</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>1..myList.size()</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Iterates between 1 and the result of 
getMyList().size()</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Literal String</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>'Beer is proof that God lov
 es us and wants us to be happy.'</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Use single quotes</p></td></tr><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>List</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>[user.name, user.email, user.phone]</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Not Operator</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>! user.deleted</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>the boolean negation of 
getUser().getDeleted()</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Not, Coerced</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>! user.middleName</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>true only if getUser.getMiddleName() returns null or an 
empty string</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Map</p></th><td colspan="1"
  rowspan="1" class="confluenceTd"><p>{ 'framework' : 'Tapestry', 'version' : 
version }</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Keys are 
string literals (in single quotes), but could be properties as 
well</p></td></tr></tbody></table></div></div>
+</div>Notes:<ul><li>Whitespace is ignored.</li><li>Integers and decimals may 
have a leading sign ('+' or '-').</li><li>Constants are in base 10 (octal and 
hex notation is not yet supported). Decimals may contain a decimal point 
(exponent notation not yet supported).</li><li>Literal strings are enclosed in 
single quotes.</li><li>The <code>rangeOp</code> creates a range object that 
will iterate between the two values. The upper and lower bounds may be literal 
integers, or property expressions.</li><li>An identifier by itself is a 
property name. An identifier with parenthesis is a method 
invocation.</li><li>Property names, method names, and keywords are 
case-insensitive.</li><li>'this' is the root object (i.e., the containing 
component).</li><li>The <code>not</code> operator coerces the expression to a 
<code>boolean</code> (so it can be used on strings, numbers, 
etc.).</li><li>Method matching is based on method name and number of 
parameters, but not parameter types. The <a  href="type-
 coercion.html">TypeCoercer</a> service is used to convert parameters to the 
correct type to be passed into the method.</li></ul><h2 
id="PropertyExpressions-Examples">Examples</h2><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>&#160;</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Example</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Notes</p></th></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>this</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>null</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Property Name</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><
 p>userName</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls 
getUserName() or setUserName, depending on context</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Property Chain</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>user.address.city</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Calls 
getUser().getAddress().getCity() or getUser().getAddress().setCity(), depending 
on context</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Property Chain</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>user?.name</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Calls getUser() and, if the result is not null, calls 
getName() on the result</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Method Invocation</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>groupList.size()</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>calls getGroupList().size()</p></
 td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Method 
Invocation</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>members.findById(user.id)?.name</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Calls 
getMembers().findById(getUser().getId()).getName() (unless findById returns 
null)</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Range</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>1..10</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Iterates between integers 1 and 10</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Range</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>1..myList.size()</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Iterates between 1 and the result of 
getMyList().size()</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Literal String</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>'Beer is proof that God lov
 es us and wants us to be happy.'</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Use single quotes</p></td></tr><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>List</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>[user.name, user.email, user.phone]</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Not Operator</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>! user.deleted</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>the boolean negation of 
getUser().getDeleted()</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Not, Coerced</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>! user.middleName</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>true only if getUser.getMiddleName() returns null or an 
empty string</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Map</p></th><td colspan="1"
  rowspan="1" class="confluenceTd"><p>{ 'framework' : 'Tapestry', 'version' : 
version }</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Keys are 
string literals (in single quotes), but could be properties as 
well</p></td></tr></tbody></table></div><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/request-processing.html
==============================================================================
--- websites/production/tapestry/content/request-processing.html (original)
+++ websites/production/tapestry/content/request-processing.html Sun Feb 25 
23:20:05 2018
@@ -136,7 +136,7 @@
 </div>
 
 
-<p><strong>Request Processing</strong> involves a sequence of steps that 
Tapestry performs when every HTTP request comes in. You <em>don't need</em> to 
know these steps to use Tapestry productively, but understanding the request 
processing pipeline is helpful if you want to understand Tapestry 
deeply.</p><p>Much of the early stages of processing are in the form of 
extensible <a  href="pipelinebuilder-service.html">pipelines</a>.</p><h2 
id="RequestProcessing-TapestryFilter">Tapestry Filter</h2><p>All incoming 
requests originate with the TapestryFilter, which is a servlet filter 
configured inside your application's <a  
href="configuration.html">web.xml</a>.</p><p>The TapestryFilter is responsible 
for a number of startup and initialization functions.</p><p>When it receives a 
request, the TapestryFilter obtains the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpServletRequestHandler.html";>HttpServletRequestHandler</a>
 service
 , and invokes its service() method.</p><h2 
id="RequestProcessing-HttpServletRequestHandlerPipeline">HttpServletRequestHandler
 Pipeline</h2><p>This pipeline performs initial processing of the request. It 
can be extended by contributing a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpServletRequestFilter.html";>HttpServletRequestFilter</a>
 into the HttpServletRequestHandler service's configuration.</p><p>Tapestry 
does not contribute any filters into this pipeline of its own.</p><p>The 
terminator for the pipeline does two things:</p><ul><li>It stores the request 
and response into the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html";>RequestGlobals</a>
 service. This is a per-thread scoped service that stores 
per-thread/per-request information.</li><li>It wraps the request and response 
as a <a  class="external-link" href="http://tapestry.apache.org/cur
 rent/apidocs/org/apache/tapestry5/services/Request.html">Request</a> and <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Response.html";>Response</a>,
 and passes them into the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestHandler.html";>RequestHandler</a>
 pipeline.</li></ul><h2 
id="RequestProcessing-RequestHandlerPipeline">RequestHandler 
Pipeline</h2><p>This pipeline is where most extensions related to requests take 
place. Request represents an abstraction on top of HttpServletRequest. 
(Primarily, this exists to bridge from the Servlet API objects to the 
corresponding Tapestry objects. This is to allow for a possible portlet 
integration for Tapestry.) Where other code and services within Tapestry 
require access to information in the request, such as query parameters, that 
information is obtained from the Request (or Response) objects.</p><p>The 
RequestHandler pipe
 line includes a number of built-in filters:</p><ul><li>CheckForUpdates is 
responsible for <a  href="class-reloading.html">class and template 
reloading</a>.</li><li>Localization identifies the <a  
href="localization.html">locale for the user</a>.</li><li>StaticFiles checks 
for URLs that are for static files (files that exist inside the web context) 
and aborts the request, so that the servlet container can handle the request 
normally.</li><li>ErrorFilter catches uncaught exceptions from the lower levels 
of Tapestry and presents the exception report page. This involves the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html";>RequestExceptionHandler</a>
 service, which is responsible for initializing and rendering the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/pages/ExceptionReport.html";>core/ExceptionReport</a>
 page.</li></ul><p>The terminator fo
 r this pipeline stores the Request and the Response into RequestGlobals, then 
requests that the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Dispatcher.html";>MasterDispatcher</a>
 service figure out how to handle the request (if it is, indeed, a Tapestry 
request).</p><h2 id="RequestProcessing-MasterDispatcherService">Master 
Dispatcher Service</h2><p>The MasterDispatcher service is a chain-of-command, 
aggregating together (in a specific order), several Dispatcher objects. Each 
Dispatcher is built to recognize and process a particular kind of URL.</p><h3 
id="RequestProcessing-RootPathDispatcher">RootPath Dispatcher</h3><p>The 
RootPath Dispatcher recognizes a request for the application root (i.e., "/") 
and handles this the same as a render request for the "Start" page. Support for 
the Start page is kept for legacy purposes. Index pages are the correct 
approach.</p><h3 id="RequestProcessing-AssetDispatcher">Asset Dispatcher</h3
 ><p>Requests that begin with "/assets/" are references to <a  
 >href="assets.html">asset resources</a> that are stored on the classpath, 
 >inside the Tapestry JARs (or perhaps inside the JAR for a component library). 
 >The contents of the file will be delivered to the client browser as a byte 
 >stream. This dispatcher also handles requests that are simply polling for a 
 >change to the file.</p><h3 
 >id="RequestProcessing-PageRenderDispatcher">PageRender Dispatcher</h3><p>Page 
 >render requests are requests to render a particular page. Such requests may 
 >include additional elements on the path, which will be treated as activation 
 >context (see ComponentEvent Dispatcher below). Generally speaking, the 
 >activation context is the primary key of some related entity object. This 
 >allows the page to reconstruct the state it will need to successfully render 
 >itself.</p><p>The event handler method for the activate event may return a 
 >value; this is treated the same as the return value from a component action re
 quest; typically this will result in a redirect to another page. In this way, 
the activate event can perform simple validation at the page level ("can the 
user see this page?").</p><p>Page render URLs consist of the logical name of 
the page plus additional path elements for the activation context. The 
dispatcher here strips terms off of the path until it finds a known page name. 
Thus, "/mypage/27" would look first for a page whose name was "mypage/27", then 
look for a page name "mypage". Assuming the second search was successful, the 
page would be activated with the context "27". If no logical page name can be 
identified, control passes to the next dispatcher.</p><h3 
id="RequestProcessing-ComponentEventDispatcher">ComponentEvent 
Dispatcher</h3><p>The ComponentEvent dispatcher is used to trigger events in 
components.</p><p>The URL identifies the name of the page, then a series of 
component ids (the path from the page down to the specific component), then the 
name of the event to be t
 riggered on the component. The remaining path elements are used as the context 
for the <em>event</em> (not for the page activation, which does not currently 
apply). For example, "/griddemo.FOO.BAR/3" would locate page "griddemo", then 
component "FOO.BAR", and trigger an event named "action" (the default event 
type, which is omitted from the URL), with the context "3".</p><p>If the page 
in question has an activation context, it is supplied as an additional query 
parameter on the link.</p><p>In cases where the event type is not the default, 
"action", it will appear between the nested component id and the event context, 
preceded by a colon. Example: "/example/foo.bar:magic/99" would trigger an 
event of type "magic". This is not common in the vanilla Tapestry framework, 
but will likely be more common as Ajax features (which would not use the normal 
request logic) are implemented.</p><p>The response from a component action 
request is typically, but not universally, used to send a redirec
 t to the client; the redirect URL is a page render URL to display the response 
to the event. This is detailed under <a  href="page-navigation.html">Request 
Processing</a>.</p><h2 
id="RequestProcessing-RequestGlobalsService">RequestGlobals Service</h2><p>The 
RequestGlobals service has a life cycle of per-thread; this means that a 
separate instance exists for every thread, and therefore, for every request. 
The terminators of the two handler pipelines store the request/response pairs 
into the RequestGlobals service.</p><h2 
id="RequestProcessing-RequestService">Request Service</h2><p>The Request 
service is a <a  href="shadowbuilder-service.html">shadow</a> of the 
RequestGlobals services' request property. That is, any methods invoked on this 
service are delegated to the request object stored inside the 
RequestGlobals.</p><h2 id="RequestProcessing-Overview">Overview</h2><p>The 
following diagram provides an overview of how the different pipelines, filters 
and dispatchers interact when pro
 cessing an incoming request.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource confluence-content-image-border" alt="Request 
Processing" 
src="https://cwiki-test.apache.org/confluence/download/attachments/22872133/tapestry_request_processing_800.png?version=1&amp;modificationDate=1299128361000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872133/tapestry_request_processing_800.png?version=1&amp;modificationDate=1299128361000&amp;api=v2";></span></p></div>
+<p><strong>Request Processing</strong> involves a sequence of steps that 
Tapestry performs when every HTTP request comes in. You <em>don't need</em> to 
know these steps to use Tapestry productively, but understanding the request 
processing pipeline is helpful if you want to understand Tapestry 
deeply.</p><p>Much of the early stages of processing are in the form of 
extensible <a  href="pipelinebuilder-service.html">pipelines</a>.</p><h2 
id="RequestProcessing-TapestryFilter">Tapestry Filter</h2><p>All incoming 
requests originate with the TapestryFilter, which is a servlet filter 
configured inside your application's <a  
href="configuration.html">web.xml</a>.</p><p>The TapestryFilter is responsible 
for a number of startup and initialization functions.</p><p>When it receives a 
request, the TapestryFilter obtains the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpServletRequestHandler.html";>HttpServletRequestHandler</a>
 service
 , and invokes its service() method.</p><h2 
id="RequestProcessing-HttpServletRequestHandlerPipeline">HttpServletRequestHandler
 Pipeline</h2><p>This pipeline performs initial processing of the request. It 
can be extended by contributing a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpServletRequestFilter.html";>HttpServletRequestFilter</a>
 into the HttpServletRequestHandler service's configuration.</p><p>Tapestry 
does not contribute any filters into this pipeline of its own.</p><p>The 
terminator for the pipeline does two things:</p><ul><li>It stores the request 
and response into the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html";>RequestGlobals</a>
 service. This is a per-thread scoped service that stores 
per-thread/per-request information.</li><li>It wraps the request and response 
as a <a  class="external-link" href="http://tapestry.apache.org/cur
 rent/apidocs/org/apache/tapestry5/services/Request.html">Request</a> and <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Response.html";>Response</a>,
 and passes them into the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestHandler.html";>RequestHandler</a>
 pipeline.</li></ul><h2 
id="RequestProcessing-RequestHandlerPipeline">RequestHandler 
Pipeline</h2><p>This pipeline is where most extensions related to requests take 
place. Request represents an abstraction on top of HttpServletRequest. 
(Primarily, this exists to bridge from the Servlet API objects to the 
corresponding Tapestry objects. This is to allow for a possible portlet 
integration for Tapestry.) Where other code and services within Tapestry 
require access to information in the request, such as query parameters, that 
information is obtained from the Request (or Response) objects.</p><p>The 
RequestHandler pipe
 line includes a number of built-in filters:</p><ul><li>CheckForUpdates is 
responsible for <a  href="class-reloading.html">class and template 
reloading</a>.</li><li>Localization identifies the <a  
href="localization.html">locale for the user</a>.</li><li>StaticFiles checks 
for URLs that are for static files (files that exist inside the web context) 
and aborts the request, so that the servlet container can handle the request 
normally.</li><li>ErrorFilter catches uncaught exceptions from the lower levels 
of Tapestry and presents the exception report page. This involves the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestExceptionHandler.html";>RequestExceptionHandler</a>
 service, which is responsible for initializing and rendering the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/pages/ExceptionReport.html";>core/ExceptionReport</a>
 page.</li></ul><p>The terminator fo
 r this pipeline stores the Request and the Response into RequestGlobals, then 
requests that the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Dispatcher.html";>MasterDispatcher</a>
 service figure out how to handle the request (if it is, indeed, a Tapestry 
request).</p><h2 id="RequestProcessing-MasterDispatcherService">Master 
Dispatcher Service</h2><p>The MasterDispatcher service is a chain-of-command, 
aggregating together (in a specific order), several Dispatcher objects. Each 
Dispatcher is built to recognize and process a particular kind of URL.</p><h3 
id="RequestProcessing-RootPathDispatcher">RootPath Dispatcher</h3><p>The 
RootPath Dispatcher recognizes a request for the application root (i.e., "/") 
and handles this the same as a render request for the "Start" page. Support for 
the Start page is kept for legacy purposes. Index pages are the correct 
approach.</p><h3 id="RequestProcessing-AssetDispatcher">Asset Dispatcher</h3
 ><p>Requests that begin with "/assets/" are references to <a  
 >href="assets.html">asset resources</a> that are stored on the classpath, 
 >inside the Tapestry JARs (or perhaps inside the JAR for a component library). 
 >The contents of the file will be delivered to the client browser as a byte 
 >stream. This dispatcher also handles requests that are simply polling for a 
 >change to the file.</p><h3 
 >id="RequestProcessing-PageRenderDispatcher">PageRender Dispatcher</h3><p>Page 
 >render requests are requests to render a particular page. Such requests may 
 >include additional elements on the path, which will be treated as activation 
 >context (see ComponentEvent Dispatcher below). Generally speaking, the 
 >activation context is the primary key of some related entity object. This 
 >allows the page to reconstruct the state it will need to successfully render 
 >itself.</p><p>The event handler method for the activate event may return a 
 >value; this is treated the same as the return value from a component action re
 quest; typically this will result in a redirect to another page. In this way, 
the activate event can perform simple validation at the page level ("can the 
user see this page?").</p><p>Page render URLs consist of the logical name of 
the page plus additional path elements for the activation context. The 
dispatcher here strips terms off of the path until it finds a known page name. 
Thus, "/mypage/27" would look first for a page whose name was "mypage/27", then 
look for a page name "mypage". Assuming the second search was successful, the 
page would be activated with the context "27". If no logical page name can be 
identified, control passes to the next dispatcher.</p><h3 
id="RequestProcessing-ComponentEventDispatcher">ComponentEvent 
Dispatcher</h3><p>The ComponentEvent dispatcher is used to trigger events in 
components.</p><p>The URL identifies the name of the page, then a series of 
component ids (the path from the page down to the specific component), then the 
name of the event to be t
 riggered on the component. The remaining path elements are used as the context 
for the <em>event</em> (not for the page activation, which does not currently 
apply). For example, "/griddemo.FOO.BAR/3" would locate page "griddemo", then 
component "FOO.BAR", and trigger an event named "action" (the default event 
type, which is omitted from the URL), with the context "3".</p><p>If the page 
in question has an activation context, it is supplied as an additional query 
parameter on the link.</p><p>In cases where the event type is not the default, 
"action", it will appear between the nested component id and the event context, 
preceded by a colon. Example: "/example/foo.bar:magic/99" would trigger an 
event of type "magic". This is not common in the vanilla Tapestry framework, 
but will likely be more common as Ajax features (which would not use the normal 
request logic) are implemented.</p><p>The response from a component action 
request is typically, but not universally, used to send a redirec
 t to the client; the redirect URL is a page render URL to display the response 
to the event. This is detailed under <a  href="page-navigation.html">Request 
Processing</a>.</p><h2 
id="RequestProcessing-RequestGlobalsService">RequestGlobals Service</h2><p>The 
RequestGlobals service has a life cycle of per-thread; this means that a 
separate instance exists for every thread, and therefore, for every request. 
The terminators of the two handler pipelines store the request/response pairs 
into the RequestGlobals service.</p><h2 
id="RequestProcessing-RequestService">Request Service</h2><p>The Request 
service is a <a  href="shadowbuilder-service.html">shadow</a> of the 
RequestGlobals services' request property. That is, any methods invoked on this 
service are delegated to the request object stored inside the 
RequestGlobals.</p><h2 id="RequestProcessing-Overview">Overview</h2><p>The 
following diagram provides an overview of how the different pipelines, filters 
and dispatchers interact when pro
 cessing an incoming request.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource confluence-content-image-border" alt="Request 
Processing" 
src="https://cwiki-test.apache.org/confluence/download/attachments/22872133/tapestry_request_processing_800.png?version=1&amp;modificationDate=1299128361000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/22872133/tapestry_request_processing_800.png?version=1&amp;modificationDate=1299128361000&amp;api=v2";></span></p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/runtime-exceptions.html
==============================================================================
--- websites/production/tapestry/content/runtime-exceptions.html (original)
+++ websites/production/tapestry/content/runtime-exceptions.html Sun Feb 25 
23:20:05 2018
@@ -111,7 +111,7 @@ operationQueue, MappedConfiguration&lt;C
             return context;
         }
     }</pre>
-</div></div><p>The contributed exception handling mechanism can easily be 
overused. Typically, if you can handle the exception locally, you should. 
Likewise, you shouldn't blindly wrap any checked exceptions inside runtime 
exceptions just to avoid writing try-catch blocks in higher layers. The 
mechanism for contributed exception types is best used for handling serious but 
rarely occurring exceptions happening in the action request cycle that you 
cannot otherwise cope with.</p></div>
+</div></div><p>The contributed exception handling mechanism can easily be 
overused. Typically, if you can handle the exception locally, you should. 
Likewise, you shouldn't blindly wrap any checked exceptions inside runtime 
exceptions just to avoid writing try-catch blocks in higher layers. The 
mechanism for contributed exception types is best used for handling serious but 
rarely occurring exceptions happening in the action request cycle that you 
cannot otherwise cope with.</p><p></p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to