[EVL] Epsilon validation for multiple diagrams on a single model?! [message #736829] |
Fri, 14 October 2011 11:17 |
Hristina Moneva Messages: 31 Registered: October 2009 |
Member |
|
|
Hi all,
I am trying to use Epsilon Validation on my GMF diagrams, but I run into a problem...
The situation is as follows: I have a single model and two diagrams (using shared editing domain). One of the diagrams corresponds to the root of my model and represents only a few elements. From there a sub-diagram ca be initiated that visualizes but part of the full model. When I add the validation, it works fine on the main diagram (no exceptions raised, but I do not have any validation there as well) but it always raises exception on the sub-diagram... The exception is:
!ENTRY nl.esi.design.diagram.view 4 0 2011-10-14 13:10:56.384
!MESSAGE Validation failed
!STACK 0
java.lang.NullPointerException
at org.eclipse.epsilon.evl.emf.validation.EvlValidator.validate(EvlValidator.java:76)
at org.eclipse.epsilon.evl.emf.validation.CompositeEValidator.validate(CompositeEValidator.java:44)
at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:165)
at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:143)
at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:114)
at nl.esi.design.diagram.view.part.ValidateAction.runEMFValidator(ValidateAction.java:159)
at nl.esi.design.diagram.view.part.ValidateAction.validate(ValidateAction.java:173)
at nl.esi.design.diagram.view.part.ValidateAction.access$0(ValidateAction.java:167)
at nl.esi.design.diagram.view.part.ValidateAction$2.run(ValidateAction.java:144)
at nl.esi.design.diagram.view.providers.DesignValidationProvider$1.run(DesignValidationProvider.java:62)
at org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.runExclusive(TransactionalEditingDomainImpl.java:328)
at nl.esi.design.diagram.view.providers.DesignValidationProvider.runWithConstraints(DesignValidationProvider.java:70)
at nl.esi.design.diagram.view.part.ValidateAction.runValidation(ValidateAction.java:141)
at nl.esi.design.diagram.view.part.ValidateAction$1.run(ValidateAction.java:89)
at org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation.execute(WorkspaceModifyDelegatingOperation.java:69)
at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
at nl.esi.design.diagram.view.part.ValidateAction.run(ValidateAction.java:92)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
When I was debugging and looking at the code, the only thing that I can find "wrong" is that the Epsilon Validation assumes that it takes diagram that corresponds to the root of the model, see EvlValidator class, validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) method, lines 69-74:
// If it is the root that is validated
// validate the whole resource and cache
// the results
if (eObject.eContainer() == null) {
results = validate(eObject.eResource());
}
The exception raised is just the next line:
Collection<EvlUnsatisfiedConstraint> unsatisfiedConstraints = results.get(eObject);
The problem is that "results" is null.
That assumption (check) would never be correct for diagrams that do not start from the root of a model as well! Even if not multiple diagrams for a single model...
I am not sure if my understanding is correct! But if yes, do you plan to remove this check and enable validating "partial" models?!
That can be also beneficial for cases where not the full model has to be validated. I believe that is very reasonable and required use case...
Looking forward you reply!
Greetings,
Hristina
|
|
|
Re: [EVL] Epsilon validation for multiple diagrams on a single model?! [message #736914 is a reply to message #736829] |
Fri, 14 October 2011 13:11 |
Hristina Moneva Messages: 31 Registered: October 2009 |
Member |
|
|
Small update...
I found temporal solution for now, but now the Quick Fixes do not work...
Clarification: I call the solution temporal, because it is not really good solution and this issue really have to be tackled in Epsilon Validation itself.
The solution is as follows:
I your diagram project, something.diagram.view.part package, ValidateAction class, runEMFValidator(View target) method --> replace the "target.getElement()" with your model root element. See example below.
/**
* @generated NOT
*/
private static Diagnostic runEMFValidator(View target) {
if (target.isSetElement() && target.getElement() != null) {
return new Diagnostician() {
public String getObjectLabel(EObject eObject) {
return EMFCoreUtil.getQualifiedName(eObject, true);
}
//}.validate(target.getElement());
}.validate( ...<your model root element here!>... );
}
return Diagnostic.OK_INSTANCE;
}
In this way, the exception from the post above is avoided, because we feed Epsilon Validation with the expected model root element.
With this solution, all constrains and critiques are found and executed correctly, but... this time the Quick Fixes fail to be found!!!
More details about the Quick Fixes problem... There are three possible situations: 1) when the validation is called from the top-level diagram, 2) when it is called from the sub-diagram which is invoked from the top-level diagram (so it is seen as part of it or with other words it has the type of the top-level diagram), and 3) when it is called from sub-diagram which is separate file (in contrast with case 2, it is seen as its own type).
Now, when we execute the validation in all these situations, the Quick Fixes are found only in case 3, in the first two situations - they are not found at all and the following exception is raised:
java.lang.NullPointerException
at org.eclipse.epsilon.evl.emf.validation.GmfMarkerResolver.getAbsoluteElementId(GmfMarkerResolver.java:33)
at org.eclipse.epsilon.evl.emf.validation.EvlMarkerResolverManager.getAbsoluteElementId(EvlMarkerResolverManager.java:51)
at org.eclipse.epsilon.evl.emf.validation.EvlMarkerResolutionGenerator.getResolutions(EvlMarkerResolutionGenerator.java:51)
at org.eclipse.epsilon.evl.emf.validation.EvlMarkerResolutionGenerator.getResolutions(EvlMarkerResolutionGenerator.java:43)
at org.eclipse.ui.internal.ide.registry.MarkerHelpRegistry.getResolutions(MarkerHelpRegistry.java:253)
at org.eclipse.ui.internal.views.markers.QuickFixHandler$1.run(QuickFixHandler.java:87)
at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:507)
at org.eclipse.ui.internal.progress.ProgressManager$RunnableWithStatus.run(ProgressManager.java:1346)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.progress.ProgressManager$7.run(ProgressManager.java:1184)
at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179)
at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
at org.eclipse.swt.widgets.Display.syncExec(Display.java:4584)
at org.eclipse.ui.internal.progress.ProgressManager.runInUI(ProgressManager.java:1182)
at org.eclipse.ui.internal.progress.WorkbenchSiteProgressService.runInUI(WorkbenchSiteProgressService.java:376)
at org.eclipse.ui.internal.views.markers.QuickFixHandler.execute(QuickFixHandler.java:124)
at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293)
at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476)
at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169)
at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241)
at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241)
at org.eclipse.ui.menus.CommandContributionItem.handleWidgetSelection(CommandContributionItem.java:820)
at org.eclipse.ui.menus.CommandContributionItem.access$19(CommandContributionItem.java:806)
at org.eclipse.ui.menus.CommandContributionItem$5.handleEvent(CommandContributionItem.java:796)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
I am looking for any ideas how to overcome this one!
Greetings,
Hristina
|
|
|
|
|
|
|
|
|
|
|
|
Re: [EVL] Epsilon validation for multiple diagrams on a single model?! [message #988508 is a reply to message #988499] |
Fri, 30 November 2012 10:04 |
|
Hi Maarten,
To support incremental validation, a constraint language needs to be statically typed so that impact analysis can be performed when something changes in the model and a set of "dirty" objects/constraints that need to be re-validated can be computed. EVL is dynamically-typed by design and as such it doesn't lend itself to static/impact analysis. One of my colleagues is currently working on a relaxed approach for static analysis of Epsilon programs which should eventually make this possible but I don't foresee releasing any publicly-available tools within the next year or so.
Having said this, there has been work on incremental evaluation of OCL constraints (OCL is statically typed); I believe the Eclipse OCL implementation provides some support for this [1]. To explore this direction further I'd suggest googling for "incremental OCL" and also checking out the EMF-IncQuery project http://viatra.inf.mit.bme.hu/incquery.
Cheers,
Dimitris
[1] http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.ocl.doc%2Fhelp%2FImpactAnalyzer.html
|
|
|
|
Re: [EVL] Epsilon validation for multiple diagrams on a single model?! [message #988513 is a reply to message #988509] |
Fri, 30 November 2012 10:25 |
|
Hi Maarten,
This would indeed be a partial solution to the problem as often not only modified objects need to be revalidated. For example consider the following scenario
class A {
ref B[*] bs;
}
class B {
attr String name;
}
context A {
constraint X {
check : self.bs.forAll(b|b.name <> "foo")
}
}
If a B is modified, all A's that link to it need to be revalidated - which one can't tell unless one is able to analyse constraint X.
In any case extending EvlModule to support validating only selected objects shouldn't be too much work (start by adding an execute(Collection objects) method and propagate downstream). I've added this to my todo list but any help with this would be also appreciated.
Cheers,
Dimitris
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05248 seconds