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 2021/04/21 16:20:52 UTC

svn commit: r1074045 - in /websites/production/tapestry/content: cache/main.pageCache type-coercion.html

Author: buildbot
Date: Wed Apr 21 16:20:52 2021
New Revision: 1074045

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/type-coercion.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/tapestry/content/type-coercion.html
==============================================================================
--- websites/production/tapestry/content/type-coercion.html (original)
+++ websites/production/tapestry/content/type-coercion.html Wed Apr 21 16:20:52 2021
@@ -142,7 +142,7 @@
             
             <!-- /// Content Start -->
             <div id="content">
-                            <div id="ConfluenceContent"><p><strong>Type Coercion</strong> is the conversion of one type of object to a new object of a different type with similar content. Tapestry frequently must coerce objects from one type to another. A common example is the coercion of string "5" into an integer 5 or a double 5.0.</p><div class="aui-label" style="float:right" title="Related Articles">
+                            <div id="ConfluenceContent"><p><strong>Type Coercion</strong> is the conversion of one type of object to a another object of a different type with similar content. Tapestry frequently must coerce objects from one type to another. A common example is the coercion of string "5" into an integer 5 or a double 5.0.</p><div class="aui-label" style="float:right" title="Related Articles">
 
 
 
@@ -177,8 +177,9 @@
 </div>
 
 
-<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="https://tapestry.apache.org/current/apidocs/org/apache/tapestry5/commons/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/commons/services/CoercionTuple.html">CoercionTuples</a>&#160;until 5.6.x and a mapped configuration of (CoercionTupe.Key, CoercionTule) from Tapestry 5.7.0 on. Each tuple defines how to coerce from one type to another. The initial set of coercions is focused prima
 rily on coercions between different numeric types:</p><p></p><p><span class="confluence-embedded-file-wrapper"><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>I
 nteger</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><code class="language-java">Double --&gt; Float
+<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 occur 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="https://tapestry.apache.org/current/apidocs/org/apache/tapestry5/commons/services/TypeCoercer.html">TypeCoercer</a> service. Its configuration consists of&#160;<a class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/commons/services/CoercionTuple.html">CoercionTuples</a>&#160;until 5.6.x and a mapped configuration of (CoercionTuple.Key, CoercionTuple) from Tapestry 5.7.0 on. Each tuple defines how to coerce from one type to another. The initial set of coercions is focused primarily o
 n coercions between different numeric types:</p><p></p><p><span class="confluence-embedded-file-wrapper"><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><h2 id="TypeCoercion-TypeCoercerInterpolation">Type Coercer Interpolation</h2><p>Tapestry will try to&#160;<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><p>Because <code>Object --&gt;&#160;String</code> is always available, this might lead to an unexpected interpolation between incompatible types due to multiple intermediate coercions. This can be easily prevented by providing an explicit CoercionTuple between the desired types.</p><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 version 5.7, the following coercions are available:</p><div class="code panel pdl" 
 style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre><code class="language-java">// Since Tapestry 5.1/5.2
+Double --&gt; Float
 Float --&gt; Double
 Long --&gt; Boolean
 Long --&gt; Byte
@@ -231,7 +232,62 @@ org.apache.tapestry5.Renderable --&gt; o
 org.apache.tapestry5.ioc.util.TimeInterval --&gt; Long
 org.apache.tapestry5.runtime.ComponentResourcesAware --&gt; org.apache.tapestry5.ComponentResources
 short[] --&gt; java.util.List
-</code></pre>
+
+
+// Since Tapestry 5.6.2
+
+java.time.Year --&gt; Integer
+Integer        --&gt; java.time.Year
+
+java.time.Month --&gt; Integer
+Integer         --&gt; java.time.Month
+String          --&gt; java.time.Month
+
+java.time.YearMonth --&gt; java.time.Year
+java.time.YearMonth --&gt; java.time.Month
+String              --&gt; java.time.YearMonth
+
+java.time.MonthDay --&gt; java.time.Month
+String             --&gt; java.time.MonthDay
+
+java.time.DayOfWeek --&gt; Integer
+Integer             --&gt; java.time.DayOfWeek
+String              --&gt; java.time.DayOfWeek
+
+java.time.LocalDate --&gt; java.time.Instant
+java.time.Instant   --&gt; java.time.LocalDate
+String              --&gt; java.time.LocalDate
+java.time.LocalDate --&gt; java.time.YearMonth
+java.time.LocalDate --&gt; java.time.MonthDay
+
+java.time.LocalTime --&gt; Long
+Long                --&gt; java.time.LocalTime
+String              --&gt; java.time.LocalTime
+
+java.time.LocalDateTime --&gt; java.time.Instant
+java.time.Instant       --&gt; java.time.LocalDateTime
+String                  --&gt; java.time.LocalDateTime
+java.time.LocalDateTime --&gt; jva.time.LocalDate
+
+java.time.OffsetDateTime --&gt; java.time.Instant
+java.time.OffsetDateTime --&gt; java.time.OffsetTime
+String                   --&gt; java.time.OffsetDateTime
+
+String --&gt; java.time.ZoneId
+
+java.time.ZonedDateTime --&gt; java.time.Instant
+java.time.ZonedDateTime --&gt; java.time.ZoneId
+String                  --&gt; java.time.ZonedDateTime
+
+java.time.Instant --&gt; Long
+Long              --&gt; java.time.Instant
+java.time.Instant --&gt; java.util.Date.class
+java.util.Date    --&gt; java.time.Instant
+
+java.time.Duration --&gt; Long
+Long               --&gt; java.time.Duration
+
+String --&gt; java.time.Period</code></pre>
 </div></div><h2 id="TypeCoercion-ContributingNewCoercions">Contributing New Coercions</h2><p>TypeCoercer is extensible; you may add new coercions as desired. For example, let's say you have a <code>Money</code> type that represents an amount of some currency, and you want to be able to convert from <code>BigDecimal</code> to <code>Money</code>. Further, let's assume that <code>Money</code> has a constructor that accepts a <code>BigDecimal</code> as its parameter. We'll use a little Tapestry IOC configuration jujitsu to inform the TypeCoercer about this coercion.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>AppModule (partial, Tapestry 5.7.0+)</b></div><div class="codeContent panelContent pdl">
 <pre><code class="language-java">public static void contributeTypeCoercer(MappedConfiguration&lt;CoercionTuple.Key, CoercionTuple&gt; configuration)
 {
@@ -268,7 +324,7 @@ short[] --&gt; java.util.List
         }
     }));
 </code></pre>
-</div></div><p></p><p></p><p></p></div>
+</div></div><h2 id="TypeCoercion-java.time(JSR310)TypeCoercers">java.time (JSR310) Type Coercers</h2><p>With Java 8, the Java Time API (JSR310) got added to the JDK, providing a new, more straightforward way of dealing with date and time. The multitude of different types created a need for additional TypeCoercers. But due to the way the Java Time API was implemented, you must be aware of some edge cases and intricacies.</p><h3 id="TypeCoercion-MillisecondsPrecision">Milliseconds Precision</h3><p>Even though the Java Time API partially supports nanosecond precision, it's not guaranteed. Actually, the OS / the JVM implementation is responsible for providing the current time with <code>java.time.Clock</code>. Most of the new types even don't have convenience-methods for a nanosecond-based representation.</p><p>All date(time)-based types use <code>java.time.Instant</code>&#160;for coercion, which itself is coerced with milliseconds precision. This provides compatibility with <code>java.
 util.Date#getTime()</code>, which is also milliseconds-based.</p><h3 id="TypeCoercion-NanosecondsPrecision">Nanoseconds Precision</h3><p>The 2 types not using milliseconds are not subclasses of or convertible to <code>java.time.Instant</code>:</p><ul><li><code>java.time.LocalTime</code>: Uses nanoseconds internally, and no convenience method for milliseconds exists.</li><li><code>java.time.Duration</code>: Uses nanoseconds and seconds internally. Even though a convenience method for milliseconds exists, the type isn't dependent on the OS/JVM precision. So the highest possible precision is used.</li></ul><h3 id="TypeCoercion-Timezones">Timezones</h3><p>The Java Time API supports timezone-less types, e.g. <code>java.time.LocalDate</code>, <code>java.time.LocalDateTime</code>.However, coercing these types into a `java.time.Instant` requires a timezone, because <code>java.time.Instant</code> uses the unix timestamp 0 as reference.</p><p>To still use automatic type coercion, the <em>Loca
 l</em> types will be seen as being in <code>ZoneId.systemDefault()</code>.</p><p>Additionally, <code>java.time.LocalDate</code> we use the local time of <em>00:00</em>&#160;for it's coercion to <code>java.time.Instant</code>.</p><h3 id="TypeCoercion-InvalidCoercionPaths">Invalid Coercion Paths</h3><p>Due to the powerful feature of finding compatible TypeCoercer paths to convert types with no explicit TypeCoercer, some additional TypeCoercers were added to ensure the correct conversion between types.</p><p>You should only try to coerce between the provided types and <code>java.time.Instant</code>&#160;as intermediate. Any other coercion path will require you to contribute a matching TypeCoercer yourself.</p><p></p><p></p></div>
             </div>
             <!-- /// Content End -->
           </div>