Sommaire
Index
OpenTool
06 Janvier 1997
  1. Onglets de formulaire commentés sur la classe Class
  2. Browser commenté sur la classe System
  3. 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
};