jueves, 27 de mayo de 2010

Hola mundo con Apache Tapestry 5

Apache Tapestry

Hace unos días publiqué una entrada en la que hice el típico programa Hola Mundo con Apache Tapestry en su versión 4.1 (T4).

En esta entrada pretendo realizar el mismo ejemplo pero esta vez mediante Apache Tapestry 5.1 (T5) en el que veremos que tiene notables diferencias sobre T4, sin embargo, es suficientemente sencillo para que no necesite muchas explicaciones. El ejemplo consistía en una página con una imagen, dos componentes uno que mostraba un texto y otro un reloj que se actualiza cada segundo mediante javascript.

Mediante estas dos entradas se puede comparar como ha evolucionado este framework y cuales han sido algunos de sus principales cambios, además de ver un pequeño ejemplo de como son las cosas en T5.

Entre los cambios más notables de una versión a otra es que en T5 se establece como requisito a partir de ahora el uso de Java 5 (de modo que si en un proyecto tenemos como requisito el utilizar un JDK 1.4 entonces tendremos que usar T4) con todas las nuevas características que esta evolución de Java aporta, entre ellas ahora en T5 se hace un uso intensivo de las anotaciones lo que le permite eliminar los archivos jwc que eran requeridos en T4 para especificar los componentes y hace aún más sencillo la escritura de los componentes. Otro de los cambios más notables de T5 es que los componentes y páginas ya no tiene porque ser abstractas ni tienen que heredar de una determinada clase de Tapestry sino que son simplemente POJOs lo que es útil a la hora de hacer casos de prueba automatizados.

Veamos como es en T5 el componente HolaMundo que ahora sólo consta del archivo HolaMundo.java:

package com.blogspot.elblogdepicodev.tapestry.helloWorld.components;

import org.apache.tapestry5.MarkupWriter;

public class HolaMundo {

    protected boolean beginRender(MarkupWriter writer) {
     writer.write("Hola mundo Tapestry !!!");
  return false;
 }
}

El componente Reloj también ha cambiado tanto en la parte java como en el javascript que tiene asociado:

Reloj.java

package com.blogspot.elblogdepicodev.tapestry.helloWorld.components;

import org.apache.tapestry5.Asset;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.RenderSupport;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
import org.apache.tapestry5.ioc.annotations.Inject;

@SupportsInformalParameters
public class Reloj {

    @Inject
    @Path("classpath:com/blogspot/elblogdepicodev/tapestry/helloWorld/components/Reloj.js")
    private Asset script;

    @Environmental
    private RenderSupport renderSupport;
    
    @Inject
    private ComponentResources componentResources;

    protected void setupRender() {
        renderSupport.addScriptLink(script);
    }

    protected boolean beginRender(MarkupWriter writer) {
        String id = componentResources.getId();
        
        writer.element("span", "id", id);
        componentResources.renderInformalParameters(writer);
 return false;
    }

    protected boolean afterRender(MarkupWriter writer) {
        String id = componentResources.getId();

        writer.end();
        renderSupport.addScript("var %s = new Reloj('%s');", id, id);       
 return true;
    }
}

Reloj.js

Reloj = function(id) {
    new PeriodicalExecuter(function(pe) {
        $(id).update(new Date().toString());
    }, 1);
}

Veamos también como es la plantilla de la página Index.tml:

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
<head>
 <title>Hola mundo Tapestry !!!</title>
</head>

<body style="font-family: Verdana; font-size: 10px;">
    <img src="${context:images/tapestry-banner.gif}"/>
    <br/>
    <br/>

    <b><t:holaMundo/></b>
    <br/>
    <br/>
    <t:reloj t:id="reloj"/>
</body>
</html>

Otro de los cambios en T5 es que ahora es un filtro el que procesa las peticiones de la aplicación en vez de un servlet como era en T4. Esto lo podemos ver en fichero web.xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
 <display-name>HelloWorldTapestry</display-name>
 <description>Aplicación Hola Mundo con Tapestry5</description>
 
 <context-param>
  <!-- The only significant configuration for Tapestry 5, this informs Tapestry
   of where to look for pages, components and mixins. -->
  <param-name>tapestry.app-package</param-name>
        <param-value>com.blogspot.elblogdepicodev.tapestry.helloWorld</param-value>
 </context-param>
    
 <filter>
  <filter-name>app</filter-name>
  <filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
 </filter>
          
 <filter-mapping>
  <filter-name>app</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <session-config>
  <session-timeout>30</session-timeout>
 </session-config>

 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
</web-app>

Además en el web.xml se indicará mediante el parámetro de contexto tapestry.app-package el paquete en el que T5 buscará las clases de los componentes, paginas y servicios.

Dado que la orientación de T5 ha sido eliminar los XML de configuración por anotaciones el fichero para la inyección de dependencias (hivemind.xml) tambien ha sido sustituido por una clase en el paquete services, AppModule. En esta clase será donde definamos nuestros servicios y contribuciones.

La página de inicio de la aplicación tiene la siguiente URL: http://localhost:8080/HelloWorldTapestry5/Index

Para construir la aplicación he utilizado ant, basta con ejecutar desde la linea de comandos:

Para Linux: $ ./ant.sh resolve package
Para Windows: > ./ant.cmd resolve package

Tal vez a la hora de obtener las dependencias con Ivy os de un mensaje de error indicando que no se ha podido obtener la librería javassist, si es el caso deberéis obtenerla manualmente y copiarla al directorio .ivy2/javassist/javassist/3.9.0.GA/jar del directorio home (para Linux) o Documents and Settings (para Windows) del usuario.

El resultado de la aplicación en funcionamiento es:

Aplicación HelloWorldTapestry funcionando

Si quieres conocer más en detalle las características de este excelente framework puedes consultar el siguiente enlace:

Documentación sobre Apache Tapestry
Código fuente ejemplo Hola Mundo con Apache Tapestry 5