blob: b78dfb9dc5f84ee0609add0ddf3a0b1a2144719c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* SAP AG - initial API and implementation
******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.editor;
import java.util.Collection;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.opposites.DefaultOppositeEndFinder;
import org.eclipse.ocl.ecore.opposites.OppositeEndFinder;
import org.eclipse.ocl.examples.impactanalyzer.ImpactAnalyzer;
import org.eclipse.ocl.examples.impactanalyzer.util.OCLFactory;
/**
* Use at the end of your EMF sample editor's <code>createModel()</code> method to request
* instant re-validation of your editor's EMF model with corresponding error marker creation/deletion.
* Example:
* <pre>
public class MyEditor
extends MultiPageEditorPart
implements IEditingDomainProvider, ISelectionProvider, IMenuListener, IViewerProvider, IGotoMarker {
@SuppressWarnings("unused") // not read; just used to avoid GC from collecting re-validator
private Revalidator revalidator;
...
public void createModel() {
...
revalidator = new Revalidator(editingDomain.getResourceSet(), MyPackage.eINSTANCE);
}
...
}
* </pre>
* @author Axel Uhl (d043530)
*
*/
public class Revalidator extends org.eclipse.ocl.examples.impactanalyzer.Revalidator {
/**
* Uses a {@link DefaultOppositeEndFinder}
*/
public Revalidator(ResourceSet resourceSet, OCLFactory oclFactory,
EPackage... pkgs) {
super(resourceSet, oclFactory, pkgs);
}
/**
* Uses the default {@link OCLFactory#INSTANCE} to create {@link OCL} objects, as well as a
* {@link DefaultOppositeEndFinder}.
*/
public Revalidator(ResourceSet resourceSet, EPackage... pkgs) {
super(resourceSet, pkgs);
}
/**
* Uses the default {@link OCLFactory#INSTANCE} with the provided opposite end finder to create
* {@link OCL} instances
*/
public Revalidator(ResourceSet resourceSet, OCLFactory oclFactory,
OppositeEndFinder oppositeEndFinder, EPackage... pkgs) {
super(resourceSet, oclFactory, oppositeEndFinder, pkgs);
}
/**
* @param resourceSet used to create {@link OCL} instances
* @param oppositeEndFinder used to instantiate an {@link OCL} object using
* {@link OCLFactory#createOCL(OppositeEndFinder)}, and used for the {@link ImpactAnalyzer} when
* retrieving and navigating hidden opposite references as well as for evaluating
* <code>allInstances()</code> expressions
* @param pkgs the metamodel packages whose invariants to observe
*/
public Revalidator(ResourceSet resourceSet,
OppositeEndFinder oppositeEndFinder, EPackage... pkgs) {
super(resourceSet, oppositeEndFinder, pkgs);
}
/**
* Returns an adapter that will be
* {@link Adapter#notifyChanged(Notification) notified} when the constraint
* whose name is given by the <code>constraintName</code> parameter may have
* changed its value due to the change {@link Notification} delivered to the
* adapter. Using the <code>impactAnalyzer</code>'s
* {@link ImpactAnalyzer#getContextObjects(Notification)} operation the
* adapter can determine the context objects for which a re-evaluation may
* be necessary.
*
* @param constraintName
* name of the invariant / constraint that may have changed its
* value based on a model change
* @param invariant
* the OCL expression that defined the invariant / constraint
* @param impactAnalyzer
* can be used by the adapter to infer the context objects on
* which re-evaluation may be necessary
* @return an adapter that will be notified about model changes within the
* {@link ResourceSet} specified during construction of this
* {@link Revalidator} that may impact the value of the constraint /
* invariant specified by <code>constraintName</code> and
* <code>invariant</code>
*/
protected Adapter getAdapter(final String constraintName,
final OCLExpression invariant, final ImpactAnalyzer impactAnalyzer) {
Adapter adapter = new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
// revalidate invariant on context objects that impact analysis will produce:
Collection<EObject> revalidateOn = impactAnalyzer.getContextObjects(msg);
if (revalidateOn != null && !revalidateOn.isEmpty()) {
new RevalidateAction(constraintName, revalidateOn, invariant, getOclFactory(),
getOppositeEndFinder()).run();
}
}
};
return adapter;
}
}