Intégration de BIRT dans un environnement PHP

Lazarel

Ce tutoriel a pour but de pouvoir intégrer un applicatif Java ici l'outil de reporting BIRT dans un environnement PHP via l'appel à une URL.

- Titre : Intégration de BIRT dans un environnement PHP

- Auteur : Lazarel

- Parution : 12 janvier 2009

- Mise à jour : 12 décembre 2019

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2009 J. Sauvebois. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.

Sommaire

- I. Introduction

- II. Prérequis

- II-A. JAVA

- II-B. PHP

- II-C. BIRT

- II-D. Eclipse

- II-E. ANT

- II-F. Jboss

- III. Intégration BIRT

- III-A. Extraction de BIRT Runtime

- III-B. Intégration de BIRT à Eclipse

- III-C. Déploiement de BIRT

- III-C-1. Déclaration du projet BIRT

- III-C-2. Utilisation du service Properties

- III-C-2-a. Configuration

- III-C-3. Automatisation du déploiement des reports

- IV. Intégration PHP

- IV-A. Architecture mise en place

- IV-B. Prérequis

- IV-B-1. Configuration de Jboss

- IV-B-2. Conception d'un état BIRT avec paramètre

- IV-C. Méthode avec utilisation d'une balise IFrame

- IV-C-1. Schéma

- IV-C-2. Mise en place du formulaire de saisie

- IV-C-3. Utilisation de BIRT Viewer

- IV-D. Méthode avec utilisation d'une balise DIV

- IV-D-1. Schéma

- IV-D-2. Mise en place du formulaire de saisie

- IV-D-3. Comment appeler la Servlet

- IV-E. Méthode avec utilisation d'une balise DIV et utilisation du Framework AJAX

- IV-E-1. Schéma

- IV-E-2. Mise en place du formulaire de saisie

- IV-E-3. Comment appeler la servlet

- IV-E-4. Utilisation de Javascript et AJAX

- IV-E-5. Utilisation de Jquery

- V. Conclusion

- VI. Annexe

- VI-A. BIRT

- VI-A-1. Fichier properties

- VI-A-2. Implémentation de l'API de BIRT

- VI-B. Jboss

- VI-B-1. Comment rendre accessible votre serveur Jboss au réseau

- VI-C. Schéma de l'architecture mise en place

- VI-C-1. IFrame

- VI-C-2. DIV

- VI-C-3. AJAX

- VI-D. Références

- VI-E. Remerciements

I - Introduction

L'informatique décisionnelle aussi appelée Business Intelligence a connu ces dernières années une forte croissance. Même si aujourd'hui le marché connait un ralentissement, les entreprises et administrations sont de plus en plus désireuses d'intégrer de tels outils dans leur système d'information dans le but de consolider leurs données opérationnelles.

Ces dernières disposent le plus souvent d'un intranet à base PHP et utilisent des outils propriétaires tels que Business Objects. Elles souhaitent donc maximiser le Return On Investment (ROI) via la suppression des licences des outils sachant que dans la plupart des cas elles n'utilisent jamais l'ensemble des fonctionnalités présentes sur ces outils.

La BI open source prend alors tout son sens, car le coût des licences est quasi nul et l'ensemble des fonctionnalités nécessaires aux utilisateurs finals sont présentes. Très souvent, l'utilisation de la BI se résume à la présentation de Key Performance Indicators (KPI) aussi appelé indicateur dans une page Web via un outil de reporting. Au niveau de PHP il existe Agata Report, mais les leaders du marché open source sont : BIRT et JasperReports tous les deux à base de Java et donc difficilement intégrables dans PHP. La solution consiste à n'intégrer que le rendu sous forme de flux HTML dans une page PHP. Ce tutoriel a donc pour but de mettre en œuvre une telle architecture.

Cette procédure peut être étendue à tout appel d'une servlet Java tournant sur un serveur d'application de type JAVA : Tomcat, Jboss, etc.

II - Prérequis

Voici l'ensemble des prérequis pour mener à bien ce tutoriel. Toute personne souhaitant le mener à bien doit disposer d'un minimum de connaissance de l'ensemble des outils cités ci-dessous.

Dans ce tutoriel nous n'entrons pas en détail sur l'installation des outils, mais uniquement sur leur usage. Ce dernier s'est fait sous environnement Windows XP Professional Service Pack 2.

II-A - JAVA

Tout d'abord, il faut disposer au minimum d'une JRE 1.5.X d'installée sur notre environnement.

II-B - PHP

Ensuite, il faut un applicatif PHP. Le plus simple est de télécharger Wamp.

II-C - BIRT

BIRT est l'outil de reporting open source auquel nous faisons appel pour la génération de graphiques et/ou tableaux. Il se divise en deux parties :

1. Le Designer pour la conception des états ;

2. Le Runtime de BIRT qui contient l'archive birt.war exploitée par la suite.

La version de BIRT choisie est là 2.3.0.

Attention, dans la seconde partie du tutoriel il est nécessaire d'implémenter l'API de BIRT. Le fichier web.xml et la classe utilisée se trouvent en annexe.

II-D - Eclipse

Eclipse va permettre d'importer l'archive de BIRT et d'y ajouter quelques fonctionnalités telles que l'utilisation du service properties présent sous Jboss.

II-E - ANT

ANT va servir à l'automatisation du déploiement de la nouvelle archive créée, ainsi que les rapports.

II-F - Jboss

JBoss est le serveur d'application Java sur lequel nous déploierons notre archive birt.

III - Intégration BIRT

Dans un premier temps, il faut : récupérer l'archive BIRT, personnaliser l'application et enfin la redéployer sur le serveur d'application.

III-A - Extraction de BIRT Runtime

Il faut commencer par extraire l'archive birt-runtime-2_3_0.zip dans un fichier temporaire, celle-ci doit contenir l'archive birt.war.

III-B - Intégration de BIRT à Eclipse

Démarrez Eclipse, et commencez par vous mettre dans la perspective JAVA EE « Window --> Open Perspective --> Other ».
Ensuite fait, « File --> Import » et sélectionner « web --> war Files ».
Dans la fenêtre d'invitation, sélectionnez l'archive birt.war, donnez un nom au projet « birtV2_3_0 » puis faites « finish ».

Normalement, après l'import de l'archive vous devez avoir une erreur sur le fichier webtemplate.xml présent dans le répertoire WebContent/WEB-INF. Pour la supprimer, remplacer la valeur de xsi:schemaLocation par http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd.

III-C - Déploiement de BIRT

Le but ici est de créer un script ANT build.xml qui a le même rôle qu'un makefile pour ceux qui connaissent et permet de déployer :

1. Le projet sous forme d'archive ;

2. Les rapports sur la plateforme Jboss.

III-C-1 - Déclaration du projet BIRT

Dans notre projet birtV2_3_0, créer un fichier build.xml à la racine. Pour commencer, déclarer trois propriétés comme ci-dessous.

Name

Value

Description

jboss.server

Chemin de votre serveur Jboss

name

birtV2_3_0

Nom de l'archive

dist

./dist

Répertoire temporaire à la racine de votre projet sous Eclipse

Ensuite, ajouter les cibles :

- clean pour effacer l'archive présente sur Jboss ;

- war pour créer votre archive war ;

- deploy pour le déploiement de votre archive (cible par défaut).

Fichier : build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="birtV2_3_0" basedir="." default="deploy">
<property name="jboss.server" value="D:/jboss-portal-2.6.5.SP1/server/default"/>
<property name="name" value="birtV2_3_0"/>
<property name="dist" value="./dist"/>
<target name="clean" description="clean">
<!-- DEV -->
<delete file="${dist}/${name}.war" />
</target>
<target name="war" depends="clean">
<!-- DEV -->
<jar jarfile="${dist}/${name}.war" basedir="./WebContent/" />
</target>
<target name="deploy" description="deployement" depends="war">
<!-- JBOSS -->
<delete file="${jboss.server}/deploy/${name}.war"/>
<copy todir="${jboss.server}/deploy" file="${dist}/${name}.war"/>
</target>
</project>

Pour finir, pour exécuter le script, il suffit de faire un clic droit sur le fichier build.xml et choisir run as Ant Build.

III-C-2 - Utilisation du service Properties

Sous Jboss, il existe un service properties qui permet de charger un ensemble de paires clef/valeur utilisables dans n'importe quel fichier présent sur Jboss.
Créer un fichier birt.properties (voir annexe) avec les six clefs comme ci-dessous.

Avec Java, via la méthode statique getProperty(key,value) de la classe System il possible de récupérer ces clefs.

Name

Value

Description

birt.viewer.2.3.0.working.folder

${jboss.server.home.dir}/data/birt/report

Répertoire où stocker les.rptdesign

birt.viewer.2.3.0.document.folder

${jboss.server.home.dir}/data/birt/documents

Répertoire où stocker les.rptdocument

birt.viewer.2.3.0.image.dir

${jboss.server.home.dir}/data/birt/report/images

Répertoire où stocker les images temporaires des rapports

birt.viewer.2.3.0.log.dir

${jboss.server.home.dir}/log/birt

Répertoire de log de BIRT

birt.viewer.2.3.0.scriptlib.dir

${jboss.server.home.dir}/data/birt/scriplib

Répertoire des scriptlib de BIRT

birt.viewer.2.3.0.resource.path

${jboss.server.home.dir}/data/birt/resource

Répertoire contenant les fichiers.properties et rptlibrary

Nous créerons un répertoire conf dans la racine de notre projet Eclipse dans lequel mettre le fichier « birt.properties ».
Ensuite, nous reporterons ces clefs dans le fichier web.xml présent dans WebContent/WEB-INF au niveau des balises context-param portant le même nom.

Pour faire référence à une clef chargée, il suffit d'utiliser la syntaxe suivante ${myKey} voir exemple ci-dessous.

Fichier : web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/webapp_2_4.xsd">
<display-name>Eclipse BIRT Report Viewer</display-name>
...
<!-- Report engine log level -->
<context-param>
<param-name>BIRT_VIEWER_LOG_LEVEL</param-name>
<param-value>${birt.viewer.2.3.0.log.level}</param-value>
</context-param>
...
</web-app>

III-C-2-a - Configuration

Il reste à configurer le service properties. Pour cela, il faut éditer le fichier propertiesservice. xml présent dans le répertoire deploy de notre serveur. Cherchez les lignes de code suivantes.

<mbean code="org.jboss.varia.property.SystemPropertiesService" name="jboss:type=Service,name=SystemProperties">

et ajoutez un nouvel attribut correspondant à votre fichier « birt.properties ».

<attribute name="URLList">${jboss.server.home.dir}/conf/birt.properties</attribute>

Voilà maintenant votre fichier.properties chargera les paires continues dedans à chaque démarrage de JBoss.
Pour finir, ajoutez une cible dans le fichier build.xml pour déployer votre fichier sur JBoss et ajoutez cette dépendance à la cible deploy.

Fichier : build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="birtV2_3_0" basedir="." default="deploy">
...
<target name="conf">
<!-- DEV -->
<copy todir="${jboss.server}/conf" file="./conf/birt.properties"/>
</target>
<target name="deploy" description="deployement" depends="war,conf">
...
</project>

III-C-3 - Automatisation du déploiement des reports

Nous allons passer maintenant à la partie déploiement des rapports. Normalement la première fois que vous démarrez le Designer de BIRT, vous devez spécifier un workspace , nous nous servirons de ce chemin pour accéder à l'ensemble des rapports à déployer. Il est important quand vous développez vos rapports de respecter l'arborescence comme ci-dessous.

Niveau 1

Niveau 2

Niveau 3

Niveau 4

workspace

report

.rptdesign

images

.jpeg,.png,.bmp

resource

.properties

.rptlibrary

.css

Notez birt.workspace le chemin d'accès au workspace de BIRT et ajoutez-le au script ANT.

Fichier : build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="birtV2_3_0" basedir="." default="deploy">

<property name="birt.workspace" value="D:/birt-rcp-2_3_0/workspace"/>

<!-- WOKRSPACE -->
<target name="report" description="deploy report">
<copy todir="${jboss.server}/data/birt/report">
<fileset dir="${birt.workspace}/report" />
</copy>
<copy todir="${jboss.server}/data/birt/resource">
<fileset dir="${birt.workspace}/resource" />
</copy>
</target>

<target name="deploy" description="deployement" depends="war,conf,report">
</project>

De ce fait, une fois les reports développés, il suffit d'appeler le script ANT avec la cible « report ».

Sous Windows si vous voulez appeler le script ANT avec la cible report, il vous suffit de créer un fichier report.bat avec le contenu suivant :

@echo off
ant -buildfile build.xml report

IV - Intégration PHP

IV-A - Architecture mise en place

L'architecture mise en place est assez simple. À gauche, PHP avec une page qui contient un formulaire basé sur des données présentes dans une SGBD MySQL, de l'autre un serveur d'applications sur lequel sont présentes deux applications de reporting : « birt » et « reporting ». Les échanges entre ces deux plateformes se font via le protocole HTTP.

IV-B - Prérequis

IV-B-1 - Configuration de Jboss

Il y a trois étapes clefs :

- démarrez le serveur Jboss et testez l'accès à page d'accueil via l'URL de la forme http://localhost:8080/;

- testez que notre applicatif BIRT fonctionne via l'URL http://localhost:8080/birtV2_3_0/;

- testez que nous pouvons exécuter l'état test fourni par BIRT à partir de cette URL http://localhost:8080/birtV2_3_0/run?__report=test.rptdesign ou en cliquant sur le lien View Example.

Est présent sur la page http://localhost:8080/birtV2_3_0/ la version du viewer, du moteur de BIRT ainsi que la JRE utilisée.

IV-B-2 - Conception d'un état BIRT avec paramètre

Il faut commencer par créer un état dit test de type graphique par exemple, en forme de camembert avec un paramètre pour la mise en place d'un formulaire. Vous trouverez l'exemple ici int-php.rptdesign.

IV-C - Méthode avec utilisation d'une balise IFrame

Ce mode est le plus répandu et le plus simple à mettre en place, car il s'agit d'une simple fenêtre ou frame HTML contenant une référence vers une URL.

IV-C-1 - Schéma

Voir annexe.

IV-C-2 - Mise en place du formulaire de saisie

Dans un premier temps nous allons mettre en place un formulaire de saisie, comme ci-dessous.

Formulaire PHP

<?php
$conn = mysql_connect("localhost", "login", "mdp");
if (!conn){
die("Impossible de se connecter : ". mysql_error());
}else{
echo 'Connexion réussie </BR>';
mysql_select_db('classicmodels', $conn);
$res = mysql_query('select c.customerNumber,c.customerName from customers c order by c.customerName',$conn);
if(!$res){
die('Requête invalide : '. mysql_error().'</BR>');
}else{
$client = $_GET['client'];
?>
<DIV id="form">
<form action="" name="int-php.iframe">
<select name="client">
<?PHP while ($row = mysql_fetch_assoc($res)) {
if ( client!=null && $row['customerNumber'] == $client){
echo '<option value ="'.$row['customerNumber'].'" selected="selected">'.$row['customerName'].'</option>';
} else {
echo '<option value ="'.$row['customerNumber'].'">'.$row['customerName'].'</option>';}}
?>
</select><input type="submit" value="Ok">
</form>
<DIV>
<?PHP}
mysql_close($conn);}
?>

Nous devons alors avoir le formulaire ci-dessous :

IV-C-3 - Utilisation de BIRT Viewer

Maintenant la partie permettant de soumettre la bonne URL. Nous allons ici utiliser sept variables sous PHP.

Variable

Description

report

Nom de l'état « .rptdesign »

host

Nom de la machine ou adresse IP

port

Port du serveur sur lequel se trouve l'application

mode

Le type de servlet utilisé au niveau du Viewer de BIRT

war

Le nom de l'archive utilisée

param

La liste des paramètres transmis dans l'URL

dest

L'URL complète

Le code associé sera comme ci-dessous :

Iframe PHP

<?PHP
$report = "int-php.rptdesign";
$host = "localhost";
$port = "8080";
$mode ="run";
$war = "birtV2_3_0";
$param="&client=$client&__agentstyle=true";
// Redirect browser
$dest = "http://$host:$port/$war/$mode?__report=$report".$param;
?>
<DIV>
<?php
echo '<iframe frameborder="0" width="410px" height="210px" src="';
if ($client!=null ){
echo $dest;
}else{ echo "#";}
echo '"></iframe>';
?>
</DIV>

IV-D - Méthode avec utilisation d'une balise DIV

Dans le premier cas, nous avons utilisé le Viewer de BIRT. Dans le second nous souhaitons mettre en place le même état, mais en faisant appel à une version personnalisée de BIRT l'archive reporting.war afin de pouvoir supprimer les balises HTML et BODY du corps de la page.

Cette manipulation est impossible avec la seule utilisation du Viewer de BIRT et demande une implémentation de l'API de BIRT.

Nous ne rentrerons ici pas dans les détails sur toute la mise en œuvre de l'API de BIRT, nous ne spécifierons ici que le paramètre à passer dans l'URL à savoir __embedded. Nous aurons donc la liste des attributs suivants :

Attributs

Description

__report

Nom de l'état « .rptdesign »

__format

Format de sortie HTML, PDF et XLS, par défaut HTML

__embedded

Présence des balises HTML et BODY (false par défaut sinon true)

IV-D-1 - Schéma

Voir annexe.

IV-D-2 - Mise en place du formulaire de saisie

Cette partie reste inchangée.

IV-D-3 - Comment appeler la Servlet

Ici nous allons utiliser le code suivant :

DIV PHP

<?PHP
$report = "int-php";
$host = "localhost";
$port = "8080";
$mode ="osspartner";
$war = "reporting";
$param="&client=$client&__embedded=true";
// Redirect browser
$dest = "http://$host:$port/$war/$mode?__report=$report".$param;
?>
<DIV class="frame">
<?php
$r = fopen($dest, "r" );
$contents = '';
if ($r){
while (!feof($r)) {
$contents.=fread($r, 8192);}
fclose($r);
echo $contents;
} else {
}?>
</DIV>

Ce code va tout simplement injecter dans la page HTML, le code HTML renvoyé par l'appel de l'URL. À l'arrivée nous obtenons le rendu comme précédemment, mais sans les bordures de la Frame.

Il faut noter que cette méthode ne fait que réinjecter le code HTML renvoyé par l'appel d'une URL.

Avec le DIV l'image est directement intégrée dans la page, vous n'aurez plus aucune bordure et donc l'illusion que votre reporting vient de PHP et non Java. Par contre, nous n'avons pas traité le cas des erreurs.

IV-E - Méthode avec utilisation d'une balise DIV et utilisation du Framework AJAX

Il s'agit là de la dernière méthode mise en œuvre, attention celle-ci ne marche qu'avec le navigateur Internet Explorer.

Avec AJAX, il n'est pas permis de faire directement appel à une URL dont la racine est différente de la première. Or, ici il y a l'URL de Jboss et celle de PHP. Internet Explorer est plus permissif que les autres navigateurs, il est d'ailleurs le seul sur lequel la méthode marche.

IV-E-1 - Schéma

Voir annexe.

IV-E-2 - Mise en place du formulaire de saisie

Cette partie reste inchangée.

IV-E-3 - Comment appeler la servlet

Le principe est le même que pour les étapes précédentes, il faut donc dans un premier temps construire l'URL d'appel avant d'utiliser la fonction Javascript.

AJAX PHP

<?PHP
$report = "int-php";
$host = "localhost";
$port = "8080";
$mode ="osspartner";
$war = "reporting";
$param="&client=$client&__embedded=true";
// Redirect browser
$dest = "http://$host:$port/$war/$mode?__report=$report".$param;
?>
<DIV id="zone" class="frame">
<SCRIPT>
window.onload=phpAJAX(<?PHP echo "'".$dest."'"?>,'zone');
</SCRIPT>
</DIV>

IV-E-4 - Utilisation de Javascript et AJAX

Pour la fonction Javascript il vous suffit de reprendre le code suivant :

Fonction Javascript

function phpAJAX(dest,zone){
var xhr;
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
}catch (e){
try {xhr = new ActiveXObject('Microsoft.XMLHTTP');
}catch (e2){
try {xhr = new XMLHttpRequest();
}catch (e3) {
xhr = false;}
}}
xhr.onreadystatechange = function() {
switch(xhr.readyState){
case 0:
document.getElementById(zone).innerHTML = '<img src="../images/timeout.gif" width="100px" height="100px">';
break;
case 1:
document.getElementById(zone).innerHTML = '<img src="../images/timeout.gif" width="100px" height="100px">';
break;
case 2:
document.getElementById(zone).innerHTML = '<img src="../images/timeout.gif" width="100px" height="100px">';
break;
case 3:
document.getElementById(zone).innerHTML = '<img src="../images/timeout.gif" width="100px" height="100px">';
break;
case 4:
if(xhr.status == 200){
document.getElementById(zone).innerHTML = xhr.responseText;
}else{
document.getElementById(zone).innerHTML = xhr.responseText;}
break;
default:}
};
xhr.open('GET',dest,true);
xhr.send(null);
}

Pour simuler la progression entre le l'appel de l'URL et la réponse une GIF animée est utilisée.

IV-E-5 - Utilisation de Jquery

Il existe des bibliothèques Javascript telles que JQuery et l'appel à la fonction Javascript se réduit à une ligne. Pour cela, il suffit de télécharger la bibliothèque à l'adresse suivante http://jquery.com/.

JQuery

$.ajax({
type: "GET",
url: "<?PHP echo $dest; ?>"
});

V - Conclusion

Ce tutoriel est assez simple et montre avec quelle facilité vous pouvez exploiter les ressources de l'outil de reporting BIRT dans votre applicatif PHP. Bien entendu, cette méthode peut être étendue à tout applicatif basé sur une URL tel qu'un Web Service par exemple. La seule difficulté c'est qu'il vous faut transposer la saisie des paramètres via un formulaire HTML dans votre PHP.

VI - Annexe

VI-A - BIRT

VI-A-1 - Fichier properties

Fichier : birt.properties

birt.viewer.2.3.0.working.folder=${jboss.server.home.dir}/data/birt/report
birt.viewer.2.3.0.document.folder=${jboss.server.home.dir}/data/birt/resource
birt.viewer.2.3.0.image.dir=${jboss.server.home.dir}/data/birt/report/images
birt.viewer.2.3.0.log.dir=${jboss.server.home.dir}/log/birt
birt.viewer.2.3.0.scriptlib.dir=${jboss.server.home.dir}/data/birt/scriplib
birt.viewer.2.3.0.resource.path=${jboss.server.home.dir}/data/birt/resource

VI-A-2 - Implémentation de l'API de BIRT

Fichier web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>

<display-name>reporting</display-name>

...

<!-- BIRT SERVLET -->
<servlet>
<servlet-name>birt</servlet-name>
<servlet-class>corp.capgemini.osspartner.birt.WebReport</servlet-class>
</servlet>

...

<servlet-mapping>
<servlet-name>birt</servlet-name>
<url-pattern>/birt</url-pattern>
</servlet-mapping>
...

</web-app>

Classe WebReport.java

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.birt.report.engine.api.HTMLRenderOption;
import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;
import org.eclipse.birt.report.engine.api.IGetParameterDefinitionTask;
import org.eclipse.birt.report.engine.api.IParameterDefnBase;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.IScalarParameterDefn;
import org.eclipse.birt.report.engine.api.PDFRenderOption;

public class WebReport extends HttpServlet {

/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Constructor of the object.
*/
private IReportEngine birtReportEngine = null;
protected static Logger logger = Logger.getLogger("org.eclipse.birt");

public WebReport() {
super();
}

public void init() throws ServletException {
BirtEngine.initBirtConfig();

}

public void destroy() {
super.destroy();
// BirtEngine.destroyBirtEngine();
}

/**
* The doGet method of the servlet.
*
*
*/
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

/**
* TRAITEMENT PARAMETRE : __format __report __embedded
*/

String __format = req.getParameter("__format");
String __report = req.getParameter("__report");
String __embedded = req.getParameter("__embedded");

// format
if (__format != null && __format.equalsIgnoreCase("pdf")) {
__format = "pdf";
} else {
__format = "html";
}

// embedded
if (__embedded != null && __embedded.equalsIgnoreCase("false")) {
__embedded = "false";
} else {
__embedded = "true";
}

/**
*
*/
ServletContext sc = req.getSession().getServletContext();
this.birtReportEngine = BirtEngine.getBirtEngine(sc);

IReportRunnable design;
try {

/**
* ouverture rptdesign
*/
design = birtReportEngine.openReportDesign(sc
.getRealPath("/report")
+ "/" + __report + ".rptdesign");

if (design != null) {

// create task to run and render report
/**
* creation d'une tache run&render
*/
IRunAndRenderTask task = birtReportEngine
.createRunAndRenderTask(design);
if (task != null) {

/**
* Parameters
*/
IGetParameterDefinitionTask params = birtReportEngine
.createGetParameterDefinitionTask(design);

Object tmpParam;
if (params != null) {

Iterator iter = params.getParameterDefns(true)
.iterator();
while (iter.hasNext()) {

IParameterDefnBase parameterDefnBase = (IParameterDefnBase) iter
.next();
switch (parameterDefnBase.getParameterType()) {

case IParameterDefnBase.SCALAR_PARAMETER:

IScalarParameterDefn scalarParsmeterDefn = (IScalarParameterDefn) parameterDefnBase;

switch (scalarParsmeterDefn.getDataType()) {

// INTEGER
case IScalarParameterDefn.TYPE_INTEGER:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

// search value
if (tmpParam != null
&& !tmpParam.equals("")) {
tmpParam = Integer
.parseInt((String) tmpParam);

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);
}
// set default value
else {

tmpParam = Integer.parseInt(params
.getParameterValue(
scalarParsmeterDefn
.getName())
.toString());

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

}

break;
// FLOAT
case IScalarParameterDefn.TYPE_FLOAT:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {
tmpParam = Float
.parseFloat((String) tmpParam);

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

} else {

tmpParam = Float.parseFloat(params
.getParameterValue(
scalarParsmeterDefn
.getName())
.toString());

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

}

// TODO
break;
// BOOLEAN
case IScalarParameterDefn.TYPE_BOOLEAN:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {
tmpParam = Boolean
.parseBoolean((String) tmpParam);

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

} else {

tmpParam = Boolean.parseBoolean(params
.getParameterValue(
scalarParsmeterDefn
.getName())
.toString());

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

}

// TODO
break;
// DATE
case IScalarParameterDefn.TYPE_DATE:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {

tmpParam = Boolean
.parseBoolean((String) tmpParam);

} else {

}

// TODO
break;
// DATE TIME
case IScalarParameterDefn.TYPE_DATE_TIME:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {

} else {

}

// TODO
break;
// TIME
case IScalarParameterDefn.TYPE_TIME:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {

} else {

}

// TODO
break;
// STRING
case IScalarParameterDefn.TYPE_STRING:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {

task.setParameterValue(
parameterDefnBase.getName(),
tmpParam);

} else {

}

// TODO
break;
// ANY
case IScalarParameterDefn.TYPE_ANY:

tmpParam = req
.getParameter(scalarParsmeterDefn
.getName());

if (tmpParam != null
&& !tmpParam.equals("")) {

} else {

}

// TODO
break;
// STRING
default:
// TODO
break;
}

break;
/**
* IParameterGroupDefn
*/
case IParameterDefnBase.PARAMETER_GROUP:

break;
/**
* ICascadingParameterGroup
*/
case IParameterDefnBase.CASCADING_PARAMETER_GROUP:

break;
/**
*
*/
case IParameterDefnBase.LIST_PARAMETER:

break;
/**
*
*/
case IParameterDefnBase.TABLE_PARAMETER:

break;
/**
*
*/
default:

break;

}

}
}

/**
* PDF
*/
if (__format.equalsIgnoreCase("pdf")) {
PDFRenderOption optionPDF = new PDFRenderOption();
optionPDF
.setOutputFormat(PDFRenderOption.OUTPUT_FORMAT_PDF);
optionPDF.setOutputStream(resp.getOutputStream());
task.setRenderOption(optionPDF);
}
/**
* HTML
*/
else {
HTMLRenderOption optionHTML = new HTMLRenderOption();
// set the image handler to a
// HTMLServerImageHandler if you plan on using
// the base image url.
optionHTML
.setImageHandler(new HTMLServerImageHandler());
optionHTML
.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML);
// options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF);
optionHTML.setOutputStream(resp.getOutputStream());
optionHTML.setBaseImageURL(req.getRequestURL()
+ "/images");
optionHTML.setImageDirectory(sc
.getRealPath("/birt/images"));

//
optionHTML.setEmbeddable(new Boolean(__embedded));
task.setRenderOption(optionHTML);
}
task.run();
task.close();

} else {
/**
* TODO
*/
}

} else {
/**
* TODO
*/
}

if (__format.equalsIgnoreCase("pdf")) {
resp.setContentType("application/pdf");
resp.setHeader("Content-Disposition", "inline; filename="
+ __report + ".pdf");
}
/**
* HTML
*/
else {
resp.setContentType("text/html");
}
// get report name and launch the engine

} catch (Exception e) {

e.printStackTrace();
throw new ServletException(e);
}
}

/**
* The doPost method of the servlet.
*
*
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html");
PrintWriter out = response.getWriter();
out
.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println("  <BODY>");
out.println(" Post Not Supported");
out.println("  </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}

}

VI-B - Jboss

VI-B-1 - Comment rendre accessible votre serveur Jboss au réseau

Pour rendre accessible le serveur Jboss sur le réseau c'est-à-dire une adresse autre que localhost, il suffit d'ajouter au lancement du serveur l'option -b 0.0.0.0.

VI-C - Schéma de l'architecture mise en place

VI-C-1 - IFrame

VI-C-2 - DIV

VI-C-3 - AJAX

VI-D - Références

Quelques références utiles :

- Integrating and Extending BIRT Second Edition ;

- BIRT A Field Guide to Reporting Second Edition ;

- Exemple de servlet;

- Jquery.

VI-E - Remerciements

Tout d'abord, je voulais remercier Adrien Artero qui m'a poussé à rejoindre l'équipe BI des forums developpez.com et m'a conduit à écrire ce tutoriel. Ensuite, il y a mon Manager Jean Guillaume Lalanne qui a fait en sorte que ce tutoriel à la base confidentiel puisse être diffusé à la communauté open source. Bien entendu, il y a toute l'équipe BI qui apporte des suggestions afin d'améliorer ce tutoriel pour que celui-ci soit plus facile d'accès aux utilisateurs.