package org.eclipse.gmf.tooling.runtime.edit.policies.effect; import java.util.Collections; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy; import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.Style; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.gmf.tooling.runtime.GMFToolingRuntimePlugin; import org.eclipse.gmf.tooling.runtime.ocl.tracker.OclTracker; import org.eclipse.gmf.tooling.runtime.ocl.tracker.OclTracker.Registrator; import org.eclipse.gmf.tooling.runtime.ocl.tracker.OclTrackerFactory; public abstract class AbstractOclVisualEffectEditPolicy extends CanonicalEditPolicy { private OclTracker myOclTracker; private Registrator myOclRegistrator; private final OclTrackerFactory myOclTrackerFactory; protected abstract String getExpressionBody(); public AbstractOclVisualEffectEditPolicy() { this(GMFToolingRuntimePlugin.getInstance().getOclTrackerFactory()); } public AbstractOclVisualEffectEditPolicy(OclTrackerFactory.Type factoryType) { this(GMFToolingRuntimePlugin.getInstance().getOclTrackerFactory(factoryType)); } public AbstractOclVisualEffectEditPolicy(OclTrackerFactory factory) { myOclTrackerFactory = factory; } private OclTracker getOclTracker() { if (myOclTracker == null) { myOclTracker = myOclTrackerFactory.createOclTracker(getExpressionBody(), false); } return myOclTracker; } private boolean initializeOclTracker() { EObject context = getContext(); if (context == null) { return false; } getOclTracker().initialize(context); return true; } protected EObject getContext() { return getSemanticHost(); } // TODO: never called from hierarchy since handleNotificationEvent is overriden @Override protected boolean shouldHandleNotificationEvent(Notification event) { return getOclTracker().handleNotification(event); } private void installVisualEffect() { if (!initializeOclTracker()) { return; } getOclTracker().installListeners(getHostImpl().getEditingDomain(), // new NotificationListener() { public void notifyChanged(Notification notification) { refreshVisualEffect(); } }, getOclRegistrator()); } @Override public void activate() { super.activate(); installVisualEffect(); refreshVisualEffect(); } @Override protected void refreshSemantic() { //Important - we are NOT actually CanonicalEditPolicy, and not capable to perform semantic refresh //We extends CanonicalEditPolicy //super.refreshSemantic(); } @Override public void deactivate() { getOclTracker().uninstallListeners(); super.deactivate(); } private void refreshVisualEffect() { if (!initializeOclTracker()) { return; } setVisualEffectValue(getOclTracker().getValue()); } protected abstract void setVisualEffectValue(Object value); @Override protected void handleNotificationEvent(Notification event) { if (shouldHandleNotificationEvent(event)) { refreshVisualEffect(); } } protected final void executeICommand(ICommand command) { executeCommand(new ICommandProxy(command)); } protected IGraphicalEditPart getHostImpl() { return (IGraphicalEditPart) getHost(); } /** * We are using CanonicalEditPolicy infrastructure for listening to the * model, executing commands, etc. However, we are not going to * install/remove any new children from view-tree. */ @Override protected final List<EObject> getSemanticChildrenList() { return Collections.emptyList(); } protected final void ensureHasStyle(EClass styleClass) { if (!NotationPackage.eINSTANCE.getStyle().isSuperTypeOf(styleClass)) { throw new IllegalArgumentException("Notation Style expected:" + styleClass); //$NON-NLS-1$ } IGraphicalEditPart editPart = getHostImpl(); View view = editPart.getNotationView(); Style style = view.getStyle(styleClass); if (style == null) { style = (Style) styleClass.getEPackage().getEFactoryInstance().create(styleClass); SetRequest request = new SetRequest(editPart.getEditingDomain(), view, NotationPackage.eINSTANCE.getView_Styles(), style); executeICommand(new SetValueCommand(request)); } } protected final Registrator getOclRegistrator() { if (myOclRegistrator == null) { myOclRegistrator = new Registrator() { public void registerListener(String filterId, NotificationListener listener, EObject element) { addListenerFilter(filterId, listener, element); } public void unregisterListener(String filterId) { removeListenerFilter(filterId); } }; } return myOclRegistrator; } }