Modified: websites/production/tapestry/content/injection.html
==============================================================================
--- websites/production/tapestry/content/injection.html (original)
+++ websites/production/tapestry/content/injection.html Mon May 21 05:20:56 2018
@@ -86,11 +86,13 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="injection-in-detail.html">Injection in 
Detail</a>
@@ -99,19 +101,19 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="injection-faq.html">Injection FAQ</a>
+                        <a  href="injection.html">Injection</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="injection.html">Injection</a>
+                        <a  href="injection-faq.html">Injection FAQ</a>
                 
                         
                     </div>
@@ -120,25 +122,25 @@
 
 
 <p>Injection is a key concept in Tapestry, and it is used in several different 
but related ways, listed below.</p><h2 
id="Injection-InjectioninTapestryIOCServices">Injection in Tapestry IOC 
Services</h2><p>Main Article: <a  href="injection-in-detail.html">Injection in 
Detail</a></p><p>The Tapestry IoC container makes use of injection primarily 
through constructors and via parameters to service builder methods.</p><h2 
id="Injection-InjectioninComponentClasses">Injection in Component 
Classes</h2><p>For components, however, Tapestry takes a completely different 
tack: injection directly into component fields.</p><p>The @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 annotation is used to identify fields that will contain injected services and 
other resources.</p><p>Tapestry allows for two kinds of 
injection:</p><ul><li><strong>Default injection</strong>, where Tapestry 
determines the object to injec
 t into the field based on its type.</li><li><strong>Explicit 
injection</strong>, where the particular service to be injected is 
specified.</li></ul><p>In both cases, the field is transformed into a read only 
value. As elsewhere in Tapestry, this transformation occurs at runtime (which 
is very important in terms of being able to test your components). Attempting 
to update an injected field will result in a runtime exception.</p><p>In 
addition, there are a few special cases that are triggered by specific field 
types, or additional annotations, in addition, to @Inject, on a field.</p><h3 
id="Injection-BlockInjection">Block Injection</h3><p>For field type <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html";>Block</a>,
 the value of the Inject annotation is the id of the <span 
class="confluence-link">&lt;t:block&gt;</span> element within the component's 
template. Normally, the id of the block is determined from the field name 
(after s
 tripping out any leading "_" and "$" characters):</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 private Block foo;
 </pre>
 </div></div><p>Where that is not appropriate, an @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Id.html";>Id</a>
 annotation can be supplied:</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 @Id("bar")
 private Block barBlock;
 </pre>
 </div></div><p>The first injection will inject the Block with id "foo" (as 
always, case is ignored). The second injection will inject the Block with id 
"bar".</p><h3 id="Injection-ResourceInjection">Resource Injection</h3><p>For a 
particular set of field types, Tapestry will inject a <em>resource</em> related 
to the component, such as its Locale.</p><p>A very common example occurs when a 
component needs access to its <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html";>resources</a>.
 The component can define a field of the appropriate type and use the 
<code>@Inject</code> annotation without a value:</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 private ComponentResources resources;
 </pre>
 </div></div><p>Tapestry uses the type of the field, ComponentResources, to 
determine what to inject into this field.</p><p>The following types are 
supported for resources injection:</p><ul><li><strong>java.lang.String</strong> 
&#8211; The complete id of the component, which incorporates the complete class 
name of the containing page and the nested id of the component within the 
page.</li></ul><ul><li><strong>java.util.Locale</strong> &#8211; The locale for 
the component (all components within a page use the same 
locale).</li></ul><ul><li><strong>org.slf4j.Logger</strong> &#8211; A Logger 
instance configured for the component, based on the component's class name. <a  
class="external-link" href="http://www.slf4j.org/"; rel="nofollow">SLF4J</a> is 
a wrapper around Log4J or other logging 
toolkits.</li></ul><ul><li><strong>org.apache.tapestry5.ComponentResources</strong>
 &#8211; The resources for the component, often used to generate links related 
to the component.</li></ul><ul><li><stron
 g>org.apache.tapestry5.ioc.Messages</strong> &#8211; The component message 
catalog for the component, from which <a  href="injection.html">localized</a> 
messages can be generated.</li></ul><h3 id="Injection-AssetInjection">Asset 
Injection</h3><p>Main Article: <a  href="assets.html">Assets</a></p><p>When the 
@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Path.html";>Path</a>
 annotation is also present, then the injected value (relative to the 
component) will be a localized asset.</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 @Path("context:images/top_banner.png")
 private Asset banner;
 </pre>
 </div></div><p>Symbols in the annotation value are expanded.</p><h3 
id="Injection-ServiceInjection">Service Injection</h3><p>Here, a custom 
EmployeeService service is injected, but any custom or built-in service may be 
injected in the same way.</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 private EmployeeService employeeService;
 </pre>
 </div></div><p>A large number of services are provided by Tapestry. See the 
following packages:</p><div class="navmenu" style="float:left; width:15em; 
background:white; margin:3px; padding:3px">
@@ -150,7 +152,7 @@ private EmployeeService employeeService;
 </div><div class="navmenu" style="float:left; width:15em; background:white; 
margin:3px; padding:3px">
 <ul><li><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/package-summary.html";>Tapestry
 IOC Services</a></li><li><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/cron/package-summary.html";>Tapestry
 IOC Cron Services</a></li><li><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/kaptcha/services/package-summary.html";>Kaptcha
 Services</a></li><li><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/upload/services/package-summary.html";>File
 Upload Services</a></li></ul>
 </div><div style="clear:both"></div>&#160;<h3 
id="Injection-ExplicitServiceInjection">Explicit Service Injection</h3><p>Here, 
a specific object is requested. A @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Service.html";>Service</a>
 annotation is used to identify the service name.</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;">@Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@Inject
 @Service("Request")
 private Request request;
 </pre>

Modified: 
websites/production/tapestry/content/integration-with-existing-applications.html
==============================================================================
--- 
websites/production/tapestry/content/integration-with-existing-applications.html
 (original)
+++ 
websites/production/tapestry/content/integration-with-existing-applications.html
 Mon May 21 05:20:56 2018
@@ -78,14 +78,14 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="Integrationwithexistingapplications-Integrationwithexistingapplications">Integration
 with existing applications</h1><h2 
id="Integrationwithexistingapplications-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334094474 {padding: 0px;}
-div.rbtoc1523334094474 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334094474 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880008118 {padding: 0px;}
+div.rbtoc1526880008118 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880008118 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334094474">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880008118">
 <ul class="toc-indentation"><li><a  
href="#Integrationwithexistingapplications-HowdoImakeaformonaJSPsubmitintoTapestry?">How
 do I make a form on a JSP submit into Tapestry?</a></li><li><a  
href="#Integrationwithexistingapplications-HowdoIshareinformationbetweenaJSPapplicationandtheTapestryapplication?">How
 do I share information between a JSP application and the Tapestry 
application?</a></li><li><a  
href="#Integrationwithexistingapplications-HowdoIputtheTapestryapplicationinsideafolder,toavoidconflicts?">How
 do I put the Tapestry application inside a folder, to avoid 
conflicts?</a></li></ul>
 </div><p>You may have an existing JSP (or Struts, Spring MVC, etc.) 
application that you want to migrate to Tapestry. It's quite common to do this 
in stages, moving some functionality into Tapestry and leaving other parts, 
initially, in the other system. <a  href="request-processing-faq.html">You may 
need to prevent Tapestry from handling certain requests</a>.</p><h2 
id="Integrationwithexistingapplications-HowdoImakeaformonaJSPsubmitintoTapestry?">How
 do I make a form on a JSP submit into Tapestry?</h2><p>Tapestry's Form 
component does a lot of work while an HTML form is rendering to store all the 
information needed to handle the form submission in a later request; this is 
all very specific to Tapestry and the particular construction of your pages and 
forms; it can't be reproduced from a JSP.</p><p>Fortunately, that isn't 
necessary: you can have a standard HTML Form submit to a Tapestry page, you 
just don't get to use all of Tapestry's built in conversion and validation 
logic.</p><p
 >All you need to know is how Tapestry converts page class names to page names 
 >(that appear in the URL). It's basically a matter of stripping off the 
 ><em>root-package</em>.<code>pages</code> prefix from the fully qualified 
 >class name. So, for example, if you are building a login screen as a JSP, you 
 >might want to have a Tapestry page to receive the user name and password. 
 >Let's assume the Tapestry page class is 
 ><code>com.example.myapp.pages.LoginForm</code>; the page name will be 
 ><code>loginform (although, since&#160;</code><span>Tapestry is case 
 >insensitive, LoginForm would work just as well)</span><span>, and the URL 
 >will be </span><code>/loginform</code><span>.</span></p><p>&#160;</p><div 
 >class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
 >panelHeader pdl" style="border-bottom-width: 
 >1px;"><b>LoginForm.tml</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;form method="post" action="/loginform"&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;form method="post" 
action="/loginform"&gt;
 
   &lt;input type="text" value="userName"/&gt;
   &lt;br/&gt;
@@ -96,7 +96,7 @@ div.rbtoc1523334094474 li {margin-left:
 &lt;/form&gt;
 </pre>
 </div></div><p>On the Tapestry side, we can expect that the LoginForm page 
will be activated; this means that its activate event handler will be invoked. 
We can leverage this, and Tapestry's RequestParameter annotation:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>LoginForm.java</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class LoginForm
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class LoginForm
 {
   void onActivate(@RequestParameter("userName") String userName, 
@RequestParameter("password") String password)
   {
@@ -105,7 +105,7 @@ div.rbtoc1523334094474 li {margin-left:
 }
 </pre>
 </div></div><p>The RequestParameter annotation extracts the named query 
parameter from the request, coerces its type from String to the parameter type 
(here, also String) and passes it into the method.</p><h2 
id="Integrationwithexistingapplications-HowdoIshareinformationbetweenaJSPapplicationandtheTapestryapplication?">How
 do I share information between a JSP application and the Tapestry 
application?</h2><p>From the servlet container's point of view, there's no 
difference between a servlet, a JSP, and an entire Tapestry application. They 
all share the same ServletContext, and (once created), the same 
HttpSession.</p><p>On the Tapestry side, it is very easy to read and write 
session attributes:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>ShowSearchResults.java</b></div><div class="codeContent panelContent 
pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class ShowSearchResults
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class 
ShowSearchResults
 {
   @SessionAttribute
   private SearchResults searchResults;

Modified: 
websites/production/tapestry/content/ioc-cookbook-basic-services-and-injection.html
==============================================================================
--- 
websites/production/tapestry/content/ioc-cookbook-basic-services-and-injection.html
 (original)
+++ 
websites/production/tapestry/content/ioc-cookbook-basic-services-and-injection.html
 Mon May 21 05:20:56 2018
@@ -78,7 +78,7 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><p>The starting point for Tapestry 
IOC services and injection is knowing a few conventions: what to name your 
classes, what packages to put them in and so forth.</p><p>In many cases, these 
conventions are just a little stronger: you may have to do some amount of extra 
configuration if you choose to go your own way.</p><h1 
id="IoCCookbook-BasicServicesandInjection-GettingStarted">Getting 
Started</h1><p>As always, you'll first need to choose a package for your 
application, such as org.example.myapp.</p><p>By convention, services go in a 
sub-package named "services". Tapestry IOC Module class names have a "Module" 
suffix. Thus, you might start with a module class 
org.example.myapp.services.MyAppModule.</p><h1 
id="IoCCookbook-BasicServicesandInjection-SimpleServices">Simple 
Services</h1><p>The simplest services don't have any special configuration or 
dependencies. They are defined as services so that they can be 
shared.</p><p>For example, the 
 <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PropertyAccess.html";>PropertyAccess</a>
 service is used in multiple places around the framework to access properties 
of objects (its a wrapper around the Java Beans Introspector and a bit of 
reflection). This is defined in the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TapestryIOCModule.html";>TapestryIOCModule</a>.</p><p>It's
 useful to share PropertyAccess, because it does a lot of useful caching 
internally.</p><p>The PropertyAccess service is defined inside 
TapestryIOCModule's bind() method:</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 bind(ServiceBinder binder)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
bind(ServiceBinder binder)
   {
     . . .
     binder.bind(PropertyAccess.class, PropertyAccessImpl.class);
@@ -86,7 +86,7 @@
     . . .
   }</pre>
 </div></div><p>This example includes <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/ExceptionAnalyzer.html";>ExceptionAnalyzer</a>,
 because it has a dependency on PropertyAccess:</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 class ExceptionAnalyzerImpl implements 
ExceptionAnalyzer
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class 
ExceptionAnalyzerImpl implements ExceptionAnalyzer
 {
     private final PropertyAccess propertyAccess;
     public ExceptionAnalyzerImpl(PropertyAccess propertyAccess)
@@ -97,7 +97,7 @@
     . . .
 }</pre>
 </div></div><p>And that's the essence of Tapestry IoC right there; the bind() 
plus the constructor is <em>all</em> that's necessary.</p><h1 
id="IoCCookbook-BasicServicesandInjection-ServiceDisambiguation">Service 
Disambiguation</h1><p>In the previous example, we relied on the fact that only 
a single service implements the PropertyAccess interface. Had more than one 
done so, Tapestry would have thrown an exception when the ExceptionAnalyzer 
service was realized (it isn't until a service is realized that dependencies 
are resolved).</p><p>That's normally okay; in many situations, it makes sense 
that only a single service implement a particular interface.</p><p>But there 
are often exceptions to the rule, and in those cases, we must provide more 
information to Tapestry when a service is defined, and when it is injected, in 
order to disambiguate &#8211; to inform Tapestry which particular version of 
service to inject.</p><p>This example demonstrates a number of ideas that we 
haven't discu
 ssed so far, so try not to get too distracted by some of the details. One of 
the main concepts introduced here is <em>service builder methods</em>. These 
are methods, of a Tapestry IoC Module class, that act as an alternate way to 
define a service. You often used a service builder method if you are doing more 
than simply instantiating a class.</p><p>A service builder method is a method 
of a Module, prefixed with the word "build". This defines a service, and 
dependency injection occurs on the parameters of the service builder 
method.</p><p>The Tapestry web framework includes the concept of an "asset": a 
resource that may be inside a web application, or packaged inside a JAR. Assets 
are represented as the type <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Asset.html";>Asset</a>.</p><p>In
 fact, there are different implementations of this class: one for context 
resources (part of the web application), the other for classpath resources (pa
 ckaged inside a JAR). The Asset instances are created via <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapesty/services/AssetFactory.html";>AssetFactory</a>
 services.</p><p>Tapestry defines two such services, in the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/TapestryModule.html";>TapestryModule</a>.</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;">  @Marker(ClasspathProvider.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  
@Marker(ClasspathProvider.class)
   public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache,
 
   ClasspathAssetAliasManager aliasManager)
@@ -115,7 +115,7 @@
     return new ContextAssetFactory(request, globals.getContext());
   }</pre>
 </div></div><p>Service builder methods are used here for two purposes: For the 
ClasspathAssetFactory, we are registering the new service as a listener of 
events from another service. For the ContextAssetFactory, we are extracting a 
value from an injected service and passing <em>that</em> to the 
constructor.</p><p>What's important is that the services are differentiated not 
just in terms of their id (which is defined by the name of the method, after 
stripping off "build"), but in terms of their <em>marker 
annotation</em>.</p><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Marker.html";>Marker</a>
 annotation provides the discriminator. When the service type is supplemented 
with the ClasspathProvider annotation, the ClasspathAssetFactory is injected. 
When the service type is supplemented with the ContextProvider annotation, the 
ContextAssetFactory is injected.</p><p>Here's an example. Again, we've jumped 
the gun with
  this <em>service contributor method</em> (we'll get into the why and how of 
these later), but you can see how Tapestry is figuring out which service to 
inject based on the presence of those annotations:</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 
contributeAssetSource(MappedConfiguration&lt;String, AssetFactory&gt; 
configuration,
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public void 
contributeAssetSource(MappedConfiguration&lt;String, AssetFactory&gt; 
configuration,
       @ContextProvider
       AssetFactory contextAssetFactory,
 

Modified: 
websites/production/tapestry/content/ioc-cookbook-overriding-ioc-services.html
==============================================================================
--- 
websites/production/tapestry/content/ioc-cookbook-overriding-ioc-services.html 
(original)
+++ 
websites/production/tapestry/content/ioc-cookbook-overriding-ioc-services.html 
Mon May 21 05:20:56 2018
@@ -78,14 +78,14 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="IoCCookbook-OverridingIoCServices-OverridingTapestryIoCServices">Overriding 
Tapestry IoC Services</h1><p>Tapestry is designed to be easy to customize, and 
the IoC container is the key to that customizability.</p><p>One of Tapestry's 
most important activities is resolving injected objects; that is, when Tapestry 
is building an object or service and sees a constructor parameter or a field, 
it must decide what value to plug in. Most of the time, the injected object is 
a service defined elsewhere within the Tapestry IoC container.</p><p>However, 
there are cases where you might want to override how Tapestry operates in some 
specific way.</p><p>The strategy used to determine what object gets injected is 
<a  href="injection-in-detail.html">defined inside Tapestry IoC itself</a>; 
thus we can take advantage of several features of the Tapestry IoC container in 
order to take control over specific injections.</p><h2 
id="IoCCookbook-OverridingI
 oCServices-ContributingaServiceOverride">Contributing a Service 
Override</h2><p>In most cases, services are injected by matching just the type; 
there is no @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 annotation, just a method or constructor parameter whose type matches the 
service's interface.</p><p>In this case, it is very easy to supply your own 
alternate implementation of a service, by <em>contributing</em><em> a Service 
Override</em> in your module class (usually AppModule.java), like this:</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;">  @Contribute(ServiceOverride.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  
@Contribute(ServiceOverride.class)
   public static void 
setupApplicationServiceOverrides(MappedConfiguration&lt;Class,Object&gt; 
configuration)
   {
     configuration.addInstance(SomeServiceType.class, 
SomeServiceTypeOverrideImpl.class);
   }
 </pre>
 </div></div><p>The name of the method is not important, as long as the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Contribute.html";>Contribute</a>
 annotation is present on the method.</p><p>In this example, we are using 
<code>addInstance()</code> which will instantiate the indicated class and 
handle dependency resolution. (Be careful with this, because in some cases, 
resolving dependencies of the override class can require checking against the 
ServiceOverrides service, and you'll get a runtime exception about 
ServiceOverrides requiring itself!).</p><p>Sometimes you'll want to define the 
override as a service of its own. This is useful if you want to inject a Logger 
specific to the service, or if the overriding implementation needs a <a  
href="tapestry-ioc-configuration.html">service configuration</a>:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bot
 tom-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 bind(ServiceBinder binder)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
bind(ServiceBinder binder)
   {
     binder.bind(SomeServiceType.class, 
SomeServiceTypeOverrideImpl.class).withId("SomeServiceTypeOverride");
   }
@@ -97,7 +97,7 @@
   }
 </pre>
 </div></div><p>Here we're defining a service using the module's 
<code>bind()</code> method.</p><p>Every service in the IoC container must have 
a unique id, that's why we used the <code>withId()</code> method; if we we 
hadn't, the default service id would have been "SomeServiceType" which is a 
likely conflict with the very service we're trying to override.</p><p>We can 
inject our overriding implementation of SomeServiceType using the special @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Local.html";>Local</a>
 annotation, which indicates that a service within the same module only should 
be injected (that is, services of the indicated type in other modules are 
ignored). Without @Local, there would be a problem because the override 
parameter would need to be resolved using the MasterObjectProvider and, 
ultimately, the ServiceOverride service; this would cause Tapestry to throw an 
exception indicating that ServiceOverride depe
 nds on itself. We defuse that situation by using @Local, which prevents the 
MasterObjectProvider service from being used to resolve the override 
parameter.</p><h2 
id="IoCCookbook-OverridingIoCServices-DecoratingServices">Decorating 
Services</h2><p>Another option is to <a  
href="tapestry-ioc-decorators.html">decorate</a> the existing service. Perhaps 
you want to extend some of the behavior of the service but keep the 
rest.</p><p>Alternately, this approach is useful to override a service that is 
matched using marker annotations.</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 SomeServiceType decorateSomeServiceType(final 
SomeServiceType delegate)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public SomeServiceType 
decorateSomeServiceType(final SomeServiceType delegate)
   {
     return new SomeServiceType() { . . . };
   }

Modified: websites/production/tapestry/content/ioc-cookbook-patterns.html
==============================================================================
--- websites/production/tapestry/content/ioc-cookbook-patterns.html (original)
+++ websites/production/tapestry/content/ioc-cookbook-patterns.html Mon May 21 
05:20:56 2018
@@ -86,20 +86,22 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="ioc-cookbook-patterns.html">IoC Cookbook - 
Patterns</a>
+                        <a  
href="pipelinebuilder-service.html">PipelineBuilder Service</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  
href="strategybuilder-service.html">StrategyBuilder Service</a>
@@ -108,16 +110,16 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="pipelinebuilder-service.html">PipelineBuilder Service</a>
+                        <a  href="ioc-cookbook-patterns.html">IoC Cookbook - 
Patterns</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="chainbuilder-service.html">ChainBuilder 
Service</a>
@@ -129,13 +131,13 @@
 
 
 <p>The basis for these patterns is often the use of <em>service builder 
methods</em>, where a <a  
href="ioc-cookbook-service-configurations.html">configuration</a> for the 
service is combined with a factory to produce the service implementation on the 
fly.</p><p><span class="confluence-anchor-link" 
id="IoCCookbook-Patterns-chainofcommand"></span></p><h1 
id="IoCCookbook-Patterns-ChainofCommandPattern">Chain of Command 
Pattern</h1><p>Main Article: <a  href="chainbuilder-service.html">Chain of 
Command</a></p><p>Let's look at another example, again from the Tapestry code 
base. The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/InjectionProvider.html";>InjectProvider</a>
 interface is used to process the @Inject annotation on the fields of a 
Tapestry page or component. Many different instances are combined together to 
form a <em>chain of command</em>.</p><p>The interface has only a single method 
(this is far from uncommon):</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 interface InjectionProvider
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public interface 
InjectionProvider
 {
   boolean provideInjection(String fieldName, Class fieldType, ObjectLocator 
locator,
       ClassTransformation transformation, MutableComponentModel 
componentModel);
 }</pre>
 </div></div><p>The return type indicates whether the provider was able to do 
something. For example, the AssetInjectionProvider checks to see if there's an 
@Path annotation on the field, and if so, converts the path to an asset, works 
with the ClassTransformation object to implement injection, and returns true to 
indicate success. Returning true terminates the chain early, and that true 
value is ultimately returned to the caller.</p><p>In other cases, it returns 
false and the chain of command continues down to the next provider. If no 
provider is capable of handling the injection, then the value false is 
ultimately returned.</p><p>The InjectionProvider service is built up via 
contributions. These are the contributions from the TapestryModule:</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 contributeInjectionProvider(
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public static void 
contributeInjectionProvider(
     OrderedConfiguration&lt;InjectionProvider&gt; configuration,
     MasterObjectProvider masterObjectProvider,
     ObjectLocator locator,
@@ -154,12 +156,12 @@
   configuration.add("Service", new ServiceInjectionProvider(locator), 
"after:*");
 }</pre>
 </div></div><p>And, of course, other contributions could be made in other 
modules ... if you wanted to add in your own form of injection.</p><p>The 
configuration is converted into a service via a service builder method:</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 InjectionProvider 
build(List&lt;InjectionProvider&gt; configuration, ChainBuilder chainBuilder)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public InjectionProvider 
build(List&lt;InjectionProvider&gt; configuration, ChainBuilder chainBuilder)
   {
     return chainBuilder.build(InjectionProvider.class, configuration);
   }</pre>
 </div></div><p>Now, let's see how this is used. The InjectWorker class looks 
for fields with the InjectAnnotation, and uses the chain of command to inject 
the appropriate value. However, to InjectWorker, there is no chain ... just a 
<em>single</em> object that implements the InjectionProvider interface.</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 class InjectWorker implements 
ComponentClassTransformWorker
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class InjectWorker 
implements ComponentClassTransformWorker
 {
   private final ObjectLocator locator;
 

Modified: 
websites/production/tapestry/content/ioc-cookbook-service-configurations.html
==============================================================================
--- 
websites/production/tapestry/content/ioc-cookbook-service-configurations.html 
(original)
+++ 
websites/production/tapestry/content/ioc-cookbook-service-configurations.html 
Mon May 21 05:20:56 2018
@@ -78,13 +78,13 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="IoCcookbook-ServiceConfigurations-ServiceConfigurations">Service 
Configurations</h1><p>This is an area of Tapestry IoC that is often least well 
understood. Tapestry services often must have some configuration to fine tune 
exactly what they do. One of the interactions between modules is that these 
service configurations are shared: they may be contributed into by any 
module.</p><p>Let's start with the most basic kind, the unordered 
configuration.</p><h1 
id="IoCcookbook-ServiceConfigurations-UnorderedServiceConfigurations">Unordered 
Service Configurations</h1><p>One of Tapestry's features is the ability to 
package assets (images, style sheets, JavaScript libraries, etc.) inside JAR 
files and expose those to the client. For example, an application URL 
/assets/org/example/mylib/mylib.js would refer to a file, myllib.js, stored on 
the classpath in the /org/example/mylib folder.</p><p>That's fine for most 
cases, but for certain file exte
 nsions, we don't want to allow a client browser to "troll" for the files, as 
the contents could compromise security. For example, downloading a .class file 
is bad: a clever client might download one that contains a hard-coded user name 
or password.</p><p>Thus, for certain file extensions, Tapestry guards the 
resource by attaching an MD5 digest for the resource to the URL. The checksum 
is derived from the file contents; thus it can't be spoofed from the client 
unless the client already has the file contents.</p><p>This is controlled by 
the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ResourceDigestGenerator.html";>ResourceDigestGenerator</a>
 service, which uses its configuration to determine which file extensions 
require an MD5 digest.</p><h2 
id="IoCcookbook-ServiceConfigurations-ContributingtoaService">Contributing to a 
Service</h2><p>Main Article: <a  
href="tapestry-ioc-configuration.html">Tapestry IoC Configuration</a></p>
 <p>The Tapestry module makes a contribution into the service 
configuration:</p><div class="code panel pdl" style="border-style: 
solid;border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static void 
contributeResourceDigestGenerator(Configuration&lt;String&gt; configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeResourceDigestGenerator(Configuration&lt;String&gt; configuration)
   {
     configuration.add("class");
     configuration.add("tml");
   }</pre>
 </div></div><p>This is a <em>service contribution method</em>, a method that 
is invoked to provide values for a configuration. We'll see how the service 
receives these contributions shortly. The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Configuration.html";>Configuration</a>
 object is how values are added to the service's configuration. Other 
parameters to a service configuration method are injected much as with a 
service's constructor, or a service builder method.</p><p>How does Tapestry 
know which service configuration to update? It's from the name of the method, 
anything after the "contribute" prefix is the id of the service to contribute 
to (the match against service id is case insensitive).</p><p>Here, the 
configuration receives two values: "class" (a compiled Java class) and "tml" (a 
Tapestry component template).</p><p>Say your application stored a file on the 
classpath needed by your application; for illustrative purpos
 es, perhaps it is a PGP private key. You don't want any client to able to 
download a .pgp file, no matter how unlikely that would be. Thus:</p><div 
class="code panel pdl" style="border-style: solid;border-width: 1px;"><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class MyAppModule
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class MyAppModule
 {
  public static void 
contributeResourceDigestGenerator(Configuration&lt;String&gt; configuration)
  {
@@ -92,7 +92,7 @@
  }
 }</pre>
 </div></div><p>The contribution in MyAppModule doesn't <em>replace</em> the 
normal contribution, it is <em>combined</em>. The end result is that .class, 
.tml and .pgp files would <em>all</em> be protected.</p><h2 
id="IoCcookbook-ServiceConfigurations-ReceivingtheConfiguration">Receiving the 
Configuration</h2><p>A service receives the configuration as an injected 
parameter ... not of type Configuration (that's used for <em>making</em> 
contributions), but instead is of type Collection:</p><div class="code panel 
pdl" style="border-style: solid;border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class ResourceDigestGeneratorImpl implements 
ResourceDigestGenerator
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class 
ResourceDigestGeneratorImpl implements ResourceDigestGenerator
 {
   private final Set&lt;String&gt; digestExtensions;
 
@@ -104,7 +104,7 @@
   . . .
 }</pre>
 </div></div><p>In many cases, the configuration is simply stored into an 
instance variable; in this example, the value is transformed from a Collection 
to a Set.</p><p>These kinds of unordered configurations are surprisingly rare 
in Tapestry (the only other notable one is for the <a  
href="ioc-cookbook-service-configurations.html">TypeCoercer</a> service). 
However, as you can see, setting up such a configuration is quite easy.</p><h1 
id="IoCcookbook-ServiceConfigurations-OrderedConfigurations">Ordered 
Configurations</h1><p>Ordered configurations are very similar to unordered 
configurations ... the difference is that the configuration is provided to the 
service as a parameter of type List. This is used when the order of operations 
counts. Often these configurations are related to a design pattern such as <a  
href="chainbuilder-service.html">Chain of Command</a> or <a  
href="pipelinebuilder-service.html">Pipeline</a>.</p><p>Here, the example is 
the <a  class="external-link" href="http
 
://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/Dispatcher.html">Dispatcher</a>
 interface; a Dispatcher inside Tapestry is roughly equivalent to a servlet, 
though a touch more active. It is passed a Request and decides if the URL for 
the Request is something it can handle; if so it will process the request, send 
a response, and return true.</p><p>Alternately, if the Request can't be 
handled, the Dispatcher returns false.</p><div class="code panel pdl" 
style="border-style: solid;border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public void 
contributeMasterDispatcher(OrderedConfiguration&lt;Dispatcher&gt; 
configuration, . . .)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public void 
contributeMasterDispatcher(OrderedConfiguration&lt;Dispatcher&gt; 
configuration, . . .)
 {
   // Looks for the root path and renders the start page
 
@@ -123,12 +123,12 @@
   configuration.add("ComponentAction", new ComponentActionDispatcher(. . .), 
"after:PageRender");
 }</pre>
 </div></div><p>With an <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/OrderedConfiguration.html";>OrderedConfiguration</a>,
 each contribution gets a name, which must be unique. Here the names are 
RootPath, Asset, PageRender and ComponentAction.</p><p>The add() method takes a 
name, the contributed object for that name, and then zero or more optional 
constraints. The constraints control the ordering. The "after:" constraint 
ensures that the contribution is ordered after the other named contribution, 
the "before:" contribution is the opposite.</p><p>The ordering occurs on the 
complete set of contributions, from all modules.</p><p>Here, we need a specific 
order, used to make sure that the Dispatchers don't get confused about which 
URLs are appropriate ... for example, an asset URL might be 
/assets/tapestry5/tapestry.js. This looks just like a component action URL (for 
page "assets/tapestry5/tapestry" and component "js"). Given that sof
 tware is totally lacking in basic common-sense, we instead use careful 
ordering of the Dispatchers to ensure that AssetDispatcher is checked 
<em>before</em> the ComponentAction dispatcher.</p><h2 
id="IoCcookbook-ServiceConfigurations-ReceivingtheConfiguration.1">Receiving 
the Configuration</h2><p>The configuration, once assembled and ordered, is 
provided as a List.</p><p>The MasterDispatcher service configuration defines a 
<a  href="chainbuilder-service.html">Chain of Command</a> and we can provide 
the implementation using virtually no code:</p><div class="code panel pdl" 
style="border-style: solid;border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static Dispatcher 
buildMasterDispatcher(List&lt;Dispatcher&gt; configuration, ChainBuilder 
chainBuilder)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static Dispatcher 
buildMasterDispatcher(List&lt;Dispatcher&gt; configuration, ChainBuilder 
chainBuilder)
   {
     return chainBuilder.build(Dispatcher.class, configuration);
   }</pre>
 </div></div><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/ChainBuilder.html";>ChainBuilder</a>
 is a service that <em>builds other services</em>. Here it creates an object of 
type Dispatcher in terms of the list of Dispatchers. This is one of the most 
common uses of service builder methods ... for when the service implementation 
doesn't exist, but can be constructed at runtime.</p><h1 
id="IoCcookbook-ServiceConfigurations-MappedConfigurations">Mapped 
Configurations</h1><p>The last type of service configuration is the mapped 
service configuration. Here we relate a key, often a string, to some value. The 
contributions are ultimately combined to form a Map.</p><p>Tapestry IoC's <a  
href="symbols.html">symbol</a> mechanism allows configuration values to be 
defined and perhaps overridden, then provided to services via injection, using 
the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/
 tapestry5/ioc/annotations/Value.html">Value</a> annotation.</p><p>The first 
step is to contribute values.</p><div class="code panel pdl" 
style="border-style: solid;border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static void 
contributeFactoryDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeFactoryDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
   {
     configuration.add(SymbolConstants.FILE_CHECK_INTERVAL, "1000"); // 1 second
     configuration.add(SymbolConstants.FILE_CHECK_UPDATE_TIMEOUT, "50"); // 50 
milliseconds

Modified: websites/production/tapestry/content/ioc-cookbook.html
==============================================================================
--- websites/production/tapestry/content/ioc-cookbook.html (original)
+++ websites/production/tapestry/content/ioc-cookbook.html Mon May 21 05:20:56 
2018
@@ -86,41 +86,43 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="ioc.html">IOC</a>
+                        <a  href="tapestry-ioc-overview.html">Tapestry IoC 
Overview</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="ioc-cookbook.html">IoC cookbook</a>
+                        <a  href="ioc.html">IOC</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="tapestry-ioc-overview.html">Tapestry IoC 
Overview</a>
+                        <a  
href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control 
FAQ</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control 
FAQ</a>
+                        <a  href="ioc-cookbook.html">IoC cookbook</a>
                 
                         
                     </div>

Modified: websites/production/tapestry/content/javascript-faq.html
==============================================================================
--- websites/production/tapestry/content/javascript-faq.html (original)
+++ websites/production/tapestry/content/javascript-faq.html Mon May 21 
05:20:56 2018
@@ -78,11 +78,11 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="JavaScriptFAQ-JavaScript">JavaScript</h1><p>Main articles: <a  
href="client-side-javascript.html">Client-Side JavaScript</a>, <a  
href="legacy-javascript.html">Legacy JavaScript</a></p><h2 
id="JavaScriptFAQ-Contents">Contents</h2><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1523334093732 {padding: 0px;}
-div.rbtoc1523334093732 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334093732 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880018258 {padding: 0px;}
+div.rbtoc1526880018258 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880018258 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334093732">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880018258">
 <ul class="toc-indentation"><li><a  
href="#JavaScriptFAQ-WhydoIgeta&quot;Tapestryisundefined&quot;erroronformsubmit?(5.3andearlier)">Why
 do I get a "Tapestry is undefined" error on form submit? (5.3 and 
earlier)</a></li><li><a  
href="#JavaScriptFAQ-What'sthedifferencebetweentheT5objectandtheTapestryobjectinthebrowser?(5.3andearlier)">What's
 the difference between the T5 object and the Tapestry object in the browser? 
(5.3 and earlier)</a></li></ul>
 </div><h2 
id="JavaScriptFAQ-WhydoIgeta&quot;Tapestryisundefined&quot;erroronformsubmit?(5.3andearlier)">Why
 do I get a "Tapestry is undefined" error on form submit? (5.3 and 
earlier)</h2><p>This client-side error is clear but can be awkward to solve. It 
means your browser has not been able to load the tapestry.js file properly. The 
question is, why? It can be due to multiple reasons, some of them 
below:</p><ul><li>First, check if 'tapestry.js' is present in the head part of 
your resulting HTML page.</li><li><p>If you have set the <a  
href="configuration.html">tapestry.combine-scripts</a> configuration symbol to 
true, Tapestry generates one single URL to retrieve all the JS files. 
Sometimes, this can produce long URLs that browsers are unable to retrieve. Try 
setting the symbol to false.</p><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="confluen
 ce-information-macro-body"><p>This only applies to Tapestry 
5.1.</p></div></div></li><li>If you have included jQuery in conjunction with 
Tapestry's prototype, that will cause a conflict with the '$' selector used by 
both. In this case, you should put jQuery on top of the stack and turn on the 
<a  class="external-link" href="http://api.jquery.com/jQuery.noConflict/"; 
rel="nofollow">jQuery.noConflict</a> mode.</li><li>Also, if you have included a 
custom or third-party JS library on top of the stack that causes the JavaScript 
parsing to fail, then check the JavaScript syntax in that library.</li><li>If 
you have used a tool to minimize your JavaScript libraries, this can lead to 
JavaScript syntax errors, so check if it works with all the JavaScript files 
unpacked.</li></ul><h2 
id="JavaScriptFAQ-What'sthedifferencebetweentheT5objectandtheTapestryobjectinthebrowser?(5.3andearlier)">What's
 the difference between the <code>T5</code> object and the 
<code>Tapestry</code> object in the browser?
  (5.3 and earlier)</h2><p>Both of these objects are <em>namespaces</em>: 
containers of functions, constants, and nested namespaces.</p><p>The 
<code>T5</code> object is a replacement for the <code>Tapestry</code> object, 
starting in release 5.3. Increasingly, functions defined by the 
<code>Tapestry</code> object are being replaced with similar or equivalent 
functions in the <code>T5</code> object.</p><p>This is part of an overall goal, 
spanning at least two releases of Tapestry, to make Tapestry JavaScript 
framework agnostic; which is to say, not depend specifically on Prototype or 
jQuery. Much of the code in the <code>Tapestry</code> object is specifically 
linked to Prototype and Scriptaculous.</p><p>The <code>T5</code> object 
represents a stable, documented, set of APIs that are preferred when building 
components for maximum portability between underlying JavaScript frameworks. In 
other words, when building component libraries, coding to the <code>T5</code> 
object ensures that your
  component will be useful regardless of whether the final application is built 
using Prototype, jQuery or something else.</p></div>
       </div>

Modified: websites/production/tapestry/content/limitations.html
==============================================================================
--- websites/production/tapestry/content/limitations.html (original)
+++ websites/production/tapestry/content/limitations.html Mon May 21 05:20:56 
2018
@@ -78,14 +78,14 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="Limitations-Limitations">Limitations</h1><h2 
id="Limitations-Contents">Contents</h2><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1523334040609 {padding: 0px;}
-div.rbtoc1523334040609 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334040609 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880008656 {padding: 0px;}
+div.rbtoc1526880008656 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880008656 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334040609">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880008656">
 <ul class="toc-indentation"><li><a  
href="#Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I 
add new components to an existing page dynamically?</a></li><li><a  
href="#Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why 
doesn't my service implementation reload when I change it?</a></li><li><a  
href="#Limitations-HowdoIrunmultipleTapestryapplicationsinthesamewebapplication?">How
 do I run multiple Tapestry applications in the same web 
application?</a></li></ul>
 </div><h2 
id="Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I 
add new components to an existing page dynamically?</h2><p>The short answer 
here is: <strong>you don't</strong>. The long answer here is <strong>you don't 
have to, to get the behavior you desire</strong>.</p><p>One of Tapestry basic 
values is high scalability: this is expressed in a number of ways, reflecting 
scalability concerns within a single server, and within a cluster of 
servers.</p><p>Although you code Tapestry pages and components as if they were 
ordinary POJOs (<span>Plain Old Java Objects -- Tapestry does not require you 
to extend any base classes or implement any special interfaces)</span><span>, 
as deployed by Tapestry they are closer to a traditional servlet: a single 
instance of each page services requests from multiple threads. Behind the 
scenes, Tapestry transforms you code, rewriting it on the 
fly.</span></p><p>What this means is that <em>any</em> incoming request must be 
handled 
 by a <em>single page instance</em>. Therefore, Tapestry enforces the concept 
of <strong>static structure, dynamic behavior</strong>.</p><p>Tapestry provides 
quite a number of ways to vary what content is rendered, well beyond simple 
conditionals and loops. It is possible to "drag in" components from other pages 
when rendering a page (other FAQs will expand on this concept). The point is, 
that although a Tapestry page's structure is very rigid, the order in which the 
components of the page render does not have to be top to bottom.</p><h2 
id="Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why 
doesn't my service implementation reload when I change it?</h2><p>Main article: 
<a  href="service-implementation-reloading.html">Service Implementation 
Reloading</a></p><p>Live service reloading has some limitations:</p><ul><li>The 
service must define a service interface.</li><li>The service implementation 
must be on the file system (not inside a JAR).</li><li>The implementati
 on must be instantiated by Tapestry, not inside code (even code inside a 
module class).</li><li>The service must use the default <a  
href="limitations.html">scope</a> (reloading of perthread scopes is not 
supported).</li></ul><p>Consider the following example module:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: true; theme: Default" 
style="font-size:12px;">public static void bind(ServiceBinder binder)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: true; theme: Default" data-theme="Default">public static void 
bind(ServiceBinder binder)
 {
   binder.bind(ArchiveService.class, ArchiveServiceImpl.class);
 }

Modified: websites/production/tapestry/content/link-components-faq.html
==============================================================================
--- websites/production/tapestry/content/link-components-faq.html (original)
+++ websites/production/tapestry/content/link-components-faq.html Mon May 21 
05:20:56 2018
@@ -78,17 +78,17 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><p>&#160;</p><p>&#160;</p><h1 
id="LinkComponentsFAQ-LinkComponents">Link Components</h1><p>Main Articles: <a  
href="page-navigation.html">Page Navigation</a>, <a  
href="component-parameters.html">Component Parameters</a></p><h2 
id="LinkComponentsFAQ-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334000971 {padding: 0px;}
-div.rbtoc1523334000971 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334000971 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880012229 {padding: 0px;}
+div.rbtoc1526880012229 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880012229 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334000971">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880012229">
 <ul class="toc-indentation"><li><a  
href="#LinkComponentsFAQ-HowdoIaddqueryparameterstoaPageLinkorActionLink?">How 
do I add query parameters to a PageLink or ActionLink?</a></li><li><a  
href="#LinkComponentsFAQ-HowdoIcreateaLinkbacktothecurrentpagefromacomponent?">How
 do I create a Link back to the current page from a component?</a></li></ul>
 </div><h2 
id="LinkComponentsFAQ-HowdoIaddqueryparameterstoaPageLinkorActionLink?">How do 
I add query parameters to a PageLink or ActionLink?</h2><p>These components do 
not have parameters to allow you to specify query parameters for the link; they 
both allow you to specify a <em>context</em> (one or more values to encode into 
the request path).</p><p>However, you can accomplish the same thing with a 
little code and markup. For example, to create a link to another page and pass 
a query parameter, you can replace your PageLink component with a standard 
<code>&lt;a&gt;</code> tag:</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;a href="${profilePageLink}"&gt;Display Profile (w/ 
full details)&lt;/a&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;a 
href="${profilePageLink}"&gt;Display Profile (w/ full details)&lt;/a&gt;
 </pre>
 </div></div><p>In the matching Java class, you can create the Link 
programmatically:</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;">  @Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  @Inject
   private PageRenderLinkSource linkSource;
 
   public Link getProfilePageLink()
@@ -99,7 +99,7 @@ div.rbtoc1523334000971 li {margin-left:
   }
 </pre>
 </div></div><p>... and in the DisplayProfile page:</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>DisplayProfile.java 
(partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class DisplayProfile
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class DisplayProfile
 {
   void onActivate(@RequestParameter("detail") boolean detail)
   {
@@ -115,7 +115,7 @@ div.rbtoc1523334000971 li {margin-left:
     <div class="param-body">You may also bind a link component's 
<code>parameters</code> parameter; this is a Map of additional query parameters 
to add to the URL. The Map keys should be strings, and the Map values will be 
encoded to strings. Tapestry 5.3 also adds a literal map syntax to the <a  
href="property-expressions.html" rel="nofollow">property expression 
language</a>.</div>
 
 </div><h2 
id="LinkComponentsFAQ-HowdoIcreateaLinkbacktothecurrentpagefromacomponent?">How 
do I create a Link back to the current page from a component?</h2><p>Sometimes 
it is useful to create a link back to the current page, but you don't always 
know the name of the page (the link may appear inside a deeply nested 
subcomponent). Fortunately, this is easy.</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;t:pagelink 
page="prop:componentResources.pageName"&gt;refresh page&lt;/t:pagelink&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;t:pagelink 
page="prop:componentResources.pageName"&gt;refresh page&lt;/t:pagelink&gt;
 </pre>
 </div></div><p>Every component has an extra property, componentResources, 
added to it: it's the instance of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html";>ComponentResources</a>
 that represents the link between your code and all of Tapestry's structure 
around your class. One of the properties of ComponentResources is pageName, the 
name of the page. By binding the PageLink's page parameter with the "prop:" 
binding prefix, we ensure that we bind to a computed property; this is 
necessary because the PageLink.page parameter defaults to the "literal:" 
binding prefix.</p><p>As an added benefit, if the page class is ever renamed or 
moved to a different package, the pageName property will automatically adjust 
to the new name.</p></div>
       </div>

Modified: websites/production/tapestry/content/maven-support-faq.html
==============================================================================
--- websites/production/tapestry/content/maven-support-faq.html (original)
+++ websites/production/tapestry/content/maven-support-faq.html Mon May 21 
05:20:56 2018
@@ -78,14 +78,14 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="MavenSupportFAQ-MavenSupport">Maven Support</h1><h2 
id="MavenSupportFAQ-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1523334093488 {padding: 0px;}
-div.rbtoc1523334093488 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1523334093488 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1526880017911 {padding: 0px;}
+div.rbtoc1526880017911 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1526880017911 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1523334093488">
+/*]]>*/</style></p><div class="toc-macro rbtoc1526880017911">
 <ul class="toc-indentation"><li><a  
href="#MavenSupportFAQ-WhydoMavenprojectnamesandotherdetailsshowupinmypages?">Why
 do Maven project names and other details show up in my pages?</a></li></ul>
 </div><h2 
id="MavenSupportFAQ-WhydoMavenprojectnamesandotherdetailsshowupinmypages?">Why 
do Maven project names and other details show up in my pages?</h2><p>Tapestry 
and maven both use the same syntax for dynamic portions of files: the 
<code>${...</code>} syntax. When Maven is copying resources from 
<code>src/main/resources</code>, and when filtering is <em>enabled</em> (which 
is not the default), then any expansions in <em>Tapestry templates</em> that 
match against Maven project properties are substituted. If you look at the 
deployed application you'll see that <code>${name</code>} is gone, replaced 
with your project's name!</p><p>The solution is to update your 
<code>pom.xml</code> and ignore any .tml files when copying and 
filtering:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml 
(partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">  &lt;resource&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">  &lt;resource&gt;
     &lt;directory&gt;src/main/resources&lt;/directory&gt;
     &lt;excludes&gt;
       &lt;exclude&gt;**/*.tml&lt;/exclude&gt;

Modified: websites/production/tapestry/content/menuleft.html
==============================================================================
--- websites/production/tapestry/content/menuleft.html (original)
+++ websites/production/tapestry/content/menuleft.html Mon May 21 05:20:56 2018
@@ -77,28 +77,9 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><form 
enctype="application/x-www-form-urlencoded" method="get" 
id="advancedSearch_form" 
action="/confluence/plugins/advancedSearch/results.action"><input type="hidden" 
id="advancedSearch_autoSubmit" value="false">
-<p>  <input type="text" name="advancedSearch_query" value=""><br clear="none">
-  <input type="submit" value="Search"></p></form>
-
-    
-
-<form enctype="application/x-www-form-urlencoded" method="get" 
id="advanced-search-params">
-            <input type="hidden" name="types" value="page,blogpost">
-            <input type="hidden" name="debug" value="false">
-            <input type="hidden" name="maxResults" value="20">
-            <input type="hidden" name="fieldNames" 
value="title,rating,creation,modified,author,space">
-            <input type="hidden" name="sortField" value="title">
-            <input type="hidden" name="fields" 
value="title!Resource,rating,creation,modified,author,space!Partner">
-            <input type="hidden" name="rateThreshold" value="5">
-            <input type="hidden" name="sortDir" value="asc">
-    </form>
-
-<div id="advanced-search-results-container">
-    <div class="hidden" id="advanced-search-throbber">Loading...</div>
-    <div id="advanced-search-results"></div>
-</div>
+                <div id="ConfluenceContent"><img class="wysiwyg-unknown-macro" 
src="https://cwiki.apache.org/confluence/plugins/servlet/confluence/placeholder/unknown-macro?name=search-form&amp;locale=en_GB&amp;version=2";>
 
+<img class="wysiwyg-unknown-macro" 
src="https://cwiki.apache.org/confluence/plugins/servlet/confluence/placeholder/unknown-macro?name=search-results&amp;locale=en_GB&amp;version=2";>
 
 
 <div class="navmenu" style="float:right; background:white; margin:3px; 
padding:3px">

Modified: 
websites/production/tapestry/content/meta-programming-page-content.html
==============================================================================
--- websites/production/tapestry/content/meta-programming-page-content.html 
(original)
+++ websites/production/tapestry/content/meta-programming-page-content.html Mon 
May 21 05:20:56 2018
@@ -79,7 +79,7 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="Meta-ProgrammingPageContent-Meta-ProgrammingPageContent">Meta-Programming 
Page Content</h1><p>It is likely that you have some cross-cutting concerns 
across your pages, specific features you would like to "mix in" to your pages 
without getting tied into knots by inheritance. This is one of those areas 
where Tapestry shines.</p><p>This specific example is adapted from a real 
client requirement: the client was concerned about other sites wrapping his 
content in a frameset and making the site content appear to be theirs. Not all 
pages (in some cases, that would be an advantage) but specific pages in the 
application. For those pages, the following behaviors were 
required:</p><ul><li>Set the X-Frame-Options response header to 
"DENY"</li><li>Include JavaScript to "pop" the page out of a frame, if in 
one</li></ul><p>Again, this <em>could</em> be done by having a specific 
base-class that included a <code>beginRender()</code> method, but the
  meta-programming approach is nearly as easy and much more flexible.</p><h2 
id="Meta-ProgrammingPageContent-ComponentMeta-Data">Component 
Meta-Data</h2><p>In Tapestry, every component (and remember, pages are 
components) has <em>meta data</em>: an extra set of key/value pairs stored in 
the component's <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html";>ComponentResources</a>.</p><p>By
 hooking into the component class transformation pipeline, we can change an 
annotation into meta-data that can be accessed by a filter.</p><h2 
id="Meta-ProgrammingPageContent-DefiningtheAnnotation">Defining the 
Annotation</h2><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>ForbidFraming.java</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package com.fnord.annotations;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">package 
com.fnord.annotations;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -100,7 +100,7 @@ public @interface ForbidFraming {
 }
 </pre>
 </div></div><p>This annotation presence is all that's needed; there aren't any 
additional attributes to configure it.</p><h2 
id="Meta-ProgrammingPageContent-ConvertingtheAnnotationintoMeta-Data">Converting
 the Annotation into Meta-Data</h2><p>This is in three parts:</p><ul><li>Define 
the meta-data key, and define a constant for that key</li><li>Set a default 
meta-data value for the key</li><li>Set a different value for the key when the 
annotation is present</li></ul><p>Our key is just "forbid-framing", with values 
"true" and "false". The default is "false".</p><h3 
id="Meta-ProgrammingPageContent-DefiningtheConstant">Defining the 
Constant</h3><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>FnordSymbols.java</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package com.fnord;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">package com.fnord;
 
 import org.apache.tapestry5.services.BaseURLSource;
 
@@ -120,7 +120,7 @@ public class FnordSymbols {
 }
 </pre>
 </div></div><h3 
id="Meta-ProgrammingPageContent-SettingtheMeta-DataDefault">Setting the 
Meta-Data Default</h3><p>Next, we'll create a module just for the logic 
directly related to framing. In the module, we'll define the default value for 
the meta-data.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>ForbidFramingModule.class</b></div><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package com.fnord.services.forbidframing;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">package 
com.fnord.services.forbidframing;
 
 import org.apache.tapestry5.ioc.MappedConfiguration;
 import org.apache.tapestry5.ioc.annotations.Contribute;
@@ -140,7 +140,7 @@ public class ForbidFramingModule {
 }
 </pre>
 </div></div><h3 id="Meta-ProgrammingPageContent-MappingtheAnnotation">Mapping 
the Annotation</h3><p>Most of the work has already been done for us: we just 
have to make a contribution to the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/meta/MetaWorker.html";>MetaWorker</a>
 service, which is already plugged into the component class transformation 
pipeline. MetaWorker spots the annotations we define and uses a second object, 
a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/meta/MetaDataExtractor.html";>MetaDataExtractor</a>
 we provide, to convert the annotation into a meta-data value.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>ForbidFramingModule.java 
(partial)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Contribute(MetaWorker.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  
@Contribute(MetaWorker.class)
   public static void mapAnnotationsToMetaDataValue(
       MappedConfiguration&lt;Class, MetaDataExtractor&gt; configuration) {
     configuration
@@ -149,7 +149,7 @@ public class ForbidFramingModule {
   }
 </pre>
 </div></div><p>If the ForbidFraming annotation had attributes, we would have 
provided an implementation of MetaDataExtractor that examined those attributes 
to set the meta-data value. Since it has no attributes, the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/meta/FixedExtractor.html";>FixedExtractor</a>
 class can be used. The argument is the meta-data key, and the default value is 
"true".</p><h2 
id="Meta-ProgrammingPageContent-PluggingIntoPageRendering">Plugging Into Page 
Rendering</h2><p>The work we ultimately want to do occurs when rendering a 
page. Tapestry defines a <a  
href="meta-programming-page-content.html">pipeline</a> for that overall 
process. The point of a pipeline is that we can add filters to it. We'll add a 
filter that checks for the meta-data key and adds the response header and 
JavaScript.</p><p>The service is <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/s
 ervices/MarkupRenderer.html">MarkupRenderer</a>, which (being a pipeline 
service), takes a configuration of filters (in this case, <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MarkupRendererFilter.html";>MarkupRendererFilter</a>.</p><p>We
 contribute into the pipeline; the order is important: since the filter will 
need to write JavaScript, it must be added <em>after</em> the built-in filter 
that provides the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html";>JavaScriptSupport</a>
 environmental object.</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>ForbidFramingModule.java (partial)</b></div><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Contribute(MarkupRenderer.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  
@Contribute(MarkupRenderer.class)
   public static void addFilter(
       OrderedConfiguration&lt;MarkupRendererFilter&gt; configuration) {
     configuration.addInstance("ForbidFraming", ForbidFramingFilter.class,
@@ -157,7 +157,7 @@ public class ForbidFramingModule {
   }
 </pre>
 </div></div><p>How do you know what filters are built-in and where to add your 
own? The right starting point is the JavaDoc for the method of TapestryModule 
that contributes the base set: <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/modules/TapestryModule.html";>contributeMarkupRenderer()</a></p><h2
 id="Meta-ProgrammingPageContent-ImplementingtheFilter">Implementing the 
Filter</h2><p>Everything comes together in the filter:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>ForbidFramingFilter.java</b></div><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package com.fnord.services.forbidframing;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">package 
com.fnord.services.forbidframing;
 
 import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.ioc.annotations.Inject;
@@ -207,7 +207,7 @@ public class ForbidFramingFilter impleme
 }
 </pre>
 </div></div><p>There's a bit going on in this short piece of code. The heart 
of the code is the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/MetaDataLocator.html";>MetaDataLocator</a>
 service; given a meta-data key and a page name, it can not only extract the 
value, but then <a  href="meta-programming-page-content.html">coerce</a> it to 
a desired type, all in one go.</p><p>How do we know which page is being 
rendered? Before Tapestry 5.2 that was a small challenge, but 5.2 adds a method 
to <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html#getActivePageName()">RequestGlobals</a>
 for this exact purpose.</p><p>Both Request and JavaScriptSupport are 
per-thread/per-request services. You don't see that here, because that's part 
of the service definition, and invisible to the consumer code, as 
here.</p><p>Of course, it is vitally important that the filter re-
 invoke <code>markup()</code> on the next renderer in the pipeline (you can see 
that as the last line of the method).</p><p>This code makes one assumption: 
that the fnord application's Layout component added fnord.js to every page. 
That's necessary for the JavaScript that's added:</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>fnord.js (partial)</b></div><div 
class="codeContent panelContent pdl">
-<pre class="brush: js; gutter: false; theme: Default" 
style="font-size:12px;">Fnord = {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: js; 
gutter: false; theme: Default" data-theme="Default">Fnord = {
   popOutOfFrame : function() {
     if (top != self)
       top.location.replace(location);


Reply via email to