Author: buildbot
Date: Wed Nov 11 12:19:45 2015
New Revision: 972093

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/page-life-cycle.html
    websites/production/tapestry/content/request-processing.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

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 Wed Nov 11 
12:19:45 2015
@@ -125,7 +125,7 @@
                         
                     </div>
     </li></ul>
-</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. 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.</p><p>Because multiple requests are handled by many different 
threads, this means that the single instance's variable 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 pa
 ge 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><h2 id="PageLifeCycle-PageLifeCycleMethods">Page 
Life Cycle Methods</h2><p>There are a few situations 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>The page life cycle is 
quite simple. When first needed,
  a page is loaded. Loading a page involves instantiating the components of the 
page and connecting them together.</p><p>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.</p><p>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.</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 identifying methods to be 
invoked.</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" rowspa
 n="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"><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><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 t
 he 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 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 p
 age 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 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 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 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 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>
+</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. 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.</p><p>Because multiple requests are handled by many different 
threads, this means that the single instance's variable 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 pa
 ge 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><h2 id="PageLifeCycle-PageLifeCycleMethods">Page 
Life Cycle Methods</h2><p>There are a few situations 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>The page life cycle is 
quite simple. When first needed,
  a page is loaded. Loading a page involves instantiating the components of the 
page and connecting them together.</p><p>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.</p><p>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.</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 identifying methods to be 
invoked.</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" rowspa
 n="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"><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><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 t
 he 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 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 p
 age 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 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 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 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 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>
       </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 Wed Nov 11 
12:19:45 2015
@@ -125,7 +125,7 @@
                         
                     </div>
     </li></ul>
-</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>
 s
 ervice, 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.o
 rg/current/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 the basis for the planned 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 
RequestHand
 ler pipeline 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 termi
 nator for 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 Dispat
 cher</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 a
 ction request; 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 triggered 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
  redirect 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">Page Navigation</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 whe
 n processing an incoming request.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-content-image-border" 
src="request-processing.data/tapestry_request_processing_800.png"></span></p></div>
+</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>
 s
 ervice, 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.o
 rg/current/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 
RequestHandle
 r pipeline 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 termina
 tor for 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 Dispatch
 er</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 act
 ion request; 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 t
 o be triggered 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 r
 edirect 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">Page Navigation</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 
 processing an incoming request.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-content-image-border" 
src="request-processing.data/tapestry_request_processing_800.png"></span></p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to