ModelJoin/Xtend Join Execution
This page should clarify the new xtend-based implementation for model join transformations. Prior to this project the transformation language used was QVT.
The classes from the project  generate an executable xtend-file which uses the runtime API to perform the transformation on actual instances. Entrypoint is the ModelJoinTransformationGenerator.xtend which impelements the IGenerator2 interface. The compiler input are the parsed grammar objects (generated by the xtext language) from a query file.
The runtime project  contains classes used by the generated xtend class from the compiler. Functions such as joins and query constraints let the actual transformation file be much smaller and better readable.
If you want to use the xtend transformations in a model join project the following dependencies must be there in the manifest:
To allow the project to use the runtime API you need to alter its access restrictions:
- Rightclick your project and select "Properties"
- Select "Java Build Path"
- Go to the tab "Libraries"
- Expand the "Plug-in Dependencies"
- Select "Access rules" and click Edit
- Add the following rule: Resolution: Accessible , Rule Pattern: "edu/kit/ipd/sdq/mdsd/mj/transformation/generator/xtend/runtime/**"
This chapter will explain the worklfow for an user wanting to execute a model join transformation step by step:
- Create/Edit a transformation file (.mj) and save it
- After saving the xtend transformation file should be created in a folder named "transformations" (Right click on the folder, select Build-Path and add it as a source folder, if not allready done)
- Build/Clean the project, then the compiled java classes of the transformations should be created in the "xtend-gen" folder
- Righclick on the *_Transformation.xtend you want to execute and select "Run As" > "MJ Transformation"
- A Dialog will pop up where you have to set the following paremeters, and then press run (After that the new instance should be created or an error displayed)
- Joined Metamodel: Select the joined metamodel file your MJ query created
- Tranformation Target: Select a destination where the joined instance should be created (If no Transformation Target exists, create a new target.xmi file)
- Join Sources: A List of all needed join sources which will be used as inputs for the join (Actual instances of the models imported in your query)
Open Points / Improvements
A list of missing features yet to be implemented or new ideas
Join DSL Improvement
The Xtext DSL for join queries is still set for qvt. Theta-joins and KeepCalculated expressions need to be adapted as xtend-expressions (with xbase). A system is needed to translate calls on attributes from eobjects by the user-logic in the queries, so it can be placed into the Xtend-Generator project as implementations of "CustomTransformationCode". As an example, the generator has to write a lambda for the ThetaJoin which implements the ThetaJoinCondition (which has a method "check(EObject left, EObject right)"). The user-defined condition described in the query as a xtend-expression has to be inserted into the lamba (therefore implements the check method and returns a boolean). The abstract class ThetaJoinCondition extends CustomTransformationCode which has a method "getAttributeValue(Eobject object, String attribute)". This is an example method and can be used by the check-Method implementation. Other Methods needed can be created at will. These methods must be visible to the writer of the Join-query or somehow translated automatically by special keywords or predefined names. As this is not yet decided or tested the DSL remains unchanged and the ThetaJoin and KeepCalculated generators from the xtend-generator project remain unfinished and will produce syntax errors (because they dont create an implementation for the runtime yet, which is described above how it could be done)
Standalone Test Execution
See project . Executing the testcases for ModelJoin will create a standalone environment and run a special workflow to simulate an user creating queries. The small test edu.kit.ipd.sdq.mdsd.mj.workflow.test.TestWorkflow uses the same classes from the worklfow-project like the testcases and is a simple way to manually test creating a targetmodel and xtend-transformation from a simple query. Like the other testcases this will currently result in the exception "de.uka.ipd.sdq.workflow.jobs.JobFailedException: MWE2 workflow component failed" because the URI resolution fails at some point "1084 [main] ERROR xt.linking.lazy.LazyLinkingResource - resolution of uriFragment '|::0.2.0::7::/5' failed.". This changed most likely because of the new xtext version. Someone with more knowledge about MWE-workflows and their resourcemanagement could check the ModelJoinCompositeJob for problems why it wont find the resources anymore.
Auto-Compile for Xtend
After saving a modeljoin-query the xtend-transformation will be created in a special folder. Currently, if the user wants to execute this transformation with the launcher (rightclick > run as > mj transformation) an error will occur that the main class/method cant be found. This happens because the generated xtend class wont be translated automatically in an executable java-class. Therefore the user has to rebuild the project via the eclipse menu, which will trigger the xtend build and create the java classes from the transfrormations. A possible solution and handy improvement for usability is to trigger the xtend-build for this project automatically from the launcher project, so when launching a transformation it will guarantee the java files are created. The "Xtend-build-call" could be implemented and used by the class "edu.kit.ipd.sdq.mdsd.mj.transformation.xtend.launch.TransformationLaunchConfiguration" before trying to launch the java-class.
General Code Improvements
Taken from the Codereview: (done improvements removed)
- Generische Run-Methode oder spezielleres Interface
- Run-Methode typsicher machen (mit URIs)
- Dominik hat für Reactions einen Import-Helper geschrieben
- evlt. Erweiterungspunkt für neue Join-Typen einführen
- save()-Methode und URIs als Eingabe ist eigentlich eine Convenience, die außenrum gebaut wird
- Man hätte gerne eine Schnittstelle, mit der man Ressourcen reinstecken kann oder sogar EObjects
- anderes drumherum packen als Persistenz-Wrapper
- "compile" in "build" umbenennen, denn man hat ein Builder-Pattern
- Umstellung auf Fluent API für lesbare Ausdrücke
- Mit Args4J (oder so ähnlich) die Argumente benennen
- Magic Strings entfernen
- Property Sheet für die Auswahl des Generators
- Code-Qualität (Kommentare)
- JvmModelInferrer als Alternative