package pyUML.listeners; import org.eclipse.gmf.runtime.common.ui.util.IWorkbenchPartDescriptor; import org.eclipse.gmf.runtime.common.ui.util.WorkbenchPartDescriptor; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.uml2.diagram.clazz.part.UMLDiagramEditor; import org.eclipse.uml2.diagram.clazz.part.ValidateAction; import org.eclipse.uml2.diagram.clazz.providers.UMLValidationDecoratorProvider; /** * This class is a listener that runs a live validation run, * when the listener is called. * Additionally, it provides static functions to run validation as a background * process which call the Validation run every n seconds. */ public class LiveValidationListener implements IPropertyListener{ private static LiveValidationListener singleton; private static boolean isStarted; private static int intervalSeconds = 3; private static IWorkbenchWindow workbenchWindow; private LiveValidationListener() { } /** * Gets the singleton instance of this listener */ public static LiveValidationListener getListenerSingleton() { if (LiveValidationListener.singleton == null) LiveValidationListener.singleton = new LiveValidationListener(); return LiveValidationListener.singleton; } /** * Runs a live validation process once. Uses the currently open * document for validation */ public static void startLiveValidation() { LiveValidationListener.getListenerSingleton().propertyChanged(null, 0); } /** * Listener method: On every change: do live validation run */ public void propertyChanged(Object o, int i) { IEditorPart ed; if (LiveValidationListener.workbenchWindow == null) LiveValidationListener.workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (LiveValidationListener.workbenchWindow == null) return; try { ed = LiveValidationListener.workbenchWindow.getActivePage().getActiveEditor(); } catch (NullPointerException e) { return; } if (!(ed instanceof UMLDiagramEditor)) return; UMLDiagramEditor umlEditor = (UMLDiagramEditor) ed; IWorkbenchPartDescriptor desc = new WorkbenchPartDescriptor(umlEditor.getSite().getId(), umlEditor.getSite().getClass(), umlEditor.getSite().getPage()); ValidateAction action = new ValidateAction(desc); UMLValidationDecoratorProvider.usedResource = umlEditor.getDiagram().eResource(); action.run(); } /** * Starts a live validation Thread in background. * The thread can be stopped with stopLiveValidationInBackground(). * Runs validation every getIntervalSeconds() seconds */ public static void startLiveValidationInBackground() { LiveValidationListener.workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (isStarted) return; isStarted = true; Runnable runnable = new Runnable() { public void run() { // do validation run and sleep for a while // to avoid bad performance on slow systems, the time // the run takes is measured; the 2-fold time of the // run is added to the interval time, so that // the overall CPU usage for validation is < 33% while (LiveValidationListener.isStarted()) { long timeBefore = System.currentTimeMillis(); // run validation LiveValidationListener.startLiveValidation(); long timeAfter = System.currentTimeMillis(); long timeDiff = timeAfter-timeBefore; long timeToSleep = LiveValidationListener.getIntervalSeconds()*1000 + timeDiff * 2; try { Thread.sleep(timeToSleep); } catch (InterruptedException e) {} } } }; Thread t = new Thread(runnable); t.start(); } /** * Stops the live validation in background. */ public static void stopLiveValidationInBackground() { isStarted = false; } /** * * @return true, if there is a background thread doing validation */ public static boolean isStarted() { return isStarted; } /** * @return the update interval in seconds */ public static int getIntervalSeconds() { return intervalSeconds; } /** * @param intervalSeconds the new interval between beackground live * validation runs in seconds */ public static void setIntervalSeconds(int intervalSeconds) { LiveValidationListener.intervalSeconds = intervalSeconds; } }