IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[Annotations] Génération de code de délégation


Sujet :

Java

  1. #21
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Attends, mais tu sais que c'est pas con en fait

    J'étais resté sur le fait de faire appel à mon type déléguant, mais si je pointe directement sur un type déléguateur, ça le fait (sauf dans l'IDE où il va sans cesse me proposer de créer ma classe et où je n'aurais pas de complétion sur les constructeurs puisque inexistants) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    [...]
    WithDelegation_MaClasse toto=new MaClasse(); // là l'IDE gueule et pas de complétion pour le constructeur (inconnu alors)
    [...]
     
    [...]
    abstract class WithDelegation_MaClasse extends Bidule implements InterfaceMachin, InterfaceTruc {
      @Delegate
      protected InterfaceMachin fieldMachin;
      @Delegate
      protected InterfaceTruc fieldTruc;
     
      WithDelegation_MaClasse(InterfaceMachin p_machin, InterfaceTruc p_truc){
         fieldMachin=p_machin;
         fieldTruc=p_truc;
      }
     
      [...]
     
    }
    [...]
     
    @GeneratedDelegateClass
    class MaClass extends WithDelegation_MaClasse  {
      //méthodes déléguées
     
      //réplication des constructeurs avec appel à super(...);
     
    }
    Du coup j'ai juste à imposer une syntaxe, vérifier les cas litigieux et à utiliser un Filer

    Merci maître adiGuba, toi au moins tu sais expliquer les choses !

    Reste plus qu'à voir si ça marche (le plus dur sera de savoir si une méthode est implémentée dans MaClasse, Bidule, ou un autre parent).

    Remarque : pour le problème de l'éditeur je devrais sans doute conserver la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WithDelegate_MaClass toto=new WithDelegate_MaClass(...)
    qui serait remplacé à la volée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass toto=new MaClass(...)
    mais c'est encore super complexe...

    Edit : non en fait ça ne change rien car en mettant la classe déléguante abstract j'ai un autre message d'erreur puisque ma classe est abstraite... donc finalement il me faudra supporter les erreurs de classe introuvable par l'IDE et l'absence de complétion ; avec des classes incomplètes (mon idée initiale) j'aurais eu d'autres messages d'erreur, le moindre mal est sûrement celui que tu proposes.

  2. #22
    Membre Expert

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Par défaut
    Pour l'IDE j'utilise IntelliJ qui permet de configurer un processing d'annotation et ainsi te faire de la completion sur les types générés, mais j'imagine que c'est une feature répandue.

    Si tu veux rendre complètement opaque la génération de code et éviter de te trimballer 2 types tu peux tenter un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class DelegateClassLoader extends ClassLoader
    {
       @Override
       public Class<?> loadClass(String name) throws ClassNotFoundException
       {
          Class<?> clazz = super.loadClass(name);
          if (clazz.isAnnotationPresent(Delegate.class))
          {
             clazz = super.loadClass("WithDelegate_" + name);
          }
          return clazz;
       }
    }
    C'est du sucre mais ca rend plus sexy l'utilisation de tes types générés.

  3. #23
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Merci Alain pour cette suggestion.

    Tu sembles vouloir dire que c'est la classe déléguante (WithDelegation_MaClasse) qui serait chargée si j'écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WithDelegate_MaClasse toto=new MaClasse(...);
    Cependant c'est bien la classe déléguatrice que je veux, pas la classe déléguante...

    Je ne comprends donc pas à quoi ça peut servir et comment s'en servir un exemple serait le bien venu

    A la limite, je comprendrai mieux de pouvoir écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WithDelegate_MaClasse toto=new WithDelegate_MaClasse(...);
    Et que ça me charge la classe délégatrice...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class DelegatorClassLoader extends ClassLoader
    {
       @Override
       public Class<?> loadClass(String name) throws ClassNotFoundException
       {
          Class<?> clazz = super.loadClass(name);
          if (clazz.isAnnotationPresent(Delegate.class) && name.startWith("WithDelegate_"))
          {
             clazz = super.loadClass(name.substring("WithDelegate_".length+1);
          }
          return clazz;
       }
    }
    ou un truc comme ça

    J'aurai toujours les warning sur le fait que c'est une classe abstraite, mais peut-être que c'est plus sympa à utiliser.

    Par contre je ne sais pas comment utiliser ce ClassLoader...

  4. #24
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    sauf erreur ou omission de ma part: si tu charges la classe englobante qui fait de la délégation la classe sur laquelle la délégation opère sera chargée .... donc je ne vois pas l'intérêt de ta version de code.

  5. #25
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    En fait je crois que j'ai compris... tu as une logique inverse de la mienne ; elle est sûrement mieux d'ailleur : je pourrais écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClasse toto=new MaClasse(...);
    avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public abstract class MaClasse implements List {
     
        @Delegate protected List machin;
     
        public MaClasse(List p_machin){
            this.machin=p_machin;
        }
     
    }
     
    @GeneratedDelegateClass
    public class DelegatorMaClasse extends MaClasse {
     
        public MaClasse(List p_machin){
            super(p_machin)
        }
     
        @Override
        public boolean Add(Object p_element){
           machin.Add(p_element);
        }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class DelegatorClassLoader extends ClassLoader
    {
       @Override
       public Class<?> loadClass(String name) throws ClassNotFoundException
       {
          Class<?> clazz = super.loadClass(name);
          if (clazz.isAnnotationPresent(Delegate.class))
          {
             clazz = super.loadClass("Delegator"+name);
          }
          return clazz;
       }
    }
    Comment je peux rendre l'instantiation du ClassLoader transparente ?

  6. #26
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    sauf erreur ou omission de ma part: si tu charges la classe englobante qui fait de la délégation la classe sur laquelle la délégation opère sera chargée .... donc je ne vois pas l'intérêt de ta version de code.
    Je veux bien mais comprends rien... tu peux expliciter s'il te plait ?

  7. #27
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Citation Envoyé par Alain Defrance Voir le message
    Pour l'IDE j'utilise IntelliJ qui permet de configurer un processing d'annotation et ainsi te faire de la completion sur les types générés, mais j'imagine que c'est une feature répandue.
    j'utilise aussi IntelliJ, c'est quoi cette fonctionnalité ?

  8. #28
    Membre Expert

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Par défaut
    Tiens une doc IntelliJ/JPA qui fait ça : http://blogs.jetbrains.com/idea/2009...-20-metamodel/

    Pour le classloader soit tu l'appel soit, soit tu peux le définir comme classloader system.
    Je te conseil de lire ça : http://download.oracle.com/javase/1....assLoader.html. Tu as une propriété system.class.loader qui t'aidera

  9. #29
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    En fait le classloader ne fonctionne qu'à l'exécution...

    Si je mets MonDeleguant abstract et
    si je fais un "new MonDeleguant(...)",
    à la compilation il me dira "MonDeleguant ne peut pas être instancié".

    Si je mets MonDeleguant concret et
    si je fais un "new MonDeleguant(...)",
    à la compilation il me dira "MonDeleguant n'implemente pas complètement les interfaces".

    Si je mets MonDeleguant abstract et
    si je fais un "new DelegatorMonDeleguant(...)",
    lors de l'édition il me dira "DelegatorMonDeleguant n'existe pas".

    Donc finalement, j'aurai quoi qu'il arrive une erreur et je ne peux pas me débarrasser des problèmes de compilation sans faire appel uniquement à la classe générée

  10. #30
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Citation Envoyé par Alain Defrance Voir le message
    Tiens une doc IntelliJ/JPA qui fait ça : http://blogs.jetbrains.com/idea/2009...-20-metamodel/

    Pour le classloader soit tu l'appel soit, soit tu peux le définir comme classloader system.
    Je te conseil de lire ça : http://download.oracle.com/javase/1....assLoader.html. Tu as une propriété system.class.loader qui t'aidera
    merci pour la doc ! je vais lire ça

  11. #31
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Finalement, j'ai l'impression qu'il est impossible de faire de la delegation propre par les annotations.

    Mais ce fut une belle aventure et j'ai appris plein de trucs sympa qui pourront toujours me resservir...

    Merci pour votre participation

  12. #32
    Membre Expert

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Par défaut
    Tout est possible.

    J'ai eu un peu le temps aujourd'hui en fin de journée. Je t'ai écrit le coeur du problème : https://github.com/defrancea/delegationdemo--dvp-

    Il te reste quand même un TODO : la génération du fichier (qui actuellement est écrit) mais le méchanisme autours de ça est en place.

    EDIT : Bien entendu c'est pas une véritable implémentation c'est juste un petit bout de code pour te montrer comment je vois les choses.

    Alain.

  13. #33
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    c'est bien ce que j'avais compris (et que j'ai aussi implémenté en ce sens sur la base de tes conseils) je me permets juste quelques remarques sur ton implémentation (mais tu as fait ça vite fait) :
    - j'avais supposé une délégation d'interface, mais ton approche est intéressante
    - d'où sort ce new B() ? dans l'idéal le délègué est passé par constructeur
    - tu n'as qu'un constructeur par défaut ; quid d'un vrai constructeur avec ta factory ?
    - être obligé de passer par une factory, en mode classe utilitaire en plus, c'est pas userfriendly. c'est déjà pas si mal, mais ça ne me plait pas trop

    La conclusion disait simplement que faire une delegate userfriendly c'est pas possible : on peut toujours faire du delegate avec annotations mais c'est trop gras pour être assez pratique. Mais ça reste intéressant ! La je n'ai plus le temps d'approfondir, mais si tu arrives a quelque chose de finalisé, tiens moi au courant, sinon je me repencherai dessus dans quelques temps.

    Edit: un truc me chiffonne en fait : si je veux étendre A (hors délégation), comment je fais ?

  14. #34
    Membre Expert

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Par défaut
    Salut,

    Citation Envoyé par behess Voir le message
    c'est bien ce que j'avais compris (et que j'ai aussi implémenté en ce sens sur la base de tes conseils) je me permets juste quelques remarques sur ton implémentation (mais tu as fait ça vite fait) :
    En effet.

    Citation Envoyé par behess Voir le message
    - j'avais supposé une délégation d'interface, mais ton approche est intéressante
    Peu importe, ça marcherait pareil.
    Citation Envoyé par behess Voir le message
    - d'où sort ce new B() ? dans l'idéal le délègué est passé par constructeur
    Dans l'idéal ca pourrait interessant de n'avoir pas d'instance et d'injecter le délégué et/ou le passer par constructeur mais peut importe cela ne changerai rien.
    Citation Envoyé par behess Voir le message
    - tu n'as qu'un constructeur par défaut ; quid d'un vrai constructeur avec ta factory ?
    C'est quoi le problème ? On pourrait compier les constructeurs vers le délégué, on peut également invoquer un constructeur ayant des paramètres avec de la reflexion.
    Citation Envoyé par behess Voir le message
    - être obligé de passer par une factory, en mode classe utilitaire en plus, c'est pas userfriendly. c'est déjà pas si mal, mais ça ne me plait pas trop
    On pourrait se passer de la factory en overridant le classloader system il me semble (j'ai eu à le faire). Sinon si tu préfère tu peux toujours avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = new A_WithDelegation();
    Pour ma part je n'aime pas rendre visible des types qui ne sont pas présent avant la compilation, et mon code ne pose pas de problèmes de completion même sans configuration de processor au niveau de l'IDE.

    Citation Envoyé par behess Voir le message
    La conclusion disait simplement que faire une delegate userfriendly c'est pas possible : on peut toujours faire du delegate avec annotations mais c'est trop gras pour être assez pratique. Mais ça reste intéressant ! La je n'ai plus le temps d'approfondir, mais si tu arrives a quelque chose de finalisé, tiens moi au courant, sinon je me repencherai dessus dans quelques temps.
    J'ai pris le temps d'écrire ca très rapidement hier soir, tu te doutes bien que j'ai du travail et que je ne peux pas m'occuper de "de faire un code source full ok, productisé & co".
    Si ca t'interesse de polir/améliorer c'est à toi de jouer

    Citation Envoyé par behess Voir le message
    Edit: un truc me chiffonne en fait : si je veux étendre A (hors délégation), comment je fais ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    A2 extends A
    A_WithDelegation extends A2
    Rien ne t'empêche de déterminer la première classe de ta hiérarchie qui délègue et la dernière.
    Rien ne t'empêche non plus de créer une annotation facultative sur un type qui permet de customiser ce comportement.

    Comme tu le vois (ou tu le sait), développer de la lib/framework est compliqué car ton utilisateur est un développeur et il sera tenté de faire n'importe quoi, il faut donc penser à tout et prévoir le plus de cas possible pour pas que ca chie/bride le développeur.
    Néanmoins c'est le jeu et il faut avancer petit à petit et régler les problèmes les uns derrières les autres à base de test unitaire pour éviter les régressions.
    Je n'ai pas vu de truc "bloquant" dans ce que tu m'a dit, le sucre que tu veux poser par dessus ou les features/use case que tu m'a donné plus haut ne sont que des implémentations supplémentaires.
    Courage

Discussions similaires

  1. Génération de code & bpm4struts
    Par k4eve dans le forum BPM
    Réponses: 3
    Dernier message: 08/03/2007, 15h12
  2. Modelisation UML / Génération de code C++ sous eclipse
    Par silverhawk.os dans le forum Eclipse C & C++
    Réponses: 5
    Dernier message: 03/01/2006, 00h15
  3. [UML] génération de code avec omondo.uml
    Par RENAULT dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 31/10/2003, 13h14
  4. [Lomboz] Génération de code pour EJB
    Par paikan dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 09/07/2003, 14h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo