Creating EMF-Models with RSA
This is a short article which's aim is to provide you with a short introduction on how to
- Create EMF/ECORE-models with RSA (IBM Rational Software Architect) for Eclipse 2006 (including the use of a ECORE Profile)
- Export multiple models, that reference each other, into UML2-Files - (For RSA Version <=6.0.1, we provide a little tool to fix the buggy export of RSA)
- Import the UML2-models into EMF
- Evaluate OCL-expressions in models generated by EMF
For the following article "IBM Rational Software Development Platform, Version: 6.0.1, Build id: 20050725_1800" (Rational Software Architect for Eclipse) is used. Note: Currently we use RSA 7.x. The information provided below should still be valid. Dialogs and the UI might have changed slightly and the mentioned problem of the uml export was fixed.
Process
The following process is obeyed. See also Creating EMF-Models with RSA#PCM Change Process below.
- Model metamodel in RSA
- Export model to a UML model
- If you create the model for the first time: Create a new EMF Generator Model (.genmodel). If you reexport the metamodel, reuse your existing genmodel.
- Import the UML model in the EMF genmodel.
- Generate code from the EMF genmodel.
To generate a copyright string in the model code, select the root element of the genmodel, look at the property sheet, set Copyright Fields to true, and enter the copyright string in the Copyright Text. To change the copyright statement in the javadoc at the beginning of each class, you have to delete the classes before regenerating them. If you do not delete, the old string stays there.
Create EMF/ECORE-models with RSA
Set up a new RSA UML Modeling Project
First set up a new UML Project (we will start modeling with a UML model): File > New > Project...
Choose UML Project > Next and set the Project name to something like "My Ecore Modeling Project".
Chose the Blank Model Template, name the file "My Ecore Model", and create a "Class Diagram" in "My Ecore Modeling Project".
Your new project's workspace should now look like below. "My Ecore Modeling Project" is the new project (with "UML Model" nature). "My Ecore Model.emx" is the RSA file where all models and diagrams are stored in. "My Ecore Model" is a model within this file. "Main" is the empty class diagram that was just created by selecting "Class Diagram" in the previous wizard step. "(UML2)" indicates that "My Ecore Model" imports (package import) "UML2". This allows to use / reference all kinds UML2 data types and meta-classes.
The tab "My Ecore Model::Main" shows the empty UML2 class diagram.
Using ECORE data types
For some reasons we want to use ECORE data types. For example UML2 data types do not offer types like double (floatpoint numbers). Right-click on "My Ecore Model" and select "Import Model Library...".
Then choose "Ecore Types"
Now your model imports ECORE data types. For example they can be used for class attributes' data types.
Using the ECORE profile
To use ECORE sterotypes like <<ePackage>> and <<eClass>> in your project, you have to use the ECORE profile. To do so, select the base package of your modelling file.
Then select the "Profiles" tab in the packages' property sheet. Here you see a list of all profiles already used in your project.
Click the "Add Profile" button on the lower left. This opens a new window.
As ECORE is none of the default profiles, you have to select the project file yourself. You can find in the RSA installation directory under, e.g.:
/opt/IBM/Rational/SDP/6.0/radrsm_shared/eclipse/plugins/org.eclipse.uml2.resources_1.0.1/profiles/Ecore.profile.uml2
After closing the dialog, the ECORE profile appears in the profile list.
Now you can switch to the "Stereotypes" tab and click "Add Sterotype" there.
The new window offers you a list of possible stereotypes for the selected package. One of them is the desired <<ePackage>>.
After adding the <<ePackage>> stereotype, you can specify typical ECORE attributes for packages, like name space prefixes etc.
Note: Even though the namespaces are specified in the ECORE/UML model, you will have to set the "All->Base Package" property in the generator model (.genmodel) as well.
Modeling
To start modeling the tab "My Ecore Model::Main" is the right choice. New classes can be creating by drag and drop or by holding the mouse cursor over the drawing area. In the latter case a menu as shown below appears. New classes can be created by chosing the "C" class icon.
In the example below there are three classes "ClientServerSzenario", "Server", and "Client". What we want to model is a meta-model for client server configuration szenarios. The goal is to create a model for valid models. The model we create is a meta-model, which means, that we describe some kind of rules for possible model instances of our meta-model. To give an example: A meta-model instance ("model") might contain 3 servers and 4 clients or something alike.
Don't mind, that we in fact start with a UML model instance, which does not really look like a meta-model. We will point out later how our model gets a meta-model.
Creation actions for the later ECORE (EMF) meta-model are in general only possible for "Composition Associations". In our example "ClientServerSzenario" should be able to have multiple servers and clients. Servers and clients are both associated with the "ClientServerSzenario". Therefore "ClientServerSzenario" composes "Server" and "Client".
The picture below shows the correct kind of association which in terms of ECORE is translated to creation functionality.
TODO: Association...
Incorporating Java classes and Generics into RSA-UML models
In the following, it is explained how you can refer to types and generic types defined in Java in the RSA-UML model. This allows you to refer to existing library implementations of Java classes in your meta-models.
Creating Types based on existing Java classes
- Create a Primitive Data Type in your UML model for each type you want to refer to:
- Apply the eDataType stereotype to each Primitive Data Type
- Go to Properties -> Advanced and set the instanceClassName field to the fully qualified name of the Java class you are referring to, set the field dataTypeName to the name of the type. If you are adding a generic class, do not specify the generic type parameters (e.g. <E> ) as part of these fields.
Creating Generic Types and Generic Type Parameterizations
- Right click the Primitive Data Type that represents the generic java class and add a Template Parameter via Add UML -> Template Parameter -> Advanced... and then selecting Primitive Data Type. Then name this parameter.
- For each parameterized type you want to create - for example Amount<Power> as a parameterization of Amount<E> - you add a separate Primitive Data Type to the model. This time around, on top of the eDataType stereotype, apply the eGenericType stereotype.
- Add a template binding from the AmountPower type to Amount.
- Set the Template parameter to the type that is to parameterize your generic class.
- Important: After you have generated and exported your model to EMF as described in the next step, check your generated .ecore models for potentially incomplete or erroneous eAnnotations and delete them.
TODO: determine cause for these erroneous annotations
TODO: complete
Exporting
As a default, use the UML export. The Ecore export has some problems.
Import UML2-models into EMF
TODO: ...
If you use the ECORE UML Profile in RSA, you also need to import the corresponding meta model into EMF within Eclipse. You can find the Ecore.ecore file at platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore.
Update the EMF genmodel
After a ecore model changes / evolves, you need to update the EMF genmodel. Usually, you are not willing to re-define the whole genmodel. EMF provides an option to circumvent this issue: Right click on your genmodel in the Package Explorer (NOT genmodel editor) and select "Reload...". Then simply proceed as with a new Ecore or UML model when creating a new genmodel.
The updated ecore/uml model should reside in your model directory to prevent models having <foreignModel>file://somewhere/tmp/FeatureConfig.uml</foreignModel>.
If the wizard shows several root packages to import and not only the one you are tying to reload (for example it shows pcm.ecore or Ecore.ecore as a second root package), try the following in that order:
- Check the "referenced generator models" section whether the model is available, if yes, tick it. It should disappear from the root packages list
- Make sure the plugin that should contain that model (e.g. de.uka.ipd.sdq.pcm for pcm.ecore) is in your plugin's dependency list. If it is not, try adding it. Then add the genmodel in the wizard to the "referenced generator models" section.
- If the root package has a too simple name, then your RSA model might be incomplete. The name should be the name that you expect the corresponding plugin to have. For example, I have seen root package Ecore, while it should be named org.eclipse.emf.ecore. To fix this, go to RSA and make sure your model has the epackage stereotype applied. Then, under properties -> advanced, select an appropriate base package. In the example case, this was org.eclipse.emf. Also, set the other values right. In my example, this was nsPrefix = ecore, package name = ecore, prefix = ecore and nsURI = http://www.eclipse.org/emf/2002/Ecore. Maybe some values are superfluous. After having set this and re-exporting the models, the ecore model was available as "referenced generator models". Possibly, you have to delete your old model code to get it right.
Troubleshooting in genmodel
eReferenceType error with EType
Error messages:
- The required feature "eReferenceType" of 'platform:/resource/.../mymodel.ecore#//pathTo/node' must be set
- The generic reference type must not refer to a data type
In this case, the error is caused by the referenced ecore model for which the genmodel was created. It is referencing an EObject which was unrolled to the "EType" EJavaObject [java.lang.Object].
- Solution: Check whether all referenced models are present in the models folder and can be accessed by EMF.
- Workaround (if not all references models can be placed in the models folder): Change the "EType" of that reference to EObject [org.eclipse.emf.ecore.EObject].
Duplicate methods
Errors in generated code:
- Duplicate methods in classes
- Variable are named "package" in generated code
- Generated classes are missing prefixes
Solution:
- Check the ECore properties "packageName" and "prefix" for all packages in the meta-model. If these names are not set (default) the above errors occur.
- Setting "packageName" and "prefix" requires to import the ECore Profile and applying "ePackage" to all UML packages.
Inconsistent inheritance hierarchy
Another Error: "the hierarchy of the type XY is inconsistent" for all model classes (or at least all interfaces)
- In my case, the JRE was not on the build path of the plugin that contained the model. Do "Configure Build Path"->Libraries->Add Library->JRE System Library or click on "Update the classpath settings" in the Overview Page of the Manifest Editor.
- In case the error persists, see if all dependencies are resolved: if not, Eclipse won't start a new build and the compiler error cannot be resolved.
Problem with cross-document references
After creating a model with my generated editor, saving and closing it, I was not able to open it again. The error:
java.lang.IllegalArgumentException: The class 'RepositoryComponent' is not a valid classifier
In the serialized model file, the reference to the RepositoryComponent named repositorycomponent was serialised as an XML attribute.
<alternativetasks_Alternative probabilityOfExecution="1.0" failureProbability="0.0020" meanDemandedTime="7.0" repositorycomponent="BasicComponent default.repository#_74WmQKOdEd6Wld2f-l5cjw" allocationcontext="default.allocation#_U78qwKOXEd6D1ZKDqAnLPA" abstractaction="_1:InternalAction default.repository#_-W5sUKOdEd6Wld2f-l5cjw" task_AlternativeTask="#//@task_TaskList.1"/>
The actual type of the referenced RepositoryComponent (i.e. BasicComponent) could not be resolved when loading (weird, but happened). The reason seems to be that the genmodel was set to save the model with the Resource Type XML (see genmodel, properties of the base package, Model -> Resource Type. This leads to the option OPTION_USE_ENCODED_ATTRIBUTE_STYLE to be set in the createResource(URI uri) of the factory (cf. EMF book section 15.4.6. "Generated").
To fix this, I changed the Resource Type to XMI. It also worked for me to uncomment the two lines in the Factory in which the OPTION_USE_ENCODED_ATTRIBUTE_STYLE was set to true. Now the serialisation looks like this:
<alternativetasks_Alternative probabilityOfExecution="1.0" failureProbability="0.0020" meanDemandedTime="7.0" task_AlternativeTask="//@task_TaskList.1"> <repositorycomponent xsi:type="BasicComponent" href="default.repository#_74WmQKOdEd6Wld2f-l5cjw"/> <allocationcontext href="default.allocation#_U78qwKOXEd6D1ZKDqAnLPA"/> <abstractaction xsi:type="_1:InternalAction" href="default.repository#_-W5sUKOdEd6Wld2f-l5cjw"/> </alternativetasks_Alternative>
Troubeshooting in oAW eXtend-files (.ext)
If model elements of an imported model are not found, check whether the /model directory of the imported model is part of the src-path of the imported plugin project ("configure project properties").
Tool to fix the buggy export of RSA (Only RSA Version 6.x and before)
If there are multiple UML-models in RSA (Version 6.x), that reference each other, the exported UML2-files violate the XMI serialization standard. For example referenced files are addressed with the ".emx"-extension of RSA though they are named ".uml2". Further more the XMI-IDs of the referenced entities are not the right ones.
This tool fixes the faulty exported UML2-Files so that it can be easily imported by EMF. This allows to export/import models that contain OCL-constraints. (The alternative "ECORE"-format, that works for the RSA-export EMF-import procedure, does not handle OCL constraints, defined in the UML-model, correctly. RSA does export the constraint's names only.)
Download the tool:
- Source code of the patch tool (Visual Studio 2005 Project, C#, ZIP)
- Win32 executeable (Requires the MS .NET Framework 2.0 [1], ZIP)
- RSA-EMX-UML2 Project Revision 6271 not in the trunk anymore
Evaluate OCL-expressions in a EMF generated model code
To automatically evaluate OCL constraints within a EMF-generated model which have been specified in a meta model, portions of the EMF templates need to be adapted. Remark: Current templates do not support typed code for Collection types etc. as generics are not used in the templates. NOTE: Changing the templates only works up to EMF 2.3.
- Edit the plugin.xml of the plugin you like to add support for OCL for. Add org.eclipse.emf.ocl as required Plug-in.
- Import changed templates into your project (see de.uka.ipd.sdq.pcm/templates for an example; the corresponding plugin is part of the source in the pcm feature at PCM update site)
- Edit the root of your genmodel in the genmodel editor of EMF
- Open the Properties view for the root node
- Section "All"
- Runtime Version 2.3 (See note above)
- Section "Templates & Merge"
- Code Formatting: false
- Dynamic Templates: true
- Facade Helper Class: org.eclipse.emf.codegen.merge.java.facade.ast.ASTFacadeHelper
- Force Overwrite: false
- Redirection Pattern:
- Template Directory: /de.uka.ipd.sdq.pcm/templates (set to wherever you previously placed your templates)
- Template Plugin Variables:
- Update Classpath: true
- Section "Model"
- Model Plug-in Variables: EMFT_OCL=org.eclipse.emf.ocl
- Re-Generate your model code. The generated src folder now should hava a *.validation folder containing a NodeValidator.java.
Finally, validate your model instance in the generated emf editor using the context menu:
See also
- Evaluate OCL Constraints for Model Instances to see how to play around with OCL in your model
- Generate Method Body from Meta-Model OCL constraints (German)
- For the original tutorial please see Implementing Model Integrity in EMF with MDT OCL.
PCM Change Process
Please pay attention to the PCM Metamodelling Process
Change RSA Models and export them to UML
- Open in RSA: https://svnserver.informatik.kit.edu/i43/svn/code/Palladio/Core/trunk/MetaModels/de.uka.ipd.sdq.pcm.rsa
- Do not forget: http://sdqweb.ipd.kit.edu/wiki/EMF_Identifier_Generation
- Do changes to PCM meta-model
- If model elements or assocations are renamed or refactored, some OCL constraints may have syntax errors now. To find buggy OCL constraints, right click on the changed ePackage and click on "Check". Syntax errors in OCL constraints should appear as warnings in the RSA Error log view. Note: There is one OCL constraint attached to core::composition::AssemblyConnector that takes use of the ecore specific ocl operation closure(). This is not supported by RSA and will raise an error here but will work in emf later on.
- Export the model to UML: File -> Export -> Other/UML Model -> Select Models: [...] -> Select Directory: [...] -> Finish
- If the changes have occured in the pcm package only, select the following models to be exported:
- ProbabilityFunction.emx,
- Units.emx,
- identifier.emx,
- pcm.emx,
- stoex.emx
- Make sure "Recreate IDs" ("IDs erneut erstellen") is NOT checked
- Make sure "Export applied profiles" ("Angewendete Profile exportieren") is checked
- If the changes have occured in the pcm package only, select the following models to be exported:
Import UML to ECore using Eclipse and generate the PCM
- Eclipse (Version muss zuer Metamodell-Version passen!) mit EMF, GMF, GEF (Nota bene: seit 3.4 enthält das Eclipse-Modellierungsversion alle notwendigen Voraussetzungen)
- Be sure to have the following projects loaded and opened in your Eclipse workspace (https://svnserver.informatik.kit.edu/i43/svn/code/Palladio/Core/trunk/MetaModels); contents of these projects will be partially overwritten during the generation step:
- de.uka.ipd.sdq.pcm (core project)
- de.uka.ipd.sdq.pcm.edit (auxiliary functions)
- de.uka.ipd.sdq.pcm.editor (model editors)
- Be sure to have an UML plug-in installed (Europa Discovery Site -> Models and Model Development -> UML2 Tools/Extender/EndUser...)
- Create ecore model: File "de.uka.ipd.sdq.pcm/model/pcm.genmodel" -> context menu -> Reload -> UML Model
- Select all .uml files that have been exported before
- The profile files xy.profile.uml do not have to be selected
- Troubleshooting ... all genmodel packages must have prefixes (?)
- Select all .uml files that have been exported before
- If you recreate the genmodel:
- To generate a copyright string in the model code, select the root element of the genmodel, look at the property sheet, set Copyright Fields to true, and enter the copyright string in the Copyright Text. To change the copyright statement in the javadoc at the beginning of each class, you have to delete the classes before regenerating them. If you do not delete, the old string stays there.
- Generate the PCM:
- Make sure that you have the Palladio Coding Conventions activated
- File "de.uka.ipd.sdq.pcm/model/pcm.genmodel" -> context menu -> Open With -> EMF Generator
- Clean-Up Files before regeneration:
- Delete Directory META-INF including MANIFEST.MF
- delete the files build.properties, plugin.properties and plugin.xml
- Root node = "PalladioComponentModel" -> context menu -> generate all
- Fix dependencies in MANIFEST.MF
- Add Dependency to org.antlr
- Add Dependency to de.uka.ipd.sdq.errorhandling
- Export Package de.uka.ipd.sdq.pcm.stochasticexpressions.parser
Update the PCM code basis
Other projects might have to be updated to match the new PCM version!
Updating GMF projects
See PCM Development/Updating generated GMF editors
Log PCM Changes
Log all changes to the meta model in the PCM Changelog.