blob: c0a1cd8e75f05d248cecfb4391d8c4721d4d169f [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2011 Nicolas Deblock & Manuel Giles.
*
*
* 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:
* Nicolas Deblock nico.deblock@gmail.com - Initial API and implementation
* Manuel Giles giles.manu@live.fr - Initial API and implementation
* Cedric Dumoulin Cedric.dumoulin@lifl.fr - Idea of the java generator project & help for the conception
*
*****************************************************************************/
package org.eclipse.papyrus.designer.languages.java.generator.jdtsynchronizer;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.m2m.qvt.oml.BasicModelExtent;
import org.eclipse.m2m.qvt.oml.ExecutionContextImpl;
import org.eclipse.m2m.qvt.oml.ExecutionDiagnostic;
import org.eclipse.m2m.qvt.oml.ModelExtent;
import org.eclipse.m2m.qvt.oml.TransformationExecutor;
import org.eclipse.papyrus.designer.languages.java.generator.jdtsynchronizer.impl.SynchJDTJavaModel;
import org.eclipse.papyrus.designer.languages.java.generator.transfo.umltojdt.UmltojdtActivator;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.generatoroptionsmm.GeneratoroptionsmmFactory;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.generatoroptionsmm.Options;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTJavaElement;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTJavaModel;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JdtmmPackage;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.visitor.JDTVisitor;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.visitor.JDTVisitorException;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
/**
* Class to Run the QVT Transformation, and then the Java generation
*/
public class RunGenerator {
/**
* This is the metamodele
*/
private EList<EObject> inObjects;
/**
* Constructor of RunGenerator using .uml file
*
* @param UMLFileUrl
* the '.uml' file's url
* @throws FileNotFoundException
*/
public RunGenerator(String umlFileUrl) throws FileNotFoundException {
// charge the model of the '.uml' file
inObjects = loadUmlModel(umlFileUrl);
}
/**
* Constructor of RunGenerator using EList<EObject> metamodel
*
* @param UMLFileUrl
* the '.uml' file's url
*/
public RunGenerator(EList<EObject> inObjects) {
this.inObjects = inObjects;
}
/**
* run code generation using QVTo transformation
*
* @throws JDTVisitorException
*/
public void runGeneration(GeneratorPreference preference) throws JDTVisitorException {
// Create an options model using the Eclipse Preferences
EList<EObject> inOptions = createOptionModelFromEclipsePreferences(preference);
// Refer to an existing transformation via URI
final URI scriptUri =
URI.createURI("platform:/plugin/" + UmltojdtActivator.PLUGIN_ID + UmltojdtActivator.PATH_QVT_FILE);
List<EObject> outObjects = runTransformation(scriptUri, inObjects, inOptions);
if (outObjects.size() == 0) {
throw new JDTVisitorException("No classes or packages produced from the transformation. Nothing is generated.");
}
if (outObjects.size() > 1) {
System.err.println("Warning, JDT modele has more than one root. Found root:");
for (EObject el : outObjects) {
System.err.println(((JDTJavaElement) el).getElementName());
}
System.err.println("-------");
}
// finally, we synchronize the JDT model with org.eclipse.jdt.core
if (outObjects.size() > 0) {
/*
* TODO : if metamodel have some root node, we make a loop
* JDTJavaElement proj = (JDTJavaElement) outObjects.get(0);
*
* JDTVisitor visitor = new SynchJDTJavaModel();
* proj.accept(visitor);
*/
for (Object o : outObjects) {
if (o instanceof JDTJavaModel) {
JDTJavaElement proj = (JDTJavaElement) o;
JDTVisitor visitor = new SynchJDTJavaModel(preference);
proj.accept(visitor);
}
}
}
}
/**
* Create a new GeneratorOptions model and inject eclipse preferences on it.
*
* @param preference
* eclipse preferences
* @return a new instance of Options, where options.defaultSourceFolder have been initialized.
*/
private EList<EObject> createOptionModelFromEclipsePreferences(GeneratorPreference preference) {
GeneratoroptionsmmFactory optionsFactory = GeneratoroptionsmmFactory.eINSTANCE;
// Create a new Options object and inject the default source folder name from Eclipse preferences
Options options = optionsFactory.createOptions();
options.setDefaultSourceFolder(preference.defaultSourceFolderName());
// Add options to the model
EList<EObject> optionsContents = new BasicEList<EObject>(1);
optionsContents.add(options);
return optionsContents;
}
/**
* Run QVTo transformation using the scriptUri and the inObjects model
*
* @param scriptUri
* The script QVTo
* @param inObjects
* The entry model
* @param inOptions2
* @return The output model
*/
private List<EObject> runTransformation(URI scriptUri, EList<EObject> inObjects, EList<EObject> inOptions) {
// initialize the transformation
// First, you need to instantiate a Registry:
EPackage.Registry registry = new EPackageRegistryImpl(EPackage.Registry.INSTANCE);
// which is used to register the meta-models in E:\workspace\modelesUML\org.eclipse.papyrus.designer.languages.java.javagen.mmJDT\metaModel
JdtmmPackage mm1 = JdtmmPackage.eINSTANCE;
registry.put(mm1.getNsURI(), mm1);
// class which allow to execute the transformation
TransformationExecutor t = new TransformationExecutor(scriptUri, registry);
ExecutionContextImpl executionContext = new ExecutionContextImpl();
// allow to contains the model uml
ModelExtent input = new BasicModelExtent(inObjects);
ModelExtent inputOptions = new BasicModelExtent(inOptions);
ModelExtent output = new BasicModelExtent();
// make the transformation
ExecutionDiagnostic executionDiagnostic = t.execute(executionContext, input, inputOptions, output);
// the errors
System.out.println(executionDiagnostic.getMessage());
for (Diagnostic d : executionDiagnostic.getChildren()) {
System.out.println(d.getMessage());
}
// we take the out JDT model in a list
return output.getContents();
}
/**
* Allow to charge the uml model in a list
*
* @param url
* the '.uml' file's url
* @return the charge model
* @throws FileNotFoundException
*/
private EList<EObject> loadUmlModel(String url) throws FileNotFoundException {
ResourceSet resourceSet = new ResourceSetImpl();
// charge the metamodel util for read the model
resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
// Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put( "uml", new UMLResourceFactoryImpl());
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl());
URIConverter.URI_MAP.put(URI.createURI("pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml"), URI.createFileURI(System.getProperty("user.dir") + "/Model_Libs/UMLPrimitiveTypes.library.uml"));
// the '.uml' file's url
File file = new File(url);
if (!file.exists()) {
throw new FileNotFoundException("File " + new File(url).getAbsolutePath() + " not found");
}
URI fileURI = URI.createFileURI(new File(url).getAbsolutePath());
// demand load the resource for this file.
Resource resource = resourceSet.getResource(fileURI, true);
return resource.getContents();
}
}