FR 2742245 A1 19970613 FR 9514576 A 19951208 / Procédé de manipulation de modèles de données utilisés en génie logiciel. La présente invention concerne un procédé de manipulation de modèles de données pour le transfert desdits modèles entre une pluralité d'outils de génie logiciel et l'application à un dit modèle, de règles de transformation, la transformation de modèles de données étant réalisée au moyen de passerelles permettant de convertir le format d'un outil dans le format d'un autre outil en passant par un format intermédiaire neutre et unique. De manière générale, la volonté commune et profonde des utilisateurs ou des concepteurs est de rechercher l'interopérabilité entre outils logiciels pour permettre d'échanger, sous forme de modèles de données, des informations relatives au développement d'applications entre des outils de développement hétérogènes utilisés dans leur environnement propre. En particulier, le transfert de modèles de données peut être d'une aide précieuse pour permettre par exemple, la migration d'applications entre outils de génie logiciel ou entre un outil de génie logiciel existant et un nouvel outil de développement d'un modèle clienUtserveur, ou bien la gestion d'informations de développement, sous forme de modèles de données, par exemple dans un référentiel (appelé "repository" par l'homme de métier). Ainsi, et ceci sachant que l'utilisation de tels outils est de plus en plus courante, il peut être désiré administrer, récupérer ou transférer des fichiers d'export d'un ou vers un ou plusieurs outils de génie logiciel du marché permettant de faire de la conception ou de l'analyse de modèles d'information. Cependant, dans l'état actuel des choses, divers inconvénients sont présentés. En effet, chaque outil a son propre formalisme interne et une manière privée ou spécifique de représenter les objets, de stocker les informations, etc., si bien que deux outils ne peuvent communiquer ou s'échanger directement des informations. La solution qui était encore récemment utilisée, pour passer outre ces inconvénients, consistait à développer pour chaque outil et d'outil à outil, ce que l'homme du métier appelle des "passerelles" c'est-à-dire des interfaces dont le rôle est de permettre de convertir le format d'un outil dans le format d'un autre outil. De la sorte, pour autoriser le dialogue entre outils, il devait être développé pour chaque outil un nombre de passerelles égal au nombre crd'outils avec lesquels il était désiré communiquer et lorsqu'un nouvel outil apparaissait il était nécessaire de développer pour chaque outil une passerelle spécifique pour autoriser le dialogue avec le nouvel outil. A l'évidence, cette solution présente un inconvénient principal qui est qu'elle nécessite de créer autant de passerelles qu'il y a de combinaisons d'outils possibles, ce qui en terme de coût et de temps de développement devient très rapidement prohibitif. En effet, à titre d'exemple et ceci même en prenant un nombre d'outils relativement restreint, pour permettre le dialogue entre, respectivement, 4, 5 ou 6 outils, il faudrait nécessairement développer, respectivement, 6, 10 ou 15 passerelles. Pour remédier au moins partiellement à cet inconvénient, certains ont imaginé une solution qui consistait à développer des passerelles également spécifiques mais prévues pour permettre de convertir le format d'un outil dans le format d'un autre outil en passant par un format intermédiaire commun neutre et donc unique en créant un modèle d'information pivot neutre servant de noyau d'échange. Cette notion de représentation neutre utilisant ce modèle d'information pivot, o toutes les passerelles passent par ce noyau d'échange, permet de réduire significativement le nombre de passerelles et ceci d'autant plus que le nombre d'outils à mettre en communication est grand. Ainsi, en reprenant l'exemple précédent, pour permettre le dialogue, entre, respectivement, 4, 5 ou 6 outils, il sera dans ce cas nécessaire de ne développer que, respectivement, 4, 5 ou 6 passerelles, une passerelle par outil pour accéder audit noyau d'échange et convertir le format dudit outil dans le format intermédiaire commun. Avec ce type de solution, pour assurer une portabilité aisée, il a été opté pour une approche propriétaire dans laquelle sont développés des langages spécifiques, donc écrits et interprétés pour remplir cette fonctionnalité, qui sont compacts, de contrôle facile et fonctionnellement adaptés. En effet, dans ce monde fermé le portage est assez significativement simplifié puisqu'un seul programme est à interpréter. Cependant, cette solution bien qu'avantageuse comporte également des inconvénients. Un premier inconvénient est inhérent au fait qu'un langage interprété est assez peu rapide, I'interprète devant analyser ledit langage pour pouvoir ensuite effectuer les actions décrites. Un second important inconvénient à utiliser un tel langage propriétaire est qu'il ne permet pas d'exploiter la notion de composant réutilisable. En effet, lorsqu'il est désiré développer une nouvelle passerelle, il est nécessaire de réécrire tout le code dans ce langage spécifique. Par ailleurs, de tels langages souffrent généralement d'un environnement de développement très pauvre (pas de bibliothèques de fonctions réutilisables, pas d'outil de mise au point ou "débogueur", etc.). La présente invention a pour but de remédier aux divers inconvénients des différentes méthodes de l'art antérieur connues et propose un procédé de manipulation de modèles de données qui, de par le choix judicieux du langage utilisé apporte une importante flexibilité et une grande rapidité d"exécution, est aisément extensible et permet d'exploiter la notion de composant réutilisable tout en offrant un haut niveau de portabilité et de performances ainsi qu'un faible coût. Pour cela, le procédé de manipulation de modèles de données mentionné dans le préambule est remarquable en ce que, l'élaboration des passerelles est, selon une approche dite orientée objet, réalisée à partir d'un langage exécuté, les passerelles étant des exécutables permettant la transformation d'un modèle de données en plusieurs étapes activées successivement, de manière systématique ou conditionnelle, grâce à un langage de commande décrivant une logique d'enchaînement dynamique des étapes, l'enchaînement étant une procédure paramétrée et nommée, chaque étape étant un exécutable dont le code est développé à partir d'un ensemble de classes réutilisables et l'activation d'une procédure nécessitant simplement de fournir le nom et les paramètres de la procédure correspondante. Ainsi, selon l'idée de l'invention, il a été décidé d'utiliser un langage exécuté en adoptant une approche orientée objet et ceci malgré un préjugé défavorable, les langages propriétaires développés de manière spécifique étant considérés autoriser une portabilité aisée et favoriser une stricte adaptation fonctionnelle ressentie comme nécessaire. Contrairement à ce préjugé et donc aux approches antérieures connues, il a donc été décidé d'utiliser un langage standard connu plus flexible, de préférence directement compilé et dont la gestion mémoire est plus fine et plus efficace, par exemple comme le langage C++. En outre, un tel langage présente un très bon niveau d'abstraction et, employé avec des bibliothèques adéquates, il permet d'une part, d'augmenter l'efficacité et la rapidité et d'autre part, d'apporter une avantageuse généricité puisqu'une même structure peut être réutilisée dans des contextes différents, les facteurs de réutilisabilité et de compatibilité étant ainsi de plus favorisés. Autre avantage, ce type de langage peut être aisément mis au point à l'aide d'un débogueur correspondant, ce qui permet de diminuer encore les temps de développement des passerelles. Enfin, un tel choix d'un langage standard pour lequel il existe de très nombreux produits et utilisateurs ne peut qu'offrir l'assurance d'un environnement de qualité. De cette manière, pour réaliser des transferts d'un outil à un autre ou d'un modèle à un autre, il existe plusieurs composants conçus pour permettre d'exécuter le code d'une passerelle, chaque passerelle étant en fait développée comme un programme orienté objet construit à l'aide de bibliothèques de classes s réutilisables. Ces classes vont servir à élaborer différentes passerelles sachant qu'une passerelle peut être construite en plusieurs phases, par exemple, une phase de décodage physique des fichiers par reconnaissance des codes et donc des éléments syntaxiques dans le fichier d'import, puis une phase de codage de la transformation dans laquelle sont trouvés ou créés les correspondants des éléments syntaxiques dans le modèle d'information neutre et éventuellement une phase de contrôle d'intégrité. Chacune de ces phases constitue un module réutilisable et l'ensemble des modules peut être enchaîné dynamiquement non comme un programme mais selon une suite de procédures à appliquer. Pour cela, la liste des modules à enchaîner dynamiquement est décrite à l'aide d'un fichier de définition d'opérations (appelé également "operation definition file" par l'homme du métier), alors qu'un gestionnaire de tâches (appelé aussi 'task manager" par l'homme du métier) va chercher, parmi les exécutables contenant les procédures réutilisables, lesdits modules pour les exécuter et ainsi construire la passerelle en tenant compte des paramètres de configuration pour I'adaptation de ladite passerelle. Toutes ces informations peuvent être stockées dans un espace persistant, par exemple un disque, tandis que les résultats intermédiaires sont gardés temporairement en mémoire. En outre, le gestionnaire de tâches permet également de sélectionner l'ordre d'exécution optimal lorsqu'il existe simultanément plus d'une procédure et/ou d'un exécutable qui conviennent. En effet, il peut être, par exemple disposé de plusieurs copies de différentes procédures, dans ce cas, le gestionnaire de tâches sélectionne automatiquement la séquence de modules et la classe de procédure qui minimise le chargement des exécutables ce qui permet d'optimiser la durée d'exécution. Le procédé de manipulation de modèles de données active donc des composants réutilisables qui permettent de développer rapidement des passerelles. De manière remarquable, pour le développement d'une passerelle, il est créé une classe réutilisable permettant de représenter les modèles et méta- modèles stockés en mémoire dans un référentiel ou dans un fichier externe en utilisant une allocation dynamique des objets de modélisation, les objets de cette classe intégrant un ensemble de structures de mémoire et fournissant des fonctions pour manipuler les données d'un modèle chargé en mémoire. De manière générale, les données peuvent être stockées sous différentes formes, formats et emplacements. De préférence et de sorte à simplifier les manipulations, les mécanismes suivants sont ici privilégiés: - un mécanisme permettant de lire, écrire et analyser les fichiers d'export d'outil (ou '"tool export file") qui sont des fichiers de données utilisateur générés par un outil dans un format propriétaire, - des mécanismes qui correspondent à des objets, par exemple des objets C++ , qui encapsulent ou intègrent chacun un ensemble de structures mémoire et fournissent des fonctions pour manipuler des modèles de données chargés à partir de fichiers d'export d'outil et/ou d'un référentiel, la mise en oeuvre de ces objets et les fonctions de manipulation de ces objets constituant une classe réutilisable. De manière préférée, l'organisation des données d'un modèle est basée sur un métamodèle chargé au moment de la création de ces classes, les métamodèles étant chargés au moment de l'exécution à partir de fichiers de textes appelés fichiers de métamodèles. Une telle classe peut être chargée avec un métamodèle d'outil ou peut être chargée avec un métamodèle du modèle d'information neutre, ces deux types d'objets étant utilisés pendant l'exécution de la passerelle, - un mécanisme appelé fichier de données neutre qui est un fichier de texte contenant des données qui ont été mises en correspondance avec des données du modèle d'information neutre, ce mécanisme étant utilisé pour le transfert des données entre différents exécutables ou pour le stockage permanent sue disque, - un référentiel dans lequel les données d'un utilisateur peuvent être stockées en utilisant des schémas représentant le modèle d'information neutre, et être gérées par des outils du référentiel (par exemple, gestion des versions, des requêtes, etc.). Ainsi, avec les passerelles, les données peuvent être déplacées et manipulées d'un emplacement ou d'un mécanisme de stockage à un autre et/ou d'une forme à une autre. Il peut être donné trois exemples de passerelles, les passerelles d'import, d'export ou de transfert. La mise en oeuvre d'une passerelle d'import permet d'extraire des données d'un fichier d'export d'un outil pour les placer dans le référentiel alors que la mise en oeuvre d'une passerelle d'export permet d'extraire des données du référentiel pour créer un fichier d"export d'outil. La mise en oeuvre d'une passerelle de transfert permet elle de récupérer des données directement d'un fichier d'export d'un outil à un autre sans passer par s un stockage dans le référentiel. Il y a bien entendu d'autres types d'opérations dont l'objet n'est pas nécessairement de déplacer ou de coder des données mais qui permettent de traiter des données chargées à un instant donné en mémoire. Toutes ces opérations requièrent donc la possibilité de charger des données en mémoire, de les manipuler ainsi que d'écrire les données en les stockant de manière persistante, ces opérations étant réalisables du fait de l'existence des classes réutilisables et des fonctions ici revendiquées. Un certain nombre d'opérations requièrent la création d'objets mutiples et impliquent des conversions ou codages entre divers objets. Par exemple, lorsque des données sont extraites d'un fichier d'export d'outil, un exécutable permet d'analyser syntaxiquement ce fichier et de créer un objet qui contient les données du fichier d'export mais structurées de manière à correspondre au métamodèle de l'outil. Ensuite, les données spécifiques de l'outil sont converties en données générales selon le modèle d'information neutre qui implique la conversion de cet objet en un objet correspondant au modèle d'information neutre. Les données ainsi stockées peuvent être traitées et éventuellement sauvegardées dans un fichier de données neutre (si les données doivent être communiquées à un autre exécutable) ou stockées dans le référentiel. Par conséquent, les passerelles permettent d'accéder aux modèles de données et aux définitions de métamodèles stockés en mémoire, les objets des modèles étant dynamiquement alloués en mémoire. Après chargement du métamodèle, un modèle est construit en utilisant le gabarit du métamodèle. Les ensembles de modèles ont une structure similaire à celle des ensembles de métamodèles, ce qui autorise de rapides mises en correspondance entre objets et entre définitions des propriétés et leurs instances. Egalement de manière caractéristique, pour le développement d'une passerelle, il est créé une classe réutilisable permettant de coder et décoder différents formats de fichiers d'export d'outils, cette classe encapsulant les enregistrements d'export d'outil et étant utilisée pour décrire les formats d'enregistrement d'un fichier d'import, alors qu'à l'initialisation, tandis que le métamodèle d'un outil est lu à l'aide de la classe de représentation des modèles et métamodèles stockés en mémoire à partir d'un fichier de texte, le code de la passerelle permet de lire le fichier d'export d'outil, d'accéder aux champs propres aux enregistrements et de créer les objets et leurs propriétés en utilisant les fonctions de la classe de représentation des modèles et métamodèles stockés en mémoire. En effet, les langages de programmation et donc également le langage C++ ne permettent pas de manipuler de manière directe des structures contenant plusieurs champs variables. La solution proposée ici est de mettre en oeuvre des déclarations d'enregistrements sous la forme d'une série de descripteurs de champs. Le programmeur définit des tailles de champs fixes et variables, des codes type d'enregistrement avec pour valeurs des constantes et des valeurs de séparateurs. Dans le code traitement, le programmeur appelle d'abord des fonctions permettant de faire correspondre un enregistrement avec son descripteur puis accède aux champs de l'enregistrement. Pour la création d'un enregistrement du fichier d'export, le programmeur remplit les champs propres à cet enregistrement à partir des données du modèle puis il écrit l'enregistrement dans son entier. La description de l'enregistrement comporte, pour chaque champ, le nom, le type et la taille de l'information au moment de l'exécution. L'information de description de même que les données peuvent être affichées pour la mise au point. Cette classe ainsi revendiquée permet de définir des macros pour la construction des descripteurs d'enregistrement et des prototypes de fonctions pour faire correspondre un registre avec une description d'enregistrement, en fournissant des données à partir d'un champ dans un enregistrement, en fixant des données dans un champ d'enregistrement et en fournissant un enregistrement complet pour l'extraction. Cette classe réutilisable permet ainsi avantageusement de réaliser différents traitements de différents fichiers d'export d'outil, ces fichiers étant lus et écrits au moyen de composants de la passerelle. Enfin et également de manière remarquable, pour le développement d'une passerelle, il est créé une classe réutilisable de manipulation de chaînes de caractères qui permet de prendre en charge les affectations, les concaténations et les opérateurs de comparaison avec les fonctions de sous-chaîne et de réaffectation dynamique de mémoire tout en conservant la compatibilité avec les chaînes de caractères d'un langage de type C. De cette manière, cette classe réutilisable fournit une solution technique pratique en proposant un type de données spécifique des chaînes de caractères qui offre un comportement comparable à celui des types de données prédéfinis en langage C. Cette classe présente aussi une caractéristique de grande importance, car elle permet d'interdire toute perte d'information généralement associée à des pertes de blocs de mémoire. La description suivante en regard des dessins annexés, le tout donné à titre d'exemple non limitatif, fera bien comprendre comment et dans quel environnement l'invention peut être réalisée. La figure 1 donne un exemple d'interopérabilité selon la présente invention entre divers outils de génie logiciel. La figure 2 représente une architecture dans laquelle apparaissent divers composants permettant de mettre en oeuvre l'invention. Sur la figure 1 est présentée de manière schématique et en conformité avec l'idée de l'invention la possible et avantageuse interopérabilité dans un ensemble d'outils Ta, Tb, Tc, Td,..., de génie logiciel, lesdits outils s'échangeant, sous forme de modèles de données, des informations, par exemple, relatives au développement d'applications. Les outils Ta, Tb, Tc et Td sont des outils de développement hétérogènes utilisés, chacun, dans un environnement propre et avec son propre dictionnaire. La transformation de modèles de données entre ces quatre outils est réalisée au moyen de passerelles telles que Ba, Bb, Bc et Bd qui permettent de convertir le format propre d'un des outils Ta, Tb, Tc, Td dans le format propre d'un autre desdits outils en passant par un format intermédiaire neutre et unique, le modèle d'information neutre NIM. Plus précisément, les informations échangées transitent par les fichiers d'export desdits outils qui ainsi transmettent ou recoivent les données vers le ou du modèle NIM qui est par conséquent le modèle pivot. Les données qui instancient le modèle d'information neutre NIM sont stockées dans une base de données objets appelée référentiel. Sur la figure 2 est proposé un exemple d'architecture dans laquelle apparaissent divers composants permettant de mettre en oeuvre l'invention, composants parmi lesquels des interfaces, des contrôleurs, des mécanismes de stockage, des fichiers de configuration, des séquences type de contrôle (scripts dans le langage exécuté selon l'invention). des passerelles ainsi que le référentiel. Cet environnement peut être considéré comme étant une boîte à outils de développement. Toute action de cette boîte à outils est contrôlée par une classe de contrôle CC appelée aussi classe d'interface programmeur, cette classe permet d'organiser l'environnement pour le transfert de données et également d'appeler les procédures adéquates. Les développeurs d'interfaces pour la visualisation sur l'écran d'un poste de travail WS, comme l'interface graphique utilisateur GUI, l'interface de lignes de commande CLI ou tout autre interface, utilisent exclusivement la classe de contrôle CC. Cette classe CC contient les fonctions de l'interface applicative (API) permettant d'appeler les passerelles et de lancer toute commande. Il est ici rappelé d'une part, qu'une passerelle est un mécanisme spécifique pour autoriser le déplacement de données d'un emplacement à un autre et leur manipulation d'une forme à une autre et d'autre part qu'il existe, entre autres, trois types de passerelles, les passerelles d'import, d'export et de transfert. La classe de contrôle CC est paramétrée par les fichiers de configuration CF et les séquences de type contrôle CS (scripts). Les données peuvent être chargées en mémoire sous différentes formes et formats et à des emplacements différents. Quatre mécanismes de stockage peuvent être ainsi utilisés, chacun ayant une utilité propre et possédant son propre jeu de services associés, ce sont les fichiers d'export d'outil TEF, le fichier de données neutre NDF, le référentiel R et un mécanisme D d'allocation dynamique d'objets de modèle. Un fichier d'export d'outil TEF est en fait un fichier de données utilisateur généré par un outil externe dans le format propriétaire dudit outil, ce fichier TEF peut être, selon les moyens de l'invention, lu, écrit et analysé. Un fichier de données neutre NDF qui lui est un fichier de texte contenant le résultat de la modélisation, selon le métamodèle d'information neutre, du modèle importé et initialement structuré selon le métamodèle de l'outil. Ce fichier NDF est une représentation ASCII de cette représentation neutre du modèle. Des services de lecture et d'écriture du fichier de données neutre NDF sont fournis selon l'invention. Un fichier de données neutre permet de transférer des données relatives à des objets C++ d'un exécutable à des objets C++ d'un autre exécutable en évitant toute perte de données. Le référentiel R contient, quant à lui, un schéma permettant de mettre en oeuvre le modèle d'information neutre. Les données d'un utilisateur peuvent être stockées dans le référentiel dans le format du modèle d'information neutre et ensuite gérées et manipulées par des outils du référentiel incluant la gestion des versions, des requêtes, etc., alors que des services sont fournis pour stocker des données dans ou extraire des données du référentiel. Un fichier de données neutre NDF peut aussi être stocké dans le référentiel comme un objet avec son contenu. Le mécanisme D d'allocation dynamique d'objets de modèles est également un point fort de l'invention, il fournit un jeu de classes C++ utilisé pour la représentation de modèles de données de façon totalement générique et dans la manière spécifiée par les données du métamodèle chargées au moment de l'exécution. Un métamodèle est chargé à partir d'un fichier de texte appelé fichier de métamodèle et est stocké comme un objet C++. Les données d'un utilisateur qui sont ensuite stockées comme objets C++, sont mises en correspondance dans le métamodèle associé. Il est à noter que le modèle d'information neutre est un métamodèle prévu pour être suffisament complet pour permettre de capturer la plupart des concepts de tous les métamodèles d'outils. Un objet C++ qui est chargé avec le métamodèle du modèle d'information neutre est en fait un format de stockage central ou pivot à partir duquel peut être généré tout autre format de stockage. Le mécanisme D d'allocation dynamique d'objets contient l'ensemble des classes nécessaires à la mise en oeuvre de l'invention de même qu'il contient tous les métamodèles MTa, MTb,..., NIM MT. Les quatre mécanismes de stockage, fichiers TEF, fichiers NDF, référentiel R et mécanisme D sont en relation directe avec un mécanisme de passerelles et d'opérations OBM qui est également en relation avec la classe de contrôle CC. Comme cela a déjà été dit précédemment et de plus en relation avec la figure 2 et en particulier le mécanisme de passerelles et d'opérations OBM, pour réaliser des transferts d'un outil à un autre ou d'un format à un autre, il existe plusieurs composants conçus pour permettre d'exécuter le code d'une passerelle, chaque passerelle étant en fait une opération développée comme un programme orienté objet construit à l'aide de bibliothèques de classes réutilisables. Ces classes servent à élaborer différentes passerelles Ba, Bb, Bc,...,sachant qu'une passerelle peut être construite en plusieurs phases, par exemple, une phase de décodage physique des fichiers par reconnaissance des codes et donc des éléments syntaxiques dans le fichier d'import, puis une phase de codage de la transformation dans laquelle sont trouvés ou créés les correspondants des éléments syntaxiques dans le modèle d'information neutre et éventuellement une phase de contrôle d'intégrité (mécanisme IC). Chacune de ces phases constitue un module réutilisable et l'ensemble des modules peut être enchaîné dynamiquement non comme un programme mais selon une suite de procédures. Pour cela, la liste des modules à enchaîner dynamiquement est décrite à l'aide d'un fichier de définition d'opérations ODF (appelé également "operation definition file" par l'homme du métier), fichier exploité par un gestionnaire de tâches TM (appelé aussi 'task manager" par l'homme du métier) qui va chercher, parmi les exécutables contenant les procédures réutilisables, lesdits modules pour les exécuter et ainsi construire la passerelle en tenant compte des paramètres de configuration pour l'adaptation de ladite passerelle tout en autorisant, comme cela a été explicité précédemment, une avantageuse réduction de la durée d'exécution. Tous ces paramètres peuvent être stockés dans un espace persistant (CS), tandis que les résultats intermédiaires sont gardés temporairement en mémoire. Le procédé de manipulation de modèles de données active donc des composants réutilisables qui permettent de développer rapidement des passerelles. Des opérations autres que les passerelles peuvent être effectuées telles que des opérations autonomes ("standalone operations") qui sont des opérations dans lesquelles les données ne sont pas obligatoirement déplacées ou converties, par exemple le contrôle d'intégrité IC ou les services de conversion de nommage NCS. Pour une meilleure appréhension de l'idée de l'invention, il est proposé ci-après quelques définitions et une description de mises en oeuvre possibles mais non limitatives de diverses classes revendiquées selon la présente invention. Tout d'abord, il est proposé des définitions de classes relativement à l'organisation des "scripts" et aux configurations, se rappelant qu'un composant d'une application est un programme qui fournit une interface à un utilisateur de l'environnement de l'invention, interface qui peut être de tout type. L'application instancie un objet de la classe de contrôle (TsControl Class) au nom de l'utilisateur, puis appelle ses fonctions pour connaître les opérations permises à cet utilisateur. L'utilisateur peut soit choisir parmi ces opérations et fournir des informations sur la manière dont lesdites opérations doivent être exécutées soit spécifier des "scripts" de contrôle prédéfinis qui contiennent ces instructions et informations. Lorsque l'application le permet, la classe de contrôle (TsControl Class) peut être également utilisée pour créer ces "scripts" prédéfinis. La classe de contrôle (TsControl Class) est utilisée pour configurer et initier les opérations dans l'environnement de l'invention. L'application utilise les fonctions pour lire et écrire les "scripts" de contrôle et dresser la liste des opérations possibles. Les valeurs mots-clés peuvent être définies en utilisant les fonctions "set" et "get" et des actions peuvent être commandées en utilisant la fonction "do". Certaines de ces fonctions sont génériques lorsque l'utilisateur spécifie le mot-clé ou l'opération auquel la fonction s'applique, tandis que la plupart des fonctions sont spécifiques de mots-clés ou d'opérations connues. Ces dernières fonctions sont prévues pour être utilisées avec une interface appropriée et le code du composant de l'application. classe TsControl TsSysConfig sysconf; Il Objet fichier de configuration TsMessageLib msglib; //Objet bibliothèque de messages TsOperCtlScript //Script de contrôle *operctl; Il Pointeur d'objet TsStr opemame; /Nom d'opération Singly_linkedlist(TsKwdlnfoPtr) Il Liste de mots-clés keywords; /I Doubly_linkedlist(TsStr) Il Liste d'outils disponibles btools_list; Il int error; Il Valeur d'état d'erreur il Valeurs mémorisées de mots-clé communs et connus, TsTokens importfiles; Il Liste de fichiers d'import TsTokens exportfiles; Il Liste de fichiers d'export TsStr srcpctepath; Il Nom d'accès au référentiel (source) TsStr tarpctepath; Il Nom d'accès au référentiel (cible) TsStr srctoolname; //Nom de l'outil source TsStr tartoolname; Il Nom de l'outil cible TsStr logfilepath; //Nom d'accès au fichier-joumrnal TsBoolean autonaming; Il Indicateur de nom normalisé TsBoolean autochecking; Il Indicateur de contrôle d'intégrité Il Fonctions internes Doubly_linkedlist(TsStr) * I GetGroupPrompts( Il Lecture de noms de groupes Singly_linkedlist(TsGrouplnfoPtr) Il Groupement d'info et retour group_list); Y vers le demandeur TsKwdlnfo FindKeyword( Il Trouver définition de mot-clé const TsStr& keyword) const; // objet pour un mot-clé donné void AddKeywords(const / Ajouter mots-clés à la liste Singly_linked_list(TsKwdlnfoPtr)& / Liste de mots-clés kwd_list); Il Il Fonctions constructeur et destructeur TsControl( // Constructeur const TsStr& sys_config_path, Il Chemin du fichier de configuration const TsStr& msg_lib_path / Chemin bibliothèque de messages ); // virtual -TsControl(; Il Destructeur Il Fonctions pour le chargement et la génération de "scripts" de contrôle et leurs exécutions int LoadNewOperCtlScript( Il Charger un "script" de contrôle const TsStr& ctlscript_path); I1 int WriteOperCtlScript(; I1 Ecrire valeurs dans "script" de contrôle int CreateOperCtlScript( Il Créer un "script" de contrôle const TsStr& ctlscript_path); /I int RunOperCtlScript(; I1 Exécuter "script" de contrôle Il Fonctions pour fixer et lire le nom de l'opération void SetOperationName( Il Fixer le nom de l'opération const TsStr& opname); Il const TsStr& GetOperationName( const; Il Lire le nom de l'opération s Il Fonctions pour fixer et lire les valeurs de mots-clés connus void SetTargetPctePath( Il Fixer chemin référentiel (cible) const TsStr& tpath); Il const TsStr& GetTargetPctePath() const; Il Lire chemin référentiel (cible) void SetSourcePctePath( Il Fixer chemin référentiel (source) const TsStr& spath); Il const TsStr& GetSourcePctePath( const; Il Lire chemin référentiel (source) void SetTargetToolName( Il Fixer nom de l'outil cible const TsStr& tname); Yl const TsStr& GetTargetToolName( const //Lire nom de l'outil cible void SetSourceToolName( Il Fixer nom de l'outil cible const TsStr& sname); Il const TsStr& GetSourceToolName( const; Il Lire nom de l'outil source void SetLogFilePath( Il Fixer chemin fichier-joumrnal const TsStr& Ipath); Il const TsStr& GetLogFilePath() const; Il Lire chemin fichierjoumrnal void SetAutoNamingOn(); Il Enclenche la normalisation des noms void SetAutoNamingOff(); Il Supprime la normalisation des noms void SetAutoNamingFlag( Il Fixer valeur d'indicateur de nom const TsStr& name_flag); Il Chaîne de caractères indicateur int GetAutoNamingState(); Il Lire état indicateur nom const char *const GetAutoNamingFlag(; Il Lire indicateur nom void SetAutoCheckingOn(); Il Indique contrôle d'intégrité void SetAutoCheckingOff(; Il N'indique pas contrôle d'intégrité void SetAutoCheckingFlag( Il Fixer valeur indicateur contrôle d'intégrité const TsStr& check_flag); Il Indicateur de chaîne de caractères int GetAutoCheckingState(; Il Lire état indicateur contrôle d'intégrité const char *const GetAutoCheckingFlag(); Il Lire valeur indicateur contrôle d'intégrité void SetlmportFiles( Il Ajouter noms fichiers import const TsStr& ifiles); Il Chaîne noms fichiers import void AddlmportFile( Il Ajouter nom fichier import const TsStr& ifile); Il Nom fichier import void RemovelmportFile( Il Annuler nom fichier import const TsStr& ifile); Il Nom fichier import int IslmportFileOnList( //Il Vérifier si nom sur liste const TsStr& ifile); Il Nom fichier import const TsStr& GetlmportFilesStr(; Il Lire chaîne noms fichiers import const Doubly_linkedlist(TsStr)& Il GetlmportFilesList(; Il Lire liste noms fichiers import void SetExportFiles( Il Ajouter nom fichiers export const TsStr& efiles);// Il Chaîne noms fichiers export void AddExportFile( Il Ajouter nom fichier export const TsStr& efile); Il Nom fichier export void RemoveExportFile( Il Annuler nom fichier export const TsStr& efile); Il Nom fichier export int IsExportFileOnList( Il Vérifier si nom sur liste const TsStr& efile); Il Nom fichier export const TsStr& GetExportFilesStr(); Il Lire chaîne noms fichiers export const Doubly_linkedlist(TsStr)& Il GetExportFilesList(); Il Lire liste noms fichier export const Doubly_linkedlist(TsStr) * Y ListTools(); Il Lire liste noms outils disponibles Il Fonctions de mots- clés générales void SetKeywordValue( Il Ajouter mot-clé à la liste const TsStr& name, Il Chaîne nom mot-clé const TsStr& value); Il Chaîne valeur de mot-clé const TsStr& GetKeywordValue( Il Trouver valeur de mot-clé pour const TsStr& keyword) const; Il nom mot-clé donné void RemoveKeyword( Il Trouver définition de mot- clé const TsStr& keyword); Il objet pour nom mot-clé donné Doubly_linkedlist(TsStr) * Il Trouver noms de GetGroups(const TsKwdExpr& exp); Il Critères rencontre groupes Doubly_linkedlist(TsStr) * Il Trouver noms de GetGroups(const TsKwdlnfo& inf); Il Critères rencontre groupes Il Fonctions pour exécuter des opérations specifiques (import, export, etc.) void Dolmport(; Il Exécute opération import void DoExport(; Il Exécute opération export void DoTransfer(; Il Exécute opération transfert Il Autres fonctions de classes operator int () const; Il Enregistrer entier void Print(); I/Imprimer valeurs dans objet }; Il Fin classe TsControl La classe SysConfig est une classe spécifique du fichier de configuration dans l'environnement de l'invention. L'instantiation permet de fixer le nom d'accès du fichier de configuration. Cette classe peut être utilisée de deux manières. Selon une première manière, lors de l'installation, un exécutable appelé avec un indicateur spécial et le nom d'accès du fichier de configuration instancie cette classe et appelle la fonction statique "SysConfig::AppendLocalConfigurationO" qui a juste à appeler la table de configuration courante de l'exécutable (à partir d'une table statique) à la fin du fichier. Toute information pour l'exécutable courant qui existait antérieurement dans le fichier est annulée. Selon l'utilisation normale, la classe SysConfig présente une fonction "SysConfig::LoadFileO" d'enregistrement et d'analyse du fichier de configuration et de création des structures de données d'exécutable, de groupe, de méthode, etc., qui représente ce qui existe dans la présente installation. La fonction LoadFile() vérifie également que la configuration de l'exécutable courant correspond à ce qui est dans le fichier de configuration. Une série de fonctions "SysConfig::Find...(" offre un accès rapide aux structures du système pour la récupération de l'information de configuration. classe SysConfig TsStr pathname; I1 Nom d'accès au fichier configuration TsFileReader *input; Il Objet pour lecture configuration TsFileWriter *output; Il Objet pour écriture configuration Singly_linkedring(TsExeclnfo *) exec_list; Il Structures données configuration TsExeclnfo *currexec; Il Pointeur vers info courante exécution TsGrouplnfo *currgroup; Il Pointeur vers groupe courant TsMethodlnfo *currmethod; Il Pointeur vers méthode courante SysConfig(const TsStr& path); Il Constructeur -SysConfig(; Il Destructeur int LoadFile(); Il Lecture et analyse fichier TsExeclnfo *FindExec(const TsStr& name, I1 Trouver exécutable nommé const TsStr& location); Il TsGrouplnfo *FindGroup(const TsStr& name); Il Trouver groupe nommé TsMethodlnfo *FindProc(const TsStr& name); Il Trouver méthode nommée static int AppendLocalConfiguration(; Il Ecriture info dans fichier static int DeleteLocalConfiguration(); Il Annulation info dans fichier } La classe OperCtlScript est une classe spécifique des scripts de contrôle de l'environnement de l'invention. L'instantiation permet de fixer le nom d'accès du script de contrôle. La fonction "OperCtlScript::LoadFile(" est utilisée pour enregistrer et analyser le script de contrôle en créant un liste d'opérations à exécuter avec les listes correspondantes de définitions de mots-clés. La fonction "OperCtlScript::SaveFile(" est utilisée pour sortir les définitions et les commandes d'un script de contrôle. Cette classe renferme également des fonctions pour l'exécution des commandes et la configuration et l'appel de l'exécutable suivant. classe OperCtlScript TsStr pathname; Il Nom d'accès du script int temp; Il Indicateur temporaire de script TsFileReader *input; Il Objet pour lecture script TsFileWriter *output; Il Objet pour écriture script TsExeclnfo *curr_exec; Il Exécutable courant TsGrouplnfo *currgroup; Il Groupe courant TsMethodlnfo *curr_method; Il Méthode courante Singly_LinkedList(TsMethodlnfo *) commands; Il Commandes à exécuter Singly_LinkedList(TsDef *) defines; Il Paramètres pour commandes SysConfig *system; Il Pointeur vers l'objet SysConfig TsStr next_exec; Il Exécution suivante à effectuer TsStr next_loc Il Emplacement exécution suivante OperCtlScript(const TsStr& path); Il Constructeur - OperCtlScript(; Il Destructeur int LoadFile(); Il Lecture et analyse fichier int SaveFile(); Il Ecriture configuration fichier int SaveFile(const TsStr& newpath); Il Creation nouveau fichier int RunCommands(); Il Appel méthodes int PassExecution(); Il Appel nouvel exécutable } La classe TsDef est utilisée pour stocker et récupérer les mots-clés et les valeurs d'un script de contrôle. classe TsDef { TsStr keyword; I/ Identifiant mot-clé TsStr value; Il Valeur mot-clé TsDef(const TsStr& kwd, const TsStr& val); Il Constructeur -TsDef(); Il Destructeur void SetValue(const TsStr& val); Il Fixer valeur de mot- clé const TsStr& GetKeyword(); Il Lire identifiant de mot-clé const TsStr& GetValue(); Il Lire valeur de mot-clé } La classeTsKwdlnfo est utilisée pour stocker et récupérer les mots-clés et demander les identifiants d'un fichier de configuration. Un objet de cette classe stocke également un pointeur vers l'objet TsDef contenant la valeur courante (définition la plus récente) du mot-clé. classe TsKwdlnfo ( TsStr keyword; I Identifiant mot-clé int prompt_id; Il Message chaîne guide TsDef *definition; Il Pointeur vers objet valeur mot-clé TsKwdlnfo(const TsStr& kwd, Il Constructeur const TsStr& prmt); Il -TsKwdlnfo(; Il Destructeur int SetDef(const Singly_linkedlist(TsDef *)& defs); Il Fixer valeur mot-clé const TsStr& GetKeyword(); Il Lire identifiant de mot-clé const TsStr& GetValue(); Il Lire valeur de mot-clé const TsStr& GetPrompt(); Il Lire chaîne guide } La classe TsMethodlnfo est utilisée pour identifier une méthode avec ses mots- clés et options associés. class TsMethodlnfo TsStr name; Il Nom de méthode TsGrouplnfo *group; //l Retour pointeur vers objet groupe Singly_linkedlist(TsKwdlnfo *) kwdlist; Il Liste mots-clés Singly_linkedlist(TsKwdlnfo *) optlist; Il Liste options TsMethodlnfo(const TsStr& nam, TsGrouplnfo *grp); Il Constructeur - TsMethodlnfo(); Il Destructeur const TsStr& GetName(); Il Lire nom méthode TsGrouplnfo *GetGroup(); Il Lire pointeur vers objet groupe void AddKeyword(TsKwdlnfo *kwd); Il Ajouter mot-clé à liste void AddOption(TsKwdlnfo *opt); Il Ajouter option à liste TsKwdlnfo *FindKey(const TsStr& key_name); Il Lire mot- clé } La classe TsGrouplnfo est utilisée pour identifier un groupe et ses méthodes associées. classe TsGrouplnfo { TsStr name; Il Nom groupe TsExeclnfo *exec; Il Retour pointeur vers exécutable Singly_linkedlist(TsMethodlnfo *) method_list; // Liste méthodes TsGrouplnfo(const TsStr& nam, TsExeclnfo *exc);// Constructeur -TsGrouplnfo(); Il Destructeur const TsStr& GetName(); Il Lire nom groupe TsExeclnfo *GetExec(; Il Lire pointeur vers objet exécutable void AddProc(TsMethodlnfo *method); Il Ajouter méthode à liste TsMethodlnfo *FindProc(const TsStr& methodname);// Lire méthode } La classe TsExeclnfo est utilisée pour identifier un exécutable et ses groupes associés. classe TsExeclnfo TsStr name; Il Nom exécutable TsStr location; Il Nom d'accès exécutable Singly_linkedlist(TsGrouplnfo *) group_list; Il Liste groupes TsExeclnfo(const TsStr& nam, i Constructeur const TsStr& location); I1 -TsExeclnfo(; IY Destructeur const TsStr& GetName(); Yl Lire nom exécutable const TsStr& GetLocation(); Il Lire chemin exécutable void AddGroup(TsGrouplnfo *group); Il Ajouter groupe à liste TsGrouplnfo *FindGroup(const TsStr& group_name); Il Lire groupe } Il est à présent proposé des définitions de classes relatives à la représentation des modèles et métamodèles stockés en mémoire et à l'allocation dynamique des objets de modélisation. Le mécanisme (appelé mécanisme D sur la figure 2) utilisé permet de stocker en mémoire, pour accès par les composants de la passerelle, une définition de métamodèle et un modèle de données en allouant dynamiquement les objets du modèle dans ladite mémoire. Ce mécanisme permet de charger un métamodèle puis de construire un modèle en utilisant le gabarit du métamodèle. Une telle construction permet avantageusement une rapide mise en correspondance entre les objets, les définitions de propriété et leurs instances. Le mécanisme D possède des classes privées cachées et des classes d'interface publiques. Pour stocker et accéder aux données dans les objets, un programme utilise des fonctions des classes d'interface publiques TsOBJ et TsLNK Les objets d'adressage utilisent des index dans un arbre d'un ensemble de pointeurs pour une classe d'objet ou de lien, une instance d'objet, un type de propriété et une liste de lignes de la valeur, la classe d'objet ou de lien et le type de propriété peuvent être donnés comme des noms de texte que les interfaces font correspondre aux valeurs d'index. Outre les ensembles de pointeurs pour un accès direct à une vue hiérarchisée des données, le mécanisme D possède des ensembles d'index classés par valeurs de propriétés- clés d'objets correspondants qui fournissent un accès rapide (recherche dichotomique) aux objets sélectionnés et permettent des affichages d'objets classés par champs-clés. Le "constructeur" du mécanisme D va appeler la fonction readMetaModel pour lire le fichier de définitions de propriétés et d'objets. Cette routine va créer une définition de classe d'objet pour chaque type d'objet, en insérant l'adresse de définition de classe d'objet dans l'ensemble de classes d'objets ordonné par nom de classe. Le mécanisme D supporte l'héritage. En outre, il insère chaque propriété dans un ensemble de propriétés ordonné par nom de propriété. Une fois que les objets et les propriétés sont définis, l'index de classe d'objet et chaque index de propriété de classe d'objet sont figés, prêts à être utilisés à la construction d'un modèle. Un outil construit et manipule un modèle (outil ou modèle d'information neutre NIM) dans ce mécanisme D. Lorsqu'il est appelé pour fixer une valeur de propriété, le mécanisme D exécute les étapes suivantes qui sont optimisées lorsque les noms sont déjà mis en correspondance avec les valeurs d'index et que les objets créés à la demande existent déjà: recherche du nom de type objet dans le tableau des classes d'objets pour lire l'index cllNdx, - à la position clNdx dans le tableau d'objets de modèle, trouver ou créer l'élément pour le tableau d'instances d'objets et affecter un nouvel index objNdx, - créer un nouvel objet et stocker son adresse dans le tableau d'instances d'objets, - chercher le nom de propriété dans le tableau de définitions de propriétés pour trouver l'index propNdx, - à la position propNdx dans le tableau d'instances de propriétés d'objets, trouver l'adresse de valeur de propriété ou en créer une nouvelle et y stocker cette adresse, - chercher le numéro de ligne dans la liste de valeurs de propriétés, si trouvé stocker la valeur dans l'objet valeur de propriété, sinon créer une nouvelle valeur de propriété et l'insérer dans la liste, - indexer le tableau d'instances de propriétés pour trouver o stocker le pointeur valeur de propriété, - en stockant une valeur primaire ou secondaire de propriété-clé, insérer ou mettre à jour l'index objNdx dans la table d'index correspondante ordonnée par la valeur clé. Le tableau d'instances de propriétés est une concaténation des pointeurs de propriété de classe courant et antérieurs. Les classes TsDynamo, TsOBJ, et TsLNK définissent l'interface utilisateur pour l'accès au mécanisme D. La classe TsOBJ permet d'indexer la classe, l'objet, la propriété et la ligne en fournissant un mécanisme d'adressage dans les objets du mécanisme D. La classe TsLNK opère l'adressage des liens du mécanisme D. L'interface du mécanisme D offre à l'utilisateur un domaine d'application (modélisation de données) et cache les pointeurs, les structures et l'allocation mémoire C++. Les itérateurs TsOBJ bouclent sur toutes les classes d'objets ou toutes les occurences d'une classe d'objets ou toutes les propriétés. Un programme peut parcourir un modèle ou sélectionner une partie ou un sous- arbre d'objets et de propriétés. Les itérateurs TsLNK (dérivée des itérateurs TsOBJ) bouclent sur les liens. Un programme peut explorer un modèle en traversant des liens entre objets. Un lien peut avoir des propriétés parce qu'il hérite de cette possibilité de la classe TsOBJ. La classe TsDynamo présente des objets (objet C++ appelé objet dynamo dans la suite) qui désignent un métamodèle et un modèle en train d'être manipulés. Un objet TsOBJ désigne un objet dynamo et contient les index d'une position dans le modèle. La position d'un objet TsOBJ peut être fixée par des noms de classes et de propriétés dans des chaînes de caractères et/ou par des valeurs d'index. Ceci permet d'allier la polyvalence des noms à l'exécution à l'efficacité d'utilisation de sous-scripts. Les valeurs d'index égales à 1 correspondent à des valeurs implicites. #include TsDynamo PAC("pac", "Test Model"); Il construire PACLAN/X (outil) TsDynamo NIM("nim", "Neutral Model"); Il construire NIM TsOBJ PAC_ORB(PAC, "ORB"); while (PACORB.nextObjo) Il itération sur tout l'ORB {r if (PAC_ORB('"TYPE")!= "O") continue; Il sélection OBJs, sauter RELs TsOBJ NIM_BEN(NIM, "BEN"); NIM_BEN.setObj(; Il créer nouveau BEN NIMBEN('TITLE") = PAC_ORB("NAME"); Il copier propriétés NIMBEN("ALIAS") = PAC_ORB("CODE"); NIMBEN("NOTES", 1) = "%PX8_CODE " + PACORB("CODE"); Il concaténation propriétés NIMBEN("NOTES", 2) = "%PX8_NAME " + PACORB("NAME"); Il seconde ligne de NOTES NIMBEN("NOTES") += PAC_ORB("DOC"); Il annexer à l'ensemble ou bloc NIMBEN("TITLE") += "-suffix"; Il concaténer à la valeur NIMBEN("PROP") = Str(PACORB("PROPERTY"),5,6); Il déplacement sous- chaîne 5, longueur 6 } Attention: TsOBJ = TsOBJ; signifie copier la valeur de propriété et non l'objet TsOBJ! TsOBJ nim_obj(nim); Il copier clones constructeur TsOBJ nim nim_obj.copy(nim); Il copier TsOBJ nim dans TsOBJ nimobj nim_obj = nim; Il copier valeur property de nim vers nimobj Fichiers "Include" référencés #include "tsarray.h" #include "tsstr.h" #include "t'srec.h" Manipulateurs I/O #define setleft setiosflags(ios::left) #define resetleft resetiosflags(ios::left) Exécution pas à pas macros extern int Tracing; #define TRACE(arg) if (Tracing) cout #define COPL(c) "TsOBJ(" " c->classNdx objNdx >propNdx lineNbr unes ou toutes les valeurs Ndx. classe TsOBJ Il Numéros d'index pour adresser une valeur dans le mécanisme D { TsDynamo* dyn; Il pointeur pour situer données dans dynamo int classNdx; int objNdx; int propNdx; lineNbr; int iterNdx; I//index ensemble clé pour itérateurs, commencer à -1 int error; / 10: ok, >0: adresse défaillante, saut Constructeur TsOBJ avec valeurs numériques TsOBJ(TsDynamo& aDyn, int aClassNdx=1, int aObjNdx=1, int aPropNdx=1, int aLineNbr=1); Constructeur TsOBJ avec noms de classes et de propriétés TsOBJ(TsDynamo &aDyn, const char* aClass, int aObjNdx=1, const char* aProp=1, int aLine=1); Constructeur de copie TsOBJ TsOBJ(TsOBJ& c); TsOBJ Destructeur -TsOBJ() { Fonctions pour adresser les objets dynamo via TsOBJ TsStr& getV(); TsPropValue* getPropValue(; TsObjectlnst* getObject(); TsObjKeyArray* getPrimeKeyArray(; TsObjKeyArray* getSecndKeyArray(; TsObjlnstArray* getObjlnstArray(; TsModelObjArray* getModelObjArray(; TsPropDefnArray* getPropDefnArray(; TsPropDefn* getPropDefn(; TsObjClassDefn* getObjClassDefn(; TsObjClassArray* getObjClassArray(; char* getClassName(; char* getPropName(; Fonctions pour fixer et lire les valeurs d'objets et de propriétés dans un modèle int setObj(const char* aClass, int aObjNdx=1); int setProp(const char* aProp); int setValue(const char* aProp, int aLineNbr, const char* aValue); int setValue(int aLineNbr, const char* aValue); int setValue(const char* aValue) {retumrn setValue(1, aValue);} int setValue(TsStrList* aValue); TsStr getValue(const char* aObj, int aObjNdx, const char* aProp, int aLineNbr=1); TsStr getValue(const char* aProp, int aLineNbr=1); TsStrList getList(const char* aProp); TsPropType getPropType(; int findObj(const char* aObj, const char* aProp, const char* aValue); Fonctions d'opérateur pour améliorer la syntaxe des passerelles TsOBJ& operator() (const char* aObj, int aObjNdx, const char* aProp, int aPropNbr); TsOBJ& operator() (const char* aObj, int aObjNdx, const char* aProp); TsOBJ& operator() (const char* aObj, char* aProp); TsOBJ& operator() (const char* aProp, int aLineNbr); TsOBJ& operator() (const char* aProp); TsOBJ& operator() (; Il op() n'autorise pas de défaut TsOBJ& copy(TsOBJ& b); Il copier TsOBJ TsOBJ& operator= (TsOBJ& in); Il copier la valeur de propriété TsOBJ& operator= (const char* in); Il copier la valeur de chaîne TsOBJ& operator+= (TsOBJ& in); Il annexer la valeur de propriété TsOBJ& operator+= (char* in); Il annexer la valeur de chaîne int operator!O {retumrn error;} Il signaler si demrnière réf ou affectation défaillante operator TsStr&() {return getV();} //conversion de op active tous Str ops Fonctions itérateur pour parcourir les classes, objets, propriétés, lignes. Retour à 0 quand la dernière occurrence est dépassée, pour arrêter l'itération. Pointeurs "null" intégrant un saut dans les ensembles. int firstClass(); int firstObject(); int firstProperty(); int firstLine(); int nextClass(); int nextObject(); int nextProperty(); int nextLine(); }; Cardinalité enum Cardn {C0_1, C1_1, CO_M, C1_M}; extern char* Cardn_str[]; Il ensemble chaîne pour convertir Cardn en texte Paire index de classe et index d'objet pair pour trier une valeur de propriété clé struct Clob { int classNdx; int objNdx; }; Dans le mécanisme D, les classes "Metamodel" représentent le modèle d'information neutre NIM ou le métamodèle de l'outil concerné comme une structure constante pour interpréter les données dans le modèle à manipuler. Définitions de classes d'ensemble de définition de propriété Ensemble de chaînes pour convertir "enum" en texte const char* TsPropTypeStr[] = {"??", 'V/alue", "Array", "Block"}; classe TsPropDefn I contenu dans PropDefnArray { friend class TsPropDefnArray; friend class TsObjectlnst; friend class TsOBJ; TsStr propName; TsPropType type; int length; TsPropDefn(const char* aPropName, TsPropType aType, int aLength); -TsPropDefn() {} }; Ensemble définition de propriété TsArray(TsPropDefn*, TsPropDefnPtArray); Il spécialise le gabarit classe TsPropDefnArray { friend class TsObjClassDefn; friend class TsObjClassArray; friend class TsObjectlnst; friend class TsDynamo; friend class TsOBJ; TsPropDefnPtArray Prop; TsPropDefnArray(: Prop(MaxProps) {} -TsPropDefnArray(; Il supprime chaque objet désigné par le tableau void display(TsOBJ* at); TsPropDefn* define(const char* aName, TsPropType aType, int aLength); TsPropDefn* insert(const char* aName, TsPropType aType, int aLength); int getlndex(const char* aName); TsPropDefn* find(const char* aName); }; Trouver le nom de propriété et renvoyer son index de tableau (ou 0) int TsPropDefnArray::getlndex(const char* name); Trouver le nom de propriété et renvoyer l'adresse de PropDefn (ou NULL) TsPropDefn* TsPropDefnArray::find(const char* name); Insérer TsPropDefn dans TsPropDefnArray trié par nom de propriété TsPropDefn* TsPropDefnArray::insert(const char* aName, TsPropType aType, int aLength); Définir un nouveau TsPropDef, vérifier si le nom de propriété est un doublon TsPropDefn* TsPropDefnArray::define(const char* Name, TsPropType Type, int Length) Définition de classe d'objet, information d'objet de métamodèle class TsObjClassDefn { friend class TsObjClassArray; friend class TsObjlnstArray; friend class TsObjectlnst; friend class TsDynamo; friend class TsOBJ; TsStr className; l nom classe d'objet TsStr parentName; l nom d'objet ayant une parenté TsObjClassDefn* parent; YI propriétés héritées TsPropDefnArray* pda; Il recherche dichotomique pour nom de propriété TsStr primeKeyName; int primeKeyPrNdx; TsStr secndKeyName; int secndKeyPrNdx; TsObjClassDefn(const char* Name, const char* ParentName=O, const char* Prime=O, const char* Second=O); -TsObjClassDefn() void TsObjClassDefn::display(TsOBJ* at); Traduire les index de propriété-clé lorsque le métamodéle est figé void TsObjClassDefn::resolveKeys() }; Définition du tableau de classes d'objets Tableau de classes d'objets, sommet du métamodéle TsArray(TsObjClassDefn*, TsObjClassDefnPtArray); Il spécialise le gabarit classe TsObjClassArray { friend class TsOBJ; TsObjClassDefnPtArray Class; TsStr metaModelName; int usageCount; Il protège le métamodèle commun int isFrozen; Il 0=find insère nouvel obj/prop defns TsObjClassArray(const char* name): Class(MaxClass); -TsObjClassArray(); void release() {if (-usageCount == 0) delete this;} void display(TsOBJ* at); void writeNDF(TsOBJ* at, ostream& ndf); void resolveKeys(); TsObjClassDefn* define(const char* name); TsObjClassDefn* defineKey(const char* obj, char* key, const char* prop); TsObjClassDefn* insert(const char* name); TsObjClassDefn* find(const char* name); int getlndex(const char* name); }; Traduire le nom de classe ayant une parenté et les index de propriété-clé void TsObjClassArray::resolveKeys(); Trouver l'index du tableau pour le nom de classe d'objet int TsObjClassArray::getlndex(const char* name) Trouver l'adresse de définition de classe d'objet par son nom de classe d'objet TsObjClassDefn* TsObjClassArray::find(const char* name) Insérer définition de classe d'objet dans le tableau de classes d'objets trié par le nom de classe TsObjClassDefn* TsObjClassArray::insert(const char* name) Définir une nouvelle définition de classe d'objet dans le tableau de classes d'objets, vérifier si doublon TsObjClassDefn* TsObjClassArray::define(const char* name) Définir un premier ou un second nom de propriété-clé TsObjClassDefn* TsObjClassArray::defineKey(const char* obj, char* key, const char* prop) Dans le mécanisme D, les classes de données de modèle représentent le modèle de l'utilisateur dans la structure définie par le modèle d'information neutre NIM correspondant ou par le métamodèle de l'outil concerné. Définition de classe de valeur de propriété classe TsPropValue / chaîne de valeur de propriété unique { friend class TsObjectlnst; friend class TsOBJ; TsPropValue* next; /les propriétés à multivaleur sont enchaînées int lineNbr; // fichier de tri pour insertion TsStr v; // I'affectation de chaîne supporte le redimensionnement TsPropValue(int line_Nbr, const char* val) -TsPropValue() {} void display(TsOBJ* at); void dump(TsOBJ* at); void writeNDF(TsOBJ* at, ostream& ndf); void set(int line_Nbr, const char* val); TsStr get(int line_Nbr); operator const char*() const {return (const char*)v;} }; void TsPropValue::display(TsOBJ* at) void TsPropValue::dump(TsOBJ* at) void TsPropValue::writeNDF(TsOBJ* at, ostream& ndf) Fixer un numéro de ligne et une valeur pour une valeur de propriété void TsPropValue::set(int line_Nbr, const char* val) Fixer une valeur de propriété multiligne void TsPropValue::set(const TsStrList* val) Lire une valeur de propriété par son numéro de ligne TsStr TsPropValue::get(int lineNbr) Lire une valeur de propriété multiligne TsStrList TsPropValue::get() Définition de classe d'instance d'objet L'instance d'objet contient un tableau d'instances de propriétés, elle désigne les valeurs de propriété TsArray(TsPropValue*, TsPropValuePtArray); Il spécialise le gabarit class TsObjectinst / index parallèle à PropDefnArray { friend class TsObjlnstArray; friend class TsOBJ; TsPropValuePtArray Prop; TsObjectlnst(: Prop(MaxProps) {} -TsObjectlnst() void display(TsOBJ* at); void dump(TsOBJ* at); void writeNDF(TsOBJ* at, ostream& ndf); TsPropValue* setValue(TsOBJ* at, const char* val); }; Définition de classe d'ensemble clé d'objets Ensemble clé d'objet, index d'objet utilisant une propriété clé TsArray(int, TsObjNdxArray); Il spécialise le gabarit class TsObjKeyArray Il objNdxs trié par valeur de propriété clé { friend class TsObjlnstArray; friend class TsOBJ; TsObjNdxArray objNdx; Il délivrer dans l'ordre ou recherche dichotomique TsObjKeyArray(: objNdx(MaxKeys) {} -TsObjKeyArray() {} void display(TsOBJ* at); void insert(TsOBJ* at); int find(char* val); Définition de la classe de tableaux d'instances d'objets TsArray(TsObjectlnst*, TsObjectPtArray); Il spécialise le gabarit class TsObjlnstArray Il instances d'objet indexées par objNdx { friend class TsModelObjArray; friend class TsOBJ; TsObjKeyArray* primeKeyArray; TsObjKeyArray* secndKeyArray; TsObjectPtArray Obj; TsObjlnstArray(: Obj(MaxKeys) -TsObjlnstArray() Positionner un index d'objet, le créer si nécessaire TsObjectlnst* setObject(int objNdx) void display(TsOBJ* at); void dump(TsOBJ* at); void writeNDF(TsOBJ* at, ostream& ndf); void updateKey(TsOBJ* at); }; Mettre à jour un ensemble clé d'objets par insertion en conformité avec la valeur de propriété clé void TsObjlnstArray::updateKey(TsOBJ* at) Fixer la propriété courante à la valeur donnée TsPropValue* TsObjectlnst::setValue(TsOBJ* at, const char* val) Définition de classe de tableaux d'objets de modèle Ensemble d'objets de modèle, sommet de modèle, désignation d'instances d'objet TsArray(TsObjlnstArray*, TsObjlnstPtArray); Il spécialise le gabarit class TsModelObjArray Il classes d'objets indexées par clndx { friend class TsOBJ; TsStr modelName; TsObjlnstPtArray Class; public: TsModelObjArray(const char* Name): Class(MaxClass) -TsModelObjArray() void display(TsOBJ* at); void dump(TsOBJ* at); void writeNDF(TsOBJ* at, ostream& ndf); Positionner le tableau courant d'instances d'objets avec l'index de classe TsObjlnstArray* setClass(int classNdx) }; Une définition de classe de liens dans le mécanisme D est une sous-classe d'une définition de classe d'objets. Un lien de modèles est une instance d'un lien. Une définition de classe de liens décrit les classes d'objets que les liens peuvent rattacher. Une instance de lien spécifie les instances d'objets de modèle qui y sont rattachées. Les objets de lien dérivent d'objets réguliers parce que les liens ont les caractéristiques des objets (ils ont les noms et peuvent avoir les propriétés), mais ils ont également des vecteurs '"to" et 'Y"from" et une cardinalité. Les éléments de données additionnels aux liens, dans un but d'optimisation des performances, sont codés en langage C++ plutôt que d'être mis en oeuvre comme des propriétés d'objets. Les ensembles d'index triés permettent également d'optimiser la recherche. Le constructeur du mécanisme D lit les définitions de liens avec les autres définitions d'objets à partir d'un métamodèle d'outil ou du fichier de métamodèles du modèle d'information neutre NIM. s Un lien contient les index d'objets clNdx et objNdx provenant et à destination desdits objets pour permettre de trouver les objets de modèle qui sont connectés par le lien. Une définition de lien spécifie les objets qu'elle peut regrouper mais une classe réelle peut être dérivée d'une classe d'objets spécifiée, ainsi les liens contiennent les index clNdx et objNdx. Les liens peuvent posséder des propriétés au même titre que les objets. Le fait de créer un lien entre deux objets implique aussi son entrée dans les tableaux d'index. Un ensemble de clés de liens est trié pour trouver tous les objets ou des objets spécifiques qu'un type de lien regroupe déjà. Un ensemble de liens d'objets est trié pour trouver tous les liens ou des liens spécifiques provenant ou à destination d'un objet donné. La définition de classe de liens peut contenirun index propNdx d'une propriété dont la valeur détermine l'ordre d'itération au travers des liens d'un objet. Ceci permet d'inspecter les attributs d'une entité et les sous-champs d'un attribut dans un ordre spécifique. Le séquencement par défaut d'ensembles d'index de liens utilise la clé d'objet cible, ce qui facilite les recherches dichotomiques et la mise en ordre des listings. La structure de passerelle qui permet de mettre en correspondance un modèle d'un métamodèle avec un autre met en oeuvre en fait une hiérarchie de boucles qui utilisent des itérateurs pour inspecter chaque objet primaire d'un modèle et ensuite parcourent ses liens ou utilisent des clés étrangères pour trouver des objets associés. Les autres traitements qui modifient un modèle NIM, soit déjà implanté soit copié, utilisent ce même type de traitement général pour le contrôle d'intégrité et d'autres opérations de service. #include "t'lsdynamo.h" //Ensemble de chaînes pour mettre en correspondance les valeurs "Cardn enum" avec le texte char* Cardn_str[] = {"0:1 ", "1:1", "0:m", "1:m"}; Définition de classe de lien classe TsLinkClassDefn: TsObjClassDefn { friend class TsLNK friend class TsLinkClassArray; TsStr fromVerb; TsStr toVerb; int fromCINdx; int toCINdx; Cardn fromCardn; Cardn toCardn; int toKeyPropNdx; Il mise en ordre d'un ensemble de liens d'objet TsStr toSetMbr; TsStr fromSetMbr; TsLinkClassDefn( const char* aClassName, const char* aFromVerb, const char* aToVerb, const char* aFromCIName, const char* aToCIName, const char* aFromCardn, const char* aToCardn, const char* aToKeyPropName, const char* aToSetMbr, const char* aFromSetMbr); void display(TsLNK* at); }; void TsLinkClassDefn::display(TsLNK* at); Lien au niveau du modèle classe TsLinklnst: TsObjectlnst int fromCNdx; int fromObjCNdx; int fromObjCNdx; int toObCINdx; int toObjNdx; TsLinklnst(TsOBJ& aFrom, TsOBJ& aTo); -TsLinklnst( {} void display(TsLNK* at); void putNDF(ostream& ndf, TsLNK* at); TsPropValue* setProp(TsLNK* at, const char* val); }; void TsLinklnst::display(TsLNK* at); Ensemble clé de liens, index de liens triés utilisant une propriété clé TsArray(TsClob, TsClobArray); // spécialise le gabarit classe TsLinkKeyArray Il InkNdxs triés par la valeur de propriété clé d'objet cible { friend class TsLinklnstArray; friend class TsLNK; TsClobArray linkNdx; Il délivrer dans l'ordre ou recherche dichotomique TsLinkKeyArray(: linkNdx(MaxKeys) {} -TsLinkKeyArray() void display(TsLNK* at); void insert(TsLNK* at); int find(char* val); }; Mise à jour d'un ensemble de clés de liens, insertion conforme à la valeur de propriété clé void TsLinklnstArray::updateToKey(TsOBJ* at); Mise à jour à partir d'un ensemble clé de liens, insertion conforme à la valeur de propriété clé void TsLinklnstArray::updateFromKey(TsOBJ* at); Classe TsLNK, classe d'interface La classe TsLNK est dérivée de la classe TsOBJ. Les possibilités supplémentaires de la classe TsLNK concement l'exploration ou la navigation entre objets dans un modèle par l'intermédiaire des liens dans le métamodèle. Choisir le lien courant int TsLNK::setLink(const char* aClass, int aLnkNdx); Il Fixer le lien spécifique aux index donnés Il Faire croître l'arbre de liens si nécessaire int TsLNK::setLink(TsOBJ& from, TsOBJ& to); Remise à l'état initial du lien courant int TsLNK::resetLink(TsOBJ& from, TsOBJ& to); Lire la cible du lien spécifique TsClop TsLNK:getTargetO; Lire l'origine (source) du lien spécifique TsClop TsLNK:getSource(); Trouver l'index de lien pour le type de lien requis et la valeur clé int TsLNK::findLink(const char* aLnk, const char* aProp, const char* aVal); Insérer l'index d'objet courant dans son ensemble d'index de vecteurs void TsVtrKeyArray::insert(TsOBJ* at) Il est à présent proposé des définitions de classes relatives au codage et décodage des enregistrements dans différents formats de fichiers d'export d'outils. Descripteurs d'enregistrement pour des champs de longueur variable Les langages C et C++ ne permettent pas de supporter complètement les enregistrements. Ils proposent des ensembles de caractères et des structures avec des éléments de données tels que des ensembles de caractères et des sous-structures. Après qu'une structure a été déclarée, le programmeur doit coder l'information de longueur de nouveau dans le code procédural pour pouvoir accéder à ses contenus. Des champs de longueur variable qui utilisent des délimiteurs sont, de manière typique, traités par codage de la syntaxe des enregistrements dans le code qui effectue l'analyse syntaxique desdits enregistrements. La solution avantageuse présentée et définie dans le présent cas est de mettre en oeuvre des déclarations d'enregistrements comme une collection de descripteurs de champs. En premier lieu, le programmeur définit des champs de taille fixe et variable et affecte des codes de valeur constante aux types d'enregistrements, ainsi que des valeurs de délimiteurs. Ensuite dans le code procédural, le programmeur appelle des fonctions pour mettre en correspondance un enregistrement avec son descripteur, puis accède aux champs dans l'enregistrement. Pour sortir les informations, le programmeur appelle des fonctions qui permettent de supprimer l'enregistrement, de remplir ses champs et ensuite de fournir l'enregistrement complet pour sa sortie. La description d'enregistrement contient le nom, le type et la taille de l'information au moment de l'exécution. L'information descriptive et les données peuvent être affichées pour la mise au point. Avec la classe TsRec, le fichier tsrec.h définit des macros pour la construction des descripteurs d'enregistrement et des prototypes de fonctions pour la mise en correspondance d'un registre avec une description d'enregistrement en fournissant des données provenant d'un champ de l'enregistrement, en fixant des données dans un champ d'enregistrement et en fournissant un enregistrement complet pour permettre de le sortir. La classe TsRec peut ainsi traiter un grand nombre de fichiers du mécanisme D et de fichiers d'export d'outil écrits et lus par les composants de la passerelle. Définir les types de champs enum TsFieldType {REC, BFR, LIT, FLD, VAR, END}; Une description d'enregistrement est un tableau de structures TsFieldDescr. struct TsFieldDescr TsFieldType type; char* name; int length; }; Macros pour aider les programmeurs à définir des descriptions d'enregistrement #define MaxRec(len) const int RecBufSize = len; #define XRec(name) extemrn char RECBUF##name[; \ extern TsFieldDescr name[]; #define Rec(name) char RECBUF##name[RecBufSize+1]; \ TsFieldDescr name[] = {{REC, #name, 0}, \ {BFR, RECBUF##name, RecBufSize}, #define Lit(string) {LIT, string} #define Fld(name, len) {FLD, #name, len} #define Var(name) {VAR, #name} #define End {END}} Macros pour accéder aux valeurs de champs #define GetFld(rec,fld) getfld(rec, #fld) #define SetFld(rec,fld,val) setfld(rec, #fld, val) Prototypes de fonctions Convertir un entier en ASCII avec des options de base, de taille et de remplissage char* itoa(int value, int base=10, int size=O, char fill=' '); Convertion inverse d'ASCII en entier int atoi(const char* p); Fonctions d'enregistrement dynamique Mise en correspondance d'un registre avec un enregistrement int match(char* buffer, TsFieldDescr* f); Lire un champ d'un enregistrement TsStr getfld(const TsFieldDescr* rec, const char* name); Lire un champ avec une valeur char* void setfld(TsFieldDescr* rec, const char* name, const char* value); Lire un champ avec une valeur de la classe TsStr (définie ci-après) inline void setfld(TsFieldDescr* rec, const char* name, const TsStr& value); Lire un champ avec une valeur entière convertie en char* inline void setfid(TsFieldDescr* rec, const char* name, const int value) { setfld(rec, name, itoa(value)); } Supprimer un enregistrement void clear(TsFieldDescr* rec); Afficher un enregistrement void display(const TsFieldDescr* rec); Convertir le type "enum TsFieldType" en symbole char* char* aTsFieldType(const TsFieldType t); Lire le pointeur de nom d'enregistrement inline char* GetRec(const TsFieldDescr* rec) {retum(rec+1)->name;} Déclarer IOTAF pour être extérieur XRec(IO_TAF); Il est aussi proposé des définitions de classes relativement à la manipulation de chaînes de caractères. Définition de la classe de chaînes de caractères TsStr Le fichier en- tête tsstr.h contient les définitions de la classe TsStr qui fournit un type de données de chaînes de caractères particulièrement avantageux car il se comporte comme beaucoup de types de données intégrés en langage C. De grande importance est également le fait d'interdire toute perte d'information généralement associée à des pertes de blocs de mémoire. Le but de la classe TsStr est de définir une classe de chaînes de caractères C++ qui permet de supporter les affectations, les concaténations et les opérateurs de comparaison avec les fonctions de sous-chaîne et de réaffectation dynamique de mémoire tout en conservant la compatibilité avec les chaînes de caractères char* d'un langage de type C. Nouvelles macros de caractères de ligne #define NL "n" #define NL2 '"n\n" Affichage variable avec nom #define SEE(x) " "#x ": " (const TsStr &b) const {return strcmp(pt, b.pt) > 0;} int operator ≥ (const TsStr &b) const {retumrn strcmp(pt, b.pt) ≥ O;} int operator (const char* b) const {retumrn strcmp(pt, b) > 0;} int operator ≥ (const char* b) const {retumrn strcmp(pt, b) ≥ 0;} int operator (const char* a, const TsStr &b){retum strcmp(a,b.pt)> 0;} friend int operator> =(const char* a, const TsStr &b){retum strcmp(a,b.pt)≥0;} friend int operator > (istream& s, TsStr& a); Lire pointeur de chaîne de caractères char* de la classe TsStr friend char* getPt(const TsStr& s) {retumrn s.pt;} Lire longueur de chaine de la classe TsStr friend int strlen(const TsStr& s) {return s.ln;} Lire un caractère de la classe TsStr avec un décalage donné friend char ch(const TsStr& str, int offset) {retumrn str.pt[offset];} }; Il fin de la définition de classe TsStr Suivent les descriptions de classes et de fichiers contenant des classes utilisées dans l'environnement de la présente invention. Définitions de la classe d'entrée/sortie TsFile Le fichier en-tête tsfile.h contient les définitions des classes TsFile, TsFileReader, TsFileWriter, TsDataReader et TsDataWriter. Ces classes permettent d'encapsuler des opérations d'entrée/sortie du fichier. La classe TsFile permet d'encapsuler les appels du système UNIX (marque déposée licenciée exclusivement par l'intermédiaire de X/OPEN Company Ltd) qui exploitent un pointeur de fichier, l'ouverture et la fermeture du fichier étant traitées par les constructeurs et les destructeurs, la tâche du demandeur est considérablement simplifiée. Les autres classes construites avec cette encapsulation offrent la possibilité de lire et d'écrire une ligne à la fois et donc un fichier entier à la fois. classe TsFile { Il FILE * const fp; Il pointeur de fichier TsFile( Il Constructeur const char *path, Il Nom d'accès de fichier const char *mode = ' " Il Mode d'ouverture ); Il -TsFile(; Il Destructeur int flush(); Il Surcharge file d'attente char *gets(char *s); Il Surcharge en lecture(s) int puts(char *s); Il Surcharge en écriture (s) int putc(char c); Il Surcharge en écriture (c) }; Il Fin de classe TsFile I classe TsFileReader Il Lit des lignes d'un fichier { TsFile *f; char *buffer; TsFileReader( Il Constructeur const char *path, int buffer_size ); - TsFileReader(); Il Destructeur char *getnext(); I! Lire données suivantes }; classe TsFileWriter Il Ecrit des lignes dans un fichier TsFile *f; enum {NEW, APPEND}; TsFileWriter(! Constructeur const char *path, int new_or_append ); -TsFileWriter(; I Destructeur int putnext(char *buffer); Il Ecrire données suivantes int putnewline(); l Ecrire un caractère de nouvelle ligne }; classe TsDataReader Singly_linkedlist(TsStr) datalist; TsDataReader(; I1 Constructeur -TsDataReader(); Il Destructeur void loadfile(const char *path); I Charger un fichier dans liste Singly_linkedlist(TsStr)& getlist(); I! Lire dans la liste void print(); Il Imprimer la liste }; classe TsDataWriter { Singly_linkedlist(TsStr) datalist; TsDataWriter(; Il Constructeur -TsDataWriter(; Il Destructeur void setlist(Singly_linkedlist(TsStr)& L);! Organiser liste pour écriture void dumpfile(const char *path); Il Sortir liste de fichier void print(); I/Imprimer la liste }; En ce qui concerne le fichier de données neutre NDF, son format permet de stocker un modèle de manière séquentielle. Le fichier NDF peut représenter des modèles sous la forme d'un modèle d'information neutre NIM ou d'un métamodèle d'outil. Le fichier NDF permet de préserver les classes, les objets, les propriétés et les coordonnées des lignes de la représentation d'un modèle avec les valeurs de propriétés. Les objets du mécanisme D (appelés objets dynamo) possèdent des fonctions d'écriture dans le fichier NDF qui permettent de stocker un modèle. La possibilité d'édition à la demande de fichiers NDF s'avère utile pour la génération de données de test. Le format NDF est commode pour évaluer les résultats lors d'exécutions de test. Les développeurs de passerelles peuvent utiliser des fichiers NDF pour sauvegarder ou évaluer des résultats et poursuivre ou relancer des tests en différents points intermédiaires lors du traitement de passerelles. Registre de fichier d'entrée pour l'analyse syntaxique de texte. classe TsBuffer { char* buf; Il pointeur de registre char* cp; Il position du caractère courant int bufSize; Il capacité de registre int lineNbr; Il numéro de ligne corant dans le fichier d'entrée int indent; Il espaces et/ou tabulations (1 mod 8) comptées comme espaces int rescan; Il 1: saut de lecture, utilise mêmes contenus de registres FILE* fd; Il fichier ouvert par constructeur TsBuffer(const char* aFilePath, int aLen = 256); -TsBuffer() {delete [] buf;} Mise en correspondance du texte et d'une valeur à la position courante du registre, progression pointeur int TsBuffer::match(const char* v) Test pour ligne de commentaire int TsBuffer::isComment() Exploration décrochements, ajustement tabulations int TsBuffer::scanlndent() Lecture ligne de texte, lignes de commentaires ignorées, comptage décrochements, installation de bordures \n int TsBuffer::readBuf() Lecture du mot délimité par "delim" char* TsBuffer::getWord(char delim) Exploration d'une valeur décimale, renvoi d'une valeur dans un entier, progression curseur int TsBuffer::scanDec() Lecture d'un modèle NDF, construction d'un objet dynamo classe TsReadNDF: registre TsBuffer protégé { TsStr metaModelName; TsStr modeiName; TsStr objName; int objNdx; TsStr propName; int lineNbr; char* value; TsDynamo* dyn; TsOBJ* at; int status; TsReadNDF(const char* aFileName); }; Lecture fichier NDF et chargement objet dynamo Le constructeur est l'algorithme entier TsReadNDF::TsReadNDF(const char* aFileName): TsBuffer(aFileName) Syntaxe du fichier NDF Dans la syntaxe du fichier NDF, le décrochement indique un emboîtement. Les lignes de commentaires commencent par '"*. Métamodèle de fichier NDF Le format suivant du fichier NDF permet de spécifier un métamodèle, un modèle et les objets, propriétés et valeurs ainsi que des liens qui constituent un modèle. * NDF rev 1.0 /ligne de commentaires pour identifier le fichier MetaModelName: metaModelName / Nom du métamodèle requis pour lire le modèle Model: modeiName Il Créer un objet dynamo(nom de modèle, nom de métamodèle) Object: Class,ObjNdx II Créer un objet(classe, indexObjNdx)propld: value Il Fixer propriété de valeur unique propsym: Il Fixer valeurs multiples dans ensemble ou bloc propNdx: value... Il Une valeur par ligne Link: InkName,lnkNdx II Créer lien (nom et index du lien) FROM: Class,objNdx Il Fixer point final TO: Class,objNdx II Fixer point final Il Le fichier "metaModelName. mta" fournit les métamodèles du modèle d'information neutre NIM, PX8, etc.. Il La structure n'est donc pas présente dans le fichier "modelName.ndf'. Il Exemple: *NDFrev 1.0 MetaModelName: nim Model: ndfsample Object: BEN,1 TITLE: My Object X NOTES: * 1: %PX8_CODE myobjx 2: %PX8_NAME My Object X Object: BEN,2 TITLE: another obj NOTES: 1: %PX8_CODE nother 2: %PX8_NAME another obj Object: ATT, 1 DATY: DATE NOTES: 1: %PX8_CODE bdate 2: %PX8_NAME birthdate PIC: YY-MM-DD SIZE: 8 TITLE: birthdate Link: BEN1,1 FROM: BEN,2 TO: ATT, 1 Pour conclure, la description précédente du procédé de manipulation de modèles de données selon l'invention, du fait de l'utilisation d'un langage exécuté (par exemple du type C++) pour la construction de passerelles au lieu d'un langage propriétaire interprété, permet de mettre en évidence les effets techniques avantageux dudit procédé prévu pour être appliqué à une nouvelle technologie autorisant l'interopérabilité d'une pluralité d'outils de génie logiciel. Non seulement tout outil peut être aisément représenté suivant le modèle d'information neutre proposé, mais également toute représentation de modèle interne peut être réalisée, ceci permet à un utilisateur de conserver son propre modèle d'information pour la représentation interne de ses données de développement ou d'exploiter tous les standards de l'industrie comme par exemple le format d'échange de données (CDIF) conçu pour les différents outils de génie logiciel (CASE) associés à un référentiel commun. Le caractère de réutilisabilité du code est pleinement mis à profit et permet ainsi de satisfaire aux contraintes relatives aux délais de mise sur le marché de telles passerelles, alors que les temps et coût de développement desdites passerelles sont très significativement réduits puisque les librairies de code sont réutilisables. De même, est offerte une grande simplification de toute procédure d'ajout de nouveaux composants de passerelles pour faire évoluer et finement adapter un processus de transfert d'un modèle aux besoins spécifiques d'un client. Les performances sont très sensiblement améliorées par le fait que le présent procédé peut être considéré comme l'application d'un simple et unique exécutable. Revendications: 1. Procédé de manipulation de modèles de données pour le transfert desdits modèles entre une pluralité d'outils de génie logiciel et pour l'application à un dit modèle, de règles de transformation, la transformation de modèles de données étant réalisée au moyen de passerelles permettant de convertir le format d'un outil dans le format d'un autre outil en passant par un format intermédiaire neutre et unique, caractérisé en ce que l'élaboration des passerelles est, selon une approche dite orientée objet, réalisée à partir d'un langage exécuté, les passerelles étant des exécutables permettant la transformation d'un modèle de données en plusieurs étapes activées successivement, de manière systématique ou conditionnelle, grâce à un langage de commande décrivant une logique d'enchaînement dynamique des étapes, l'enchaînement étant une procédure paramétrée et nommée, chaque étape étant un exécutable dont le code est développé à partir d'un ensemble de classes réutilisables et l'activation d'une procédure nécessitant simplement de fournir le nom et les paramètres de la procédure correspondante. 2. Procédé de manipulation de modèles de données selon la revendication 1, caractérisé en ce que, pour le développement d'une passerelle, il est créé une classe réutilisable permettant de représenter les modèles et méta-modèles stockés en mémoire dans un référentiel ou dans un fichier externe en utilisant une allocation dynamique des objets de modélisation, les objets de cette classe intégrant un ensemble de structures de mémoire et fournissant des fonctions pour manipuler les données d'un modèle chargé en mémoire. 3. Procédé de manipulation de modèles de données selon les revendications 1 et 2, caractérisé en ce que, pour le développement d'une passerelle, il est créé une classe réutilisable permettant de coder et décoder différents formats de fichiers d'export d'outils, cette classe encapsulant les enregistrements d'export d'outil et étant utilisée pour décrire les formats d'enregistrement d'un fichier d'import, alors qu'à l'initialisation, tandis que le métamodèle d'un outil est lu à l'aide de la classe de représentation des modèles et métamodèles stockés en mémoire à partir d'un fichier de texte, le code de la passerelle permet de lire le fichier d'export d'outil, d'accéder aux champs propres aux enregistrements et de créer les objets et leurs propriétés en utilisant les fonctions de la classe de représentation des modèles et métamodèles stockés en mémoire. 4. Procédé de manipulation de modèles de données selon l'une quelconque des revendications 1 à 3, caractérisé en ce que, pour le développement d'une passerelle, il est créé une classe réutilisable de manipulation de chaînes de caractères qui permet de prendre en charge les affectations, les concaténations et les opérateurs de comparaison avec les fonctions de sous-chaîne et de réaffectation dynamique de mémoire tout en conservant la compatibilité avec les chaînes de caractères d'un langage de type C.