Next I have registered a custom AbstractModelConstraint class to the constraintProviders extension point, where I invoke a custom Diagnostican object to collect all errors from the validation to embed them in a ContraintStatus.Multi (compound) status list. Which is fed to my custom validation listener.

As fas as I know, this is the route to have/combine life and batch validations, markers, EMF, and EVL validation in an application.

The context of the Diagnostican object, is available in EvlValidator, see Bug #395261. So, in a similar way a variable could be passed to the EvlValidator, like the bug report does for the progress monitor.

Currently I have the following added to the EvlValidator#validate(Resource Map<Object, Object>) to get make the variable/value available:

So basically, I grab the value of the variable from the context of the Diagnostican. But in a hack-ish way

But, I was wondering whether there is another/nicer way to pass a variable/value to the EVL validation rules...
If not, I am willing to think of a more generic solution and provide a patch (if you guys want this feature of course!)

Well, from a look at Dimitris' fix for bug 395261, it seems we are *almost* there: as you say, we already have the Diagnostician context in EvlValidator#validate(Resource, Map).

The main problem with making this sort of change is ensuring that we don't break existing EVL code. We could always expose the Map object as a variable with a name that will not conflict with the user's variables, e.g. "diagnosticianContext". I don't see many people using this name for something different, but if necessary we could only enable this new behaviour if the developer enabled it in the constraintsBinding extension.

In fact, if we implement the new boolean setting in constraintsBinding, we could do something better than diagnosticianContext.get("MyVarValue"): we could map the "MyVarValue" entry directly to the "MyVarValue" variable.

I think this second way would be both safe and convenient. You'd probably need to add a get/setPropagateDiagnosticianContext(...) pair to EvlValidator and act upon it in #validate(Resource, Map). Then you'd need to query the extension attribute and invoke the set method appropriately in EValidatorPopulator#earlyStartup().

If you could whip up a patch for this, I'd be happy to review it and try it out .

In fact, if we implement the new boolean setting in constraintsBinding, we could do something better than diagnosticianContext.get("MyVarValue"): we could map the "MyVarValue" entry directly to the "MyVarValue" variable.

I think this second way would be both safe and convenient. You'd probably need to add a get/setPropagateDiagnosticianContext(...) pair to EvlValidator and act upon it in #validate(Resource, Map). Then you'd need to query the extension attribute and invoke the set method appropriately in EValidatorPopulator#earlyStartup().

You mean setting the variable and its value in the constraintsBinding? The value is changing at run-time, so that is not really possible.

I could add a custom key, e.g. "EvlValidatorVariable", with a map as its value. The map then contains the variable/value pairs. If the key is not set, nothing changes, i.e. nothing breaks. If the is set, the variables are added to the EvlModule context.

A more complex method would be to add the variable names to the contextBinding and used these names to grab the values from the context. Thereby, circumventing the map. But it needs more support (and has probably more ways to break?)

You mean setting the variable and its value in the constraintsBinding? The value is changing at run-time, so that is not really possible.

No, not that. It'd be just a boolean flag for enabling or disabling the propagation of Diagnostician context entries as EVL global variables.

Maarten Bezemer wrote on Mon, 09 September 2013 15:24

A more complex method would be to add the variable names to the contextBinding and used these names to grab the values from the context. Thereby, circumventing the map. But it needs more support (and has probably more ways to break?

This would provide finer control to the user and would also be a good idea. I don't see the problem myself: most users will leave this variable list empty, after all.

Going back to your example: I propose that by adding the "MyVarValue" name to the hypothetical "diagnosticianVariables" list field in the "constraintBinding" extension, EVL would expose the value associated to the "MyVarValue" key of the Diagnostician's context as the global variable "MyVarValue". This can be postponed until right before the EVL script is run, just like your custom code.