Erreur “No Factories configured for this Application”

Lors de l’installation de l’application sur un nouveau poste, Tomcat plantait avec l’erreur suivante :

[java] java.lang.IllegalStateException: No Factories configured for this Application.
This happens if the faces-initialization does not work at all - make sure that you properly include
all configuration settings necessary for a basic faces application and that all the necessary libs are included.
Also check the logging output of your web application and your container for any exceptions!
[java] If you did that and find nothing, the mistake might be due to the fact that you use some special web-containers
which do not support registering context-listeners via TLD files and a context listener is not setup in your web.xml.

[java] A typical config looks like this;
[java] <listener>

[java] <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
[java] </listener>

Comme indiqué dans le message d’erreur lui-même, il a fallu ajouter ce listener dans le fichier web.xml :

<listener>
<listener-class>
org.apache.myfaces.webapp.StartupServletContextListener
</listener-class>
</listener>

Par contre je ne sais pas pourquoi le problème ne s’est pas produit sur les précédentes installations…

Powered by ScribeFire.

Affichage optionnel selon le type d’utilisateur

MonDossierWeb doit, dans le menu du Dossier (etat-civil, adresses, inscriptions etc..), afficher un lien pour retourner à la page d’accueil dans le cas où l’utilisateur est un enseignant. En effet, quand un enseignant consulte le dossier d’un étudiant il doit à tout moment pouvoir revenir à sa page d’accueil.

Pour cela nous avons tout d’abord créé un lien vers le dossier etudiant depuis la page d’accueil enseignant(pour pouvoir tester après). Ensuite nous avons insérer le code suivant dans le bean sessionController:

public boolean isEnseignant(){
boolean b=false;
if(typeUser().equals(“enseignant”)){
b=true;
}
return b;
}

La méthode typeUser() retourne “enseignant”, “etudiant” ou “”. Ainsi cette méthode isEnseignant nous retourne ‘true’ si l’utilisateur est un enseignant , ‘false’ sinon.

Ensuite il ne reste qu’à insérer le code suivant dans le template-menu.xhtml qui est notre template facelets représentant le menu de MonDossierWeb:

<h:commandLink id=”link” action=”navigationIndexEns” rendered=”#{sessionController.enseignant}”>
Retour au sommaire
</h:commandLink>

Il faut bien sur posséder la règle de navigation jsf “navigationIndexEns” qui renvoit vers la page d’accueil de l’enseignant. Ainsi, si isEnseignant() retourne ‘true’ le lien sera affiché (il sera rendu, “rendered”).

A noter que l’EL de l’attribut ‘rendered’ est ‘nomBean.enseignant’ et non pas ‘nomBean.isEnseignant’ car comme il attend une valeur booléenne jsf va automatiquement aller chercher la méthode isNomAttribut dans le bean.

Creation d’un fichier excel retourné (servlet)

Après les tests pour générer du pdf, MonDossierWeb doit générer des fichier excel, nous avons testé POI. Apres quelques essais nous avons réussi à obtenir le résultat voulu grâce à la librairie POI. Voici comment sont implantées les choses :

Tout d’abord il faut penser à importer la librairie poi-2.5.1-final-20040804.jar disponible ici dans le projet.

Puis, dans notre Controller qui contient (en attribut : nne, nom, dossier, annee etc.) les informations affichées à l’écran, nous ajoutons la méthode exportExcel():

public String exportExcel(){

FacesContext context = FacesContext.getCurrentInstance();
ExternalContext external = context.getExternalContext();
HttpServletResponse response = (HttpServletResponse) external.getResponse();

//formatage de la réponse
response.setContentType(“application/octet-stream”);
response.setHeader (“Content-Disposition”, “attachment; filename=\”test.xls\”" );
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);

//creation du fichier excel
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(“etat-civil” );

//formatage taille de la premiere colonne
sheet.setColumnWidth((short)0,(short)(20*256));

// Creation des colonnes
HSSFRow row = sheet.createRow((short)0);
HSSFRow row1 = sheet.createRow((short)1);
HSSFRow row2 = sheet.createRow((short)2);
HSSFRow row3 = sheet.createRow((short)3);
HSSFRow row4 = sheet.createRow((short)4);
HSSFRow row5 = sheet.createRow((short)5);
HSSFRow row6 = sheet.createRow((short)6);
HSSFRow row7 = sheet.createRow((short)7);

//CREATION DES STYLES:
//STYLE1:

HSSFCellStyle headerStyle = wb.createCellStyle();
headerStyle.setFillBackgroundColor((short) HSSFColor.DARK_RED.index);
headerStyle.setFillForegroundColor(HSSFColor.DARK_RED.index);
headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFFont font = wb.createFont();
font.setColor(HSSFColor.WHITE.index);
font.setBoldweight((short) 10);
headerStyle.setFont(font);
//bordure style1
headerStyle.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
headerStyle.setBottomBorderColor(HSSFColor.BLACK.index);
headerStyle.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
headerStyle.setLeftBorderColor(HSSFColor.BLACK.index);
headerStyle.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
headerStyle.setRightBorderColor(HSSFColor.BLACK.index);
headerStyle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
headerStyle.setTopBorderColor(HSSFColor.BLACK.index);

//STYLE2:
HSSFCellStyle headerStyle2 = wb.createCellStyle();
headerStyle2.setFillBackgroundColor((short) HSSFColor.BLUE.index);
headerStyle2.setFillForegroundColor(HSSFColor.BLUE.index);
headerStyle2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
headerStyle2.setFont(font);
//bordure style2
headerStyle2.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
headerStyle2.setBottomBorderColor(HSSFColor.BLACK.index);
headerStyle2.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
headerStyle2.setLeftBorderColor(HSSFColor.BLACK.index);
headerStyle2.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
headerStyle2.setRightBorderColor(HSSFColor.BLACK.index);
headerStyle2.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
headerStyle2.setTopBorderColor(HSSFColor.BLACK.index);

//Creation des cellules
HSSFCell cellLib = row.createCell((short) 0);
cellLib.setCellStyle(headerStyle);
cellLib.setCellValue(“ETAT-CIVIL” );

HSSFCell cellLib2 = row1.createCell((short) 0);
cellLib2.setCellStyle(headerStyle2);
cellLib2.setCellValue(“GENERALITES” );

row2.createCell((short)0).setCellValue(“Dossier “);
row2.createCell((short)1).setCellValue(dossier);
row3.createCell((short)0).setCellValue(“NNE “);
row3.createCell((short)1).setCellValue(nne);
row4.createCell((short)0).setCellValue(“Nom “);
row4.createCell((short)1).setCellValue(nom);

HSSFCell cellLib3 = row5.createCell((short) 0);
cellLib3.setCellStyle(headerStyle2);
cellLib3.setCellValue(“INSCRIPTION UNIVERSITAIRE” );

row6.createCell((short)0).setCellValue(“Anee “);
row6.createCell((short)1).setCellValue(annee);
row7.createCell((short)0).setCellValue(“Etablissement “);
row7.createCell((short)1).setCellValue(etablissement);

//FUSION des CELLULES:
Region reg=new Region(0,(short)0,0,(short)2);
Region reg2=new Region(1,(short)0,1,(short)2);
Region reg3=new Region(5,(short)0,5,(short)2);
sheet.addMergedRegion(reg);
sheet.addMergedRegion(reg2);
sheet.addMergedRegion(reg3);

// Ecriture dans l’output
ServletOutputStream out;
try {
out = response.getOutputStream();
wb.write(baos);
baos.writeTo(out);
baos.flush();
context.responseComplete();
} catch (IOException e) {

e.printStackTrace();
}
return null;
}

Enfin, il ne reste plus qu’à ajouter un lien dans notre page xhtml, qui va nous proposer d’enregistrer le pdf généré:

<h:commandLink id=”link” action=”#{controller.exportExcel}”>
EXCEL

</h:commandLink>

Ainsi, en cliquant sur le lien ‘EXCEL’ vous aurez l’invitation suivante :

InvitationExcel

Il ne reste plus qu’à enregistrer le fichier. Voir le resultat

 

 

Redirection depuis l’accueil selon le type utilisateur

Notre application ayant des interfaces et donc des fonctionnalités différentes selon le type de l’utilisateur (etudiant ou enseignant) nous allons créer une page d’accueil qui lancera automatiquement la méthode d’un bean (par exemple la méthode accueil du bean sessionController) redirigeant vers la bonne page d’accueil ( une pour chaque type d’utilisateur) selon le type de l’utilisateur.

Il y a deux méthodes possibles suivant si on utilise ou pas les possibilités offertes par le composant JSF onload.

Voici la première, sans utiliser le composant onload :

Tout d’abord, on ajoute la méthode accueil() au bean sessionController. Cette méthode teste le type de l’utilisateur, puis revoit “pageAccueilType1″ ou “pageAccueilType2″ :

public String accueil() {

type=recupérationTypeUtilisateur();

si (type==type1){

return “pageAccueilType1″;

}else{

si(type==type2){

return “pageAccueilType2″;

}else{

return “error”;

} } }

Ensuite, après avoir créer les différentes pages d’accueil, il faut ajoute les liens de navigation dans le fichier de configuration jsf (dans notre cas navigation-rules.xml):

<navigation-case>
<from-outcome>pageAccueilType1</from-outcome>
<to-view-id>/stylesheets/type1/index.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>pageAccueilType2</from-outcome>
<to-view-id>/stylesheets/type2/index.xhtml</to-view-id>
</navigation-case>

Il ne reste plus qu’à modifier votre page d’accueil d’origine (param default-view dans le web.xml) pour y mettre le code suivant:

<h:form id=”formAccueil”>
<h:commandLink type=”submit” id=”idtest” action=”#{sessionController.accueil}”>
<h:outputText value=”mon_texte”/>
</h:commandLink>
</h:form>

<script type=”text/javascript”>

var myLink = document.getElementById(‘formAccueil:idtest’);
myLink.onclick();

</script>

ainsi, dès de chargement de la page d’accueil basique on lancera la méthode accueil() qui redirigera vers le bon index.xhtml

Voici la deuxième méthode (à préférer à la précédente) en utilisant le composant onload:

Il faut effectuer les mêmes étapes que précédamment excepté la dernière. Au lieu d’ajouter du code javascript pour lancer la méthode de notre bean nous allons utiliser les propriétés du composant onload (index.xhtml sera donc vide). Il suffit alors de rajouter dans le onload.xml:

<navigation-rule>
<view-id>/stylesheets/index.faces</view-id>
<action>#{sessionController.accueil}</action>
</navigation-rule>

Ainsi avant chaque accès à la page index.xhtml, on passe par la méthode accueil du bean sessionController, qui (comme elle ne renvoit jamais “null”) renvoit vers une autre page (voir le descriptif de la méthode ci-dessus). A noter qu’au lieu de retourner vers la page d’erreur en cas de non-identification de l’utilisateur, il est peut-être préférable de le rediriger vers une page de login l’invitant à s’identifier (ou une page d’erreur ayant un lien vers la page de login).

Génération d’un PDF retourné (servlet) :

Le futur MonDossierWeb (Facelets) aura besoin de reprendre les fonctionnalités de l’ancien canal MonDossierWeb ; comme la génération en pdf des informations affichées à l’écran. Apres quelques essais nous avons réussi à obtenir le résultat voulu grâce à la librairie iText. Voici comment sont implantées les choses :

Tout d’abord il faut penser à importer la librairie itext-2.0.1.jar disponible ici dans le projet.

Puis, dans notre Controller qui contient (en attribut : nne, nom, dossier, annee etc.) les informations affichées à l’écran, nous ajoutons la méthode export() :

 

public String export() {

try {

FacesContext context = FacesContext.getCurrentInstance();

ExternalContext external = context.getExternalContext();

HttpServletResponse response = (HttpServletResponse) external.getResponse();

response = configureResponse(response , “TEST PDF”);

// création du document.

Document document = new Document(PageSize.A4,10,10,20,20);

// Document d = new Document(PageSize.A4); //portrait

// Document d = new Document(PageSize.A4.rotate()); //paysage

// configuration du document

document = configureDocument(11.5f, 14f, 0.5f);

// redirection du pdf.

ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);

PdfWriter writer = PdfWriter.getInstance(document, baos);

writer.setStrictImageSequence(true);

// ouverture du document.

document.open();

// configuration des fonts

Font normal = FontFactory.getFont(FontFactory.TIMES_ROMAN, 8, Font.NORMAL);

Font titre = FontFactory.getFont(FontFactory.TIMES_ROMAN, 10, Font.NORMAL);

Font header = FontFactory.getFont(FontFactory.TIMES_ROMAN, 12, Font.BOLD);

//ajout image test

Image image1 = Image.getInstance(“http://www.univ-nancy2.fr/images/logo_nu_n2.gif”);

image1.scaleAbsolute(100, 20);

document.add(image1);

//nouveau paragraphe

Paragraph p=new Paragraph(“ETAT CIVIL\n\n”,header);

p.indentationLeft();

document.add(p);

//paragraphe GENERALITES

Chunk c1=new Chunk(“GENERALITES: “, titre);

c1.setBackground(Color.cyan);

Chunk c2=new Chunk(“\nDossier : “+dossier,normal);

Chunk c3=new Chunk(“\nNNE : “+nne,normal);

Chunk c4=new Chunk(“\nNom : “+nom,normal);

Paragraph p1=new Paragraph();

p1.add(c1);p1.add(c2);p1.add(c3);p1.add(c4);

document.add(p1);

//paragraphe INSCRIPTION UNIVERSITAIRE

Chunk c5=new Chunk(“INSCRIPTION UNIVERSITAIRE: “, titre);

c5.setBackground(Color.cyan);

Chunk c6=new Chunk(“\nAnnee : “+annee,normal);

Chunk c7=new Chunk(“\nEtablissement : “+etablissement,normal);

Paragraph p2=new Paragraph();

p2.add(c5);p2.add(c6);p2.add(c7);

document.add(p2);

//paragraphe BAC

Chunk c8=new Chunk(“BAC: “, titre);

c8.setBackground(Color.cyan);

Chunk c9=new Chunk(“\nBac : “+bac,normal);

Chunk c10=new Chunk(“\nObtenu en : “+anneeobtentionbac,normal);

Paragraph p3=new Paragraph();

p3.add(c8);p3.add(c9);p3.add(c10);

document.add(p3);

// fermeture du document.

document.close();

// préparation de la reponse

response.setContentLength(baos.size());

// retour du ByteArrayOutputStream en ServletOutputStream

ServletOutputStream out = response.getOutputStream();

baos.writeTo(out);

baos.flush();

context.responseComplete();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

Vous aurez remarqué que la méthode export appelle les deux méthodes suivantes, qu’il faut donc implémenter dans le Controller:

private HttpServletResponse configureResponse(HttpServletResponse response, String fileName) {

response.setHeader(“Expires”, “0″);

response.setHeader(“Cache-Control”, “must-revalidate, post-check=0, pre-check=0″);

response.setHeader(“Pragma”, “public”);

response.setContentType(“application/pdf”);

response.addHeader(“Content-disposition”, “attachment; filename=\”" + fileName +”.pdf\”");

return response;

}

private Document configureDocument(float width, float height, float margin) {

Document document = new Document();

float widhtPage = (width / 2.54f) * 72f;

float heightPage = (height / 2.54f) * 72f;

document.setPageSize(new Rectangle(widhtPage,heightPage));

float marginPage = (margin / 2.54f) * 72f;

document.setMargins(marginPage, marginPage, marginPage, marginPage);

return document;

}

 

Enfin, il ne reste plus qu’à ajouter un lien dans notre page xhtml, qui va nous proposer d’enregistrer le pdf généré:

<h:commandLink id=”pdfLink” action=”#{Controller.export}”>

PDF

</h:commandLink>

Ainsi, en cliquant sur le lien ‘PDF’ vous aurez l’invitation suivante :

pdfSaveAs

 

 

 

 

 

Il ne reste plus qu’à enregistrer le pdf et voilà, le tour et joué. Voir le résultat.

Il reste maintenant à obtenir le même résultat en mode portlet, car vous aurez remarqué qu’on le sert de l’objet HttpServletResponse pour retourner le pdf.

Comment modifier l’emplacement de la page par défaut dans esup-commons

Par défaut, une application esup-commons accède à la page /stylesheets/welcome.faces
Ceci est définit dans la classe FacesServlet avec les variables DEFAULT_VIEW_PARAM et DEFAULT_DEFAULT_VIEW

Mais il a été aussi prévu la possibilité de modifier cette page par défaut en modifiant le paramètre “default-view” d’initialisation de la servlet.

Pour cela, modifier le web.xml comme dans cet exemple :

<servlet>
<description>
The main servlet of the application. This class inherits from the MyFaces implementation and handles exceptions thrown for specific exception handling.
</description>
<display-name>Faces Servlet</display-name>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>
org.esupportail.commons.web.servlet.FacesServlet
</servlet-class>
<init-param>
<param-name>default-view</param-name>
<param-value>/stylesheets/etu/welcome.faces</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet>

En prime, un lien intéressant sur les servlets

Les droits d’accès dans l’application

Actuellement le canal DossierWeb est décliné pour 2 usages :

  • la partie visible par chaque étudiant sachant bien qu’un étudiant ne peut voir que son propre dossier
  • la partie visible aux enseignants et aux personnels qui peuvent consulter le dossier de tous les étudiants

Pour la partie enseignants/personnels nous faisons actuellement un double test :

  • la personne appartient-elle à un groupe uPortal précisé en configuration?
  • si non, la personne possède-t-elle un compte actif dans Apogée? Cela fonctionne si et seulement si les logins LDAP et Apogée sont identiques

Actuellement le contrôle d’accès à l’un de ces modules est fait très simplement :

  • il y a deux channels uPortal : l’une pour les étudiants et l’autre pour les enseignants
  • la channel enseignant utilise la channel étudiant en mode servant
  • la channel enseignant est réservée au profil personnel et affichera un message d’erreur si l’utilisateur n’est pas autorisé

Dans le cadre de la migration vers esup-commons, MonDossierWeb pourra être déployé en servlet ou portlet et la problématique de gestion des accès est plus compliquée car il faut empêcher tout accès aux pages réservées aux enseignants par des étudiants qui en connaitraient les URLs

A priori nous aurons une arborescence pour les pages découpées en deux sou-répertoires : ens et etu

Plusieurs solutions s’offrent à nous pour la gestion des droits d’accès aux différentes pages :

  • le mécanisme d’esup-commons mais qui implique l’utilisation des tags qui ne sont pas pour l’instant compatible avec facelets
  • l’utilisation d’acegi, module puissant mais complexe à mettre en oeuvre compte-tenu de nos besoins assez simples. Des composants JSF pour Acegi existent déjà : acegi-jsf. Acegi bénéficie toutefois d’une excellente intégration avec Spring et CAS.
  • l’utilisation d’un composant JSF onload qui s’appuie sur le mécanisme des PhaseListener qui permettent de placer des hooks sur les évenements JSF de rendu des pages et donc, par exemple, de faire des contrôles préalables à tout affichage pour vérifier que l’utilisateur a bien accès

Il est donc maintenant nécessaire d’approfondir la question et notamment :

  • parmi ces 3 possibilités, laquelle est la plus adaptée à notre contexte
  • comment tester l’appartenance d’un utilisateur à un groupe uPortal
  • comment, une fois l’utilisateur ayant été identifié par CAS, alimenter un bean qui stockera des informations sur :
    • son profil : enseignant ou étudiant
    • le code étudiant

Un point sur les facelets et JSF

Pour mener à terme le développement de MonDossierWeb en portlet , plusieurs questions se posent:

-Est-il possible de faire marcher les tags ADF (la librairie de tag d’Oracle) en facelets?

-Comment avoir un système de template qui fonctionne pour portlet et servlet?

-Peut-on faire sans les tags esup utilisés dans esup-example ?

-Peut-on faire un Look-and-feel proche de l’original?

-Comment peut-on générer des fichiers pdf et excel sans passer par le xsl comme c’était le cas dans MonDossierWeb jusqu’ici?

Voici, pour l’instant, où en est notre réflexion :

-Est-il possible de faire marcher les tags ADF (la librairie de tag d’Oracle) en facelets ?

Sur ce point, il n’y a aucun problème car il existe une librairie (adf-facelets.jar) qui fournie les tags ADF pour facelets. Nous ne l’avons pas encore testée mais nous le ferons d’ici peu. Voici un lien qui en explique rapidement le fonctionnement : lien

 

-Comment avoir un système de template qui fonctionne pour portlet et servlet?

Cette question est primordiale et voici comment nous avons pensé la résoudre : Chaque page xhtml se compose de la manière suivante :

<div xmlns:h=”http://java.sun.com/jsf/html”

xmlns:e=”http://commons.esup-portail.org”

xmlns:ui=”http://java.sun.com/jsf/facelets”>

<ui:composition template=”template.xhtml”>

<ui:define name=”body”>

[CODE DE LA PAGE]

</ui:define>

</ui:composition>

</div>

De cette façon il suffit de modifier le ‘template.xhtml’ pour qu’il corresponde aux servlets (avec balise <html>) ou aux portlets (sans balise <html>). Nous avons donc créé deux templates (template-servlet.xhtml et template-portlet.xhtml) et il suffit de copier celui désiré en ‘template.xhtml’.

Voici un exemple basique (ce n’est pas le template final qui affiche le menu de la portlet) du template-servlet.xhmtl :

 

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html xmlns=”http://www.w3.org/1999/xhtml”

xmlns:ui=”http://java.sun.com/jsf/facelets”

xmlns:h=”http://java.sun.com/jsf/html”

xmlns:f=”http://java.sun.com/jsf/core”>

<head>

<title><ui:insert name=”pageTitle”>MonDossierWeb</ui:insert></title>

</head>

<body>

<p><ui:insert name=”body”>Page Body</ui:insert></p>

</body>

</html>

 

Et voici maintenant un exemple de template-portlet.xhtml

 

<div xmlns:h=”http://java.sun.com/jsf/html”

xmlns:e=”http://commons.esup-portail.org”

xmlns:ui=”http://java.sun.com/jsf/facelets”>

<h1><ui:insert name=”pageHeader”>MonDossierWeb</ui:insert></h1>

<p><ui:insert name=”body”>Page Body</ui:insert></p>

</div>

 

-Peut-on faire sans les tags esup utilisés dans esup-example ?

Pour savoir si il était possible de faire sans les tags esup (qui sont des tag jsf, donc difficilement utilisables en facelets) nous les avons listés et pour chacun d’eux, nous avons défini son rôle afin de déterminer si il nous était utile et si c’était le cas, si nous pouvions nous arranger pour obtenir le même résultat par un moyen détourné.

Il s’est avéré que la plupart d’entre eux sont effectivement utiles mais qu’il est possible d’obtenir le même résultat avec des tags ‘normaux’ html. Le seul qui soit vraiment compliqué est le tag ‘page’ qui initialise un certain nombre de paramètres. Peut-être devrons nous créer notre tag facelets qui fait la même chose…

 

-Peut-on faire un Look-and-feel proche de l’original?

Comme MonDossierWeb est à l’origine basé sur du xsl, il est tout à fait possible de récupérer les tags html de ces fichiers, et comme le css de uportal ne change pas cela fonctionne très bien. On peut donc, en changeant quelques tags qui ne fonctionnent pas en facelets bien sur, notamment pour afficher les attributs d’une classe, obtenir un rendu quasi identique à l’application de départ. En voici la preuve après une après midi de test de mise au point des templates :

lookANdFeel1

 

Le rendu est effectivement très proche de l’original.

 

-Comment peut-on générer des fichiers pdf et excel sans passer par le xsl comme c’était le cas dans la MonDossierWeb jusqu’ici?

Sur ce point rien n’est encore défini car s’il est vrai que l’on peut facilement créer des fichiers excel et pdf en java, est-il possible de le faire depuis le rendu html de notre page pour le retourner ensuite à l’utilisateur. Nous allons nous pencher sur JFree qui est une librairie java qui permet de faire des sorties pdf et excel en se basant sur du xml.

Introduction aux facelets : Installation

Après la rapide présentation des facelets de vendredi, voici un tutoriel qui explique comment utiliser les facelets, et notamment comment incorporer un petit exemple de facelet au sein d’esup-common.

Ce tutoriel étant assez long, il n’est pas décrit clairement dans ce post mais est disponible en pdf ici.

Introduction aux facelets

Facelets est un framework permettant de faire des vues de JSF basées sur le modèle html. Il permet de coder des vues avec de simples balises XML, bien plus familières que le codage de jsp. Il offre également un support à JSF pour l’utilisation de template, ce qui réduit la quantité de code produite.

En fait, Facelets est basé sur une représentation de la page sous forme d’UIComponents (composants JSF) et traite les tags JSF (les Facelets supportent tous les composants JSF) et HTML comme étant des membres à part entière de l’arbre. Il permet également la création de composants réutilisable sans une seule ligne de code java.

Facelet est basé sur trois idées principales :

L’integration JSF : Facelet fournit une technologie performante : JSF-centric qui utilise le standard ViewHandler. Facelet intègre tous les composants JSF et fonctionne sans le cycle de vie de JSF.

La composition : Facelet compile un arbre de composant JSF à partir de plusieurs vues. Il traite les balises dans le fichier comme des instructions de construction d’un arbre de composants JSF. Il peut compiler un ou plusieurs fichiers de vue en un seul arbre de composant.

Les templates : Facelet supporte la définition de template de vues reutilisable dans plusieures pages. Quand Facelet contruit l’arbre de composant il parcourt le template et remplace dynamiquement son contenu ou utilise les valeurs par défaut dans le template.

Le templating et la facilité de développement sont les points forts des facelets.

Le but, dans notre cas, sera d’intégrer Facelets dans esup-commons.

Liens utiles :

Présentation des facelets :

http://www.labo-sun.com/resource-fr-articles-1188-0-java-web-jsf-et-les-facelets.htm

http://www.supinfo-projects.com/fr/2006/initiation_facelets/

https://facelets.dev.java.net/nonav/docs/dev/docbook.html

Le site officiel avec les librairies :

https://facelets.dev.java.net/