Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » M2M (model-to-model transformation) » [ATL] Run Modisco .javaxmi transformation programmatically
[ATL] Run Modisco .javaxmi transformation programmatically [message #662785] Thu, 31 March 2011 22:26 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 #663125 is a reply to message #662785] Sun, 03 April 2011 19:27 Go to previous messageGo to next message
Thanasis Naskos is currently offline Thanasis Naskos
Messages: 22
Registered: March 2011
Junior Member
I figure out what is going with the first approach!

I've changed the extract path from a relative one to an absolute and the file is generated as ti should be!!! I couldn't find the file cause I'm running the transformation as a plugin, and the file is created in a strange path!
// Saving model
		extractor.extract(targetModel, "file:///home/thanasis/workspace/runAtl/model/newModel.javaxmi"); //the name of the generated model


But I still can't understand why the second approach is not working.. any help would be appreciated!
Re: [ATL] Run Modisco .javaxmi transformation programmatically [message #717157 is a reply to message #663125] Fri, 19 August 2011 13:09 Go to previous messageGo to next message
Eszter Hofmann is currently offline Eszter Hofmann
Messages: 16
Registered: July 2011
Junior Member
Hi,
I am having the same problem, did you figure it out, what's wrong?
I have this problem only when my in and output metamodels are the same.
Re: [ATL] Run Modisco .javaxmi transformation programmatically [message #718461 is a reply to message #717157] Wed, 24 August 2011 12:14 Go to previous message
Eszter Hofmann is currently offline Eszter Hofmann
Messages: 16
Registered: July 2011
Junior Member
I found the solution sourceMetamodel and targetMetamodel must be the same instance, when the input and output metamodel is the same.
Previous Topic:eoperation in atl
Next Topic:[QVT] missing model elements
Goto Forum:
  


Current Time: Tue Sep 02 21:25:55 GMT 2014

Powered by FUDForum. Page generated in 0.01812 seconds