package org.eclipse.gmf.tooling.runtime.impl.ocl.tracker.impactanalyzer; 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.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.tooling.runtime.ocl.tracker.OclTracker; import org.eclipse.gmf.tooling.runtime.ocl.tracker.OclTrackerBase; import org.eclipse.ocl.ParserException; import org.eclipse.ocl.ecore.EcoreEnvironmentFactory; import org.eclipse.ocl.ecore.OCL; import org.eclipse.ocl.ecore.OCL.Helper; import org.eclipse.ocl.ecore.OCLExpression; import org.eclipse.ocl.examples.eventmanager.EventFilter; import org.eclipse.ocl.examples.eventmanager.EventManager; import org.eclipse.ocl.examples.eventmanager.EventManagerFactory; import org.eclipse.ocl.examples.impactanalyzer.ImpactAnalyzer; import org.eclipse.ocl.examples.impactanalyzer.ImpactAnalyzerFactory; import org.eclipse.ocl.examples.impactanalyzer.util.OCLFactory; public class ImpactAnalyzerTracker extends OclTrackerBase { private OCL myOcl; private OCLExpression myExpression; private ImpactAnalyzer myImpactAnalyzer; private EventFilter myFilter; private EventManager myEventManager; private Adapter myAdapter; private boolean myActual = false; private Object myValue; private final boolean myCached; private boolean myInitialized = false; public ImpactAnalyzerTracker(String expressionBody, boolean cached) { super(expressionBody); myCached = cached; } @Override protected void doInitialize() { if (myInitialized) { return; } myInitialized = true; myOcl = OCL.newInstance(new EcoreEnvironmentFactory()); Helper helper = myOcl.createOCLHelper(); helper.setContext(getContext().eClass()); try { myExpression = helper.createQuery(getExpressionBody()); } catch (ParserException e) { throw new RuntimeException(e); } myImpactAnalyzer = ImpactAnalyzerFactory.INSTANCE.createImpactAnalyzer(myExpression, // the expression to re-evaluate incrementally true, // whether to re-evaluate when new context objects appear OCLFactory.getInstance()); myFilter = myImpactAnalyzer.createFilterForExpression(); } @Override public void installListeners(TransactionalEditingDomain domain, final NotificationListener listener, OclTracker.Registrator registrator) { myEventManager = EventManagerFactory.eINSTANCE.getEventManagerFor(domain.getResourceSet()); myAdapter = new AdapterImpl() { @Override public void notifyChanged(Notification msg) { listener.notifyChanged(msg); } }; myEventManager.subscribe(myFilter, myAdapter); } @Override public void uninstallListeners() { if (myEventManager == null) { return; } myEventManager.unsubscribe(myAdapter); } @Override public final Object getValue() { if (!isCached() || !myActual) { myValue = doGetValue(); myActual = true; } return myValue; } @Override public final boolean handleNotification(Notification notification) { if ((!isCached() || myActual) && doHandleNotification(notification)) { myActual = false; return true; } return false; } private Object doGetValue() { return myOcl.evaluate(getContext(), myExpression); } private boolean doHandleNotification(Notification notification) { return myImpactAnalyzer.getContextObjects(notification).contains(getContext()); } private boolean isCached() { return myCached; } }