Skip to content

Commit

Permalink
Fixed Java launcher generators.
Browse files Browse the repository at this point in the history
- constructor name
- required bundles
- export packages
  • Loading branch information
ylussaud committed Apr 26, 2024
1 parent 50fa05c commit 0160a95
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 14 deletions.
3 changes: 2 additions & 1 deletion plugins/org.eclipse.acceleo.aql.ide.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.ecore.editor,
org.eclipse.acceleo.query.ide.ui,
org.eclipse.core.expressions,
org.eclipse.ui.editors
org.eclipse.ui.editors,
org.eclipse.pde.core
Automatic-Module-Name: org.eclipse.acceleo.aql.ide.ui
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
* the selected {@link [module.getReceiverClassName()/]}
* @generated
*/
public MainGeneratorEclipse([module.getReceiverClassName()/] selected) {
public [module.getEclipseClassName()/]([module.getReceiverClassName()/] selected) {
super(Collections.emptyList(), getTarget(selected));
this.value = Collections.singletonList(selected);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,24 @@
[protected ('imports') startTagPrefix('//') endTagPrefix('//')]

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.OpenModeKind;
import org.eclipse.acceleo.Template;
import org.eclipse.acceleo.aql.AcceleoUtil;
import org.eclipse.acceleo.aql.evaluation.AcceleoEvaluator;
import org.eclipse.acceleo.aql.evaluation.GenerationResult;
import org.eclipse.acceleo.aql.evaluation.strategy.DefaultGenerationStrategy;
import org.eclipse.acceleo.aql.evaluation.strategy.DefaultWriterFactory;
import org.eclipse.acceleo.aql.evaluation.strategy.IAcceleoGenerationStrategy;
import org.eclipse.acceleo.aql.evaluation.writer.IAcceleoWriter;
import org.eclipse.acceleo.aql.parser.AcceleoParser;
import org.eclipse.acceleo.aql.parser.ModuleLoader;
import org.eclipse.acceleo.query.AQLUtils;
Expand Down Expand Up @@ -95,7 +99,7 @@
* the target folder for the generation
* @generated
*/
public MainGenerator(List<String> resources, String target) {
public [module.getClassName()/](List<String> resources, String target) {
this.resources = resources;
this.target = target;
}
Expand Down Expand Up @@ -215,7 +219,7 @@
* @generated
*/
protected List<Template> getTemplates(Module module) {
return AcceleoUtil.getMainTemplate(module);
return AcceleoUtil.getMainTemplates(module);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.acceleo.aql.ide.ui.module.main;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringJoiner;

import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.Template;
import org.eclipse.acceleo.Variable;
import org.eclipse.acceleo.aql.AcceleoUtil;
import org.eclipse.acceleo.query.parser.AstValidator;
import org.eclipse.acceleo.query.runtime.IValidationResult;
import org.eclipse.acceleo.query.runtime.impl.ValidationServices;
import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameQueryEnvironment;
import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.internal.core.ibundle.IBundle;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;
import org.osgi.framework.Constants;

public abstract class AbstractGenerator {

/**
* Gets the Set of dependency bundle names.
*
* @param queryEnvironment
* @return the Set of dependency bundle names
*/
protected Set<String> getDependencyBundleNames(final IQualifiedNameQueryEnvironment queryEnvironment,
Module module) {
final Set<String> res = new LinkedHashSet<>();

final AstValidator validator = new AstValidator(new ValidationServices(queryEnvironment));
for (Template main : AcceleoUtil.getMainTemplates(module)) {
for (Variable parameter : main.getParameters()) {
final IValidationResult validationResult = validator.validate(Collections.emptyMap(),
parameter.getType());
for (IType iType : validator.getDeclarationTypes(queryEnvironment, validationResult
.getPossibleTypes(parameter.getType().getAst()))) {
final Object type = iType.getType();
final Class<?> cls;
if (type instanceof Class<?>) {
cls = (Class<?>)type;
} else if (type instanceof EClassifier && ((EClassifier)type)
.getInstanceClass() != null) {
cls = ((EClassifier)type).getInstanceClass();
} else {
cls = null;
}
if (cls != null) {
if (cls.getClassLoader() instanceof BundleReference) {
final Bundle bundle = ((BundleReference)cls.getClassLoader()).getBundle();
res.add(bundle.getSymbolicName());
}
}
}
}
}

return res;
}

/**
* Adds needed plugin dependencies to the given {@link IProject}.
*
* @param project
* the {@link IProject}
* @param dependencyBundleNames
* the {@link Set} of dependency bundle names
*/
@SuppressWarnings("restriction")
protected void addPluginDependencies(IProject project, Set<String> dependencyBundleNames) {
final IPluginModelBase model = PluginRegistry.findModel(project);
if (model instanceof IBundlePluginModelBase) {
final IBundle bundle = ((IBundlePluginModelBase)model).getBundleModel().getBundle();
final IManifestHeader manifestHeader = bundle.getManifestHeader(Constants.REQUIRE_BUNDLE);
final String requiredBundleString;
if (manifestHeader != null) {
requiredBundleString = manifestHeader.getValue();
} else {
requiredBundleString = null;
}
if (requiredBundleString == null) {
final StringJoiner joiner = new StringJoiner(",\n ");
for (String dependency : dependencyBundleNames) {
joiner.add(dependency);
}
bundle.setHeader(Constants.REQUIRE_BUNDLE, joiner.toString());
} else {
final StringJoiner joiner = new StringJoiner(",\n ");
joiner.add(requiredBundleString);
for (String dependency : dependencyBundleNames) {
boolean foundInRequirement = false;
for (String requirement : requiredBundleString.split(",")) {
if (requirement.contains(dependency)) {
foundInRequirement = true;
break;
}
}
if (!foundInRequirement) {
joiner.add(dependency);
}
bundle.setHeader(Constants.REQUIRE_BUNDLE, joiner.toString());
}
}

((IBundlePluginModelBase)model).save();
}
}

/**
* Adds needed plugin dependencies to the given {@link IProject}.
*
* @param project
* the {@link IProject}
* @param packages
* the {@link Set} of package names
*/
@SuppressWarnings("restriction")
protected void addexportPackages(IProject project, Set<String> packages) {
final IPluginModelBase model = PluginRegistry.findModel(project);
if (model instanceof IBundlePluginModelBase) {
final IBundle bundle = ((IBundlePluginModelBase)model).getBundleModel().getBundle();
final IManifestHeader manifestHeader = bundle.getManifestHeader(Constants.EXPORT_PACKAGE);
final String exportedPackageString;
if (manifestHeader != null) {
exportedPackageString = manifestHeader.getValue();
} else {
exportedPackageString = null;
}
if (exportedPackageString == null) {
final StringJoiner joiner = new StringJoiner(",\n ");
for (String dependency : packages) {
joiner.add(dependency);
}
bundle.setHeader(Constants.EXPORT_PACKAGE, joiner.toString());
} else {
final StringJoiner joiner = new StringJoiner(",\n ");
joiner.add(exportedPackageString);
for (String dependency : packages) {
boolean foundInExportedPacakges = false;
for (String requirement : exportedPackageString.split(",")) {
if (requirement.contains(dependency)) {
foundInExportedPacakges = true;
break;
}
}
if (!foundInExportedPacakges) {
joiner.add(dependency);
}
bundle.setHeader(Constants.EXPORT_PACKAGE, joiner.toString());
}
}

((IBundlePluginModelBase)model).save();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.Template;
Expand Down Expand Up @@ -55,7 +57,7 @@
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
public class EclipseUIProjectGenerator {
public class EclipseUIProjectGenerator extends AbstractGenerator {

/**
* The {@link List} of module {@link IFile} for the {@link IProject}.
Expand All @@ -72,6 +74,11 @@ public class EclipseUIProjectGenerator {
*/
private final String destinationFolder;

/**
* The {@link Set} of model {@link Module} parameter bundle dependencies.
*/
protected Set<String> dependencyBundleNames;

/**
* Constructor.
*
Expand Down Expand Up @@ -122,21 +129,23 @@ public void generate() {
final IAcceleoGenerationStrategy strategy = createGenerationStrategy(resourceSetForModels);

final Module module = (Module)resolver.resolve(moduleQualifiedName);
final Template main = AcceleoUtil.getMainTemplate(module).iterator().next();
final Template main = AcceleoUtil.getMainTemplates(module).iterator().next();
final URI logURI = AcceleoUtil.getlogURI(targetURI, options.get(AcceleoUtil.LOG_URI_OPTION));

final IQualifiedNameResolver workspaceResolver = QueryPlugin.getPlugin().createQualifiedNameResolver(
getClass().getClassLoader(), projectModuleFiles.get(0).getProject(),
AcceleoParser.QUALIFIER_SEPARATOR, true);

final List<Module> modelModules = new ArrayList<>();
dependencyBundleNames = new LinkedHashSet<>();
for (IFile file : projectModuleFiles) {
final java.net.URI binaryURI = workspaceResolver.getBinaryURI(file.getLocation().toFile()
.toURI());
workspaceResolver.addLoader(new ModuleLoader(new AcceleoParser(), null));
final String modelModuleQualifiedName = workspaceResolver.getQualifiedName(binaryURI);
final Module modelModule = (Module)workspaceResolver.resolve(modelModuleQualifiedName);
modelModules.add(modelModule);
dependencyBundleNames.addAll(getDependencyBundleNames(queryEnvironment, modelModule));
}

synchronized(this) {
Expand Down Expand Up @@ -314,14 +323,15 @@ protected void afterGeneration(GenerationResult generationResult) {
}
}
} else {
final String projectUIAbsolutePath = destinationFolder + File.pathSeparator + projectUIName;
final String projectUIAbsolutePath = destinationFolder + File.separatorChar + projectUIName;
try {
final String projectFilePath = projectUIAbsolutePath + File.pathSeparator + ".project";
final String projectFilePath = projectUIAbsolutePath + File.separatorChar + ".project";
final IProjectDescription description = ResourcesPlugin.getWorkspace().loadProjectDescription(
new Path(projectFilePath));
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
project.create(description, null);
project.open(null);
addPluginDependencies(project, dependencyBundleNames);
} catch (CoreException e) {
Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
"couldn't import project " + projectUIAbsolutePath, e));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.aql.AcceleoUtil;
Expand Down Expand Up @@ -49,13 +52,28 @@
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
public class StandaloneGenerator {
public class StandaloneGenerator extends AbstractGenerator {

/**
* The main {@link Module} {@link IFile}.
*/
private final IFile moduleFile;

/**
* The model {@link Module} qualified name.
*/
protected String modelModuleQualifiedName;

/**
* The model {@link Module}.
*/
protected Module modelModule;

/**
* The {@link Set} of model {@link Module} parameter bundle dependencies.
*/
protected Set<String> dependencyBundleNames;

/**
* Constructor.
*
Expand Down Expand Up @@ -111,8 +129,12 @@ public void generate() {
final java.net.URI binaryURI = workspaceResolver.getBinaryURI(moduleFile.getLocation().toFile()
.toURI());
workspaceResolver.addLoader(new ModuleLoader(new AcceleoParser(), null));
final String modelModuleQualifiedName = workspaceResolver.getQualifiedName(binaryURI);
final Module modelModule = (Module)workspaceResolver.resolve(modelModuleQualifiedName);
modelModuleQualifiedName = workspaceResolver.getQualifiedName(binaryURI);
modelModule = (Module)workspaceResolver.resolve(modelModuleQualifiedName);
dependencyBundleNames = new LinkedHashSet<>();
dependencyBundleNames.add("org.eclipse.acceleo.query");
dependencyBundleNames.add("org.eclipse.acceleo.aql");
dependencyBundleNames.addAll(getDependencyBundleNames(queryEnvironment, modelModule));

synchronized(this) {
beforeGeneration(queryEnvironment, workspaceResolver);
Expand Down Expand Up @@ -275,6 +297,11 @@ protected void afterGeneration(GenerationResult generationResult) {
Services.initialize(null, null);
try {
moduleFile.getParent().refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
addPluginDependencies(moduleFile.getProject(), dependencyBundleNames);
final String packageName = new Services().getJavaPackage(modelModule);
if (!packageName.isEmpty()) {
addexportPackages(moduleFile.getProject(), Collections.singleton(packageName));
}
} catch (CoreException e) {
Activator.getDefault().getLog().log(new Status(IStatus.ERROR, getClass(), "could not refresh "
+ moduleFile.getParent().getFullPath(), e));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public Set<EPackage> getAllEPackages(Module module) {
public String getReceiverQualifiedClassName(Module module) {
final String res;

final List<Template> mains = AcceleoUtil.getMainTemplate(module);
final List<Template> mains = AcceleoUtil.getMainTemplates(module);
if (!mains.isEmpty()) {
final Template main = mains.get(0);
if (!main.getParameters().isEmpty()) {
Expand Down
Loading

0 comments on commit 0160a95

Please sign in to comment.