[516363] Add parent EClass in revalidation for EParameters & MapEntry
Bug: 516363
Change-Id: I391e8ea440d53cd78bb58c1949a01cdebe73362a
diff --git a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/LiveValidationTrigger.java b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/LiveValidationTrigger.java
index a5dfce3..3a3d0c4 100644
--- a/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/LiveValidationTrigger.java
+++ b/org.eclipse.emf.ecoretools.design/src/org/eclipse/emf/ecoretools/design/service/LiveValidationTrigger.java
@@ -17,9 +17,12 @@
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.RecordingCommand;
@@ -32,101 +35,107 @@
public class LiveValidationTrigger implements ModelChangeTrigger {
- public static final NotificationFilter IS_ECORE_CHANGE = new NotificationFilter.Custom() {
+ public static final NotificationFilter IS_ECORE_CHANGE = new NotificationFilter.Custom() {
- public boolean matches(Notification notification) {
- return (!notification.isTouch() && notification.getFeature() instanceof EStructuralFeature && ((EStructuralFeature) notification.getFeature()).getEContainingClass().getEPackage() == EcorePackage.eINSTANCE);
- }
- };
+ public boolean matches(Notification notification) {
+ return (!notification.isTouch() && notification.getFeature() instanceof EStructuralFeature
+ && ((EStructuralFeature) notification.getFeature()).getEContainingClass()
+ .getEPackage() == EcorePackage.eINSTANCE);
+ }
+ };
- private TransactionalEditingDomain domain;
+ private TransactionalEditingDomain domain;
- /**
- * We need to be triggered before the refresh mechanism takes place so that
- * the diagnostic attachements are up-to date when computing colors.
- */
- public static final int PRIORITY = 0;
+ /**
+ * We need to be triggered before the refresh mechanism takes place so that the
+ * diagnostic attachements are up-to date when computing colors.
+ */
+ public static final int PRIORITY = 0;
- public LiveValidationTrigger(TransactionalEditingDomain domain) {
- this.domain = domain;
- }
+ public LiveValidationTrigger(TransactionalEditingDomain domain) {
+ this.domain = domain;
+ }
- public Option<Command> localChangesAboutToCommit(Collection<Notification> notifications) {
- final Set<EObject> changedEcoreObjects = Sets.newLinkedHashSet();
- for (Notification notif : notifications) {
- Object obj = notif.getNotifier();
- if (obj instanceof EObject && ((EObject) obj).eClass() != null && ((EObject) obj).eClass().getEPackage() == EcorePackage.eINSTANCE) {
- changedEcoreObjects.add((EObject) obj);
- }
- }
- if (changedEcoreObjects.size() > 0) {
+ public Option<Command> localChangesAboutToCommit(Collection<Notification> notifications) {
+ final Set<EObject> changedEcoreObjects = Sets.newLinkedHashSet();
+ for (Notification notif : notifications) {
+ Object obj = notif.getNotifier();
+ if (obj instanceof EObject && ((EObject) obj).eClass() != null
+ && ((EObject) obj).eClass().getEPackage() == EcorePackage.eINSTANCE) {
+ changedEcoreObjects.add((EObject) obj);
+ }
+ }
+ if (changedEcoreObjects.size() > 0) {
- Command revalidateEObjects = new RecordingCommand(domain) {
+ Command revalidateEObjects = new RecordingCommand(domain) {
- @Override
- protected void doExecute() {
- Set<EObject> containers = Sets.newLinkedHashSet();
- for (EObject eObj : changedEcoreObjects) {
- revalidate(eObj);
- EObject container = eObj.eContainer();
- if (container != null) {
- containers.add(container);
- }
- }
- /*
- * When an Ecore object changes it is likely the container
- * might have a new validation error (or an error might be
- * gone) even if it has suffered no change itself. Example :
- * two EStructural features having the same name and
- * contained in the same EClass will trigger an error on
- * such EClass. This state should be updated when one of the
- * EStructuralFeature got renamed.
- */
- for (EObject container : containers) {
- revalidate(container);
- }
- }
+ @Override
+ protected void doExecute() {
+ Set<EObject> containers = Sets.newLinkedHashSet();
+ for (EObject eObj : changedEcoreObjects) {
+ revalidate(eObj);
+ EObject container = eObj.eContainer();
+ if (container != null) {
+ containers.add(container);
+ /*
+ * in the case of a changed EParameter or annotationwe really want to include
+ * the parent EClass in the revalidation.
+ */
+ if ((eObj instanceof EParameter || eObj instanceof EStringToStringMapEntryImpl)
+ && container.eContainer() instanceof EClass) {
+ containers.add(container.eContainer());
+ }
+ }
+ }
+ /*
+ * When an Ecore object changes it is likely the container might have a new
+ * validation error (or an error might be gone) even if it has suffered no
+ * change itself. Example : two EStructural features having the same name and
+ * contained in the same EClass will trigger an error on such EClass. This state
+ * should be updated when one of the EStructuralFeature got renamed.
+ */
+ for (EObject container : containers) {
+ revalidate(container);
+ }
+ }
- protected void revalidate(EObject eObj) {
- DiagnosticAttachment diag = DiagnosticAttachment.getAttachment(eObj);
- /*
- * If the EObject had a validation marker, then we need to
- * update its state, otherwise nobody cared about its
- * validation status, no need to pre-compute it.
- */
- if (diag != null) {
- try {
- /*
- * anything could happen within the validate. We
- * make sure we won't fail the whole post-process in
- * this case.
- */
- Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
- /*
- * We attach the result of the validation on the
- * EObject through the eAdapters list. It might be
- * consumed by some modelers to change colors or
- * update tooltips.
- */
- diag.setDiagnostic(diagnostic);
- } catch (Throwable e) {
- /*
- * Anything which happens here might not be a
- * concern.
- */
- }
- }
- }
- };
+ protected void revalidate(EObject eObj) {
+ DiagnosticAttachment diag = DiagnosticAttachment.getAttachment(eObj);
+ /*
+ * If the EObject had a validation marker, then we need to update its state,
+ * otherwise nobody cared about its validation status, no need to pre-compute
+ * it.
+ */
+ if (diag != null) {
+ try {
+ /*
+ * anything could happen within the validate. We make sure we won't fail the
+ * whole post-process in this case.
+ */
+ Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj);
+ /*
+ * We attach the result of the validation on the EObject through the eAdapters
+ * list. It might be consumed by some modelers to change colors or update
+ * tooltips.
+ */
+ diag.setDiagnostic(diagnostic);
+ } catch (Throwable e) {
+ /*
+ * Anything which happens here might not be a concern.
+ */
+ }
+ }
+ }
+ };
- return Options.newSome(revalidateEObjects);
- }
+ return Options.newSome(revalidateEObjects);
+ }
- return Options.newNone();
- }
+ return Options.newNone();
+ }
- public int priority() {
- return PRIORITY;
- }
+ public int priority() {
+ return PRIORITY;
+ }
}