Etiqueta: programación

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.

Las 20 mejores respuestas cuando una aplicación no funciona

11 may 2010

A continuación, las mejores respuestas de un desarrollador ante un fallo en una de sus aplicaciones:

20. “Esto es raro …”

19. “Esto nunca había pasado antes.”

18. “Ayer funcionaba.”

17. “¿Cómo es esto posible?”

16. “Debe ser un problema del hardware.”

15. “¿Qué pusistes para que esto petara?”

14. “Algo está mal en tus datos.”

13. “Pues, ¡no he tocado este módulo en semanas!”

12. “Tienes que tener una versión errónea.”

11. “Sólo es una desafortunada coincidencia.”

10. “¡No lo puedo testear todo!”

9. “ESTO no puede ser la causa de AQUELLO”.

8. “Funcionar funciona, lo que pasa que no ha sido probado”.

7. “Alguien ha tenido que tocar mi código”.

6. “¿Has mirado si tienes virus en tu sistema?”

5. “A pesar de que esto no funciona, ¿cómo te sientes?”

4. “Esta versión no está hecha para este sistema.”

3. “¿Por qué tienes que hacerlo así?”

2. “¿Dónde estabas cuando la aplicación reventó?”

Y el número uno de las respuestas ante fallos de aplicaciones:

1. “En mi máquina funciona”

Traducción libre de The Top 20 replies by programmers when their programs do not work

Curiosidad: Estoy seguro de que nos olvidamos de algo…(Los problemas de la sinceridad)

27 ene 2010

Que pasaría si al hacer una entrega de software al cliente le decimos:

Estoy seguro de que nos olvidamos de algo, y sé que tenemos algunos conflictos pendientes. Al mismo tiempo, necesitamos la cobertura de una versión real, y en su conjunto tiene muy buen aspecto. Hemos corregido unos cuantos conflictos en los últimos días, y siempre tendremos las versiones 2.6.30.x (parches).

Pues este es precisamente el mensaje con el Linus Torvalds dio a conocer la versión 2.6.30 del Kernel de Linux!! (el mensaje original en: http://lkml.org/lkml/2009/6/9/710). Sería impensable que le dijéramos una frase similar a un cliente.

Salvando los posibles problemas con clientes que “entren en pánico” debido a este derroche de sinceridad, y ahora que está tan de moda las políticas de calidad, objetivos, métricas, … Nuestro objetivo es que la calidad de nuestras aplicaciones esté tan demostrada, que en una situación puntual le podamos decir a un cliente una frase tan sincera como ésta, sin que el cliente sienta ningún tipo de angustia.

Visteme despacio que tengo prisa!

10 mar 2009

Los programadores se enfrentan a una paradoja de valores básicos. Todos los desarrolladores con algunos años de experiencia saben que desordenes previos son causas de retraso. Y sin embargo todos los desarrolladores sienten que la presión les hace dejar mal algunas cosas para conseguir alcanzar las fechas de entrega. En resumen, no se toman el tiempo necesario para ir rápido.

Los verdaderos profesionales saben que la segunda parte de la paradoja está mal. No llegarás a la fecha haciendo mal las cosas. Es más, hacer las cosas mal te retrasará instantáneamente, y te forzará a incumplir la fecha de entrega. La única manera de llegar a la fecha -la única manera de ir rápido- es mantener el código tan limpio como sea posible durante todo el tiempo.

Parrafos del libro “Clean Code”,  leido en el blog de José Manuel Beas

Programar es divertido, entregar es tu trabajo

25 ene 2007

Un abstract,  en traducion, mas o menos libre, de algo escrito por Chuck Jazdzewski:

  • Nunca dejes de aprender. Nunca dejes de estudiar.
  • La comunicacion es critica. Aprende a expresarte. Oralmente y por escrito. Transmite confianza. Aprende a comunicarte con otros tecnicos, pero tambien con clientes, con jefes,  gente de marketing, con gente que no sabe ni quiere saber el argot tecnico… Aprende a expresarte en ingles, al menos a nivel tecnico.
  • Promete menos de lo que crees poder hacer, y da mas de lo que has prometido.
  • Admite cuando te equivocas. Y hazlo saber, no lo escondas.
  • Si no ha sido testeado, no funciona. Asumir lo contrario es un error.
  • Programar es divertido, pero no es tu trabajo, entregar si lo es. Si hace falta documentar, hazlo, es tu trabajo.

(El blog de Chuck: http://www.removingalldoubt.com/)