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

CORBA Discussion :

Problème d'union dont certains champs ne sont pas renseignés


Sujet :

CORBA

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut Problème d'union dont certains champs ne sont pas renseignés
    Bonjour,

    Depuis quelques jours, je suis face à un problème que je ne peux pas résoudre. En effet, dans mon appli (sous Java avec jacORB), je souhaite utiliser des IDL d'entrée pouvant contenir des unions, dont les valeurs ne sont pas toutes renseignées. Exemple :

    enum myEnum {
    State0,
    State1,
    State2
    };

    union UnionPartial switch(::myEnum) {
    case ::State0 : string value0;
    case ::State2 : string value2;
    };

    Je souhaite récupérer la valeur de l'union dans un Any dans le cas où elle est dans l'etat "State1", donc dans le cas où le DynUnion n'a pas de membre actif (j'utilise la fonction set_to_no_active_member()) . Je met donc les valeurs de mon DynUnion comme il faut. Pour récupérer les valeurs lorsqu'on est en "State0" ou "State2", aucun problème ne se présente. Mais dans le cas de State1, lorsque je manipule mon DynUnion, j'essaie de récupérer sa valeur via la fonction to_any(), qui bien sur me jette sur une NullPointerException.

    En regardant dans les sources de to_any() du DynUnion, j'ai remarqué que jacORB ne semble pas gérer le cas où il n'y a pas de membre actif. En effet, il fait appel au champ "member" du DynUnion, mais dans le cas du no_active_member "member" est censé être nul. Donc je m'y perds un poil.

    Donc j'imagine qu'il me manque une manipulation, et j'ai beau éplucher tout le net, je ne trouve pas de solution. Sauf peut être de redéfinir un to_any dans ce cas bien précis ?

    Si quelqu'un a un idée ou une simple piste, je suis preneuse,

    Merci beaucoup,

  2. #2
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Points : 193
    Points
    193
    Par défaut
    Tu peux utiliser le membre default de l'union :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    union UnionPartial switch(::myEnum) {
    case ::State0 : string value0;
    case ::State2 : string value2;
    default : 
      short Dummy;
    };
    Pour une valeur de l'enum non prise en compte par l'union, tu tomberas sur le champ par défaut. Ca t'evite de te retrouver avec une union qui ne contient rien.
    Par contre je ne saurais te dire quelle est la valeur du Dummy par défaut dans l'exemple, à tester.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par menator Voir le message
    Tu peux utiliser le membre default de l'union :

    Pour une valeur de l'enum non prise en compte par l'union, tu tomberas sur le champ par défaut. Ca t'evite de te retrouver avec une union qui ne contient rien.
    Par contre je ne saurais te dire quelle est la valeur du Dummy par défaut dans l'exemple, à tester.
    Le gros problème est que je ne peux pas modifier les IDL. Mon appli doit gérer ce genre de cas

    Mais merci tout de même !

  4. #4
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Points : 193
    Points
    193
    Par défaut
    c'est moi qui me perds dans ton objectif :
    avec has_no_activemember() (vu en J2SE 1.5) ou en récupérant le discriminant, tu dois etre capable d'identifier si l'union est renseignée ou non, et faire le traitement adéquat.

    Quand l'union n'est ni renseigné par un State2 ou un State0 tu te recuperes un membre null, OK normal.
    Mais je ne saisi pas pourquoi tu parles de State1, vu que ton union ne peux pas contenir de State1.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par menator Voir le message
    c'est moi qui me perds dans ton objectif :
    avec has_no_activemember() (vu en J2SE 1.5) ou en récupérant le discriminant, tu dois etre capable d'identifier si l'union est renseignée ou non, et faire le traitement adéquat.

    Quand l'union n'est ni renseigné par un State2 ou un State0 tu te recuperes un membre null, OK normal.
    Mais je ne saisi pas pourquoi tu parles de State1, vu que ton union ne peux pas contenir de State1.
    Ah voila, le problème est là. Donc, bien que mon discriminant ait un champ "State1", mon union ne peut en aucun cas prendre cette valeur ?

    Je pensais que les deux cas suivants (UnionTest1 et UnionTest2) étaient identiques en fait, et que les champs manquants étaient "induis". Donc c'est complètement différent ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            union UnionTest1 switch(::myEnum) {
                        case ::State0 :     string value1;   
                        case ::State1 :
                        case ::State2 :    string value2;
            };
    	
            union UnionTest2 switch(::myEnum) {
                        case ::State0 :    string value0;
                        case ::State2 :    string value2;
            };
    Merci,

  6. #6
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Points : 193
    Points
    193
    Par défaut
    Effectivement les 2 unions que tu cites sont differentes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    union UnionTest2 switch(::myEnum) {
                        case ::State0 :    string value0;
                        case ::State2 :    string value2;
            };
    exprime que les valeurs de discriminant State0 ou State2 sont associées à un membre. Le membre State1 de l'enum n'est associé à aucun membre. Dans du code standard, tu ne pourras pas initialiser l'union avec un discriminant State1 + une valeur de membre.

    Par contre mettre une valeur de discriminant hors de celles precisées pour le switch (don State1 ici) et sans membre, semble possible si l'union n'a pas de valeur par défaut et ne definit pas toutes le valeurs possibles, en utilisant :
    - la methode _default(myEnum.State1)
    - un DynUnion, voir (*) ci-dessous.

    L'autre union que tu cites est un cas spécial, pour factoriser une déclaration de membre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    union UnionTest1 switch(::myEnum) {
                        case ::State0 :     string value1;   
                        case ::State1 :
                        case ::State2 :    string value2;
            };
    Tu précises explicitement que le discriminant State0 est associé a value1 et que State1 et State2 sont associés à value2.

    (*) avec un DynUnion, les liens suivants nous suggerent que l'on peut forcer le discriminant a une valeur non declarée dans l'union, comme tu le fais avec set_to_no_member()
    http://www.iona.com/support/docs/e2a...on.html#271488
    https://java.sun.com/j2se/1.5.0/docs...active_member()

    - valable uniquement si l'union n'a pas de default ou n'utilise pas toutes les valeurs possibles du discriminant.
    -> le membre n'existe pas, tu te prends une exception si tu tentes de le recuperer.

    Donc je suis allé un peu vite, dans ton cas (UnionTest2) tu peux effectivement avoir State1 comme valeur de discriminant, mais sans membre associé.
    Par contre si l'union a une valeur par defaut, ou si l'union utilise toutes les valeurs de l'enum, cette possibilité disparait.
    Merci les unions

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut
    Ah oui merci ! Du coup je comprends beaucoup mieux.

    Donc en admettant qu'on utilise la méthode _default() pour State1. Je tombe dans un problème nettement plus compliqué si j'ai deux (ou plus) cas non référencés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            enum myEnum {
                        State0,
                        State1,
                        State2,
                        State3
                      };
    	
    	        union UnionTest switch(::simpleEnum) {
    	                    case ::State0 :    string value0;
    	                    case ::State2 :    string value2;
    	        };
    L'une des solutions, serait de changer la "valeur par défaut" du discriminant à chaque fois selon le cas selectionné.

    Autre petite question du coup : je ne vois pas comment utilier la méthode _default() via mon dynAny , j'ai beau cherché je vois pas...

    Encore merci pour le coup de main,

  8. #8
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Points : 193
    Points
    193
    Par défaut
    Tu peux passer en argument de UnionTest._default(valeur discriminant) la valeur du discriminant que tu souhaites fixer (State1 ou State3 puisqu'ils ne sont pas déclarés dans l'union).

    Les 2 méthodes _default()/_default(...) n'existent pas dans un DynUnion.
    Elles sont définies uniquement dans le mapping Java (par exemple), donc dans "UnionTest.java".

    En dynamique, tu as accès aux méthodes de DynUnion qui devraient te permettre de reproduire le même comportement que _default(...), par exemple avec set_discriminator(DynAny d).

    Je ne vois toujours pas bien pourquoi tu cherches a considérer des valeurs qui ne sont pas prévues dans l'Union. Côté serveur, les unions ayant des valeurs de discriminants hors du contrat défini par l'union devraient plutôt être ignorées.

    Et il te faut forcémment un traitement générique à base de Dyn* ?
    Cette API CORBA est certes puissante pour faire des outils génériques, mais franchement pénible

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par menator Voir le message
    Je ne vois toujours pas bien pourquoi tu cherches a considérer des valeurs qui ne sont pas prévues dans l'Union. Côté serveur, les unions ayant des valeurs de discriminants hors du contrat défini par l'union devraient plutôt être ignorées.
    Et il te faut forcémment un traitement générique à base de Dyn* ?
    J'avoue que cette API commence à abuser un peu de ma patience , mais bon...

    Sinon oui je suis obligée d'utiliser des Dyn* et de récupérer à partir de là l'Any correspondant pour ensuite l'envoyer via une requête... En fait je n'ai pas accès à ma classe directement, je ne traite qu'avec des Dyn* et des Any. Le principe marche pour tous les cas sauf celui-ci en fait.

    En fait, la raison pour laquelle j'utilise une union avec des champs non représentés, c'est que mon union peut être dans un état particulier ("State1" par exemple) sans pour autant avoir de valeur qui la représentent. Exemple
    mon union correspond a un système qui peut être

    + en état de chargement
    + en état éteint
    + en état allumé

    Dans le cas éteint, je n'ai pas besoin de valeur de représentation, donc je n'en ai pas, mais il m'arrive d'être tout de même dans cet état.

    Donc si on repasse maintenant au problème CORBA, quand je crée mon DynUnion, je fais un set_discriminator(mondynenum), au bon état (State1 toujours tant qu'a faire). La tout se passe bien. Je suis dans un état non représenté, donc member null (effet du set_discrimator). Et la impossible de récupérer mon Any pour cette raison justement... Le "to_any" de mon union utilise la valeur du discriminant et celle du member donc je me recupère une 'NullPointerException'.

    Voilaaaaa je patauge un peu

  10. #10
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 161
    Points : 193
    Points
    193
    Par défaut
    Voilaaaaa je patauge un peu
    Il me semble plutôt que tu as tout saisi.
    Tu sais identifier le cas "State1", il n'ya plus qu' ignorer le to_any() quand tu es sur un cas State1, vu que tu ne t'attends pas à récupérer une valeur.

    Non ? y'a encore un souci ?

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    90
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 90
    Points : 62
    Points
    62
    Par défaut
    Non ? y'a encore un souci ?
    Alors y'avait un souci, parce que je voulais quand meme récupérer la valeur en Any de mon Union. Mais du coup, on a trouvé ! Pour cela, l'astuce de derrière les fagots consiste à, au moment de la création du typecode de l'union (orb.create_union_tc), et plus précisement du tableau de members (UnionMember).

    Il suffit d'instancier de faire en sorte que chacun des états du discriminant (même ceux non représentés comme State1) a un member de l'union et de lui attitrer un typecode bidon comme label, au lieu du typeCode de sa représentation...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      member = new org.omg.CORBA.UnionMember();
      // discriminant value
       member.label = DiscrState1;
     // "human" representation
       member.name = "State1";
     // actual object type in the union for this value of the discriminant
       member.type = TypeCodeBidon;
       unionMembers[1] = member;
    Voila, donc ça fonctionne, mais c'est certainement pas la manière la plus propre.

    Merci en tout cas,

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème d'exclusion de certains champs de ma table
    Par diblasio dans le forum Requêtes
    Réponses: 4
    Dernier message: 27/05/2014, 14h23
  2. Réponses: 5
    Dernier message: 21/04/2007, 17h49
  3. Retourné des lignes dont certains champs sont vides
    Par griese dans le forum Langage SQL
    Réponses: 5
    Dernier message: 27/06/2006, 10h23
  4. UNION ? des lignes qui ne sont pas prises...
    Par fred23195 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/12/2005, 14h50

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