Re: [Eugene-devel] [Lutingenerator-devel] signets dans les générateurs ?
Romain Manni-Bucau a écrit :
Bonjour,
Bonjour,
est-il possible d'une façon simple d'avoir une sorte de signets avec les générateurs ?
Pour le principe, je voudrais pouvoir signifier un point dans le fichier de sortie et pouvoir ensuite générer à partir de ce point.
Exemple :
/*{toto }*/ createPoint(1); // identitifant = 1 /*{titi }*/ createPoint(2); writeOnPoint(1); /*{tata }*/
etc ...
et ça créérait le fichier : toto tata titi
D'avance merci
Je n'ai pas très bien compris votre notion de signet. Le contenu entre /*{ et }*/ est ecrit directement, il n'est pas conservé en mémoire pour avoir la possibilité de réutilisation. Mais est-ce que l'implentation suivante, basé sur des fonctions répond à votre besoin ? protected void echoToto(Writer out) { /*{toto }*/ } protected void echoTiti(Writer out) { /*{titi }*/ } protected void echoTata(Writer out) { /*{tata }*/ } public void generateFromModel(ObjectModel model, Writer out) { echoToto(out); echoTata(out); echoTiti(out); } Ceci produira également le résultat : toto tata titi PS: aux erreurs de compilation près ;-) -- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
Ce que j'aurais voulu était de garder le concept d'écriture des templates entre /*{ }*/ mais que ceux-ci puisse apartenir à un groupe un groupe étant écrit d'un bloc. Par exemple /*[1]{toto1}*/ /*{pas de groupe 1*}/ /*[2]{toto2}*/ /*{pas de groupe 2*}/ /*[1]{toto3}*/ écrirait : toto1 toto3 /*{pas de groupe 1*}/ toto2 /*{pas de groupe 2*}/ Ajouter un "signet" crée un nouveau buffer à l'endroit où on est, ne pas signaler de signet crée un nouveau buffer à la fin. Pour prendre un exemple plus parlant peut-être, si je veux générée un .java, je crée par exemple un signet "imports", un signet "attributes", et un dernier "methods" et je peux par exemple faire : /*{ package .... }*/ createPoint("imports"); /*{ public class .... }*/ createPoint(attributes); createPoint(method); /*[methods]*{ public void useless() {} }*/ /*[imports]{ import java.util.*; }*/ /*[attributes]{ private int toto = 0; }*/ /*{ } }*/ qui me donne : package ... import java.util.*; public class ... private int toto = 0; public void useless() {} Dans l'idée (disons son interface) cette classe conviendrait mais on perd le côté template inclut dans le code qui était appréciable : package org.ofbiz.neogia.generators.util; import java.io.Writer; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Set; public class WriterWithSavePoints { private static final char FIRST_IN_NAME = '_'; private Writer output = null; private Map<String, StringBuilder> savePointMap; private LinkedList<String> savePoints; public WriterWithSavePoints(Writer out) { setOutput(out); savePointMap = new HashMap<String, StringBuilder>(); savePoints = new LinkedList<String>(); } public void setOutput(Writer output) { this.output = output; } public Writer getOutput() { return output; } private void createSavePoint(String name) { savePoints.add(name); savePointMap.put(name, new StringBuilder()); } /** * Add value to the end of the buffer (not to a savepoint) * @param value */ public void add(String value) { String name = FIRST_IN_NAME + Integer.toString(savePoints.size()); if (savePoints.getLast().charAt(0) == FIRST_IN_NAME) { // we are already in append mode name = savePoints.getLast(); savePointMap.get(name).append(value); } else { createSavePoint(name); savePointMap.get(name).append(value); } } /** * The same methode that add(String) but adding a \n to value * @see value add(String) */ public void addln(String value) { add(value+'\n'); } /** * Create a new save point * @param name the name of the new save point * /!\ the save point length has to be > 0 * and should not begin with '_' * (it is reserved for the working save points) */ public void addSavePoint(String name) { if (savePointMap.containsKey(name) || name.length() == 0 || name.charAt(0) == FIRST_IN_NAME) throw new IllegalStateException("Save point "+name+"is already defined."); createSavePoint(name); } /** * %v in the form are replaced by the good variable in the vararg list * @param name the save point name * @param form the form of the string to add at the save point * @param var the list of variable * Example : * addToSavePoint("mySavePoint", "this save %v is called %v", "point", "mySavePoint"); */ public void addToSavePoint(String name, String form, String... var) { if (!savePointMap.containsKey(name)) throw new IllegalStateException("Save point "+name+"doesn't exist."); String toAdd = form; int stringIdx, varIdx = 0, varLgth = var.length; while((stringIdx = toAdd.indexOf("%v")) >= 0) { if (varIdx >= varLgth) throw new IllegalStateException("Not enough variable to this form "+form); toAdd = toAdd.substring(0, stringIdx) + var[varIdx++] + toAdd.substring(stringIdx+2); } savePointMap.get(name).append(toAdd); } /** * concatenate to the save point name value * @param name the save point name * @param value the string to add to the save point named */ public void addToSavePoint(String name, String value) { if (!savePointMap.containsKey(name)) throw new IllegalStateException("Save point "+name+"doesn't exist."); savePointMap.get(name).append(value); } /** * the same method that addToSavePoint() one but adding \n after form * @see addToSavePoint */ public void addlnToSavePoint(String name, String form, String... var) { addlnToSavePoint(name, form+'\n', var); } /** * the same method that addToSavePoint() one but adding \n after value * @see addToSavePoint */ public void addlnToSavePoint(String name, String value) { if (!savePointMap.containsKey(name)) throw new IllegalStateException("Save point "+name+"doesn't exist."); savePointMap.get(name).append(value+'\n'); } /** * @return the set of all save point name */ public Set<String> getSavePoints() { return savePointMap.keySet(); } /** * Write all the buffers on the output */ public void writeAll() { for(String sp : savePoints) { @SuppressWarnings("unused") String value = savePointMap.get(sp).toString(); /*{value}*/ } } } Le mercredi 12 août 2009 à 17:55 +0200, Eric Chatellier a écrit :
Romain Manni-Bucau a écrit :
Bonjour,
Bonjour,
est-il possible d'une façon simple d'avoir une sorte de signets avec les générateurs ?
Pour le principe, je voudrais pouvoir signifier un point dans le fichier de sortie et pouvoir ensuite générer à partir de ce point.
Exemple :
/*{toto }*/ createPoint(1); // identitifant = 1 /*{titi }*/ createPoint(2); writeOnPoint(1); /*{tata }*/
etc ...
et ça créérait le fichier : toto tata titi
D'avance merci
Je n'ai pas très bien compris votre notion de signet. Le contenu entre /*{ et }*/ est ecrit directement, il n'est pas conservé en mémoire pour avoir la possibilité de réutilisation.
Mais est-ce que l'implentation suivante, basé sur des fonctions répond à votre besoin ?
protected void echoToto(Writer out) { /*{toto }*/ }
protected void echoTiti(Writer out) { /*{titi }*/ }
protected void echoTata(Writer out) { /*{tata }*/ }
public void generateFromModel(ObjectModel model, Writer out) { echoToto(out); echoTata(out); echoTiti(out); }
Ceci produira également le résultat : toto tata titi
PS: aux erreurs de compilation près ;-)
Romain Manni-Bucau a écrit :
Ce que j'aurais voulu était de garder le concept d'écriture des templates entre /*{ }*/ mais que ceux-ci puisse apartenir à un groupe un groupe étant écrit d'un bloc.
Par exemple /*[1]{toto1}*/ /*{pas de groupe 1*}/ /*[2]{toto2}*/ /*{pas de groupe 2*}/ /*[1]{toto3}*/
écrirait : toto1 toto3 /*{pas de groupe 1*}/ toto2 /*{pas de groupe 2*}/
Ajouter un "signet" crée un nouveau buffer à l'endroit où on est, ne pas signaler de signet crée un nouveau buffer à la fin.
Pour prendre un exemple plus parlant peut-être, si je veux générée un .java, je crée par exemple un signet "imports", un signet "attributes", et un dernier "methods" et je peux par exemple faire :
/*{ package .... }*/ createPoint("imports"); /*{ public class .... }*/ createPoint(attributes); createPoint(method); /*[methods]*{ public void useless() {} }*/ /*[imports]{ import java.util.*; }*/ /*[attributes]{ private int toto = 0; }*/ /*{ } }*/
qui me donne : package ... import java.util.*; public class ... private int toto = 0; public void useless() {}
Je comprend bien, mais on ne peut pas faire ça. Et je trouve que ça rend le template plus difficile à lire.
Dans l'idée (disons son interface) cette classe conviendrait mais on perd le côté template inclut dans le code qui était appréciable :
Oui, c'est une autre façon de générer sans template finalement. Mais je ne vois pas très bien l'intérêt de passer par des "signet" pour générer ce genre de code, si ce n'est parcourir une seule fois le modèle. Dans votre cas, vous voulez générer "import", "attributs", "méthodes". On a exactement les mêmes problématiques de notre coté. Donc fait ça simplement, même si ce n'est pas optimisé en temps : - parcourt du modèle pour génération des imports - parcourt du modèle pour génération des attributs - parcourt du modèle pour génération des méthodes Il y a même une générateur d'import qui a été développé récemment : http://www.nuiton.org/repositories/entry/eugene/trunk/eugene/src/main/java/o... Bref, je ne peux pas vous aider plus je pense, apart vous montrer des exemples de générateurs : http://www.nuiton.org/repositories/browse/eugengo/trunk/src/main/java/org/nu... http://www.nuiton.org/repositories/browse/topia/trunk/topia-persistence/src/... -- Éric <chatellier@codelutin.com> Tel: 02 40 50 29 28 http://www.codelutin.com
l'idée de parcourir plusieurs fois le modèle ne me plait pas mais il me semble indispensable. merci de vos réponses Le jeudi 13 août 2009 à 15:51 +0200, Eric Chatellier a écrit :
Romain Manni-Bucau a écrit :
Ce que j'aurais voulu était de garder le concept d'écriture des templates entre /*{ }*/ mais que ceux-ci puisse apartenir à un groupe un groupe étant écrit d'un bloc.
Par exemple /*[1]{toto1}*/ /*{pas de groupe 1*}/ /*[2]{toto2}*/ /*{pas de groupe 2*}/ /*[1]{toto3}*/
écrirait : toto1 toto3 /*{pas de groupe 1*}/ toto2 /*{pas de groupe 2*}/
Ajouter un "signet" crée un nouveau buffer à l'endroit où on est, ne pas signaler de signet crée un nouveau buffer à la fin.
Pour prendre un exemple plus parlant peut-être, si je veux générée un .java, je crée par exemple un signet "imports", un signet "attributes", et un dernier "methods" et je peux par exemple faire :
/*{ package .... }*/ createPoint("imports"); /*{ public class .... }*/ createPoint(attributes); createPoint(method); /*[methods]*{ public void useless() {} }*/ /*[imports]{ import java.util.*; }*/ /*[attributes]{ private int toto = 0; }*/ /*{ } }*/
qui me donne : package ... import java.util.*; public class ... private int toto = 0; public void useless() {}
Je comprend bien, mais on ne peut pas faire ça. Et je trouve que ça rend le template plus difficile à lire.
Dans l'idée (disons son interface) cette classe conviendrait mais on perd le côté template inclut dans le code qui était appréciable :
Oui, c'est une autre façon de générer sans template finalement.
Mais je ne vois pas très bien l'intérêt de passer par des "signet" pour générer ce genre de code, si ce n'est parcourir une seule fois le modèle.
Dans votre cas, vous voulez générer "import", "attributs", "méthodes". On a exactement les mêmes problématiques de notre coté. Donc fait ça simplement, même si ce n'est pas optimisé en temps : - parcourt du modèle pour génération des imports - parcourt du modèle pour génération des attributs - parcourt du modèle pour génération des méthodes
Il y a même une générateur d'import qui a été développé récemment : http://www.nuiton.org/repositories/entry/eugene/trunk/eugene/src/main/java/o...
Bref, je ne peux pas vous aider plus je pense, apart vous montrer des exemples de générateurs : http://www.nuiton.org/repositories/browse/eugengo/trunk/src/main/java/org/nu... http://www.nuiton.org/repositories/browse/topia/trunk/topia-persistence/src/...
Romain Manni-Bucau a écrit :
l'idée de parcourir plusieurs fois le modèle ne me plait pas mais il me semble indispensable.
Bonjour, Désolé pour ma réponse tardive. En fait ce qu'on fait généralement c'est préparer les données avant de générer. D'expérience ca permet de rendre le template (générateur) plus lisible. Car nous nous sommes rendu compte que parcourir plusieurs fois le modèle n'a que peu d'impact (les perfs ne s'en ressentent pas) par rapport à un template qui devient illisible (c'est souvent le cas). Cordialement, Arnaud.
merci de vos réponses
Le jeudi 13 août 2009 à 15:51 +0200, Eric Chatellier a écrit :
Romain Manni-Bucau a écrit :
Ce que j'aurais voulu était de garder le concept d'écriture des templates entre /*{ }*/ mais que ceux-ci puisse apartenir à un groupe un groupe étant écrit d'un bloc.
Par exemple /*[1]{toto1}*/ /*{pas de groupe 1*}/ /*[2]{toto2}*/ /*{pas de groupe 2*}/ /*[1]{toto3}*/
écrirait : toto1 toto3 /*{pas de groupe 1*}/ toto2 /*{pas de groupe 2*}/
Ajouter un "signet" crée un nouveau buffer à l'endroit où on est, ne pas signaler de signet crée un nouveau buffer à la fin.
Pour prendre un exemple plus parlant peut-être, si je veux générée un .java, je crée par exemple un signet "imports", un signet "attributes", et un dernier "methods" et je peux par exemple faire :
/*{ package .... }*/ createPoint("imports"); /*{ public class .... }*/ createPoint(attributes); createPoint(method); /*[methods]*{ public void useless() {} }*/ /*[imports]{ import java.util.*; }*/ /*[attributes]{ private int toto = 0; }*/ /*{ } }*/
qui me donne : package ... import java.util.*; public class ... private int toto = 0; public void useless() {}
Je comprend bien, mais on ne peut pas faire ça. Et je trouve que ça rend le template plus difficile à lire.
Dans l'idée (disons son interface) cette classe conviendrait mais on perd le côté template inclut dans le code qui était appréciable :
Oui, c'est une autre façon de générer sans template finalement.
Mais je ne vois pas très bien l'intérêt de passer par des "signet" pour générer ce genre de code, si ce n'est parcourir une seule fois le modèle.
Dans votre cas, vous voulez générer "import", "attributs", "méthodes". On a exactement les mêmes problématiques de notre coté. Donc fait ça simplement, même si ce n'est pas optimisé en temps : - parcourt du modèle pour génération des imports - parcourt du modèle pour génération des attributs - parcourt du modèle pour génération des méthodes
Il y a même une générateur d'import qui a été développé récemment : http://www.nuiton.org/repositories/entry/eugene/trunk/eugene/src/main/java/o...
Bref, je ne peux pas vous aider plus je pense, apart vous montrer des exemples de générateurs : http://www.nuiton.org/repositories/browse/eugengo/trunk/src/main/java/org/nu... http://www.nuiton.org/repositories/browse/topia/trunk/topia-persistence/src/...
_______________________________________________ Eugene-devel mailing list Eugene-devel@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/eugene-devel
-- Société Code Lutin http://www.codelutin.com tel : 02 40 50 29 28 fax : 09 59 92 29 28
oui c'est ce que j'ai commencé à faire avec des méthode de recherche de champs et de relations mais je me suis heurté sur des problème liés à l'utilisation même des objets modélisant les relatons (objectmodelattributes) [cf un autre message sur cette même liste] merci de votre réponse PS : je trouve quand même l'utilisation de mon "writer" pratique et elle permet de vérifier le code des templates directement dans son ide Le vendredi 21 août 2009 14:01:06, Arnaud Thimel a écrit :
Romain Manni-Bucau a écrit :
l'idée de parcourir plusieurs fois le modèle ne me plait pas mais il me semble indispensable.
Bonjour,
Désolé pour ma réponse tardive.
En fait ce qu'on fait généralement c'est préparer les données avant de générer. D'expérience ca permet de rendre le template (générateur) plus lisible. Car nous nous sommes rendu compte que parcourir plusieurs fois le modèle n'a que peu d'impact (les perfs ne s'en ressentent pas) par rapport à un template qui devient illisible (c'est souvent le cas).
Cordialement, Arnaud.
merci de vos réponses
Le jeudi 13 août 2009 à 15:51 +0200, Eric Chatellier a écrit :
Romain Manni-Bucau a écrit :
Ce que j'aurais voulu était de garder le concept d'écriture des templates entre /*{ }*/ mais que ceux-ci puisse apartenir à un groupe un groupe étant écrit d'un bloc.
Par exemple /*[1]{toto1}*/ /*{pas de groupe 1*}/ /*[2]{toto2}*/ /*{pas de groupe 2*}/ /*[1]{toto3}*/
écrirait : toto1 toto3 /*{pas de groupe 1*}/ toto2 /*{pas de groupe 2*}/
Ajouter un "signet" crée un nouveau buffer à l'endroit où on est, ne pas signaler de signet crée un nouveau buffer à la fin.
Pour prendre un exemple plus parlant peut-être, si je veux générée un .java, je crée par exemple un signet "imports", un signet "attributes", et un dernier "methods" et je peux par exemple faire :
/*{ package .... }*/ createPoint("imports"); /*{ public class .... }*/ createPoint(attributes); createPoint(method); /*[methods]*{ public void useless() {} }*/ /*[imports]{ import java.util.*; }*/ /*[attributes]{ private int toto = 0; }*/ /*{ } }*/
qui me donne : package ... import java.util.*; public class ... private int toto = 0; public void useless() {}
Je comprend bien, mais on ne peut pas faire ça. Et je trouve que ça rend le template plus difficile à lire.
Dans l'idée (disons son interface) cette classe conviendrait mais on perd le côté template inclut dans le code qui était appréciable :
Oui, c'est une autre façon de générer sans template finalement.
Mais je ne vois pas très bien l'intérêt de passer par des "signet" pour générer ce genre de code, si ce n'est parcourir une seule fois le modèle.
Dans votre cas, vous voulez générer "import", "attributs", "méthodes". On a exactement les mêmes problématiques de notre coté. Donc fait ça simplement, même si ce n'est pas optimisé en temps : - parcourt du modèle pour génération des imports - parcourt du modèle pour génération des attributs - parcourt du modèle pour génération des méthodes
Il y a même une générateur d'import qui a été développé récemment : http://www.nuiton.org/repositories/entry/eugene/trunk/eugene/src/main/ja va/org/nuiton/eugene/ImportsManager.java
Bref, je ne peux pas vous aider plus je pense, apart vous montrer des exemples de générateurs : http://www.nuiton.org/repositories/browse/eugengo/trunk/src/main/java/or g/nuiton/eugengo/generator http://www.nuiton.org/repositories/browse/topia/trunk/topia-persistence/ src/main/java/org/nuiton/topia/generator
_______________________________________________ Eugene-devel mailing list Eugene-devel@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/eugene-devel
-- Manni-Bucau Romain
participants (4)
-
Arnaud Thimel -
Eric Chatellier -
Manni-Bucau Romain (Néréide) -
Romain Manni-Bucau