Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » MoDisco » [ATL] Run Modisco .javaxmi transformation programmatically
[ATL] Run Modisco .javaxmi transformation programmatically [message #662781] Thu, 31 March 2011 18:06 Go to next message
Thanasis Naskos is currently offline Thanasis Naskos
Messages: 22
Registered: March 2011
Junior Member
Hi,

I'm trying to run an ATL transformation programmatically, I've searched about it a lot, but I can't make it work.

Project scope:
I'm discovering Modisco Java Model (.javaxmi file) from a Java Project and transforming it to an other Modisco Java Model making some changes so the code conforms to Singleton Uml Pattern (singleton if anyone intersted).
After that, I'm generating the Java code from the "new" .javaxmi file.

Problem:
I've made the .atl file with the Modisco Java Model transformation and everything goes fine, when I'm running it from the "Run As" menu.
But what I want to do is run it from java code. Looking in previous posts and with some googling I partially figure it out and I've made 2 code approaches.

The first one is a plugin, based on public2private plugin, and the problem is that after successfully running it, nothing happens, no new file is made, as it should be.

The second approach come's from this post #655532 and the main difference with the previous is that it can work outside the Eclipse Environment.
The problem is that when I run it I'm getting this Exception:

Exception in thread "main" org.eclipse.m2m.atl.engine.emfvm.VMException: Cannot create MODISCOJAVA!Block
at __matchBlock#29(modiscoJavaModelSingleton.atl[215:8-220:36])
local variables: self=modiscoJavaModelSingleton : ASMModule, s=IN!<unnamed>
at __matcher__#31(modiscoJavaModelSingleton.atl)
local variables: self=modiscoJavaModelSingleton : ASMModule
at main#42(modiscoJavaModelSingleton.atl)
local variables: self=modiscoJavaModelSingleton : ASMModule

Below I'm attaching the code of this two approaches and only the header of the ATL transformation file because it's too large (1733 lines) but if it's needed I can upload it too.

First approach (plugin) I've changed the plugin.xml to work with .javaxmi files not .uml:
/*******************************************************************************
 * Copyright (c) 2008, 2010 Obeo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Obeo - Public2Private example IDE
 *******************************************************************************/
package org.eclipse.m2m.atl.examples.public2private.ui;

import java.net.URL;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.m2m.atl.core.ATLCoreException;
import org.eclipse.m2m.atl.core.IExtractor;
import org.eclipse.m2m.atl.core.IInjector;
import org.eclipse.m2m.atl.core.IModel;
import org.eclipse.m2m.atl.core.IReferenceModel;
import org.eclipse.m2m.atl.core.ModelFactory;
import org.eclipse.m2m.atl.core.launch.ILauncher;
import org.eclipse.m2m.atl.core.service.CoreService;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.osgi.framework.Bundle;

/**
 * Privatize action implementation.
 * 
 * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
 */
public class PrivatizeAction implements IObjectActionDelegate {

	private static IInjector injector;

	private static IExtractor extractor;

	private static IReferenceModel sourceTargetMetamodel;

	private static URL asmURL;

	private ISelection currentSelection;

	static {
		// ATL public2private transformation
		Bundle bundle = Platform.getBundle("org.eclipse.m2m.atl.examples.public2private"); //$NON-NLS-1$
		asmURL = bundle.getEntry("transformation/Public2Private.asm"); //$NON-NLS-1$  [B]//It's not the same Public2Private.atl file as the example's, I've replaced the original code with mine and keep the same name[/B]
		try {
			injector = CoreService.getInjector("EMF"); //$NON-NLS-1$
			extractor = CoreService.getExtractor("EMF"); //$NON-NLS-1$			
		} catch (ATLCoreException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Constructor for Action1.
	 */
	public PrivatizeAction() {
		super();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction,
	 *      org.eclipse.ui.IWorkbenchPart)
	 */
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		// Getting files from selection
		IStructuredSelection iss = (IStructuredSelection)currentSelection;
		for (Iterator<?> iterator = iss.iterator(); iterator.hasNext();) {
			try {
				privatize((IFile)iterator.next());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

	private void privatize(IFile file) throws Exception {
		// Defaults
		ModelFactory factory = CoreService.getModelFactory("EMF"); //$NON-NLS-1$

		//launch parameters
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("allowInterModelReferences", Boolean.TRUE);
		
		// Metamodels
		sourceTargetMetamodel = factory.newReferenceModel();
		injector.inject(sourceTargetMetamodel, "http://www.eclipse.org/MoDisco/Java/0.2.incubation/java");

		// Getting launcher
		ILauncher launcher = null;
		launcher = CoreService.getLauncher("EMF-specific VM"); //$NON-NLS-1$
		
		launcher.initialize(Collections.<String, Object> emptyMap());

		// Creating models
		IModel sourceModel = factory.newModel(sourceTargetMetamodel);
		IModel targetModel = factory.newModel(sourceTargetMetamodel);

		// Loading existing model
		injector.inject(sourceModel, file.getFullPath().toString());

		// Launching
		launcher.addInModel(sourceModel, "IN", "MODISCOJAVA");
		launcher.addOutModel(targetModel, "OUT", "MODISCOJAVA");
		

		launcher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), parameters, asmURL.openStream());

		// Saving model
		extractor.extract(targetModel, "model/newModel.javaxmi"); //the name of the generated model

		// Refresh workspace
		file.getParent().refreshLocal(IProject.DEPTH_INFINITE, null);
		
		System.out.println("Done");

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
	 *      org.eclipse.jface.viewers.ISelection)
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		this.currentSelection = selection;
	}
}




Second approach:
package test;

import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.m2m.atl.core.ATLCoreException;
import org.eclipse.m2m.atl.core.IExtractor;
import org.eclipse.m2m.atl.core.IInjector;
import org.eclipse.m2m.atl.core.IModel;
import org.eclipse.m2m.atl.core.IReferenceModel;
import org.eclipse.m2m.atl.core.ModelFactory;
import org.eclipse.m2m.atl.core.emf.EMFExtractor;
import org.eclipse.m2m.atl.core.emf.EMFInjector;
import org.eclipse.m2m.atl.core.emf.EMFModelFactory;
import org.eclipse.m2m.atl.core.launch.ILauncher;
import org.eclipse.m2m.atl.core.service.CoreService;
import org.eclipse.m2m.atl.engine.emfvm.launch.EMFVMLauncher;

public class RunTransformation {

	private static IInjector injector;
	private static IExtractor extractor;
	private static IReferenceModel sourceMetamodel;
	private static IReferenceModel targetMetamodel;
	/*
	 * My test data
	 */
	private static String transformationFilepath = "transformation/modiscoJavaModelSingleton.asm";
	private static String sourceFilepath = "model/java.ecore"; //copied from org.eclipse.gmt.modisco.java/model/java.ecore
	private static String targetFilepath = "model/java.ecore";
	private static String dataSourceFilepath = "data/toSingleton.javaxmi";
	private static String dataTargetfilepath = "data/newModel.javaxmi";

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		try {
			CoreService.registerLauncher("EMF-specific VM", EMFVMLauncher.class);
			CoreService.registerFactory("EMF", EMFModelFactory.class); 
			CoreService.registerExtractor("EMF", EMFExtractor.class);
			CoreService.registerInjector("EMF", EMFInjector.class);
			
			injector = CoreService.getInjector("EMF"); 
			extractor = CoreService.getExtractor("EMF"); 			
		} catch (ATLCoreException e) {
			e.printStackTrace();
		}
		
		// Defaults
		ModelFactory factory = CoreService.getModelFactory("EMF");

		//launch parameters
		HashMap<String, Object> parameters = new HashMap<String, Object>();
		parameters.put("allowInterModelReferences", Boolean.TRUE);
		
		// Metamodels
		sourceMetamodel = factory.newReferenceModel();
		targetMetamodel = factory.newReferenceModel();
		injector.inject(sourceMetamodel, sourceFilepath);
		injector.inject(targetMetamodel, targetFilepath);

		// Getting launcher
		ILauncher launcher = null;
		launcher = (EMFVMLauncher)CoreService.getLauncher("EMF-specific VM"); 
		launcher.initialize(Collections.<String, Object> emptyMap());

		// Creating models
		IModel sourceModel = factory.newModel(sourceMetamodel);
		IModel targetModel = factory.newModel(targetMetamodel);

		// Loading existing model
		injector.inject(sourceModel, dataSourceFilepath);

		// Launching
		launcher.addInModel(sourceModel, "IN", "MODISCOJAVA");
		launcher.addOutModel(targetModel, "OUT", "MODISCOJAVA");
		/*
		 * As a reference for this I provide the first two lines of my TestATL.atl file:
		 * module TestATL;
		 * create OUT : MM1 from IN : MM;
		 */
		
		// the loadModule function requires an absolute path to the ASM file
		// this is my dirty (?) way to transform a relative path (inside the project) to an absolute path
		URL asmFile = new File(transformationFilepath).toURI().toURL();
		Object loadedModule = launcher.loadModule(asmFile.openStream());

		
		launcher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), parameters, loadedModule);

		// Saving model
		extractor.extract(targetModel, dataTargetfilepath);
		
		System.out.println("DONE!");
	}

}



ATL transformation file header:
-- @nsURI MODISCOJAVA=http://www.eclipse.org/MoDisco/Java/0.2.incubation/java

module modiscoJavaModelSingleton;
create OUT : MODISCOJAVA from IN : MODISCOJAVA;


Please let me know if you need any further information...
Thank you for your time..!
Re: [ATL] Run Modisco .javaxmi transformation programmatically [message #662832 is a reply to message #662781] Fri, 01 April 2011 03:13 Go to previous messageGo to next message
Fabien Giquel is currently offline Fabien Giquel
Messages: 138
Registered: July 2009
Senior Member
Hello,

i would like to help you but it requires more advanced ATL skill :-)
Regarding the first approach (no output model), do you have any message
in error log ? Did you make it work first with the original code (from
..uml model) ?

You may try the both approaches with some simple .uml file and simple
uml2uml transformation, and if it fails you may submit some bug or post
on ATL forum...

Fabien.


----------------------------------------------------
Fabien GIQUEL
R&D Engineer
Mia-Software
4, rue du Ch√Ęteau de l'Eraudiere
44324 NANTES CEDEX 03
----------------------------------------------------
Re: [ATL] Run Modisco .javaxmi transformation programmatically [message #663124 is a reply to message #662781] Sun, 03 April 2011 15:20 Go to previous message
Thanasis Naskos is currently offline Thanasis Naskos
Messages: 22
Registered: March 2011
Junior Member
Hi Fabien,

Actually I figure it out!
The first approach doesn't give any error message cause it's working properly!

I've changed the extract path from a relative one to an absolute and the file is generated as ti should be!!!
// Saving model
		extractor.extract(targetModel, [B]"file:///home/thanasis/workspace/runAtl/model/newModel.javaxmi"[/B]); //the name of the generated model


But I still can't understand why the second approach is not working.. anyway thanks again Fabien for your interest!!
Previous Topic:java.ecore Metamodel Type/TypeAccess
Next Topic:MoDisco 0.8 Java Code Generation
Goto Forum:
  


Current Time: Sat Aug 30 14:25:54 EDT 2014

Powered by FUDForum. Page generated in 0.07178 seconds