<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Richard Bolkey - Blog</title>
	
	<link>http://blog.bolkey.com</link>
	<description>Thoughts of a plain old java developer.</description>
	<lastBuildDate>Thu, 08 Dec 2011 00:53:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/rbolkey" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="rbolkey" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Creating a news feed in Tapestry 5</title>
		<link>http://blog.bolkey.com/2010/05/creating-a-news-feed-in-tapestry-5/</link>
		<comments>http://blog.bolkey.com/2010/05/creating-a-news-feed-in-tapestry-5/#comments</comments>
		<pubDate>Mon, 17 May 2010 22:50:47 +0000</pubDate>
		<dc:creator>rbolkey</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Mixins]]></category>
		<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.bolkey.com/?p=62</guid>
		<description><![CDATA[News feeds are frequently encountered in today&#8217;s web interfaces. Using Ajax, news and social feeds are continually monitored with new items being retrieved for display. In Apache Tapestry 5, the lingua-franca of performing these types of Ajax updates is the Zone component. The Zone component marks (or contains) a region of your Tapestry template that [...]]]></description>
			<content:encoded><![CDATA[<p>News feeds are frequently encountered in today&#8217;s web interfaces.  Using Ajax, news and social feeds are continually monitored with new items being retrieved for display.  In Apache Tapestry 5, the lingua-franca of performing these types of Ajax updates is the Zone component.  The Zone component marks (or contains) a region of your Tapestry template that you wish to replace on an Ajax event; however, with news feeds you typically want to add new markup to a page without replacing the existing markup.</p>
<p>Currently, Tapestry does not behave this way. But with the ease of a custom mixin (a way Tapestry can add or alter the behavior of a component), we can easily change a Zone to insert the new markup.  And with the addition of another simple mixin, we can continue to poll for new markup to insert!</p>
<p>This tutorial requires previous knowledge of <a href="http://tapestry.apache.org/tapestry5.1/guide/mixins.html">mixins</a> and <a href="http://tapestry.apache.org/tapestry5.1/guide/ajax.html">ajax</a> in Tapestry, as well as some familiarity with <a href="http://www.prototypejs.org/">Prototype</a>, a JavaScript framework used by Tapestry.</p>
<h2>Inserting markup instead of replacing</h2>
<p>First, we will alter the behavior of a zone to insert instead of replace markup.  This does not require much code.  All you need is to add a mixin to the zone component that alters the baked in Tapestry behavior.  In this example, we will call this mixin the ZoneInserter.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Modifies how a the content of a Tapestry Zone is updated.  Allows content to 
 * be inserted instead of just updating an element.
 */</span>
@IncludeJavaScriptLibrary<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ZoneInserter.js&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ZoneInserter <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Accepted insertion points are:
     * &lt;ul&gt;
     * &lt;li&gt;before (as element's previous sibling)&lt;/li&gt;
     * &lt;li&gt;after (as element's next sibling)&lt;/li&gt;
     * &lt;li&gt;top (as element's first child)&lt;/li&gt;
     * &lt;li&gt;bottom (as element's last child) [&lt;b&gt;default&lt;/b&gt;]&lt;/li&gt;
     * &lt;/ul&gt;
     */</span>
    @Parameter<span style="color: #009900;">&#40;</span>defaultPrefix <span style="color: #339933;">=</span> BindingConstants.<span style="color: #006633;">LITERAL</span>, value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;bottom&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> insertion<span style="color: #339933;">;</span>
&nbsp;
    @InjectContainer
    <span style="color: #000000; font-weight: bold;">private</span> Zone zone<span style="color: #339933;">;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> ComponentResources resources<span style="color: #339933;">;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> RenderSupport renderSupport<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> afterRender<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> id <span style="color: #339933;">=</span> zone.<span style="color: #006633;">getClientId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> JSONObject config <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JSONObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>resources.<span style="color: #006633;">isBound</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;insertion&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> config.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;insertion&quot;</span>, insertion<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        renderSupport.<span style="color: #006633;">addInit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;zoneInserter&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> JSONArray<span style="color: #009900;">&#40;</span>id, config<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This is a very simple mixin that passes the client id of the zone and a single configuration parameter (&#8220;insertion&#8221;) to a JavaScript initialization script.  The mixin needs to run after the zone renders so that the zones client id is known.<span id="more-62"></span> The necessary JavaScript included by the mixin is a little more interesting:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Tapestry.<span style="color: #660066;">Initializer</span>.<span style="color: #660066;">zoneInserter</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>zoneId<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Need to access the zone after the zone manager is configured during Tapestry.onDomLoaded</span>
    Event.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;load&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> zoneObject <span style="color: #339933;">=</span> Tapestry.<span style="color: #660066;">findZoneManagerForZone</span><span style="color: #009900;">&#40;</span>zoneId<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>zoneObject<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
&nbsp;
        zoneObject.<span style="color: #660066;">show</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> key <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>options.<span style="color: #660066;">insertion</span> <span style="color: #339933;">||</span> <span style="color: #3366CC;">'bottom'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> insertion <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Hash<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            insertion.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span> content<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">updateElement</span>.<span style="color: #660066;">insert</span><span style="color: #009900;">&#40;</span>insertion.<span style="color: #660066;">toJSON</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">evalJSON</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #003366; font-weight: bold;">var</span> func <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">visible</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">updateFunc</span> <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">showFunc</span><span style="color: #339933;">;</span>
&nbsp;
            func.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">fire</span><span style="color: #009900;">&#40;</span>Tapestry.<span style="color: #660066;">ZONE_UPDATED_EVENT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As we have said, by default Tapestry replaces the content of a zone with new markup.  This script alters that default behavior of a given zone.  The key is in changing the default <code>show</code> method of the zone object in JavaScript.  Tapestry&#8217;s default <code>show</code> method uses Prototype&#8217;s <code>update</code> method on the zone&#8217;s update element, and instead, we want to use the <code>insert</code> method here to insert content around that element (before, after, at the top of, or at the bottom of).</p>
<p>Now that we can insert new markup before a zone element instead of always replacing the element&#8217;s contents, we can turn to another mixin that will poll for new markup to insert!</p>
<h2>Polling for new markup to insert</h2>
<p>Here, we want to trigger a Tapestry event on a periodic interval in order to fetch new markup for our page.  Again, we turn to mixins to solve this problem.  We will call this mixin &#8220;PeriodicUpdate&#8221;.  It&#8217;s still not a lot of code, but requires a few more lines to get working than the ZoneInserter .</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Enables a zone to be periodically refreshed with the response from the given event.
 */</span>
@IncludeJavaScriptLibrary<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PeriodicUpdate.js&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PeriodicUpdate <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * The name of the event to call to update the zone.
     */</span>
    @Parameter<span style="color: #009900;">&#40;</span>required <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span>, defaultPrefix <span style="color: #339933;">=</span> BindingConstants.<span style="color: #006633;">LITERAL</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> event<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * The context for the triggered event. The clientId of the containing zone is always 
     * added as the final context item.
     */</span>
    @Parameter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;defaultContext&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> context<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * How long, in seconds, to wait between the end of one request and the beginning of the next.
     */</span>
    @Parameter<span style="color: #009900;">&#40;</span>defaultPrefix <span style="color: #339933;">=</span> BindingConstants.<span style="color: #006633;">LITERAL</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> period<span style="color: #339933;">;</span>
&nbsp;
    @InjectContainer
    <span style="color: #000000; font-weight: bold;">private</span> Zone zone<span style="color: #339933;">;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> ComponentResources resources<span style="color: #339933;">;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> RenderSupport renderSupport<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getDefaultContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> afterRender<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> id <span style="color: #339933;">=</span> zone.<span style="color: #006633;">getClientId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> List<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span> context <span style="color: #339933;">=</span> Lists.<span style="color: #006633;">newArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Arrays</span>.<span style="color: #006633;">asList</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">context</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        context.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>zone.<span style="color: #006633;">getClientId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> Link link <span style="color: #339933;">=</span> resources.<span style="color: #006633;">createEventLink</span><span style="color: #009900;">&#40;</span>event, context.<span style="color: #006633;">toArray</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span>context.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">final</span> JSONObject config <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JSONObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>resources.<span style="color: #006633;">isBound</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;period&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> config.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;period&quot;</span>, period<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Let subclasses do more.</span>
        configure<span style="color: #009900;">&#40;</span>config<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        renderSupport.<span style="color: #006633;">addInit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;periodicupdater&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> JSONArray<span style="color: #009900;">&#40;</span>id, link.<span style="color: #006633;">toAbsoluteURI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, config<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This mixin builds a link to a Tapestry event, and passes that link along with the client ID of a zone and the period of time between calling the link as parameters to a JavaScript initialization script, which we&#8217;ll look at now.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Tapestry.<span style="color: #660066;">PeriodicUpdater</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">Class</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    initialize<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>element<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span> <span style="color: #339933;">=</span> options<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">period</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">options</span>.<span style="color: #660066;">period</span> <span style="color: #339933;">||</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span> <span style="color: #339933;">=</span> element<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">url</span> <span style="color: #339933;">=</span> url<span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    start<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onUpdate</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">updateComplete</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">timer</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onTimerEvent</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">delay</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">period</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #000066;">stop</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onUpdate</span> <span style="color: #339933;">=</span> undefined<span style="color: #339933;">;</span>
        clearTimeout<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">timer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    updateComplete<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">timer</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onTimerEvent</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">delay</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">period</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    onTimerEvent<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> zoneObject <span style="color: #339933;">=</span> Tapestry.<span style="color: #660066;">findZoneManagerForZone</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>zoneObject<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
&nbsp;
        zoneObject.<span style="color: #660066;">updateFromURL</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">onUpdate</span> <span style="color: #339933;">||</span> Prototype.<span style="color: #660066;">emptyFunction</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Tapestry.<span style="color: #660066;">Initializer</span>.<span style="color: #660066;">periodicupdater</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>elementId<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    $T<span style="color: #009900;">&#40;</span>elementId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">periodicupdater</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Tapestry.<span style="color: #660066;">PeriodicUpdater</span><span style="color: #009900;">&#40;</span>elementId<span style="color: #339933;">,</span> url<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This script creates a new Class in prototype that encapsulates the events needed to poll for updates, and adds it to the zone element.  The class provides actions to start, stop, and perform the polling (<code>timer</code>), as well as an event for when an update has run (<code>onUpdate</code>).  The polling occurs by the <code>onUpdate</code> event calling the <code>timer</code> method on a delay, after which the <code>timer</code> performs the update and triggers back to <code>onUpdate</code>.</p>
<h2>Tying things together</h2>
<p>We can tie these mixins together in a Tapestry template on one zone component like so:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:zone</span> <span style="color: #000066;">mixins</span>=<span style="color: #ff0000;">&quot;ZoneInserter, PeriodicUpdate&quot;</span> <span style="color: #000066;">insertion</span>=<span style="color: #ff0000;">&quot;top&quot;</span> <span style="color: #000066;">period</span>=<span style="color: #ff0000;">&quot;10&quot;</span> <span style="color: #000066;">event</span>=<span style="color: #ff0000;">&quot;updates&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
...</pre></div></div>

<p>This line in a Tapestry template will create a zone that will have any new markup returned by a custom <code>updates</code> event inserted at the top of the zone element every 10 seconds.  Pretty nice!</p>
<h2>Conclusion</h2>
<p>By using these two mixins on a Zone component in Tapestry, you can build a news feed.  the ZoneInserter mixin to insert new markup in a page, and the PeriodicUpdate mixin to monitor for new markup to insert.  I hope you enjoyed this example!</p>
<p><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2010%2F05%2Fcreating-a-news-feed-in-tapestry-5%2F&amp;linkname=Creating%20a%20news%20feed%20in%20Tapestry%205" title="Delicious" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_instapaper" href="http://www.addtoany.com/add_to/instapaper?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2010%2F05%2Fcreating-a-news-feed-in-tapestry-5%2F&amp;linkname=Creating%20a%20news%20feed%20in%20Tapestry%205" title="Instapaper" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/instapaper.png" width="16" height="16" alt="Instapaper"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.bolkey.com%2F2010%2F05%2Fcreating-a-news-feed-in-tapestry-5%2F&amp;title=Creating%20a%20news%20feed%20in%20Tapestry%205" id="wpa2a_2">Share/Bookmark</a></p><img src="http://feeds.feedburner.com/~r/rbolkey/~4/1oJWGGomvEo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.bolkey.com/2010/05/creating-a-news-feed-in-tapestry-5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Building a contextual recursive tree in Tapestry 5</title>
		<link>http://blog.bolkey.com/2009/06/tapestry-5-recursive-tree/</link>
		<comments>http://blog.bolkey.com/2009/06/tapestry-5-recursive-tree/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 21:09:15 +0000</pubDate>
		<dc:creator>rbolkey</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.bolkey.com/?p=29</guid>
		<description><![CDATA[UPDATE: There have been a few requests for a more complete source code example. The following link is to a demo application of the concepts from this entry, and the source code in this entry has been updated to reflect the content of the demo: Recursive Tapestry Tree Demo Application or fork from GitHub. We [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE</strong>: There have been a few requests for a more complete source code example.  The following link is to a demo application of the concepts from this entry, and the source code in this entry has been updated to reflect the content of the demo: <a href='http://blog.bolkey.com/2009/06/tapestry-5-recursive-tree/tapestry-tree/' rel='attachment wp-att-53'>Recursive Tapestry Tree Demo Application</a> or fork from <a href="http://github.com/rbolkey/tapestry5-tree">GitHub</a>.</p>
<p>We use Tapestry 5 at work.  Tapestry is a wonderful, efficient, and powerful framework, but like any piece of technology, there are headaches.  The headache we had this past week was how on earth to render a tree of of components where we have to dynamically select the component depending upon the current context within the tree.  Here&#8217;s the approach we uncovered using three components: a component acting as a container for the tree, another to render individual nodes of the tree (contextually subclassed for different nodes), and a custom delegate component (to turn off parameter caching).</p>
<h2>The Container Component</h2>
<p>The container component maintains stateful tree information while rendering the tree, and selects the component to render for the current node of the tree.</p>
<p>Here is the container&#8217;s template.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul</span> <span style="color: #000066;">xmlns:t</span>=<span style="color: #ff0000;">&quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- The custom delegate to the component to render based on the context of the current node. --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:nodedelegate</span> <span style="color: #000066;">to</span>=<span style="color: #ff0000;">&quot;currentNodeRenderer&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:block<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- This block contains a set of components to delegate rendering to based on the current node. --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">t:id</span>=<span style="color: #ff0000;">&quot;blackNode&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- Delegate to the child component to render.  This replaces the component's body. --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:nodedelegate</span> <span style="color: #000066;">to</span>=<span style="color: #ff0000;">&quot;currentNodeRenderer&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">t:id</span>=<span style="color: #ff0000;">&quot;redNode&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:nodeDelegate</span> <span style="color: #000066;">to</span>=<span style="color: #ff0000;">&quot;currentNodeRenderer&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/t:block<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><span id="more-29"></span><br />
And the container&#8217;s implementation.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Tree <span style="color: #009900;">&#123;</span>
&nbsp;
    @Parameter<span style="color: #009900;">&#40;</span>required <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> Node node<span style="color: #339933;">;</span>
&nbsp;
    @<span style="color: #003399;">Component</span><span style="color: #009900;">&#40;</span>id <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;blackNode&quot;</span>, parameters <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;node=currentNode&quot;</span>, <span style="color: #0000ff;">&quot;childPosition=currentChildPosition&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> RenderBlackNode blackNode<span style="color: #339933;">;</span>
&nbsp;
    @<span style="color: #003399;">Component</span><span style="color: #009900;">&#40;</span>id <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;redNode&quot;</span>, parameters <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;node=currentNode&quot;</span>, <span style="color: #0000ff;">&quot;childPosition=currentChildPosition&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> RenderRedNode redNode<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Node currentNode<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Map<span style="color: #339933;">&lt;</span>Node, Integer<span style="color: #339933;">&gt;</span> childPositions<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Node getCurrentNode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> currentNode<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setCurrentNode<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> Node node<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// set the initial child position for the node to 0 if it has not been seen yet.</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>childPositions.<span style="color: #006633;">containsKey</span><span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            childPositions.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>node, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">currentNode</span> <span style="color: #339933;">=</span> node<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getCurrentChildPosition<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> childPositions.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">currentNode</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setCurrentChildPosition<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> pos<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">childPositions</span>.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>currentNode, pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Selects the Node component to render based on the currentNode type.
     *
     * @return the component to render the current node
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> BaseRenderNode getCurrentNodeRenderer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        BaseRenderNode object <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currentNode <span style="color: #000000; font-weight: bold;">instanceof</span> BlackNode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            object <span style="color: #339933;">=</span> blackNode<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currentNode <span style="color: #000000; font-weight: bold;">instanceof</span> RedNode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            object <span style="color: #339933;">=</span> redNode<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> object<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> setupRender<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        childPositions <span style="color: #339933;">=</span> CollectionFactory.<span style="color: #006633;">newMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setCurrentNode<span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>The Custom Delegate</h2>
<p>This was the <strong>crucial</strong> component that unlocked our ability to build the tree.  As you can see above, the delegate will be encountered with every node in the tree, and since the type of a child node may change, the delegate needs to be able to change the component that it references.  The built-in Delegate component in Tapestry 5 cannot do this, since the &#8220;to&#8221; parameter is cached.  We needed to build a custom Delegate component identical to the built-in one but with the &#8220;to&#8221; parameter uncached so that the delegate would query the container for what component to render each time the delegate is encountered.</p>
<h2>The Node Component (with subclasses)</h2>
<p>Each type of node in the tree needs its own component type, but they all extend from an identical base component that is responsible for changing the current node to render as well as updating the index of the next child node to render.</p>
<p>Each subcomponent needs to share this basic structure:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">xmlns:t</span>=<span style="color: #ff0000;">&quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- The body is replaced with component(s) for the child nodes. --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;t:body</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Here&#8217;s the base Node component.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BaseRenderNode <span style="color: #009900;">&#123;</span>
&nbsp;
    @Parameter<span style="color: #009900;">&#40;</span>required <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span>, cache <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> Node node<span style="color: #339933;">;</span>
&nbsp;
    @Parameter
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> childPosition<span style="color: #339933;">;</span>
&nbsp;
    @SetupRender
    <span style="color: #000066; font-weight: bold;">boolean</span> setup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// prevents rending with the node parameter is null.</span>
        <span style="color: #000000; font-weight: bold;">return</span> node <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @BeforeRenderBody
    <span style="color: #000066; font-weight: bold;">boolean</span> beforeChild<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// the node  has children, render the body to render a child</span>
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">boolean</span> render <span style="color: #339933;">=</span> node.<span style="color: #006633;">getChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>render<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// sets the container's currentNode to the node's child at the given index.</span>
            node <span style="color: #339933;">=</span> node.<span style="color: #006633;">getChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>childPosition<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> render<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @AfterRenderBody
    <span style="color: #000066; font-weight: bold;">boolean</span> afterChild<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// increment the child position, afterRender on the child will have the container's currentNode set back to the node before the body was rendered.</span>
        childPosition <span style="color: #339933;">=</span> childPosition <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// return true on last child index, finishing the iteration over the children, otherwise re-render the body (to render the next child)</span>
        <span style="color: #000000; font-weight: bold;">return</span> node.<span style="color: #006633;">getChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;=</span> childPosition<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @AfterRender
    <span style="color: #000066; font-weight: bold;">void</span> after<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// set the currentNode to the parent after render (pop the stack)</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>node.<span style="color: #006633;">isRoot</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            node <span style="color: #339933;">=</span> node.<span style="color: #006633;">getParent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Conclusion</h2>
<p>We have seen how a tree-like structure can be rendered through Tapestry 5.  Tapestry&#8217;s ability to dynamically render static templates made this possible, but we needed to turn off a caching optimization in the Delegate component in order to increase the dynamism.</p>
<p><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2009%2F06%2Ftapestry-5-recursive-tree%2F&amp;linkname=Building%20a%20contextual%20recursive%20tree%20in%20Tapestry%205" title="Delicious" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_instapaper" href="http://www.addtoany.com/add_to/instapaper?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2009%2F06%2Ftapestry-5-recursive-tree%2F&amp;linkname=Building%20a%20contextual%20recursive%20tree%20in%20Tapestry%205" title="Instapaper" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/instapaper.png" width="16" height="16" alt="Instapaper"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.bolkey.com%2F2009%2F06%2Ftapestry-5-recursive-tree%2F&amp;title=Building%20a%20contextual%20recursive%20tree%20in%20Tapestry%205" id="wpa2a_4">Share/Bookmark</a></p><img src="http://feeds.feedburner.com/~r/rbolkey/~4/rwx50JolHGM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.bolkey.com/2009/06/tapestry-5-recursive-tree/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The Trouble with Proxies: Hibernate or DataNucleus</title>
		<link>http://blog.bolkey.com/2009/05/hibernate-datanucleus-r1/</link>
		<comments>http://blog.bolkey.com/2009/05/hibernate-datanucleus-r1/#comments</comments>
		<pubDate>Fri, 22 May 2009 22:39:39 +0000</pubDate>
		<dc:creator>rbolkey</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Datanucleus]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Persistence]]></category>

		<guid isPermaLink="false">http://blog.bolkey.com/?p=21</guid>
		<description><![CDATA[Hibernate and DataNucleus (JDO2) are arguably the two most substantial persistence frameworks in the open source ecosystem.  I have worked with DataNucleus quite a bit on the side, and I am now finding an opportunity to use Hibernate during my day job. I have now spent enough time using Hibernate to appreciate the approach that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.hibernate.org/">Hibernate</a> and <a href="http://www.datanucleus.org/">DataNucleus</a> (JDO2) are arguably the two most substantial persistence frameworks in the open source ecosystem.  I have worked with DataNucleus quite a bit on the side, and I am now finding an opportunity to use Hibernate during my day job.</p>
<p>I have now spent enough time using Hibernate to appreciate the approach that DataNucleus takes using bytecode enhancement in comparison to Hibernate&#8217;s proxies.  Essentially, I am finding myself having to appease Hibernate&#8217;s view of the world in unexpected ways where I would like to leave my code alone. Two problem cases have come up so far that I would not have encountered with DataNucleus: using <code>instanceof</code> with type hierarchies and implementing <code>equals</code>.  In both of these case, bytecode enhancement would leave my Java code to work just as I expected; but instead, I have to deal with an extra layer of indirection where I was expecting to deal directly with my objects.</p>
<h2>Type hierarchies and <code>instanceof</code></h2>
<p>Lets say that I have the following type hierarchy:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Transformer <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Autobot <span style="color: #000000; font-weight: bold;">extends</span> Transformer <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Decepticon <span style="color: #000000; font-weight: bold;">extends</span> Transformer <span style="color: #009900;">&#123;</span> ... <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Obviously, there are times that I may be given an instance of type Transformer where I want to distinguish between an Autobot and a Decepticon using <code>instanceof</code>.  However, if I am persisting these instances with Hibernate, and I receive a proxy to the persisted entity, I cannot use <code>instanceof</code> to determine the type of the instance I am dealing with.  In Hibernate, the entity instance could well be an Autobot, but the returned proxy to the entity will implement both the Autobot and the Decepticon types.</p>
<p>In order to determine the instance type I am dealing with, I have to either unwrap the proxy or turn off lazy loading.  Both of these are undesirable solutions.  Unwrapping the proxy adds extra persistence operations outside of the persistence tier of your application, which violates a clean separation of concerns.  And of course, there is a performance hit for turning off lazy loading.  I wouldn&#8217;t have to use either of these undesirable solutions with DataNucleus.<br />
<span id="more-21"></span></p>
<h2>Implementing <code>equals</code></h2>
<p>This problem seems well documented within the Hibernate community, but it is still an annoyance and evidence of how Hibernate&#8217;s design forces you to alter expected Java constructs to fit Hibernate&#8217;s needs.  If you want an <code>equals</code> method to play friendly with Hibernate proxies you need to.</p>
<ul>
<li><strong>Do comparisons on properties instead of fields</strong>. If you compare on fields, the proxy may return null, comparing on properties will initialize the proxy and return the expected result.</li>
<li><strong>Use <code>instanceof</code> comparison instead of class equality</strong>.  The type of the proxy is not equal to the type of the entity, but rather extends the type of the entity.</li>
<li><strong>Compare to the interface instead of the implementing class</strong>. You need to do this if you are using interface proxies instead.</li>
</ul>
<p>All of the above break the expected construct of the <code>equals</code> method, and DataNucleus does not force you to make any of these concessions.</p>
<h2>Conclusion</h2>
<p>Obviously, I&#8217;m still expanding my knowledge in the Hibernate way of the world, but from just these two headaches I have had with Hibernate, DataNucleus&#8217; approach of using bytecode enhancement looks much superior to the proxying that Hibernate does.</p>
<p><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2009%2F05%2Fhibernate-datanucleus-r1%2F&amp;linkname=The%20Trouble%20with%20Proxies%3A%20Hibernate%20or%20DataNucleus" title="Delicious" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_instapaper" href="http://www.addtoany.com/add_to/instapaper?linkurl=http%3A%2F%2Fblog.bolkey.com%2F2009%2F05%2Fhibernate-datanucleus-r1%2F&amp;linkname=The%20Trouble%20with%20Proxies%3A%20Hibernate%20or%20DataNucleus" title="Instapaper" rel="nofollow" target="_blank"><img src="http://blog.bolkey.com/wp-content/plugins/add-to-any/icons/instapaper.png" width="16" height="16" alt="Instapaper"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.bolkey.com%2F2009%2F05%2Fhibernate-datanucleus-r1%2F&amp;title=The%20Trouble%20with%20Proxies%3A%20Hibernate%20or%20DataNucleus" id="wpa2a_6">Share/Bookmark</a></p><img src="http://feeds.feedburner.com/~r/rbolkey/~4/DydNPkjOxbM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.bolkey.com/2009/05/hibernate-datanucleus-r1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 2.756 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-08 13:45:12 -->

