Bug #416893: support diagnostician-based variables in evl.emf.integration
diff --git a/plugins/org.eclipse.epsilon.evl.emf.validation/schema/org.eclipse.epsilon.evl.emf.validation.exsd b/plugins/org.eclipse.epsilon.evl.emf.validation/schema/org.eclipse.epsilon.evl.emf.validation.exsd
index bb9e554..5fc4df5 100644
--- a/plugins/org.eclipse.epsilon.evl.emf.validation/schema/org.eclipse.epsilon.evl.emf.validation.exsd
+++ b/plugins/org.eclipse.epsilon.evl.emf.validation/schema/org.eclipse.epsilon.evl.emf.validation.exsd
@@ -57,6 +57,9 @@
          </documentation>
       </annotation>
       <complexType>
+         <sequence>
+            <element ref="diagnosticVariable" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
          <attribute name="namespaceURI" type="string" use="required">
             <annotation>
                <documentation>
@@ -98,6 +101,25 @@
       </complexType>
    </element>
 
+   <element name="diagnosticVariable">
+      <annotation>
+         <documentation>
+            Adds a new global variable with the specified name to the EVL script.
+
+The value of the variable is taken from the entry with the same name in the context map of the EMF Diagnostician.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The name of the variable, which is used as the key of the Diagnostican context.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
    <annotation>
       <appInfo>
          <meta.section type="apiInfo"/>
diff --git a/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EValidatorPopulator.java b/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EValidatorPopulator.java
index 877aae3..ed24fe4 100644
--- a/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EValidatorPopulator.java
+++ b/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EValidatorPopulator.java
@@ -59,6 +59,12 @@
 					String modelName = configurationElement.getAttribute("modelName");

 					if (modelName == null || modelName.trim().length() == 0) modelName = EvlValidator.DEFAULT_MODEL_NAME;

 					evlValidator = new EvlValidator(url.toURI(), modelName, ePackageUri, bundleId);

+

+					// Add variables for propagating EMF Diagnostician context entries

+					IConfigurationElement[] diagnosticVariables = configurationElement.getChildren("diagnosticVariable");

+					for (IConfigurationElement diagnosticVariable : diagnosticVariables) {

+						((EvlValidator) evlValidator).addDiagnosticianVariable(diagnosticVariable.getAttribute("name"));

+					}

 				}

 				else {

 					evlValidator = new OclValidator(url.toURI());

diff --git a/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EvlValidator.java b/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EvlValidator.java
index ab4e2fe..fc19903 100644
--- a/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EvlValidator.java
+++ b/plugins/org.eclipse.epsilon.evl.emf.validation/src/org/eclipse/epsilon/evl/emf/validation/EvlValidator.java
@@ -13,7 +13,9 @@
 import java.net.URI;

 import java.util.ArrayList;

 import java.util.Collection;

+import java.util.HashSet;

 import java.util.Map;

+import java.util.Set;

 

 import org.eclipse.core.runtime.IProgressMonitor;

 import org.eclipse.emf.common.util.BasicDiagnostic;

@@ -24,12 +26,14 @@
 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.emf.ecore.EValidator;

 import org.eclipse.emf.ecore.resource.Resource;

+import org.eclipse.emf.ecore.util.Diagnostician;

 import org.eclipse.epsilon.common.dt.util.LogUtil;

 import org.eclipse.epsilon.emc.emf.EmfPrettyPrinter;

 import org.eclipse.epsilon.emc.emf.InMemoryEmfModel;

-import org.eclipse.epsilon.eol.annotations.EolAnnotationsUtil;

 import org.eclipse.epsilon.eol.dt.launching.EclipseContextManager;

 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;

+import org.eclipse.epsilon.eol.execute.context.Variable;

+import org.eclipse.epsilon.eol.types.EolAnyType;

 import org.eclipse.epsilon.evl.EvlFixInstance;

 import org.eclipse.epsilon.evl.EvlModule;

 import org.eclipse.epsilon.evl.EvlUnsatisfiedConstraint;

@@ -38,6 +42,7 @@
 

 public class EvlValidator implements EValidator {

 

+	protected Set<String> diagnosticVariables = null;

 	protected EvlModule module = null;

 	protected URI source;

 	protected EmfPrettyPrinter printer = new EmfPrettyPrinter();

@@ -62,6 +67,27 @@
 		this.ePackageUri = ePackageUri;

 		this.bundleId = bundleId;

 	}

+

+	/**

+	 * <p>Indicates that the value of the entry of the {@link Diagnostician}

+	 * context {@link java.util.Map} with the specified <code>name</code> should

+	 * be published as a global variable in the EVL script. If the context map

+	 * does not contain an entry with the specified <code>name</code>, the variable

+	 * will be set to <code>null</code>.

+	 *

+	 * <p>Note: this map is received through the <code>validate</code> methods in this

+	 * class.</p>

+	 *

+	 * @see #validate(EObject, DiagnosticChain, Map)

+	 * @see #validate(EClass, EObject, DiagnosticChain, Map)

+	 * @see #validate(EDataType, Object, DiagnosticChain, Map)

+	 */

+	public void addDiagnosticianVariable(String name) {

+		if(diagnosticVariables == null) {

+			diagnosticVariables = new HashSet<String>();

+		}

+		diagnosticVariables.add(name);

+	}

 	

 	public boolean validate(EObject object, DiagnosticChain diagnostics,

 			Map<Object, Object> context) {

@@ -154,6 +180,16 @@
 			EclipseContextManager.setup(module.getContext());

 		}

 

+		// Add variables to the EvlModule to make the available to the EVL rules

+		if (diagnosticVariables != null) {

+			for (String diagnosticVariable : diagnosticVariables) {

+				final Variable variable = new Variable(diagnosticVariable,

+						context.get(diagnosticVariable),

+						EolAnyType.Instance);

+				module.getContext().getFrameStack().put(variable);

+			}

+		}

+

 		try {

 			module.execute();

 		} catch (EolRuntimeException e) {