Modified: websites/production/tapestry/content/security.html
==============================================================================
--- websites/production/tapestry/content/security.html (original)
+++ websites/production/tapestry/content/security.html Sat Feb  3 16:21:22 2018
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,10 +77,61 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry has a number of 
<strong>security</strong> features designed to harden your application against 
unwanted intrusion and denial of service.</p><p>&#160;</p><parameter 
ac:name="style">float:right</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter 
ac:name="class">aui-label</parameter><rich-text-body><parameter 
ac:name="showLabels">false</parameter><parameter 
ac:name="showSpace">false</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter ac:name="cql">label in ("spring","security") and 
space = currentSpace()</parameter></rich-text-body><p>&#160;</p><h2 
id="Security-HTTPS-onlyPages">HTTPS-only Pages</h2><p>Main Article: <a  
href="https.html">HTTPS</a></p><p>Tapestry provides several annotations and 
configuration settings that you can use to&#160;<span style="text-align: 
justify;line-height: 1.4285715;">ensure that all access to certain pages (or 
all pages) occurs only via the encrypted 
 HTTPS protocol</span><span style="text-align: justify;line-height: 
1.4285715;">. See&#160;<a  href="https.html">HTTPS</a> for 
details.</span></p><h2 id="Security-ControllingPageAccess"><span 
style="text-align: justify;line-height: 1.4285715;">Controlling Page 
Access</span></h2><p><plain-text-body>{float:right|background=#eee|padding=0 
1em}
-    *JumpStart Demo:*
-    [Protecting 
Pages|http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/protectingpages]
-{float}</plain-text-body><span style="text-align: justify;line-height: 
1.4285715;">For simple access control needs, you can contribute a&#160;<span><a 
 class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ComponentRequestFilter.html";>ComponentRequestFilter</a>
 with your custom logic that decides which pages should be accessed by which 
users. The <a  class="external-link" 
href="https://tapestry-app.apache.org/hotels/";>Tapestry Hotel Booking </a>app 
demonstrates this approach with an <code>@AnonymousAccess</code> annotation 
along with a ComponentRequestFilter 
named&#160;<code>AuthenticationFilter.java</code>. The filter enforces security 
by intercepting all requests to pages that don't have that annotation, and it 
redirects those requests to the login page. <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/protectingpages";
 rel="nofollow">JumpStart</a> has a similar demo.<br clear="no
 ne"></span></span></p><p><span style="line-height: 1.4285715;text-align: 
justify;">For more advanced needs see the Security Framework Integration 
section below.</span></p><h2 id="Security-White-listedPages">White-listed 
Pages</h2><p>Pages whose component classes are annotated with&#160;@<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/WhitelistAccessOnly.html";>WhitelistAccessOnly</a>&#160;will
 only be displayed to users (clients) that are on the&#160;<em>whitelist</em>. 
By default the whitelist consists only of clients whose fully-qualified domain 
name is "localhost" (or the IP address equivalent, 127.0.0.1 or 
0:0:0:0:0:0:0:1),&#160;but you can customize this by contributing to the 
ClientWhitelist service&#160;in your application's module class (usually 
AppModule.java):</p><parameter ac:name="language">java</parameter><parameter 
ac:name="title">AppModule.java (partial) -- simple inline 
example</parameter><plain-text-body>   
  @Contribute(ClientWhitelist.class)
+                <div id="ConfluenceContent"><p>Tapestry has a number of 
<strong>security</strong> features designed to harden your application against 
unwanted intrusion and denial of service.</p><p>&#160;</p><div 
class="aui-label" style="float:right" title="Related Articles">
+
+
+
+
+
+
+
+
+<h3>Related Articles</h3>
+
+<ul class="content-by-label"><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="security.html">Security</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  
href="integrating-with-spring-framework.html">Integrating with Spring 
Framework</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="security-faq.html">Security FAQ</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="https.html">HTTPS</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div>
+
+
+<p>&#160;</p><h2 id="Security-HTTPS-onlyPages">HTTPS-only Pages</h2><p>Main 
Article: <a  href="security.html">Security</a></p><p>Tapestry provides several 
annotations and configuration settings that you can use to&#160;<span>ensure 
that all access to certain pages (or all pages) occurs only via the encrypted 
HTTPS protocol</span><span>. See&#160;<a  href="security.html">Security</a> for 
details.</span></p><h2 id="Security-ControllingPageAccess"><span>Controlling 
Page Access</span></h2><p></p><div class="navmenu" style="float:right; 
background:#eee; margin:3px; padding:0 1em">
+<p>    <strong>JumpStart Demo:</strong><br clear="none">
+    <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/protectingpages";
 rel="nofollow">Protecting Pages</a></p></div><span>For simple access control 
needs, you can contribute a&#160;<span><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ComponentRequestFilter.html";>ComponentRequestFilter</a>
 with your custom logic that decides which pages should be accessed by which 
users. The <a  class="external-link" 
href="https://tapestry-app.apache.org/hotels/";>Tapestry Hotel Booking </a>app 
demonstrates this approach with an <code>@AnonymousAccess</code> annotation 
along with a ComponentRequestFilter 
named&#160;<code>AuthenticationFilter.java</code>. The filter enforces security 
by intercepting all requests to pages that don't have that annotation, and it 
redirects those requests to the login page. <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples
 /infrastructure/protectingpages" rel="nofollow">JumpStart</a> has a similar 
demo.<br clear="none"></span></span><p><span>For more advanced needs see the 
Security Framework Integration section below.</span></p><h2 
id="Security-White-listedPages">White-listed Pages</h2><p>Pages whose component 
classes are annotated with&#160;@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/WhitelistAccessOnly.html";>WhitelistAccessOnly</a>&#160;will
 only be displayed to users (clients) that are on the&#160;<em>whitelist</em>. 
By default the whitelist consists only of clients whose fully-qualified domain 
name is "localhost" (or the IP address equivalent, 127.0.0.1 or 
0:0:0:0:0:0:0:1),&#160;but you can customize this by contributing to the 
ClientWhitelist service&#160;in your application's module class (usually 
AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-
 width: 1px;"><b>AppModule.java (partial) &#8211; simple inline 
example</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">    @Contribute(ClientWhitelist.class)
     public static void 
provideWhitelistAnalyzer(OrderedConfiguration&lt;WhitelistAnalyzer&gt; 
configuration)
     {
         configuration.add("MyCustomAnalyzer", new WhitelistAnalyzer()
@@ -81,7 +142,10 @@
                 return true;
             }
         }, "before:*");
-    }</plain-text-body><p>&#160;</p><p>Sometimes, in production, a firewall or 
proxy may make it look like the client web browser originates from localhost, 
with the consequence that whitelisted pages may be visible to all users. See 
the&#160;<a  href="security.html">Security FAQ</a> for how to deal with 
this.</p><h2 id="Security-AssetSecurity">Asset Security</h2><p>Main 
Article:&#160;<a  href="assets.html">Assets</a></p><p>Tapestry serves assets 
(static content such as CSS files, images, and JavaScript, many of which are on 
the classpath alongside your compiled class files) to the client.&#160;Because 
of this, great care has gone into ensuring that certain file types cannot be 
served to the client. By default, file ending with ".class', ".tml" and 
".properties" can be served to the client only if the request includes the 
file's MD5 checksum. As you would expect, that blacklist can be extended. 
See&#160;<a  href="assets.html">Asset Security</a> for more information.</p><h2 
id="Secur
 ity-ProtectingSerializedObjectDataontheClient">Protecting Serialized Object 
Data on the Client</h2><p><span style="color: rgb(0,0,0);">As of version 5.3.6, 
Tapestry integrates a&#160;</span><a  class="external-link" 
href="http://en.wikipedia.org/wiki/HMAC"; rel="nofollow" style="text-decoration: 
underline;text-align: justify;">hash-based message authentication code</a><span 
style="color: rgb(0,0,0);">&#160;(HMAC) into serialized Java object data that 
it sends to the client (generally, this means the&#160;</span><code 
style="text-align: justify;">t:formdata</code><span style="color: 
rgb(0,0,0);">&#160;hidden field used by the Form component). This ensures that 
the hidden binary object data is guaranteed to be unaltered when it returns to 
the server upon form (or AJAX) submission. The HMAC pass phrase is set using 
the&#160;<a  href="configuration.html">tapestry.hmac-passphrase</a> 
configuration symbol. If you don't set that value, you'll see a warning message 
in the browser, like this:
 &#160;</span></p><plain-text-body>The symbol 'tapestry.hmac-passphrase' has 
not been configured. This is used to configure hash-based message 
authentication of Tapestry data stored in forms, or in the URL. You application 
is less secure, and more vulnerable to denial-of-service attacks, when this 
symbol is not configured.</plain-text-body><p><span style="color: 
rgb(0,0,0);">The solution is to set the tapestry.hmac-passphrase to some value 
(any fixed, private string, such as 30 to 40 random-looking characters, will 
do) in your application's module class (usually AppModule.java).</span></p><h2 
id="Security-CrossSiteRequestForgery(CSRF)"><span style="color: 
rgb(83,145,38);font-size: 20.0px;line-height: 1.5;">Cross Site Request Forgery 
(CSRF)</span></h2><p>Cross Site Request Forgery is a type of security 
vulnerability in which legitimate, authorized users may be made to unwittingly 
submit malicious requests to your web application.</p><p><a  
class="external-link" href="https://github.co
 m/porscheinformatik/tapestry-csrf-protection" 
rel="nofollow">Tapestry-csrf-protection</a>&#160;is a 3rd party module that has 
several features for preventing CSRF attacks. It protects 
all&#160;<span>component event handlers (event links, forms, etc.) by adding 
a&#160;</span><span>CSRF token to event links and adds a CSRF token as a hidden 
field to all forms.&#160;</span><span>Tokens are generated on a per-session 
basis.</span></p><h2 id="Security-SecurityFrameworkIntegration"><span 
style="line-height: 1.5;">Security Framework Integration</span></h2><p>Tapestry 
does not lock you into a specific authentication/authorization implementation. 
There are integration modules available for the more popular open source Java 
security frameworks. A popular choice among Tapestry users is <a  
class="external-link" href="http://www.tynamo.org/tapestry-security+guide/"; 
rel="nofollow">tapestry-security (based on Apache Shiro) from Tynamo.org</a>. 
It is always kept up-to-date with the latest Tapestry
  versions and offers several supporting security modules (e.g. <a  
class="external-link" href="http://www.tynamo.org/tapestry-security-jpa+guide/"; 
rel="nofollow">tapestry-security-jpa</a>, <a  class="external-link" 
href="http://www.tynamo.org/tynamo-federatedaccounts+guide/"; 
rel="nofollow">tynamo-federatedaccounts</a>). There's also an <a  
class="external-link" 
href="http://www.localhost.nu/java/tapestry-spring-security"; 
rel="nofollow">integration module available for Spring Security</a> but lately, 
it hasn't kept up with the latest versions of Tapestry 5.</p><p>Additional 
information:</p><ul><li><a  class="external-link" 
href="http://www.tynamo.org/tynamo-federatedaccounts+guide/"; 
rel="nofollow">Tynamo-federatedaccounts</a>&#160;<span style="color: 
rgb(0,0,0);">is an add-on to the&#160;</span><a  class="external-link" 
href="http://www.tynamo.org/tapestry-security+guide/"; 
rel="nofollow">tapestry-security</a><span style="color: 
rgb(0,0,0);">&#160;module, providing federated (third-pa
 rty) authentication with Facebook, Twitter or 
Google.</span></li></ul><ul><li><span style="line-height: 1.4285715;">To 
include OpenID with Spring Security in your application, see the following Wiki 
entry:&#160;</span><a  class="external-link" 
href="http://wiki.apache.org/tapestry/Tapestry5HowToSpringSecurityAndOpenId"; 
style="line-height: 
1.4285715;">http://wiki.apache.org/tapestry/Tapestry5HowToSpringSecurityAndOpenId</a></li></ul><p>&#160;</p></div>
+    }</pre>
+</div></div><p>&#160;</p><p>Sometimes, in production, a firewall or proxy may 
make it look like the client web browser originates from localhost, with the 
consequence that whitelisted pages may be visible to all users. See the&#160;<a 
 href="security.html">Security FAQ</a> for how to deal with this.</p><h2 
id="Security-AssetSecurity">Asset Security</h2><p>Main Article:&#160;<a  
href="security.html">Security</a></p><p>Tapestry serves assets (static content 
such as CSS files, images, and JavaScript, many of which are on the classpath 
alongside your compiled class files) to the client.&#160;Because of this, great 
care has gone into ensuring that certain file types cannot be served to the 
client. By default, file ending with ".class', ".tml" and ".properties" can be 
served to the client only if the request includes the file's MD5 checksum. As 
you would expect, that blacklist can be extended. See&#160;<a  
href="security.html">Asset Security</a> for more information.</p><h2 
id="Security-P
 rotectingSerializedObjectDataontheClient">Protecting Serialized Object Data on 
the Client</h2><p><span style="color: rgb(0,0,0);">As of version 5.3.6, 
Tapestry integrates a&#160;</span><a  class="external-link" 
href="http://en.wikipedia.org/wiki/HMAC"; rel="nofollow" style="text-decoration: 
underline;text-align: justify;">hash-based message authentication code</a><span 
style="color: rgb(0,0,0);">&#160;(HMAC) into serialized Java object data that 
it sends to the client (generally, this means the&#160;</span><code 
style="text-align: justify;">t:formdata</code><span style="color: 
rgb(0,0,0);">&#160;hidden field used by the Form component). This ensures that 
the hidden binary object data is guaranteed to be unaltered when it returns to 
the server upon form (or AJAX) submission. The HMAC pass phrase is set using 
the&#160;<a  href="security.html">tapestry.hmac-passphrase</a> configuration 
symbol. If you don't set that value, you'll see a warning message in the 
browser, like this:&#160;</sp
 an></p><div class="preformatted panel" style="border-width: 1px;"><div 
class="preformattedContent panelContent">
+<pre>The symbol 'tapestry.hmac-passphrase' has not been configured. This is 
used to configure hash-based message authentication of Tapestry data stored in 
forms, or in the URL. You application is less secure, and more vulnerable to 
denial-of-service attacks, when this symbol is not configured.</pre>
+</div></div><p><span style="color: rgb(0,0,0);">The solution is to set the 
tapestry.hmac-passphrase to some value (any fixed, private string, such as 30 
to 40 random-looking characters, will do) in your application's module class 
(usually AppModule.java).</span></p><h2 
id="Security-CrossSiteRequestForgery(CSRF)"><span style="color: 
rgb(83,145,38);">Cross Site Request Forgery (CSRF)</span></h2><p>Cross Site 
Request Forgery is a type of security vulnerability in which legitimate, 
authorized users may be made to unwittingly submit malicious requests to your 
web application.</p><p><a  class="external-link" 
href="https://github.com/porscheinformatik/tapestry-csrf-protection"; 
rel="nofollow">Tapestry-csrf-protection</a>&#160;is a 3rd party module that has 
several features for preventing CSRF attacks. It protects 
all&#160;<span>component event handlers (event links, forms, etc.) by adding 
a&#160;</span><span>CSRF token to event links and adds a CSRF token as a hidden 
field to all forms.&#16
 0;</span><span>Tokens are generated on a per-session basis.</span></p><h2 
id="Security-SecurityFrameworkIntegration"><span>Security Framework 
Integration</span></h2><p>Tapestry does not lock you into a specific 
authentication/authorization implementation. There are integration modules 
available for the more popular open source Java security frameworks. A popular 
choice among Tapestry users is <a  class="external-link" 
href="http://www.tynamo.org/tapestry-security+guide/"; 
rel="nofollow">tapestry-security (based on Apache Shiro) from Tynamo.org</a>. 
It is always kept up-to-date with the latest Tapestry versions and offers 
several supporting security modules (e.g. <a  class="external-link" 
href="http://www.tynamo.org/tapestry-security-jpa+guide/"; 
rel="nofollow">tapestry-security-jpa</a>, <a  class="external-link" 
href="http://www.tynamo.org/tynamo-federatedaccounts+guide/"; 
rel="nofollow">tynamo-federatedaccounts</a>). There's also an <a  
class="external-link" href="http://www.localhost
 .nu/java/tapestry-spring-security" rel="nofollow">integration module available 
for Spring Security</a> but lately, it hasn't kept up with the latest versions 
of Tapestry 5.</p><p>Additional information:</p><ul><li><a  
class="external-link" 
href="http://www.tynamo.org/tynamo-federatedaccounts+guide/"; 
rel="nofollow">Tynamo-federatedaccounts</a>&#160;<span style="color: 
rgb(0,0,0);">is an add-on to the&#160;</span><a  class="external-link" 
href="http://www.tynamo.org/tapestry-security+guide/"; 
rel="nofollow">tapestry-security</a><span style="color: 
rgb(0,0,0);">&#160;module, providing federated (third-party) authentication 
with Facebook, Twitter or Google.</span></li></ul><ul><li><span>To include 
OpenID with Spring Security in your application, see the following Wiki 
entry:&#160;</span><a  class="external-link" 
href="http://wiki.apache.org/tapestry/Tapestry5HowToSpringSecurityAndOpenId";>http://wiki.apache.org/tapestry/Tapestry5HowToSpringSecurityAndOpenId</a></li></ul><p>&#160;</p></div
 >
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/session-storage.html
==============================================================================
--- websites/production/tapestry/content/session-storage.html (original)
+++ websites/production/tapestry/content/session-storage.html Sat Feb  3 
16:21:22 2018
@@ -119,14 +119,14 @@
 </div>
 
 
-<p>Ordinary <a  href="persistent-page-data.html">page-persistent fields</a> 
won't work for this, since persistent fields are available only to a specific 
page, not shared across multiple pages.</p><p>Tapestry provides two mechanisms 
for storing such data: Session State Objects and Session Attributes. When 
deciding between the two, it's best to use Session State Objects for complex 
objects, and Session Attributes for simple types.</p><h2 
id="SessionStorage-SessionStateObjects">Session State Objects</h2><p>With a 
Session State Object (SSO), the value is automatically stored outside the page; 
with the default storage strategy, it is stored in the session. Such a value is 
global to all pages <em>for the same user</em>, but is stored separately for 
different users.</p><p>A field holding an SSO is marked with the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SessionState.html";>SessionState</a>
 annotation.</p><div class="navmen
 u" style="float:right; background:white; margin:3px; padding:3px">
+<p>Ordinary <a  href="session-storage.html">page-persistent fields</a> won't 
work for this, since persistent fields are available only to a specific page, 
not shared across multiple pages.</p><p>Tapestry provides two mechanisms for 
storing such data: Session State Objects and Session Attributes. When deciding 
between the two, it's best to use Session State Objects for complex objects, 
and Session Attributes for simple types.</p><h2 
id="SessionStorage-SessionStateObjects">Session State Objects</h2><p>With a 
Session State Object (SSO), the value is automatically stored outside the page; 
with the default storage strategy, it is stored in the session. Such a value is 
global to all pages <em>for the same user</em>, but is stored separately for 
different users.</p><p>A field holding an SSO is marked with the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SessionState.html";>SessionState</a>
 annotation.</p><div class="navmenu" st
 yle="float:right; background:white; margin:3px; padding:3px">
 <div class="panel" style="border-width: 1px;"><div class="panelHeader" 
style="border-bottom-width: 1px;"><b>Contents</b></div><div 
class="panelContent">
 <style type="text/css">/*<![CDATA[*/
-div.rbtoc1499639543191 {padding: 0px;}
-div.rbtoc1499639543191 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1499639543191 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1517674844246 {padding: 0px;}
+div.rbtoc1517674844246 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1517674844246 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style><div class="toc-macro rbtoc1499639543191">
+/*]]>*/</style><div class="toc-macro rbtoc1517674844246">
 <ul class="toc-indentation"><li>Related Articles</li></ul>
 <ul><li><a  href="#SessionStorage-SessionStateObjects">Session State 
Objects</a>
 <ul class="toc-indentation"><li><a  
href="#SessionStorage-Pitfalls">Pitfalls</a></li><li><a  
href="#SessionStorage-CheckforCreation">Check for Creation</a></li><li><a  
href="#SessionStorage-PersistenceStrategies">Persistence 
Strategies</a></li><li><a  href="#SessionStorage-ConfiguringSSOs">Configuring 
SSOs</a></li></ul>
@@ -161,7 +161,7 @@ div.rbtoc1499639543191 li {margin-left:
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @SessionState(create=false)
   private ShoppingCart shoppingCart;
 </pre>
-</div></div><p>In this case, the shoppingCart field will be null if the 
ShoppingCart SSO does not exist, but will be non-null if it has been created 
(either by assigning a value to the field, or by a different SSO field where 
create is true).</p><h3 id="SessionStorage-PersistenceStrategies">Persistence 
Strategies</h3><p>Main Article: <a  href="persistent-page-data.html">Persistent 
Page Data</a></p><p>Each SSO is managed according to a persistence strategy. 
The default persistence strategy, "session", stores the SSOs inside the 
session. The session is created as needed.</p><h3 
id="SessionStorage-ConfiguringSSOs">Configuring SSOs</h3><p>Generally, you will 
need to configure your Session State Object if you want to change the 
persistence strategy to other than the default. (Right now there's only one 
built in strategy, but more will be coming in the future.)</p><p>Alternately, 
you can configure a Session State Object in order to control how it is 
instantiated. You may need to inject so
 me values into the SSO when it is first created, or otherwise initialize it. 
In this case, you may provide an <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ApplicationStateCreator.html";>ApplicationStateCreator</a>
 object, which will be called upon to create the SSO as necessary. This is also 
the technique to use when you want your SSO to be represented by an 
<em>interface</em> rather than a <em>class</em>: you need to provide a creator 
that knows about the class that implements the interface.</p><p>A Session State 
Object is configured using contributions to the ApplicationStateManager 
service. From your application's module:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>In this case, the shoppingCart field will be null if the 
ShoppingCart SSO does not exist, but will be non-null if it has been created 
(either by assigning a value to the field, or by a different SSO field where 
create is true).</p><h3 id="SessionStorage-PersistenceStrategies">Persistence 
Strategies</h3><p>Main Article: <a  href="session-storage.html">Persistent Page 
Data</a></p><p>Each SSO is managed according to a persistence strategy. The 
default persistence strategy, "session", stores the SSOs inside the session. 
The session is created as needed.</p><h3 
id="SessionStorage-ConfiguringSSOs">Configuring SSOs</h3><p>Generally, you will 
need to configure your Session State Object if you want to change the 
persistence strategy to other than the default. (Right now there's only one 
built in strategy, but more will be coming in the future.)</p><p>Alternately, 
you can configure a Session State Object in order to control how it is 
instantiated. You may need to inject some va
 lues into the SSO when it is first created, or otherwise initialize it. In 
this case, you may provide an <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ApplicationStateCreator.html";>ApplicationStateCreator</a>
 object, which will be called upon to create the SSO as necessary. This is also 
the technique to use when you want your SSO to be represented by an 
<em>interface</em> rather than a <em>class</em>: you need to provide a creator 
that knows about the class that implements the interface.</p><p>A Session State 
Object is configured using contributions to the ApplicationStateManager 
service. From your application's module:</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;">  public void 
contributeApplicationStateManager(MappedConfiguration&lt;Class, 
ApplicationStateContribution&gt; configuration)
   {
     ApplicationStateCreator&lt;MyState&gt; creator = new 
ApplicationStateCreator&lt;ShoppingCart&gt;()
@@ -212,33 +212,7 @@ public class Page {
     private User userName;
 }
 </pre>
-</div></div><p></p><h2 id="SessionStorage-ClusteringIssues">Clustering 
Issues</h2>
-
-<p>The Servlet API was designed with the intention that there would be only a 
modest amount of server-side state, and that the stored values would be 
individual numbers and strings, and thus, immutable.</p>
-
-<p>However, many web applications do not use the HttpSession this way, instead 
storing large, mutable objects in the session. This is not a problem for single 
servers, but in a cluster, anything stored in the session must be serialized to 
a bytestream and distributed to other servers within the cluster, and restored 
there.</p>
-
-<p>Most application servers perform that serialization and distribution 
whenever HttpSession.setAttribute() is called. This creates a data consistency 
problem for mutable objects, because if you read a mutable session object, 
change its state, but <em>don't</em> invoke setAttribute(), the changes will be 
isolated to just a single server in the cluster.</p>
-
-<p>Tapestry attempts to solve this: any session-persisted object that is read 
during a request will be re-stored back into the HttpSession at the end of the 
request. This ensures that changed internal state of those mutable objects is 
properly replicated around the cluster.</p>
-
-<p>But while this solution solves the data consistency problem, it does so at 
the expense of performance, since all of those calls to setAttribute() result 
in extra session data being replicated needlessly if the internal state of the 
mutable object hasn't changed.</p>
-
-<p>Tapestry has solutions to this, too:</p>
-
-<h3 
id="SessionStorage-@ImmutableSessionPersistedObjectAnnotation">@ImmutableSessionPersistedObject
 Annotation</h3>
-
-<p>Tapestry knows that Java's String, Number and Boolean classes are 
immutable. Immutable objects do not require a re-store into the session.</p>
-
-<p>You can mark your own session objects as immutable (and thus not requiring 
session replication) using the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/ImmutableSessionPersistedObject.html";>ImmutableSessionPersistedObject</a>
 annotation.</p>
-
-<h3 
id="SessionStorage-OptimizedSessionPersistedObjectInterface">OptimizedSessionPersistedObject
 Interface</h3>
-
-<p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/OptimizedSessionPersistedObject";>OptimizedSessionPersistedObject</a>
 interface allows an object to control this behavior. An object with this 
interface can track when its mutable state changes. Typically, you should 
extend from the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.html";>BaseOptimizedSessionPersistedObject</a>
 base class.</p>
-
-<h3 
id="SessionStorage-SessionPersistedObjectAnalyzerService">SessionPersistedObjectAnalyzer
 Service</h3>
-
-<p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/SessionPersistedObjectAnalyzer.html";>SessionPersistedObjectAnalyzer</a>
 service is ultimately responsible for determining whether a session persisted 
object is dirty or not (dirty meaning in need of a restore into the session). 
This is an extensible service where new strategies, for new classes, can be 
introduced.</p><h2 id="SessionStorage-SessionLocking">Session 
Locking</h2><p>Starting with version 5.4, by default Tapestry will apply 
locking semantics around access to the HttpSession. Reading attribute names 
occurs with a shared read lock, and getting or setting an attribute upgrades 
the lock to an exclusive write lock. This can tend to serialize threads when a 
number of simultaneous (Ajax) requests from the client arrive. However, many 
implementations of HttpSession are not thread safe, and often mutable 
objects<br clear="none"> are stored in the session and shared betwe
 en threads.</p><p>The <code>tapestry.session-locking-enabled</code> <a  
href="configuration.html">symbol</a> can control this behavior. Setting this to 
true (the default) will yield a more robust application; setting it to false 
may speed up processing for more Ajax intensive applications (but care should 
then be given to ensuring that objects shared inside the session are 
themeselves immutable or thread-safe).</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>AppModule.java (partial)</b></div><div 
class="codeContent panelContent pdl">
+</div></div><p></p><h2 id="SessionStorage-ClusteringIssues">Clustering 
Issues</h2><p>The Servlet API was designed with the intention that there would 
be only a modest amount of server-side state, and that the stored values would 
be individual numbers and strings, and thus, immutable.</p><p>However, many web 
applications do not use the HttpSession this way, instead storing large, 
mutable objects in the session. This is not a problem for single servers, but 
in a cluster, anything stored in the session must be serialized to a bytestream 
and distributed to other servers within the cluster, and restored 
there.</p><p>Most application servers perform that serialization and 
distribution whenever HttpSession.setAttribute() is called. This creates a data 
consistency problem for mutable objects, because if you read a mutable session 
object, change its state, but <em>don't</em> invoke setAttribute(), the changes 
will be isolated to just a single server in the cluster.</p><p>Tapestry 
attempts to
  solve this: any session-persisted object that is read during a request will 
be re-stored back into the HttpSession at the end of the request. This ensures 
that changed internal state of those mutable objects is properly replicated 
around the cluster.</p><p>But while this solution solves the data consistency 
problem, it does so at the expense of performance, since all of those calls to 
setAttribute() result in extra session data being replicated needlessly if the 
internal state of the mutable object hasn't changed.</p><p>Tapestry has 
solutions to this, too:</p><h3 
id="SessionStorage-@ImmutableSessionPersistedObjectAnnotation">@ImmutableSessionPersistedObject
 Annotation</h3><p>Tapestry knows that Java's String, Number and Boolean 
classes are immutable. Immutable objects do not require a re-store into the 
session.</p><p>You can mark your own session objects as immutable (and thus not 
requiring session replication) using the <a  class="external-link" 
href="http://tapestry.apache.org/cu
 
rrent/apidocs/org/apache/tapestry5/annotations/ImmutableSessionPersistedObject.html">ImmutableSessionPersistedObject</a>
 annotation.</p><h3 
id="SessionStorage-OptimizedSessionPersistedObjectInterface">OptimizedSessionPersistedObject
 Interface</h3><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/OptimizedSessionPersistedObject";>OptimizedSessionPersistedObject</a>
 interface allows an object to control this behavior. An object with this 
interface can track when its mutable state changes. Typically, you should 
extend from the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.html";>BaseOptimizedSessionPersistedObject</a>
 base class.</p><h3 
id="SessionStorage-SessionPersistedObjectAnalyzerService">SessionPersistedObjectAnalyzer
 Service</h3><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Sessi
 onPersistedObjectAnalyzer.html">SessionPersistedObjectAnalyzer</a> service is 
ultimately responsible for determining whether a session persisted object is 
dirty or not (dirty meaning in need of a restore into the session). This is an 
extensible service where new strategies, for new classes, can be 
introduced.</p><h2 id="SessionStorage-SessionLocking">Session 
Locking</h2><p>Starting with version 5.4, by default Tapestry will apply 
locking semantics around access to the HttpSession. Reading attribute names 
occurs with a shared read lock, and getting or setting an attribute upgrades 
the lock to an exclusive write lock. This can tend to serialize threads when a 
number of simultaneous (Ajax) requests from the client arrive. However, many 
implementations of HttpSession are not thread safe, and often mutable 
objects<br clear="none"> are stored in the session and shared between 
threads.</p><p>The <code>tapestry.session-locking-enabled</code> <a  
href="session-storage.html">symbol</a> can co
 ntrol this behavior. Setting this to true (the default) will yield a more 
robust application; setting it to false may speed up processing for more Ajax 
intensive applications (but care should then be given to ensuring that objects 
shared inside the session are themeselves immutable or thread-safe).</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>AppModule.java 
(partial)</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static void 
contributeApplicationDefaults(MappedConfiguration&lt;String,String&gt; 
configuration)
   {
     configuration.add(SymbolConstants.SESSION_LOCKING_ENABLED, true);

Modified: 
websites/production/tapestry/content/unit-testing-pages-or-components.html
==============================================================================
--- websites/production/tapestry/content/unit-testing-pages-or-components.html 
(original)
+++ websites/production/tapestry/content/unit-testing-pages-or-components.html 
Sat Feb  3 16:21:22 2018
@@ -44,13 +44,26 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
+
+</div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
- <input type="text" name="q"> 
- <input type="submit" value="Search"> 
-</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Unit testing pages or components</h1></div></div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
+<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
+  <input type="text" name="q">
+  <input type="submit" value="Search">
+</form>
+
+</div>
+
+
+<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
+
+
+<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Unit testing pages or components</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -62,19 +75,40 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry provides support for 
easily <strong>unit testing your pages and components</strong>. Follow the 
simple steps below.</p><div class="aui-label" style="float:right" 
title="Related Articles"><h3>Related Articles</h3><ul 
class="content-by-label"><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="integration-testing.html">Integration Testing</a> 
-  </div> </li><li> 
-  <div> 
-   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
-  </div> 
-  <div class="details"> 
-   <a  href="unit-testing-pages-or-components.html">Unit testing pages or 
components</a> 
-  </div> </li></ul></div><h2 
id="Unittestingpagesorcomponents-Settingupadrivingenvironment">Setting up a 
driving environment</h2><p>In order to unit test a page, you'll need to create 
an instance of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html";>PageTester</a>.
 It acts as both the browser and the servlet container so that you can use it 
to drive your page.</p><p>The PageTester falls into a middle ground between 
pure unit testing and <a  href="integration-testing.html">full-scale 
integration testing</a>.</p><p>As the PageTester is not a real servlet 
container, you need to tell it the same information as you would in 
web.xml:</p><ol><li>Your application package.</li><li>Your filter name. This is 
used to load your Tapestry IoC module only. If you have none, you can pass an 
empty string or anything to it.</li><li>The folder acting as your context root. 
This is used to locate your templates (if they're put there).Here
  is an example (using TestNG, but you're free to use JUnit or anything 
else):</li></ol><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+                <div id="ConfluenceContent"><p>Tapestry provides support for 
easily <strong>unit testing your pages and components</strong>. Follow the 
simple steps below.</p><div class="aui-label" style="float:right" 
title="Related Articles">
+
+
+
+
+
+
+
+
+<h3>Related Articles</h3>
+
+<ul class="content-by-label"><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="integration-testing.html">Integration 
Testing</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="unit-testing-pages-or-components.html">Unit 
testing pages or components</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div>
+
+
+<h2 id="Unittestingpagesorcomponents-Settingupadrivingenvironment">Setting up 
a driving environment</h2><p>In order to unit test a page, you'll need to 
create an instance of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html";>PageTester</a>.
 It acts as both the browser and the servlet container so that you can use it 
to drive your page.</p><p>The PageTester falls into a middle ground between 
pure unit testing and <a  
href="unit-testing-pages-or-components.html">full-scale integration 
testing</a>.</p><p>As the PageTester is not a real servlet container, you need 
to tell it the same information as you would in web.xml:</p><ol><li>Your 
application package.</li><li>Your filter name. This is used to load your 
Tapestry IoC module only. If you have none, you can pass an empty string or 
anything to it.</li><li>The folder acting as your context root. This is used to 
locate your templates (if they're put there).Here is an examp
 le (using TestNG, but you're free to use JUnit or anything 
else):</li></ol><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;">public class MyTest extends Assert
 {
     @Test

Modified: websites/production/tapestry/content/uploading-files.html
==============================================================================
--- websites/production/tapestry/content/uploading-files.html (original)
+++ websites/production/tapestry/content/uploading-files.html Sat Feb  3 
16:21:22 2018
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,20 +77,24 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Tapestry provides a file upload 
component based on <a  class="external-link" 
href="http://commons.apache.org/fileupload/";>Apache Commons FileUpload</a> to 
make it easier to handle files uploaded through web forms (via the standard 
&lt;input type="file"&gt; HTML element).</p><h1 
id="UploadingFiles-Downloading">Downloading</h1><p><strong>tapestry-upload</strong>
 is not automatically included in Tapestry applications because of the 
additional dependencies it requires. To include it, just add the 
<code>tapestry-upload</code> dependency to the pom of your application, 
something like this:</p><parameter 
ac:name="language">xml</parameter><plain-text-body>&lt;dependency&gt;
+                <div id="ConfluenceContent"><p>Tapestry provides a file upload 
component based on <a  class="external-link" 
href="http://commons.apache.org/fileupload/";>Apache Commons FileUpload</a> to 
make it easier to handle files uploaded through web forms (via the standard 
&lt;input type="file"&gt; HTML element).</p><h1 
id="UploadingFiles-Downloading">Downloading</h1><p><strong>tapestry-upload</strong>
 is not automatically included in Tapestry applications because of the 
additional dependencies it requires. To include it, just add the 
<code>tapestry-upload</code> dependency to the pom of your application, 
something like this:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;dependency&gt;
     &lt;groupId&gt;org.apache.tapestry&lt;/groupId&gt;
     &lt;artifactId&gt;tapestry-upload&lt;/artifactId&gt;
     &lt;version&gt;${tapestry-release-version}&lt;/version&gt;
 &lt;/dependency&gt;
-</plain-text-body><p>If you aren't using Maven, you'll have to download the 
jar and its dependencies yourself.</p><h1 
id="UploadingFiles-Usage">Usage</h1><p>The upload component supports default 
value binding (based on id) and 
validation.</p><plain-text-body>{float:right|background=#eee|padding=0 1em}
-    *JumpStart Demo:*
-    [File 
Upload|http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/fileupload]
-{float}</plain-text-body><h2 id="UploadingFiles-ComponentTemplate">Component 
Template</h2><parameter ac:name="language">java</parameter><plain-text-body>    
&lt;t:form&gt;
+</pre>
+</div></div><p>If you aren't using Maven, you'll have to download the jar and 
its dependencies yourself.</p><h1 id="UploadingFiles-Usage">Usage</h1><p>The 
upload component supports default value binding (based on id) and 
validation.</p><div class="navmenu" style="float:right; background:#eee; 
margin:3px; padding:0 1em">
+<p>    <strong>JumpStart Demo:</strong><br clear="none">
+    <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/fileupload";
 rel="nofollow">File Upload</a></p></div><h2 
id="UploadingFiles-ComponentTemplate">Component Template</h2><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;">    &lt;t:form&gt;
         &lt;t:errors/&gt;
         &lt;input t:type="upload" t:id="file" t:value="file" 
validate="required"/&gt;
         &lt;br/&gt;
         &lt;input type="submit" value="Upload"/&gt;
-    &lt;/t:form&gt;</plain-text-body><p>Here, because the value parameter was 
not bound, the component used the file property of its container (because the 
component's id is 'file'). If you want to upload as a different property, 
either bind the value parameter or change the component's id.</p><h2 
id="UploadingFiles-Pageclass">Page class</h2><parameter 
ac:name="language">java</parameter><plain-text-body>    public class 
UploadExample
+    &lt;/t:form&gt;</pre>
+</div></div><p>Here, because the value parameter was not bound, the component 
used the file property of its container (because the component's id is 'file'). 
If you want to upload as a different property, either bind the value parameter 
or change the component's id.</p><h2 id="UploadingFiles-Pageclass">Page 
class</h2><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;">    public class UploadExample
     {
         @Property
         private UploadedFile file;
@@ -91,7 +105,9 @@
             
             file.write(copied);
         }
-    }</plain-text-body><h1 id="UploadingFiles-UploadExceptions">Upload 
Exceptions</h1><p>In some cases, file uploads may fail. This can be because of 
a simple communication exception, or more likely, because the configured 
maximum upload size was exceeded.</p><p>When a file upload exception occurs, 
Tapestry will trigger a "uploadException" event on the page to notify it of the 
error. All other normal processing is skipped (no "activate" event, no form 
submission, etc.).</p><p>The event handler should return a non-null object, 
which will be handled as a navigational result. Example:</p><parameter 
ac:name="language">java</parameter><plain-text-body>   
@Persist(PersistenceConstants.FLASH)
+    }</pre>
+</div></div><h1 id="UploadingFiles-UploadExceptions">Upload 
Exceptions</h1><p>In some cases, file uploads may fail. This can be because of 
a simple communication exception, or more likely, because the configured 
maximum upload size was exceeded.</p><p>When a file upload exception occurs, 
Tapestry will trigger a "uploadException" event on the page to notify it of the 
error. All other normal processing is skipped (no "activate" event, no form 
submission, etc.).</p><p>The event handler should return a non-null object, 
which will be handled as a navigational result. Example:</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;">   @Persist(PersistenceConstants.FLASH)
     @Property
     private String message;
 
@@ -101,7 +117,8 @@
         message = "Upload exception: " + ex.getMessage();
 
         return this;
-    }</plain-text-body><p>Note the importance of <code>return this;</code>. A 
void event handler method, or one that returns null, will result in the 
FileUploadException being reported to the user as an uncaught runtime 
exception.</p><h1 id="UploadingFiles-Configuration">Configuration</h1><p>Four 
values may be configured as <a  href="symbols.html">symbols</a>:</p><div 
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>upload.repository-location</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>The directory to which files 
that are too large to keep in memory will be written to. The default is from 
the java.io.tmpdir system property.</p></td></tr><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>upload.repository-threshold</p></th><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Upload size, in bytes, at which 
point the uploaded file is written to disk rather than kept in memory. The 
default is 10 kiloby
 tes.</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.requestsize-max</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Maximim size, in bytes, for the overall 
request. If exceeded, a FileUploadException will occur. The default is no 
maximum.</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.filesize-max</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Maximum size, in bytes, for any individual uploaded 
file. Again, a FileUploadException will occur if exceeded. The default is no 
maximum.</p></td></tr></tbody></table></div><p>The class <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/upload/services/UploadSymbols.html";>UploadSymbols</a>
 defines constants for all four of these.</p><h1 
id="UploadingFiles-PotentialIssues">Potential Issues</h1><p>The Commons 
FileUpload library uses the CommonsIO file cleaner service to remove temporary 
files when they are no longer nee
 ded. This service creates a thread to carry out its work. If the commons-io 
library is shared amongst multiple applications (e.g. added to server 
classpath) it is possible for an application to terminate this thread 
prematurely and cause errors for the other applications. (see the <a  
class="external-link" 
href="http://jakarta.apache.org/commons/fileupload/using.html";>Resource 
Cleanup</a> section in for more discussion)</p><p>Technically the file cleanup 
service is not needed by Tapestry Upload (which deletes temporary files at the 
end of request processing). However it is currently not possible to disable it 
(enhancement request has been filed as <a  class="external-link" 
href="https://issues.apache.org/jira/browse/FILEUPLOAD-133";>FILEUPLOAD-133</a>).</p></div>
+    }</pre>
+</div></div><p>Note the importance of <code>return this;</code>. A void event 
handler method, or one that returns null, will result in the 
FileUploadException being reported to the user as an uncaught runtime 
exception.</p><h1 id="UploadingFiles-Configuration">Configuration</h1><p>Four 
values may be configured as <a  
href="uploading-files.html">symbols</a>:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.repository-location</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>The directory to which files that are too 
large to keep in memory will be written to. The default is from the <a  
class="external-link" href="http://java.io"; rel="nofollow">java.io</a>.tmpdir 
system property.</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.repository-threshold</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Upload size, in bytes, at which point the 
uploaded file is writ
 ten to disk rather than kept in memory. The default is 10 
kilobytes.</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.requestsize-max</p></th><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Maximim size, in bytes, for the overall 
request. If exceeded, a FileUploadException will occur. The default is no 
maximum.</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>upload.filesize-max</p></th><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Maximum size, in bytes, for any individual uploaded 
file. Again, a FileUploadException will occur if exceeded. The default is no 
maximum.</p></td></tr></tbody></table></div><p>The class <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/upload/services/UploadSymbols.html";>UploadSymbols</a>
 defines constants for all four of these.</p><h1 
id="UploadingFiles-PotentialIssues">Potential Issues</h1><p>The Commons 
FileUpload library uses the CommonsIO file clean
 er service to remove temporary files when they are no longer needed. This 
service creates a thread to carry out its work. If the commons-io library is 
shared amongst multiple applications (e.g. added to server classpath) it is 
possible for an application to terminate this thread prematurely and cause 
errors for the other applications. (see the <a  class="external-link" 
href="http://jakarta.apache.org/commons/fileupload/using.html";>Resource 
Cleanup</a> section in for more discussion)</p><p>Technically the file cleanup 
service is not needed by Tapestry Upload (which deletes temporary files at the 
end of request processing). However it is currently not possible to disable it 
(enhancement request has been filed as <a  class="external-link" 
href="https://issues.apache.org/jira/browse/FILEUPLOAD-133";>FILEUPLOAD-133</a>).</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/url-rewriting.html
==============================================================================
--- websites/production/tapestry/content/url-rewriting.html (original)
+++ websites/production/tapestry/content/url-rewriting.html Sat Feb  3 16:21:22 
2018
@@ -44,13 +44,26 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
+
+</div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
- <input type="text" name="q"> 
- <input type="submit" value="Search"> 
-</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">URL rewriting</h1></div></div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
+<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
+  <input type="text" name="q">
+  <input type="submit" value="Search">
+</form>
+
+</div>
+
+
+<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
+
+
+<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">URL rewriting</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -62,28 +75,8 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h1 
id="URLrewriting-TapestryURLRewritingSupport">Tapestry URL Rewriting 
Support</h1>
-
-<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>Starting with Tapestry 5.2, the URLRewriterRule service has been replaced 
with the new LinkTransformer service.  This page needs to be revised to reflect 
the new API.  Meanwhile, please see Igor Drobiazko's <a  class="external-link" 
href="http://blog.tapestry5.de/index.php/2010/09/06/new-url-rewriting-api/"; 
rel="nofollow">excellent blog post on this topic</a>.</p></div></div>
-
-<p>Since 5.1.0.1, Tapestry has basic support for URL rewriting. Incoming 
requests and links generated by Tapestry can be rewritten using exactly the 
same API, based on a chain of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/urlrewriter/URLRewriterRule.html";>URLRewriterRule</a>
 interfaces. These rules are executed before all other Tapestry request 
handling, so your application does not otherwise know that the received request 
is not the original one.</p>
-
-<p>Each URL rewriter rule, in its <code>Request process</code>, can choose 
between returning another <code>Request</code>, effectively rewriting it, or 
returning the received request unchanged, meaning that this rule does not apply 
to that request.</p>
-
-<p>To facilitate <code>Request</code> creation, Tapestry provides the 
<code>SimpleRequestWrapper</code> class. It wraps a <code>Request</code>, 
delegating all methods except <code>getPath()</code> and 
<code>getServerName()</code>. More request wrappers may be added in the future 
on demand.</p>
-
-<h2 id="URLrewriting-Configuration">Configuration</h2>
-
-<p>Tapestry's URL rewriting support is configured by Tapestry-IoC through 
contribution of a <code>URLRewriterRule</code> to the <code>URLRewriter</code> 
service. The following example is part of the Tapestry's tests.</p>
-
-<h2 id="URLrewriting-Simpleexampleofrulechaining">Simple example of rule 
chaining</h2>
-
-<p>This example just rewrites all incoming requests to <code>/struts</code> to 
<code>/tapestry</code>. In your <code>AppModule</code> or any other 
Tapestry-IoC module class:</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;">
-public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
+                <div id="ConfluenceContent"><h1 
id="URLrewriting-TapestryURLRewritingSupport">Tapestry URL Rewriting 
Support</h1><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>Starting with Tapestry 5.2, the 
URLRewriterRule service has been replaced with the new LinkTransformer service. 
This page needs to be revised to reflect the new API. Meanwhile, please see 
Igor Drobiazko's <a  class="external-link" 
href="https://web.archive.org/web/20150906154302/http://blog.tapestry5.de/index.php/2010/09/06/new-url-rewriting-api/";
 rel="nofollow">excellent blog post on this topic</a>.</p></div></div><p>Since 
5.1.0.1, Tapestry has basic support for URL rewriting. Incoming requests and 
links generated by Tapestry can be rewritten using exactly the same API, based 
on a chain of <a  class="external-link" href="http://tapes
 
try.apache.org/current/apidocs/org/apache/tapestry5/urlrewriter/URLRewriterRule.html">URLRewriterRule</a>
 interfaces. These rules are executed before all other Tapestry request 
handling, so your application does not otherwise know that the received request 
is not the original one.</p><p>Each URL rewriter rule, in its <code>Request 
process</code>, can choose between returning another <code>Request</code>, 
effectively rewriting it, or returning the received request unchanged, meaning 
that this rule does not apply to that request.</p><p>To facilitate 
<code>Request</code> creation, Tapestry provides the 
<code>SimpleRequestWrapper</code> class. It wraps a <code>Request</code>, 
delegating all methods except <code>getPath()</code> and 
<code>getServerName()</code>. More request wrappers may be added in the future 
on demand.</p><h2 
id="URLrewriting-Configuration">Configuration</h2><p>Tapestry's URL rewriting 
support is configured by Tapestry-IoC through contribution of a 
<code>URLRewriterRul
 e</code> to the <code>URLRewriter</code> service. The following example is 
part of the Tapestry's tests.</p><h2 
id="URLrewriting-Simpleexampleofrulechaining">Simple example of rule 
chaining</h2><p>This example just rewrites all incoming requests to 
<code>/struts</code> to <code>/tapestry</code>. In your <code>AppModule</code> 
or any other Tapestry-IoC module class:</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;">public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
 {
     
     URLRewriterRule rule = new URLRewriterRule() 
@@ -111,15 +104,8 @@ public static void contributeURLRewriter
     configuration.add("myrule", rule);
 }
 </pre>
-</div></div>
-
-<h2 id="URLrewriting-Exampleofrulechaining">Example of rule chaining</h2>
-
-<p>In your <code>AppModule</code> or any other Tapestry-IoC module class.</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;">
-public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
+</div></div><h2 id="URLrewriting-Exampleofrulechaining">Example of rule 
chaining</h2><p>In your <code>AppModule</code> or any other Tapestry-IoC module 
class.</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;">public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
 {
     
     URLRewriterRule rule1 = new URLRewriterRule()
@@ -218,19 +204,8 @@ public static void contributeURLRewriter
     
 }
 </pre>
-</div></div>
-
-<p>This examples shows the URL rewriting chaining: the first rule rewrites 
requests to <code>/struts</code> and rewrites them to <code>/jsf</code> and 
leaves requests to other URLs unchanged. The second rewrites <code>/jsf</code> 
to <code>/tapestry</code> and the third rewrites <code>/tapestry</code> to 
<code>/urlrewritesuccess</code>.</p>
-
-<p>The result is that any request to <code>/struts</code> end up being handled 
by the same class that handles <code>/urlrewritesuccess</code>, while the 
browser, the user and Tapestry still sees <code>/struts</code>.</p>
-
-<p>Note that this applies to rewriting links generated by Tapestry too: a 
<code>PageLink</code> to the <code>urlrewritesuccess</code> page with an 
activation context of <code>login</code> (path 
<code>/urlrewritesuccess/login</code>) will generate an <code>a</code> tag 
pointing to <code><a  class="external-link" href="http://login.domain.com"; 
rel="nofollow">http://login.domain.com</a></code>.</p>
-
-<p>The URLRewriteContext (added in 5.1.0.4) provides additional information 
for rewriting, particularly in the context of rewriting generated link urls. In 
the following example, we'll reconfigure the url used to render pages. Whereas 
the previous examples used separate rules for handling inbound and outbound 
rewriting, this demonstration will utilize a single rule for both scenarios. To 
simplify the example, we will assume that every page is named "XXXPage" 
(UserPage, TransactionPage, IndexPage, etc.). This naming convention also means 
that we don't have to worry about tapestry's auto-stripping of "index" from 
URLs, because our page would be IndexPage, rather than Index.</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;">
-public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
+</div></div><p>This examples shows the URL rewriting chaining: the first rule 
rewrites requests to <code>/struts</code> and rewrites them to 
<code>/jsf</code> and leaves requests to other URLs unchanged. The second 
rewrites <code>/jsf</code> to <code>/tapestry</code> and the third rewrites 
<code>/tapestry</code> to <code>/urlrewritesuccess</code>.</p><p>The result is 
that any request to <code>/struts</code> end up being handled by the same class 
that handles <code>/urlrewritesuccess</code>, while the browser, the user and 
Tapestry still sees <code>/struts</code>.</p><p>Note that this applies to 
rewriting links generated by Tapestry too: a <code>PageLink</code> to the 
<code>urlrewritesuccess</code> page with an activation context of 
<code>login</code> (path <code>/urlrewritesuccess/login</code>) will generate 
an <code>a</code> tag pointing to <code><a  class="external-link" 
href="http://login.domain.com"; 
rel="nofollow">http://login.domain.com</a></code>.</p><p>The URLRewriteContext (
 added in 5.1.0.4) provides additional information for rewriting, particularly 
in the context of rewriting generated link urls. In the following example, 
we'll reconfigure the url used to render pages. Whereas the previous examples 
used separate rules for handling inbound and outbound rewriting, this 
demonstration will utilize a single rule for both scenarios. To simplify the 
example, we will assume that every page is named "XXXPage" (UserPage, 
TransactionPage, IndexPage, etc.). This naming convention also means that we 
don't have to worry about tapestry's auto-stripping of "index" from URLs, 
because our page would be IndexPage, rather than Index.</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;">public static void 
contributeURLRewriter(OrderedConfiguration&lt;URLRewriterRule&gt; configuration)
 {
     URLRewriterRule rule = new URLRewriterRule() 
     {
@@ -270,13 +245,7 @@ public static void contributeURLRewriter
 
 }
 </pre>
-</div></div>
-
-<p>In the first part of <code>process</code>, 
<code>context.isIncoming()</code> determines if the call to 
<code>process</code> occurred due to an inbound request. If so, the rule 
reverses the mapping done in the second portion of the method, so tapestry sees 
the original request.</p>
-
-<p>The second half of <code>process</code> rewrites only page links by 
retrieving the logical page name and replacing its occurrence in the url with 
the shortened form of the link. This code segment demonstrates how the 
additional information provided by <code>URLRewriteContext</code> can be used 
to rewrite urls in a generalized manner.</p>
-
-<p>Note that <code>getPageParameters()</code> will only return non-null when 
<code>process</code> is called due to page link creation, and 
<code>getComponentEventParameters()</code> will only return non-null when 
<code>process</code> is called as a result of creating component event 
links.</p></div>
+</div></div><p>In the first part of <code>process</code>, 
<code>context.isIncoming()</code> determines if the call to 
<code>process</code> occurred due to an inbound request. If so, the rule 
reverses the mapping done in the second portion of the method, so tapestry sees 
the original request.</p><p>The second half of <code>process</code> rewrites 
only page links by retrieving the logical page name and replacing its 
occurrence in the url with the shortened form of the link. This code segment 
demonstrates how the additional information provided by 
<code>URLRewriteContext</code> can be used to rewrite urls in a generalized 
manner.</p><p>Note that <code>getPageParameters()</code> will only return 
non-null when <code>process</code> is called due to page link creation, and 
<code>getComponentEventParameters()</code> will only return non-null when 
<code>process</code> is called as a result of creating component event 
links.</p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to