Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Epsilon » Construct models programmatically but manipulate them with Epsilon
Construct models programmatically but manipulate them with Epsilon [message #1857254] Thu, 26 January 2023 18:18 Go to next message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
Hello,

Firstly, thanks for the great documentation available, it is really helpful!
I've looked through it a bit and I think Eclipse Epsilon is perfect for my own project but I'm having a little trouble getting started.

Firstly:
- I want to use Eclipse Epsilon outside from Eclipse IDE
- I use EMF (but I'm not very good with it yet)
- I use Maven
- I want to do transformations and model to text later but I will not detail that here because I think these parts are sufficiently documented

I have created a tiny metamodel with EMFatic and I see thanks to the documentation how to use it with Eclipse Epsilon, through Maven.

But in my case, my models have do be built during runtime because the information to create them comes from several external sources.
In the website, I found that I can load metamodel and model in a programmatically way (here) but if I understand well I have to load them at the same time and from files in the filesystem.

As I have to build my model with Java code, it is better for me to have my metamodel as java classes. My first question is:
- Is it possible to generate from EMFatic the classes for the metamodel in the same way I can with EMF and ecore/genmodel files? If yes, is it possible to trigger the generation in a Maven phase?

That done, I will have my metamodel and models loaded with EMF. Can I use them with Eclipse Epsilon without have to load a file as I found on the website?

Thank you in advance for your help!
Re: Construct models programmatically but manipulate them with Epsilon [message #1857257 is a reply to message #1857254] Thu, 26 January 2023 20:15 Go to previous messageGo to next message
Horacio Hoyos is currently offline Horacio HoyosFriend
Messages: 242
Registered: October 2009
Location: Mexico
Senior Member

Hi,

I am a bit confused of what you actually want to achieve. So some questions and answers.

Are your metamodels generated programmatically (i.e. at runtime?).
- If not (that is, you have the metamodels at build time - as I understand) I would suggest creating the Genmodels for them, generate your code and add it to version control.
- If yes, the genmodel (afaik) is not designed to be run outside eclipse, so you would probably need to run it inside a headless eclipse, from an Ant script and call that ant from maven. See some ideas here.

When you pass the metamodel and model file to an EmfModel and then call
load()
what Epsilon does is what you are doing, i.e. load the metamodel and model via EMF. If you look at the EmfModel API, there is a setResoruce method. You can use that method to assign the resource you loaded via EMF. With this approach, you should also skip the load call.

Resoruce r = yourEmfLoadMethod();

EmfModel model = new EmfModel();
model.setName("M");
model.setStoredOnDisposal(true);
model.setResource(r);

// Parses and executes the EOL program
EolModule module = new EolModule();
module.parse(new File("program.eol"));
// Makes the model accessible from the program
module.getContext().getModelRepository().addModel(model);
module.execute();


Horacio Hoyos Rodriguez
Kinori Tech
Need professional support for Epsilon, EMF?
Go to: https://kinori.tech

[Updated on: Thu, 26 January 2023 20:22]

Report message to a moderator

Re: Construct models programmatically but manipulate them with Epsilon [message #1857261 is a reply to message #1857257] Thu, 26 January 2023 22:27 Go to previous messageGo to next message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
Thank you very much for your answer!
I want to define my metamodel in a EMFatic file (emf) and generate Java classes from it.
If I understand correctly, you advise to use Eclipse to generate my classes (EMFatic to ecore file and generate classes from the ecore and a genmodel) and add these classes in my git?
Re: Construct models programmatically but manipulate them with Epsilon [message #1857262 is a reply to message #1857261] Fri, 27 January 2023 00:12 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Théo,

I don't believe that EMF provides an easy way to invoke the Java code generator from Maven, so generating your code within Eclipse and pushing it to your Git repo sounds sensible to me.

Thanks,
Dimitris
Re: Construct models programmatically but manipulate them with Epsilon [message #1857297 is a reply to message #1857262] Sun, 29 January 2023 15:17 Go to previous messageGo to next message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
Thank you very much for your answers, I will follow your advices.
Re: Construct models programmatically but manipulate them with Epsilon [message #1857419 is a reply to message #1857297] Mon, 06 February 2023 19:12 Go to previous messageGo to next message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
Hello,
Finally, I chose to use XCore to create my metamodels because I can generate my Java classes by using Maven.
Now I try to do my transformation. I have two metamodels A and B and one instance of A named a. I want to get an instance of B b resulting of the transformation of a using model_transformation.etl.
I search on Internet to see if there are examples to do that but I didn't find any solution working for me...
All the code can be find here.

My Metamodels:

(A.xcore)
@GenModel(
    bundleManifest="false",
    modelDirectory="src/main/java-gen",
    complianceLevel="17"
)

package fr.theogiraudet.test.a

class A {
    String name
}


(B.xcore)
@GenModel(
    bundleManifest="false",
    modelDirectory="src/main/java-gen",
    complianceLevel="17"
)

package fr.theogiraudet.test.a

class A {
    String name
}


(model_transformation.etl)
rule A2B
    transform a : A!A
    to        b : B!B {

    a.name = b.name;
}


And finally, the code to apply programmatically the transformation:

public class Main {

    private static Logger logger = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) throws Exception {

        final A model = AFactory.eINSTANCE.createA();

        ResourceSet rs = new ResourceSetImpl();
        rs.getPackageRegistry().put(APackage.eNS_URI, APackage.eINSTANCE);
        rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("a", new EcoreResourceFactoryImpl());

        rs.getPackageRegistry().put(BPackage.eNS_URI, BPackage.eINSTANCE);
        rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("b", new EcoreResourceFactoryImpl());

        final Resource fooResource = createResource(model, "foo.a", rs);

        final EmfModel fooModel = createModel(fooResource, "foo.a");
        final EmfModel aMetaModel = createModel(APackage.eINSTANCE.eResource(), "A");
        final EmfModel bMetaModel = createModel(BPackage.eINSTANCE.eResource(), "B");


        EtlModule module = new EtlModule();
        module.getContext().setModule(module);
        module.parse(Main.class.getClassLoader().getResource("transformation/model_transformation.etl"));
        module.getContext().getModelRepository().addModel(aMetaModel);
        module.getContext().getModelRepository().addModel(bMetaModel);
        module.getContext().getModelRepository().addModel(fooModel);
        module.getContext().setTransformationStrategy(new DefaultTransformationStrategy());
        var result = module.execute();
        System.out.println();
    }

    public static Resource createResource(EObject model, String name, ResourceSet set) throws IOException {
        var uri = URI.createURI("https:///www.theogiraudet.fr/test/schemas/" + name);
        var resource = set.createResource(uri);
        resource.getContents().add(model);
        resource.load(Map.of());
        return resource;
    }

    public static EmfModel createModel(Resource resource, String name) {
        final InMemoryEmfModel model = new InMemoryEmfModel(resource);
        model.setName(name);
        return model;
    }


I guess result must be is (or wraps) my instance of B but the result is of type TransformationTrace and these attributes (cache and transformations) are totally empty...

Thank you in advance for your help!

[Updated on: Mon, 06 February 2023 19:26]

Report message to a moderator

Re: Construct models programmatically but manipulate them with Epsilon [message #1857420 is a reply to message #1857419] Mon, 06 February 2023 23:37 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Theo,

I've submitted a pull request to your minimal example repository that shows how to run the transformation and get the generated B elements from the target model.

Thanks,
Dimitris
Re: Construct models programmatically but manipulate them with Epsilon [message #1857440 is a reply to message #1857420] Tue, 07 February 2023 19:55 Go to previous messageGo to next message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
Thank you really much for your pull request. Last question I have (I hope) about that is that I need to inject my model `a`. In your commit, you create instance directly from the EmfModel. I see I can use the `setResource` as I have done in the first version of my minimal project but when I am trying, I have or an empty array for result (if I put the instruction before the load) or even an exception "Exception in thread "main" Type 'A!A' not found" (if after the load).
How can I do that?

[Updated on: Tue, 07 February 2023 19:58]

Report message to a moderator

Re: Construct models programmatically but manipulate them with Epsilon [message #1857441 is a reply to message #1857440] Tue, 07 February 2023 22:41 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Theo,

Replacing the following lines

// The source model of the transformation
EmfModel sourceModel = new EmfModel();
sourceModel.setName("A");
sourceModel.setReadOnLoad(false); // As the model doesn't exist
sourceModel.setStoredOnDisposal(false); // We don't want to store the source model
sourceModel.setModelFileUri(URI.createFileURI("foo.a"));
sourceModel.setMetamodelUri(APackage.eNS_URI);
sourceModel.load();


with

// The source model of the transformation
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getPackageRegistry().put(APackage.eNS_URI, APackage.eINSTANCE);
Resource resource = resourceSet.createResource(URI.createFileURI("foo.a"));
InMemoryEmfModel sourceModel = new InMemoryEmfModel("A", resource);


should do the trick.

Thanks,
Dimitris

[Updated on: Tue, 07 February 2023 22:42]

Report message to a moderator

Re: Construct models programmatically but manipulate them with Epsilon [message #1857461 is a reply to message #1857441] Wed, 08 February 2023 21:12 Go to previous message
Théo Giraudet is currently offline Théo GiraudetFriend
Messages: 9
Registered: January 2021
Junior Member
It works perfectly, thanks!
Previous Topic:EPSILON INSTALLATION
Next Topic:Resolve reference between models with ETL
Goto Forum:
  


Current Time: Sat Apr 27 11:50:27 GMT 2024

Powered by FUDForum. Page generated in 0.03661 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top