Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Programmatic ecore to Java working, but directory structure is strange. Please help?
Programmatic ecore to Java working, but directory structure is strange. Please help? [message #772630] Fri, 30 December 2011 03:41 Go to next message
Vitor Souza is currently offline Vitor Souza
Messages: 2
Registered: December 2011
Junior Member
Hello,

I'm developing an RCP application (check out github.com / vitorsouza / Unagi -- I can't post links, so I had to post it like this) and I want to generate Java source code from an EMF ecore file. Searching the Internet I found a way to do it and it works great, with one exception: I specify the following directory as target for the sources:

/home/vitor/A-CAD/src

And since I set my base package to be it.unitn.disi.acad.models, I expect it to create the following directory structure (A):

/home/vitor/A-CAD/src/it/unitn/disi/acad/model

But instead, it's creating the following strange directory structure (B):

/home/vitor/A-CAD/src/vitor/A-CAD/src/it/unitn/disi/acad/model (note the repetition of vitor/A-CAD/src)

I tried changing some of the parameters that mentioned the target directory, but with no success. I tried debugging so I could understand why it was creating such a strange folder structure, but I couldn't. Can anyone please help? I want to know how to make EMF generate the directory structure that I expect (A).

Below I present a summary of the source code that generates the sources from the ecore model. The complete version can be seen at Github (In the GitHub source, look for it.unitn.disi.unagi.application/src/it/unitn/disi/unagi/application/internal/services/ManageModelsServiceBean.java). Note that in the original code my .ecore file references two other .ecore files, but I removed that from the code below to simplify, assuming that this doesn't have anything to do with my directory structure issue.

// mainEcoreFile = ... (a java.io.File referencing my .ecore file - e.g., /home/vitor/A-CAD/models/acad.ecore)
// targetFolder = ... (a java.io.File referencing the directory where I want the sources to be generated - e.g., /home/vitor/A-CAD/src)
// basePackage = ... (a String with the base package - e.g., "it.unitn.disi.acad.models")

/* STEP 1: .genmodel file generation */

// Initializes the resource set.
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getURIConverter().getURIMap().putAll(EcorePlugin.computePlatformURIMap());

// "Opens" the ecore file and retrieves its package.
IPath mainPath = new Path(mainEcoreFile.getAbsoluteFile().getCanonicalPath());
URI ecoreURI = URI.createFileURI(mainPath.toString());
Resource resource = resourceSet.getResource(ecoreURI, true);
EPackage mainPackage = (EPackage) resource.getContents().get(0);

// Determines the name of the .genmodel file (same as .ecore with different extension).
IPath genModelPath = mainPath.removeFileExtension().addFileExtension("genmodel");
URI genModelURI = URI.createFileURI(genModelPath.toString());

// Creates the genmodel object in memory and sets its attributes.
IPath modelDir = new Path(targetFolder.getAbsoluteFile().getCanonicalPath()).makeRelative();
GenModel mainGenModel = GenModelFactory.eINSTANCE.createGenModel();
mainGenModel.setModelDirectory(modelDir.toString());
mainGenModel.getForeignModel().add(mainPath.toString());
mainGenModel.initialize(Collections.singleton(mainPackage));
mainGenModel.setModelName(mainPath.removeFileExtension().lastSegment());

// Sets the base package in the main package of the genmodel.
GenPackage genPackage = mainGenModel.getGenPackages().get(0);
genPackage.setBasePackage(basePackage);

// Creates the genmodel resource and saves it in the file system.
Resource genModelResource = Resource.Factory.Registry.INSTANCE.getFactory(genModelURI).createResource(genModelURI);
genModelResource.getContents().add(mainGenModel);
resourceSet.getResources().add(genModelResource);
genModelResource.save(Collections.EMPTY_MAP);


/* STEP 2: Java source code generation */

// Creates a null progress monitor to ignore the progress.
IProgressMonitor progressMonitor = new NullProgressMonitor();

// Retrieves the genmodel object from the genmodel resource and checks that it's valid.
GenModel genModel = (GenModel) genModelResource.getContents().get(0);
IStatus status = genModel.validate();
if (!status.isOK()) {
	Diagnostic diagnostic = genModel.diagnose();
	throw new IllegalStateException("Genmodel file is not valid. Diagnostic message is: " + diagnostic.getMessage()); //$NON-NLS-1$
}

// Creates a generator from the model and configures the generation.
Generator generator = new Generator(); // Using org.eclipse.emf.codegen.ecore.generator.Generator
generator.setInput(genModel);
genModel.setForceOverwrite(true);
genModel.reconcile();
genModel.setCanGenerate(true);
genModel.setValidateModel(true);
genModel.setUpdateClasspath(false);
genModel.setCodeFormatting(true);

// Generates the source code at the target folder.
IPath path = new Path(modelName);
CodeGenUtil.EclipseUtil.findOrCreateContainer(path, true, path, BasicMonitor.toIProgressMonitor(CodeGenUtil.EclipseUtil.createMonitor(progressMonitor, 1)));
generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, CodeGenUtil.EclipseUtil.createMonitor(progressMonitor, 1));



Re: Programmatic ecore to Java working, but directory structure is strange. Please help? [message #774080 is a reply to message #772630] Tue, 03 January 2012 03:24 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26014
Registered: July 2009
Senior Member
Vitor,

Comments below.

On 30/12/2011 9:41 AM, Vitor Souza wrote:
> Hello,
>
> I'm developing an RCP application (check out github.com / vitorsouza /
> Unagi -- I can't post links, so I had to post it like this) and I want
> to generate Java source code from an EMF ecore file. Searching the
> Internet I found a way to do it and it works great, with one
> exception: I specify the following directory as target for the sources:
>
> /home/vitor/A-CAD/src
>
> And since I set my base package to be it.unitn.disi.acad.models, I
> expect it to create the following directory structure (A):
>
> /home/vitor/A-CAD/src/it/unitn/disi/acad/model
>
> But instead, it's creating the following strange directory structure (B):
>
> /home/vitor/A-CAD/src/vitor/A-CAD/src/it/unitn/disi/acad/model (note
> the repetition of vitor/A-CAD/src)
How are you initializing the GenModel's...
>
> I tried changing some of the parameters that mentioned the target
> directory, but with no success. I tried debugging so I could
> understand why it was creating such a strange folder structure, but I
> couldn't. Can anyone please help? I want to know how to make EMF
> generate the directory structure that I expect (A).
>
> Below I present a summary of the source code that generates the
> sources from the ecore model. The complete version can be seen at
> Github (In the GitHub source, look for
> it.unitn.disi.unagi.application/src/it/unitn/disi/unagi/application/internal/services/ManageModelsServiceBean.java).
> Note that in the original code my .ecore file references two other
> .ecore files, but I removed that from the code below to simplify,
> assuming that this doesn't have anything to do with my directory
> structure issue.
>
> // mainEcoreFile = ... (a java.io.File referencing my .ecore file -
> e.g., /home/vitor/A-CAD/models/acad.ecore)
> // targetFolder = ... (a java.io.File referencing the directory where
> I want the sources to be generated - e.g., /home/vitor/A-CAD/src)
> // basePackage = ... (a String with the base package - e.g.,
> "it.unitn.disi.acad.models")
>
> /* STEP 1: .genmodel file generation */
>
> // Initializes the resource set.
> ResourceSet resourceSet = new ResourceSetImpl();
> resourceSet.getURIConverter().getURIMap().putAll(EcorePlugin.computePlatformURIMap());
>
>
> // "Opens" the ecore file and retrieves its package.
> IPath mainPath = new
> Path(mainEcoreFile.getAbsoluteFile().getCanonicalPath());
> URI ecoreURI = URI.createFileURI(mainPath.toString());
> Resource resource = resourceSet.getResource(ecoreURI, true);
> EPackage mainPackage = (EPackage) resource.getContents().get(0);
>
> // Determines the name of the .genmodel file (same as .ecore with
> different extension).
> IPath genModelPath =
> mainPath.removeFileExtension().addFileExtension("genmodel");
> URI genModelURI = URI.createFileURI(genModelPath.toString());
>
> // Creates the genmodel object in memory and sets its attributes.
> IPath modelDir = new
> Path(targetFolder.getAbsoluteFile().getCanonicalPath()).makeRelative();
> GenModel mainGenModel = GenModelFactory.eINSTANCE.createGenModel();
> mainGenModel.setModelDirectory(modelDir.toString());
What's this computing in you situation?
> mainGenModel.getForeignModel().add(mainPath.toString());
> mainGenModel.initialize(Collections.singleton(mainPackage));
> mainGenModel.setModelName(mainPath.removeFileExtension().lastSegment());
>
> // Sets the base package in the main package of the genmodel.
> GenPackage genPackage = mainGenModel.getGenPackages().get(0);
> genPackage.setBasePackage(basePackage);
>
> // Creates the genmodel resource and saves it in the file system.
> Resource genModelResource =
> Resource.Factory.Registry.INSTANCE.getFactory(genModelURI).createResource(genModelURI);
> genModelResource.getContents().add(mainGenModel);
> resourceSet.getResources().add(genModelResource);
> genModelResource.save(Collections.EMPTY_MAP);
>
>
> /* STEP 2: Java source code generation */
>
> // Creates a null progress monitor to ignore the progress.
> IProgressMonitor progressMonitor = new NullProgressMonitor();
>
> // Retrieves the genmodel object from the genmodel resource and checks
> that it's valid.
> GenModel genModel = (GenModel) genModelResource.getContents().get(0);
> IStatus status = genModel.validate();
> if (!status.isOK()) {
> Diagnostic diagnostic = genModel.diagnose();
> throw new IllegalStateException("Genmodel file is not valid.
> Diagnostic message is: " + diagnostic.getMessage()); //$NON-NLS-1$
> }
>
> // Creates a generator from the model and configures the generation.
> Generator generator = new Generator(); // Using
> org.eclipse.emf.codegen.ecore.generator.Generator
> generator.setInput(genModel);
> genModel.setForceOverwrite(true);
> genModel.reconcile();
> genModel.setCanGenerate(true);
> genModel.setValidateModel(true);
> genModel.setUpdateClasspath(false);
> genModel.setCodeFormatting(true);
>
> // Generates the source code at the target folder.
> IPath path = new Path(modelName);
> CodeGenUtil.EclipseUtil.findOrCreateContainer(path, true, path,
> BasicMonitor.toIProgressMonitor(CodeGenUtil.EclipseUtil.createMonitor(progressMonitor,
> 1)));
> generator.generate(genModel,
> GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE,
> CodeGenUtil.EclipseUtil.createMonitor(progressMonitor, 1));
>
>
>
Re: Programmatic ecore to Java working, but directory structure is strange. Please help? [message #945644 is a reply to message #774080] Mon, 15 October 2012 09:53 Go to previous message
Vitor Souza is currently offline Vitor Souza
Messages: 2
Registered: December 2011
Junior Member
Hi Ed,

After more than 9 months, I'm replying to this, so let me start by saying thank you for taking the time to reply to my original post and sorry for not getting back to you. I had to abandon my Eclipse plug-in for a while and recently I've resumed working on it, and on the topic of this post.

So just to give you (and anyone else that ends up here from Google) an update, I decided to revamp my plug-in so it would be based on an Workspace, use Eclipse's file API (IFile, IFolder, IPath etc.) instead of using the RCP just for its integration with other Eclipse plug-ins. This way, I could completely remove the call to
CodeGenUtil.EclipseUtil.findOrCreateContainer()
and the Java sources were generated from the GenModel in the correct path. Problem solved!

If anyone is interested in the final working code, go to GitHub and append the following path after .com/:

sefms-disi-unitn/Unagi/blob/master/it.unitn.disi.unagi.application/src/it/unitn/disi/unagi/application/internal/services/ManageModelsService.java


Thanks again,
- VĂ­tor
Previous Topic:Retrieving E_ID from EObject
Next Topic:CDO Serverv. 2.0 and Embedded Derby setup
Goto Forum:
  


Current Time: Mon Sep 01 19:45:15 EDT 2014

Powered by FUDForum. Page generated in 0.09736 seconds