blob: 83d089d94150498f896e9d636a2452be03314aa4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2018 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.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.HashSet;
import java.util.List;
import java.util.Set;
import javax.tools.JavaFileObject;
import org.eclipse.core.resources.IFile;
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.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.JavaClasspath;
import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
import org.eclipse.ocl.examples.codegen.genmodel.OCLGenModelUtil;
/**
* GenModelCompilerStep activates the EMF GenModel tooling to generate the Java classes from the
* synthesized Ecore model for the middle/trace model.
*/
public class GenModelGenerateCompilerStep 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() {
for (GeneratorAdapterFactory.@NonNull Descriptor descriptor : OCLGenModelUtil.getGeneratorAdapterFactoryDescriptors()) {
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 GenModelGenerateCompilerStep(@NonNull CompilerChain compilerChain) {
super(compilerChain, QVTrCompilerChain.GENMODEL_STEP);
}
public void execute() throws IOException {
Boolean keepOldJavaFiles = compilerChain.basicGetOption(QVTrCompilerChain.GENMODEL_STEP, QVTrCompilerChain.KEEP_OLD_JAVA_FILES_KEY);
URI genmodelURI = compilerChain.getURI(QVTrCompilerChain.GENMODEL_STEP, QVTrCompilerChain.URI_KEY);
ResourceSet resourceSet = environmentFactory.getResourceSet();
Resource genmodelResource = resourceSet.getResource(genmodelURI, true);
assert genmodelResource != null;
GenModel genModel = (GenModel) genmodelResource.getContents().get(0);
URI classFileURI = compilerChain.basicGetOption(QVTrCompilerChain.CLASS_STEP, QVTrCompilerChain.URI_KEY);
@SuppressWarnings("unused")
URI traceURI = compilerChain.getURI(QVTrCompilerChain.TRACE_STEP, QVTrCompilerChain.URI_KEY);
if (classFileURI != null) {
String classFilePath = classFileURI.toFileString();
String sourceFilePathPrefix;
if (EcorePlugin.IS_ECLIPSE_RUNNING) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IFile genIFile = root.getFile(new Path(genModel.getModelDirectory()));
File genFile = URIUtil.toFile(genIFile.getLocationURI());
sourceFilePathPrefix = genFile.getAbsolutePath().replace("\\", "/");
}
else {
URI genModelDirectoryURI = URI.createPlatformResourceURI(genModel.getModelDirectory(), true);
sourceFilePathPrefix = resourceSet.getURIConverter().normalize(genModelDirectoryURI).toFileString() + "/";
}
assert classFilePath != null;
if (keepOldJavaFiles != Boolean.TRUE) {
for (GenPackage genPackage : genModel.getGenPackages()) {
String basePackage = genPackage.getBasePackage();
String sourcePath = sourceFilePathPrefix + (basePackage != null ? ("/" + basePackage.replace(".", "/")) : "") + "/" + genPackage.getEcorePackage().getName();
JavaFileUtil.deleteJavaFiles(sourcePath);
}
}
generateModels(genModel);
new File(classFilePath).mkdirs();
List<@NonNull JavaFileObject> compilationUnits = new ArrayList<@NonNull JavaFileObject>();
Set<@NonNull String> basePackages = new HashSet<>();
for (GenPackage genPackage : genModel.getGenPackages()) {
String basePackage = genPackage.getBasePackage();
basePackage = (basePackage != null ? ("/" + basePackage.replace(".", "/")) : "") + "/" + genPackage.getEcorePackage().getName();
if (basePackages.add(basePackage)) {
String sourceFilePath = sourceFilePathPrefix + basePackage;
JavaFileUtil.gatherCompilationUnits(compilationUnits, new File(sourceFilePath));
}
}
JavaClasspath classpath = compilerChain.basicGetOption(QVTrCompilerChain.CLASS_STEP, QVTrCompilerChain.CLASSPATH_KEY);
assert classpath != null;
String problemMessage = JavaFileUtil.compileClasses(compilationUnits, sourceFilePathPrefix, classFilePath, classpath);
if (problemMessage != null) {
addProblem(new CompilerChainException(problemMessage));
}
}
throwCompilerChainExceptionForErrors();
compiled(genmodelResource);
}
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);
*/
GenModelGenerateCompilerStep.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());
}
}
}
}
}