blob: cb2e3aab5fecc2131de109e75826b07346a4d0d5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Willink Transformations and others.
* 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:
* E.D.Willink - initial API and implementation based on MtcBroker
******************************************************************************/
package org.eclipse.qvtd.compiler;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory.Descriptor;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
import org.eclipse.ocl.examples.codegen.oclinecore.OCLinEcoreGeneratorAdapterFactory;
import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.qvtd.compiler.internal.genmodel.QVTdGenModelGeneratorAdapterFactory;
import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.QVTr2QVTc;
import org.eclipse.qvtd.compiler.internal.utilities.JavaSourceFileObject;
/**
* GenModelCompilerStep activates the EMG GenModel tooling to generate the Java classes from the
* synthesized Ecore model for the middle/trace model.
*/
public class GenModelCompilerStep extends AbstractCompilerStep
{
private static final class Generator extends org.eclipse.emf.codegen.ecore.generator.Generator
{
private final @NonNull Collection<GeneratorAdapterFactory> adapterFactories = new ArrayList<>();
public Generator() {
// Replacement for EMF to fix BUG 485764, BUG 485089
addAdapterFactoryDescriptor(QVTdGenModelGeneratorAdapterFactory.DESCRIPTOR);
// OCLinEcore embedded support
addAdapterFactoryDescriptor(OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR);
}
private void addAdapterFactoryDescriptor(Descriptor descriptor) {
GeneratorAdapterFactory adapterFactory = descriptor.createAdapterFactory();
adapterFactories.add(adapterFactory);
adapterFactory.setGenerator(this);
}
@Override
protected Collection<GeneratorAdapterFactory> getAdapterFactories( Object object) {
return adapterFactories;
}
}
private static class Issues
{
public void addError(@NonNull CompilerChain compilerChain, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.err.println(message);
}
public void addWarning(@NonNull CompilerChain compilerChain, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.out.println(message);
}
public void addError(@NonNull CompilerChain compilerChain, String string) {
System.err.println(string);
}
public void addWarning(@NonNull CompilerChain compilerChain, String string) {
System.out.println(string);
}
}
public GenModelCompilerStep(@NonNull CompilerChain compilerChain) {
super(compilerChain, QVTrCompilerChain.GENMODEL_STEP);
}
public void execute() throws IOException {
URI genmodelURI = compilerChain.getURI(QVTrCompilerChain.GENMODEL_STEP, QVTrCompilerChain.URI_KEY);
URI qvtcURI = compilerChain.getURI(QVTrCompilerChain.QVTC_STEP, QVTrCompilerChain.URI_KEY);
Resource cResource = environmentFactory.getMetamodelManager().getASResourceSet().getResource(qvtcURI, true);
assert cResource != null;
Resource gResource = environmentFactory.getResourceSet().getResource(genmodelURI, true);
assert gResource != null;
GenModel genModel = (GenModel) gResource.getContents().get(0);
URI classURI = compilerChain.getOption(QVTrCompilerChain.CLASS_STEP, QVTrCompilerChain.URI_KEY);
URI traceURI = compilerChain.getURI(QVTrCompilerChain.TRACE_STEP, QVTrCompilerChain.URI_KEY);
if (classURI != null) {
String binProjectName = QVTr2QVTc.getProjectName(traceURI);
File binFile;
String objectPath;
String sourcePathPrefix;
List<@NonNull String> classpathProjects;
if (EcorePlugin.IS_ECLIPSE_RUNNING) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject binProject = root.getProject(binProjectName);
IFolder binFolder = binProject.getFolder("bin");
binFile = URIUtil.toFile(binFolder.getLocationURI());
objectPath = binFile.toString()/*.replace(".", "/")*/.replace("\\", "/"); // FIXME deduce/parameterize bin
IFile genIFile = root.getFile(new Path(genModel.getModelDirectory()));
File genFile = URIUtil.toFile(genIFile.getLocationURI());
sourcePathPrefix = genFile.getAbsolutePath().replace("\\", "/");
classpathProjects = JavaSourceFileObject.createClasspathProjectList(binProjectName, "org.eclipse.emf.common", "org.eclipse.emf.ecore", "org.eclipse.jdt.annotation", "org.eclipse.ocl.pivot", "org.eclipse.osgi", "org.eclipse.qvtd.runtime");
}
else {
ResourceSet resourceSet = environmentFactory.getResourceSet();
URI normalizedClassURI = resourceSet.getURIConverter().normalize(classURI);
objectPath = normalizedClassURI.toFileString();
URI location = ClassUtil.nonNullState(((StandaloneProjectMap)environmentFactory.getProjectManager()).getLocation(binProjectName));
binFile = new File(location.appendSegment("bin").toFileString());
URI genModelDirectoryURI = URI.createPlatformResourceURI(genModel.getModelDirectory(), true);
sourcePathPrefix = resourceSet.getURIConverter().normalize(genModelDirectoryURI).toFileString() + "/";
classpathProjects = null;
}
assert objectPath != null;
for (GenPackage genPackage : genModel.getGenPackages()) {
String basePackage = genPackage.getBasePackage();
String sourcePath = sourcePathPrefix + (basePackage != null ? ("/" + basePackage.replace(".", "/")) : "");
JavaFileUtil.deleteJavaFiles(sourcePath);
}
generateModels(genModel);
binFile.mkdir();
for (GenPackage genPackage : genModel.getGenPackages()) {
String basePackage = genPackage.getBasePackage();
String sourcePath = sourcePathPrefix + (basePackage != null ? ("/" + basePackage.replace(".", "/")) : "");
JavaSourceFileObject.compileClasses(sourcePath, objectPath, classpathProjects);
}
}
compiled(cResource);
}
protected void generateModels(@NonNull GenModel genModel) {
environmentFactory.getMetamodelManager().addGenModel(genModel);
//** ResourceUtils.checkResourceSet(resourceSet);
// genModel.setCanGenerate(true);
// validate();
genModel.setValidateModel(true); // The more checks the better
// genModel.setCodeFormatting(true); // Normalize layout
genModel.setForceOverwrite(false); // Don't overwrite read-only
// files
genModel.setCanGenerate(true);
// genModel.setFacadeHelperClass(null); // Non-null gives JDT
// default NPEs
// genModel.setFacadeHelperClass(ASTFacadeHelper.class.getName()); // Bug 308069
// genModel.setValidateModel(true);
// genModel.setBundleManifest(false); // New manifests should be
// // generated manually
// genModel.setUpdateClasspath(false); // New class-paths should be
// // generated manually
// if (genModel.getComplianceLevel().compareTo(GenJDKLevel.JDK50_LITERAL) < 0) {
// genModel.setComplianceLevel(GenJDKLevel.JDK50_LITERAL);
// }
// genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container");
Diagnostic diagnostic = genModel.diagnose();
assert diagnostic != null;
reportDiagnostics(new Issues(), diagnostic);
/*
* JavaModelManager.getJavaModelManager().initializePreferences();
* new
* JavaCorePreferenceInitializer().initializeDefaultPreferences();
*
* GenJDKLevel genSDKcomplianceLevel =
* genModel.getComplianceLevel(); String complianceLevel =
* JavaCore.VERSION_1_5; switch (genSDKcomplianceLevel) { case
* JDK60_LITERAL: complianceLevel = JavaCore.VERSION_1_6; case
* JDK14_LITERAL: complianceLevel = JavaCore.VERSION_1_4; default:
* complianceLevel = JavaCore.VERSION_1_5; } // Hashtable<?,?>
* defaultOptions = JavaCore.getDefaultOptions(); //
* JavaCore.setComplianceOptions(complianceLevel, defaultOptions);
* // JavaCore.setOptions(defaultOptions);
*/
GenModelCompilerStep.Generator generator = new Generator();
generator.setInput(genModel);
Monitor monitor = /*showProgress ? new LoggerMonitor(log) :*/ new BasicMonitor();
diagnostic = generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, monitor);
assert diagnostic != null;
reportDiagnostics(new Issues(), diagnostic);
}
protected void reportDiagnostics(@NonNull Issues issues, @NonNull Diagnostic diagnostic) {
int severity = diagnostic.getSeverity();
if (severity != Diagnostic.OK) {
List<Diagnostic> children = diagnostic.getChildren();
if (children.size() > 0) {
for (Diagnostic child : children) {
severity = child.getSeverity();
@SuppressWarnings("unchecked") List<Object> data = (List<Object>) child.getData();
Throwable throwable = null;
String message;
if ((data.size() == 1) && (data.get(0) instanceof Throwable)) {
throwable = (Throwable) data.get(0);
data = null;
message = child.getMessage();
}
else {
message = child.toString();
}
if (severity == Diagnostic.ERROR) {
issues.addError(compilerChain, message, null, null, throwable, data);
}
else if (severity == Diagnostic.WARNING) {
issues.addWarning(compilerChain, message, null, null, throwable, data);
}
}
}
else {
if (severity == Diagnostic.ERROR) {
issues.addError(compilerChain, diagnostic.toString());
}
else if (severity == Diagnostic.WARNING) {
issues.addWarning(compilerChain, diagnostic.toString());
}
}
}
}
}