Modified: websites/production/tapestry/content/tapestry-ioc-decorators.html
==============================================================================
--- websites/production/tapestry/content/tapestry-ioc-decorators.html (original)
+++ websites/production/tapestry/content/tapestry-ioc-decorators.html Sun Feb 
18 20:20:09 2018
@@ -75,13 +75,13 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Starting with Tapestry 5.1, 
Service Decoration is augmented with <a  
href="tapestry-ioc-decorators.html">Service Advice</a>. Advisors are similar 
but more general, as they work on any service interface, which doesn't have to 
be known at build time. Decoration is used when the type of the service being 
decorated <em>is</em> known at build time, and involves supplying a new 
implementation of the service interface.</p></div></div><p><em>Decoration</em> 
is the name of a popular design pattern. Using decoration, an existing object's 
behavior can be extended without changing the implementation of the 
object.</p><p>Instead, a new object is placed <em>around</em> the existing 
object. The rest of the world sees this new ob
 ject, termed an <strong>interceptor</strong>. The interceptor implements the 
same interface as the underlying object being decorated.</p><p>A common example 
for this is the Java I/O library. The abstract InputStream base class has a 
very simple API for reading bytes from a stream (and a few other things). 
Subclasses of InputStream provide a wide array of other options such as 
buffering, encryption or decryption, as well as control over the source of data 
read by the stream. All of these <em>concerns</em> are encapsulated in 
different implementations of InputStream, and all can be connected together in 
a kind of pipeline, using the common InputStream API.</p><p>Tapestry IoC uses a 
similar approach, where one or more interceptor objects, all implementing the 
service interface, are strung together. The service's proxy (responsible for 
just-in-time instantiation of the service implementation) is at one end of this 
pipeline, the core service implementation is at the other.</p><p>For each
  method in the service interface, the interceptor object can perform some 
operations before and after re-invoking the same method on the core service 
implementation. This is another design pattern: <em>delegation</em>. An 
interceptor can even catch exceptions thrown by the underlying implementation 
and react to them. A sufficiently clever interceptor could retry a method if an 
exception is thrown, or could "soften" a checked exception by wrapping it in a 
RuntimeException.</p><p>Decorators often are used in the context of 
<em>cross-cutting concerns</em>, such as logging or transaction management. 
This approach is a kind of <em>aspect oriented design</em>.</p><p>One such 
cross cutting concern is lazy initialization of services. In Apache HiveMind, 
services are created only as needed, when a method of a service interface is 
first invoked. This concern is supplied by the Tapestry IoC framework itself, 
but similar concerns are easily implemented as decorations.</p><p>Whereas the 
popular 
 AspectJ framework changes the compiled bytecode of your classes (it calls the 
process "weaving"), with Tapestry IoC, the approach is to wrap your existing 
classes in new objects. These wrapper objects are often dynamically created at 
runtime.</p><p>It is also common to have <em>multiple</em> decorations on a 
single service. In this case, a whole stack of interceptor objects will be 
created, each delegating to the next. Tapestry IoC provides control over the 
order in which such decorations occur.</p><p>Decorations are driven by service 
decoration methods. Often, a reusable service exists to do the grunt work of 
creating and instantiating a new class.</p><h1 
id="TapestryIoCDecorators-ServiceDecorationMethods">Service Decoration 
Methods</h1><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+                <div id="ConfluenceContent"><p>&#160;</p><p></p><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Starting with Tapestry 5.1, 
Service Decoration is augmented with <a  href="service-advisors.html">Service 
Advice</a>. Advisors are similar but more general, as they work on any service 
interface, which doesn't have to be known at build time. Decoration is used 
when the type of the service being decorated <em>is</em> known at build time, 
and involves supplying a new implementation of the service 
interface.</p></div></div><p><em>Decoration</em> is the name of a popular 
design pattern. Using decoration, an existing object's behavior can be extended 
without changing the implementation of the object.</p><p>Instead, a new object 
is placed <em>around</em> the existing object. The rest of the world see
 s this new object, termed an <strong>interceptor</strong>. The interceptor 
implements the same interface as the underlying object being decorated.</p><p>A 
common example for this is the Java I/O library. The abstract InputStream base 
class has a very simple API for reading bytes from a stream (and a few other 
things). Subclasses of InputStream provide a wide array of other options such 
as buffering, encryption or decryption, as well as control over the source of 
data read by the stream. All of these <em>concerns</em> are encapsulated in 
different implementations of InputStream, and all can be connected together in 
a kind of pipeline, using the common InputStream API.</p><p>Tapestry IoC uses a 
similar approach, where one or more interceptor objects, all implementing the 
service interface, are strung together. The service's proxy (responsible for 
just-in-time instantiation of the service implementation) is at one end of this 
pipeline, the core service implementation is at the other.</
 p><p>For each method in the service interface, the interceptor object can 
perform some operations before and after re-invoking the same method on the 
core service implementation. This is another design pattern: 
<em>delegation</em>. An interceptor can even catch exceptions thrown by the 
underlying implementation and react to them. A sufficiently clever interceptor 
could retry a method if an exception is thrown, or could "soften" a checked 
exception by wrapping it in a RuntimeException.</p><p>Decorators often are used 
in the context of <em>cross-cutting concerns</em>, such as logging or 
transaction management. This approach is a kind of <em>aspect oriented 
design</em>.</p><p>One such cross cutting concern is lazy initialization of 
services. In Apache HiveMind, services are created only as needed, when a 
method of a service interface is first invoked. This concern is supplied by the 
Tapestry IoC framework itself, but similar concerns are easily implemented as 
decorations.</p><p>Whereas
  the popular AspectJ framework changes the compiled bytecode of your classes 
(it calls the process "weaving"), with Tapestry IoC, the approach is to wrap 
your existing classes in new objects. These wrapper objects are often 
dynamically created at runtime.</p><p>It is also common to have 
<em>multiple</em> decorations on a single service. In this case, a whole stack 
of interceptor objects will be created, each delegating to the next. Tapestry 
IoC provides control over the order in which such decorations 
occur.</p><p>Decorations are driven by service decoration methods. Often, a 
reusable service exists to do the grunt work of creating and instantiating a 
new class.</p><h1 id="TapestryIoCDecorators-ServiceDecorationMethods">Service 
Decoration Methods</h1><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;">package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.services.LoggingDecorator;
 import org.slf4j.Logger;
 
-public class MyAppModule
+public class AppModule
 {
   public static Indexer build()
   {
@@ -101,13 +101,13 @@ public class MyAppModule
   {
     return decorator.build(Indexer.class, delegate, "Indexer", logger);
   }</pre>
-</div></div><p>Of course, nothing stops you from combining building with 
decorating inside the service builder method:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Of course, nothing stops you from combining building with 
decorating inside the service builder method:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>AppModule (partial)</b></div><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.services.LoggingDecorator;
 import org.slf4j.Logger;
 
-public class MyAppModule
+public class AppModule
 {
   public static Indexer build(Logger logger, LoggingDecorator decorator)
   {
@@ -122,7 +122,7 @@ public class MyAppModule
   {
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }   </pre>
-</div></div><p>You can use multiple patterns with @Match, in which case, the 
decorator will be applied to a service that matches <em>any</em> of the 
patterns. For instance, if you only wanted logging for your data access and 
business logic services, you might end up with <code>@Match("Data*", 
"*Logic")</code> (based, of course, on how you name your services).</p><p>As 
the preceding example showed, a simple "glob" matching is supported, where a 
asterisk ('*') may be used at the start or end of the match string to match any 
number of characters. As elsewhere, matching is case insensitive.</p><p>Thus, 
<code>@Match("*")</code> is dangerous, because it will match every service in 
every module.</p><p><em>Note: It is not possible to decorate the services of 
the TapestryIOCModule.</em></p><p><em>Note: Another idea will be other ways of 
matching services: base on inheritance of the service interface and/or based on 
the presence of particular class annotations on the service interface. None o
 f this has been implemented yet, and can readily be accomplished inside the 
decorator method (which will return null if it decides the service doesn't need 
decoration).</em></p><h1 
id="TapestryIoCDecorators-OrderingofDecorators">Ordering of 
Decorators</h1><p>In cases where multiple decorators will apply to a single 
service, you can control the order in which decorators are applied using an 
additional annotation: @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Order.html";>Order</a>.</p><p>This
 annotation allows any number of <a  
href="tapestry-ioc-decorators.html">ordering constraints</a> to be specified 
for the decorator, to order it relative to any other decorators.</p><p>For 
example, you almost always want logging decorators to come first, so:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+</div></div><p>You can use multiple patterns with @Match, in which case, the 
decorator will be applied to a service that matches <em>any</em> of the 
patterns. For instance, if you only wanted logging for your data access and 
business logic services, you might end up with <code>@Match("Data*", 
"*Logic")</code> (based, of course, on how you name your services).</p><p>As 
the preceding example showed, a simple "glob" matching is supported, where a 
asterisk ('*') may be used at the start or end of the match string to match any 
number of characters. As elsewhere, matching is case insensitive.</p><p>Thus, 
<code>@Match("*")</code> is dangerous, because it will match every service in 
every module.</p><p><em>Note: It is not possible to decorate the services of 
the TapestryIOCModule.</em></p><p><em>Note: Another idea will be other ways of 
matching services: base on inheritance of the service interface and/or based on 
the presence of particular class annotations on the service interface. None o
 f this has been implemented yet, and can readily be accomplished inside the 
decorator method (which will return null if it decides the service doesn't need 
decoration).</em></p><h1 
id="TapestryIoCDecorators-OrderingofDecorators">Ordering of 
Decorators</h1><p>In cases where multiple decorators will apply to a single 
service, you can control the order in which decorators are applied using an 
additional annotation: @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Order.html";>Order</a>.</p><p>This
 annotation allows any number of <a  
href="ordering-by-constraints.html">ordering constraints</a> to be specified 
for the decorator, to order it relative to any other decorators.</p><p>For 
example, you almost always want logging decorators to come first, so:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Match("*")
   @Order("before:*")
   public static &lt;T&gt; T decorateLogging(Class&lt;T&gt; serviceInterface, T 
delegate,
@@ -177,7 +177,7 @@ Added in 5.2
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }
 </pre>
-</div></div><p>The decorator above is applied to any implementation of the 
MyService interface that is marked by the @Blue annotation.</p><h1 
id="TapestryIoCDecorators-CreatingyourownDecorators">Creating your own 
Decorators</h1><p>Decorators are a limited form of Aspect Oriented Programming, 
so we have borrowed some of that terminology here.</p><p>A decorator exists to 
create an <em>interceptor</em>. The interceptor wraps around the service 
(because these interceptors can get chained, we talk about the "delegate" and 
not the "service").</p><p>Each method of the interceptor will take 
<em>advice</em>. Advice is provided by a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/MethodAdvice.html";>MethodAdvice</a>
 instance. The sole method, <code>advise()</code>, receives an <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Invocation.html";>Invocation</a>.
 MethodAdvice gives you a chance to 
 see what the method invocation <em>is</em>; you can query the name of the 
method, and the types and values of the parameters.</p><p>The MethodAdvice can 
override the parameters if necessary, then invoke <code>proceed()</code>. This 
call invokes the corresponding method on the original object, the 
delegate.</p><p>If the method call throws a runtime exception, that exception 
is not caught. Your method advice can put a try ... catch block around the call 
to proceed() if interested in catching runtime exceptions.</p><p>Checked 
exceptions are not thrown (since they are not part of the proceed() method's 
signature). Instead the invocation's <code>isFail()</code> method will return 
true. You can then retrieve the exception or override it.</p><p>In the normal 
success case, you can ask for the return value and even override it before 
returning from the advise() method.</p><p>In other words, you have total 
control. Your MethodAdvice can query or change parameters, decide whether it 
proceed in
 to the original code, it can intercept exceptions that are thrown and replace 
them, and can query or even replace the return value.</p><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/AspectDecorator.html";>AspectDecorator</a>
 service is how you put your MethodAdvice into action.</p><p>By way of an 
example, we'll show an implementation of the LoggingDecorator service:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+</div></div><p>The decorator above is applied to any implementation of the 
MyService interface that is marked by the @Blue annotation.</p><h1 
id="TapestryIoCDecorators-CreatingyourownDecorators">Creating your own 
Decorators</h1><p>Decorators are a limited form of Aspect Oriented Programming, 
so we have borrowed some of that terminology here.</p><p>A decorator exists to 
create an <em>interceptor</em>. The interceptor wraps around the service 
(because these interceptors can get chained, we talk about the "delegate" and 
not the "service").</p><p>Each method of the interceptor will take 
<em>advice</em>. Advice is provided by a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/MethodAdvice.html";>MethodAdvice</a>
 instance. The sole method, <code>advise()</code>, receives an <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Invocation.html";>Invocation</a>.
 MethodAdvice gives you a chance to 
 see what the method invocation <em>is</em>; you can query the name of the 
method, and the types and values of the parameters.</p><p>The MethodAdvice can 
override the parameters if necessary, then invoke <code>proceed()</code>. This 
call invokes the corresponding method on the original object, the 
delegate.</p><p>If the method call throws a runtime exception, that exception 
is not caught. Your method advice can put a try ... catch block around the call 
to proceed() if interested in catching runtime exceptions.</p><p>Checked 
exceptions are not thrown (since they are not part of the proceed() method's 
signature). Instead the invocation's <code>isFail()</code> method will return 
true. You can then retrieve the exception or override it.</p><p>In the normal 
success case, you can ask for the return value and even override it before 
returning from the advise() method.</p><p>In other words, you have total 
control. Your MethodAdvice can query or change parameters, decide whether it 
proceed in
 to the original code, it can intercept exceptions that are thrown and replace 
them, and can query or even replace the return value.</p><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/AspectDecorator.html";>AspectDecorator</a>
 service is how you put your MethodAdvice into action.</p><p>By way of an 
example, we'll show an implementation of the LoggingDecorator service:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>LoggingDecoratorImpl.java</b></div><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class LoggingDecoratorImpl implements 
LoggingDecorator
 {
     private final AspectDecorator aspectDecorator;

Modified: websites/production/tapestry/content/type-coercion.html
==============================================================================
--- websites/production/tapestry/content/type-coercion.html (original)
+++ websites/production/tapestry/content/type-coercion.html Sun Feb 18 20:20:09 
2018
@@ -108,7 +108,7 @@
 </div>
 
 
-<p>Although type coercions happen more inside tapestry-core (including <a  
href="type-coercion.html">coercions of <span class="confluence-link">component 
parameters</span></a><span class="confluence-link">&#160;</span>), they may 
also happen inside tapestry-ioc, such as when injecting a value, rather than a 
service, into a builder method.</p><p>Like everything else in Tapestry, type 
coercions are extensible. At the root is the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TypeCoercer.html";>TypeCoercer</a>
 service. Its configuration consists of a number of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/CoercionTuple.html";>CoercionTuples</a>.
 Each tuple defines how to coerce from one type to another. The initial set of 
coercions is focused primarily on coercions between different numeric 
types:</p><p>&#160;</p><p><span class="confluence-embedded-file-wrapper"><i
 mg class="confluence-embedded-image" 
src="type-coercion.data/type-coercer.png"></span></p><h2 
id="TypeCoercion-DefaultTypeCoercions">Default Type Coercions</h2><p>There are 
a few special coercions related to <code>null</code> there; <code>Object</code> 
--&gt; <code>List</code> wraps a lone object as a singleton list, we then need 
<code>null</code> --&gt; <code>List</code> to ensure that <code>null</code> 
stays <code>null</code> (rather than a singleton list whose lone element is a 
<code>null</code>).</p><p>Tapestry can <em>interpolate</em> necessary 
coercions. For example, say it is necessary to coerce a 
<code>StringBuffer</code> to an <code>Integer</code>; the TypeCoercer service 
will chain together a series of coercions:</p><ul><li><code>Object</code> 
--&gt; <code>String</code></li><li><code>String</code> --&gt; 
<code>Long</code></li><li><code>Long</code> --&gt; 
<code>Integer</code></li></ul><h2 id="TypeCoercion-Coercingfromnull">Coercing 
from null</h2><p>Coercing from <code>null<
 /code> is special; it is not a spanning search as with the other types. Either 
there is a specific coercion from <code>null</code> to the desired type, or no 
coercion takes places (and the coerced value is <code>null</code>).</p><p>The 
only built-in <code>null</code> coercion is from <code>null</code> to 
<code>boolean</code> (which is always false).</p><h2 
id="TypeCoercion-ListofCoercions">List of Coercions</h2><p>As of Tapestry 
versions 5.1 and 5.2, the following coercions are available:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<p>Although type coercions happen more inside tapestry-core (including <a  
href="parameter-type-coercion.html">coercions of <span 
class="confluence-link">component parameters</span></a><span 
class="confluence-link">&#160;</span>), they may also happen inside 
tapestry-ioc, such as when injecting a value, rather than a service, into a 
builder method.</p><p>Like everything else in Tapestry, type coercions are 
extensible. At the root is the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TypeCoercer.html";>TypeCoercer</a>
 service. Its configuration consists of a number of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/CoercionTuple.html";>CoercionTuples</a>.
 Each tuple defines how to coerce from one type to another. The initial set of 
coercions is focused primarily on coercions between different numeric 
types:</p><p>&#160;</p><p><span class="confluence-embedded-file-w
 rapper"><img class="confluence-embedded-image" 
src="type-coercion.data/type-coercer.png"></span></p><h2 
id="TypeCoercion-DefaultTypeCoercions">Default Type Coercions</h2><p>There are 
a few special coercions related to <code>null</code> there; <code>Object</code> 
--&gt; <code>List</code> wraps a lone object as a singleton list, we then need 
<code>null</code> --&gt; <code>List</code> to ensure that <code>null</code> 
stays <code>null</code> (rather than a singleton list whose lone element is a 
<code>null</code>).</p><p>Tapestry can <em>interpolate</em> necessary 
coercions. For example, say it is necessary to coerce a 
<code>StringBuffer</code> to an <code>Integer</code>; the TypeCoercer service 
will chain together a series of coercions:</p><ul><li><code>Object</code> 
--&gt; <code>String</code></li><li><code>String</code> --&gt; 
<code>Long</code></li><li><code>Long</code> --&gt; 
<code>Integer</code></li></ul><h2 id="TypeCoercion-Coercingfromnull">Coercing 
from null</h2><p>Coercing from <
 code>null</code> is special; it is not a spanning search as with the other 
types. Either there is a specific coercion from <code>null</code> to the 
desired type, or no coercion takes places (and the coerced value is 
<code>null</code>).</p><p>The only built-in <code>null</code> coercion is from 
<code>null</code> to <code>boolean</code> (which is always false).</p><h2 
id="TypeCoercion-ListofCoercions">List of Coercions</h2><p>As of Tapestry 
versions 5.1 and 5.2, the following coercions are available:</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;">Double --&gt; Float
 Float --&gt; Double
 Long --&gt; Boolean
@@ -186,8 +186,7 @@ short[] --&gt; java.util.List
         }
     }));
 </pre>
-</div></div><p>&#160;</p><p></p>
-() { public Boolean coerce(Void input) { return false; } })); 
]]&gt;<p>&#160;</p><p>&#160;</p></div>
+</div></div><p>&#160;</p><p></p><p>() { public Boolean coerce(Void input) { 
return false; } })); ]]&gt;</p><p>&#160;</p><p>&#160;</p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to