blob: a931ab5cda121e375a844922eb78b84b0bdcb473 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.acceleo.aql;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.acceleo.AcceleoPackage;
import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.ModuleElement;
import org.eclipse.acceleo.Template;
import org.eclipse.acceleo.aql.evaluation.AcceleoEvaluator;
import org.eclipse.acceleo.query.ast.TypeLiteral;
import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
import org.eclipse.acceleo.query.services.EObjectServices;
import org.eclipse.acceleo.util.AcceleoSwitch;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
/**
* Utility class for Acceleo.
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
public final class AcceleoUtil {
/**
* Constructor.
*/
private AcceleoUtil() {
// utility class can't be instantiated
}
/**
* Gets the {@link Template#isMain() main} {@link Template} of the given {@link Module}.
*
* @param module
* the {@link Module}
* @return the {@link Template#isMain() main} {@link Template} of the given {@link Module} if any,
* <code>null</code> otherwise
*/
public static Template getMainTemplate(Module module) {
Template res = null;
for (ModuleElement moduleElement : module.getModuleElements()) {
if (moduleElement instanceof Template && ((Template)moduleElement).isMain()) {
res = (Template)moduleElement;
break;
}
}
return res;
}
/**
* Generates with the given {@link AcceleoEvaluator} and {@link IAcceleoEnvironment}.
*
* @param evaluator
* the {@link AcceleoEvaluator}
* @param acceleoEnvironment
* the {@link IAcceleoEnvironment}
* @param module
* the {@link Module}
* @param model
* the {@link Resource} containing the model
*/
public static void generate(AcceleoEvaluator evaluator, IAcceleoEnvironment acceleoEnvironment,
Module module, Resource model) {
final IQueryEnvironment queryEnvironment = acceleoEnvironment.getQueryEnvironment();
final EObjectServices services = new EObjectServices(queryEnvironment, null, null);
final Template main = getMainTemplate(module);
// TODO more than one parameter is allowed ?
// TODO not EClass type ?
// TODO more than one EClass type ?
final String parameterName = main.getParameters().get(0).getName();
// TODO use IType ?
final EClass parameterType = (EClass)((TypeLiteral)main.getParameters().get(0).getType().getAst())
.getValue();
final List<EObject> values = new ArrayList<EObject>();
for (EObject root : model.getContents()) {
if (parameterType.isInstance(root)) {
values.add(root);
}
values.addAll(services.eAllContents(root, parameterType));
}
final Map<String, Object> variables = new HashMap<String, Object>();
for (EObject value : values) {
variables.put(parameterName, value);
evaluator.generate(module, variables);
}
}
/**
* Provides the concrete Acceleo {@link EClass EClasses} that are, inherit or extend the given Acceleo
* {@link EClass}. This is useful to use an {@link AcceleoSwitch} on non-instantiable EClasses.
*
* @param superType
* the (non-{@code null}) {@link AcceleoPackage Acceleo} {@link EClass}.
* @return the {@link List} of concrete (i.e. both {@link EClass#isInterface()} and
* {@link EClass#isAbstract()} return {@code false}) {@link EClass EClasses} from
* {@link AcceleoPackage} that are, inherit, or extend, the given Acceleo {@link EClass}.
*/
public static List<EClass> getConcreteAcceleoTypesInheriting(EClass superType) {
if (!superType.getEPackage().equals(AcceleoPackage.eINSTANCE)) {
throw new IllegalArgumentException(
"This can only be used for EClasses from the Acceleo EPackage. " + superType
+ " is from EPackage " + superType.getEPackage() + ".");
}
List<EClass> eClasses = new ArrayList<>();
if (!superType.isAbstract() && !superType.isInterface()) {
eClasses.add(superType);
}
List<EClass> allAcceleoConcreteEClasses = AcceleoPackage.eINSTANCE.getEClassifiers().stream().filter(
EClass.class::isInstance).map(EClass.class::cast).filter(eClass -> !eClass.isInterface()
&& !eClass.isAbstract()).collect(Collectors.toList());
List<EClass> acceleoConcreteSubTypes = allAcceleoConcreteEClasses.stream().filter(eClass -> eClass
.getESuperTypes().contains(superType)).collect(Collectors.toList());
eClasses.addAll(acceleoConcreteSubTypes);
return eClasses;
}
}