61
Assemblage par vues de composants logiciels Alexis MULLER Mémoire de DEA Informatique - Équipe GOAL Laboratoire d’Informatique Fondamentale de Lille [email protected]

Assemblage par vues de composants

  • Upload
    karousn

  • View
    270

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Assemblage par vues de composants

Assemblage par vues de composantslogiciels

Alexis MULLER

Mémoire de DEA Informatique - Équipe GOAL

Laboratoire d’Informatique Fondamentale de Lille

[email protected]

Page 2: Assemblage par vues de composants
Page 3: Assemblage par vues de composants

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.

Page 4: Assemblage par vues de composants
Page 5: Assemblage par vues de composants

Table des matières

Introduction 5

1 Problématique et positionnement 71.1 Composants, ACCORD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2 Vues, SOP / AOP, Catalysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.3 Rapprochement vues/composants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.4 Modèle, Méta-Modèle, MDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2 Le modèle abstrait 172.1 Le méta-modèle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.2 Description des éléments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.3 Contraintes OCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 Réalisation du Profil UML 213.1 Identification du sous-ensemble UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.2 Les éléments du profil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4 Ciblage 254.1 Du modèle abstrait aux composants CCM . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4.1.1 Le modèle de composants CORBA . . . . . . . . . . . . . . . . . . . . . . . . . 254.1.2 Règles de transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.2 Du modèle abstrait aux composants EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.2.1 Le modèle de composants EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.2.2 Règles de transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Conclusion et Perspectives 41

A Le code J 45

B La démarche MDA 57

1

Page 6: Assemblage par vues de composants

2 Table des matières

Page 7: Assemblage par vues de composants

Table des figures

1.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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.1 Le méta-modèle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4.1 Composant abstrait CCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264.2 L’architecture EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314.3 Modèle abstrait vers EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3

Page 8: Assemblage par vues de composants

4 Table des figures

Page 9: Assemblage par vues de composants

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

Page 10: Assemblage par vues de composants

6 Introduction

Page 11: Assemblage par vues de composants

Chapitre 1

Problématique et positionnement

1.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 oul’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

Page 12: Assemblage par vues de composants

8 Chapitre 1. Problématique et positionnement

des 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

Page 13: Assemblage par vues de composants

1.2. Vues, SOP / AOP, Catalysis 9

Base

Car

immatriculation

date

constructor

model

Agency location()

Car findByDate()

Car findByImmatriculation()

int nbRenting()

bool free(date from, date to)

Agency

Name

adresse

capacity

Client* findAll()

Car* findAll()

void transfering(Client c)

void add(Agency a)

void remove(Agency a)

Client

Name

date

phone

adresse

Agency location()

Client findByDate()

Client findByName()

int nbRenting()

Rent

From

due_date

return_date

manage

0..*

own 0..*

reference

0..*

contain 0..*

FIG. 1.1 – Location de voitures - Approche objet

Page 14: Assemblage par vues de composants

10 Chapitre 1. Problématique et positionnement

Agency

att: Name,adresse

Plan debase

Client

att: Name,date, phone,adresse

Car

att: date, model,immatriculation,constructor

mth: findAllPlan derechercheclient

mth: location,findByDate,findByKey

mth: findAllPlan derecherchevoiture

mth: location,findByDate,findByKey

att: capacitymth: add,transfering,remove

Plan degestion desresources

mth: free,nbRenting

Plan delocations

att:maximum_durationmth: nbRenting

Rent

att: From,due_date,return_date

FIG. 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

Page 15: Assemblage par vues de composants

1.3. Rapprochement vues/composants 11

Base

Rent

From

due_date

return_date

Location

indentifiant

adresse

capacity

Document* findAll()

void transfering(ResourceOwner o)

void add(Document r)

void remove(Document r)

Document

title

publication_date

Location location()

Document findByDate()

Document findByKey()

int nbRenting()

bool free(date from, date to)

Researcher

name

arrival_date

Team

name

Book

ISBN

Periodical

number

Client

name

inscription_date

int nbRenting()

0..*publishes

0..*1..*

Contain 0..*

reference

0..*

FIG. 1.3 – Bibliothèque universitaire - Approche objet

Location

att: adresse,identifiant

Plan debase

Client

att: Name,inscription_date

Document

att: title,publication_date

mth: findAllPlan derecherchedocument

mth: location,findByDate,findByKey

att: capacitymth: add,transfering,remove

Plan degestion desresources

mth: free,nbRenting

Plan delocations

att:maximum_durationmth: nbRenting

Rent

att: From,due_date,return_date

FIG. 1.4 – Bibliothèque universitaire - Structuration par contextes

Page 16: Assemblage par vues de composants

12 Chapitre 1. Problématique et positionnement

<<Component>> Search

<<ViewClass>>

DateResource

identifiant <<ViewAttibute>>

date <<ViewAttribute>>

Location location()

DateResource findByDate()

DateResource findByKey()

<<ViewClass>>

Location

name <<ViewAttribute>>

adresse <<ViewAttribute>>

DateResource* findAll()

store 0..*

FIG. 1.5 – Composant de recherche

certains 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).

Page 17: Assemblage par vues de composants

1.3. Rapprochement vues/composants 13

Base

Car

immatriculation

date

constructor

model

Agency

Name

adresse

<<Component>> Search

<<Component>> Search

<<ViewClass>>

DateResource

identifiant <<ViewAttibute>>

date <<ViewAttribute>>

Location location()

DateResource findByDate()

DateResource findByKey()

<<ViewClass>>

DateResource

identifiant <<ViewAttibute>>

date <<ViewAttribute>>

Location location()

DateResource findByDate()

DateResource findByKey()

<<Component>> Renting

Rent

From

due_date

return_date

<<ViewClass>>

Product

identifiant <<ViewAttribute>>

int nbRenting()

bool free(date from, date to)

<<ViewClass>>

Client

identifiant <<ViewAttibute>>

maximum_duration

int nbRenting()

<<Component>> ResourceManager

<<ViewClass>>

Resource

identifiant <<ViewAttribute>>

<<ViewClass>>

ResourceOwner

identifiant <<ViewAttribute>>

capacity

void transfering(ResourceOwner o)

void add(Resource r)

void remove(Resource r)

Client

Name

date

phone

adresse

<<ViewClass>>

Location

name <<ViewAttribute>>

adresse <<ViewAttribute>>

DateResource* findAll()

<<ViewClass>>

Location

name <<ViewAttribute>>

adresse <<ViewAttribute>>

DateResource* findAll()

<<ViewAssociation>>

<<ViewAssociation>>

<<ViewAssociation>>manage

0..*

contain0..*

reference0..*

manage

0..*

own 0..*

store

0..*

store 0..*

FIG. 1.6 – Location de voitures - Approche composants vues

Page 18: Assemblage par vues de composants

14 Chapitre 1. Problématique et positionnement

Base

<<Component>> Renting

Rent

From

due_date

return_date

<<ViewClass>>

Product

identifiant <<ViewAttribute>>

int nbRenting()

bool free(date from, date to)

<<ViewClass>>

Client

identifiant <<ViewAttibute>>

int nbRenting()

<<Component>> ResourceManager

<<ViewClass>>

Resource

identifiant <<ViewAttribute>>

<<ViewClass>>

ResourceOwner

identifiant <<ViewAttribute>>

capacity

void transfering(ResourceOwner o)

void add(Resource r)

void remove(Resource r)

Location

indentifiant

adresse

Document

title

publication_date

Researcher

name

arrival_date

Team

name

<<Component>> Search

<<ViewClass>>

Location

name <<ViewAttribute>>

adresse <<ViewAttribute>>

DateResource* findAll()

<<ViewClass>>

DateResource

identifiant <<ViewAttribute>>

date <<ViewAttribute>>

Location location()

DateResource findByDate()

DateResource findByKey()

Book

ISBN

Periodical

number

AddToBase

Client

name

inscription_date

<<ViewAssociation>>

<<ViewAssociation>>

contain0..*

reference0..*

store 0..*

0..*

publishes0..* 1..*

store

0..*

FIG. 1.7 – Bibliothèque universitaire - Approche composants vues

Page 19: Assemblage par vues de composants

1.4. Modèle, Méta-Modèle, MDA 15

Niveau M3

Niveau M2

Niveau M1

Niveau M0 Instances

Modèle

Méta-modèle

Méta-méta-modèle

Cette voiturerouge immatriclée12 XY 59

Une voiture a une couleuret une immatriculation

Une classe désigne unensemble d’objets qui peuventavoir des attributs

Il existe des entités quipeuvent avoir des relationsentre elles

FIG. 1.8 – Les quatre niveaux de modélisation

1.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.

Page 20: Assemblage par vues de composants

16 Chapitre 1. Problématique et positionnement

View UML Base UMLconnexion

vérificationdes contraintes

Modèle CCMavec

associations IDLXML+Java XML

Base BinaireCCM

Base BinaireEJB(++) BDR

BinaireCCM

BinaireEJB(++)

PIM

PSM

FIG. 1.9 – Application de MDA

Page 21: Assemblage par vues de composants

Chapitre 2

Le modèle abstrait

2.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éments

Component Un Composant est une spécialisation de la méta-classe UML Package. Son rôle est deregrouper 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 instancede celle-ci peut contenir les mêmes éléments qu’un autre Classifier ainsi que desViewAttribute. L’association viewOf (entre une ViewClass et une Class) indique dansquelle Class les Attribute racine (root) des ViewAttribute de la ViewClass doiventse trouver.

Pour reprendre l’analogie avec la structuration par contextes, une Class correspond au plan de baseet, 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’uneBehavioralFeature, son rôle est de désigner, par l’association root, une autre Feature.L’élément ExternalStructuralFeature spécialise ExternalFeature en imposant uneStructuralFeature comme racine (root).

17

Page 22: Assemblage par vues de composants

18 Chapitre 2. Le modèle abstrait

Feature (from UML)

ownerScope

visibility

Classifier (from UML)

StructuralFeature (from UML)

multiplicity

changeability

targetScope

Attribute (from UML)

initialValue

ExternalFeature

ExternalStructuralFeature

ViewAttribute

Class (from UML)

isActive

ViewClass

Package (from UML)Component

0..1

+owner0..*

+feature+type

0..* connection

0..*

+root

0..*

0..*

+viewOf

0..*

+viewOf AssociationEnd (from UML)

isNavigable

ordering

aggreagation

targetScope

multiplicity

changeability

visibility

Association (from UML)

ViewAssociation

+participant

*

+association

*

+specification

*

+specifedEnd

2..*

+connection

0..*

+root

FIG. 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’exterieuret 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 à pouvoirapparaî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’Associationconrrespondante entre les classes de la base.

2.3 Contraintes OCL

ExternalFeature et ExternalStructuralFeature

Contraintes de conception

[1] La racine d’un ExternalStructuralFeature doit être un StructuralFeature.

self.root.oclIsKindOf(StructuralFeature);

Page 23: Assemblage par vues de composants

2.3. Contraintes OCL 19

ViewClass

Contraintes 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 );

ViewAttribute

Contraintes 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);

ViewAssociation

Contraintes de conception

[6] Une ViewAssociation ne peut être que dans un Component

self.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));

Component

Contraintes 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 Component

self.allReferencedElements->select( v | v.oclIsKindOf(ViewClass) )->forAll ( v1, v2 : ViewClass | not v1.viewOf = v2.viewOf );

Page 24: Assemblage par vues de composants

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 v2

self.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);

Page 25: Assemblage par vues de composants

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– Dependency

3.2 Les éléments du profil

Les ExternalFeature et ExternalStructuralFeature sont représentées dans notre profil UML par uneFeature 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’auxsté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 del’é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 uneDependency entre elles stéréotypée par «viewOf».

1Disponible en annexe

21

Page 26: Assemblage par vues de composants

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éfinitionroot «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.

«stereotype»ExternalFeature

<<tagged value>> root: string

<<baseElement>> Feature{From UML}

«<<stereotype>>»ExternalStructuralFeature

«stereotype»ViewAttribute

<<baseElement>>

<<baseElement>>

FIG. 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.

«stereotype»ViewClass

Classifier{From UML}

<<baseElement>>

FIG. 3.2 – Méta-modèle virtuel des ViewClass

Un ViewAttribute est représenté par un Attribute UML stéréotypé par «ViewAttribute». Enspécialisant «ExternalStructuralFeature», le stéréotype «ViewAttribute» hérite dela valeur marquée root, qui doit ici contenir le nom d’un Attribute.

Page 27: Assemblage par vues de composants

3.2. Les éléments du profil 23

«stereotype»viewOf

<<baseElement>>

Dependency{From UML}

FIG. 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.

«stereotype»ViewAttribute

Attribute{From UML}

<<baseElement>>

FIG. 3.4 – Méta-modèle virtuel des ViewAttribute

Une ViewAssociation est représentée par une AssociationUML 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éfinitionroot «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.

«stereotype»ViewAssociation

<<tagged value>> root: string

Association{From UML}

<<baseElement>>

FIG. 3.5 – Méta-modèle virtuel des ViewAssociation

Un 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».

Page 28: Assemblage par vues de composants

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.

«stereotype»Component

Package{From UML}

<<baseElement>>

FIG. 3.6 – Méta-modèle virtuel des Component

FIG. 3.7 – Le module Objecteering

Page 29: Assemblage par vues de composants

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 lespropriétés d’un type de composant. Pour cela, le langage OMG IDL a été étendu pour prendre encompte 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

Page 30: Assemblage par vues de composants

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 duCCM :– 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éceptacle

Puit d’événement

Source d’événement

Implémentationdes facettes

Composant CCMRéférence deComposant

Attributs

Référencesde facettes

Composant

Composant

FIG. 4.1 – Composant abstrait CCM

Le 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 langageest associée à un framework, le CIF (Component Implementation Framework), qui définit commentles 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 leconteneur.

Le modèle de déploiement définit un processus qui permet d’installer une application sur différents sitesd’exécution de manière simple et automatique. Ce modèle s’appuie sur l’utilisation de paquetages decomposants, ainsi que de descripteurs OSD (Open Software Description, un vocabulaire XML), lespaquetages é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 composantsqu’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.

Page 31: Assemblage par vues de composants

4.1. Du modèle abstrait aux composants CCM 27

Chaque 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 correspondantepaquetage UML X module CCM Xclasse X component X doté d’une

facette de nom serviceX de l’interface IXet d’une maison de composant homeX

attributs publiques UML attributs IDL3 dans l’interface IXopérations publiques UML opérations IDL3 dans l’interface IXassociation 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 ;

} ;

Page 32: Assemblage par vues de composants

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 IXet d’un réceptacle de nom receptX de l’interface RXet d’une maison de composant homeX

«viewAttribute» spécifié dans l’interface IX si publicspécifié dans l’interface RX

«viewAssociation» opérations de manipulation de l’associationspé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) ;

Page 33: Assemblage par vues de composants

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{

Page 34: Assemblage par vues de composants

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_LocationHomemanages AdaptResourceOwner_Location {} ;

home AdaptResource_Documenthomemanages 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 suivantes2.– 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

1dans sa version actuelle, la projection ne produit pas le descripteur de déploiement des composants EJB mais cette opération esttout à fait envisageable

2La 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

Page 35: Assemblage par vues de composants

4.2. Du modèle abstrait aux composants EJB 31

utilise 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.

FIG. 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,

Page 36: Assemblage par vues de composants

32 Chapitre 4. Ciblage

par 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

Page 37: Assemblage par vues de composants

4.2. Du modèle abstrait aux composants EJB 33

des 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 persistance3.

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 à sauvegarderpublic abstract String getDocumentId(); // accès à la clé primairepublic 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 à sauvegarderpublic abstract Collection getAuthors();public abstract void setAuthors(Collection authors);

public abstract Location getLocation()public abstract void setLocation(Location loc) throws RemoteException { }

// Méthodes métierspublic void addAuthor(Researcher r) { ... }

// Méthode pour la gestion par le conteneurpublic 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 à sauvegarderpublic abstract String getLocationId(); // accès à la clé primairepublic abstract String getAddress();public abstract void setAddress(String address);

3l’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

Page 38: Assemblage par vues de composants

34 Chapitre 4. Ciblage

// Methodes d’accès abstraites indiquant les associations à sauvegarderpublic abstract Collection getDocuments();public abstract void setDocuments(Collection documents);

// Méthodes métierspublic void addDocument(Document d) { ... }

// Méthodes pour la gestion par le conteneurpublic 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.

Page 39: Assemblage par vues de composants

4.2. Du modèle abstrait aux composants EJB 35

BD

Locat ion(Ent it é )

EJB Home object

EJB Object

Conteneur Base

JVM

Conteneur des vues

JVM

RessourceOwner(Ent it é )

EJB Home object

EJB Object

BD

JDBC

JDBC

viewof

Ressource(Ent it é )

EJB Home object

EJB Object

Document(Ent it é )

EJB Home object

EJB Object

viewof

1..*

FIG. 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 lagé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.

Page 40: Assemblage par vues de composants

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 lesinstances du composant de base.

Le code ci-dessous montre l’interface de fabrique obtenue selon ces règles pour les classes ViewClassRessourceOwner 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 constituentune 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éationde 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 estimportant 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 leurprojection. 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 nomde l’attribut. Pour l’attribut implantant la clé primaire, seule la méthode d’accès en lecture estgénérée.

– Une association donne lieu à la spécification d’une méthode "get" pour l’accès aux instancesde vue à l’extrémité de l’association et d’une seconde méthode "set" pour la modification. Lasignature générée pour ces deux méthodes, notamment vis-à-vis du type du paramètre et du typerésultat, dépend de la cardinalité de l’association. En particulier, pour une association 1-N, le typeutilisé 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 nombrede paramètres. De plus, les types de ces paramètres sont adaptés par rapport à la projection desclasses 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 surla 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 laclasse 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 classesViewClass RessourceOwner et Ressource du composant RessourceManager.

public interface RessourceOwner extends EJBLocalObject{

// Projection des attributs de la ViewClass

Page 41: Assemblage par vues de composants

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 ViewAssociationpublic Collection getRessources();public void setRessources(Collection r);

// Projection des opérations métierspublic void addRessource(Ressource r);public void removeRessource(Ressource r);public void transfering(RessourceOwner ro);

}

public interface Ressource extends EJBLocalObject{

// Projection des attributs de la ViewClasspublic String getRessourceId(); // clé primaire

// Projection de la vue associationpublic RessourceOwner getOwner();public void setOwner(RessourceOwner ro);

}

La classe d’implantation doit fournir des implantations pour deux catégories de méthodes : les méthodesspécifiées dans les interfaces de fabrique et de services ; les méthodes invoquées par le conteneurpour la gestion du cycle de vie des composants (ejbCreate, ejbRemove, ejbLoad, . . .). Les règlessuivantes 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 EJBimplantant la classe du composant de base associée. Il est utilisé pour réaliser l’implantation desViewAttribute 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’uneinstance 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 deces méthodes vise à indiquer la persistance de ces caractéristiques. L’implantation effective de cesméthodes sera prise en charge au niveau de la sous-classe générée par le conteneur (cf explicationssur 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 deservices sont implantées par délégation en invoquant des méthodes de l’instance du composant debase 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’interfacede 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 laViewAssociation é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 ;

Page 42: Assemblage par vues de composants

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 debase) ; 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 niveaudu 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éesavec un corps vide. Deux exceptions sont la méthode "ejbcreate" invoquée lors de la création et lamé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 composantde base spécifiée en paramètre. La méthode "ejbpostcreate" implante l’initialisation de l’attributviewof pour les instances de vue obtenues par recherche.

Le code ci-dessous montre la classe d’implantation obtenue selon ces règles pour la ViewClassRessourceOwner du composant Ressource. On obtiendrait une implantation similaire pour la classeRessource 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 baseprivate Location viewof;

// Méthodes abstraites indiquant les attributs à sauvegarder// (idem pour des associations)public abstract String getRessourceOwnerId()

throws RemoteException; // clé primairepublic abstract void setRessourceOwnerId() throws RemoteException;public abstract int getCapacity() throws RemoteException;public abstract void setCapacity(int capacity) throws RemoteException;

// Implantation d’une ViewAssociationpublic Collection getRessources(){ // Récupération par délégation des instances à l’extrémité de

// l’association du composant de baseCollection 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é primaireIterator 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 :

Page 43: Assemblage par vues de composants

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éthoderessources.add(r);

}}catch(NamingException ne) { ... }catch(CreateException ce) { ... }return ressources;

}

// Implantation des opérationspublic 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ètresetRessourceOwnerId(loc.getLocationId());// méthode non disponible à partir de l’interface// initialisation de l’attribut viewofviewof = 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 vuetry{ // 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 viewofLocation 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() {}

Page 44: Assemblage par vues de composants

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".

Page 45: Assemblage par vues de composants

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

Page 46: Assemblage par vues de composants
Page 47: Assemblage par vues de composants

Bibliographie

[1] L. DEBRAUWER O. CARON, B. CARRÉ. Contextualization of OODB Schemas in CROME. DEXA2000, 11th International Conference, London, Septembre 2000.

[2] William T. COUNCILL George T. HEINEMAN. Component-based software engineering : Putting thepieces together. AddisonWesley, 2001.

[3] Robert C. SEACORD Kurt C. WALLNAU, Scott A. HISSAM. Building systems from commercial com-ponents. AddisonWesley, 2002.

[4] CORBA/IIOP Specification,http ://www.omg.org/technology/documents/formal/corba_iiop.htm.

[5] L. DUCHIEN J.M. SOUCÉ. Etat de l’art sur les langages de description des architectures. Technicalreport, 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. DEBRAUWER. 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écembre1998.

[8] G. KICZALES and al. Aspect-Oriented Programming. In European Conference on Object-OrientedProgramming (ECOOP), Finland, June 1997. Springer-Verlag LNCS 1241.

[9] S. CLARKE. Extending standard UML with model composition semantics. Science of ComputerProgramming, Elsevier Science, 2002.

[10] Desmond D’Souza and Alan Wills. Objects, Components and Frameworks With UML : The CatalysisApproach. Addison-Wesley, 1999.

[11] E BRETON and J. BÉZIVIN. Un méta-modèle de gestion par les activités. CITE’2001, November2001.

[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. POOLE. Model-Driven Architecture : Vision, Standards And Emerging Technologies. ECCOOP2001, Workshop on Metamodeling and Adaptive Object Models, April 2001.

[15] A. MULLER. La démarche MDA. Technical report, Projet RNTL Accord, 2002.

[16] O.M.G. Home Page, http ://www.omg.org, 2001.

[17] R. MARVIE, P. MERLE, and O. CARON. Le modèle de composants CCM. Technical report, ProjetRNTL Accord, 2002.

43

Page 48: Assemblage par vues de composants

44 Bibliographie

[18] R. MARVIE and M.-C. PELLEGRINI. Modèles de composants, un état de l’art. Numéro spécial deL’Objet, 8(3), 2001.

[19] OMG. CORBA 3.0 New Components Chapters. Object Management Group, Novembre 2001. OMGptc/2001-11-03.

[20] E. Gamma, R. Helm, R. Johnson, J. Vlissides, and G. Booch. Design Patterns : Elements of ReusableObject-Oriented Software. Addison-Westley Professional Computing, USA, 1995.

Page 49: Assemblage par vues de composants

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

Page 50: Assemblage par vues de composants

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 check

Package 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;

}

Page 51: Assemblage par vues de composants

47

if (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 getViewOf

boolean 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 isIn

String 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

Page 52: Assemblage par vues de composants

48 Annexe A. Le code J

String 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 postGenerate

void 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

Page 53: Assemblage par vues de composants

49

boolean 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");

Page 54: Assemblage par vues de composants

50 Annexe A. Le code J

StdOut.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 check

Class 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

Page 55: Assemblage par vues de composants

51

} // method getViewOf

String 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 preGenerate

String 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 postGenerate

String 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") ){

Page 56: Assemblage par vues de composants

52 Annexe A. Le code J

idl = " interface R" + Name + NL + " {" + NL;

// Pour chaque view attribute generatePartAttribute.<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 generate

Feature 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;}

}

Page 57: Assemblage par vues de composants

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 getRoot

boolean 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@[email protected]("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 check

String 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;

Page 58: Assemblage par vues de composants

54 Annexe A. Le code J

// END OF MODIFIABLE ZONE@OBJID@11409@3704357416:347@E@21

} // method generate

boolean 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 isParticipate

Association 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;

Page 59: Assemblage par vues de composants

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 getRoot

void 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 generate

void 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 test

boolean 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

Page 60: Assemblage par vues de composants

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 isStereotypedBy

boolean 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 check

String 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

Page 61: Assemblage par vues de composants

Annexe B

La démarche MDA

57