How to generate code from ecore model with OCL expressions in the separate file? - ocl

I'm using Eclipse addon to work with OCL. I have an Ecore model with some operations and derived attributes also I have a separate OCL file with expressions in it. I made a genmodel file and added:
<genAnnotations source="http://www.eclipse.org/OCL/GenModel">
<details key="Use Delegates" value="false"/>
</genAnnotations>
Also I checked that in the preferences realisation of OCL embedded within ecore models set to generate code. But when I try to generate code using this genmodel it only generates code without OCL expressions in it. What else should I do to generate code for all OCL expressions from a separate file?
Here is my model file: ecore file
Here is my genmodel file:.genmodel file
Start of OCL file:
import 'CarRental.ecore#/'
package CarRental
context Person
inv Person3:
age > 0 and age < 80
context Person::fullName : String
derive: self.firstname.concat(' ').concat(self.lastname)
...
endpackage
Model file in OCLinEcore:
package CarRental : CarRental = 'http:///CarRental.ecore'
{
class Person
{
operation email() : String[*|1];
operation updateAge(newAge : ecore::EInt[1]);
attribute firstname : String[?];
attribute lastname : String[?];
attribute age : ecore::EInt[1];
attribute isMarried : Boolean[1];
attribute fullName : String[?] { derived };
}
...
}

An outright Eclipse question should be asked on the Eclipse OCL newsgroup.
https://www.eclipse.org/forums/index.php/f/26/
Your Ecore/GenModel files are not Ecore/GenModel files; they are snapshots of the top level declarations. snapshots are very rarely good substitutes for files.
Your genmodel snippet looks good, but without the rest of the project it is very difficult to comment on the many possible mistakes you could have made.
My best guess is that given that you post a Sample Ecore Model Editor snapshot rather than an OCLinEcore editor snapshot, you have failed to synthesize all the EAnnotations that are necessary to register your OCL add-ons. The OCLinEcore editor does it all automatically.
I suggest you post a zipped project to the Eclipse OCL newsgroup.

Once details were provided on the Eclipse OCL Forum, it transpired that there were no OCLExpressions from which to generate code. Zero in => zero out.

Related

Use the same project for EMF model and edit code?

Can I somehow use the same Eclipse plug-in project for both a generated EMF model and the corresponding generated EMF Edit code?
Normally these two components reside in two different projects, the EMF Edit one with the suffix .edit to its name. I find this superfluous, since there is so little code in the Edit project, and it is so closely related to the model code.
I have tried setting both the modelDirectory and the editDirectory Gen Model attributes to (different) directories in the same project, but that seems to lead to endless confusion and build problems. I think maybe the two generation steps overwrite each others project setting files.
After some more experimentation it seems like it works fine to have EMF and EMF Edit generated code in the same project.
The things I had to do to make it work are the following:
Setting the genmodel property modelDirectory and editDirectory to the same directory. Otherwise I got a build error saying "The type ... is already defined in ...".
Setting the genmodel property bundleManifest="false". Otherwise the plug-in ID is overwritten by the generation process.
Apart from this I also set updateClasspath="false" to avoid that the generation process messes around with that.
The automatic updates to the manifest and plugin.xml files seem to be the following:
Set plug-in ID
Add exported packages
Add EMF extensions to plugin.xml
2 and 3 needs to be performed manually if they are desired. That would involve adding entries to plugin.xml similar to these:
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- #generated model -->
<package
uri="somePackage"
class="somePackage.SomePackage"
genModel="model/model.xcore"/>
</extension>
<extension point="org.eclipse.emf.edit.itemProviderAdapterFactories">
<!-- #generated model -->
<factory
uri="somePackage"
class="somePackage.someClass"
supportedTypes=
"org.eclipse.emf.edit.provider.IEditingDomainItemProvider
org.eclipse.emf.edit.provider.IStructuredItemContentProvider
org.eclipse.emf.edit.provider.ITreeItemContentProvider
org.eclipse.emf.edit.provider.IItemLabelProvider
org.eclipse.emf.edit.provider.IItemPropertySource"/>
</extension>

Add new rule to Codan

I am using the integrated CODAN static code analysis tool in Eclipse CDT. But i want to add some rules to check naming conventions of my code. How can I create and add that kind of rules to Codan?
To add rules to Codan first of all you have to make modification in Plugin.xml file by adding problem and checker tag.
<checker
class="org.eclipse.cdt.codan.internal.checkers.NamespaceNaming"
id="org.eclipse.cdt.codan.internal.checkers.NamespaceNaming"
name="%checker.name.NamespaceNaming">
<problem
category="org.eclipse.cdt.codan.core.categories.CodeStyle"
defaultEnabled="true"
defaultSeverity="Error"
description="%problem.description.NamespaceNaming"
id="org.eclipse.cdt.codan.internal.checkers.NamespaceNaming"
messagePattern="%problem.messagePattern.NamespaceNaming"
multiple="true"
name="%problem.name.NamespaceNaming">
</problem>
Then in bundle.properties you have to add message and description of your problem. After which you have to create a class in Codan Source code, do what implementation you like to do in it (like you can create a pattern with regex so you can compare your file name with it).

How to read the serialized objects stored in the model file

I have created the ecore file for basic family and i have generated the model,edit and editor code and i run the application now i am able to create the family model file in the run time.But now i want to read that model file to get the serialized objects stored in the family model file.
Model file is of type
?xml version="1.0" encoding="UTF-8"?
This is a plain EMF question (I mean, it's not Sirius-related). If you are new to EMF, this references some documentation. In particular, this PDF is a sample chapter of the "EMF book", which gives a high level overview of the framework. In particular, the section called Object Persistence should answer your question (in particular the code snippet on page 31 which shows how to load a resource/model in memory).
If you have a basic family metamodel and if you have generated its model, edit and editor code and if you have created a ".basicfamily" model from it, you could read it using this piece of code:
URI uri = URI.createURI(new File("path of your file").getAbsolutePath());
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(BasicfamilyPackage.eNS_URI, BasicfamilyPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("basicfamily", new XMIResourceFactoryImpl());
Resource resource = resourceSet.getResource(uri, true);
List<EObject> contents = resource.getContents();
// now you can iterate on the root objects of your model, use EObject#getContents() to
// retrieve the children of an EObject and thus navigate in your data
If this code is running in an Eclipse plugin with your metamodel installed, some parts of this code may not be necessary (the addition of the basic family EPackage in the package registry and the registration of the resource factory) since they are handled by the plugin.xml of the generated projects.

List all available models in EMF application

I'm working on a project consisting of two Eclipse plugin projects. One is an EMF project and contains the metamodel for the application. The other one is the acctual plugin working on that metamodel.
I'm now looking for a way to list all types of models available in the metamodel project. Since I basically need all generated classes I could use reflections to iterate through the metamodel package but I'd prefer an easier way if there is one.
The models are already listed as extensions in the plugin.xml like this:
<plugin>
<extension point="org.eclipse.emf.ecore.generated_package">
<package
uri="MyModel"
class="org.myproject.metamodel.MyModel.MyModelPackage"
genModel="model/MetaModel.genmodel"/>
</extension>
</plugin>
where the class MyModelPackage extends EPackage and org.myproject.metamodel.MyModel also contains all the other generated classes I need to list. I'm guessing that I can use that information but I still don't know how.
Update
The project I'm working on is based on EMFStore. Running it offers the EMFStore perspective. If I have the Navigator view with a project I can right click on that project and select New Model Element. This opens a dialog where all the model elements from my metamodel are listed so it is possible. It must be done somewhere in EMFStore or one of it's dependencies. I looked through the source code but can't seem to find where it's done.
The plugin.xml of the project org.eclipse.emf.emfstore.perspective refers to the class org.eclipse.emf.emfstore.emfperspective.EMFStorePerspective which I can't find in the sources. I imported the project via the Eclipse Import Plug-Ins and Fragments functionality and it has no source folder. In the EMFStore git repositories I can't even find that project.
Update
I now got the registry that contains the generated packages using EPackage.Registry.INSTANCE. Unfortunately it contains more than the EPackages from the one project containing the metadata (org.myproject.metamodel). Now I'm just looking for a proper way to filter it, but still can't get the hang of it.
Update
As the filtering is not part of my original question I accepted the answer by #SpaceTrucker. For those who are curious, this is how I've done it now:
Registry registry = EPackage.Registry.INSTANCE;
for (String key : new HashSet<String>(registry.keySet())) {
EPackage ePackage = registry.getEPackage(key);
if (ePackage.getClass().getName().startsWith("org.myproject.metamodel")) {
//do stuf
}
}
I found no way to filter for the project but luckily all the packages start with the same prefix.
EPackages may be registered via an EPackage.Registry. There seems to be a globally used instance available via ECorePlugin.getDefaultRegistryImplementation(). However I'm not 100% sure on that.
MoDisco comes with a EMF Model Browser, where you are also able to select any registered EMF model. So you also could have a look at those sources.

How to generate 'java code with annotations' from emf model

More precisely, I want to know, how one can model annotations into the ecore model definition. So that the generated java code would contain them. (For eg: hibernate persistence tags)
This post on the EMF Forums discusses how to use custom templates for code generation: https://www.eclipse.org/forums/index.php/t/131673/.
In a nutshell, you can dynamically provide different templates for your code generation, making it possible to insert the required annotations. In the forum post, Ed Merks (the EMF lead) suggests two pieces of information to read:
http://wiki.eclipse.org/index.php/EMF-FAQ#What_are_Dynamic_Templates.3F
http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_I_use_Dynamic_Templates.3F
and a small example of how to use them:
The inserts look like this:
<%# include file="Class/getGenFeature.annotations.insert.javajetinc" fail="silent" %>
so under your templates folder you'd create files like this:
<someproject>/templates/model/Class/getGenFeature.annotations.insert.java jetinc
and whatever you put in the file will be inserted on the getter. Likely
you'd include guards like this:
<%if (isImplementation) {%>
#Something
<%}%>
Try to follow the convention of using tabs for the indentation since
these will be converted to the formatting preference of the target project.
Once you can provide your own templates you have two choices:
Add the hibernate tags by default to all your code
Modify the templates to read annotations in the ecore model.
For 2, you will need to define your own annotation source (basically a url), something like https://myproject/emf/hibernate and then add EAnnotations to your EClasses that use your custom url and provide key:value settings (e.g. the hibernate annotation to add). Your custom template can then read the annotations from the EClass, query if your source is used and then used the provided values to add the Java annotations.
The post also mentions the Teneo project, that provides JPA support for EMF. No recent development has been done (apparently), but it can be mature enough to use.
I don't think you can to this out of the box. However, you could look into the parameters of the ".genmodel" file to see if you can tweak how annotations (EAnnotations) are being output to the files. The problem with code generation templates is that they are fixed, but maybe through some option in the genmodel you can control how annotations get written to files.