Jump to: navigation, search

Difference between revisions of "MoScript"

(Advanced Megamodel Population)
 
(24 intermediate revisions by the same user not shown)
Line 63: Line 63:
 
=== The MoScript Language  ===
 
=== The MoScript Language  ===
  
MoScript reuses a big part of the [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language ATL] syntax like the OCL expressions, 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 have the Rule concept.  
+
MoScript reuses a big part of the [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language ATL] syntax and semantics such as the [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language#OCL_Declarative_Expressions OCL expressions] and [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language#Data_types data types], the [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language#ATL_imperative_code control flow statements] and the [http://wiki.eclipse.org/ATL/User_Guide_-_The_ATL_Language#ATL_Helpers 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.  
  
 
==== General Structure  ====
 
==== General Structure  ====
Line 74: Line 74:
 
   
 
   
 
  ['''using''' {
 
  ['''using''' {
  -- Comments
+
-- Comments
 
   
 
   
  -- Variable declarations  
+
-- Variable declarations  
  variable :type = OclExpr;
+
variable :type = OclExpr
  ...
+
...
 
  }]
 
  }]
 
   
 
   
 
  '''do''' {
 
  '''do''' {
  -- Value assignements
+
-- Value assignements
  variable <− OclExpr;
+
variable <− OclExpr;
 
   
 
   
  -- Operations invocations
+
-- Operations invocations
  save(...);
+
save(...);
 
   
 
   
  -- Operations invocations
+
-- Operations invocations
  ... remove(OclExpr);  
+
... remove(OclExpr);  
 
   
 
   
  -- Operations invocations
+
-- Operations invocations
  ... register (...) ;
+
... register (...) ;
 
   
 
   
  -- Control flow statements
+
-- Control flow statements
 
  '''  if'''...   
 
  '''  if'''...   
 
   
 
   
  -- Control flow statements
+
-- Control flow statements
 
  '''  for''' . .
 
  '''  for''' . .
 
  }
 
  }
 
   
 
   
 
  '''helper context''' OclAny '''def''': helper_name( params ) :return_type
 
  '''helper context''' OclAny '''def''': helper_name( params ) :return_type
  ...  
+
...  
 
  ;
 
  ;
  
Line 108: Line 108:
  
 
==== Model element data type  ====
 
==== 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.
+
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  ====
 
==== Operations  ====
  
 
*<pre>Model&nbsp;:: allContentInstancesOf(elementType&nbsp;:String): Collection(OclAny)</pre>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&nbsp;'''''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.  
 
*<pre>Model&nbsp;:: allContentInstancesOf(elementType&nbsp;:String): Collection(OclAny)</pre>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&nbsp;'''''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.  
*<pre>Model&nbsp;:: inject(injectorName: String, modelElement: TupleType(...))&nbsp;: Model</pre>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 in ...&nbsp;
+
*<pre>Model&nbsp;:: inject(injectorName: String, modelElement: TupleType(...))&nbsp;: Model</pre>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.  
 
*<pre>Model&nbsp;:: save(location&nbsp;:String)</pre>This operation stores the model in '''''location'''''&nbsp;&nbsp; &nbsp;  
 
*<pre>Model&nbsp;:: save(location&nbsp;:String)</pre>This operation stores the model in '''''location'''''&nbsp;&nbsp; &nbsp;  
 
*<pre>ATLTransformation&nbsp;:: applyTo(Map{(key&nbsp;:String, model&nbsp;:Model),...,(..., ...)})&nbsp;:Map(key&nbsp;:String, model&nbsp;:Model)</pre>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.  
 
*<pre>ATLTransformation&nbsp;:: applyTo(Map{(key&nbsp;:String, model&nbsp;:Model),...,(..., ...)})&nbsp;:Map(key&nbsp;:String, model&nbsp;:Model)</pre>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.  
Line 130: Line 132:
 
: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, &nbsp;and also the atributes contained in each model element.
 
: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, &nbsp;and also the atributes contained in each model element.
  
*<pre>IdentifiedElement&nbsp;:: remove()</pre>This operation allows to remove any megamodel element which extends from the Core::IdentifiedElement element.
+
*<pre>IdentifiedElement&nbsp;:: remove()</pre>This operation allows to remove any megamodel element which extends from the Core::IdentifiedElement element.  
 
*<pre>ReferenceModel&nbsp;:: registerInEMFpkgReg()</pre>This operation registers the reference model in the EMF packages registry
 
*<pre>ReferenceModel&nbsp;:: registerInEMFpkgReg()</pre>This operation registers the reference model in the EMF packages registry
  
Line 138: Line 140:
 
*Select all the models in the megamodel, get the first one and remove it from the megamodel.<pre>!Model.allInstances()-&gt;first().remove();
 
*Select all the models in the megamodel, get the first one and remove it from the megamodel.<pre>!Model.allInstances()-&gt;first().remove();
 
</pre>
 
</pre>
*Select the models conforming to a given ''xmlRefernceModel'', get the first one&nbsp;and the inject it with the XML injector to obtain an XML model in XMI.<br><pre>xml &lt;- !TerminalModel.allInstances()-&gt;select(m | m.conformsTo = xmlReferenceModel)-&gt;first();
+
 
xmlModel &lt;- xml.inject('XML', xmlEcoreModelTuple);
+
*Select the models in textual syntax which conform to a given ''xmlRefernceModel'' (grammar), get the first one&nbsp;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.
</pre>
+
xml &lt;-&nbsp;!TerminalModel.allInstances()-&gt;select(m | m.conformsTo = xmlReferenceModel)-&gt;first();
 +
xmlModel &lt;- xml.inject('XML', xmlEcoreModelTuple);
  
 
=== Screencasts &amp; slides  ===
 
=== Screencasts &amp; slides  ===
Line 157: Line 160:
 
[[MoScript/Use_Cases/Megamodel_Population_Part_1| Click here for more details and actual resources...]]
 
[[MoScript/Use_Cases/Megamodel_Population_Part_1| Click here for more details and actual resources...]]
  
=== YYY  ===
+
=== Megamodel Population Part 2 ===
 +
Continuing with the use case Megamodel Population Part 1, this use cases shows how to programmatically populate the megamodel with models, metamodels and transformations. For this purpose we are going to populate it with the content of an ATL project that can be found in the [http://www.eclipse.org/m2m/atl/atlTransformations/#Class2Relational ATL Transformations Zoo][[MoScript/Use_Cases/Megamodel_Population_Part_2| Click here for more details and actual resources...]]
  
To be completed.  
+
=== 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. [[MoScript/Use_Cases/Advanced_Megamodel_Population| Click here for more details and actual resources...]]
  
 
== Support  ==
 
== Support  ==
Line 175: Line 180:
  
 
[[Category:Modeling]] [[Category:MDD]] [[Category:AM3]] [[Category:AMMA]]
 
[[Category:Modeling]] [[Category:MDD]] [[Category:AM3]] [[Category:AMMA]]
 +
 +
== Acknowledgments ==
 +
The present work has been partially supported by the [http://galaxy.lip6.fr/  Galaxy (ANR - French National) project]

Latest revision as of 12:02, 29 March 2012

< To: MDT
< To: MoDisco
< To: AM3

AM3
Download
Community
Mailing ListForum
Bugzilla
Opened bugs
All bugs
Contribute
Browse Source

The MoScript prototype (extending AM3), being developed by the AtlanMod Team, is part of the MoDisco project. It provides a textual domain-specific language for model management.

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:

  1. Download the Eclipse Modeling Tools from here: Eclipse Modeling Tools (Indigo)
  2. Install ATL from sources:
    • Download the ATL source code project set file (.psf) from here [1].
    • Import it into Eclipse with File->Import->Team->Team Project Set.
    • Download the MoScript patch for ATL from Bugzilla – Bug 361688.
    • Click right click on any ATL plugin project and select Team->Apply Patch ... and select the patch to apply it to ATL.
  3. Install sublcipse and subversion if you have not done it yet.
  4. Install AM3 and MoScript from sources:
    • Open the SVN perspective by selecting Window -> Open Perspective-> SVN Repository Exploring perspective.
    • Add a new repository location by selecting File->New->Repository Location. The required parameters are the followings:
    • 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. MoScript-HelloWorld2.png

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... MoScript-HelloWorld3.png

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.

MoScript-HelloWorld4.png

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

Error loading file:...workspacePath/.am3/megamodel.xmi: java.io.FileNotFoundException: ... (No such file or directory)

This is because the megamodel file has not been created yet.

For creating the megamodel file, open the AM3 Perspective. MoScript-HelloWorld1.png

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. MoScript-HelloWorld5.png

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

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.

General Structure

A MoScript program has the following general structure:

program program_name

uses library ... 

[using {
-- Comments

-- Variable declarations 
variable :type = OclExpr
...
}]

do {
-- Value assignements
variable <− OclExpr;

-- Operations invocations
save(...);

-- Operations invocations
... remove(OclExpr); 

-- Operations invocations
... register (...) ;

-- Control flow statements
   if...  

-- Control flow statements
   for . .
}

helper context OclAny def: helper_name( params ) :return_type	
... 
;

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

  • Model :: allContentInstancesOf(elementType :String): Collection(OclAny)
    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.
  • Model :: inject(injectorName: String, modelElement: TupleType(...)) : Model
    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.
  • Model :: save(location :String)
    This operation stores the model in location    
  • ATLTransformation :: applyTo(Map{(key :String, model :Model),...,(..., ...)}) :Map(key :String, model :Model)
    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:
      • Attribute tuple:
        TupleType(attributeName :String, primitiveType :String, attributeValue :String)
      • Reference tuple:
        TupleType(creationId :String, referenceName :String, concreteType :String, referenceValue :Set(TupleType(...)))
        TupleType(referenceName: String, concreteType :String, creationId: String)
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.
xml <- !TerminalModel.allInstances()->select(m | m.conformsTo = xmlReferenceModel)->first();
xmlModel <- xml.inject('XML', xmlEcoreModelTuple);

Screencasts & slides

MoScript: A textual DSL for model manipulations (slides)

Related publications

MoScript: A DSL for querying and manipulating model repositories (paper)

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

Megamodel Population Part 2

Continuing with the use case Megamodel Population Part 1, this use cases shows how to programmatically populate the megamodel with models, metamodels and transformations. For this purpose we are going to populate it with the content of an ATL project that can be found in the ATL Transformations Zoo 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...

Support

Relationships with other Eclipse Projects

MoScript reuses different existing EMP (Eclipse Modeling Project) projects: To be completed.

Acknowledgments

The present work has been partially supported by the Galaxy (ANR - French National) project