Apache Tapestry es un marco de aplicaciones web Java orientado a componentes de código abierto [ aclaración necesaria ] conceptualmente similar a JavaServer Faces y Apache Wicket . [2] Tapestry fue creado por Howard Lewis Ship, [ ¿cuándo? ] y fue adoptado por la Apache Software Foundation como un proyecto de alto nivel en 2006. [3]
Tapestry pone énfasis en la simplicidad, la facilidad de uso y la productividad del desarrollador. Se adhiere al paradigma de Convención sobre Configuración , eliminando casi toda la configuración XML . [4] Tapestry utiliza un enfoque modular para el desarrollo web al tener un fuerte vínculo entre cada componente de interfaz de usuario (objeto) en la página web y su clase Java correspondiente . Esta arquitectura basada en componentes toma prestadas muchas ideas de WebObjects . [5]
Una aplicación Tapestry mínima y con plantilla necesita solo tres archivos:
<!DOCTYPE html> <html xmlns= "http://www.w3.org/1999/xhtml" xmlns:t= "http://tapestry.apache.org/schema/tapestry_5_3.xsd" > <body> <p> Hola, ${nombreusuario} </p> </body> </html>
paquete org.example.demo.pages ; /** Una clase de página (asociada automáticamente con el archivo de plantilla del mismo nombre) */ public class HelloWorld { /** Un getter ordinario */ public String getUsername () { return "World" ; } }
<?xml version="1.0" encoding="UTF-8"?> <!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> Ejemplo de Tapestry </display-name> <context-param> <!-- Indicar a Tapestry 5 dónde buscar páginas, componentes y mixins --> <param-name> tapestry.app-package </param-name> <param-value> org.example.demo </param-value> </context-param> <filter> <!-- Definir el filtro del servlet Tapestry --> <filter-name> app </filter-name> <filter-class> org.apache.tapestry5.TapestryFilter </filter-class> </filter> <filter-mapping> <!-- Indica al contenedor de servlets qué solicitudes enviar al filtro de servlets de Tapestry --> <filter-name> app </filter-name> <url-pattern> /* </url-pattern> </filter-mapping> </web-app>
Tapestry utiliza la manipulación de bytecode para transformar las clases de páginas y componentes en tiempo de ejecución. Este enfoque permite que las clases de páginas y componentes se escriban como POJOs simples , con algunas convenciones de nombres y anotaciones que potencialmente desencadenan un comportamiento adicional sustancial en el momento de carga de la clase. Las versiones 5.0, 5.1 y 5.2 de Tapestry usaban la biblioteca de manipulación de bytecode de Javassist. Las versiones posteriores reemplazaron a Javassist con una nueva capa de manipulación de bytecode llamada Plastic que se basa en ObjectWeb ASM . [11] [12]
Las versiones de Tapestry 5 hasta la 5.3 incluían los frameworks JavaScript Prototype y script.aculo.us , junto con una biblioteca específica de Tapestry, para soportar operaciones Ajax como ciudadanos de primera clase. Hay módulos de terceros disponibles para integrar jQuery en lugar de Prototype/Scriptaculous o además de ellos.
A partir de la versión 5.4, Tapestry incluye una nueva capa de JavaScript que elimina la dependencia de los componentes integrados de Prototype, lo que permite conectar jQuery u otro marco de JavaScript. [13]
La versión 5.4 también introduce soporte para módulos JavaScript que utilizan el sistema de carga de módulos RequireJS.
La documentación del proyecto Tapestry cita cuatro "principios" que rigen todas las decisiones de desarrollo de Tapestry, a partir de la versión 5 en 2008: [14]
Tapestry ha sido criticado por no ser compatible con versiones anteriores en las principales versiones, especialmente en la transición de la versión 4 a la versión 5, donde no había disponible una ruta de migración limpia para las aplicaciones existentes. [15] Los miembros del equipo del proyecto han reconocido que esto era un problema importante para los usuarios de Tapestry en el pasado, y la compatibilidad con versiones anteriores se convirtió en un objetivo de diseño importante para Tapestry en el futuro. Desde el comienzo del desarrollo de la versión 5, la compatibilidad con versiones anteriores se incluyó como uno de los cuatro nuevos "Principios básicos" de Tapestry, y dos de los otros tres tenían como objetivo hacer posible la evolución del marco sin sacrificar la compatibilidad con versiones anteriores. Los miembros del equipo del proyecto afirman que todas las versiones de Tapestry desde la 5.0 han sido altamente compatibles con versiones anteriores.
Las primeras críticas a Tapestry 5 también mencionaban la documentación como una deficiencia. Los miembros del proyecto afirman ahora que esta deficiencia se ha solucionado en gran medida con una Guía del usuario completamente revisada y actualizada y otra documentación.
Desde la versión 5.0, Tapestry incluye las bibliotecas JavaScript Prototype y Scriptaculous. Según Howard Lewis Ship, en el período 2008-2009 eran opciones razonables. Sin embargo, desde entonces, la popularidad de Prototype ha disminuido y la de jQuery ha aumentado drásticamente. En respuesta, la comunidad de Tapestry desarrolló módulos que permitían utilizar jQuery además de Prototype o en lugar de él. Mientras tanto, la versión actual de Tapestry, 5.4, elimina por completo la dependencia de Prototype y la reemplaza con una capa de compatibilidad en la que se puede conectar jQuery o Prototype (o potencialmente cualquier otro marco de JavaScript).
Según Howard Lewis Ship, Tapestry fue concebido inicialmente como un intento de implementar en Java algunos de los conceptos y enfoques generales encontrados en WebObjects, que en ese momento estaba escrito en Objective-C y era de código cerrado. [16]
Apache Wicket se desarrolló como respuesta a la complejidad de las primeras versiones de Tapestry, según el creador de Wicket, Jonathan Locke. [17]
Facelets , la tecnología de visualización predeterminada en JavaServer Faces , se inspiró supuestamente en las primeras versiones de Tapestry, como un intento de cubrir la necesidad de "un marco como Tapestry, respaldado por JavaServer Faces como el estándar de la industria". [18] [19]