• Like
Assemblage par vues de composants
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Assemblage par vues de composants

  • 235 views
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
235
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
8
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Assemblage par vues de composants logiciels Alexis M ULLER Mémoire de DEA Informatique - Équipe GOAL Laboratoire d’Informatique Fondamentale de Lille Alexis.Muller@lifl.fr
  • 2. Remerciements Je tiens à remercier ici toutes les personnes qui m’ont permis de réaliser ce mémoire ainsi que toutescelles qui le liront. Je remercie donc Jean-Marc Geib, pour m’avoir permis d’effectuer mon stage de DEA dans son équipe.Je tiens à remercier tout particulièrement mes responsables, Olivier Caron, Bernard Carré et Gilles Van-wormhoudt pour ce qu’ils m’ont appris du métier de chercheur et pour toute la précieuse aide qu’ils m’ontapporté. Merci également à Jean-Luc Dekeyser pour m’avoir permis d’effectuer ce DEA. Merci aussi à toute l’équipe GOAL, ceux de mon bureau (Jean-François Roos, Bassem Kosayba, Em-manuel Renaux et Olivier Caron) et les autres, pour leur accueil et pour leur(s) machine(s) à café. Enfin merci à mes camarades de DEA, particulièrement Florent Fareneau, Stéphane Patureau et PatrickTessier d’avoir supporté mes blagues à l’heure du midi, ainsi que Jérémie Hattat pour avoir été mon binomeau premier semestre et pour nos soirées passées à . . . travailler.
  • 3. Table des matièresIntroduction 51 Problématique et positionnement 7 1.1 Composants, ACCORD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2 Vues, SOP / AOP, Catalysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3 Rapprochement vues/composants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4 Modèle, Méta-Modèle, MDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Le modèle abstrait 17 2.1 Le méta-modèle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.2 Description des éléments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3 Contraintes OCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Réalisation du Profil UML 21 3.1 Identification du sous-ensemble UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2 Les éléments du profil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Ciblage 25 4.1 Du modèle abstrait aux composants CCM . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.1.1 Le modèle de composants CORBA . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.1.2 Règles de transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.2 Du modèle abstrait aux composants EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.2.1 Le modèle de composants EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.2.2 Règles de transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34Conclusion et Perspectives 41A Le code J 45B La démarche MDA 57 1
  • 4. 2 Table des matières
  • 5. Table des figures1.1 Location de voitures - Approche objet . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.2 Location de voitures - Structuration par contextes . . . . . . . . . . . . . . . . . . . . . . 101.3 Bibliothèque universitaire - Approche objet . . . . . . . . . . . . . . . . . . . . . . . . . 111.4 Bibliothèque universitaire - Structuration par contextes . . . . . . . . . . . . . . . . . . . 111.5 Composant de recherche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.6 Location de voitures - Approche composants vues . . . . . . . . . . . . . . . . . . . . . . 131.7 Bibliothèque universitaire - Approche composants vues . . . . . . . . . . . . . . . . . . . 141.8 Les quatre niveaux de modélisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.9 Application de MDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.1 Le méta-modèle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.1 Méta-modèle virtuel des ExternalFeature . . . . . . . . . . . . . . . . . . . . . . . 223.2 Méta-modèle virtuel des ViewClass . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.3 Méta-modèle virtuel des viewOf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.4 Méta-modèle virtuel des ViewAttribute . . . . . . . . . . . . . . . . . . . . . . . . . 233.5 Méta-modèle virtuel des ViewAssociation . . . . . . . . . . . . . . . . . . . . . . . 233.6 Méta-modèle virtuel des Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.7 Le module Objecteering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244.1 Composant abstrait CCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264.2 L’architecture EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314.3 Modèle abstrait vers EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3
  • 6. 4 Table des figures
  • 7. Introduction Il existe aujourd’hui plusieurs modèles technologiques de composants : CCM (OMG), EJB, .NET, ...Le problème de l’hétérogénéité de ces modèles se pose aujourd’hui et une recherche consiste à définir unmodèle abstrait commun de composants et d’assemblage par contrats, comportant des spécifications dehaut niveau, indépendantes des plates-formes technologiques. Les moyens d’expression de l’assemblage, pour spécifier un système d’information dans son entier,restent assez pauvres et l’assemblage n’est généralement pas représenté. Le contrat d’assemblage d’uncomposant se limite souvent à une interface de services unitaires. Nous proposons ici une approche de laproblématique de l’assemblage, guidée par la conception par vues de systèmes d’information (SI). Ce mode de conception favorise le découpage fonctionnel de SI en rapport avec un référentiel d’enti-tés qui le caractérise. Chaque vue décrit une fonction du système. Par exemple, un système d’informationd’entreprise peut se décomposer en grandes fonctions : comptable, commerciale, décisionnelle, ... Les sys-tèmes de vues ont été très étudiés dans le monde des bases de données à objets, en particulier dans l’équipe[1]. Il s’agit ici de structurer modulairement le schéma du système d’information en schémas vues (corres-pondant aux fonctions du système), d’en gérer la cohérence et les interactions. Une telle conception vise latraçabilité des besoins fonctionnels (localisés dans les vues correspondantes) et l’évolution du système pargreffage de nouvelles vues. Ces qualités sont pour beaucoup communes aux deux approches et l’idée consiste à faire le lien entre lanotion de vues fonctionnelles et la notion de composants métiers et d’appliquer les principes de compositionde vues au problème de l’assemblage de tels composants. Les bénéfices espérés sont réciproques. Lescomposants apportent leurs propriétés d’autonomie, d’auto-description, de réutilisation et de dynamicité.La conception par vues apporte quant à elle des règles d’assemblage de vues métiers pour former un SIdans son entier. Dans un premier temps nous présentons, brièvement, les notions de composants et de vues, position-nons notre travail dans ce paysage et introduisons les notions de modèle, méta-modèle et l’approche MDA.Nous détaillons ensuite, dans le deuxième chapitre, le modèle abstrait et le méta-modèle virtuel que nousavons réalisés. Les chapitres suivants présentent respectivement leur mise en œuvre par le profil UMLcorrespondant et le ciblage de l’exemple vers les plates-formes EJB et CCM (IDL3). Enfin, nous discu-tons des perspectives d’évolutions de notre approche que nous pouvons attendre du travail sur le MDA,notamment la version 2.0 d’UML, qui doit introduire la notion de composant, ainsi que les techniques detransformation de modèles. 5
  • 8. 6 Introduction
  • 9. Chapitre 1 Problématique et positionnement1.1 Composants, ACCORD L’origine des composants logiciels n’est pas nouvelle. Certains pensent qu’ils ont toujours existé sousdifférentes formes pour la construction de systèmes logiciels [2]. Pour d’autres cette notion est apparuedans les années 70 en réponse à la deuxième crise du logiciel afin de réduire les coûts et d’améliorer laqualité des logiciels [3]. L’idée des composants logiciels s’inspire largement de ce qui existe dans les autres domaines industriels(électronique, automobile...), le but est de pouvoir concevoir une application par assemblage comme onassemble un téléviseur ou une voiture, à l’aide de composants existants en limitant les développementsspécifiques au strict minimum. Si cette capacité de réutilisation avait été attribuée à la programmationobjet, du fait du très bas niveau de mise en œuvre (celui du code source), elle n’a jamais pu être réellementutilisée sauf pour des structures de données simples (listes, piles, ...) ou pour des traitements très “standard”(comme les services objets communs de CORBA [4]) ainsi que dans le domaine des interfaces hommes-machines (IHM). En se plaçant à un niveau de granularité beaucoup plus important, la conception parcomposants logiciels doit permettre la réutilisation de structures plus complexes et ce de façon naturelleen les rendant disponibles le plus tôt possible dans le cycle de vie. Ce type de composants, suffisammentcomplexes pour contenir un certain “savoir faire”, est appelé composant métier. Ce sont eux qui noussemblent le plus intéressant et que nous considérons dans notre approche.Les bénéfices attendus sont multiples : – Diminuer considérablement les coûts et le temps de conception en généralisant la réutilisation ou l’achat de composants déjà réalisés. – Augmenter la fiabilité des logiciels par l’utilisation de composants largement testés. – Faciliter et réduire les coûts de maintenance et d’évolution des systèmes, par le remplacement de composants. – Enfin, rentabiliser les développements par la vente de COTS Component (Commercial-off-the-shelf Component ou composants sur étagère).Il n’y a pas encore de définition consensuelle dans le domaine des composants comme c’est le cas pour lesobjets. Cependant, la vision minimale suivante est toujours retenue. Un composant logiciel est une unité quirend des services grâce à des interfaces externes et utilise d’autre services grâce à des interfaces requises.Afin d’obtenir un système complet il faut donc assembler un certain nombre de composants en reliant leursinterfaces externes et leurs interfaces requises. C’est pour cette phase d’assemblage qu’il reste encore beaucoup de problèmes à résoudre. Commentformaliser les connexions entre les composants ? Comment décrire un système dans son ensemble ? Ilexiste pour répondre à ces questions plusieurs travaux de recherche notamment sur les ADL (ApplicationDefinition Language) [5]. Cependant, ils imposent l’utilisation (et donc l’apprentissage) de leur proprelangage. D’autres problèmes sont à résoudre si l’on souhaite réellement profiter de la grande promesse 7
  • 10. 8 Chapitre 1. Problématique et positionnementdes composants, c’est à dire la réutilisation. En effet, il faut être capable de choisir les composants quirépondent à nos besoins et de savoir si ils sont “compatibles”. Actuellement, la description d’un composantest le plus souvent résumée à la liste de ses interfaces, ce qui est insuffisant pour espérer “comprendre” lecomposant. Il devient donc indispensable de développer la notion de contrat. Ces contrats doivent décrireles besoins et capacités d’un composant, mais il n’existe pas encore de méthode formelle pour les spécifier.De plus, les méthodes de conception actuelles ne sont pas adaptées [3], elles poussent le plus souvent àspécifier des composants alors qu’ils sont, la plupart du temps, déjà disponibles. Pour répondre à ces problèmes et du fait de l’hétérogénéité des modèles technologiques de composants,une recherche consiste à définir un modèle abstrait commun de composants et d’assemblage par contrats.L’équipe participe à ce titre à un projet national (RNTL ACCORD pour “Assemblage de Composants parContrats en environnement Ouvert et Réparti”) visant à définir un tel modèle abstrait et ses projectionstechnologiques, en particulier vers CCM et EJB. Pour qu’un modèle de composants permette réellement la réutilisation, il doit fournir les moyens despécifier des composants génériques et de représenter leur configuration. La généricité est le concept parlequel un composant peut être défini indépendamment des contextes dans lesquels il sera utilisé. La confi-guration, au contraire, permet d’intégrer le composant dans un contexte particulier. Il apparaît donc que cesdeux concepts soient indissociables et indispensables.1.2 Vues, SOP / AOP, Catalysis Dans l’approche CROME [1] qui constitue le point de départ de ce mémoire, le mécanisme des vuespermet à chaque utilisateur de manipuler un système avec une vision qui lui est propre, adaptée en fonctionde ses besoins. Dans cette approche, le schéma de base correspond aux éléments communs aux différentesfonctions du système. Les schémas vues quant à eux ajoutent au schéma de base un certain nombre d’élé-ments propres à leur fonction. Cette approche permet de tenir compte de l’orthogonalité objets/fonctions.En effet, pour un système donné les objets peuvent intervenir dans plusieurs fonctions et celles-ci peuventutiliser un certain nombre d’objets. Mais il est évident que tous les objets n’interviennent pas dans toutes lesfonctions de même les fonctions n’utilisent pas systématiquement tous les objets [6, 7]. Si l’approche objetpermet de découper naturellement le système en entités distinctes, elle ne permet pas de séparer les diffé-rentes fonctions à l’intérieur des objets. Le mécanisme des vues ajoute ce découpage et rend ainsi possiblede concevoir les fonctions du système indépendamment des autres tout en garantissant leur compatibilité. Pour illustrer cette orthogonalité, considérons l’exemple d’un système de location de voitures (cf figure1.1). Grâce à l’approche objet, le découpage en entités distinctes est bien représenté, mais toutes les fonc-tions sont confondues. L’activité de gestion des voitures (transfering, add, remove) , par exemple, n’a pasd’intérêt à considérer la liste des clients. De même, l’activité consistant à rechercher à quelle agence est rat-tachée un client ne doit pas être perturbée par la durée ou le nombre de locations de celui-ci. Une approche“à la CROME” permet de séparer les fonctions du système et permet de les réaliser indépendamment lesunes des autres (cf figure 1.2). Les attributs communs à toutes les fonctions sont déclarés dans le plan debase, les autres attributs et méthodes sont déclarés dans le plan où ils sont utilisés. Prenons en exemple laclasse Agency, les attributs Name et adresse, qui sont utiles à toutes les fonctions du système, sont déclarésdans le plan de base. L’attribut capacity et les méthodes add, transfering et remove, qui ne servent qu’à lagestion des ressources, sont déclarés dans le plan correspondant. D’autres approches comme l’AOP [8] (Aspect-Oriented Progamming) ou le SOP [9] (Subject-OrientedProgramming) permettent de mieux découper les systèmes en “séparant les préoccupations” (sécurité, au-thentification...). Elles suggèrent de développer séparément les différentes fonctions du système puis deles assembler, cette étape est appelée le tissage. Contrairement à la conception par vues, qui s’applique auniveau conception, la programmation par aspects (comme son nom l’indique) est destinée à être utiliséeau niveau des langages de programmation. Clarke [9] propose le découpage d’un système en activités auniveau modèle, à l’aide du langage UML. Chaque activité est représentée par un paquetage indépendant.Celui-ci contient uniquement les éléments nécessaires à son activité. Contrairement à l’approche par vues,il n’y a pas de paquetage de référence, si un élément est utile à plusieurs paquetages, il est représenté danschacun d’eux. L’application complète peut être retrouvée par “l’assemblage” de tous les paquetages autravers d’un jeu d’opérateurs de composition (override, merge, ...), la correspondance entre les différents
  • 11. 1.2. Vues, SOP / AOP, Catalysis 9 Base Agency Client Name Name adresse date own 0..* capacity phone adresse Client* findAll() Car* findAll() Agency location() void transfering(Client c) Client findByDate() void add(Agency a) Client findByName() void remove(Agency a) int nbRenting() manage 0..* reference Car immatriculation 0..* date constructor Rent model From Agency location() due_date Car findByDate() contain return_date 0..* Car findByImmatriculation() int nbRenting() bool free(date from, date to) F IG . 1.1 – Location de voitures - Approche objet
  • 12. 10 Chapitre 1. Problématique et positionnement Agency Client Car Rent att: Name, att: Name, att: date, model, Plan de date, phone, base adresse immatriculation, adresse constructor Plan de mth: findAll mth: location, recherche findByDate, client findByKey Plan de mth: findAll mth: location, recherche findByDate, voiture findByKey Plan de att: capacity gestion des mth: add, resources transfering, remove Plan de mth: free, att: att: From, locations nbRenting maximum_ due_date, duration return_date mth: nbRenting F IG . 1.2 – Location de voitures - Structuration par contexteséléments étant indiquée grâce à un nommage identique dans les différents paquetages. Dans l’approcheCatalysis [10], il est également question de découpage fonctionnel. Elle propose le découpage d’un schémaUML (par exemple, d’un système de ventes) en “composants à gros grains” (paiement, base de contact,vente...). D’après les auteurs, avant de penser à réutiliser des composants existants, nous avons besoin d’unmodèle spécifiant ce qu’ils font. Malheureusement, actuellement ils ne sont jamais accompagnés d’un telmodèle. L’approche Catalysis diffère de celles de CROME et de [9] par le fait que le découpage n’est paseffectué au niveau des attributs et des méthodes, mais au niveau des classes dans leur intégralité. L’assem-blage des composants est modélisé par les associations qui traversent les frontières des ces composants,c’est à dire, par les associations entre des classes ne faisant pas partie du même composant. Toutes ces approches permettent de mieux structurer le système en fonction de ses activités, maisn’apportent rien au niveau de la généricité. Il n’y a pas de réutilisation dans ces méthodes, tout doit êtreréévalué d’un système à l’autre.1.3 Rapprochement vues/composants Nous proposons de considérer les approches composants et vues dans un même modèle, la premièreapportant le principe de généricité et de configuration, la seconde, une méthode de structuration cohérenteet plus riche que l’approche objet traditionnelle. Pour illustrer les bénéfices d’une telle approche, considé-rons l’exemple d’une bibliothèque universitaire (cf figure 1.3). Il est possible de découper ce système encontextes comme nous l’avons fait pour l’exemple précédent (cf figure 1.4). Il apparaît ici clairement qu’uncertain nombre de fonctions sont communes aux deux systèmes, même s’ils utilisent des noms différents,et qu’il serait intéressant de pouvoir disposer de composants génériques pour les implémenter. L’approche conception par vues permet de représenter un système à base de composants en associant àchaque composant un schéma vue. Le schéma de base représente le système déjà en place auquel on sou-haite ajouter des fonctions par application de composants. Dans le cas d’un nouveau système, le schéma debase peut représenter le cœur de l’application, c’est à dire la partie “stable”, qui a peu de chance d’évoluerdans le temps. Notre modèle d’assemblage s’inspire donc largement de la notion de vues, cependant il diffère sur
  • 13. 1.3. Rapprochement vues/composants 11 Base Location Team indentifiant name adresse capacity Document* findAll() void transfering(ResourceOwner o) Researcher void add(Document r) name void remove(Document r) arrival_date publishes 1..* 0..* 0..* Document Rent Contain 0..* title From publication_date due_date return_date Location location() Document findByDate() Document findByKey() 0..* int nbRenting() reference bool free(date from, date to) Client Book Periodical name ISBN number inscription_date int nbRenting() F IG . 1.3 – Bibliothèque universitaire - Approche objet Location Client Document Rent Plan de att: adresse, att: Name, att: title, base identifiant inscription_ publication_date date Plan de mth: findAll mth: location, recherche findByDate, document findByKeyPlan de att: capacitygestion des mth: add,resources transfering, removePlan de mth: free, att: att: From,locations nbRenting maximum_ due_date, duration return_date mth: nbRenting F IG . 1.4 – Bibliothèque universitaire - Structuration par contextes
  • 14. 12 Chapitre 1. Problématique et positionnement <<Component>> Search <<ViewClass>> <<ViewClass>> DateResource Location identifiant <<ViewAttibute>> name <<ViewAttribute>> date <<ViewAttribute>> adresse <<ViewAttribute>> store 0..* Location location() DateResource* findAll() DateResource findByDate() DateResource findByKey() F IG . 1.5 – Composant de recherchecertains points. Contrairement à un schéma vue qui “importe” systématiquement tous les éléments duschéma de base, un composant vue doit préciser les éléments (classes, attributs, associations) du schémade base qu’il souhaite manipuler, il les contextualisent. L’interface requise correspond donc à un “schéma requis”, celui-ci est matérialisé par les ViewClass,ViewAttribute et ViewAssociation du composant (cf figure 1.5). Les éléments vues du compo-sant Search indiquent que celui-ci ne pourra s’appliquer qu’à un schéma de base contenant une classe(jouant le rôle de location) contenant au moins deux attributs pour matérialiser les ViewAttributeName et adresse, et une autre classe (jouant le rôle de DateRessource) avec des attributs matérialisant iden-tifiant et date. Ces deux classes devant être liées par une association pour matérialiser la ViewAssociationstore. La définition formelle des éléments vues ainsi que les règles auxquelles ils sont soumis sont détailléesdans le deuxième chapitre de ce mémoire. L’interface externe est quant à elle matérialisée par le schémaconstitué des éléments publiques du composant. A partir des exemples précédents, il est possible d’extraire trois fonctions communes : recherche, ges-tion des ressources et location, et d’en faire des composants. Pour cela, il faut les rendre génériques etpouvoir les configurer afin de les appliquer aux deux exemples. Dans notre modèle, la généricité est intro-duite par l’utilisation d’éléments “externes” et la phase de configuration est représentée par un mécanismede connexion. Les modèles obtenus pour chacun des deux exemples sont représentés figure 1.6 pour l’agence delocation de voitures et 1.7 pour la bibliothèque universitaire. L’application d’un composant vue à la base sefait par la connexion entre chaque ViewClass du composant et la classe de la base qui la matérialise. Cesconnexions sont représentées sur les figures par les flèches pointillées. Pour être complètes, les connexionsdoivent également être effectuées entre chaque ViewAttribute et l’attribut de la base qui le matérialise,de même pour les ViewAssociation et les associations (ces connexions ne sont pas représentées parsouci de clarté). Les connexions, pour être valides, doivent vérifier un certain nombre de contraintes. Celles-ci sont détaillées pour chaque élément vue dans le deuxième chapitre. On retrouve dans les deux exemples les mêmes composants fonctionnels Search, ResourceManager etRenting, ce qui illustre leur réutilisation sur différentes bases. La généricité permet également d’utiliser lemême composant à plusieurs “endroits” de la même application, illustré ici par l’application du composantSearch entre Agency et Car et entre Agency et Client dans le premier exemple. De façon conforme àl’approche par vues, les données spécifiques à une fonction particulière du système sont regroupées dans lecomposant correspondant (la classe Rent par exemple fait partie du composant Renting et non de la base).
  • 15. 1.3. Rapprochement vues/composants 13 <<Component>> Search <<ViewClass>> <<ViewClass>> DateResource Location identifiant <<ViewAttibute>> name <<ViewAttribute>> <<ViewAssociation>> date <<ViewAttribute>> adresse <<ViewAttribute>> store 0..* Location location() DateResource* findAll() DateResource findByDate() DateResource findByKey() <<Component>> Search <<Component>> ResourceManager Base <<ViewClass>> <<ViewClass>> ResourceOwner Location Client Agency identifiant <<ViewAttribute>> name <<ViewAttribute>> Name Name own capacity 0..* date adresse <<ViewAttribute>> adresse phone void transfering(ResourceOwner o) DateResource* findAll() adresse void add(Resource r) <<ViewAssociation>> void remove(Resource r) store manage 0..* <<ViewAssociation>> 0..* <<ViewClass>> manage Car DateResource 0..* immatriculation identifiant <<ViewAttibute>> date <<ViewClass>> date <<ViewAttribute>> constructor Resource Location location() model identifiant <<ViewAttribute>> DateResource findByDate() DateResource findByKey() <<Component>> Renting Rent From due_date return_date 0..* 0..* contain reference <<ViewClass>> <<ViewClass>> Product Client identifiant <<ViewAttribute>> identifiant <<ViewAttibute>> maximum_duration int nbRenting() bool free(date from, date to) int nbRenting() F IG . 1.6 – Location de voitures - Approche composants vues
  • 16. 14 Chapitre 1. Problématique et positionnement <<Component>> ResourceManager <<ViewClass>> ResourceOwner <<ViewClass>> <<ViewAssociation>> Resource identifiant <<ViewAttribute>> capacity identifiant <<ViewAttribute>> store 0..* void transfering(ResourceOwner o) void add(Resource r) <<Component>> Search void remove(Resource r) <<ViewClass>> Base Location name <<ViewAttribute>> adresse <<ViewAttribute>> Location Team DateResource* findAll() indentifiant adresse name <<ViewAssociation>> store 0..* <<ViewClass>> 0..* DateResource Researcher Document identifiant <<ViewAttribute>> name title 0..* publishes 1..* date <<ViewAttribute>> arrival_date AddToBase publication_date Location location() Client DateResource findByDate() DateResource findByKey() name inscription_date Book Periodical ISBN number <<Component>> Renting Rent From due_date return_date 0..* 0..* contain reference <<ViewClass>> <<ViewClass>> Product Client identifiant <<ViewAttribute>> identifiant <<ViewAttibute>> int nbRenting() int nbRenting() bool free(date from, date to) F IG . 1.7 – Bibliothèque universitaire - Approche composants vues
  • 17. 1.4. Modèle, Méta-Modèle, MDA 15 Il existe des entités qui Niveau M3 Méta-méta-modèle peuvent avoir des relations entre elles Une classe désigne un Niveau M2 Méta-modèle ensemble d’objets qui peuvent avoir des attributs Une voiture a une couleur Niveau M1 Modèle et une immatriculation Cette voiture Niveau M0 Instances rouge immatriclée 12 XY 59 F IG . 1.8 – Les quatre niveaux de modélisation1.4 Modèle, Méta-Modèle, MDA Nous décrivons notre modèle abstrait à l’aide d’un méta-modèle, nous introduisons donc ici les basesdes techniques de modélisation et de méta-modélisation avant de le détailler. Les méthodes de méta-modélisations sont basées sur quatre couches [11] (cf figure 1.8). Chaque niveau est décrit à l’aide du niveausupérieur. Le niveau M0 correspond à celui des instances, aux données réellement manipulées. C’est, parexemple, à ce niveau qu’est décrit une voiture particulière, immatriculée ’12 XY 59’, de couleur rouge...Le niveau M1 est celui des modèles, c’est lui qui est utilisé pour concevoir un logiciel. Un diagramme écriten UML correspond à ce niveau. Pour reprendre notre exemple, c’est le niveau qui définit le type voiture,qu’elle doit avoir une immatriculation, une couleur... On ne décrit pas une voiture en particulier mais sonconcept. Le niveau M2 est le niveau des méta-modèles, c’est par exemple à ce niveau qu’est décrite lasyntaxe du langage UML, le fait qu’une classe a un nom, qu’elle est composée d’attributs... Le dernierniveau, M3, a la particularité de se décrire lui même. Il serait sinon possible d’avoir une infinité de niveaux.Ce niveau est celui des méta-méta-modèles, c’est certainement le niveau le plus difficile à comprendre. Ilpermet de décrire le niveau M2, qu’il existe des entités (classes, attributs...) qui peuvent avoir des relationsentre elles. Pour résumer, on peut dire que le niveau M0 correspond à une application en cours d’exécution,le niveau M1 au schéma UML d’une application en particulier, le niveau M2 à la façon de représenter uneapplication en général et enfin le niveau M3 à introduire les concepts nécessaires au niveau M2. Il existe deux grandes techniques de méta-modélisations, le MOF (Meta Object Facilities) [12] et lesprofils UML. Le MOF est un langage de niveau M3, il permet donc d’introduire de nouveaux concepts pourle niveau M2. La méta-modélisation par profils est une technique plus “légère” prévue par le langage UML,elle ne permet pas vraiment d’introduire de nouveaux méta-concepts mais de spécialiser, en les étiquetantpar des “stéréotypes”, les méta-concepts existants. L’approche MDA (Model Driven Architecture) [13, 14, 15] de l’OMG (Object Managment Group) [16]définit une méthode de conception basée sur les modèles permettant d’obtenir à partir d’un schéma de baseunique sa réalisation sur n’importe quelle plate-forme (supportée par le MDA). La principale motivationest de rester indépendant d’un système donné afin de suivre l’évolution des technologies et des intergicielssans perdre ce qui a déjà été réalisé. Pour obtenir ce résultat, le MDA introduit deux types de modèles : les PIMs (Platform IndependentModel) qui doivent représenter l’application en utilisant uniquement des concepts indépendants de toutesplates-formes, et les PSMs (Platform Specific Model) qui sont des projections des PIMs pour une plate-forme donnée. Nous avons réalisé dans le cadre du projet ACCORD un état de l’art de l’approche MDA,celui-ci est disponible en annexe de ce mémoire. En proposant une approche qui définit un modèle de composants abstraits (PIM) tout en permettant saprojection vers des plates-formes existantes (PSM), nous respectons la philosophie du MDA. De plus, enutilisant l’UML et les profils, nous sommes “compatibles” avec les choix technologiques de l’OMG, cequi facilite l’utilisation de notre modèle (outils, XMI...). La figure 1.9 illustre l’articulation des différentsmodèles dans notre approche. L’interconnexion de nos composants au niveau PIM permet l’interopérabilitéau niveau binaire.
  • 18. 16 Chapitre 1. Problématique et positionnement View UML Base UML connexion vérification des contraintes PIM PSM Modèle CCM avec XML+ associations IDL Java XML Binaire Binaire Base Binaire Base Binaire CCM EJB(++) CCM EJB(++) BDR F IG . 1.9 – Application de MDA
  • 19. Chapitre 2 Le modèle abstrait2.1 Le méta-modèle La figure 2.1 représente les concepts du modèle de composant vues. Ce méta-modèle introduit la notionde connexions entre un élément et sa vue, grâce aux associations viewOf et root.Les sémantiques de ces deux types de relation sont différentes. Une association viewOf indique quel’élément source (de type Component ou ViewClass) est une extension de l’élément qu’il désigne(respectivement de type Package ou Class). Par contre, une association root signifie que l’élémentsource (de type ViewAttribute ou ViewAssociation) n’est qu’une représentation de l’élémentdésigné (respectivement de type Attribute ou Association). Dans ce modèle, un composant est donc un ensemble de ViewClass et de Class que l’on peutappliquer à un ensemble (Package) de Class. Grâce au mécanisme de connexions, un composant peutêtre modélisé indépendamment des Package sur lesquelles il sera appliqué. Les seuls règles à suivrelors de cette phase de modélisation sont décrites par les règles de conception, néanmoins pour que lesystème obtenu par la “fusion” des Package et des Component soit cohérent, les règles de connexiondoivent être vérifiées. Ce découpage correspond respectivement aux phases de conception et d’assemblagedu composant. Les contraintes OCL sont présentées pour chacun des concepts à la fin de ce chapitre.2.2 Description des élémentsComponent Un Composant est une spécialisation de la méta-classe UML Package. Son rôle est de regrouper toutes les ViewClass, Class ainsi que tout autre élément UML nécessaire à la modé- lisation du composant.ViewClass Une ViewClass est une spécialisation de la méta-classe UML Classifier. Une instance de celle-ci peut contenir les mêmes éléments qu’un autre Classifier ainsi que des ViewAttribute. L’association viewOf (entre une ViewClass et une Class) indique dans quelle Class les Attribute racine (root) des ViewAttribute de la ViewClass doivent se trouver. Pour reprendre l’analogie avec la structuration par contextes, une Class correspond au plan de base et, une ViewClass qui lui est connectée correspond à son extension dans un autre plan.ExternalFeature et ExternalStructuralFeature Une ExternalFeature est un élément abstrait consti- tuant d’un Classifier au même titre qu’une StructuralFeature ou qu’une BehavioralFeature, son rôle est de désigner, par l’association root, une autre Feature. L’élément ExternalStructuralFeature spécialise ExternalFeature en imposant une StructuralFeature comme racine (root). 17
  • 20. 18 Chapitre 2. Le modèle abstrait Component Package (from UML) 0..* +viewOf AssociationEnd (from UML) 0..* isNavigable * Association (from UML) ordering Classifier (from UML) +connection aggreagation +participant +association targetScope 2..* * * multiplicity changeability +specification +specifedEnd visibility +root 0..1 0..* 0..* +owner ViewAssociation +type +feature Feature (from UML) ownerScope ViewClass Class (from UML) 0..* visibility isActive +viewOf connection 0..* +root 0..* StructuralFeature (from UML) ExternalFeature multiplicity changeability targetScope ExternalStructuralFeature Attribute (from UML) initialValue ViewAttribute F IG . 2.1 – Le méta-modèle Ce sont les éléments de base de notre modèle, qui permettent “d’importer” des données de l’exterieur et qui permettent ainsi la conception du composant.ViewAttribute Un ViewAttribute est un ExternalStructuralFeature dont le lien racine (root) ne peut porter que sur un Attribute. Un ViewAttribute ne peut appartenir qu’à une ViewClass. C’est le seul élément de type ExternalFeature qui ne soit pas abstrait, donc le seul à pouvoir apparaître dans un modèle de conception.ViewAssociation Une ViewAssociation est une spécialisation de la méta-classe UML Association. Une instance de celle-ci permet de contextualiser une Association du Package auquel s’ap- plique (par le lien viewOf) le Component. Une ViewAssociation est utilisée dans un composant pour “imposer” et manipuler l’Association conrrespondante entre les classes de la base.2.3 Contraintes OCLExternalFeature et ExternalStructuralFeatureContraintes de conception [1] La racine d’un ExternalStructuralFeature doit être un StructuralFeature.self.root.oclIsKindOf(StructuralFeature);
  • 21. 2.3. Contraintes OCL 19ViewClassContraintes de conception [2] Toutes les ViewClass doivent être dans un Component.self.package.oclIsKindOf(Context);Contraintes de connexion [3] Tous les ViewAttribute d’une ViewClass doivent avoir le même propriétaire de leur racine que laviewOf.self.allFeatures->select( f | f.oclIsKindOf(ViewAttribute) ) ->forAll ( f : ViewAttribute | f.root.owner = self.viewOf );ViewAttributeContraintes de conception [4] Le propriétaire d’un ViewAttribute doit être une ViewClass.self.owner.oclIsKindOf(ViewClass);Contraintes de connexion [5] Le propriétaire de la racine d’un ViewAttribute doit être une Class.self.root.owner.oclIsKindOf(Class);ViewAssociationContraintes de conception [6] Une ViewAssociation ne peut être que dans un Componentself.namespace.oclIsKindOf(Context);Contraintes de connexion [7] S’il existe dans le Component une ViewClass dont la viewOf participe à ViewAssociation.root alorscette ViewClass participe à la ViewAssociation.self.namespace.allContents->select( v | v.oclIsKindOf(ViewClass) ) ->forAll( v : ViewClass | self.root.allConnections->collect( type ) ->includes(v.viewOf) implies self.allConections->collect( type ) ->includes(v));ComponentContraintes de connexion [8] Toutes les ViewClass d’un Component doivent avoir le même Package de leur viewOf que la viewOfdu Component.self.allReferencedElements->select( v | v.oclIsKindOf(ViewClass) ) ->forAll ( v : ViewClass | v.viewOf.package = self.viewOf ); [9] Il ne peut pas y avoir deux ViewClass de la même Class dans un Componentself.allReferencedElements->select( v | v.oclIsKindOf(ViewClass) ) ->forAll ( v1, v2 : ViewClass | not v1.viewOf = v2.viewOf );
  • 22. 20 Chapitre 2. Le modèle abstrait [10] Si deux ViewClass (v1, v2) sont dans le même Component et qu’il y a une Association entrev1.viewOf et v2.viewOf alors il y a une ViewAssociation entre v1 et v2self.allReferencedElements->select( v | v.oclIsKindOf(ViewClass) ) ->forAll ( v1, v2 : ViewClass | v1.viewOf.allAssociations ->intersection(v2.viewOf.allAssociations)->size = v1.allAssociations->intersection(v2.allAssociations) ->select( va | va.oclIsKindOf(ViewAssociation) )->size);
  • 23. Chapitre 3 Réalisation du Profil UML Comme il a été présenté dans le premier chapitre, il existe deux méthodes de méta-modèlisation, leMOF et les profils. Nous présentons ici la réalisation de notre modèle abstrait grâce aux profils. Vous pour-rez trouver en annexe, la réalisation de celui-ci avec l’outil Objecteering de la société Softeam, partenairedu projet ACCORD. Actuellement, le langage OCL n’est pas supporté par cet outil, les contraintes ontdonc été traduites en J1 , le langage spécifique à Objecteering. Le module résultant de cette réalisation (cffigure 3.7), utilisable avec la version gratuite d’Objecteering, est disponible en ligne.(http ://www.lifl.fr/ mullera/ViewComponents.prof).  3.1 Identification du sous-ensemble UML Le profil de composant vues étend le paquetage UML core en se basant sur les méta-classes suivantes : – Package – Classifier – Feature – Class – StructuralFeature – Attribute – Association – Dependency3.2 Les éléments du profilLes ExternalFeature et ExternalStructuralFeature sont représentées dans notre profil UML par une Feature stéréotypée respectivement par «ExternalFeature» et «ExternalStructuralFeature». La valeur marquée de nom root s’applique au stéréotype «ExternalFeature» ainsi qu’aux stéréotypes héritant de celui-ci («ExternalStructuralFeature» et «ViewAttribute»). La valeur de type chaîne de caractères associée à ce tag contient le nom de la Feature racine de l’élément. Cette valeur marquée est indispensable pour représenter la connexion.Une ViewClass est représentée dans notre profil par une Class stéréotypée par «ViewClass». L’as- sociation entre une ViewClass et la Class à laquelle elle se réfère est représentée par une Dependency entre elles stéréotypée par «viewOf». 1 Disponible en annexe 21
  • 24. 22 Chapitre 3. Réalisation du Profil UML Stéréotype s’applique à Définition «ExternalFeature» Feature Indique que la Feature est externe. «ExternalStructural Feature Spécialise «ExternalFeature». Feature» Indique que la racine porte sur un élément structurel. Tag s’applique à Définition root «ExternalFeature» Nom d’une Feature Désigne la racine de l’élément.TAB . 3.1 – Stéréotypes et valeurs marquées pour les méta-types ExternalFeature etExternalStructuralFeature. <<baseElement>> Feature {From UML} «stereotype» ExternalFeature <<tagged value>> root: string <<baseElement>> «<<stereotype>>» ExternalStructuralFeature <<baseElement>> «stereotype» ViewAttribute F IG . 3.1 – Méta-modèle virtuel des ExternalFeature Stéréotype s’applique à Définition «ViewClass» Class Indique que la Class est une vue. «viewOf» Dependency Permet d’indiquer une dépendance entre une classe et sa vue. TAB . 3.2 – Stéréotypes pour le méta-type ViewClass. Classifier {From UML} <<baseElement>> «stereotype» ViewClass F IG . 3.2 – Méta-modèle virtuel des ViewClassUn ViewAttribute est représenté par un Attribute UML stéréotypé par «ViewAttribute». En spécialisant «ExternalStructuralFeature», le stéréotype «ViewAttribute» hérite de la valeur marquée root, qui doit ici contenir le nom d’un Attribute.
  • 25. 3.2. Les éléments du profil 23 Dependency {From UML} <<baseElement>> «stereotype» viewOf F IG . 3.3 – Méta-modèle virtuel des viewOf Stéréotype s’applique à Définition «ViewAttribute» Attribute Spécialise «ExternalStructuralFeature». Indique que l’attribut est une vue. TAB . 3.3 – Stéréotype pour le méta-type ViewAttribute. Attribute {From UML} <<baseElement>> «stereotype» ViewAttribute F IG . 3.4 – Méta-modèle virtuel des ViewAttributeUne ViewAssociation est représentée par une Association UML stéréotypée par «ViewAssociation». Une valeur marquée de nom root lui est appliquée. La valeur de type chaîne de caractères associée à ce tag contient le nom de l’Association racine. Celle-ci permet de manipuler, dans le composant, l’association définie dans le paquetage de base. Stéréotype s’applique à Définition «ViewAssociation» Association Indique que l’association est une vue. Tag s’applique à Définition root «ViewAssociation» Nom d’une Association Désigne la racine de la ViewAssociation. TAB . 3.4 – Stéréotypes et valeurs marquées pour le méta-type ViewAssociation. Association {From UML} <<baseElement>> «stereotype» ViewAssociation <<tagged value>> root: string F IG . 3.5 – Méta-modèle virtuel des ViewAssociationUn composant est représenté par un Package UML stéréotypé par «Component». Son application à un Package est représenté par une Dependency entre eux stéréotypée par «viewOf».
  • 26. 24 Chapitre 3. Réalisation du Profil UML Stéréotype s’applique à Définition «Component» Package Indique que le Package est un composant vue. «viewOf» Dependency Permet d’indiquer un dépendance entre un paquetage et un composant. TAB . 3.5 – Stéréotypes pour le méta-type Component. Package {From UML} <<baseElement>> «stereotype» Component F IG . 3.6 – Méta-modèle virtuel des Component F IG . 3.7 – Le module Objecteering
  • 27. Chapitre 4 Ciblage Pour tester notre modèle, nous avons mis en œuvre l’exemple de la bibliothèque universitaire présentéedans le premier chapitre sur les plates-formes CCM et EJB. La première réalisation (vers CCM) ne produitpas de code éxecutable, uniquement les spécifications (IDL 3) mais elle est entièrement automatisée. Laseconde (vers EJB) n’a pas fait l’objet d’une automatisation, mais a été entiérement spécifiée. Les sectionssuivantes présentent ces travaux.4.1 Du modèle abstrait aux composants CCM Nous proposons ici une génération automatique des descriptions UML des composants vues vers descomposants CCM. Plus précisément, l’atelier UML génère : – La spécification IDL3 des composants CCM issus d’un composant de base. – La spécification IDL3 des composants CCM issus d’un composant vue. – La spécification IDL3 des composants CCM d’assemblage entre un composant vue et un composant de base.Après une description succinte du modèle de composants CORBA (cf 4.1.1), nous détaillons les différentesrègles de transformation d’un schéma UML profilé vers la spécification IDL3 (cf 4.1.2).4.1.1 Le modèle de composants CORBA Les modèles à objets ont progressivement montré leurs limites. Certains industriels, comme Microsoft,Sun et l’OMG, ont fait évoluer leurs modèles vers les composants, dans le but de simplifier le dévelop-pement d’applications. La réponse de l’OMG [16] est le "CORBA Component Model" (CCM) modèle debase du futur standard CORBA 3 [17, 18, 19]. Dans un but de compatibilité ascendante, l’OMG a définison modèle de composants comme une extension du modèle objet de CORBA 2. Les composants CORBAreprésentent donc une spécialisation des objets CORBA tels que nous les connaissons aujourd’hui. La spé-cification de ce standard n’est pas encore achevée ; cependant, le chapitre sur le modèle de composants aété finalisé à l’OMG en janvier 2002. C’est donc l’un des plus jeunes modèles de composants mais aussil’un des plus riches en comparaison avec d’autres modèles. La spécification du CCM, qui représente plus de 1000 pages, est découpée en quatre modèles et unméta-modèle. Ce document décrit :Le modèle abstrait offre aux concepteurs le moyen d’exprimer les interfaces (fournies et utilisées) et les propriétés d’un type de composant. Pour cela, le langage OMG IDL a été étendu pour prendre en compte les nouveaux concepts introduits dans le CCM (le langage IDL3). Un type de composant (component) regroupe la définition d’attributs et de ports. Les attributs représentent les propriétés 25
  • 28. 26 Chapitre 4. Ciblage configurables du type de composant. Un port représente une interface (au sens CORBA 2) soit four- nie, soit requise, par le type de composant. Quatre types de ports sont définis dans le contexte du CCM : – Une facette est une interface fournie par un type de composant et qui est utilisée par des clients en mode synchrone. – Un réceptacle est une interface utilisée par un type de composant en mode synchrone. – Un puit d’événement est une interface fournie par un type de composant et utilisée par ses clients en mode asynchrone. – Une source d’événement est une interface utilisée par un type de composant en mode asynchrone. La figure 4.1 illustre un composant abstrait CCM doté de plusieurs ports. Référence de Réceptacle Composant Composant CCM Composant Implémentation Références des facettes Puit d’événement de facettes Source d’événement Composant Attributs F IG . 4.1 – Composant abstrait CCMLe modèle de programmation spécifie le langage CIDL (Component Implementation Definition Lan- guage) à utiliser pour définir la structure de l’implantation d’un type de composant, ainsi que cer- tains de ses aspects non-fonctionnels (persistance, transactions, sécurité). L’utilisation de ce langage est associée à un framework, le CIF (Component Implementation Framework), qui définit comment les parties fonctionnelles (programmées) et non-fonctionnelles (décrites en IDL / CIDL et générées) doivent coopérer. Il inclut aussi la manière dont l’implantation d’un composant interagit avec le conteneur.Le modèle de déploiement définit un processus qui permet d’installer une application sur différents sites d’exécution de manière simple et automatique. Ce modèle s’appuie sur l’utilisation de paquetages de composants, ainsi que de descripteurs OSD (Open Software Description, un vocabulaire XML), les paquetages étant déployables et composables.Le modèle d’exécution définit l’environnement d’exécution des instances de composants. Le rôle princi- pal des conteneurs est de masquer et prendre en charge les aspects non-fonctionnels des composants qu’il n’est alors plus nécessaire de programmer.4.1.2 Règles de transformation Pour la génération automatique, nous nous sommes basés sur le langage IDL3 permettant de décrire lemodèle abstrait CCM. De plus, nous nous sommes interressés uniquement aux ports synchrones du modèle(facettes et réceptacles).Génération du composant de base Le tableau 4.1 énumère la transformation de chaque concept UML vers des concepts IDL3. Un com-posant de base défini par un paquetage UML est spécifié par un module CCM.
  • 29. 4.1. Du modèle abstrait aux composants CCM 27Chaque classe UML de ce paquetage est spécifiée par un composant CCM, ce composant dispose d’unefacette décrite par une interface IDL contenant toutes les descriptions publiques (attributs et opérations) dela classe UML.Les attributs d’une classe sont transformés en attributs primitifs CORBA (l’atelier UML vérifiant que lesattributs définis dans le modèle sont des attributs simples). Ces attributs sont spécifiés dans l’interface cor-respondante à l’unique facette du composant CCM.Les opérations UML sont également transformées en opérations contenues dans l’interface IDL de la fa-cette du composantLes associations sont exprimées par des opérations primitives de manipulation de l’association (add, get, remove) définies dans l’interface IDL correspondante à la facette du composant. ces associations sontégalement gérées par l’introduction de réceptacles au niveau des composants participants à l’association(l’atelier UML se limite aux associations binaires) Concept modèle abstrait UML spécification IDL3 correspondante paquetage UML X module CCM X classe X component X doté d’une facette de nom serviceX de l’interface IX et d’une maison de composant homeX attributs publiques UML attributs IDL3 dans l’interface IX opérations publiques UML opérations IDL3 dans l’interface IX association UML opérations de gestion des associations, réceptacle pour l’extrémité de l’association. TAB . 4.1 – Correspondance composant UML de base et composants CCM Exemple : Nous illustrons cette génération par l’exemple de la bibliothèque universitaire et en selimitant aux classes UML Location et Document reliée par une association de nom manage, la spé-cification IDL3 générée par l’atelier UML est la suivante :module Base{ interface ILocation ; interface IDocument ; typedef sequence<IDocument> IDocuments ; interface ILocation { attribute string identifiant ; attribute string adresse ; public void addManage(IDocument value) ; public IDocuments getManage() ; public void removeManage(IDocument value) ; } ; interface IDocument { attribute string title ; attribute string publication_date ; public void setManage(ILocation value) ; public ILocation getManage() ; public void removeManage() ; } ; component Location { provides ILocation serviceLocation ; uses multiple IDocument manage ; } ;
  • 30. 28 Chapitre 4. Ciblage component Document { provides IDocument serviceDocument ; uses ILocation manage ; } ; home LocationHome manages Location { } ; home DocumentHome manages Document { } ;} ;Génération du composant vue Pour un composant vue, les règles de transformation définies pour un composant de base sont intégra-lement applicables pour les constructions UML standards. Le tableau 4.2 énumère la transformation de chaque concept UML étendu (viewClass, viewAttribute,. . .) vers des concepts IDL3. Une classe «viewClass» est spécifiée par un composant CCM, ce composant dispose d’une fa-cette décrite par une interface IDL contenant toutes les descriptions publiques (attributs et opérations) dela classe UML et dispose d’un réceptacle correspondant à toutes les descriptions requises (constructions«viewAttribute» et «viewAssociation»). Concept modèle abstrait UML spécification IDL3 correspondante «viewClass» X component X dotée d’une facette de nom serviceX de l’interface IX et d’un réceptacle de nom receptX de l’interface RX et d’une maison de composant homeX «viewAttribute» spécifié dans l’interface IX si public spécifié dans l’interface RX «viewAssociation» opérations de manipulation de l’association spécifiés dans l’interface IX et RX TAB . 4.2 – Correspondance composant UML vue et composants CCM Exemple : Pour illustrer la spécification IDL3 suivante décrit le composant vue resourceManager :module ResourceManager{ interface IResourceOwner ; interface IResource ; typedef sequence<IResource> IResources ; interface IResourceOwner { attribute string identifiant ; attribute long capacity ; public void addStore(IResource value) ; public IResources getStore() ; public void removeStore(IResource value) ; public void transfering(IResourceOwner o) ; } ; interface RResourceOwner { attribute string identifiant ; public void addStore(RResource value) ; public RResources getStore() ; public void removeStore(RResource value) ;
  • 31. 4.1. Du modèle abstrait aux composants CCM 29 } ; interface IResource { attribute string identifiant ; public void setStore(IResourceOwner value) ; public IResourceOwner getStore() ; public void removeStore() ; } ; interface RResource { attribute string identifiant ; public void setStore(RResourceOwner value) ; public RResourceOwner getStore() ; public void removeStore() ; } ; component ResourceOwner { provides IResourceOwner serviceResourceOwner ; uses RResourceOwner receptResourceOwner } ; component Resource { provides IResource serviceResource ; uses RResource receptResource ; } ; home ResourceOwnerHome manages ResourceOwner { } ; home ResourceHome manages Resource { } ;} ;Génération du composant d’assemblage Comme l’illustre les exemples, composants de bases et composants vues sont parfaitement indépen-dants. Les constructions UML détaillant la connexion d’un composant vue à un composant de base vontpermettre de générer les composants CCM d’assemblage : ce sont en fait, des composants adaptateurs quivont permettre de relier un réceptacle d’un composant CCM vue à la facette du composant CCM de base. Le pattern classique adaptateur [20] est utilisé pour les connexions comme le montre le code exemplesuivant permettant de connecter un composant vue X à un composant de base Y : component AdaptX_Y { provides RX serviceAdaptX ; uses IY receptAdaptY ; } Exemple : voici l’exemple du composant d’assemblage permettant de connecter le composant vueResourceManager au composant de base Base de la bibliothèque universitaire :import ResourceManager ;import Base ;module adapt{ component AdaptResourceOwner_Location {
  • 32. 30 Chapitre 4. Ciblage provides ResourceManager::RResourceOwner serviceAdaptResourceOwner ; uses Base::Ilocation receptAdaptLocation ; } ; component AdaptResource_Document { provides ResourceManager::RResource serviceAdaptResource ; uses Base::IDocument receptAdaptDocument ; } ; home AdaptResourceOwner_LocationHome manages AdaptResourceOwner_Location {} ; home AdaptResource_Documenthome manages AdaptResource_Document {} ;4.2 Du modèle abstrait aux composants EJB Dans cette section, nous présentons une seconde projection des composants de notre modèle abstrait.Il s’agit d’une projection vers la plate-forme EJB qui propose des composants orientés vers le développe-ment d’applications au-dessus d’un système d’informations d’entreprise. En plus de proposer des règlespour générer la spécification, des composants, cette projection introduit aussi des règles pour produire leurimplantation. La projection proposée produit le code Java d’implantation de composants EJB correspondant auxclasses ViewClass d’un composant connecté à un composant de base au niveau modèle. Un composantde notre modèle sera matérialisé par une archive empaquetant ces composants EJB avec des descripteursde déploiement1. Les composants EJB résultant de la projection présentent les caractéristiques suivantes 2 . – Ils sont connectables localement ou à distance avec des composants EJB implantant les classes du composant de base pour lesquels la connexion a été vérifiée ; – Ils mettent en oeuvre des traitements pour préserver la sémantique de vues à l’exécution ; – Ils sont manipulables pour les outils EJB standard d’empaquetage et de déploiement sur un serveur. – Ils définissent un schéma abstrait de persistance qui permet de définir un descripteur pour leur sau- vegarde (état, associations) dans une base de donnée quelconque.Dans la prochaine section, nous présentons les grandes lignes de la norme EJB. Cette partie permettrad’introduire les notions utilisées lors de la projection. Ces notions sont illustrées en implantant le composantde base de la bibliothèque sous forme de composants EJB. La section suivante décrit le choix de mise enoeuvre et les règles de générations qui en découlent pour les composants vues.4.2.1 Le modèle de composants EJB La norme EJB (Enterprise Java Bean) a été proposée par SUN Microsystems pour répondre aux be-soins de l’industrie en matière de construction de serveurs d’applications d’entreprise. Cette norme (quien est à sa version 2.0) décrit une architecture normalisée pour le développement et le déploiement de cesapplications à base de composants "Bean" écrits en Java. L’apport principal de cette norme est d’accorderune grande importance à la prise en change des aspects non fonctionnels requis par les composants de cetype d’applications à savoir la persistance des données, la sécurité et la gestion des transactions. Cette priseen charge permet au développeur de se concentrer sur les aspects métiers de ces composants. Un composant EJB est un ensemble de définitions JAVA (interfaces et classes) et des descripteurs XMLempaquetés - dans une archive de type jar - qui sont déployés sur un serveur d’applications. Le serveur 1 dans sa version actuelle, la projection ne produit pas le descripteur de déploiement des composants EJB mais cette opération esttout à fait envisageable 2 La production de composants EJB qui seraient génériques par rapport à plusieurs composants de base implantées avec descomposants EJB est envisageable mais réclame l’utilisation d’outils puissants comme la réflexivité. Nous laissons l’étude de telscomposants pour des travaux futurs
  • 33. 4.2. Du modèle abstrait aux composants EJB 31utilise les informations contenues dans le descripteur pour instancier le composant EJB dans un containerdont la fonction est de fournir une interface entre le composant et son environnement, prenant en charge uncertain nombre d’aspects non-fonctionnels. F IG . 4.2 – L’architecture EJB Un composant EJB offre des services exposés aux clients sous la forme d’une interface Java de typeEJBObject (pour des client distants) ou EJBLocalObject (pour des clients locaux, c’est-à-dire s’exécutantdans la même machine virtuelle). Un client d’un EJB peut être n’importe quel programme susceptible decommuniquer par le protocole RMI-IIOP et notamment un autre EJB ou encore un ensemble de servletet de pages JSP. Le container se charge de transformer les requêtes distantes du client en appels réels auxcomposants, en les enveloppant éventuellement dans un contexte transactionnel. Le code suivant présente l’interface de services proposée par des composants EJB implantant respecti-vement la classe Document et la classe Location appartenant au composant de base de notre exemple. Lesméthodes spécifiées par chaque interface donne accès aux attributs et aux associations définis à ce niveau.public interface Document extends EJBLocalObject{ public String getDocumentId(); public String getTitle(); public void setTitle(String title); public Date getPublicationDate(); public void setPublicationDate(Date d); public Location getLocation(); public void setLocation(Location loc); public Collection getAuthors(); public void addAuthor(Researcher r);}public interface Location extends EJBLocalObject{ public String getLocationId(); public String getAddress(); public void setAddress(String a); public Collection getDocuments(); public void addDocument(Document d);} A chaque composant EJB est également associée une maison de composant qui est chargée de laconstruction effective des composants, de leur destruction et éventuellement de leur recherche. Ces mai-sons correspondent à la notion bien connue de fabrique. Elles sont généralement localisables par un client,
  • 34. 32 Chapitre 4. Ciblagepar exemple au travers d’un service de nommage, et offre une interface uniforme de type EJBHome (des-tinée aux clients distants) ou EJBLocalHome (destinée aux clients locaux) pour la gestion des instances decomposants associés. Le code suivant présente les interfaces de fabrique pour la création (méthodes de nom "create") et larecherche (méthodes ayant un nom préfixé par "find") d’instances de composants EJB implantant respecti-vement la classe Document et la classe Location du composant de base.public interface LocalDocumentHome extends EJBLocalHome{ public Document create(String id, String title, Date publication Date) throws CreateException; public Document create(String id, String title, Date publicationDate, Location loc) throws CreateException; public Document findByPrimaryKey(String id) throws FinderException; public Document findByDate(Date d) throws FinderException;}public interface LocationHome extends EJBLocalHome{ public Location create(String id, String address) throws CreateException; public Location findByPrimaryKey(String id) throws FinderException;} La norme EJB définit trois types de composants qui se différentient principalement par rapport à leurutilité et la gestion de leur cycle de vie par le conteneur : il s’agit des beans "session", des beans "orientésmessage" (message-driven) et des beans "entité". Les bean "session" sont des composants existants pourune session demandée par le client. Ils peuvent être avec état ou sans état ce qui, dans ce dernier cas, permetau conteneur de les partager entre plusieurs clients (sous forme de pool). Les beans "orientés message" sontdes réceptables de messages asynchrones gérés par file d’attente. Les beans "entité" sont des composantsreprésentant des données d’une base de données dont ils permettent d’obtenir une vue orientée objet. Etant donné que les beans "entité" sont les seuls beans à être employés lors de la projection, nous nousfocalisons sur les caractéristiques de ce type de bean dans le reste de la présentation, notamment ceux quisont liées à la gestion de la persistance. L’association des beans "entité" avec les éléments d’une base de données leur confère deux caractéris-tiques principales. La première caractéristique est d’être identifié de manière unique par un clé primaire. La présence decette clé permet aux clients de rechercher un bean entité donné par sa clé primaire. Il suffit pour cela quele client s’adresse à la maison liée au bean. Cette clé primaire peut-être n’importe quel objet sérialisable. La seconde caractéristique est d’être persistant ce qui signifie que l’état du bean et ses associationsavec d’autres beans peuvent être sauvegardés dans la base de données. Pour la gestion de cette persistance,la norme EJB propose deux approches : une gestion par le bean et une gestion par le conteneur que nousprivilégions. Dans ce second cas, le container collabore avec le gestionnaire de la base pour mettre enoeuvre un schéma de persistence qui leur est fourni au travers du descripteur de bean. Schématiquement,le descripteur définit des sources de données, des champs de données et des relations (à la manière d’unschéma de base de données) qui sont identifiés au niveau de la classe d’implantation du bean par desméthodes d’accès abstraites nommées selon des conventions particulières. Il appartient au conteneur et augestionnaire de la base de créer et de mettre à jour effectivement et automatiquement les données lors de lacréation et l’exécution des beans. Le code suivant présente les classes d’implantation des composants EJB Document et Location (sanscode d’implantation pour plus de clarté). Ces classes héritent de EntityBean pour indiquer que ceux sont
  • 35. 4.2. Du modèle abstrait aux composants EJB 33des beans de type entité. Les différentes méthodes abstraites spécifiées par ces classes servent à indiquerles attributs et les associations qui composent le schéma abstrait de persistance 3 . Les méthodes dont le nom est préfixé par "ejb" sont des méthodes particulières destinées à être in-voquées par le conteneur à certaines étapes du cycle de vie du composant (création, destruction, sau-vegarde, rechargement). Ces méthodes présentent surtout un intérêt pour les beans gérant leur aspectsnon-fonctionnels, en leur permettant de réaliser les traitements correspondants. Dans le cas de bean géréautomatiquement par le conteneur, la plupart de ces méthodes possèdent généralement une implantationqui est vide (une exception est la méthode d’initialisation "ejbcreate" qui est invoquée par le conteneursuite à la création d’une instance de composant).public abstract class DocumentImpl implements EntityBean{ private EntityContext context; // Méthodes d’accès abstraites indiquant les attributs à sauvegarder public abstract String getDocumentId(); // accès à la clé primaire public abstract String getTitle(); public abstract void setTitle(String title); public abstract Date getPublicationDate(); public abstract void setPublicationDate(Date publicationDate); public abstract Location getLocation(); public abstract void setLocation(Location loc); // Méthodes d’accès abstraites indiquant les associations à sauvegarder public abstract Collection getAuthors(); public abstract void setAuthors(Collection authors); public abstract Location getLocation() public abstract void setLocation(Location loc) throws RemoteException { } // Méthodes métiers public void addAuthor(Researcher r) { ... } // Méthode pour la gestion par le conteneur public String ejbCreate(String id, String title, Date publicationDate, Location loc) throws CreateException { ... } public void ejbActivate() {} public void ejbPassivate() {} public void ejbLoad() {} public void ejbStore() {} public void ejbRemove() {} public void setEntityContext(EntityContext ctx) { } public void unsetEntityContext() { }}public abstract class LocationImpl implements EntityBean{ private EntityContext context; // Méthodes d’accès abstraites indiquant les attributs à sauvegarder public abstract String getLocationId(); // accès à la clé primaire public abstract String getAddress(); public abstract void setAddress(String address); 3 l’implantation de ces méthodes sera fournie automatiquement au niveau de la sous-classe générée par conteneur au moment dudéploiement. Il en est de même pour l’implantation des attributs et associations
  • 36. 34 Chapitre 4. Ciblage // Methodes d’accès abstraites indiquant les associations à sauvegarder public abstract Collection getDocuments(); public abstract void setDocuments(Collection documents); // Méthodes métiers public void addDocument(Document d) { ... } // Méthodes pour la gestion par le conteneur public String ejbCreate(String id, String address) throws CreateException { ... } public void ejbPostCreate(String ident, String address) {} public void ejbActivate() {} public void ejbPassivate() {} public void ejbLoad() {} public void ejbStore() {} public void ejbRemove() {} public void setEntityContext(EntityContext ctx) { } public void unsetEntityContext() { }} Les interfaces et la classe d’implantation forment l’ensemble du code d’un composant EJB. Pour pou-voir déployer le composant sur un serveur, il suffit de compiler ce code et l’empaqueter avec des descrip-teurs destinés à spécifier son schéma de persistance, ses caractéristiques transactionnelles, ses dépendanceséventuelles, des informations de nommage, . . .Ces opérations s’effectuent généralement au moyen d’outilsspécialisés.4.2.2 Règles de transformation Au cours de la section précédente, nous avons vu que les classes du composant de base sont classique-ment implantées par des composants EJB de type entité ce qui permet de gérer facilement la persistance.Nous nous sommes basés sur ce principe d’implantation pour choisir la mise en oeuvre des composantsvues de notre modèle. La solution adoptée pour implanter les composants vues du modèle repose sur une approche classiqued’implantation de vues sur une base d’objets existants [Vanwormhoudt99]. Cette approche consiste à re-présenter chaque vue d’un objet existant par un objet séparé et par conséquent à définir une classe par typede vue. Dans ce type d’approche, il existe généralement un lien de l’objet vue vers l’objet existant pourpouvoir réutiliser les caractéristiques de ce dernier au niveau de la vue. L’application de cette solution à notre contexte conduit à introduire un composant EJB de type entitépour chaque ViewClass définit dans le composant au niveau modèle et à représenter chaque vue associéeà une instance du composant de base par une instance de ce composant. Nous faisons également le choix deconnecter les instances de vues aux instances du composant de base. Cette connexion gérée au niveau desinstances de vue permettra notamment d’utiliser les caractéristiques offertes par les instances du composantde base pour l’implantation d’un ViewAttribute et d’une ViewAssocation. La figure 4.3 illustrel’application de ces principes à travers l’exemple du composant vue RessourceManagement connecté avecle schéma de base de gestion de bibliothèque. Cette figure montre qu’il existe un composant EJB pour chaque ViewClass du composant Ressource.Elle fait également apparaître la liaison de ces composants avec les composants EJB implantant la classede base associée. Le choix de représentation des vues décrit ci-dessus présente néanmoins deux problèmes qu’il fautgérer pour garantir l’intégrité de la représentation. Le premier problème est lié à l’existence d’une instance de vue qui est intimement liée à celle del’instance associée du schéma de base : une instance de vue n’a pas de raison d’exister isolément. Lagestion de ce problème oblige à mettre en place des traitements spécifiques au moment de la création d’uneinstance de vue ainsi qu’ au moment de la suppression d’une instance du composant de base.
  • 37. 4.2. Du modèle abstrait aux composants EJB 35 Conteneur des vues BD JDBC BD EJB Home object Ressource Owner EJB Object (Entité ) viewof Conteneur Base JDBC EJB Home object Ressource EJB Home object Location (Entité ) EJB Object viewof (Entité ) EJB Object 1..* JVM EJB Home object Document (Entité ) EJB Object JVM F IG . 4.3 – Modèle abstrait vers EJB Le second problème provient de la sémantique de la ViewAssociation. Dans un composant vue,l’accès à une ViewAssociation permet d’obtenir les vues correspondantes des instances du composantde base situés aux extrémités de l’association. Le respect de cette sémantique dans le cadre de la solutiondécrite ci-dessus nécessite de retrouver facilement une instance de vue depuis une instance du composantde base. Pour résoudre ce problème, nous proposons d’attribuer la même clé primaire à l’instance ducomposant de base et à ses instances de vue et d’effectuer une recherche selon cette clé. Nous reviendrons plus en détail sur les traitements de ces deux problèmes lors de la description de laclasse d’implantation des composants EJB représentant des vues.Projection d’une ViewClass La définition d’une classe de composant EJB correspondant à une ViewClass est établie selon plu-sieurs règles de projection que nous allons maintenant préciser. Ces règles sont illustrées en reprenantl’exemple du composant vue RessourceManager. La projection d’une ViewClass d’un composant donne lieu à la génération des interfaces (fabrique etservices) et la génération d’une classe de composant EJB de type entité. Pour simplifier, nous limitons lesexplications aux interfaces locales de fabrique et de services, les interfaces distantes pouvant être élaboréesselon des règles similaires.L’interface de fabrique locale doit permettre la création d’instance de la ViewClass ainsi que la re- cherche de ces instances à partir d’une clé primaire. Les règles suivantes sont appliquées pour la génération de cette interface : – Le nom de l’interface est construit à partir du nom de la ViewClass et du suffixe "Home" – Comme toute interface de fabrique locale, l’interface générée hérite de EJBLocalHome – Pour la création, l’interface inclue la spécification d’une méthode nommée "create" à un paramètre dont l’utilité est importante : il sert à initialiser la connexion avec l’instance du composant de base. Ce paramètre est donc typé par le composant EJB (plus précisément son interface de service locale) implantant la classe du composant de base associée à la ViewClass.
  • 38. 36 Chapitre 4. Ciblage – Pour la recherche, l’interface inclue la spécification d’une méthode nommée "findByPrimaryKey" qui prend en paramètre une clé primaire du même type que celle utilisée pour rechercher les instances du composant de base. Le code ci-dessous montre l’interface de fabrique obtenue selon ces règles pour les classes ViewClass RessourceOwner et Ressource du composant Ressource. public interface RessourceOwnerHome extends EJBLocalHome { public RessourceOwner create(Location loc) throws CreateException; public RessourceOwner findByPrimaryKey(String roid) throws FinderException; } public interface RessourceHome extends EJBLocalHome { public Ressource create(Document doc) throws CreateException; public Ressource findByPrimaryKey(String rid) throws FinderException; } Il convient de préciser que les méthodes de création et de recherche spécifiées ci-dessus constituent une définition minimale de la fabrique. Il est tout à fait possible d’envisager l’ajout d’autres opéra- tions pour permettre par exemple une recherche basée sur d’autres critères ou également la création de toutes les instances de vues correspondant aux instances de la classe du composant de base.L’interface de services locale est définie en fonction des caractéristiques (attributs, viewattributes, mé- thodes, associations et viewassociations) fournie au niveau du modèle pour la ViewClass. Il est important de préciser que les types spécifiés pour ces caractéristiques au niveau modèle (notam- ment en ce qui concerne les classes) sont remplacés par l’interface de service local résultant de leur projection. Les règles suivantes sont appliqués : – Le nom de l’interface est construit à partir du nom de la ViewClass – Comme toute interface de services locale, l’interface générée hérite de EJBLocalObject – Un attribut donne lieu à la spécification de deux méthodes d’accès en lecture et en écriture. Le nom de ces deux méthodes d’accès est obtenu en utilisant les préfixes "get" et "set" suivi du nom de l’attribut. Pour l’attribut implantant la clé primaire, seule la méthode d’accès en lecture est générée. – Une association donne lieu à la spécification d’une méthode "get" pour l’accès aux instances de vue à l’extrémité de l’association et d’une seconde méthode "set" pour la modification. La signature générée pour ces deux méthodes, notamment vis-à-vis du type du paramètre et du type résultat, dépend de la cardinalité de l’association. En particulier, pour une association 1-N, le type utilisé est le type java Collection. – Une opération donne lieu à la spécification d’une méthode de même nom ayant le même nombre de paramètres. De plus, les types de ces paramètres sont adaptés par rapport à la projection des classes utilisées comme type (cf remarque au début de la section). – Un ViewAttribute est projeté de la même façon qu’un attribut de la ViewClass. En re- vanche, les méthodes fournies pour l’implantation seront différentes (cf prochain paragraphe sur la génération de la classe d’implantation). – Une ViewAssociation est projetée de la même façon qu’une association de la ViewClass. Comme pour les ViewAttribute, c’est l’implantation générée au niveau de la classe d’implan- tation qui sera différence. Il est important de préciser que le préfixage du nom des méthodes d’accès aux caractéristiques de la classe par "get" et "set" vise à indiquer leur persistance au niveau de la classe d’implantation. Le code ci-dessous montre l’interface de services locale obtenue selon ces règles pour les classes ViewClass RessourceOwner et Ressource du composant RessourceManager. public interface RessourceOwner extends EJBLocalObject { // Projection des attributs de la ViewClass
  • 39. 4.2. Du modèle abstrait aux composants EJB 37 public String getRessourceOwnerId(); // clé primaire accessible en lecture seulement public int getCapacity(); public void setCapacity(int capacity); // Projection de la ViewAssociation public Collection getRessources(); public void setRessources(Collection r); // Projection des opérations métiers public void addRessource(Ressource r); public void removeRessource(Ressource r); public void transfering(RessourceOwner ro); } public interface Ressource extends EJBLocalObject { // Projection des attributs de la ViewClass public String getRessourceId(); // clé primaire // Projection de la vue association public RessourceOwner getOwner(); public void setOwner(RessourceOwner ro); }La classe d’implantation doit fournir des implantations pour deux catégories de méthodes : les méthodes spécifiées dans les interfaces de fabrique et de services ; les méthodes invoquées par le conteneur pour la gestion du cycle de vie des composants (ejbCreate, ejbRemove, ejbLoad, . . .). Les règles suivantes sont appliquées pour la génération de cette classe : – Le nom de la classe est construit à partir du nom de la ViewClass et du suffixe "Impl" – Comme toute classe d’implantation de composant entité, l’interface générée hérite de EntityBean – Un attribut de nom "viewof" est ajouté à la classe pour relier une instance de vue avec une ins- tance du composant de base. Cet attribut est typé par l’interface de services du composant EJB implantant la classe du composant de base associée. Il est utilisé pour réaliser l’implantation des ViewAttribute et des ViewAssociation par délégation. L’initialisation de cet attribut par- ticulier est réalisée de façon automatique au moment de la création ou de la reconstruction d’une instance de vue (cf méthode ejbpostcreate). – Les attributs et associations de la ViewClass donnent lieu à des méthodes "get" et "set" abs- traites de même signature que celles générées pour l’interface de services. Le caractère abstrait de ces méthodes vise à indiquer la persistance de ces caractéristiques. L’implantation effective de ces méthodes sera prise en charge au niveau de la sous-classe générée par le conteneur (cf explications sur la persistance des composants EJB) – Les méthodes correspondant aux opérations métiers de la ViewClass donnent lieu à des mé- thodes de même signature avec une implantation qui est vide. Cette implantation doit être com- plétée par le développeur. – Les méthodes "get" et "set" spécifiées pour un ViewAttribute au niveau de l’interface de services sont implantées par délégation en invoquant des méthodes de l’instance du composant de base contenue dans l’attribut viewof. Les méthodes ainsi invoquées sont celles correspondant à l’attribut spécifié lors de la connexion des composants au niveau modèle. – Les méthodes "get" et "set" spécifiées pour une ViewAssociation au niveau de l’interface de services reçoivent une implantation élaborée pour retourner les instances de vue correspon- dant aux extrémités de l’association du composant de base (cf problème de sémantique de la ViewAssociation évoqué précédemment). Cette implantation repose sur les étapes suivantes : 1) récupération par délégation des instances du composant de base à l’extrémité de l’association ;
  • 40. 38 Chapitre 4. Ciblage 2) recherche des instances de vue correspondant à ces instances au moyen de leur clé primaire (rappel : une instance de vue a une clé primaire identique à celle de l’instance du composant de base) ; 3) transmission de ces instances de vue comme résultat. En ce qui concerne la seconde étape, il se peut qu’une instance du composant de base ne possède pas d’instance de vue au niveau du composant. Quand ce cas se produit, l’instance de vue est créée automatiquement. – La plupart des méthodes invoquées par le conteneur pour gérer le cycle de vie sont implantées avec un corps vide. Deux exceptions sont la méthode "ejbcreate" invoquée lors de la création et la méthode "ejbpostcreate" invoquée si la création ou la reconstruction de l’instance de vue a réussi. La méthode "ejbcreate" implante le traitement d’initialisation des attributs, notamment celui cor- respondant à la clé primaire dont la valeur est déterminée à partir de l’instance du composant de base spécifiée en paramètre. La méthode "ejbpostcreate" implante l’initialisation de l’attribut viewof pour les instances de vue obtenues par recherche. Le code ci-dessous montre la classe d’implantation obtenue selon ces règles pour la ViewClass RessourceOwner du composant Ressource. On obtiendrait une implantation similaire pour la classe Ressource du même composant. public abstract class RessourceOwnerImpl implements EntityBean { private EntityContext context; // Attribut pour relier l’instance de vue avec l’instance du // composant de base private Location viewof; // Méthodes abstraites indiquant les attributs à sauvegarder // (idem pour des associations) public abstract String getRessourceOwnerId() throws RemoteException; // clé primaire public abstract void setRessourceOwnerId() throws RemoteException; public abstract int getCapacity() throws RemoteException; public abstract void setCapacity(int capacity) throws RemoteException; // Implantation d’une ViewAssociation public Collection getRessources() { // Récupération par délégation des instances à l’extrémité de // l’association du composant de base Collection documents = viewof.getDocuments (); Vector ressources = new Vector(); try { // Accès à la fabrique des instances de vue Context ctx = new InitialContext(System.getProperties()); Object obj = ctx.lookup("DocumentHome"); RessourceHome rhome = RessourceHome) PortableRemoteObject.narrow(obj, RessourceHome.class); // Recherche des instances de vue associé aux instances du // schéma de base en utilisant leur clé primaire Iterator itr = documents.iterator(); while (itr.hasNext()) { Document d = (Document) itr.next(); Ressource r; try { r = rhome.findByPrimaryKey(d.getDocumentId()); // Recherche par la fabrique } catch(FinderException fe) { // Instance de vue inexistance :
  • 41. 4.2. Du modèle abstrait aux composants EJB 39 // creation automatique en spécifiant l’instance du // composant de base associée r = rhome.create(d); } // Ajout au résultat de la méthode ressources.add(r); } } catch(NamingException ne) { ... } catch(CreateException ce) { ... } return ressources; } // Implantation des opérations public void addRessource(Ressource d) { // A completer par le développeur } public void removeRessource(Ressource d) { // A completer par le développeur } public void transfering(RessourceOwner ro) { // A completer par le développeur } public String ejbCreate(Location loc) throws CreateException { // Affectation de la clé primaire en prenant celle de l’instance // du composant de base passée en paramètre setRessourceOwnerId(loc.getLocationId()); // méthode non disponible à partir de l’interface // initialisation de l’attribut viewof viewof = loc; return null; } public void ejbPostCreate(Location loc) { if (viewof == null) { // condition vérifiée si reconstruction de l’instance à partir // de la base. // Récupération de l’instance du composant de base à partir // de la clé primaire de l’instance de vue try { // Accès à la fabrique Context ctx = new InitialContext(System.getProperties()); Object obj = ctx.lookup("LocationHome"); LocationHome lhome = (DocumentHome) PortableRemoteObject.narrow(obj, DocumentHome.class); // Recherche puis affectation à l’attribut viewof Location l = lhome.findByPrimaryKey(getRessourceOwnerId()); viewof = l; } catch(FinderException fe) { r = rhome.create(d); } } public void ejbActivate() {} public void ejbPassivate() {} public void ejbLoad() {} public void ejbStore() {}
  • 42. 40 Chapitre 4. Ciblage public void ejbRemove() {} public void setEntityContext(EntityContext ctx) {} public void unsetEntityContext() {} } La solution qui vient d’être proposée pour la classe d’implantation permet de résoudre le problèmerelatif à la sémantique de la ViewAssociation ainsi qu’une partie du problème relatif à l’existence desvues (côté composant vue). En ce qui concerne ce second problème, il reste encore une partie non traitée qui est la suppressiond’instances du composant de base. Ce qui nécessite la suppression des instances de vue associées. Unesolution à ce problème peut être envisagée en appliquant le patron de conception classique Observateur. Cepatron propose un schéma d’interaction entre un objet "observé" et des objets "observateurs" intéressés parl’apparition d’évènements (changement d’états, . . .) au niveau de ce premier. Dans le cas présent, le schémad’interaction proposé par ce patron peut être mis à profit pour notifier les instances de vue de la suppressionde leur instance de base. Par rapport à la description donnée précédemment, il suffit pour cela d’ajouter auniveau d’un composant EJB implantant une classe du modèle : une méthode pour l’enregistrement desinstances de vues à notifier et une méthode pour annuler leur enregistrement. Ainsi qu’un traitement denotification de la suppression placé dans la méthode ejbremove" invoquée par le conteneur. Au niveau ducomposant EJB implantant une ViewClass, il s’agit d’ajouter : une méthode pour recevoir la notificationde suppression et un traitement placé dans la méthode "ejbremove" pour annuler la demande de notificationen cas de suppression de l’instance de “vue".
  • 43. Conclusion et Perspectives Ce travail a permis d’étendre les techniques de modélisation par vues en intégrant la notion de com-posant. Le modèle de composant vues décrit dans ce mémoire permet de spécifier des composants vuesgénériques et répond donc aux objectifs importants de réutilisation de composants. Notre démarche permet d’établir et de vérifier, à un niveau modèle, les connexions entre les composantscorrespondants à ces modèles. Actuellement, nous ne pouvons pas “importer” de la base des traitements,cette possibilité sans vraiment compliquer notre modèle l’enrichirait grandement. Il serait par exemplepossible de faire de la composition de fonctions. Notre démarche de mise en œuvre saute une étape par rapport à l’approche MDA. Pour être conformeà celle-ci, nous devrions générer, à partir de notre modèle abstrait, un modèle spécifique (CCM ou EJB parexemple). La plus grande partie de la génération de code se ferait donc à partir de ce PSM et non directementdepuis notre modèle abstrait. De plus, certains aspects, notamment la gestion des ViewAssociationpourraient bénéficier d’une automatisation plus importante. A plus long terme, le rapprochement de notre modèle avec la future norme UML 2.0, qui prend encompte les aspects composants, ou vers le futur modèle abstrait de ACCORD, devrait s’avérer bénéfique.En effet, cela permettra l’utilisation des résultats de ce projet, notamment le profil CCM. Dans cette étude nous nous sommes donné certaines limites : présence d’une base et pas de relationsinter-plans, c’est à dire pas d’interactions entre les composants eux-mêmes. Il serait intéressant de consi-dérer la base comme un composant fournissant un schéma mais sans schéma requis. Ceci permettrait d’ob-tenir un modèle uniforme de composant autorisant une application récursive du mode d’assemblage par lesschémas. 41
  • 44. Bibliographie [1] L. D EBRAUWER O. C ARON, B. C ARRÉ. Contextualization of OODB Schemas in CROME. DEXA 2000, 11th International Conference, London, Septembre 2000. [2] William T. C OUNCILL George T. H EINEMAN. Component-based software engineering : Putting the pieces together. AddisonWesley, 2001. [3] Robert C. S EACORD Kurt C. WALLNAU, Scott A. H ISSAM. Building systems from commercial com- ponents. AddisonWesley, 2002. [4] CORBA/IIOP Specification, http ://www.omg.org/technology/documents/formal/corba_iiop.htm. [5] L. D UCHIEN J.M. S OUCÉ. Etat de l’art sur les langages de description des architectures. Technical report, Projet RNTL Accord, 2002. [6] G. VANWORMHOUDT. CROME : un cadre de programmation par objets structurés en contextes. PhD thesis, Laboratoire d’Informatique Fondamentale de Lille I, Lille, 1999. [7] L. D EBRAUWER. Des vues aux contextes pour la structuration fonctionnelle de bases de données à objets en CROME. PhD thesis, Laboratoire d’Informatique Fondamentale de Lille I, Lille, décembre 1998. [8] G. K ICZALES and al. Aspect-Oriented Programming. In European Conference on Object-Oriented Programming (ECOOP), Finland, June 1997. Springer-Verlag LNCS 1241. [9] S. C LARKE. Extending standard UML with model composition semantics. Science of Computer Programming, Elsevier Science, 2002.[10] Desmond D’Souza and Alan Wills. Objects, Components and Frameworks With UML : The Catalysis Approach. Addison-Wesley, 1999.[11] E B RETON and J. B ÉZIVIN. Un méta-modèle de gestion par les activités. CITE’2001, November 2001.[12] Meta-Object Facility (MOF), version 1.4, http ://www.omg.org/technology/documents/formal/mof.htm.[13] OMG Model-Driven Architecture Home Page, http ://www.omg.org/mda.[14] J. D. P OOLE. Model-Driven Architecture : Vision, Standards And Emerging Technologies. ECCOOP 2001, Workshop on Metamodeling and Adaptive Object Models, April 2001.[15] A. M ULLER. La démarche MDA. Technical report, Projet RNTL Accord, 2002.[16] O.M.G. Home Page, http ://www.omg.org, 2001.[17] R. M ARVIE, P. M ERLE, and O. C ARON. Le modèle de composants CCM. Technical report, Projet RNTL Accord, 2002. 43
  • 45. 44 Bibliographie[18] R. M ARVIE and M.-C. P ELLEGRINI. Modèles de composants, un état de l’art. Numéro spécial de L’Objet, 8(3), 2001.[19] OMG. CORBA 3.0 New Components Chapters. Object Management Group, Novembre 2001. OMG ptc/2001-11-03.[20] E. Gamma, R. Helm, R. Johnson, J. Vlissides, and G. Booch. Design Patterns : Elements of Reusable Object-Oriented Software. Addison-Westley Professional Computing, USA, 1995.
  • 46. Annexe A Le code J//------------------------------------------------------------// profile default#external#ViewComponent//------------------------------------------------------------boolean Package::check (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11211@3704357416:199@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11211@3704357416:199@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11211@3704357416:199@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11211@3704357416:199@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11212@3704357416:200@T@15Package viewOfPackage = null;Class viewOfClass = null;StdOut.write("Check Package ", Name, NL);if (isStereotypedBy("Component")){ viewOfPackage = getViewOf(); if (viewOfPackage == null)return false; getAllClasses() {if (isStereotypedBy("ViewClass")){ viewOfClass = getViewOf(); if (viewOfClass == null)return false; if (!viewOfPackage.isIn(viewOfClass)) {StdOut.write("Erreur, la Class ", viewOfClass.Name, " devrait etre dans le Package ", 45
  • 47. 46 Annexe A. Le code J viewOfPackage.Name, NL);return false; }}if (!check()) return false; }}else{ getAllClasses() { if (isStereotypedBy("ViewClass")) {StdOut.write("Erreur, la ViewClass ", Name, " doit etre dans un Component", NL);return false; } if (!check()) return false; }}return true;// END OF MODIFIABLE ZONE@OBJID@11212@3704357416:200@E@66} // method checkPackage Package::getViewOf (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11229@3704357416:215@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11229@3704357416:215@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11229@3704357416:215@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11229@3704357416:215@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11230@3704357416:216@T@15Package viewP = null;DestinationUse.< select (isStereotypedBy("viewOf")){ if (viewP != null) {StdOut.write("Erreur, le Component ", Name, " ne peut avoir qu’un seul lien viewOf", NL);return null; } viewP=UsedPackage;}
  • 48. 47if (viewP != null) return viewP;StdOut.write("Erreur, le Component ", Name, " doit etre connectée par un lien viewOf");StdOut.write(" à un Package ", NL);return null;// END OF MODIFIABLE ZONE@OBJID@11230@3704357416:216@E@38} // method getViewOfboolean Package::isIn (in Class class){// Summary :// START OF MODIFIABLE ZONE@OBJID@11238@3704357416:222@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11238@3704357416:222@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11238@3704357416:222@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11238@3704357416:222@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11239@3704357416:223@T@15getAllClasses(){if (this == class) return true;}return false;// END OF MODIFIABLE ZONE@OBJID@11239@3704357416:223@E@23} // method isInString Package::preGenerate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11376@3704357416:322@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11376@3704357416:322@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11376@3704357416:322@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11376@3704357416:322@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11377@3704357416:323@T@15return "module " + Name + NL + "{" + NL;// END OF MODIFIABLE ZONE@OBJID@11377@3704357416:323@E@17} // method preGenerate
  • 49. 48 Annexe A. Le code JString Package::postGenerate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11395@3704357416:337@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11395@3704357416:337@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11395@3704357416:337@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11395@3704357416:337@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11396@3704357416:338@T@15return "};" + NL;// END OF MODIFIABLE ZONE@OBJID@11396@3704357416:338@E@17} // method postGeneratevoid Package::generate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11413@3704357416:349@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11413@3704357416:349@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11413@3704357416:349@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11413@3704357416:349@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11414@3704357416:350@T@15String idl;idl = preGenerate();getAllClasses(){ idl.strcat(" interface R" + Name + ";" + NL); idl.strcat(" interface I" + Name + ";" + NL); idl.strcat(" typedef sequence<R" + Name + "> R" + Name + "s ;"+ NL); idl.strcat(" typedef sequence<I" + Name + "> I" + Name + "s ;"+ NL); idl.strcat(NL);}getAllClasses(){ idl.strcat(generate());}idl.strcat(postGenerate());StdOut.write(idl, NL);// END OF MODIFIABLE ZONE@OBJID@11414@3704357416:350@E@37} // method generate
  • 50. 49boolean Class::check (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11188@3704357416:188@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11188@3704357416:188@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11188@3704357416:188@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11188@3704357416:188@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11189@3704357416:189@T@15Class viewOf = null;boolean existe = false;Association root = null;StdOut.write("Check Class ", Name, NL);if (isStereotypedBy("ViewClass")){viewOf = getViewOf();if (viewOf == null) return false;PartAttribute{if (isStereotypedBy("ViewAttribute")) if(getRoot(viewOf) == null) return false;}PartAssociationEnd{if (RelatedAssociation.isStereotypedBy("ViewAssociation")){ root = RelatedAssociation.getRoot(viewOf); if (root == null)return false; if (!root.isParticipate(viewOf)) {StdOut.write("Erreur, la Class ", viewOf.Name," doit participer à l’association ", root.Name, NL);return false; }}}return true;}else{PartAttribute{if (isStereotypedBy("ViewAttribute")){ StdOut.write("Erreur ", Name, " ne peut pas etre un ViewAttribute");
  • 51. 50 Annexe A. Le code JStdOut.write(", il n’appartient pas à une ViewClass", NL);return false;}}PartAssociationEnd{if (RelatedAssociation.isStereotypedBy("ViewAssociation")){ StdOut.write("Erreur ", RelatedAssociation.Name," ne peut pas etre une ViewAssociation");StdOut.write(", elle n’est pas entre des ViewClass", NL);return false;}}}return true;// END OF MODIFIABLE ZONE@OBJID@11189@3704357416:189@E@79} // method checkClass Class::getViewOf (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11225@3704357416:212@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11225@3704357416:212@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11225@3704357416:212@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11225@3704357416:212@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11226@3704357416:213@T@15Class viewC = null;DestinationUse.< select (isStereotypedBy("viewOf")){ if (viewC != null) {StdOut.write("Erreur, la Class ", Name, " ne peut avoir qu’un seul lien viewOf", NL);return null; } viewC=UsedClass;}if (viewC != null) return viewC;StdOut.write("Erreur, la ViewClass ", Name, " doit etre connectée par un lien viewOf");StdOut.write(" à une Class ", NL);return null;// END OF MODIFIABLE ZONE@OBJID@11226@3704357416:213@E@36
  • 52. 51} // method getViewOfString Class::preGenerate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11400@3704357416:340@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11400@3704357416:340@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11400@3704357416:340@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11400@3704357416:340@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11401@3704357416:341@T@15// END OF MODIFIABLE ZONE@OBJID@11401@3704357416:341@E@17} // method preGenerateString Class::postGenerate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11404@3704357416:343@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11404@3704357416:343@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11404@3704357416:343@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11404@3704357416:343@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11405@3704357416:344@T@15// END OF MODIFIABLE ZONE@OBJID@11405@3704357416:344@E@17} // method postGenerateString Class::generate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11421@3704357416:356@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11421@3704357416:356@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11421@3704357416:356@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11421@3704357416:356@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11422@3704357416:357@T@15String idl;if( isStereotypedBy("ViewClass") ){
  • 53. 52 Annexe A. Le code J idl = " interface R" + Name + NL + " {" + NL; // Pour chaque view attribute generate PartAttribute.<select(isStereotypedBy("ViewAttribute")) { idl.strcat(generate()); } idl.strcat(" };" + NL);}idl.strcat(NL + " interface I" + Name + NL + " {" + NL);// Pour chaque attribut publicPartAttribute.<select(Visibility = Public){ idl.strcat(generate());}idl.strcat(" };" + NL);idl.strcat(NL + " component " + Name + NL + " {" + NL);idl.strcat(" provides I" + Name + " service" + Name + ";" + NL);idl.strcat(" uses R" + Name + " recept" + Name + ";" + NL);idl.strcat(" };" + NL);return idl;// END OF MODIFIABLE ZONE@OBJID@11422@3704357416:357@E@48} // method generateFeature Feature::getRoot (in Class class){// Summary :// START OF MODIFIABLE ZONE@OBJID@11233@3704357416:218@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11233@3704357416:218@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11233@3704357416:218@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11233@3704357416:218@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11234@3704357416:219@T@15String root;TagTaggedValue.< select (DefinitionTagType.Name == "root"){ ActualTagParameter {root = Value;class.PartAttribute.< select (Name == root){ return this;} }
  • 54. 53}StdOut.write("Erreur la racine ", root, " du ViewAttribute ", Name);StdOut.write(" n’appartient pas à la Class ", class.Name, NL);return null;// END OF MODIFIABLE ZONE@OBJID@11234@3704357416:219@E@35} // method getRootboolean Attribute::check (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11083@3704357416:135@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11083@3704357416:135@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11083@3704357416:135@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11083@3704357416:135@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11084@3704357416:136@T@15StdOut.write("Verify first constraint...");if (verifyConstraint1()) StdOut.write("OK", NL);else{ StdOut.write("Error", NL); return false;}return true;// END OF MODIFIABLE ZONE@OBJID@11084@3704357416:136@E@27} // method checkString Attribute::generate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11408@3704357416:346@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11408@3704357416:346@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11408@3704357416:346@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11408@3704357416:346@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11409@3704357416:347@T@15String type = "long";return " attribute " + type + " " + Name + ";" + NL;
  • 55. 54 Annexe A. Le code J// END OF MODIFIABLE ZONE@OBJID@11409@3704357416:347@E@21} // method generateboolean Association::isParticipate (in Class class){// Summary :// START OF MODIFIABLE ZONE@OBJID@11310@3704357416:277@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11310@3704357416:277@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11310@3704357416:277@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11310@3704357416:277@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11311@3704357416:278@T@15ConnectionAssociationEnd{ OwnerClass { if (this == class) return true; }}return false;// END OF MODIFIABLE ZONE@OBJID@11311@3704357416:278@E@27} // method isParticipateAssociation Association::getRoot (in Class class){// Summary :// START OF MODIFIABLE ZONE@OBJID@11315@3704357416:281@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11315@3704357416:281@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11315@3704357416:281@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11315@3704357416:281@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11316@3704357416:282@T@15String root;TagTaggedValue.< select (DefinitionTagType.Name == "root"){ ActualTagParameter {root = Value;class.PartAssociationEnd.< select (RelatedAssociation.Name == root){ return RelatedAssociation;
  • 56. 55} }}StdOut.write("Erreur la racine ", root, " de l’associtation ", Name);StdOut.write(" ne fait pas participer la Class ", class.Name, NL);return null;// END OF MODIFIABLE ZONE@OBJID@11316@3704357416:282@E@34} // method getRootvoid Association::generate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11744@3704357416:586@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11744@3704357416:586@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11744@3704357416:586@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11744@3704357416:586@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11745@3704357416:587@T@15// END OF MODIFIABLE ZONE@OBJID@11745@3704357416:587@E@17} // method generatevoid ModelElement::test (){// Summary :// START OF MODIFIABLE ZONE@OBJID@10892@3704357416:24@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@10892@3704357416:24@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@10892@3704357416:24@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@10892@3704357416:24@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@10893@3704357416:25@T@15if (check())StdOut.write("Check Ok", NL);// END OF MODIFIABLE ZONE@OBJID@10893@3704357416:25@E@18} // method testboolean ModelElement::isStereotypedBy (in String stereotype){// Summary :// START OF MODIFIABLE ZONE@OBJID@11048@3704357416:109@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11048@3704357416:109@E@Descriptor@summary
  • 57. 56 Annexe A. Le code J// Description :// START OF MODIFIABLE ZONE@OBJID@11048@3704357416:109@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11048@3704357416:109@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11049@3704357416:110@T@15if (notVoid(ExtensionStereotype)) if (ExtensionStereotype.Name=stereotype) return true ;return false ;// END OF MODIFIABLE ZONE@OBJID@11049@3704357416:110@E@20} // method isStereotypedByboolean ModelElement::check (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11079@3704357416:132@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11079@3704357416:132@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11079@3704357416:132@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11079@3704357416:132@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11080@3704357416:133@T@15return true;// END OF MODIFIABLE ZONE@OBJID@11080@3704357416:133@E@17} // method checkString Operation::generate (){// Summary :// START OF MODIFIABLE ZONE@OBJID@11738@3704357416:583@N@Descriptor@summary// END OF MODIFIABLE ZONE@OBJID@11738@3704357416:583@E@Descriptor@summary// Description :// START OF MODIFIABLE ZONE@OBJID@11738@3704357416:583@N@Descriptor@description// END OF MODIFIABLE ZONE@OBJID@11738@3704357416:583@E@Descriptor@description// J code :// START OF MODIFIABLE ZONE@OBJID@11739@3704357416:584@T@15// END OF MODIFIABLE ZONE@OBJID@11739@3704357416:584@E@17} // method generate
  • 58. Annexe B La démarche MDA57