Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbrun2015-03-26 16:59:02 +0000
committercbrun2015-04-17 11:19:09 +0000
commit4b68b79600eb9c913977dbd72af2f7f30bc588a1 (patch)
tree39af96482bf471d331b511712559ffab992683de
parent74711fa36d0c5db81db0e1aaedd6afab079d4043 (diff)
downloadorg.eclipse.sirius-4b68b79600eb9c913977dbd72af2f7f30bc588a1.tar.gz
org.eclipse.sirius-4b68b79600eb9c913977dbd72af2f7f30bc588a1.tar.xz
org.eclipse.sirius-4b68b79600eb9c913977dbd72af2f7f30bc588a1.zip
[463225] Create new IInterpreter instances for expression validation
The expression validation uses a specific singleton instead of CompoundInterpreter.INSTANCE to provide the guarante the IInterpreter instance configuration regarding metamodels/scope/imported classes is correctly set for each expression. The expected result is that for every call to analyze/validateExpression the IInterpreter instance has been configured *from the outside* based on the IInterpreterContext. When a new context requires a configuration update, the IInterpreter is reconfigured. Why still a singleton ? to pass a MultiLanguagesValidator instance around on all those calls would require major API breaks in many places (DialectService, SiriusInterpreterContextFactory and IInterpretedExpressionTargetSwitch among others) Bug: 463225 Change-Id: I2595abdead85dbb2b77a5d7fd1f287a20857479d Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java25
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java11
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContextUtils.java132
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.html8
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.textile2
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/IInterpreterValidationExpressionTest.java2
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java17
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java16
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/MultiLanguagesValidator.java109
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidInterpretedExpressionConstraint.java11
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java4
11 files changed, 291 insertions, 46 deletions
diff --git a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
index 78baef0c6d..b9e9171884 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.aql/src/org/eclipse/sirius/common/acceleo/aql/business/internal/AQLSiriusInterpreter.java
@@ -44,7 +44,6 @@ import org.eclipse.acceleo.query.validation.type.EClassifierType;
import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
@@ -222,33 +221,11 @@ public class AQLSiriusInterpreter extends AcceleoAbstractInterpreter {
@Override
public ValidationResult analyzeExpression(IInterpreterContext context, String fullExpression) {
- /*
- * use the VSM resource to declare dependent project/bundles.
- */
- EObject vsmElement = context.getElement();
- if (vsmElement.eResource() != null && vsmElement.eResource().getURI() != null && vsmElement.eResource().getURI().segmentCount() >= 2) {
- URI vsmURI = vsmElement.eResource().getURI();
- String bundleOrProjectName = vsmURI.segment(1);
- if (vsmURI.isPlatformResource()) {
- javaExtensions.updateScope(Sets.<String> newHashSet(), Sets.newHashSet(bundleOrProjectName));
- } else if (vsmURI.isPlatformPlugin()) {
- javaExtensions.updateScope(Sets.newHashSet(bundleOrProjectName), Sets.<String> newHashSet());
- }
- }
-
String trimmedExpression = new ExpressionTrimmer(fullExpression).getExpression();
-
ValidationResult result = new ValidationResult();
- for (EPackage pak : context.getAvailableEPackages()) {
- if (pak != null) {
- queryEnvironment.registerEPackage(pak);
- }
- }
+
Map<String, Set<IType>> variableTypes = TypesUtil.createAQLVariableTypesFromInterpreterContext(context, queryEnvironment);
- for (String dependency : context.getDependencies()) {
- addImport(dependency);
- }
QueryValidationEngine validator = new QueryValidationEngine(this.queryEnvironment);
try {
IValidationResult validationResult = validator.validate(trimmedExpression, variableTypes);
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
index ba77ce8d6d..ef362596d9 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/CompoundInterpreter.java
@@ -18,6 +18,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
@@ -97,6 +98,8 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
*/
private boolean extensionsLoaded;
+ private Map<Object, Object> properties;
+
/**
* The default constructor.
*/
@@ -106,6 +109,7 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
this.dependencies = new LinkedList<String>();
this.listeners = new ArrayList<IVariableStatusListener>();
this.interpreterIdentifiers = Maps.newHashMap();
+ this.properties = Maps.newHashMap();
}
/**
@@ -282,6 +286,10 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
result = this.providers.get(provider);
if (result == null) {
result = provider.createInterpreter();
+ for (Entry<Object, Object> entry : this.properties.entrySet()) {
+ result.setProperty(entry.getKey(), entry.getValue());
+ }
+ result.activateMetamodels(additionalMetamodels);
this.variableManager.setVariables(result);
for (final String dependency : this.dependencies) {
result.addImport(dependency);
@@ -426,6 +434,7 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
* java.lang.Object)
*/
public void setProperty(final Object key, final Object value) {
+ this.properties.put(key, value);
for (final IInterpreter interpreter : this.providers.values()) {
if (interpreter != null) {
interpreter.setProperty(key, value);
@@ -461,6 +470,8 @@ public final class CompoundInterpreter implements IInterpreter, IProposalProvide
this.variableManager.clearVariables();
this.dependencies.clear();
this.providers.clear();
+ this.properties.clear();
+ this.additionalMetamodels.clear();
this.extensionsLoaded = false;
this.modelAccessor = null;
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContextUtils.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContextUtils.java
new file mode 100644
index 0000000000..6882452634
--- /dev/null
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/interpreter/IInterpreterContextUtils.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.sirius.common.tools.api.interpreter;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.EcoreMetamodelDescriptor;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.MetamodelDescriptor;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Utility methods for working with IInterpreterContexts.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ *
+ */
+public final class IInterpreterContextUtils {
+
+ private IInterpreterContextUtils() {
+
+ }
+
+ /**
+ * Configure the given {@link IInterpreter} instance with the metamodels,
+ * dependencies and scope settings provided by the
+ * {@link IInterpreterContext}.
+ *
+ * @param interpreter
+ * the interpreter to configure.
+ * @param context
+ * the context holding the settings.
+ */
+ public static void configureInterpreter(IInterpreter interpreter, IInterpreterContext context) {
+ Set<String> projectsOrBundleInScope = collectProjectsOrPlugins(context);
+ interpreter.setProperty(IInterpreter.FILES, projectsOrBundleInScope);
+
+ Collection<MetamodelDescriptor> availableMetamodels = Sets.newLinkedHashSet();
+ for (EPackage pak : context.getAvailableEPackages()) {
+ if (pak != null && pak.eResource() != null) {
+ availableMetamodels.add(new EcoreMetamodelDescriptor(pak));
+ }
+ }
+ interpreter.activateMetamodels(availableMetamodels);
+
+ interpreter.clearImports();
+ for (String dependency : context.getDependencies()) {
+ interpreter.addImport(dependency);
+ }
+
+ }
+
+ static Set<String> collectProjectsOrPlugins(IInterpreterContext context) {
+ /*
+ * use the VSM resource to declare dependent project/bundles.
+ */
+ EObject vsmElement = context.getElement();
+ Set<String> projectsOrBundleInScope = Sets.newLinkedHashSet();
+ if (vsmElement != null && vsmElement.eResource() != null) {
+ collectProjectName(vsmElement.eResource(), projectsOrBundleInScope);
+ if (vsmElement.eResource().getResourceSet() != null) {
+ for (Resource other : vsmElement.eResource().getResourceSet().getResources()) {
+ if (other != vsmElement.eResource()) {
+ collectProjectName(other, projectsOrBundleInScope);
+ }
+ }
+ }
+ }
+ return projectsOrBundleInScope;
+ }
+
+ private static void collectProjectName(Resource eResource, Set<String> projectsOrBundleInScope) {
+ if (eResource.getURI() != null && eResource.getURI().segmentCount() >= 2) {
+ URI vsmURI = eResource.getURI();
+ String bundleOrProjectName = vsmURI.segment(1);
+ if (!StringUtil.isEmpty(bundleOrProjectName)) {
+ projectsOrBundleInScope.add(bundleOrProjectName);
+ }
+
+ }
+ }
+
+ /**
+ * Utility method to compare two contexts in order to detect if it is
+ * necessary to re-configure an {@link IInterpreter}.
+ *
+ * Only the information related to the search scope of an IInterpreter are
+ * compared : the available metamodels, the imported classes, the available
+ * EPackages.
+ *
+ * @param a
+ * a context.
+ * @param b
+ * another context.
+ * @return true if both context have the same scope definition, false
+ * otherwise.
+ */
+ public static boolean haveSameScopeDefinition(IInterpreterContext a, IInterpreterContext b) {
+ Set<String> aDependencies = Sets.newLinkedHashSet(a.getDependencies());
+ Set<String> bDependencies = Sets.newLinkedHashSet(b.getDependencies());
+ Set<String> aNSURI = collectNSUris(a);
+ Set<String> bNSURI = collectNSUris(b);
+ Set<String> aProjects = collectProjectsOrPlugins(a);
+ Set<String> bProjects = collectProjectsOrPlugins(b);
+ return aDependencies.equals(bDependencies) && aNSURI.equals(bNSURI) && aProjects.equals(bProjects);
+ }
+
+ private static Set<String> collectNSUris(IInterpreterContext a) {
+ Set<String> aNSURI = Sets.newLinkedHashSet();
+ for (EPackage pak : a.getAvailableEPackages()) {
+ String nsURI = pak.getNsURI();
+ if (!StringUtil.isEmpty(nsURI)) {
+ aNSURI.add(nsURI);
+ }
+ }
+ return aNSURI;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
index d40dd1e496..ba486a23c7 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
@@ -273,6 +273,14 @@
<li>The class
<code>org.eclipse.sirius.common.tools.api.interpreter.VariableType</code> has been introduced to represent the possible types a variable can have in a Viewpoint specification model.
</li>
+ <li>The utility class
+ <code>org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContextUtils</code> has been introduced to factorize code related to managing
+ <code>IInterpreterContext</code> instances.
+ </li>
+ <li>The class
+ <code>org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator</code> has been introduced to provide a safe and more efficient way to switch to the proper
+ <code>IInterpreter</code> instance when validating expressions.
+ </li>
</ul>
<h4 id="Changesinorg.eclipse.sirius.common.ui">Changes in
<code>org.eclipse.sirius.common.ui</code>
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
index 82c5f8aa62..592f0dcbaa 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
@@ -76,6 +76,8 @@ h4. Changes in @org.eclipse.sirius.common@
* The class @org.eclipse.sirius.common.tools.api.interpreter.TypeName@ has been introduced to represent in the codebase any type which was previously represented as a plain String.
* A new interface @org.eclipse.sirius.common.tools.api.interpreter.TypedValidation@ has been introduced for @IInterpreter@ implementations able to provide richer information when validating an expression. This information is captured through a @org.eclipse.sirius.common.tools.api.interpreter.ValidationResult@ instance.
* The class @org.eclipse.sirius.common.tools.api.interpreter.VariableType@ has been introduced to represent the possible types a variable can have in a Viewpoint specification model.
+* The utility class @org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContextUtils@ has been introduced to factorize code related to managing @IInterpreterContext@ instances.
+* The class @org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator@ has been introduced to provide a safe and more efficient way to switch to the proper @IInterpreter@ instance when validating expressions.
h4. Changes in @org.eclipse.sirius.common.ui@
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/IInterpreterValidationExpressionTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/IInterpreterValidationExpressionTest.java
index 1c2f611c69..026d0fb3dd 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/IInterpreterValidationExpressionTest.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/mtl/IInterpreterValidationExpressionTest.java
@@ -120,7 +120,7 @@ public class IInterpreterValidationExpressionTest extends SiriusDiagramTestCase
odesignEditor = page.openEditor(new FileEditorInput(odesignFile), "org.eclipse.sirius.editor.editorPlugin.SiriusEditorID");
ResourceSet rs = new ResourceSetImpl();
- Resource r = rs.getResource(URI.createURI(odesignFile.getLocationURI().toString()), true);
+ Resource r = rs.getResource(URI.createPlatformResourceURI(odesignFile.getFullPath().toOSString(), true), true);
// A CrossReferenceAdapter is needed for validation to work. In the
// standard VSM editor, one is installed on the constructor (see
// org.eclipse.sirius.editor.tools.internal.presentation.CustomSiriusEditor.CustomSiriusEditor()).
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
index d2dbadbadd..12ded3a2f8 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
@@ -26,6 +26,10 @@ import org.eclipse.sirius.tests.support.api.EclipseTestsSupportHelper;
import org.eclipse.sirius.tests.support.api.SiriusDiagramTestCase;
import org.eclipse.sirius.viewpoint.description.Group;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
/**
* Test VSM validation. VP-2506, VP-2475, VP-3836
*
@@ -191,8 +195,17 @@ public class VSMValidationTest extends SiriusDiagramTestCase {
"^The image ' /org.eclipse.sirius.tests.junit/images/logo_o.png ' does not exist.$", "^The image '/test/noimage.gif' does not exist.$",
"^The path 'icon' does not correspond to an image.$", "^The image 'icon' does not exist.$", "^The path '/org.eclipse.sirius.tests.junit/plugin.xml' does not correspond to an image.$",
"^The image 'C:\\\\images\\\\image.png' does not exist.$", "^The image '/org.eclipse.sirius.tests.junit/images/notexisting.png' does not exist.$",
- "^The required feature 'decoratorPath' of 'org.eclipse.sirius.viewpoint.description.impl.SemanticBasedDecorationImpl@.*' must be set$", };
- assertEquals("The diagnostic must contain " + expectedMessagesPatterns.length + " validation errors", expectedMessagesPatterns.length, children.size());
+ "^The required feature 'decoratorPath' of 'org.eclipse.sirius.viewpoint.description.impl.SemanticBasedDecorationImpl@.*' must be set$"};
+
+ assertEquals(
+ "The diagnostic must contain " + expectedMessagesPatterns.length + " validation errors. Returned messages were :\n"
+ + Joiner.on('\n').join(Iterables.transform(children, new Function<Diagnostic, String>() {
+
+ @Override
+ public String apply(Diagnostic input) {
+ return input.getMessage();
+ }
+ })), expectedMessagesPatterns.length, children.size());
for (int i = 0; i < expectedMessagesPatterns.length; i++) {
assertTrue("Unexpected validation error at position " + i, children.get(i).getMessage().matches(expectedMessagesPatterns[i]));
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
index d6fdcc4637..aa7a60fdad 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java
@@ -23,11 +23,8 @@ import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.sirius.business.api.query.EObjectQuery;
-import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
-import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
-import org.eclipse.sirius.common.tools.api.interpreter.TypedValidation;
import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
@@ -364,15 +361,10 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted
appendAllLocalVariableDefinitions(definitions, context);
if (context instanceof ChangeContext && context != bottom) {
ChangeContext f = (ChangeContext) context;
-
- IInterpreter interpreterForExpression = CompoundInterpreter.INSTANCE.getInterpreterForExpression(f.getBrowseExpression());
-
- if (interpreterForExpression.supportsValidation() && interpreterForExpression instanceof TypedValidation) {
- IInterpreterContext iContext = SiriusInterpreterContextFactory.createInterpreterContext(f, ToolPackage.Literals.CHANGE_CONTEXT__BROWSE_EXPRESSION);
- ValidationResult res = ((TypedValidation) interpreterForExpression).analyzeExpression(iContext, f.getBrowseExpression());
- VariableType returnTypes = res.getReturnTypes();
- changeSelfType(definitions, returnTypes);
- }
+ IInterpreterContext iContext = SiriusInterpreterContextFactory.createInterpreterContext(f, ToolPackage.Literals.CHANGE_CONTEXT__BROWSE_EXPRESSION);
+ ValidationResult res = MultiLanguagesValidator.getInstance().validateExpression(iContext, f.getBrowseExpression());
+ VariableType returnTypes = res.getReturnTypes();
+ changeSelfType(definitions, returnTypes);
}
if (context instanceof CreateInstance) {
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/MultiLanguagesValidator.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/MultiLanguagesValidator.java
new file mode 100644
index 0000000000..a1d8c4c5c8
--- /dev/null
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/MultiLanguagesValidator.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.sirius.business.api.dialect.description;
+
+import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContextUtils;
+import org.eclipse.sirius.common.tools.api.interpreter.TypedValidation;
+import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
+
+/**
+ * A common entry point to get validation for all the {@link IInterpreter}. The
+ * actual {@link IInterpreter} implementation which is going to be call depends
+ * on the given expression. This class guarantees that when the context changes,
+ * the IInterpreter's configuration regarding available metamodels or imported
+ * classes will be adapted.
+ *
+ * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a>
+ *
+ */
+public final class MultiLanguagesValidator {
+
+ private IInterpreter currentInterpreter;
+
+ private IInterpreterContext currentContext;
+
+ /**
+ * Analyze the expression and provide a validation result. This method will
+ * dynamically re-configure the required interpreter based on the given
+ * context.
+ *
+ * @param context
+ * the {@link IInterpreterContext} to use for validating this
+ * expression
+ * @param expression
+ * the expression to analyze
+ * @return the validation result.
+ */
+ public ValidationResult validateExpression(IInterpreterContext context, String expression) {
+ IInterpreter interpreter = provide(context, expression);
+ ValidationResult result = new ValidationResult();
+ if (interpreter instanceof TypedValidation) {
+ result = ((TypedValidation) interpreter).analyzeExpression(context, expression);
+ } else if (interpreter != null && interpreter.supportsValidation()) {
+ result.addAllStatus(interpreter.validateExpression(context, expression));
+ }
+ return result;
+ }
+
+ private IInterpreter provide(IInterpreterContext context, String expression) {
+ if (currentContext == null) {
+ createNewInterpreter(context, expression);
+ } else {
+ if (!IInterpreterContextUtils.haveSameScopeDefinition(context, currentContext)) {
+ if (currentInterpreter != null) {
+ currentInterpreter.dispose();
+ }
+ createNewInterpreter(context, expression);
+ }
+ }
+
+ return currentInterpreter;
+ }
+
+ void createNewInterpreter(IInterpreterContext context, String expression) {
+ currentContext = context;
+ currentInterpreter = CompoundInterpreter.createGenericInterpreter();
+ IInterpreterContextUtils.configureInterpreter(currentInterpreter, context);
+ }
+
+ /**
+ * Clear any internal state which would have been kept.
+ */
+ public void dispose() {
+ if (this.currentInterpreter != null) {
+ this.currentInterpreter.dispose();
+ this.currentInterpreter = null;
+ }
+ if (this.currentContext != null) {
+ this.currentContext = null;
+ }
+ }
+
+ /**
+ * Returns the shared instance.
+ *
+ * @return the global viewpoints registry.
+ */
+ public static MultiLanguagesValidator getInstance() {
+ return MultiLanguagesValidatorHolder.instance;
+ }
+
+ private static class MultiLanguagesValidatorHolder {
+ private static MultiLanguagesValidator instance;
+ static {
+ instance = new MultiLanguagesValidator();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidInterpretedExpressionConstraint.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidInterpretedExpressionConstraint.java
index 4813a67bdb..d31faf88c1 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidInterpretedExpressionConstraint.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidInterpretedExpressionConstraint.java
@@ -19,10 +19,10 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.emf.validation.model.ConstraintStatus;
-import org.eclipse.sirius.common.tools.api.interpreter.CompoundInterpreter;
-import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
import org.eclipse.sirius.tools.internal.validation.AbstractConstraint;
import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
@@ -74,13 +74,11 @@ public class ValidInterpretedExpressionConstraint extends AbstractConstraint {
private IStatus checkExpression(IValidationContext ctx, EObject target, EStructuralFeature feature) {
String expression = (String) target.eGet(feature);
- IInterpreter interpreterForExpression = CompoundInterpreter.INSTANCE.getInterpreterForExpression(expression);
Collection<IInterpreterStatus> errors = Sets.newLinkedHashSet();
- if (interpreterForExpression.supportsValidation()) {
+ if (!StringUtil.isEmpty(expression)) {
IInterpreterContext context = SiriusInterpreterContextFactory.createInterpreterContext(target, feature);
-
- errors = interpreterForExpression.validateExpression(context, expression);
+ errors = MultiLanguagesValidator.getInstance().validateExpression(context, expression).getStatuses();
}
if (errors.isEmpty()) {
@@ -101,4 +99,5 @@ public class ValidInterpretedExpressionConstraint extends AbstractConstraint {
}
return returnStatus;
}
+
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java
index 7a59a36e8c..22a5c551bc 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java
@@ -19,6 +19,7 @@ import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.sirius.business.api.componentization.ViewpointRegistry;
+import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator;
import org.eclipse.sirius.business.api.helper.SiriusUtil;
import org.eclipse.sirius.business.internal.helper.delete.DeleteHookDescriptorRegistryListener;
import org.eclipse.sirius.business.internal.session.factory.SessionFactoryRegistryListener;
@@ -158,7 +159,8 @@ public final class SiriusPlugin extends EMFPlugin {
javaActionRegistryListener = null;
ViewpointRegistry.getInstance().dispose();
-
+
+ MultiLanguagesValidator.getInstance().dispose();
super.stop(context);
}

Back to the top