Added delegates (validation, setting, ...) for AQL expressions.
Change-Id: I0423078bc4de01ee268e86d035bb5cc703c9e324
diff --git a/query/plugins/org.eclipse.acceleo.query/META-INF/MANIFEST.MF b/query/plugins/org.eclipse.acceleo.query/META-INF/MANIFEST.MF
index 0db05ed..ae96600 100644
--- a/query/plugins/org.eclipse.acceleo.query/META-INF/MANIFEST.MF
+++ b/query/plugins/org.eclipse.acceleo.query/META-INF/MANIFEST.MF
@@ -14,6 +14,7 @@
org.eclipse.acceleo.query.ast.impl;x-friends:="org.eclipse.acceleo.query.tests,org.eclipse.acceleo.query.ide.ui,org.eclipse.acceleo.query.ide.ui.test",
org.eclipse.acceleo.query.ast.util;x-friends:="org.eclipse.acceleo.query.tests,org.eclipse.acceleo.query.ide.ui,org.eclipse.acceleo.query.ide.ui.test",
org.eclipse.acceleo.query.ast.validation;version="5.0.0",
+ org.eclipse.acceleo.query.delegates;version="5.0.0",
org.eclipse.acceleo.query.parser;x-friends:="org.eclipse.acceleo.query.tests,org.eclipse.acceleo.query.ide.ui,org.eclipse.acceleo.query.ide.ui.test",
org.eclipse.acceleo.query.runtime;version="5.0.0",
org.eclipse.acceleo.query.runtime.impl;x-friends:="org.eclipse.acceleo.query.tests,org.eclipse.acceleo.query.ide.ui,org.eclipse.acceleo.query.ide.ui.test",
diff --git a/query/plugins/org.eclipse.acceleo.query/plugin.xml b/query/plugins/org.eclipse.acceleo.query/plugin.xml
index eb06a7d..935ff85 100644
--- a/query/plugins/org.eclipse.acceleo.query/plugin.xml
+++ b/query/plugins/org.eclipse.acceleo.query/plugin.xml
@@ -23,5 +23,33 @@
class="org.eclipse.acceleo.query.ast.AstPackage"
genModel="model/ast.genmodel"/>
</extension>
+ <extension
+ point="org.eclipse.emf.ecore.validation_delegate">
+ <delegate
+ class="org.eclipse.acceleo.query.delegates.AQLValidationDelegate"
+ uri="http://www.eclipse.org/acceleo/query/1.0">
+ </delegate>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.setting_delegate">
+ <factory
+ class="org.eclipse.acceleo.query.delegates.AQLSettingDelegateFactory"
+ uri="http://www.eclipse.org/acceleo/query/1.0">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.invocation_delegate">
+ <factory
+ class="org.eclipse.acceleo.query.delegates.AQLInvocationDelegateFactory"
+ uri="http://www.eclipse.org/acceleo/query/1.0">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.query_delegate">
+ <factory
+ class="org.eclipse.acceleo.query.delegates."
+ uri="http://www.eclipse.org/acceleo/query/1.0">
+ </factory>
+ </extension>
</plugin>
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegate.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegate.java
new file mode 100644
index 0000000..55eb0f4
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegate.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.acceleo.query.runtime.AcceleoQueryEvaluationException;
+import org.eclipse.acceleo.query.runtime.EvaluationResult;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryEvaluationEngine;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EOperation.Internal.InvocationDelegate;
+import org.eclipse.emf.ecore.InternalEObject;
+
+/**
+ * An invocation delegate supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLInvocationDelegate implements InvocationDelegate {
+
+ /**
+ * The {@link QueryEvaluationEngine}.
+ */
+ private final QueryEvaluationEngine engine;
+
+ /**
+ * The {@link AstResult}.
+ */
+ private final AstResult astResult;
+
+ /**
+ * The {@link List} of {@link org.eclipse.emf.ecore.EParameter#getName() eParameter name}.
+ */
+ private final List<String> parameterNames;
+
+ /**
+ * Constructor.
+ *
+ * @param queryEnvironment
+ * the {@link IQueryEnvironment}
+ * @param astResult
+ * the {@link AstResult}
+ * @param parameterNames
+ * the {@link List} of {@link org.eclipse.emf.ecore.EParameter#getName() eParameter name}
+ */
+ public AQLInvocationDelegate(IQueryEnvironment queryEnvironment, AstResult astResult,
+ List<String> parameterNames) {
+ engine = new QueryEvaluationEngine(queryEnvironment);
+ this.astResult = astResult;
+ this.parameterNames = parameterNames;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EOperation.Internal.InvocationDelegate#dynamicInvoke(org.eclipse.emf.ecore.InternalEObject,
+ * org.eclipse.emf.common.util.EList)
+ */
+ @Override
+ public Object dynamicInvoke(InternalEObject target, EList<?> arguments) throws InvocationTargetException {
+ if (arguments.size() != parameterNames.size()) {
+ throw new IllegalArgumentException("number of arguments mismatch " + arguments.size()
+ + " instead of " + parameterNames.size());
+ }
+
+ final Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("self", target);
+ for (int index = 0; index < parameterNames.size(); index++) {
+ variables.put(parameterNames.get(index), arguments.get(index));
+ }
+
+ final EvaluationResult evaluationResult;
+ try {
+ evaluationResult = engine.eval(astResult, variables);
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ throw new InvocationTargetException(e);
+ }
+ if (evaluationResult.getDiagnostic().getSeverity() == Diagnostic.ERROR) {
+ throw new InvocationTargetException(new AcceleoQueryEvaluationException(evaluationResult
+ .getDiagnostic().getMessage()));
+ }
+
+ return evaluationResult.getResult();
+ }
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegateFactory.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegateFactory.java
new file mode 100644
index 0000000..5b63ed6
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLInvocationDelegateFactory.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.acceleo.query.ast.AstPackage;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryBuilderEngine;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EOperation.Internal.InvocationDelegate;
+import org.eclipse.emf.ecore.EOperation.Internal.InvocationDelegate.Factory;
+import org.eclipse.emf.ecore.EParameter;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * An invocation delegate factory supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLInvocationDelegateFactory extends AbstractEnvironmentProvider implements Factory {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EOperation.Internal.InvocationDelegate.Factory#createInvocationDelegate(org.eclipse.emf.ecore.EOperation)
+ */
+ @Override
+ public InvocationDelegate createInvocationDelegate(EOperation operation) {
+ final IQueryEnvironment env = getEnvironment();
+ final String expression = EcoreUtil.getAnnotation(operation, AstPackage.eNS_URI, "body");
+
+ final QueryBuilderEngine engine = new QueryBuilderEngine(env);
+ final AstResult astResult = engine.build(expression);
+ final List<String> parameterNames = new ArrayList<String>();
+ for (EParameter parameter : operation.getEParameters()) {
+ parameterNames.add(parameter.getName());
+ }
+
+ // TODO test if something went wrong
+
+ return new AQLInvocationDelegate(env, astResult, parameterNames);
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegate.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegate.java
new file mode 100644
index 0000000..6967914
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegate.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.acceleo.query.runtime.AcceleoQueryEvaluationException;
+import org.eclipse.acceleo.query.runtime.EvaluationResult;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryEvaluationEngine;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.ecore.util.QueryDelegate;
+
+/**
+ * A query delegate supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLQueryDelegate implements QueryDelegate {
+
+ /**
+ * The {@link QueryEvaluationEngine}.
+ */
+ private final QueryEvaluationEngine engine;
+
+ /**
+ * The {@link AstResult}.
+ */
+ private final AstResult astResult;
+
+ /**
+ * Constructor.
+ *
+ * @param queryEnvironment
+ * the {@link IQueryEnvironment}
+ * @param astResult
+ * the {@link AstResult}
+ */
+ public AQLQueryDelegate(IQueryEnvironment queryEnvironment, AstResult astResult) {
+ engine = new QueryEvaluationEngine(queryEnvironment);
+ this.astResult = astResult;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.util.QueryDelegate#prepare()
+ */
+ @Override
+ public void prepare() throws InvocationTargetException {
+ // nothing to do here
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.util.QueryDelegate#execute(java.lang.Object, java.util.Map)
+ */
+ @Override
+ public Object execute(Object target, Map<String, ?> arguments) throws InvocationTargetException {
+ final Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("self", target);
+ variables.putAll(arguments);
+
+ final EvaluationResult evaluationResult;
+ try {
+ evaluationResult = engine.eval(astResult, variables);
+ // CHECKSTYLE:OFF
+ } catch (Exception e) {
+ // CHECKSTYLE:ON
+ throw new InvocationTargetException(e);
+ }
+ if (evaluationResult.getDiagnostic().getSeverity() == Diagnostic.ERROR) {
+ throw new InvocationTargetException(new AcceleoQueryEvaluationException(evaluationResult
+ .getDiagnostic().getMessage()));
+ }
+
+ return evaluationResult.getResult();
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegateFactory.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegateFactory.java
new file mode 100644
index 0000000..7f9982c
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLQueryDelegateFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.util.Map;
+
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryBuilderEngine;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.util.QueryDelegate;
+import org.eclipse.emf.ecore.util.QueryDelegate.Factory;
+
+/**
+ * A query delegate factory supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLQueryDelegateFactory extends AbstractEnvironmentProvider implements Factory {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.util.QueryDelegate.Factory#createQueryDelegate(org.eclipse.emf.ecore.EClassifier,
+ * java.util.Map, java.lang.String)
+ */
+ @Override
+ public QueryDelegate createQueryDelegate(EClassifier context, Map<String, EClassifier> parameters,
+ String expression) {
+ final IQueryEnvironment env = getEnvironment();
+
+ final QueryBuilderEngine engine = new QueryBuilderEngine(env);
+ final AstResult astResult = engine.build(expression);
+
+ // TODO test if something went wrong
+
+ return new AQLQueryDelegate(env, astResult);
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegate.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegate.java
new file mode 100644
index 0000000..d9259b2
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegate.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.acceleo.query.runtime.EvaluationResult;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryEvaluationEngine;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.BasicSettingDelegate;
+
+/**
+ * A setting delegate supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLSettingDelegate extends BasicSettingDelegate.Stateless {
+
+ /**
+ * The {@link QueryEvaluationEngine}.
+ */
+ private final QueryEvaluationEngine engine;
+
+ /**
+ * The {@link AstResult}.
+ */
+ private final AstResult astResult;
+
+ /**
+ * Constructor.
+ *
+ * @param eStructuralFeature
+ * the {@link EStructuralFeature}
+ * @param queryEnvironment
+ * the {@link IQueryEnvironment}
+ * @param astResult
+ * the {@link AstResult}
+ */
+ public AQLSettingDelegate(EStructuralFeature eStructuralFeature, IQueryEnvironment queryEnvironment,
+ AstResult astResult) {
+ super(eStructuralFeature);
+ engine = new QueryEvaluationEngine(queryEnvironment);
+ this.astResult = astResult;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.util.BasicSettingDelegate.Stateless#get(org.eclipse.emf.ecore.InternalEObject,
+ * boolean, boolean)
+ */
+ @Override
+ protected Object get(InternalEObject owner, boolean resolve, boolean coreType) {
+ final Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put("self", owner);
+
+ final EvaluationResult evaluationResult = engine.eval(astResult, variables);
+
+ if (evaluationResult.getDiagnostic().getSeverity() != Diagnostic.OK) {
+ final StringBuilder messages = new StringBuilder();
+ for (Diagnostic child : evaluationResult.getDiagnostic().getChildren()) {
+ messages.append("\n" + child.getMessage());
+ }
+ throw new IllegalArgumentException("Unable to evaluate feature \"" + eStructuralFeature.getName()
+ + "\"" + messages.toString());
+ }
+
+ return evaluationResult.getResult();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.util.BasicSettingDelegate.Stateless#isSet(org.eclipse.emf.ecore.InternalEObject)
+ */
+ @Override
+ protected boolean isSet(InternalEObject owner) {
+ // since the setting is derived it should not be setted in anyway.
+ return false;
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegateFactory.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegateFactory.java
new file mode 100644
index 0000000..47aef44
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLSettingDelegateFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import org.eclipse.acceleo.query.ast.AstPackage;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryBuilderEngine;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EStructuralFeature.Internal.SettingDelegate;
+import org.eclipse.emf.ecore.EStructuralFeature.Internal.SettingDelegate.Factory;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * A setting delegate factory supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLSettingDelegateFactory extends AbstractEnvironmentProvider implements Factory {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EStructuralFeature.Internal.SettingDelegate.Factory#createSettingDelegate(org.eclipse.emf.ecore.EStructuralFeature)
+ */
+ @Override
+ public SettingDelegate createSettingDelegate(EStructuralFeature eStructuralFeature) {
+ final IQueryEnvironment env = getEnvironment();
+ final String expression = EcoreUtil.getAnnotation(eStructuralFeature, AstPackage.eNS_URI,
+ "derivation");
+
+ final QueryBuilderEngine engine = new QueryBuilderEngine(env);
+ final AstResult astResult = engine.build(expression);
+
+ // TODO test if something went wrong
+
+ return new AQLSettingDelegate(eStructuralFeature, env, astResult);
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLValidationDelegate.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLValidationDelegate.java
new file mode 100644
index 0000000..4ed35b8
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AQLValidationDelegate.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.acceleo.query.runtime.EvaluationResult;
+import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine.AstResult;
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.impl.QueryBuilderEngine;
+import org.eclipse.acceleo.query.runtime.impl.QueryEvaluationEngine;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EValidator.ValidationDelegate;
+
+/**
+ * A validation delegate supporting AQL.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class AQLValidationDelegate extends AbstractEnvironmentProvider implements ValidationDelegate {
+
+ /**
+ * The self variable name.
+ */
+ private static final String SELF = "self";
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EValidator.ValidationDelegate#validate(org.eclipse.emf.ecore.EClass,
+ * org.eclipse.emf.ecore.EObject, java.util.Map, org.eclipse.emf.ecore.EOperation, java.lang.String)
+ */
+ @Override
+ public boolean validate(EClass eClass, EObject eObject, Map<Object, Object> context,
+ EOperation invariant, String expression) {
+ return Boolean.TRUE.equals(evaluate(eObject, expression));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EValidator.ValidationDelegate#validate(org.eclipse.emf.ecore.EClass,
+ * org.eclipse.emf.ecore.EObject, java.util.Map, java.lang.String, java.lang.String)
+ */
+ @Override
+ public boolean validate(EClass eClass, EObject eObject, Map<Object, Object> context, String constraint,
+ String expression) {
+ return Boolean.TRUE.equals(evaluate(eObject, expression));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.EValidator.ValidationDelegate#validate(org.eclipse.emf.ecore.EDataType,
+ * java.lang.Object, java.util.Map, java.lang.String, java.lang.String)
+ */
+ @Override
+ public boolean validate(EDataType eDataType, Object value, Map<Object, Object> context,
+ String constraint, String expression) {
+ return Boolean.TRUE.equals(evaluate(value, expression));
+ }
+
+ /**
+ * Evaluates the given AQL expression on the given self {@link Object}.
+ *
+ * @param self
+ * the self {@link Object}
+ * @param expression
+ * the AQL expression
+ * @return the evaluated value
+ */
+ private Object evaluate(Object self, String expression) {
+ final IQueryEnvironment environment = getEnvironment();
+
+ final Map<String, Object> variables = new HashMap<String, Object>();
+ variables.put(SELF, self);
+
+ final QueryBuilderEngine builderEngine = new QueryBuilderEngine(environment);
+ final AstResult astResult = builderEngine.build(expression);
+
+ if (astResult.getDiagnostic().getSeverity() == Diagnostic.OK) {
+ final QueryEvaluationEngine evaluationEngine = new QueryEvaluationEngine(environment);
+ final EvaluationResult evaluationResult = evaluationEngine.eval(astResult, variables);
+
+ if (evaluationResult.getDiagnostic().getSeverity() != Diagnostic.OK) {
+ final StringBuilder messages = new StringBuilder();
+ for (Diagnostic child : evaluationResult.getDiagnostic().getChildren()) {
+ messages.append("\n" + child.getMessage());
+ }
+ throw new IllegalArgumentException("Unable to evaluate \"" + expression + "\""
+ + messages.toString());
+ }
+ return evaluationResult.getResult();
+ } else {
+ final StringBuilder messages = new StringBuilder();
+ for (Diagnostic child : astResult.getDiagnostic().getChildren()) {
+ messages.append("\n" + child.getMessage());
+ }
+ throw new IllegalArgumentException("Unable to parse \"" + expression + "\"" + messages.toString());
+ }
+
+ }
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AbstractEnvironmentProvider.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AbstractEnvironmentProvider.java
new file mode 100644
index 0000000..7bf6942
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/AbstractEnvironmentProvider.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
+import org.eclipse.acceleo.query.runtime.Query;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+
+/**
+ * Provide an {@link IQueryEnvironment}.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public abstract class AbstractEnvironmentProvider {
+
+ /**
+ * The cached {@link IQueryEnvironment}.
+ */
+ private IQueryEnvironment environment;
+
+ /**
+ * Gets the configured {@link IQueryEnvironment}.
+ *
+ * @return the configured {@link IQueryEnvironment}
+ */
+ protected IQueryEnvironment getEnvironment() {
+ final IQueryEnvironment res;
+
+ if (environment == null) {
+ environment = Query.newEnvironmentWithDefaultServices(null);
+ res = environment;
+
+ for (Object ePkg : EPackageRegistryImpl.createGlobalRegistry().values()) {
+ res.registerEPackage((EPackage)ePkg);
+ }
+ } else {
+ res = environment;
+ }
+
+ return res;
+ }
+
+}
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/DelegateUtils.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/DelegateUtils.java
new file mode 100644
index 0000000..99a056d
--- /dev/null
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/delegates/DelegateUtils.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.delegates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.acceleo.query.ast.AstPackage;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * Utility class for delegates.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public final class DelegateUtils {
+
+ /**
+ * Constructor.
+ */
+ private DelegateUtils() {
+ // nothing to do here
+ }
+
+ /**
+ * Sets the AQL setting delegate on the given {@link EPackage}.
+ *
+ * @param ePackage
+ * the {@link EPackage}
+ */
+ public static void setSettingDelegates(EPackage ePackage) {
+ final List<String> delegates = EcoreUtil.getSettingDelegates(ePackage);
+ if (!delegates.contains(AstPackage.eNS_URI)) {
+ final List<String> newDelegates = new ArrayList<String>(delegates);
+ newDelegates.add(AstPackage.eNS_URI);
+ EcoreUtil.setSettingDelegates(ePackage, newDelegates);
+ }
+ }
+
+ /**
+ * Sets the AQL invocation delegate on the given {@link EPackage}.
+ *
+ * @param ePackage
+ * the {@link EPackage}
+ */
+ public static void setInvocationDelegates(EPackage ePackage) {
+ final List<String> delegates = EcoreUtil.getInvocationDelegates(ePackage);
+ if (!delegates.contains(AstPackage.eNS_URI)) {
+ final List<String> newDelegates = new ArrayList<String>(delegates);
+ newDelegates.add(AstPackage.eNS_URI);
+ EcoreUtil.setInvocationDelegates(ePackage, newDelegates);
+ }
+ }
+
+ /**
+ * Sets the AQL validation delegate on the given {@link EPackage}.
+ *
+ * @param ePackage
+ * the {@link EPackage}
+ */
+ public static void setValidationDelegates(EPackage ePackage) {
+ final List<String> delegates = EcoreUtil.getValidationDelegates(ePackage);
+ if (!delegates.contains(AstPackage.eNS_URI)) {
+ final List<String> newDelegates = new ArrayList<String>(delegates);
+ newDelegates.add(AstPackage.eNS_URI);
+ EcoreUtil.setValidationDelegates(ePackage, newDelegates);
+ }
+ }
+
+ /**
+ * Gets the AQL expression of the given constraint name for the given {@link EModelElement}.
+ *
+ * @param eModelElement
+ * the {@link EModelElement}
+ * @param constraintName
+ * the constraint name
+ * @return the AQL expression of the given constraint name for the given {@link EModelElement} if any,
+ * <code>null</code> otherwise
+ */
+ public static String getConstraint(EModelElement eModelElement, String constraintName) {
+ return EcoreUtil.getAnnotation(eModelElement, AstPackage.eNS_URI, constraintName);
+ }
+
+ /**
+ * Gets the given expression as the constraint of the given {@link EModelElement}.
+ *
+ * @param eModelElement
+ * the {@link EModelElement}
+ * @param constraintName
+ * the constraint name
+ * @param expression
+ * the AQL expression
+ */
+ public static void setConstraint(EModelElement eModelElement, String constraintName, String expression) {
+ final List<String> constraints = EcoreUtil.getConstraints(eModelElement);
+ if (!constraints.contains(constraintName)) {
+ final List<String> newConstraints = new ArrayList<String>(constraints);
+ newConstraints.add(constraintName);
+ EcoreUtil.setConstraints(eModelElement, newConstraints);
+ }
+
+ EcoreUtil.setAnnotation(eModelElement, AstPackage.eNS_URI, constraintName, expression);
+ }
+
+ /**
+ * Gets the AQL body expression of the given {@link EOperation}.
+ *
+ * @param eOperation
+ * the {@link EOperation}
+ * @return the AQL expression body of the given {@link EOperation} if any, <code>null</code> otherwise
+ */
+ public static String getBody(EOperation eOperation) {
+ return EcoreUtil.getAnnotation(eOperation, AstPackage.eNS_URI, "body");
+ }
+
+ /**
+ * Sets the given expression as the body of the given {@link EOperation}.
+ *
+ * @param eOperation
+ * the {@link EOperation}
+ * @param expression
+ * the AQL expression
+ */
+ public static void setBody(EOperation eOperation, String expression) {
+ EcoreUtil.setAnnotation(eOperation, AstPackage.eNS_URI, "body", expression);
+ }
+
+ /**
+ * Gets the AQL derivation expression for the given {@link EStructuralFeature}.
+ *
+ * @param feature
+ * the {@link EStructuralFeature}
+ * @return the AQL derivation expression for the given {@link EStructuralFeature} if any,
+ * <code>null</code> otherwise
+ */
+ public static String getDerivation(EStructuralFeature feature) {
+ return EcoreUtil.getAnnotation(feature, AstPackage.eNS_URI, "derivation");
+ }
+
+ /**
+ * Sets the given expression as the derivation of the given {@link EStructuralFeature}.
+ *
+ * @param feature
+ * the {@link EStructuralFeature}
+ * @param expression
+ * the AQL expression
+ */
+ public static void setDerivation(EStructuralFeature feature, String expression) {
+ EcoreUtil.setAnnotation(feature, AstPackage.eNS_URI, "derivation", expression);
+ }
+
+}
diff --git a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateTests.java b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateTests.java
new file mode 100644
index 0000000..703dd40
--- /dev/null
+++ b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateTests.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.ast.test.delegates;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.acceleo.query.ast.AstPackage;
+import org.eclipse.acceleo.query.delegates.AQLInvocationDelegateFactory;
+import org.eclipse.acceleo.query.delegates.AQLSettingDelegateFactory;
+import org.eclipse.acceleo.query.delegates.AQLValidationDelegate;
+import org.eclipse.acceleo.query.delegates.DelegateUtils;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EParameter;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class DelegateTests {
+
+ private static EPackage ePackage;
+
+ private static EClass eClass;
+
+ private static EAttribute eAttribute1;
+
+ private static EAttribute eAttribute2;
+
+ private static EReference eReference;
+
+ private static EOperation eOperation;
+
+ private static EClass eClassParsingError;
+
+ private static EAttribute eAttribute1ParsingError;
+
+ private static EAttribute eAttribute2ParsingError;
+
+ private static EReference eReferenceParsingError;
+
+ private static EOperation eOperationParsingError;
+
+ private static EClass eClassEvaluationError;
+
+ private static EAttribute eAttribute1EvaluationError;
+
+ private static EAttribute eAttribute2EvaluationError;
+
+ private static EReference eReferenceEvaluationError;
+
+ private static EOperation eOperationEvaluationError;
+
+ @BeforeClass
+ public static void beforeClass() {
+ // delegates registration
+ EOperation.Internal.InvocationDelegate.Factory.Registry.INSTANCE.put(AstPackage.eNS_URI,
+ new AQLInvocationDelegateFactory());
+ EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(AstPackage.eNS_URI,
+ new AQLSettingDelegateFactory());
+ EValidator.ValidationDelegate.Registry.INSTANCE.put(AstPackage.eNS_URI, new AQLValidationDelegate());
+
+ // EPackage construction
+ ePackage = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+ ePackage.setName("testEPackage");
+ ePackage.setNsPrefix("test");
+ ePackage.setNsURI("test");
+
+ eClass = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+ eClass.setName("TestEClass");
+ ePackage.getEClassifiers().add(eClass);
+
+ eAttribute1 = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute1.setName("testAttribute1");
+ eAttribute1.setEType(EcorePackage.eINSTANCE.getEString());
+ eClass.getEStructuralFeatures().add(eAttribute1);
+
+ eAttribute2 = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute2.setName("testAttribute2");
+ eAttribute2.setEType(EcorePackage.eINSTANCE.getEString());
+ eClass.getEStructuralFeatures().add(eAttribute2);
+
+ eReference = EcorePackage.eINSTANCE.getEcoreFactory().createEReference();
+ eReference.setName("testReference");
+ eReference.setEType(eClass);
+ eClass.getEStructuralFeatures().add(eReference);
+
+ eOperation = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+ eOperation.setName("testOperation");
+ eOperation.setEType(EcorePackage.eINSTANCE.getEString());
+ eClass.getEOperations().add(eOperation);
+ final EParameter eParameter1 = EcorePackage.eINSTANCE.getEcoreFactory().createEParameter();
+ eParameter1.setName("testParameter1");
+ eParameter1.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperation.getEParameters().add(eParameter1);
+ final EParameter eParameter2 = EcorePackage.eINSTANCE.getEcoreFactory().createEParameter();
+ eParameter2.setName("testParameter2");
+ eParameter2.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperation.getEParameters().add(eParameter2);
+
+ eClassParsingError = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+ eClassParsingError.setName("TestEClassParsingError");
+ ePackage.getEClassifiers().add(eClassParsingError);
+
+ eAttribute1ParsingError = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute1ParsingError.setName("testAttribute1ParsingError");
+ eAttribute1ParsingError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassParsingError.getEStructuralFeatures().add(eAttribute1ParsingError);
+
+ eAttribute2ParsingError = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute2ParsingError.setName("testAttribute2ParsingError");
+ eAttribute2ParsingError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassParsingError.getEStructuralFeatures().add(eAttribute2ParsingError);
+
+ eReferenceParsingError = EcorePackage.eINSTANCE.getEcoreFactory().createEReference();
+ eReferenceParsingError.setName("testReferenceParsingError");
+ eReferenceParsingError.setEType(eClass);
+ eClassParsingError.getEStructuralFeatures().add(eReferenceParsingError);
+
+ eOperationParsingError = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+ eOperationParsingError.setName("testOperationParsingError");
+ eOperationParsingError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassParsingError.getEOperations().add(eOperationParsingError);
+ final EParameter eParameter1ParsingError = EcorePackage.eINSTANCE.getEcoreFactory()
+ .createEParameter();
+ eParameter1ParsingError.setName("testParameter1ParsingError");
+ eParameter1ParsingError.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperationParsingError.getEParameters().add(eParameter1ParsingError);
+ final EParameter eParameter2ParsingError = EcorePackage.eINSTANCE.getEcoreFactory()
+ .createEParameter();
+ eParameter2ParsingError.setName("testParameter2ParsingError");
+ eParameter2ParsingError.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperationParsingError.getEParameters().add(eParameter2ParsingError);
+
+ eClassEvaluationError = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+ eClassEvaluationError.setName("TestEClassEvaluationError");
+ ePackage.getEClassifiers().add(eClassEvaluationError);
+
+ eAttribute1EvaluationError = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute1EvaluationError.setName("testAttribute1EvaluationError");
+ eAttribute1EvaluationError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassEvaluationError.getEStructuralFeatures().add(eAttribute1EvaluationError);
+
+ eAttribute2EvaluationError = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+ eAttribute2EvaluationError.setName("testAttribute2EvaluationError");
+ eAttribute2EvaluationError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassEvaluationError.getEStructuralFeatures().add(eAttribute2EvaluationError);
+
+ eReferenceEvaluationError = EcorePackage.eINSTANCE.getEcoreFactory().createEReference();
+ eReferenceEvaluationError.setName("testReferenceEvaluationError");
+ eReferenceEvaluationError.setEType(eClass);
+ eClassEvaluationError.getEStructuralFeatures().add(eReferenceEvaluationError);
+
+ eOperationEvaluationError = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+ eOperationEvaluationError.setName("testOperationEvaluationError");
+ eOperationEvaluationError.setEType(EcorePackage.eINSTANCE.getEString());
+ eClassEvaluationError.getEOperations().add(eOperationEvaluationError);
+ final EParameter eParameter1EvaluationError = EcorePackage.eINSTANCE.getEcoreFactory()
+ .createEParameter();
+ eParameter1EvaluationError.setName("testParameter1EvaluationError");
+ eParameter1EvaluationError.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperationEvaluationError.getEParameters().add(eParameter1EvaluationError);
+ final EParameter eParameter2EvaluationError = EcorePackage.eINSTANCE.getEcoreFactory()
+ .createEParameter();
+ eParameter2EvaluationError.setName("testParameter2EvaluationError");
+ eParameter2EvaluationError.setEType(EcorePackage.eINSTANCE.getEString());
+ eOperationEvaluationError.getEParameters().add(eParameter2EvaluationError);
+
+ // set delegates annotations
+ DelegateUtils.setInvocationDelegates(ePackage);
+ DelegateUtils.setSettingDelegates(ePackage);
+ DelegateUtils.setValidationDelegates(ePackage);
+
+ DelegateUtils.setDerivation(eReference, "self.eClass.name");
+ DelegateUtils.setDerivation(eReferenceParsingError, "self.");
+ DelegateUtils.setDerivation(eReferenceEvaluationError, "notAVariable");
+
+ DelegateUtils.setConstraint(eClass, "AttributeIsShort", "self.testAttribute1.size() < 5");
+ DelegateUtils.setConstraint(eClassParsingError, "AttributeParsingError", "5 < ");
+ DelegateUtils.setConstraint(eClassEvaluationError, "AttributeParsingError", "notAVariable");
+
+ DelegateUtils.setDerivation(eReference, "self");
+ DelegateUtils.setDerivation(eReferenceParsingError, "5 < ");
+ DelegateUtils.setDerivation(eReferenceEvaluationError, "notAVariable");
+
+ DelegateUtils.setBody(eOperation, "testParameter1 + testParameter2");
+ DelegateUtils.setBody(eOperationParsingError, "testParameter1 +");
+ DelegateUtils.setBody(eOperationEvaluationError, "notAVariable");
+ }
+
+ @Test
+ public void derivation() {
+ final EObject eObj = EcoreUtil.create(eClass);
+ final Object value = eObj.eGet(eReference);
+
+ assertEquals(eObj, value);
+ }
+
+ @Test(expected = java.lang.IllegalArgumentException.class)
+ public void derivationParsingError() {
+ final EObject eObj = EcoreUtil.create(eClassParsingError);
+ final Object value = eObj.eGet(eReferenceParsingError);
+
+ assertEquals(eObj, value);
+ }
+
+ @Test(expected = java.lang.IllegalArgumentException.class)
+ public void derivationEvaluationError() {
+ final EObject eObj = EcoreUtil.create(eClassEvaluationError);
+ eObj.eGet(eReferenceEvaluationError);
+ }
+
+ @Test
+ public void constraintOK() {
+ final EObject eObj = EcoreUtil.create(eClass);
+
+ eObj.eSet(eAttribute1, "abc");
+
+ Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+
+ assertEquals(Diagnostic.OK, diagnostic.getSeverity());
+ }
+
+ @Test
+ public void constraintKO() {
+ final EObject eObj = EcoreUtil.create(eClass);
+
+ eObj.eSet(eAttribute1, "abcdefgh");
+
+ Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+
+ assertEquals(Diagnostic.ERROR, diagnostic.getSeverity());
+ assertEquals(1, diagnostic.getChildren().size());
+ assertTrue(diagnostic.getChildren().get(0).getMessage().startsWith(
+ "The 'AttributeIsShort' constraint is violated on"));
+ }
+
+ @Test
+ public void constraintParsingError() {
+ final EObject eObj = EcoreUtil.create(eClassParsingError);
+
+ eObj.eSet(eAttribute1ParsingError, "abc");
+
+ Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+
+ assertEquals(Diagnostic.ERROR, diagnostic.getSeverity());
+ assertEquals(1, diagnostic.getChildren().size());
+ assertTrue(diagnostic.getChildren().get(0).getMessage().endsWith("missing expression"));
+ }
+
+ @Test
+ public void constraintEvaluationError() {
+ final EObject eObj = EcoreUtil.create(eClassEvaluationError);
+
+ eObj.eSet(eAttribute1EvaluationError, "abc");
+
+ Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+
+ assertEquals(Diagnostic.ERROR, diagnostic.getSeverity());
+ assertEquals(1, diagnostic.getChildren().size());
+ assertTrue(diagnostic.getChildren().get(0).getMessage().endsWith(
+ "Couldn't find the notAVariable variable"));
+ }
+
+ @Test
+ public void body() throws InvocationTargetException {
+ final EObject eObj = EcoreUtil.create(eClass);
+ final EList<Object> arguments = new BasicEList<Object>();
+ arguments.add("abc");
+ arguments.add("def");
+ final Object value = eObj.eInvoke(eOperation, arguments);
+
+ assertEquals("abcdef", value);
+ }
+
+ @Test(expected = java.lang.reflect.InvocationTargetException.class)
+ public void bodyParsingError() throws InvocationTargetException {
+ final EObject eObj = EcoreUtil.create(eClassParsingError);
+ final EList<Object> arguments = new BasicEList<Object>();
+ arguments.add("abc");
+ arguments.add("def");
+ eObj.eInvoke(eOperationParsingError, arguments);
+ }
+
+ @Test(expected = java.lang.reflect.InvocationTargetException.class)
+ public void bodyEvaluationError() throws InvocationTargetException {
+ final EObject eObj = EcoreUtil.create(eClassEvaluationError);
+ final EList<Object> arguments = new BasicEList<Object>();
+ arguments.add("abc");
+ arguments.add("def");
+ eObj.eInvoke(eOperationEvaluationError, arguments);
+ }
+
+ @Test(expected = java.lang.IllegalArgumentException.class)
+ public void bodyEvaluationWrongNumberOfArguments() throws InvocationTargetException {
+ final EObject eObj = EcoreUtil.create(eClassEvaluationError);
+ final EList<Object> arguments = new BasicEList<Object>();
+ arguments.add("abc");
+ arguments.add("def");
+ arguments.add("def");
+ eObj.eInvoke(eOperationEvaluationError, arguments);
+ }
+
+}
diff --git a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateUtilsTests.java b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateUtilsTests.java
new file mode 100644
index 0000000..4315241
--- /dev/null
+++ b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/ast/test/delegates/DelegateUtilsTests.java
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.query.ast.test.delegates;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+import org.eclipse.acceleo.query.ast.AstPackage;
+import org.eclipse.acceleo.query.delegates.DelegateUtils;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests {@link DelegateUtils}.
+ *
+ * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
+ */
+public class DelegateUtilsTests {
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setSettingDelegatesNull() {
+ DelegateUtils.setSettingDelegates(null);
+ }
+
+ @Test
+ public void setSettingDelegatesNotExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setSettingDelegates(ePkg, Lists.newArrayList("uri"));
+
+ DelegateUtils.setSettingDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getSettingDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test
+ public void setSettingDelegatesExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setSettingDelegates(ePkg, Lists.newArrayList("uri", AstPackage.eNS_URI));
+
+ DelegateUtils.setSettingDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getSettingDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setInvocationDelegatesNull() {
+ DelegateUtils.setInvocationDelegates(null);
+ }
+
+ @Test
+ public void setInvocationDelegatesNotExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setInvocationDelegates(ePkg, Lists.newArrayList("uri"));
+
+ DelegateUtils.setInvocationDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getInvocationDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test
+ public void setInvocationDelegatesExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setInvocationDelegates(ePkg, Lists.newArrayList("uri", AstPackage.eNS_URI));
+
+ DelegateUtils.setInvocationDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getInvocationDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setValidationDelegatesNull() {
+ DelegateUtils.setValidationDelegates(null);
+ }
+
+ @Test
+ public void setValidationDelegatesNotExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setValidationDelegates(ePkg, Lists.newArrayList("uri"));
+
+ DelegateUtils.setValidationDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getValidationDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test
+ public void setValidationDelegatesExisting() {
+ final EPackage ePkg = EcorePackage.eINSTANCE.getEcoreFactory().createEPackage();
+
+ EcoreUtil.setValidationDelegates(ePkg, Lists.newArrayList("uri", AstPackage.eNS_URI));
+
+ DelegateUtils.setValidationDelegates(ePkg);
+
+ final List<String> delegates = EcoreUtil.getValidationDelegates(ePkg);
+
+ assertEquals(2, delegates.size());
+ assertEquals("uri", delegates.get(0));
+ assertEquals(AstPackage.eNS_URI, delegates.get(1));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void getConstraintNull() {
+ DelegateUtils.getConstraint(null, "someConstraint");
+ }
+
+ @Test
+ public void getConstraintNotSetted() {
+ final EClass eCls = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+
+ assertEquals(null, DelegateUtils.getConstraint(eCls, "someConstraint"));
+ }
+
+ @Test
+ public void getConstraintSetted() {
+ final EClass eCls = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+
+ DelegateUtils.setConstraint(eCls, "someConstraint", "self");
+
+ assertEquals("self", DelegateUtils.getConstraint(eCls, "someConstraint"));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setConstraintNull() {
+ DelegateUtils.setConstraint(null, "someConstraint", "");
+ }
+
+ @Test
+ public void setConstraintNotExisting() {
+ final EClass eCls = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+
+ EcoreUtil.setConstraints(eCls, Lists.newArrayList("someOtherConstraint"));
+
+ DelegateUtils.setConstraint(eCls, "someConstraint", "true");
+
+ final List<String> constraints = EcoreUtil.getConstraints(eCls);
+
+ assertEquals(2, constraints.size());
+ assertEquals("someOtherConstraint", constraints.get(0));
+ assertEquals("someConstraint", constraints.get(1));
+
+ final String expression = EcoreUtil.getAnnotation(eCls, AstPackage.eNS_URI, "someConstraint");
+
+ assertEquals("true", expression);
+ }
+
+ @Test
+ public void setConstraintExisting() {
+ final EClass eCls = EcorePackage.eINSTANCE.getEcoreFactory().createEClass();
+
+ EcoreUtil.setConstraints(eCls, Lists.newArrayList("someConstraint", "someOtherConstraint"));
+
+ DelegateUtils.setConstraint(eCls, "someConstraint", "true");
+
+ final List<String> constraints = EcoreUtil.getConstraints(eCls);
+
+ assertEquals(2, constraints.size());
+ assertEquals("someConstraint", constraints.get(0));
+ assertEquals("someOtherConstraint", constraints.get(1));
+
+ final String expression = EcoreUtil.getAnnotation(eCls, AstPackage.eNS_URI, "someConstraint");
+
+ assertEquals("true", expression);
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void getBodyNull() {
+ DelegateUtils.getBody(null);
+ }
+
+ @Test
+ public void getBodyNotSetted() {
+ final EOperation eOperation = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+
+ assertEquals(null, DelegateUtils.getBody(eOperation));
+ }
+
+ @Test
+ public void getBodySetted() {
+ final EOperation eOperation = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+
+ DelegateUtils.setBody(eOperation, "self");
+
+ assertEquals("self", DelegateUtils.getBody(eOperation));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setBodyNull() {
+ DelegateUtils.setBody(null, "true");
+ }
+
+ @Test
+ public void setBody() {
+ final EOperation eOperation = EcorePackage.eINSTANCE.getEcoreFactory().createEOperation();
+
+ DelegateUtils.setBody(eOperation, "true");
+
+ final String expression = EcoreUtil.getAnnotation(eOperation, AstPackage.eNS_URI, "body");
+
+ assertEquals("true", expression);
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void getDerivationNull() {
+ DelegateUtils.getDerivation(null);
+ }
+
+ @Test
+ public void getDerivationNotSetted() {
+ final EStructuralFeature eFeature = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+
+ assertEquals(null, DelegateUtils.getDerivation(eFeature));
+ }
+
+ @Test
+ public void getDerivationSetted() {
+ final EStructuralFeature eFeature = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+
+ DelegateUtils.setDerivation(eFeature, "self");
+
+ assertEquals("self", DelegateUtils.getDerivation(eFeature));
+ }
+
+ @Test(expected = java.lang.NullPointerException.class)
+ public void setDerivationNull() {
+ DelegateUtils.setDerivation(null, "true");
+ }
+
+ @Test
+ public void setDerivation() {
+ final EStructuralFeature eFeature = EcorePackage.eINSTANCE.getEcoreFactory().createEAttribute();
+
+ DelegateUtils.setDerivation(eFeature, "true");
+
+ final String expression = EcoreUtil.getAnnotation(eFeature, AstPackage.eNS_URI, "derivation");
+
+ assertEquals("true", expression);
+ }
+
+}
diff --git a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/tests/AllTests.java b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/tests/AllTests.java
index 7126271..3a104fa 100644
--- a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/tests/AllTests.java
+++ b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/tests/AllTests.java
@@ -12,6 +12,8 @@
import org.eclipse.acceleo.query.ast.test.AstBuilderTest;
import org.eclipse.acceleo.query.ast.test.AstEvaluatorTest;
+import org.eclipse.acceleo.query.ast.test.delegates.DelegateTests;
+import org.eclipse.acceleo.query.ast.test.delegates.DelegateUtilsTests;
import org.eclipse.acceleo.query.parser.tests.BuildTest;
import org.eclipse.acceleo.query.parser.tests.CombineIteratorTest;
import org.eclipse.acceleo.query.parser.tests.CompletionCheck;
@@ -96,7 +98,7 @@
VariableCompletionProposalTests.class, EClassifierCompletionProposalTests.class,
ValidationInferrenceTest.class, TypeTests.class, QueryEnvironmentTests.class,
EPackageProviderTests.class, CompletionCheck.class, FilterCamelCaseTest.class,
- CollectionServicesAstValidationTest.class })
+ CollectionServicesAstValidationTest.class, DelegateTests.class })
public class AllTests {
}