sábado, 22 de junio de 2013

Buscar un Componente JSF por su ID Relativo del Lado del Servidor

Esta semana he sufrido un déjà vu. Necesitábamos obtener un UIComponent desde un ManagedBean en una aplicación JSF y no contábamos con la ruta absoluta que pedía la API que estábamos usando. Recordé entonces que esto con Seam 2 era trivial, pero como no estábamos usando Seam, necesitábamos una manera de encontrar el componente en el árbol de componentes del lado del servidor por su ID relativo.

Entonces recordé que yo ya había hecho esto en una vieja aplicación JSF.

JSFComponentFinder

Googleando un buen rato y con una idea fija en la cabeza, todo se encuentra. En este post está la solución: How to Find an UIComponent in ViewRoot.

Así que, tomé el código fuente y creé mi propia clase JSFComponentFinder.

Aplicación JSF de Prueba

Para probar el JSFComponentFinder armé una aplicación JSF Java EE 6. Para esto, partí del arquetipo para Maven de JBoss: jboss-javaee6-webapp-archetype. Luego, edité el index.xhtml para que tuviera unos pocos inputText y outputLabel vacíos con el único fin de poder buscarlos del lado del servidor. Debajo de estos tres inputs, puse otro inputText en el cual uno puede escribir el ID relativo del componente que se desea buscar. Al pulsar el botón Find, debajo aparecerá el ID absoluto, la ruta completa, del componente, que en el ejemplo de los inputs simplemente es el nombre del formulario, seguido por el separador de dos puntos, seguido por el ID relativo; en este caso es simple.

http://jsfcomponentfinder-elfrasco.rhcloud.com/index.jsf
El código fuente de la aplicación de prueba la subí a GitHub para el que desee consultarlo:
https://github.com/elfrasco/jsf-component-finder

El arquetipo de JBoss está muy bueno, pero es demasiado específico para JBoss AS para mi gusto. Así que modifiqué el pom.xml para que fuera más genérico, tomando únicamente la dependencia de la especificación de Java EE y sacando las librerías de hibernate y arquillian que para este ejemplo tan pequeño no hacían falta.
<dependency>
    <groupid>javax</groupid>
    <artifactid>javaee-api</artifactid>
    <version>6.0</version>
    <scope>provided</scope>
</dependency>
Así, minimalizando y estandarizando el proyecto, al ejecutar:
mvn clean install
Obtendremos un WAR que podremos desplegar en cualquier servidor de aplicaciones Java EE 6.

JSFComponentFinder en OpenShift

Para seguir jugando un poco más, decidí probar mi humilde aplicación de ejemplo en OpenShift y, una vez agregándole el perfil OpenShift y el directorio deployments requeridos por el cartridge de AS 7, funcionó perfecto.

Aquí lo pueden ver funcionando: