Overview

The goal of MoScript is to provide AM3 with a textual domain-specific language for model management, improving its model management task orchestration expressivity. With MoScript, users can automate model management tasks by means of OCL based scripts. For instance, user may write queries (based on model content, structure, relationships, and behavior derived through on-the-fly simulation) to retrieve models from model repositories, manipulate them (e.g., by running transformations on sets of models), and store them back in the repository. MoScript also allows to populate and update the megamodel automatically by doing reverse engineer of simple modeling artifact repositories.

Download and install

The MoScript prototype is available from the Eclipse-MDT MoDisco SVN (sources only). The steps to install MoScript are the following:

Browse the just created repository location until /plugins/trunk and checkout all the plugins

Documentation

You can find from this section the documentary resources around the MoScript prototype and underlying approach.

MoScript Hello World!

Create a new MoScript project by clicking on File-> New-> Project and selecting the MoScript project type under the AM3 Folder.

Then create a MoScript script by clicking in File-> New-> File. Give it the name helloWorld.mscr. When the file is open, fill it with the following script code:

program helloWorld
do{
'HelloWorld'.debug();
}

After saving the file, if there are no errors, you should see a new binary file called helloWorld.asm in the project explorer or navigator.

Now that the code is ready, create a MoScript launcher to run the script, by clicking in Run-> Run Configurations...

Browse in the workspace for the HelloWorld.mscr file and select it. Then, in the advanced tab, check the options Clear console before launch and Print execution times to console, so that you can clearly see when de script finishes.

Then press the Apply button and the Run button. In the console window you will see an error like the following:

Create any model element in the megamodel left clicking in any element in the left panel, selecting new [element]. Give any value to the element and then use File->Save option to save the Megamodel. With this operation the Megamodel file is created in the filesystem.

Now try again to run the script by clicking on Run->Run History->Hello World and you should see the output in the console.

The MoScript Language

MoScript reuses a big part of the ATL syntax and semantics such as the OCL expressions and data types, the control flow statements and the helpers. If you have any doubt about MoScript syntax please try to solve it by using the ATL syntax. Please note that MoScript does not know the notion of Rule in any form.

The using section is optional, and is used for declaring variables and assigning their initial value. The do section is mandatory and is the core of the program. In it, operations are used in combination with control flow statements and OCL queries to perform modelling artefacts manipulations.

Model element data type

The OCL specification introduces de model element data type. This type corresponds to the classes contained in the metamodel of the model is being queried. In the case of MoScript, the model which is being queried, is a megamodel, so the model elements allowed in MoScript correspond to classes of the metamodel of the megamodel. MoScript uses the implementation of the megamodel provided by AM3 which conforms to the following metamodels among others:

AM3Core: Is the top hierachy metamodel and can be found in /org.eclipse.gmt.am3.platform.runtime.core/model/AM3Core.ecore

GMM: Which extends AM3Core and can be found in /org.eclipse.gmt.am3.platform.extension.globalmodelmanagement/model/GlobalModelManagement.ecore

GMM4ATL: A megamodel extension specific for ATL M2M transformations, which extends AM3Core and GMM and can be found in /org.eclipse.gmt.am3.platform.extension.gmm4atl/model/GMM4ATL.ecore

Model element variables are referred to by means of the notation !Class. For instance, !Model, !TerminalModel, !ATLTransformation etc.

Operations

This operation dereferences and load the physical model represented by the Model element. Then it queries the model and return a collection of OCL elements of type elementType. The elements of the resulting collection are used as entry points to the model, from where the rest of the elements may be reached. Subsequent queries to the model content are made with standard OCL expressions.

This operation make a projection of model expressed in a textual syntax to a model in XMI conforming to a given metamodel. injectorName is the name of the injector that is going to be used to make the projection of the model and modelElement represents the metadata information that will describe the new model. The structure of the tuple is explained along with the register operation.

This operation applies the a transformation to one or more models. The key is the alias of that identifies the model inside an ATL transformation module and model is a model obtained from the megamodel.

register(TupleType(concreteType :String, value :Set(TupleType(...))))

This operation does the registration of a model in the megamodel i.e. it creates a new element in the megamodel of type concreteType where:

concreteType: Is a string with the concrete type of the model element to be created. The string must be in the form of Package::ConcreteType. For instance GlobalModelManagement::URI, GlobalModelManagement::ReferenceModel etc.

value: Corresponds to a set of attributes and references of the model element, each of them described again by a tuple as follows:

There are two ways for declaring reference tuples. The first one specifies first creates the element to be referenced and then references it, the second one asumes that the elements has been already created (in the same register operation), thus it uses the creationId of the element to be referenced to find it and reference it. The creationId is just a kind of variable name given to the model element instance when it is created during the execution of the register operation. It is not mandatory if the element is not going to be referenced from another element created in the same register operation execution.

Note that the Tuples are used as a recursive way of expressing the creation of model elements, the model elements referenced by this elements and so on, and also the atributes contained in each model element.

IdentifiedElement :: remove()

This operation allows to remove any megamodel element which extends from the Core::IdentifiedElement element.

ReferenceModel :: registerInEMFpkgReg()

This operation registers the reference model in the EMF packages registry

Examples

Select all the models in the megamodel, get the first one and get a collection of all its elements of type EClass.

!Model.allInstances()->first().allContentInstancesOf('EClass');

Select all the models in the megamodel, get the first one and remove it from the megamodel.

!Model.allInstances()->first().remove();

Select the models in textual syntax which conform to a given xmlRefernceModel (grammar), get the first one and the inject it with the XML injector to obtain an XML model in XMI format conforming to an XML metamodel. The xmlEcoreModelTuple contains the metadata information for the creation of the new model element like, identifier, locator, referenceModel etc.

Screencasts & slides

Related publications

Use Cases

MoScript comes with a set of use cases showing different possible uses of the MoScript tool in various contexts and for varied purposes (similarly to what is done in the M2M ATL project). A general description is given for each of these use cases, as well as some more precise documentations for many of them. For some, prototypes have already been implemented and are directly downloadable from their respective page.

Megamodel Population Part 1

A requisite for start working with MoScript is to count with a populated megamodel i.e, a megamodel with elements, which point to modeling artefacts. This megamodel population can be done through the AM3 graphical user interface, nevertheless registering a high amount of models in the megamodel through the GUI is a repetitive and time consuming task. In those cases is better to use a textual syntax, so we can repeat the process the times we want, make changes easily to it or take it as base for future megamodel populations. In this use case we show how is possible to programmatically populate the Megamodel with MoScript.
Click here for more details and actual resources...

Advanced Megamodel Population

Use cases Megamodel Population Part 1 and Megamodel Population Part 2 showed how it is possible to populate a Megamodel programmatically by specifying the whole information the Megamodel will hold as metadata. Nevertheless when we are faced to huge model repositories is not practical to exhaustively specify the whole information that describes the repository, we need mechanisms to infer which is this information, to automatically populate the Megamodel. In the following use case we show how is possible to query the content of the models in the repository to extract information that will serve to populate the Megamodel. Bringing this information to the metadata level will greatly increase performance when looking for models with specific characteristics, thus it is not necessary to open every model and inspect its content. Click here for more details and actual resources...