diff --git a/plugins/org.eclipse.emf.ecoretools.ale/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.ecoretools.ale/META-INF/MANIFEST.MF index 1493ab052..0b12afef3 100644 --- a/plugins/org.eclipse.emf.ecoretools.ale/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.ecoretools.ale/META-INF/MANIFEST.MF @@ -10,5 +10,7 @@ Require-Bundle: org.eclipse.acceleo.query, org.eclipse.emf.ecore.xmi, org.eclipse.emf.ecoretools.ale.core, org.eclipse.sirius.common, - org.eclipse.core.resources + org.eclipse.core.resources, + com.google.guava;bundle-version="21.0.0", + org.eclipse.osgi Bundle-Vendor: Inria/Obeo diff --git a/plugins/org.eclipse.emf.ecoretools.ale/plugin.properties b/plugins/org.eclipse.emf.ecoretools.ale/plugin.properties new file mode 100644 index 000000000..6565e57df --- /dev/null +++ b/plugins/org.eclipse.emf.ecoretools.ale/plugin.properties @@ -0,0 +1,18 @@ +# ==================================================================== +# Copyright (c) 2019 Inria, Obeo +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Obeo - initial API and implementation +# ==================================================================== + +ALEInterpreter_errorWithExpression= An error has appeared during the evaluation of an expression:\n\ +Expression: {0}\n\ +Diagnostic: {1}\n\ +Target URI Fragment: {2}\n\ +Target: {3}\n\ \ No newline at end of file diff --git a/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/ALEDynamicExpressionEvaluator.java b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/ALEDynamicExpressionEvaluator.java new file mode 100644 index 000000000..78a9d8c02 --- /dev/null +++ b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/ALEDynamicExpressionEvaluator.java @@ -0,0 +1,196 @@ +package org.eclipse.emf.ecoretools.ale; + +import java.text.MessageFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.acceleo.query.runtime.EvaluationResult; +import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine; +import org.eclipse.acceleo.query.runtime.IQueryEnvironment; +import org.eclipse.acceleo.query.runtime.IQueryEvaluationEngine; +import org.eclipse.acceleo.query.runtime.QueryEvaluation; +import org.eclipse.acceleo.query.runtime.QueryParsing; +import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult; +import org.eclipse.emf.common.util.BasicDiagnostic; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecoretools.ale.ALEInterpreter; +import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException; +import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterWithDiagnostic.IEvaluationResult; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + + +/** + * This class offers services similar to AQLSiriusInterpreter but without the registration to the workspace listener + * If offers the possibility to parse and evaluate string expressions and return various kinds of objects + * It relies on the queryEnvironment of an existing ALEInterpreter. (ie. this is the responsibility of this ALEInterpreter + * to clean/dispose the query environment when not use anymore) + */ +public class ALEDynamicExpressionEvaluator { + + ALEInterpreter aleInterpreter; + + public ALEDynamicExpressionEvaluator(ALEInterpreter aleInterpreter) { + super(); + this.aleInterpreter = aleInterpreter; + } + + public IEvaluationResult evaluateExpression(final EObject target, final String fullExpression) + throws EvaluationException { + // this.javaExtensions.reloadIfNeeded(); + String expression = fullExpression.replaceFirst("ale:", ""); + Map variables = new HashMap<>(); + variables.put("self", target); //$NON-NLS-1$ + + IQueryEnvironment queryEnv = aleInterpreter.getQueryEnvironment(); + if (queryEnv != null) { + final IQueryBuilderEngine builder = QueryParsing.newBuilder(queryEnv); + AstResult build = builder.build(expression); + IQueryEvaluationEngine evaluationEngine = QueryEvaluation.newEngine(queryEnv); + final EvaluationResult evalResult = evaluationEngine.eval(build, variables); + + final BasicDiagnostic diagnostic = new BasicDiagnostic(); + if (Diagnostic.OK != build.getDiagnostic().getSeverity()) { + diagnostic.merge(build.getDiagnostic()); + } + if (Diagnostic.OK != evalResult.getDiagnostic().getSeverity()) { + diagnostic.merge(evalResult.getDiagnostic()); + } + + return new IEvaluationResult() { + + @Override + public Object getValue() { + return evalResult.getResult(); + } + + @Override + public Diagnostic getDiagnostic() { + List children = diagnostic.getChildren(); + if (children.size() == 1) { + return children.get(0); + } else { + return diagnostic; + } + } + }; + } + return new IEvaluationResult() { + @Override + public Object getValue() { + return null; + } + + @Override + public Diagnostic getDiagnostic() { + return new BasicDiagnostic(); + } + + }; + + + } + + + public Object evaluate(EObject target, String fullExpression) throws EvaluationException { + IEvaluationResult evaluationResult = this.evaluateExpression(target, fullExpression); + // We fire the exception to keep the old behavior + Diagnostic diagnostic = evaluationResult.getDiagnostic(); + if (diagnostic.getSeverity() == Diagnostic.ERROR) { + String uri = EcoreUtil.getURI(target).toString(); + String message = MessageFormat.format(Messages.ALEInterpreter_errorWithExpression, fullExpression, diagnostic.toString(), uri, target); + throw new EvaluationException(message, diagnostic.getException()); + } + return evaluationResult.getValue(); + } + + /** + * {@inheritDoc} + */ + public Collection evaluateCollection(EObject context, String expression) throws EvaluationException { + Object raw = evaluate(context, expression); + final Collection result; + if (raw instanceof Collection) { + result = Lists.newArrayList(Iterables.filter((Collection) raw, EObject.class)); + } else if (raw instanceof EObject) { + result = Collections.singleton((EObject) raw); + } else if (raw != null && raw.getClass().isArray()) { + result = Lists.newArrayList(Iterables.filter(Lists.newArrayList((Object[]) raw), EObject.class)); + } else { + result = Collections.emptySet(); + } + return result; + } + + /** + * {@inheritDoc} + */ + public boolean evaluateBoolean(EObject context, String expression) throws EvaluationException { + Object raw = evaluate(context, expression); + final boolean result; + if (raw == null) { + result = false; + } else if (raw instanceof Boolean) { + result = ((Boolean) raw).booleanValue(); + } else { + String toString = raw.toString(); + if ("true".equalsIgnoreCase(toString)) { //$NON-NLS-1$ + result = true; + } else if ("false".equalsIgnoreCase(toString)) { //$NON-NLS-1$ + result = false; + } else { + /* + * raw is != null and its toString is neither true or false, + * this happens when the user expect the condition to check that + * a value is existing, then we consider any non null value + * returns true and null returns false. + */ + result = true; + } + } + return result; + } + + /** + * {@inheritDoc} + */ + public EObject evaluateEObject(EObject context, String expression) throws EvaluationException { + Object raw = evaluate(context, expression); + if (raw instanceof EObject) { + return (EObject) raw; + } else { + return null; + } + } + + /** + * {@inheritDoc} + */ + public String evaluateString(EObject context, String expression) throws EvaluationException { + Object raw = evaluate(context, expression); + if (raw != null) { + return String.valueOf(raw); + } else { + return ""; //$NON-NLS-1$ + } + } + + /** + * {@inheritDoc} + */ + public Integer evaluateInteger(EObject context, String expression) throws EvaluationException { + Object raw = evaluate(context, expression); + try { + return Integer.parseInt(String.valueOf(raw)); + } catch (NumberFormatException e) { + return Integer.valueOf(0); + } + } + +} diff --git a/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/Messages.java b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/Messages.java new file mode 100644 index 000000000..a31ce4f04 --- /dev/null +++ b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/Messages.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2015 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.ecoretools.ale; + +import org.eclipse.osgi.util.NLS; + +/** + * Helper class to obtains translated strings. + * + */ + + +public final class Messages extends NLS { + private static final String BASE_NAME = "org.eclipse.emf.ecoretools.ale.messages"; //$NON-NLS-1$ + + static { + // load message values from bundle file + NLS.initializeMessages(BASE_NAME, Messages.class); + } + + public static String ALEInterpreter_errorWithExpression; + + +} diff --git a/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/messages.properties b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/messages.properties new file mode 100644 index 000000000..1b6781218 --- /dev/null +++ b/plugins/org.eclipse.emf.ecoretools.ale/src/org/eclipse/emf/ecoretools/ale/messages.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2019 Inria 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: +# Inria - initial API and implementation +############################################################################### + +### Supplied messageses +ALEInterpreter_errorWithExpression= An error has appeared during the evaluation of an expression:\n\ +Expression: {0}\n\ +Diagnostic: {1}\n\ +Target URI Fragment: {2}\n\ +Target: {3}\n\