You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by bu...@apache.org on 2015/07/19 23:21:30 UTC

svn commit: r958985 [10/29] - in /websites/production/tapestry/content: ./ 2009/09/13/ 2009/10/27/ 2009/11/25/ 2010/07/18/ 2010/07/24/ 2010/10/11/ 2010/10/31/ 2010/11/18/ 2010/12/16/ 2010/12/17/ 2011/01/18/ 2011/03/23/ 2011/03/29/ 2011/03/30/ 2011/03/3...

Modified: websites/production/tapestry/content/defining-tapestry-ioc-services.html
==============================================================================
--- websites/production/tapestry/content/defining-tapestry-ioc-services.html (original)
+++ websites/production/tapestry/content/defining-tapestry-ioc-services.html Sun Jul 19 21:21:27 2015
@@ -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 type="text/javascript">
+  SyntaxHighlighter.defaults['toolbar'] = false;
+  SyntaxHighlighter.all();
+  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -57,15 +67,7 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><style type="text/css">/*<![CDATA[*/
-table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
-table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
-table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
-table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
-table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
-table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
-
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="tapestry-ioc-modules.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="tapestry-ioc-modules.html">Tapestry IoC Modules</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="ioc.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="ioc.html">IoC</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="service-advisors.html">Service Advisors</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="service-advisors.html"><img align="middle" border="0
 " src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div>
+<div id="ConfluenceContent">
 
 <p>Services consist of two main parts: a service interface and a service implementation.</p>
 
@@ -91,7 +93,7 @@ table.ScrollbarTable td.ScrollbarNextIco
 <p>Tapestry doesn't know how to instantiate and configure your service; instead it relies on you to provide the code to do so, in a service builder method, a method whose name is (or starts with) "build":</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 public class MyAppModule
@@ -100,7 +102,7 @@ public class MyAppModule
   {
     return new IndexerImpl();
   }
-}]]></script>
+}</pre>
 </div></div>
 
 <p>Here the service interface is Indexer (presumably inside the org.example.myapp.services package, since there isn't an import). Tapestry IoC doesn't know about the IndexerImpl class (the service implementation of the Indexer service), but it does know about the build() method.</p>
@@ -118,7 +120,7 @@ public class MyAppModule
 <p>Every module may have an optional, static bind() method which is passed a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBinder.html">ServiceBinder</a>. Services may be registered with the container by "binding" a service interface to a service implementation:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.ServiceBinder;
@@ -129,7 +131,7 @@ public class MyAppModule
   {
     binder.bind(Indexer.class, IndexerImpl.class);
   }
-}]]></script>
+}</pre>
 </div></div>
 
 <p>You can make repeated calls to ServiceBinder.bind(), to bind additional services.</p>
@@ -143,7 +145,7 @@ public class MyAppModule
 <p>Following the convention over configuration principle, the autobuilding of services can be even less verbose. If a service interface is passed as a single argument to the bind() method, Tapestry will try to find an implementation in the same package whose name matches the name of the service interface followed by the suffix <em>Impl</em>.</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.ServiceBinder;
@@ -154,7 +156,7 @@ public class MyAppModule
   {
     binder.bind(Indexer.class);
   }
-}]]></script>
+}</pre>
 </div></div>
 
 <h1 id="DefiningTapestryIOCServices-ServiceIds">Service Ids</h1>
@@ -166,22 +168,22 @@ public class MyAppModule
 <p>This can be overridden by adding the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html">ServiceId</a> annotation to the service builder method:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  @ServiceId(&quot;FileSystemIndexer&quot;)
-  public static Indexer buildIndexer(@InjectService(&quot;FileSystem&quot;) FileSystem fileSystem)
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  @ServiceId("FileSystemIndexer")
+  public static Indexer buildIndexer(@InjectService("FileSystem") FileSystem fileSystem)
   {
      . . .
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>Another option is to add the service id to the method name, after "build", for example:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  public static Indexer buildFileSystemIndexer(@InjectService(&quot;FileSystem&quot;) FileSystem fileSystem)
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  public static Indexer buildFileSystemIndexer(@InjectService("FileSystem") FileSystem fileSystem)
   {
      . . .
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>Here, the service id is "FileSystemIndexer" not "Indexer".</p>
@@ -189,26 +191,26 @@ public class MyAppModule
 <p>For autobuilt services, the service id can be specified by placing the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html">ServiceId</a> annotation directly on a service implementation class.</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  @ServiceId(&quot;FileSystemIndexer&quot;)
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  @ServiceId("FileSystemIndexer")
   public class IndexerImpl implements Indexer
   {
       ...
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>When the service is bound, the value of the annotation is used as id:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  binder.bind(Indexer.class, IndexerImpl.class);]]></script>
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  binder.bind(Indexer.class, IndexerImpl.class);</pre>
 </div></div>
 
 <p>This id can be overriden again by calling the method <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBindingOptions.html#withIdjava.lang.String">withId</a></p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  binder.bind(Indexer.class, IndexerImpl.class).withId(&quot;FileSystemIndexer&quot;);]]></script>
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  binder.bind(Indexer.class, IndexerImpl.class).withId("FileSystemIndexer");</pre>
 </div></div>
 
 <h1 id="DefiningTapestryIOCServices-Injecting_DependenciesInjectingDependencies"><span class="confluence-anchor-link" id="DefiningTapestryIOCServices-Injecting_Dependencies"></span>Injecting Dependencies</h1>
@@ -223,7 +225,7 @@ public class MyAppModule
 <p>For example, let's say the Indexer needs a JobScheduler to control when it executes, and a FileSystem to access files and store indexes.</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer build(JobScheduler scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
@@ -231,7 +233,7 @@ public class MyAppModule
     scheduler.scheduleDailyJob(indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>Tapestry assumes that parameters to builder methods are dependencies; in this example it is able to figure out what services to pass in based just on the type (later we'll see how we can fine tune this with annotations, when the service type is not sufficient to identify a single service).</p>
@@ -243,11 +245,11 @@ public class MyAppModule
 <p>What happens if there is more than one service that implements the JobScheduler interface, or the FileSystem interface? You'll see a runtime exception, because Tapestry is unable to resolve it down to a <em>single</em> service. At this point, it is necessary to <em>disambiguate</em> the link between the service interface and <em>one</em> service. One approach is to use the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html">InjectService</a> annotation:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  public static Indexer build(@InjectService(&quot;JobScheduler&quot;)
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  public static Indexer build(@InjectService("JobScheduler")
     JobScheduler scheduler,
 
-    @InjectService(&quot;FileSystem&quot;)
+    @InjectService("FileSystem")
     FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
@@ -255,7 +257,7 @@ public class MyAppModule
     scheduler.scheduleDailyJob(indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>If you find yourself injecting the same dependencies into multiple service builder (or service decorator) methods, you can <a shape="rect" href="tapestry-ioc-modules.html">cache dependency injections</a> in your module, by defining a constructor. This reduces duplication in your module.</p>
@@ -273,7 +275,7 @@ public class MyAppModule
 <p>We can associate those two JobSchedulers with two annotations.</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 @Target(
 { PARAMETER, FIELD })
 @Retention(RUNTIME)
@@ -297,10 +299,10 @@ public class MyModule
 {
   public static void bind(ServiceBinder binder)
   {
-    binder.bind(JobScheduler.class, ClusteredJobSchedulerImpl.class).withId(&quot;ClusteredJobScheduler&quot;).withMarker(Clustered.class);
-    binder.bind(JobScheduler.class, SimpleJobSchedulerImpl.class).withId(&quot;InProcessJobScheduler&quot;).withMarker(InProcess.class);
+    binder.bind(JobScheduler.class, ClusteredJobSchedulerImpl.class).withId("ClusteredJobScheduler").withMarker(Clustered.class);
+    binder.bind(JobScheduler.class, SimpleJobSchedulerImpl.class).withId("InProcessJobScheduler").withMarker(InProcess.class);
   }
-}]]></script>
+}</pre>
 </div></div>
 
 <p>Notice that the marker annotations have no attributes. Further, we support markers on fields (for use in Tapestry components) as well as parameters.</p>
@@ -308,7 +310,7 @@ public class MyModule
 <p>To get the right version of the service, you use one of the annotations:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 public class MyServiceImpl implements MyService
 {
   private final JobScheduler jobScheduler;
@@ -319,7 +321,7 @@ public class MyServiceImpl implements My
   }
 
   . . .
-}  ]]></script>
+}  </pre>
 </div></div>
 
 <p>The @Clustered annotation on the parameter is combined with the parameter type (JobScheduler) to find the exact service implementation.</p>
@@ -329,12 +331,12 @@ public class MyServiceImpl implements My
 <p>With a service builder method, you use the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Marker.html">Marker</a> annotation:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   @Marker(Clustered.class)
   public JobScheduler buildClusteredJobScheduler()
   {
     return . . .;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>The @Marker annotation may also be placed on an implementation class, which means that you may omit the call to withMarker() inside the bind() method.</p>
@@ -354,7 +356,7 @@ public class MyServiceImpl implements My
 <p>Instead, the injections occur on <em>constructor</em> for the implementation class:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
@@ -363,13 +365,13 @@ public class IndexerImpl implements Inde
 {
   private final FileSystem fileSystem;
 
-  public IndexerImpl(@InjectService(&quot;FileSystem&quot;) FileSystem fileSystem)
+  public IndexerImpl(@InjectService("FileSystem") FileSystem fileSystem)
   {
     this.fileSystem = fileSystem;
   }
 
   . . .
-}]]></script>
+}</pre>
 </div></div>
 
 <p>If the class has multiple constructors, the constructor with the <em>most</em> parameters will be invoked. Alternately, you may mark a single constructor with the Inject annotation, and Tapestry will use <em>that</em> constructor specifically, ignoring all other constructors.</p>
@@ -379,7 +381,7 @@ public class IndexerImpl implements Inde
 <p>Once thing that is not a good idea is to pass in another service, such as JobScheduler in the previous example, and pass <code>this</code> from a constructor:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
@@ -388,9 +390,9 @@ public class IndexerImpl implements Inde
 {
   private final FileSystem fileSystem;
 
-  public IndexerImpl(@InjectService(&quot;FileSystem&quot;) FileSystem fileSystem,
+  public IndexerImpl(@InjectService("FileSystem") FileSystem fileSystem,
 
-  @InjectService(&quot;JobScheduler&quot;) JobScheduler scheduler)
+  @InjectService("JobScheduler") JobScheduler scheduler)
   {
     this.fileSystem = fileSystem;
 
@@ -398,7 +400,7 @@ public class IndexerImpl implements Inde
   }
 
   . . .
-}]]></script>
+}</pre>
 </div></div>
 
 <p>Understanding why this is a bad idea involves a long detour into inner details of the Java Memory Model. The short form is that other threads may end up invoking methods on the IndexerImpl instance, and its fields (even though they are final, even though they appear to already have been set) may be uninitialized.</p>
@@ -412,18 +414,18 @@ public class IndexerImpl implements Inde
 <p>Caution: injection via fields uses reflection to make the fields accessible. In addition, it may not be as thread-safe as using the constructor to assign to final fields.</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
 package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
 
 public class IndexerImpl implements Indexer
 {
-  @InjectService(&quot;FileSystem&quot;)
+  @InjectService("FileSystem")
   private FileSystem fileSystem;
 
   . . .
-}]]></script>
+}</pre>
 </div></div>
 
 <h1 id="DefiningTapestryIOCServices-ServiceScopeDefiningServiceScope"><span class="confluence-anchor-link" id="DefiningTapestryIOCServices-ServiceScope"></span>Defining Service Scope</h1>
@@ -463,8 +465,8 @@ public class IndexerImpl implements Inde
 <p>In addition, it is possible to specify the scope when binding the service:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  bind(MyServiceInterface.class, MyServiceImpl.class).scope(ScopeConstants.PERTHREAD);]]></script>
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  bind(MyServiceInterface.class, MyServiceImpl.class).scope(ScopeConstants.PERTHREAD);</pre>
 </div></div>
 
 <h1 id="DefiningTapestryIOCServices-EagerLoadingServices">Eager Loading Services</h1>
@@ -490,8 +492,8 @@ public class IndexerImpl implements Inde
 <p>You may also specify eager loading explicitly when binding the service:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
-  bind(MyServiceInterface.class, MyServiceImpl.class).eagerLoad();]]></script>
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
+  bind(MyServiceInterface.class, MyServiceImpl.class).eagerLoad();</pre>
 </div></div>
 
 <h1 id="DefiningTapestryIOCServices-InjectingResources">Injecting Resources</h1>
@@ -510,7 +512,7 @@ public class IndexerImpl implements Inde
 <p>Example:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer build(String serviceId, Log serviceLog,
      JobScheduler scheduler, FileSystem fileSystem)
   {
@@ -519,7 +521,7 @@ public class IndexerImpl implements Inde
     scheduler.scheduleDailyJob(serviceId, indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>The order of parameters is completely irrelevant. They can come first or last or be interspersed however you like.</p>
@@ -531,7 +533,7 @@ public class IndexerImpl implements Inde
 <p>Further, ServiceResources includes an autobuild() method that allows you to easily trigger the construction of a class, including dependencies. Thus the previos example could be rewritten as:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer build(ServiceResources resources, JobScheduler jobScheduler)
   {
     IndexerImpl indexer = resources.autobuild(IndexerImpl.class);
@@ -539,7 +541,7 @@ public class IndexerImpl implements Inde
     scheduler.scheduleDailyJob(resources.getServiceId(), indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>This works the exact same way with autobuilt services, except that the parameters of the service implementation constructor are considered, rather than the parameters of the service builder method.</p>
@@ -551,10 +553,10 @@ public class IndexerImpl implements Inde
 <p>Every once and a while, you'll have a conflict between a resource type and an object injection. For example, the following does not work as expected:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer build(String serviceId, Log serviceLog,
      JobScheduler scheduler, FileSystem fileSystem,
-     @Value(&quot;${index-alerts-email}&quot;)
+     @Value("${index-alerts-email}")
      String alertEmail)
   {
     IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem, alertEmail);
@@ -562,16 +564,16 @@ public class IndexerImpl implements Inde
     scheduler.scheduleDailyJob(serviceId, indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>It doesn't work because type String always gets the service id, as a resource (as with the serviceId parameter). In order to get this to work, we need to turn off the resource injection for the alertEmail parameter. That's what the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html">Inject</a> annotation does:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer build(String serviceId, Log serviceLog,
      JobScheduler scheduler, FileSystem fileSystem,
-     @Inject @Value(&quot;${index-alerts-email}&quot;)
+     @Inject @Value("${index-alerts-email}")
      String alertEmail)
   {
     IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem, alertEmail);
@@ -579,7 +581,7 @@ public class IndexerImpl implements Inde
     scheduler.scheduleDailyJob(serviceId, indexer);
 
     return indexer;
-  }]]></script>
+  }</pre>
 </div></div>
 
 <p>Here, the alertEmail parameter will receive the configured alerts email (see <a shape="rect" href="symbols.html">the symbols documentation</a> for more about this syntax) rather than the service id.</p>
@@ -604,7 +606,7 @@ public class IndexerImpl implements Inde
 <p>With Tapestry IoC, this is not even considered a special case:</p>
 
 <div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
   public static Indexer buildIndexer(JobScheduler scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
@@ -617,7 +619,7 @@ public class IndexerImpl implements Inde
   public static FileSystem buildFileSystem(Indexer indexer)
   {
     return new FileSystemImpl(indexer);
-  }  ]]></script>
+  }  </pre>
 </div></div>
 
 <p>Here, Indexer and FileSystem are mutually dependent. Eventually, one or the other of them will be created ... let's say its FileSystem. The buildFileSystem() builder method will be invoked, and a proxy to Indexer will be passed in. Inside the FileSystemImpl constructor (or at some later date), a method of the Indexer service will be invoked, at which point, the builderIndexer() method is invoked. It still receives the proxy to the FileSystem service.</p>
@@ -627,16 +629,7 @@ public class IndexerImpl implements Inde
 <p>This approach can be very powerful.  For example, it can be used to break apart untestable monolithic code into two mutually dependent halves, each of which can be unit tested.</p>
 
 <p>The exception to this rule is a service that depends on itself <em>during construction</em>. This can occur when (indirectly, through other services) building the service tries to invoke a method on the service being built. This can happen when the service implementation's constructor invoke methods on service dependencies passed into it, or when the service builder method itself does the same. This is actually a very rare case and difficult to illustrate.</p>
-
-<style type="text/css">/*<![CDATA[*/
-table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
-table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
-table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
-table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
-table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
-table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
-
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="tapestry-ioc-modules.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="tapestry-ioc-modules.html">Tapestry IoC Modules</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="ioc.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="ioc.html">IoC</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="service-advisors.html">Service Advisors</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="service-advisors.html"><img align="middle" border="0
 " src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div></div>
+</div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/dependencies-tools-and-plugins.html
==============================================================================
--- websites/production/tapestry/content/dependencies-tools-and-plugins.html (original)
+++ websites/production/tapestry/content/dependencies-tools-and-plugins.html Sun Jul 19 21:21:27 2015
@@ -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 type="text/javascript">
+  SyntaxHighlighter.defaults['toolbar'] = false;
+  SyntaxHighlighter.all();
+  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -57,23 +67,7 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><style type="text/css">/*<![CDATA[*/
-table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
-table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
-table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
-table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
-table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
-table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
-
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%">&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="tapestry-tutorial.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="tapestry-tutorial.html">Tapestry Tutorial</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="creating-the-skeleton-application.html">Creating The Skeleton Application</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="creating-the-skeleton-application.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div><p>As much as we would like to dive into Tapestry right now, we must first talk about settin
 g up your development environment. The joy and the pain of Java development is the volume of choice available. There's just a bewildering number of JDKs, IDEs and other TLAs (Three Letter Acronyms) out there.</p><p>Let's talk about a stack of tools, all open source and freely available, that you'll need to setup. Likely you have some of these, or some version of these, already on your development machine.</p><h1 id="Dependencies,ToolsandPlugins-JDK1.5orNewer">JDK 1.5 or Newer</h1><p>Tapestry requires Java Development Kit (JDK) version 1.5 or newer, except that starting with Tapestry 5.4 you must use JDK 1.6 or newer. JDK 1.8 works only for Tapestry 5.3.8 or newer (but see the <a shape="rect" href="release-notes-538.html">release notes</a>).</p><h1 id="Dependencies,ToolsandPlugins-EclipseIDE">Eclipse IDE</h1><p>For this tutorial we'll assume you're using Eclipse as your Integrated Development Environment (IDE). Eclipse is a popular IDE, but feel free to adapt these instructions to In
 telliJ, NetBeans, or any other.</p><p>Eclipse comes in various flavors, and includes a reasonable XML editor built-in. It can be <a shape="rect" class="external-link" href="http://www.eclipse.org/downloads/" >downloaded from the eclipse.org web site</a>. We recommend the latest version of Eclipse IDE for Java Developers (but anything from version 3.7 onward should work fine).</p><h1 id="Dependencies,ToolsandPlugins-ApacheMaven3">Apache Maven 3</h1><p>Maven is a software build tool with the ability to automatically download project dependencies (such as the Tapestry JAR files, and the JAR files that Tapestry itself depends on) from one of several central repositories.</p><p>Maven is not essential for using Tapestry, but is especially helpful when performing the initial set-up of a Tapestry application.</p><p>Eclipse comes with a Maven plugin,&#160;<a shape="rect" class="external-link" href="http://eclipse.org/m2e/" >M2Eclipse</a> (also known as m2e) with an embedded version of Maven.
  We'll use that here for simplicity's sake. Alternatively, you could install Maven from <a shape="rect" class="external-link" href="http://maven.apache.org/download.html">http://maven.apache.org/download.html</a> and use it from the command line ("mvn").</p><h1 id="Dependencies,ToolsandPlugins-Jetty">Jetty</h1><p>Jetty is an open source web server and servlet container available from the Eclipse Foundation. Jetty is designed for high performance and easy embedding in other software. Maven can download it for you and run it automatically, so you DO NOT have to download it for this tutorial. Alternatively, you could download and install the RunJettyRun Eclipse plugin from the Eclipse Marketplace.</p><h1 id="Dependencies,ToolsandPlugins-Tapestry">Tapestry</h1><p>You should not have to download this directly; as we'll see, Maven should take care of downloading Tapestry, and its dependencies, as needed.</p><style type="text/css">/*<![CDATA[*/
-table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
-table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
-table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
-table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
-table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
-table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
-
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%">&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="tapestry-tutorial.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="tapestry-tutorial.html">Tapestry Tutorial</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="creating-the-skeleton-application.html">Creating The Skeleton Application</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="creating-the-skeleton-application.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div></div>
+<div id="ConfluenceContent"><p>As much as we would like to dive into Tapestry right now, we must first talk about setting up your development environment. The joy and the pain of Java development is the volume of choice available. There's just a bewildering number of JDKs, IDEs and other TLAs (Three Letter Acronyms) out there.</p><p>Let's talk about a stack of tools, all open source and freely available, that you'll need to setup. Likely you have some of these, or some version of these, already on your development machine.</p><h1 id="Dependencies,ToolsandPlugins-JDK1.5orNewer">JDK 1.5 or Newer</h1><p>Tapestry requires Java Development Kit (JDK) version 1.5 or newer, except that starting with Tapestry 5.4 you must use JDK 1.6 or newer. JDK 1.8 works only for Tapestry 5.3.8 or newer (but see the <a shape="rect" href="release-notes-538.html">release notes</a>).</p><h1 id="Dependencies,ToolsandPlugins-EclipseIDE">Eclipse IDE</h1><p>For this tutorial we'll assume you're using Eclipse as 
 your Integrated Development Environment (IDE). Eclipse is a popular IDE, but feel free to adapt these instructions to IntelliJ, NetBeans, or any other.</p><p>Eclipse comes in various flavors, and includes a reasonable XML editor built-in. It can be <a shape="rect" class="external-link" href="http://www.eclipse.org/downloads/" >downloaded from the eclipse.org web site</a>. We recommend the latest version of Eclipse IDE for Java Developers (but anything from version 3.7 onward should work fine).</p><h1 id="Dependencies,ToolsandPlugins-ApacheMaven3">Apache Maven 3</h1><p>Maven is a software build tool with the ability to automatically download project dependencies (such as the Tapestry JAR files, and the JAR files that Tapestry itself depends on) from one of several central repositories.</p><p>Maven is not essential for using Tapestry, but is especially helpful when performing the initial set-up of a Tapestry application.</p><p>Eclipse comes with a Maven plugin,&#160;<a shape="rect" cl
 ass="external-link" href="http://eclipse.org/m2e/" >M2Eclipse</a> (also known as m2e) with an embedded version of Maven. We'll use that here for simplicity's sake. Alternatively, you could install Maven from <a shape="rect" class="external-link" href="http://maven.apache.org/download.html">http://maven.apache.org/download.html</a> and use it from the command line ("mvn").</p><h1 id="Dependencies,ToolsandPlugins-Jetty">Jetty</h1><p>Jetty is an open source web server and servlet container available from the Eclipse Foundation. Jetty is designed for high performance and easy embedding in other software. Maven can download it for you and run it automatically, so you DO NOT have to download it for this tutorial. Alternatively, you could download and install the RunJettyRun Eclipse plugin from the Eclipse Marketplace.</p><h1 id="Dependencies,ToolsandPlugins-Tapestry">Tapestry</h1><p>You should not have to download this directly; as we'll see, Maven should take care of downloading Tapestry
 , and its dependencies, as needed.</p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/developer-bible.html
==============================================================================
--- websites/production/tapestry/content/developer-bible.html (original)
+++ websites/production/tapestry/content/developer-bible.html Sun Jul 19 21:21:27 2015
@@ -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 type="text/javascript">
+  SyntaxHighlighter.defaults['toolbar'] = false;
+  SyntaxHighlighter.all();
+  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -59,7 +69,7 @@
 <div id="content">
 <div id="ConfluenceContent"><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
 <div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>IDE choices, coding style and formatting, commit practices, naming conventions and other issues relevant to Tapestry committers &amp; contributers.</p><h2 id="DeveloperBible-IDEChoices">IDE Choices</h2><h3 id="DeveloperBible-IntelliJ">IntelliJ</h3><p>It's a free license for all committers and it's just better. Yes, the first few days can be an unpleasant fumble because everything is almost, but not quite, familiar. Pretty soon you'll love IDEA and recognize that Eclipse has been bending you over and doing unspeakable things.</p><p>There are shared code formatting settings in the <a shape="rect" class="external-link" href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=support">support directory</a> (idea-settings.jar). This will prevent unexpected conflicts due to format
 ting.</p><h3 id="DeveloperBible-Eclipse">Eclipse</h3><p>Howard uses this ... because he can't manage to switch IDEs constantly (he uses Eclipse for training). Lately its gotten better.</p><p>As with IntelliJ, there are shared code formatting settings for Eclipse in the <a shape="rect" class="external-link" href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=support">support directory</a> (tapestry-indent-eclipse.xml).</p><h2 id="DeveloperBible-Copyrights">Copyrights</h2><p>All source files should have the ASF copyright comment on top, except where such a comment would interfere with its behavior. For example, component template files omit the comment.</p><p>As you make changes to files, update the copyright to add the current year to the list. The goal is that the copyright notice includes the year in which files change. When creating a new file, don't back date the copyright year ... start with the current year. Try not to change the copyright year on files that
  haven't actually changed.</p><p>IntelliJ has a great comparison view: Cmd-9 to see the local changes, the Cmd-D to see the differences. You can whip through the changes (using Cmd-forward arrow) and make sure copyrights are up to date as you review the changes prior to a commit.</p><h2 id="DeveloperBible-CommitMessages">Commit Messages</h2><p>Always provide a commit message. Howard generally tries to work off the JIRA, so his commit message is often:</p><blockquote><p>TAP5-1234: Make the Foo Widget more Ajax-tastic!</p></blockquote><p>It is <em>very important</em> to include the JIRA issue id in the commit. This is used in many places: JIRA links issues to the Git&#160;commits for that issue (very handy for seeing what changed as part of a bug fix). The Hudson CI server does as well, and will actually link Git&#160;commits to issues after succesfully building.</p><h2 id="DeveloperBible-JIRAProcedures">JIRA Procedures</h2><p>All Tapestry committers should be registerred with JIRA an
 d part of the tapestry-developers JIRA group.</p><p>Every committer is invited to look at the list of <a shape="rect" class="external-link" href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12317068">'Review for closing'</a> issues and review them as it contains probably outdated or no more valid issues.</p><p>There's also a list of all <a shape="rect" class="external-link" href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12316792">Open</a> issue about the project.</p><p>Ideally, we would always work top priortity to low priority. Howard sometimes jump out of order, if there's something cool to work on that fits in an available time slot. Alternately, you are always allowed to change the priority of a bug before or as you work it.</p><p>As a general rule issues which are "<em>Invalid</em>" or "<em>Won't</em> <em>Fix</em>" shouldn't have a "<em>Fix</em> <em>version</em>".</p><h3 id="DeveloperBible-Startingwo
 rk">Starting work</h3><p>When you start to work on an issue, make sure it is <em>assigned to you</em> and use the <em>start progress</em> option.</p><p>Add comments about the state of the fix, or the challenges in creating a fix. This often spurs the Issue's adder to<br clear="none"> provide more details.</p><p>Update the issue description to make it more legible and more precise if needed, i.e., "NPE in CheckUpdates" might become "NullPointerException when checking for updates to files that have been deleted". Verbose is good.</p><h3 id="DeveloperBible-Closingbugs">Closing bugs</h3><p>Is it a bug fix without tests? <strong>No.</strong> A good plan is to write a test that fails then work the code until the test passes. Often code works in a unit test but fails unexpectedly in an integration test. As the G-Man says <em>"Expect unforeseen consequences"</em>.</p><p>When you check in a fix, you should <strong>close</strong> the issue and make sure the <strong>fix release</strong> is cor
 rect.</p><p>We're playing fast and loose &#8211; a better procedure would be to mark the bug resolved and verify the fix before closing it. That's ok, we have a community to double check our work <img class="emoticon emoticon-smile" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/smile.png" data-emoticon-name="smile" alt="(smile)">.</p><p>For anything non-trivial, wait for the Hudson CI server to build. It catches a lot of things ... such as files that were not added to Git. And even IntelliJ has a bit of trouble with wildly refactored code. Hudson will catch all that.</p><h3 id="DeveloperBible-Invalidissuesandduplicates">Invalid issues and duplicates</h3><p>Always provide comments about why_ an issue is invalid (<em>"A Ruby implementation of Tapestry is out of scope for the project."</em>), or at least, a link to the duplicate issues.</p><p>Consider writing new tests to prove that an issue is not valid and th
 en leave the tests in place &#8211; then close the bug as invalid.</p><p>Close the issue but <em>make sure the fix release is blank</em>. Otherwise, the issue <em>will be listed in the release notes</em>, which we don't want.</p><h2 id="DeveloperBible-Publicvs.Private/Internal">Public vs. Private/Internal</h2><p>This is a real big deal. As long as code is in the internal package, we have a high degree of carte-blanche to change it. As soon as code is public, we become handcuffed to backwards compatibility.</p><p><em>Interfaces are public, implementations are private</em>. You can see this is the bulk of the code, where org.apache.tapestry5.services is almost all interfaces and the implementations are in org.apache.tapestry5.internal.services.</p><p>Many more services have both the interface and the implementation in org.apache.tapestry5.internal.services.</p><p>We absolutely <em>do not</em> want to make Page or ComponentPageElement public. You will often see public service facades t
 hat take a page name as a method parameter, and convert it to a page instance before invoking methods on internal services.</p><h2 id="DeveloperBible-EvolvingComponents">Evolving Components</h2><p>We do not have a specific plan for this yet. Future Tapestry 5 will add features to allow clean renames of parameters, and a way to deprecated and eventually remove components.</p><h2 id="DeveloperBible-EvolvingInterfaces">Evolving Interfaces</h2><p>Tapestry uses interfaces quite extensively.</p><p>Interfaces fall into two categories: service interfaces called by user code, and interfaces implemented by user code.</p><p>Internal interfaces may be changed at any time. That's why so much is kept internal.</p><h3 id="DeveloperBible-ServiceInterfaces">Service Interfaces</h3><p>New methods may be added if absolutely necessary, but this should be avoided if at all possible. Don't forget the <code>@since</code> Javadoc annotation.</p><p>Consider having a stable public facade service whose impleme
 ntation calls into one or more internal service.</p><h3 id="DeveloperBible-UserInterfaces">User Interfaces</h3><p>These should be frozen, no changes once released. Failure to do so causes <em>non-backwards compatible upgrade problems</em>; that is, classes that implement the (old) interface are suddenly invalid, missing methods from the (new) interface.</p><p>Consider introducing a new interface that extends the old one and adds new methods. Make sure you support both.</p><p>You can see this with ServiceDef and ServiceDef2 (which extends ServiceDef). Yes this can be a bit ugly.</p><p>Howard uses utility methods that convert from ServiceDef to ServiceDef2, adding a wrapper implementation around a ServiceDef instance if necessary:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  public static ServiceDef2 toServiceDef2(final ServiceDef sd)
+<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">  public static ServiceDef2 toServiceDef2(final ServiceDef sd)
   {
     if (sd instanceof ServiceDef2)
         return (ServiceDef2) sd;
@@ -79,7 +89,7 @@
         . . .
     };
   }
-]]></script>
+</pre>
 </div></div><h2 id="DeveloperBible-Useof@since">Use of @since</h2><p>When adding new classes or interface, or adding new methods to existing types, add an @since Javadoc comment.</p><p>Use the complete version number of the release in which the type or method was added: i.e., <em>@since 5.1.0.3</em>.</p><h2 id="DeveloperBible-CodeStyle&amp;Formatting">Code Style &amp; Formatting</h2><p>Yes, at one time Howard used leading underscores for field names. He has since changed my mind, but this unfortunately infected other people; please try to make your code blend in when modifying existing source.</p><p>Long ago, Tapestry (3) code used the regrettable "leading-I-on-interfaces" style. Don't do that. Instead, name the implementation class with an "Impl" at the end.</p><p>Howard prefers braces on a new line (and thus, open braces lined up with close braces), so that's what the default code formatting is set up for. It's okay to omit braces for trivial one-liner if statements, such as <code
 >if (!test) return;</code>.</p><p>Indent with 4 spaces instead of tabs.</p><p>Use a lot of vertical whitespace to break methods into logical sections.</p><p>We're coding Java, not Pascal; it's better to have a few checks early on with quick returns or exceptions than have ten-levels deep block nesting just so a method can have a single return statement. In other words, <em>else considered harmful</em>. Low code complexity is better, more readable, more maintainable code.</p><p>Don't bother alphabetizing things, because the IDE lets you jump around easily.</p><p><em>Final is the new private.</em> Final fields are great for multi-threaded code. Especially when creating service implementations with dependencies, store those dependencies into final fields. Once we're all running on 100 core workstations, you'll thank me. Seriously, Java's memory model is seriously twisted stuff, and assigning to a non-final field from a constructor opens up a tiny window of non-thread safety.</p><h2 id=
 "DeveloperBible-Comments">Comments</h2><p>Comments are overwhelmingly important. Try to capture the <em>why</em> of a class or method. Add lots of links, to code that will be invoked by the method, to related methods or classes, and so forth. For instance, you may often have an annotation, a worker class for the annotation, and a related service all cross-linked.</p><p>Comment the <em>interfaces</em> and don't get worked up on the <em>implementations</em>. Javadoc does a perfectly good job of copying interface comments to implementations, so this falls under the <em>Don't Repeat Yourself</em> guideline.</p><p>Be very careful about documenting what methods can accept null, and what methods may return null. Generally speaking, people will assume that null is not allowed for parameters, and method will never return null, unless it is explicitly documented that null is allowed (or potentially returned).</p><h2 id="DeveloperBible-Documentation">Documentation</h2><p>Try and keep the docum
 entation up-to date as you make changes; it is <em>much</em> harder to do so later. This is now much easier using the Confluence wiki (you're reading the result <img class="emoticon emoticon-smile" src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/smile.png" data-emoticon-name="smile" alt="(smile)">).</p><p>Documentation was at one point the <em>#1 criticism</em> of Tapestry!</p><h2 id="DeveloperBible-ClassandMethodNamingConventions">Class and Method Naming Conventions</h2><p>Naming things is hard. Names that make sense to one person won't to another.</p><p>That being said, Howard has tried to be somewhat consistent with naming. Not perfectly.</p><h3 id="DeveloperBible-Factory,Creator">Factory, Creator</h3><p>A factory class creates new objects. Methods will often be prefixed with "create" or "new". Don't expect a Factory to cache anything, it just creates new things.</p><h3 id="DeveloperBible-Source">Source</h3
 ><p>A source is a level up from a Factory. It <em>may</em> combine multiple factories together. It <em>usually</em> will cache the result. Method are often prefixed with "get".</p><h3 id="DeveloperBible-Findvs.Get">Find vs. Get</h3><p>For methods: A "find" prefix indicates that a non-match is valid and null may be returned. A "get" prefix indicates that a non-match is invalid and an exception will be thrown in that case (and null will never be returned).</p><h3 id="DeveloperBible-Contribution">Contribution</h3><p>A data object usually associated with a Tapestry IoC service's configuration.</p><h3 id="DeveloperBible-Filter">Filter</h3><p>Part of a pipeline, where there's an associated main interface, and the Filter wraps around that main interface. Each main interface method is duplicated in the Filter, with an extra parameter used to chain the interface.</p><h3 id="DeveloperBible-Manager">Manager</h3><p>Often a wrapper around a service configuration, it provides access to the contri
 buted values (possibly after some transformation).</p><h3 id="DeveloperBible-To">To</h3><p>A method prefix that indicates a conversion or coersion from one type to another. I.e., <code>toUserPresentable()</code>.</p><h3 id="DeveloperBible-Worker">Worker</h3><p>An object that peforms a specific job. Workers will be stateless, but will be passed a stateful object to perform some operation upon.</p><h3 id="DeveloperBible-Builder">Builder</h3><p>An object whose job is to create other objects, typically in the context of creating a core service implementation for a Tapestry IoC service (such as PipelineBuilder or ChainBuilder).</p><h3 id="DeveloperBible-Support">Support</h3><p>An object that provides supporting operations to other objects; this is a kind of "loose aggregation".</p><h3 id="DeveloperBible-Parameters">Parameters</h3><p>A data object that holds a number of related values that would otherwise be separate parameter values to a method. This tends to streamline code (especially 
 when using a Filter interface) and allows the parameters to be evolved without changing the method signature.</p><h3 id="DeveloperBible-Strategy">Strategy</h3><p>An object that "plugs into" some other code, allowing certain decisions to be deferred to the Strategy. Often a Strategy is selected based on the type of some object being operated upon.</p><h3 id="DeveloperBible-Context">Context</h3><p>Captures some stateful information that may be passed around between stateless services.</p><h3 id="DeveloperBible-Constants">Constants</h3><p>A non-instantiable class that contains public static fields that are referenced in multiple places.</p><h3 id="DeveloperBible-Hub">Hub</h3><p>An object that allows listeners to be registered. Often includes a method prefixed with "trigger" that will send notifications to listeners.</p><h2 id="DeveloperBible-ImplementtoString()">Implement <code>toString()</code></h2><p>Objects that are exposed to user code should generally implement a meaningful toStri
 ng() method. And that method should be tested.</p><h2 id="DeveloperBible-Subclassing">Subclassing</h2><p>You'll notice there isn't a lot of inheritance in Tapestry. Given the function of the IoC container, it is much more common to use some variation of <em>aggregation</em> rather than <em>inheritance</em>.</p><p>Where subclassing exists, the guideline for constructor parameters is: the subclass should include all the constructor parameters of the superclass, in the same positions. Thus subclass constructor parameters are appended to the list of super-class constructor parameters.</p></div>
 </div>
 

Modified: websites/production/tapestry/content/development-dashboard.html
==============================================================================
--- websites/production/tapestry/content/development-dashboard.html (original)
+++ websites/production/tapestry/content/development-dashboard.html Sun Jul 19 21:21:27 2015
@@ -57,7 +57,7 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><h1 id="DevelopmentDashboard-DevelopmentDashboard">Development&#160;Dashboard</h1><p>Tapestry has a built-in Dashboard that is typically only available to requests from localhost (the page is whitelist access only, see <a shape="rect" href="security.html">Security</a>).</p><p><span style="line-height: 1.4285715;">The dashboard provides developer features that can help identify and resolve problems in the application.&#160;</span><span style="line-height: 1.4285715;">Some features of the dashboard are only available in development mode.</span></p><p>The dashboard is available via the URI "core/t5dashboard", or can be accessed by the <a shape="rect" class="external-link" href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/DevTool.html">DevTool</a> component's dropdown menu.</p><p><span style="line-height: 1.4285715;">&#160;</span></p><p><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-ma
 nual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard_-_pages.png" data-image-src="/confluence/download/attachments/22872137/Tapestry_5_Dashboard_-_pages.png?version=1&amp;modificationDate=1428090444000&amp;api=v2" data-unresolved-comment-count="0" data-linked-resource-id="55476329" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Tapestry_5_Dashboard_-_pages.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="22872137" data-linked-resource-container-version="7"></span></p><p>By default, there are three tabs (this is extensible).</p><h2 id="DevelopmentDashboard-Pages">Pages</h2><p>The pages tab shows what pages are currently loaded into the application. Tapestry only loads a page when it is first needed.</p><p>It is possible to clear ou
 t Tapestry's caches, forcing a reload. You can also run a garbage collection (GC).</p><p>It is possible to load any individual page, or attempt to load all pages. This can be a good way to see if all pages (and templates) are error free ... loading all will catch quite a few potential errors.</p><h2 id="DevelopmentDashboard-Services">Services</h2><p>When using Tapestry there will often be a large number of services defined in the registry; a mix of the built-in services provided by the framework and your own.</p><p>Services are usually only instantiated once they are needed.</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard.png" data-image-src="/confluence/download/attachments/22872137/Tapestry_5_Dashboard.png?version=2&amp;modificationDate=1428090010000&amp;api=v2" data-unresolved
 -comment-count="0" data-linked-resource-id="55476327" data-linked-resource-version="2" data-linked-resource-type="attachment" data-linked-resource-default-alias="Tapestry_5_Dashboard.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="22872137" data-linked-resource-container-version="7"></span></p><p>Services may be builtin, defined, virtual or real.</p><p><strong>Builtin</strong> only applies to a few special services that are part of Tapestry IoC.</p><p><strong>Defined</strong> services are defined in some module, but have not yet been referenced in any way.</p><p><strong>Virtual</strong> services have been referenced and have gotten as far as creating a service proxy.</p><p><strong>Real</strong> services have had methods invoked, this forces the <em>realization</em> of the service which includes instantiating the service, injecting dependencies, and decorating with any applicable interceptors.</
 p><h2 id="DevelopmentDashboard-ComponentLibraries">Component Libraries</h2><p><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard_-_libs.png" data-image-src="/confluence/download/attachments/22872137/Tapestry_5_Dashboard_-_libs.png?version=1&amp;modificationDate=1428090505000&amp;api=v2" data-unresolved-comment-count="0" data-linked-resource-id="55476330" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Tapestry_5_Dashboard_-_libs.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="22872137" data-linked-resource-container-version="7"></span></p><p>This page gives a summary of all component libraries used in the current application.</p></div>
+<div id="ConfluenceContent"><h1 id="DevelopmentDashboard-DevelopmentDashboard">Development&#160;Dashboard</h1><p>Tapestry has a built-in Dashboard that is typically only available to requests from localhost (the page is whitelist access only, see <a shape="rect" href="security.html">Security</a>).</p><p><span style="line-height: 1.4285715;">The dashboard provides developer features that can help identify and resolve problems in the application.&#160;</span><span style="line-height: 1.4285715;">Some features of the dashboard are only available in development mode.</span></p><p>The dashboard is available via the URI "core/t5dashboard", or can be accessed by the <a shape="rect" class="external-link" href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/DevTool.html">DevTool</a> component's dropdown menu.</p><p><span style="line-height: 1.4285715;">&#160;</span></p><p><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-ma
 nual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard_-_pages.png"></span></p><p>By default, there are three tabs (this is extensible).</p><h2 id="DevelopmentDashboard-Pages">Pages</h2><p>The pages tab shows what pages are currently loaded into the application. Tapestry only loads a page when it is first needed.</p><p>It is possible to clear out Tapestry's caches, forcing a reload. You can also run a garbage collection (GC).</p><p>It is possible to load any individual page, or attempt to load all pages. This can be a good way to see if all pages (and templates) are error free ... loading all will catch quite a few potential errors.</p><h2 id="DevelopmentDashboard-Services">Services</h2><p>When using Tapestry there will often be a large number of services defined in the registry; a mix of the built-in services provided by the framework and your own.</p><p>Services are usually onl
 y instantiated once they are needed.</p><p><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard.png"></span></p><p>Services may be builtin, defined, virtual or real.</p><p><strong>Builtin</strong> only applies to a few special services that are part of Tapestry IoC.</p><p><strong>Defined</strong> services are defined in some module, but have not yet been referenced in any way.</p><p><strong>Virtual</strong> services have been referenced and have gotten as far as creating a service proxy.</p><p><strong>Real</strong> services have had methods invoked, this forces the <em>realization</em> of the service which includes instantiating the service, injecting dependencies, and decorating with any applicable interceptors.</p><h2 id="DevelopmentDashboard-ComponentLibraries">Component Libraries</h2><p
 ><span class="confluence-embedded-file-wrapper image-center-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-content-image-border image-center" width="500" src="development-dashboard.data/Tapestry_5_Dashboard_-_libs.png"></span></p><p>This page gives a summary of all component libraries used in the current application.</p></div>
 </div>
 
 <div class="clearer"></div>