Richard Bolkey – Blog

Icon

Thoughts of a plain old java developer.

Creating a news feed in Tapestry 5

News feeds are frequently encountered in today’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.

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!

This tutorial requires previous knowledge of mixins and ajax in Tapestry, as well as some familiarity with Prototype, a JavaScript framework used by Tapestry.

Inserting markup instead of replacing

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.

/**
 * Modifies how a the content of a Tapestry Zone is updated.  Allows content to 
 * be inserted instead of just updating an element.
 */
@IncludeJavaScriptLibrary("ZoneInserter.js")
public class ZoneInserter {
 
    /**
     * Accepted insertion points are:
     * <ul>
     * <li>before (as element's previous sibling)</li>
     * <li>after (as element's next sibling)</li>
     * <li>top (as element's first child)</li>
     * <li>bottom (as element's last child) [<b>default</b>]</li>
     * </ul>
     */
    @Parameter(defaultPrefix = BindingConstants.LITERAL, value = "bottom")
    private String insertion;
 
    @InjectContainer
    private Zone zone;
 
    @Inject
    private ComponentResources resources;
 
    @Inject
    private RenderSupport renderSupport;
 
    void afterRender() {
 
        final String id = zone.getClientId();
 
        final JSONObject config = new JSONObject();
 
        if (resources.isBound("insertion")) config.put("insertion", insertion);
 
        renderSupport.addInit("zoneInserter", new JSONArray(id, config));
    }
}

This is a very simple mixin that passes the client id of the zone and a single configuration parameter (“insertion”) to a JavaScript initialization script. The mixin needs to run after the zone renders so that the zones client id is known. Read the rest of this entry »

Share/Bookmark

Building a contextual recursive tree in Tapestry 5

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 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’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).

The Container Component

The container component maintains stateful tree information while rendering the tree, and selects the component to render for the current node of the tree.

Here is the container’s template.

< ?xml version="1.0" encoding="UTF-8"?>
<ul xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
 
    <!-- The custom delegate to the component to render based on the context of the current node. -->
    <t:nodedelegate to="currentNodeRenderer"></t:nodedelegate>
 
    <t:block>
        <!-- This block contains a set of components to delegate rendering to based on the current node. -->
        <div t:id="blackNode">
            <!-- Delegate to the child component to render.  This replaces the component's body. -->
            <t:nodedelegate to="currentNodeRenderer"></t:nodedelegate>
        </div>
 
        <div t:id="redNode">
            <t:nodedelegate to="currentNodeRenderer"></t:nodedelegate>
        </div>
 
    </t:block>
 
</ul>

Read the rest of this entry »

The Trouble with Proxies: Hibernate or DataNucleus

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 DataNucleus takes using bytecode enhancement in comparison to Hibernate’s proxies.  Essentially, I am finding myself having to appease Hibernate’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 instanceof with type hierarchies and implementing equals.  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.

Type hierarchies and instanceof

Lets say that I have the following type hierarchy:

public interface Transformer { ... }
 
public interface Autobot extends Transformer { ... }
 
public interface Decepticon extends Transformer { ... }

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 instanceof.  However, if I am persisting these instances with Hibernate, and I receive a proxy to the persisted entity, I cannot use instanceof 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.

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’t have to use either of these undesirable solutions with DataNucleus.
Read the rest of this entry »