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 :

BeanUtils Gestion des beans complexes et des listes


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut BeanUtils Gestion des beans complexes et des listes
    Bonjour,

    J'ai implémenté avec BeanUtils une méthode me permettant de m'indiquer des différences entre 2 beans.
    Pour les type simples, aucuns soucis.

    Par contre, pour les beans contenus dans mon bean de départ et les listes, je ne voit pas comment je peux les traiter, et surtout les différencier.

    Pour les beans à l'intérieur de mes beans, je pensais rappeler la méthode en récursivité mais comment détecter si c'est un bean et pas un type simple?

    Pour les listes? he bien j'ai pas vraiment d'idée.

    Ma méthode de différenciation :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    public Map<String, Object> detecterModification(Object current, Object orig, List<String> exclusionsList) {
            // Validation des objets input
            if (current == null) {
                throw new ExceptionTechnique("Objet current null");
            }
            if (orig == null) {
                throw new ExceptionTechnique("Objet origine null");
            }
            if (!current.getClass().equals(orig.getClass())) {
                throw new ExceptionTechnique("Les objets ne sont pas pas de la même instance");
            }
            // Instanciation de bean
            final PropertyUtilsBean pub = BeanUtilsBean.getInstance().getPropertyUtils();
            // récupération des proprietes
            List<PropertyDescriptor> origDescriptors = new ArrayList<PropertyDescriptor>(Arrays.asList(pub.getPropertyDescriptors(orig)));
            // Copie des propriétés. Les propriété exclues seront ignoré
            Stream<PropertyDescriptor> streamPropertyDescriptor;
            if (CollectionUtils.isEmpty(exclusionsList)) {
                streamPropertyDescriptor = origDescriptors.stream();
            } else {
                // Execlure les attributs de la liste des exclusion
                streamPropertyDescriptor = origDescriptors.stream().filter(x -> !(exclusionsList.contains(x.getName())));
            }
            // comparaison des propriétés
            Map<String, Object> mapDifference = new HashMap<String, Object>();
            streamPropertyDescriptor.forEach(origDescriptor -> {
                String name = origDescriptor.getName();
                if (pub.isReadable(orig, name) && pub.isReadable(current, name)) {
                    try {
                        Object valueOrig;
                        valueOrig = pub.getSimpleProperty(orig, name);
                        Object valueCurrent;
                        valueCurrent = pub.getSimpleProperty(current, name);
     
                        if (origDescriptor.getPropertyType().isComplexType()) {      // comment détecter un bean complexe?
                            mapDifference.putAll(this.detecterModification(valueCurrent, valueOrig, null));
                        } else {
                            if(valueCurrent == null && valueOrig == null){
                                //nothing
                            }else if(valueCurrent != null && valueOrig == null){
                                mapDifference.put(name, valueCurrent);
                            }else if(valueCurrent == null && valueOrig != null){
                                mapDifference.put(name, valueCurrent);
                            }else if(!valueOrig.equals(valueCurrent)){
                                mapDifference.put(name, valueCurrent);
                            }
                        }
                    } catch (Exception e) {
                        logger.severe(() -> MessageFormat.format("Erreur de détection des modifications de {0} de la classe {1} : {2}", name, current.getClass(), e.getMessage()));
                        throw new ExceptionTechnique(e);
                    }
                }
            });
            return mapDifference;
        }
    et un exemple de bean :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class RepresentantDto {
     
        private Long identifiant;  
         private String nom;
        private LocalDate dateCreation;
        private PersonneMoraleDto personneMorale;
        private Boolean estSupprimer = Boolean.FALSE;
        private List<RepresentantQualiteDto> listeQualite;
    Merci pour votre aide

  2. #2
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    J'aurai tendance à dire qu'il faudrait commencer par faire des tests de type equals sur tous les objets qui n'implémentent pas Collection ou Map pour exclure rapidement tous les objets qui sont déjà identiques

    Pour ce qui est ensuite de comparer des collections/map entre elles, c'est un soucis qui dépendra de plus d'éléments : est-ce que l'ordre des éléments a une importance par exemple. Sinon, tu peux aussi utiliser la méthode equals dessus (qui normalement devrait faire un test pour voir si tous les éléments sont présents).


    Déjà, tu n'auras plus que les éléments qui ne sont pas strictement égaux.


    Ensuite, j'aurai personnellement tendance à créer une méthode sur chaque objet qui permette de se comparer lui même avec un autre, et de renvoyer les différences... Comme ça fini l'introspection et tu résous ton problème simplement !
    Tu crées une interface Differenciable<T> avec une méthode qui te renvoie une Map<String, Object> nommée getDifferences(T other), et tu implémentes la méthode dans les objets que tu veux différentier

  3. #3
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut
    Le but de la manœuvre est de pouvoir mettre à disposition une cartographie précise de tous les changements dans les beans. j'ai simplifié ici mais j'ai une structure complexe de beans à plusieurs niveaux. Chaque différence de valeur d'un attribut, de l'attribut d'un sous-beans, ou de l'attribut d'un bean contenu dans une collection doit être répertorié. je dois donc descendre dans toute le structure pour trouver

    Citation Envoyé par eulbobo Voir le message
    J'aurai tendance à dire qu'il faudrait commencer par faire des tests de type equals sur tous les objets qui n'implémentent pas Collection ou Map pour exclure rapidement tous les objets qui sont déjà identiques
    Pour ce qui est ensuite de comparer des collections/map entre elles, c'est un soucis qui dépendra de plus d'éléments : est-ce que l'ordre des éléments a une importance par exemple. Sinon, tu peux aussi utiliser la méthode equals dessus (qui normalement devrait faire un test pour voir si tous les éléments sont présents).
    Déjà, tu n'auras plus que les éléments qui ne sont pas strictement égaux.
    l'ordre n'a pas d'importance du moment que l'on compare bien le même beans (id identique) dans les 2 collections. ensuite, je dois détecter les différences attribut à attribut mais ça je sais déjà faire.
    De plus il me faut gérer l'ajout et la suppression dans l'une ou l'autre des listes. Je bloque toujours sur comment faire.



    Citation Envoyé par eulbobo Voir le message
    Ensuite, j'aurai personnellement tendance à créer une méthode sur chaque objet qui permette de se comparer lui même avec un autre, et de renvoyer les différences... Comme ça fini l'introspection et tu résous ton problème simplement !
    Tu crées une interface Differenciable<T> avec une méthode qui te renvoie une Map<String, Object> nommée getDifferences(T other), et tu implémentes la méthode dans les objets que tu veux différentier
    j'y avais déjà pensé mais l’intérêt est d'avoir quelque chose de dynamique car 1) je n'ai pas forcement la maîtrise des objets passés en paramètres et 2) ceux ci doivent et vont pouvoir évoluer rapidement et régulièrement; l'idée est d'avoir le moins possible d'évolution à apporter à chaque évolution. De plus celle ci ne seront pas toujours faites par des personnes ayant une connaissance approfondie de Java (c'est comme ça malheureusement....).


    Merci.

  4. #4
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Citation Envoyé par CPI_en_mousse Voir le message
    De plus il me faut gérer l'ajout et la suppression dans l'une ou l'autre des listes. Je bloque toujours sur comment faire.
    Pour l'ajout et la suppression, le plus "simple" est de prendre chaque liste (ancienne et nouvelle) et mettre leur contenu dans deux nouvelles listes :

    Exemple :
    tu testes les deux instances suivantes : acList et nvList
    Tu commences par créer deux nouvelles listes copyAcList(acList) et copyNvList(nvList)
    Tu supprimes les éléments communs des deux cotés
    copyAcList.removeAll(nvList)
    copyNvList.removeAll(acList)

    Les éléments présents dans la liste copyAcList sont les éléments qui ont disparu
    Les éléments présents dans la liste copyNvList sont les éléments qui été ajoutés




    j'y avais déjà pensé mais l’intérêt est d'avoir quelque chose de dynamique car 1) je n'ai pas forcement la maîtrise des objets passés en paramètres et 2) ceux ci doivent et vont pouvoir évoluer rapidement et régulièrement; l'idée est d'avoir le moins possible d'évolution à apporter à chaque évolution.
    L'inconvénient va être de mettre en place une usine à gaz qui devra savoir tout gérer uniquement pour résoudre en une seule fois un problème qui pourrait être résolu unitairement à plus bas niveau.
    Voyons le problème autrement : à combien de temps estimes-tu la mise en place et la modification/amélioration de ton système quand il faudra prendre en compte des cas que tu n'avais pas prévu à la base et qui font planter ton système ou ne marchent pas? Penses-tu pouvoir gérer tous les cas de manière totalement générique?
    Autre détail : l'introspection, c'est bien, mais c'est extrêmement coûteux !

    A la moindre évolution, il faudra de toute façon modifier le equals et le hashcode sinon tu auras des incohérences... Le compareTo aussi.. Le toString... Bref, au niveau de chaque classe, de nombreuses modifications de la logique même de la classe devront être apportées. Une de plus ça ne sera pas la mort et ça ouvre la voie de l'atomicité des objets qui gagne juste la responsabilité de savoir se comparer en listant les différences (ce qui est pas déconnant)

    De plus celle ci ne seront pas toujours faites par des personnes ayant une connaissance approfondie de Java (c'est comme ça malheureusement....).
    Argument non recevable : si tu pars là dessus, tu ne peux jamais rien faire parce que tu ne connais jamais le niveau des gens qui passent derrière toi. Principe de responsabilité et de contrat : chaque objet passé doit implémenter correctement ton interface. Chacun son rôle. Pas à quelqu'un en bout de chaîne de mettre en place un bidule pour corriger les défauts des autres.

    Autres intérêts MAJEURS du système :
    - tu pourras mettre en place des tests unitaires simples pour chaque objet afin de valider leur bon fonctionnement (a chaque modification de la classe d'un objet de modifier son test pour valider qu'il est correct)
    - chaque classe pourra avoir ses propres exceptions de différences (du genre si tu ne veux pas qu'un champ soit testé)

Discussions similaires

  1. Réponses: 10
    Dernier message: 11/05/2014, 15h19
  2. Réponses: 1
    Dernier message: 27/04/2012, 16h41
  3. Gestion des Nombres complexes
    Par Lalanne dans le forum C++
    Réponses: 6
    Dernier message: 16/09/2009, 10h52
  4. Gestion de BDD remplies avec des listes.
    Par Nilsico dans le forum Optimisations
    Réponses: 1
    Dernier message: 26/04/2009, 01h42
  5. Gestion des Beans
    Par Dr@ke dans le forum JSF
    Réponses: 16
    Dernier message: 10/10/2007, 17h55

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