JBoss Seam: renderizar un xhtml externo
02 dic 2011
Todos sabemos las ventajas que tiene trabajar con plantillas xhtml a la hora de generar la capa de presentación o incluso para generar emails o pdfs a través de seam.
El problema viene cuando utilizamos una gran cantidad de plantillas xhtml personalizadas y necesitamos gestionarlas de manera externa a la aplicación y almacenarlas por ejemplo en un repositorio externo: BD, gestor documental, ftp, en disco, etc.
Por defecto, el render de Seam permite generar renderizados de vistas (views) que están contenidas dentro de la propia aplicación. Un ejemplo:
renderer.render("/pdf/templatePdf.xhtml");
La anterior linea intentará generar el renderizado a partir de un resource en la propia aplicación, es decir, el archivo templatePdf.xhtml debe estar físicamente en el webapps de la aplicación.
¿Y qué ocurre si tenemos un templatePdf.xhtml externo, quizás en un repositorio o lo queremos generar dinámicamente?
Lo que tenemos que hacer es implementar un cargador de resources que controle cuándo queremos renderizar una vista normal o una vista en un repositorio externo.
Esta distinción se hará a nivel de URL, es decir, cuando queramos renderizar una vista normal nos bastaría con:
renderer.render("/pdf/templatePdf.xhtml")
mientras que para renderizar vistas externas podríamos poner algo como:
renderer.render("CUSTOM-/pdf/templatePdf.xhtml")
es decir, anteponemos un prefijo, por ejemplo “CUSTOM-”.
Ahora nos toca decirle al cargador de resources que cuando se solicite un recurso con el prefijo “CUSTOM-” lo trate de manera especial, cargándolo por ejemplo de un repositorio de plantillas, de un FTP, generándolas nosotros dinámicamente o lo que necesitéis. Aquí os pongo la implementación de la clase:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.contexts.ServletLifecycle;
import org.jboss.seam.core.ResourceLoader;
import org.jboss.seam.util.Resources;
@Name("org.jboss.seam.core.resourceLoader")
@Scope(ScopeType.STATELESS)
public class CustomResourceLoader extends ResourceLoader {
public static final String TEMPLATE_PREFIX = "CUSTOM-";
@Override
public URL getResource(final String resource) {
URL url = null;
if (resource.startsWith(TEMPLATE_PREFIX)) {
final String uriViewId = resource.substring(TEMPLATE_PREFIX.length());
try {
url = new URL("internal", "", 0, uriViewId, getHandler(uriViewId));
} catch (final MalformedURLException e) {
if (log.isErrorEnabled()) {
log.error("Unable to build the URL", e);
}
}
} else {
url = Resources.getResource(resource, ServletLifecycle.getServletContext());
}
return url;
}
// @return Our own implementation of an URLStreamHandler to get the template
// from the content repository.
private static URLStreamHandler getHandler(final String uriViewId) {
return new URLStreamHandler() {
private final String uuid = uriViewId;
@Override
protected URLConnection openConnection(final URL url) throws IOException {
return new URLConnection(url) {
@Override
public void connect() throws IOException {
// Gets not called in this case
}
@Override
public InputStream getInputStream() throws IOException {
initHandler();
try {
// Cargamos el contenido de la plantilla .xhtml
byte [] content = ....... ;
final InputStream input = new ByteArrayInputStream(content);
return input;
} catch (final Exception e) {
throw new IOException(e.getMessage(), e);
}
}
private void initHandler() {
log.debug("Init Handler");
}
};
}
};
}
/**
* Sistema de Logs
*/
protected static transient Log log = LogFactory.getFactory().getInstance(CustomResourceLoader.class);
}
Quizás el equipo de desarrollo de Seam Framework propongo otro tipo de soluciones en el futuro para estos casos, pero por ahora, tenemos que hacer un poco de magia.





