You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by bu...@apache.org on 2018/02/18 20:20:10 UTC

svn commit: r1025568 [4/4] - in /websites/production/tapestry/content: ./ cache/

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>