Étiquette : Open Source

Hibernate : mapping d’une colonne en Set

Le mapping avec Hibernate

L’utilisation d’une relation many-to many avec hibernate permet de rendre transparent la table d’association.

Dans l’exemple suivant, la table EDITION_LIVRE sera mappée de manière transparente :
Livre Many Many Hibernate
La mapping de la table LIVRE sera le suivant :

‹set name="editions" table="EDITION_LIVRE"›
‹key column="LIVRE_ID" /›
‹many-to-many column="EDITION_ID" /›
‹/set›

Et Livre contiendra un Set<Edition>, mais l’objet EditionLivre n’existera pas…

A la vue de ce type de mapping, on peut être intéressé de faire la même chose pour un mapping many to one.
En effet, plutôt que de me retrouver avec un Set d’objet dont nous n’avons besoin que pour de l’affichage, nous préférerions avoir un Set de String. Par exemple, si on prend une relation de ce type :

Livre Set Hibernate
Et qu’on ne veut pas avoir à mapper l’objet LivreMotcle, il suffit de définir dans le fichier de mapping Livre le Set suivant :

‹set name=”mots" table="LIVRE_MOTCLE"›
‹key column="LIVRE_ID" /›
‹element column="MOT" type="string"/›
‹/set›

On obtient alors un Set<String> mots dans l’objet Livre.

GWT et Drag and Drop

Le « glisser-déposer », ou Drag and Drop, n’est pas géré nativement par GWT.

Afin de palier à ce manque, un certains nombres d’implémentations ont été élaborées.
Le choix de Viaxoft s’est porté sur dnd-gwt, et ceux pour deux raisons :

  • Cette API présente l’avantage d’être non invasive, de n’impliquer aucune génération de code annexe.
  • « dnd » permet la réutilisation directe des widgets de GWT et de nos composites.

Cette note survole les grands principes autours desquels s’articule cette librairie.

containingPanel.setPixelSize(w, h);
containingPanel.getElement().getStyle().setProperty("position","relative");
PickupDragController dragController = new PickupDragController(containingPanel, true);//Paramétrage du comportement DnD
//On interdit les selections mulitples et aux Widgets draggables d'être déposés hors des drop zones
dragController.setBehaviorBoundaryPanelDrop(false);
dragController.setBehaviorMultipleSelection(false);

Une fois un DragController défini, n’importe quel widget implémentant SourcesMouseEvents peut être transformé en élément « draggable ». On pourrait donc penser être limité aux Image, Label et FocusPanel. Cependant tout composite implémentant l’interface est lui-même éligible. Le DragController permet notamment de distinguer un composite dans son ensemble de sa partie réalisant le Drag & Drop.

class TextAndPicto extends Composite implements SourcesMouseEvents{
TextField text;
Image picto;
public LabelAndPicto(TextField text, Image picto)
{
this.text = text;
this.picto=picto;
HorizontalPanel mainPanel = new HorizontalPanel();
mainPanel.add(picto);
mainPanel.add(text);
initWidget(mainPanel);
}

public void addMouseListener(MouseListener listener) {
picto.addMouseListener(listener);

}

public void removeMouseListener(MouseListener listener) {
picto.removeMouseListener(listener);
...

TextAndPicto w = new TextAndPicto(new TextBox(), new Image("pictoViaxeo/clients.gif"));
dragController.makeDraggable(w,w.getImage());
Enfin le DropController permet de définir le comportement des widgets sur lesquels pourront être déposés les éléments « draggables ». Le constructeur prend en paramètre le widget qui servira de « drop zone », et les 4 méthodes suivantes sont définies par l’interface afin de gérer son comportement : onEnter, onLeave, onDrop et onPreviewDrop. Les deux premières sont appelées lorsqu’un item est « dragué » au dessus de la drop zone. La troisième détermine les actions à prendre consécutivement à la dépose du dit item. Et enfin, onPreviewDrop permet d’effectuer des contrôles préalables avant l’exécution d’onDrop.
  public class DropZoneListener extends SimpleDropController {
private VerticalPanel panel;

public DropZoneListener(Widget dropTarget) {
super(dropTarget);
panel = (VerticalPanel)dropTarget;
}

public void onDrop(DragContext context) {
super.onDrop(context);
for(SmartWidget smartWidget : (List)context.selectedWidgets)
panel.add(smartWidget);
}

public void onEnter(DragContext context) {
super.onEnter(context);
panel.addStyleName("viaxeo-DnD-Liste-Header-seleted");
}

public void onLeave(DragContext context) {
super.onLeave(context);
panel.removeStyleName("viaxeo-DnD-Liste-Header-seleted");
}

public void onPreviewDrop(DragContext context) throws VetoDragException {
super.onPreviewDrop(context);
}

}
Dnd-gwt propose un large panel de DropController allant du GridConstrainedDropController (gestion du drop par grilles) au FlexTableRowDropController (ajout/suppression dynamique de lignes dans une FlexTable).

Velocity au runtime : modification de template

Modification de template Velocity au runtime

Velocity est un moteur de template Open Source Java de la fondation Apache. Nous utilisons Velocity depuis pas mal de temps pour tout ce qui est rapport aux fusions (Mail, publipostage,…).
Jusqu’à présent nous l’utilisions sous sa forme la plus « traditionnelle », basée sur des fichier template (.vm), que nous chargions au runtime pour être fusionnés à une map de paramètres :

  // Initialisation du moteur velocity
VelocityEngine engine = new VelocityEngine();
engine.init();
// Chargement du template
Template template = engine.getTemplate( "test.vm" );
// Création du contexte
VelocityContext context = new VelocityContext();
context.put("nom", "Durand");
// Exécution du template dans une String
StringWriter writer = new StringWriter();
template.merge( context, writer );System.out.println( writer.toString() );

Dernièrement nous avons eu le besoin de composer une variable sur la base de plusieurs autres. Il s’agit de faire un peu plus que de la concaténation ; nous avons donc laissé nos utilisateurs créer leur propres variables de la sorte :

 politesse = &civilite &nom &prenom

Mais nous devions à ce moment là modifier nos template au runtime. Velocity offre pour cela une méthode evaluate qui permet d’évaluer un template (sous forme de String) :

StringWriter result = new StringWriter();
try {
velocityEngine.evaluate(velocityContext, result, "template", template);
} catch (Exception e)...

Ceci nous a permis de stocker les modèles en base de données sans avoir ensuite à recréer des InputStream ou autre pour les fusionner.

Nous modifions les modèles au runtime en leur ajoutant les variables créées par les utilisateurs.

Loading...
X