Skip navigation

Una de las principales funcionalidades en las aplicaciones de gestión es la de presentación de información en un formato imprimible, ya sea PDF, Excel, Word, etc. Por ello hoy voy a contar cómo integrar un motor de informes como es Eclipse BIRT con Liferay.

Para el seguimiento del post es necesario tener instalado Eclipse Helios y el plugin de BIRT descargado desde la opción “Install New Software” del Eclipse, en el repositorio “http://download.eclipse.org/releases/helios

La estrategia a seguir es la de independizar los portlets de BIRT, delegando en Liferay la gestión de éste. Para ello levantaremos en Liferay el motor de BIRT, y los portlets consumiran ese servicio para generar sus reports.

A modo de resumen, los pasos que vamos a realizar para integrar BIRT con Liferay son los siguientes:

  1. Descargar el runtime de BIRT
  2. Definir la interfaz de paso de información desde un portlet a BIRT
  3. Crear un servlet para el motor dentro de Liferay
  4. Llamar desde un portlet cualquiera
  5. Presentar los datos

Descarga del runtime de BIRT

Lo primero de todo es descargar el motor de informes. Podemos hacerlo desde la página de Eclipse BIRT (proyecto Phoenix). Allí vamos a “Latest BIRT Runtime Release Build“, en este caso la 2.6.2. Y le damos a descargar el Runtime (descarga directa).

Detalle de la página de Descarga del proyecto Phoenix

Descarga de Eclipse BIRT

El lugar donde instalar el runtime debería ser accesible por el contexto de aplicación del portal Liferay (donde queremos instalar el motor de BIRT). En este caso, un buen lugar podría ser el WEB-INF/birt-runtime del portal.

Interfaz entre BIRT y los portlets

Pensando en la arquitectura, estamos creando un sistema por el cual el portal Liferay sea capaz de escuchar solicitudes de presentación de informes asociados a cualquiera de los portlets desplegados en el portal, siendo este último el responsable único de tratar dichas solicitudes. Parece conveniente el definir una interfaz de comunicaciones entre el motor de BIRT y los portlets.

Para ello, podríamos crear un conjunto de objetos Java que encapsulen los datos a pasar al informe, de tal modo que siempre se asocien los datos a la petición a BIRT de la misma manera, consiguiendo dos cosas:

  1. Unificar el modo de presentación de reports, centralizando la gestión de reports en el portal: no desplegamos BIRT en todos y cada uno de los portlets que lo utilicen.
  2. No utilizar BIRT en la capa de acceso a datos, ya que no utilizamos DataSources JDBC, sino que le pasamos al BIRT objetos Java obtenidos por cada portlet. En el report únicamente utilizaríamos ScriptedDatasources para acceder a esos objetos Java.

En la siguiente imagen la interfaz de comunicación se corresponde con “Birt-Commons”, o conjunto de clases Java que usarán los portlets.

Interfaz de comunicación entre los portlets y BIRT
Interfaz de comunicación entre los portlets y BIRT

Para que BIRT, que estará dentro del contexto de Liferay, pueda leer esos datos, los portlets deben dejarlos en el contexto de aplicación (APPLICATION_SCOPE). Para ello es necesario configurar en el fichero liferay-portlet.xml de cada portlet el siguiente elemento:

<private-session-attributes>false</private-session-attributes>

De esta forma los portlets podrán compartir datos con la sesión del portal.

BIRT Engine y Servlet de escucha de peticiones

Ya tenemos la interfaz, ahora queda codificar un servlet que levante el motor de BIRT. Pero antes es necesario crear la clase que represente a nuestro BIRTEngine:

Ya que la plantilla de WordPress no me permite formatear bien el código, os lo adjunto en un archivo de texto: birt-engine-servlet. Como veréis, existe un fichero de propiedades como atributo de la clase, en la que irá definida la ruta al runtime, que dejamos en WEB-INF/birt-runtime.

Ahora ya tenemos un BIRTEngine y un servlet que acepta peticiones de BIRT, el cual las redirige al engine y procesa para obtener un PDF.

Para que el servlet esté contenido en Liferay, será necesario que lo añadamos al web.xml del portal Liferay (<servlet> y <servlet-mapping>), donde definiremos la URL de escucha de peticiones del servlet, por ejemplo /birt

Creación de la petición

Tenemos el servlet iniciado dentro del contexto del portal, y tenemos el runtime preparado igualmente. Hemos definido además la interfaz de comunicación entr los portlets y BIRT (a través de un conjunto de clases Java que encapsulan los datos).

En un portlet, pasaremos los datos de la siguiente manera:

//le pasamos los datos al servlet del BIRT

HashMap<String,Object> datosBIRT = new HashMap<String,Object>();   

//cada portlet envía sus datos propios

datosBIRT.put(“MIS_DATOS_A_BIRT_KEY”, new Object() );    request.getSession().setAttribute(ConstantesBIRT.DATOS_BIRT, datosBIRT);

//le pasamos los parametros: solo la plantilla

ParametrosReport parametros = new ParametrosReport();    parametros.setPlantilla(“file1.rptdesign“);

parametros.setFicheroSalida( “”+( new Date().getTime() ) );    request.getSession().setAttribute(ConstantesBIRT.PARAMETROS_BIRT, parametros);

Ahora acabamos de pasar a la sesión de usuario los datos para que el servlet de BIRT pueda leerlos. Si os habéis dado cuenta, no aparece nada del APPLICATION_SCOPE. Eso es porque este ejemplo de código es para un portlet de Struts y por tanto trabajamos directamente con la HttpSession (obtenida de una HttpServletRequest), en lugar de las PortletSession y PortletRequest, respectivamente.

Independientemente del tipo de portlet, la “vista” a utilizar será un JSP que presente el report. En este JSP podemos incluir un IFRAME que haga la petición al servlet de BIRT, que inmediatamente leerá los datos de la sesión de usuario, presentando el report.

Para hacer la petición en el JSP:

<iframe title=”Impresión en PDF” style=”height:500px;width:98%” src=”<%=themeDisplay.getURLPortal() %>/birt“/>

Presentación del report

Para que el report sepa interpretar los datos que le llegan por sesión, es necesario codificar el ScriptedDatasource. Esto se realiza en los diferentes eventos del DataSet (open, fetch,…):

importPackage(Packages.java.lang);

contexto = reportContext.getAppContext();
//importamos el paquete de la interfaz 
importPackage(Packages.es.un.paquete.common.birt);
objeto = contexto.get("MIS_DATOS_A_BIRT_KEY");

Ahora ya sólo queda construir el DataSet en función de los atributos del objeto Java que recibe el report y, por código, enlazar cada columna del dataset con los valores del atributo, en el evento fetch del dataset:

row["MI_ATRIBUTO"] = objeto.getMiAtributo();

El report debería recibir la información correctamente, asociar los valores al dataset y, por tanto, visualizar todo en un PDF.

About these ads

  1. Great tip on integrating BIRT with Liferay. Can you also submit a link to your article on BIRT Exchange devshare (http://www.birt-exchange.org/org/devshare/) so more BIRT developers can benefit from it?

  2. Wow! Interesante artículo.
    Te hago algunas preguntillas, ¿ok?
    ¿Qué usos le estás dando a esto en tu proyecto? ¿Qué información estás exportando para generar los informes?
    ¿Se te ocurren ciertas “áreas” de Liferay donde encajaría tener esta integración out of the box?
    Gracias por compartir,
    Juan Fernández

  3. ¿Tienes algún portlet de ejemplo para realizar la prueba? El concepto lo entiendo pero la implementación me da problemas.

  4. Had you not used black background your article could have been more popular

    • Hello abcd, thanks for your comment

      I’ll switch it to a new blog, under Liferay community, when I have more time. I hope you like it more.

      Manuel.

  5. Hello, I’m new to liferay and Birt.
    Thankyou for sharing your solution, It was very helpful, though I don’t speak Spanish(I could understand a bit because I speak Portuguese).

    Can you provide full source code for this posts.

    Thanks in advance. Great Post.


Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d personas les gusta esto: