- Onglets de formulaire commentés sur la classe Class
- Browser commenté sur la classe System
- Diagramme de systèmes commenté
Onglets de formulaire commentés sur la classe Class
Class {
// ouverture de définition(s) sur
// une classe du méta-modèle
FORM MainUML : LABEL "General"|"Général" WIDTH 12
// déclaration d'un formulaire:
// MainUML est ici l'identifiant du formulaire
// LABEL définit ce qui apparaît sur l'onglet
// (General en anglais, Général en français)
// WIDTH permet de définir un fractionnement maximal
// de la largeur totale pour le placement ultérieur
// des champs qui apparaissent ci-dessous
{FILL WIDTH 12;
// permet de définir une zone vide
name WIDTH 2+4;
// name est de type Identifier:
// un champ simple sera utilisé pour afficher sa valeur;
// le label n'étant pas spécifié, c'est le nom fournit
// dans le méta-modèle qui est pris par défaut
// WIDTH 2+4 indique que l'on veut que le label occupe
// 2/12 de largeur et le champ 4/12
abstract WIDTH 2+1;
// abstract est de type Boolean:
// une boîte à cocher sera utilisée pour afficher sa valeur
is_derived WIDTH 2+1;
visibility WIDTH 2+4;
// visibility est de type ENUM:
// une combo box sera utilisée pour afficher ses valeurs
is_type WIDTH 2+1;
is_persistent WIDTH 2+1;
stereotype WIDTH 2+4
CREATE {ASK name;
A1.stereotype := THIS;};
FILL WIDTH 6;
// permet de combler une zone vide pour contrôler
// la disposition du champ suivant dans le formulaire
class_state_model
LABEL "state model"|"modèle d'état"
// ici le label est spécifié
WIDTH 2+4 HEIGHT 1
PRINT on_class.name
// précision sur la méthode print utilisée
CREATE {A1.create_stateDiagram_UML;}
// permet de créer une instance de ClassStateModel
// liée à l'instance de Class courante (puisque
// c'est un formulaire sur la classe Class);
// A1 représente l'instance de Class courante:
// on lui applique la méthode create_stateDiagram_UML
INSERT NONE;
// INSERT NONE empêche toute proposition d'insertion:
// "Insérer..." n'apparaît pas dans le menu contextuel
system WIDTH 2+4;
};
FORM OtherMain : LABEL "Informations" WIDTH 12
{FILL WIDTH 12;
generalizations
LABEL "superclass(es)"|"super-classe(s)"
WIDTH 6 HEIGHT 2
PRINT superclass.print
CREATE Inheritance {subclass := A1;
ASK superclass : A1.system.visibleClasses
$- (A1 $+ A1.inheritance);};
// generalizations a une cardinalité multiple:
// une liste sera utilisée pour afficher ses éléments;
// sa hauteur relative est spécifiée à 2
// CREATE permet de spécifier du code à exécuter et
// des domaines de définition (ASK) lors de l'utilisation
// de l'option "Créer..." du menu contextuel de la liste
// (même principe que pour les listes principales du browser)
specializations
LABEL "subclasses"|"sous-classes"
WIDTH 6 HEIGHT 2
PRINT subclass.print
CREATE Inheritance {superclass := A1;
ASK subclass : A1.system.visibleClasses
$- (A1 $+ A1.inheritance);};
attributes
WIDTH 6 HEIGHT 2
PRINT print_UML
CREATE {class := A1;
CHECKID(THIS); ASK name; ASK type;};
DISPLAY acquaintances
WIDTH 6 HEIGHT 2
PRINT name + " " + printCard + " : "
+ getType.name;
// DISPLAY permet d'indiquer que ce champ ne peut pas
// être modifié par l'utilisateur
};
}
Browser commenté sur la classe System
BROWSER RootSystem::System_browser_UML :
LABEL "UML Local Packages Browser"|"Browser des Paquetages Locaux UML"
{// 1ère zone de liste:
TMP L1: Stereotype;
// Déclaration d'une variable temporaire d'éditeur L1
THIS.*System::(subsystems) :
// 1er onglet de la 1ère zone de liste:
// itération récursive sur la sous-arborescence
// de l'instance de System sur laquelle le
// browser s'est ouvert; la précision de la classe
// System (abstraite dans le méta-modèle TNI)
// permet de préciser que la recherche s'effectue
// aussi bien sur les instances de SubSystem que
// de RootSystem, toutes 2 sous-classes de System
LABEL "Packages"|"Paquetages"
// Label du 1er onglet de la première zone de liste
PRINT indent + print_UML
// "indent" et "print_UML" sont des méthodes qui,
// adressées à une instance de System, renvoient
// des chaînes; "+" permet leur concaténation;
// les instances isssues de l'expression "THIS.*System::(subsystems)"
// seront présentées à l'utilisateur par l'expression
// de présentation "indent + print_UML"
CREATE SubSystem {SELECT supersystem;
name := "p1"; CHECKID(THIS); ASK name;
create_UML_dgrms;}
// CREATE SubSystem :
// la création n'est ici autorisée que pour des
// instances de SubSystem
// "SELECT supersystem" :
// permet d'affecter à l'attribut identifiant
// "supersystem" de l'instance créée
// la sélection courante dans la liste des paquetages,
// et par défaut, le paquetage racine
// "CHECKID(THIS)" :
// permet de créer automatiquement un nom identifiant
// pour "THIS", l'instance créée
// "ASK name" :
// provoque la demande de saisie du nom à l'utilisateur
// "create_UML_dgrms" :
// appel d'une méthode sur l'instance créée
{// 1er groupe d'onglets de la 2ème zone de liste,
// dépendant de l'onglet "Packages"|"Paquetages":
// chacun des onglets de cette indentation est
// donc défini par une expression
// relative à une instance de System
servers_diagram $+ system_diagram
$+ class_diagrams $+ interaction_diagrams :
// 1er onglet du 1er groupe de la 2ème zone de liste:
// une union de diagrammes définis sur le paquetage;
// cette liste est typée par la superclasse commune
// à "servers_diagram, system_diagram, ...",
// à savoir "Diagram" dans le méta-modèle
LABEL "Diagrams"|"Diagrammes"
PRINT print_br_UML
CREATE UMLSystemDiagram {system := A1; ASK name;}
CREATE UMLClassDiagram {system := A1; ASK name;}
CREATE UML_OID {system := A1; ASK name;}
// les créations ne sont définies que pour
// les classes "UMLSystemDiagram, UMLClassDiagram, ..."
// du méta-modèle
;
$SORT(classes) :
// 2ème onglet du 1er groupe de la 2ème zone de liste:
// expression de tri sur les classes du système courant
// "classes" est une accointance de System
// dans le méta-modèle
LABEL "Classes"
PRINT print_active_UML
// COLOR #Blue
// permet d'affecter une couleur aux éléments de la liste
CREATE {system := A1;
CHECKID(THIS); ASK name;}
// code de création d'une instance de Class
INSERT (visibleClasses $- classes) :
{system := A1;}
// code d'insertion d'une instance de Class existante:
// permet le déplacement d'une classe d'un paquetage
// à un autre
{attributes :
LABEL "Attributes"|"Attributs"
PRINT print_UML
CREATE {class := A1;
CHECKID(THIS); ASK name;
ASK type: $SORT(ALL AtomicType
$+ (ALL Class)[is_type * (visibility=#public)]);
};
services.getStereotype $+ L1 :
// L1 contiendra les catégories qui auront été
// créées depuis l'ouverture du browser
LABEL "Categories"|"Catégories"
CREATE {ASK name; L1 := L1 $+ THIS; }
// on ajoute chaque nouvelle catégorie créée
// à la variable locale d'éditeur L1
INSERT ALL Stereotype $- THIS.services.getStereotype $- L1:
{L1 := L1 $+ THIS; }
// on ajoute chaque nouvelle catégorie insérée
// à la variable locale d'éditeur L1
{A1.services[getStereotype = THIS * NOT(isBlock)] :
LABEL "Operations"|"Opérations"
PRINT print_graph_no_param
CREATE{class := A2; stereotype := A1;
CHECKID(THIS); ASK name; ASK type;}
INSERT A1.services[getStereotype /= THIS * NOT(isBlock)]:
{stereotype := A1;};
};
acquaintances.association :
LABEL "Associations"
CREATE
{$FIRST(roles).class := A1;
// A1 est une variable contextuelle
// qui contient ici la classe sélectionnée
// dans la zone de liste précédente
$LAST(roles).name := A1.name;
ASK $FIRST(roles).name;
ASK $FIRST(roles).card_max;
ASK $LAST(roles).name;
ASK $LAST(roles).class: system.visibleClasses
// permet de spécifier un domaine de définition
// des classes potentielles de l'association
CREATE {system := A3;};
// il est possible de spécifier du code
// de création si l'utilisateur n'a pas encore
// créé la classe pendante de l'association
ASK $LAST(roles).card_max;
// la suite d'ordres ASK provoque l'ouverture
// d'une seule boîte de dialogue contenant
// l'ensemble des requêtes
};
};
used_systems :
LABEL "Used Packages"|"Paquetages Utilisés"
PRINT name
CREATE SubSystem {users += NEW Use;
$LAST(users).user_system := A1;
name := "p1"; CHECKID(THIS); ASK name;
ASK supersystem : ALL System $- THIS;}
INSERT (ALL System $- THIS $- used_systems):
{users += NEW Use;
$LAST(users).user_system := A1;};
types :
LABEL "Types"
CREATE {system_definer := A1; ASK name;};
};
};
Diagramme de systèmes commenté
DIAGRAM UMLSystemDiagram::theDiagram -dblclick :
// la racine du diagramme est une instance de UMLSystemDiagram
LABEL "Sub-Packages"|"Sous-Paquetages" {
system.*(subsystems) :
// expression OTScript permettant d'obtenir
// l'arborescence sémantique des paquetages existants
// (system est l'accointance qui relie la classe
// UMLSystemDiagram à la classe System dans le méta-modèle TNI).
// l'ensemble de ces paquetages est, du point de vue du diagramme,
// l'ensemble des entités sémantiques représentables
// graphiquement (mais pas obligatoirement représentées):
// un élément graphique qui représente sur la vue
// un paquetage est mémorisé dans un fichier.
//
EXHAUSTIVE TRUE
// ceci impose que l'ensemble des entités sémantiques
// figure graphiquement, ce qui n'est pas le cas
// lorsque EXHAUSTIVE TRUE n'est pas mentionné:
// on peut alors ne représenter graphiquement
// qu'une partie des entités sémantiques au moyen
// des fonctions utilisateur "Montrer" et "Cacher".
DISPLAY BoxWithLists(#Folder $+ #Left $+ #Bold, name)
// dit comment on représente les paquetages
// dans ce diagramme :
// BoxWithLists est une boîte pouvant contenir
// des champs; ses arguments précisent l'affichage:
// #Folder pour une boîte en forme de dossier,
// #Left $+ #Bold pour exprimer que le titre
// est justifié à gauche et en gras;
// name fournit le "print" souhaité pour le paquetage
CREATE SubSystem
// permet de créer des instances de SubSystem:
// il s'agit bien ici d'une création sémantique,
// qui sera aussitôt représentée sur le diagramme
{CLICK supersystem;
// demande à l'utilisateur de cliquer
// sur le paquetage père graphique
name := "p1"; CHECKID(THIS);
// affecte par défaut un nom puis calcule
// à partir de ce nom un nom identifiant valide
create_UML_dgrms;
// fait appel à la méthode create_UML_dgrms
}
{subsystems
$+ (THIS ISA RootSystem
IF TRUE: VOID SubSystem
IF FALSE: THIS[EACH ISA SubSystem])
INVERSE supersystem $+ THIS :
// il s'agit ici de tracer le lien père-fils
// entre les paquetages; or, ce lien n'est matérialisé
// par aucune classe dans le méta-modèle:
// pour matérialiser ces liens sur un paquetage,
// on va utiliser la notion de sous-paquetage,
// représentée par subsystems dans le méta-modèle;
// pour un paquetage donné (THIS), sa représentation
// graphique en tant que boîte va avoir pour fils
// graphiques le lien vers le père s'il existe,
// et le ou les liens vers les sous-paquetages
// s'ils existent:
// il faut donc fournir dans l'expression de navigation
// - les liens graphiques vers les sous-paquetages:
// subsystems
// - le lien vers le père s'il existe: THIS.
// la relation INVERSE permet une optimisation de l'outil
// en lui fournissant ses parents graphiques
EXHAUSTIVE TRUE
DISPLAY Link(#Default, VOID String, #DiamondTip);
// la représentation graphique associée est
// un lien (Link),
// de trait plein (#Default),
// sans label (VOID String),
// avec un losange à l'une des extrémités (#DiamondTip)
(needs $+ users) [is_local(A1.system)]
INVERSE used_system $+ user_system:
// il s'agit de dessiner les liens d'utilisation
// entre paquetages: ces liens sont matérialisés
// par la classe Use dans le méta-modèle;
// needs et users sont les accointances
// reliant un paquetage à ses liens "besoins"
// et à ses liens "utilisateurs".
// il est précisé dans ce diagramme que l'on ne montre
// que les utilisations locales, et non celles avec
// des paquetages externes: [is_local(A1.system)]
EXHAUSTIVE TRUE
DISPLAY Link(#Dash, "" , #OpenArrowTip)
// la représentation graphique associée est
// un lien (Link),
// de trait pointillé (#Dash),
// sans label (""),
// avec une flèche simple (#OpenArrowTip)
CREATE{CLICK user_system; CLICK used_system;};
// pour créer un rel lien, on demande à l'utilidateur
// de cliquer d'abord sur le paquetage utilisateur,
// (CLICK user_system), puis sur le paquetage
// utilisé (CLICK used_system)
classes[visibility = #public] INVERSE system :
// on peut intrduire ici dans les boîtes de paquetage
// des classes représentées sous forme de champ
// dans la boîte
DISPLAY SimpleName(#Default, name) -inbox
// -inbox signifie que cet objet graphique
// est représenté dans son parent;
// sémantiquement, c'est une classe qui est créée,
// et qui peut être montrée sous forme de boîte
// dans un diagramme de classes.
CREATE{CLICK system; CHECKID(THIS);};
};
notes :
// permet d'intrduire des remarques textuelles
// non sémantiques dans la zone graphique
// sous forme de rectangles éditables
EXHAUSTIVE TRUE
DISPLAY BoxWithLists(#Sheet $+ #Gray $+ #Filled $+ #Color1 $+ #Left, comment)
// BoxWithLists dessine une boîte
// ses arguments précisent l'affichage:
// #Sheet pour une boîte avec un coin replié,
// #Gray pour exprimer que le tour est en gris,
// #Filled $+ #Color1 pour exprimer
// que le fond est rempli par la couleur Color1
// définie dans le fichier "opentool.ini",
// #Left pour justifier le texte à gauche;
// comment fournit le texte affiché
CREATE{diagram := A1;};
// relie la "note" au diagramme
};