/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package org.absmodels.abs.plugin.debug; import static org.absmodels.abs.plugin.debug.DebugUtils.getSchedulerRef; import static org.absmodels.abs.plugin.util.Constants.ABS_DEBUG_VARIABLE_VIEW; import static org.absmodels.abs.plugin.util.Constants.ABS_DEBUG_VIEW; import static org.absmodels.abs.plugin.util.Constants.DEFAULT_SCHEDULER; import java.util.List; import org.absmodels.abs.plugin.debug.model.Debugger; import org.absmodels.abs.plugin.debug.scheduling.SchedulingStrategy; import org.absmodels.abs.plugin.debug.views.debugview.DebugView; import org.absmodels.abs.plugin.debug.views.variablesview.VariableView; import org.absmodels.abs.plugin.editor.ABSEditor; import org.absmodels.abs.plugin.util.Constants; import org.absmodels.abs.plugin.util.UtilityFunctions; import org.absmodels.abs.plugin.util.Constants.Scheduler; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import abs.backend.java.debugging.TaskInfo; import abs.backend.java.observing.ObjectView; import abs.backend.java.observing.TaskStackFrameView; import abs.backend.java.observing.TaskView; /** * Convenience methods used by classes in the debug package. * @author fstrauss, mweber, tfischer * */ public class DebugUtils { private static Scheduler scheduler = DEFAULT_SCHEDULER; public static IAction resume; public static IAction terminate; public static IAction executeSingleStep; public static IAction executeNSteps; public static IAction stepOver; public static IAction runToLine; public static IAction saveHistory; public static IAction selectScheduler; public static IAction schedulerMenu; public static SchedulingStrategy schedulerRef; private static DebugView debugView; public static volatile boolean highlightStep = true; private static volatile TaskInfo lastHighlightInfo = null; private static boolean runAutomatically; private static String historyFile; private static IProject currentProject; public static void enableHightlighting(){ highlightStep = true; if(lastHighlightInfo!=null){ highlightLine(lastHighlightInfo); } getSchedulerRef().highlightNextStep(); } public static void disableHighlighting(){ highlightStep = false; removeAllHighlighting(); } /** * Sets the enablement of resume, singleStep, NSteps, stepOver and runToLine buttons. * @param enabled if true the five buttons are enabled, otherwise disabled */ private static void setStepButtonEnablement(boolean enabled){ executeSingleStep.setEnabled(enabled); executeNSteps.setEnabled(enabled); stepOver.setEnabled(enabled); runToLine.setEnabled(enabled); resume.setEnabled(enabled); } /** * Disables ExecuteNSteps, resume and terminate buttons. Enables saveHistory button. Checks, if an action exists for * the currently in the debug tree selected element and sets enablement of singleStep button accordingly. */ public static void refreshButtonEnablement(){ if (terminate == null) { return; } terminate.setEnabled(isDebuggerRunning()); schedulerMenu.setEnabled(isDebuggerRunning()); saveHistory.setEnabled(true); //Set enablement for step buttons explicitly setStepButtonEnablement(false); List<TaskView> schedulableTasks; switch(scheduler){ case interactive: Object selectedObject = getDebugViewerSelection(); schedulableTasks = getSchedulerRef().getSchedulableTasks(); if(selectedObject instanceof TaskView){ if(schedulableTasks != null){ for(TaskView taskView : schedulableTasks){ if (taskView == selectedObject){ setStepButtonEnablement(true); } } } } else if(selectedObject instanceof TaskStackFrameView){ if(schedulableTasks != null){ for(TaskView taskView : schedulableTasks){ if (taskView == ((TaskStackFrameView)selectedObject).getStack().getTask()){ setStepButtonEnablement(true); } } } } break; case random: case replay: schedulableTasks = getSchedulerRef().getSchedulableTasks(); if(schedulableTasks != null && ! schedulableTasks.isEmpty()){ setStepButtonEnablement(true); } break; default: //disable all buttons setStepButtonEnablement(false); terminate.setEnabled(false); saveHistory.setEnabled(false); } } private static boolean isDebuggerRunning() { return getDebugger() != null && getDebugger().isRunning(); } public static void highlightLine(final IPath path, final int n){ Display.getDefault().asyncExec(new Runnable() { @Override public void run() { ABSEditor editor = UtilityFunctions.openABSEditorForFile(path, currentProject); editor.highlightLine(n); } }); } public static void highlightLine(TaskInfo info){ lastHighlightInfo = info; if(highlightStep){ int line = info.getCurrentLine() - 1; String curFilepath = info.getCurrentFile(); if(curFilepath!=null) highlightLine(new Path(curFilepath), line); } } public static void removeHighlighting(TaskInfo info){ if(lastHighlightInfo==info){ lastHighlightInfo = null; } if(highlightStep){ String curFilePath = info.getCurrentFile(); if(curFilePath!=null) removeHighlighting(new Path(curFilePath)); } } public static void removeHighlighting(final IPath path){ Display.getDefault().asyncExec(new Runnable() { @Override public void run() { ABSEditor editor = UtilityFunctions.openABSEditorForFile(path, currentProject); editor.removeHighlighting(); } }); } public static void removeAllHighlighting(){ Display.getDefault().asyncExec(new Runnable() { @Override public void run() { IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences(); for (IEditorReference iEditorReference : editorReferences) { IEditorPart editor = iEditorReference.getEditor(false); if(editor instanceof ABSEditor){ ABSEditor abseditor = (ABSEditor) editor; abseditor.removeHighlighting(); } } } }); } private static DebugView getDebugView(){ IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); debugView = (DebugView)activePage.findView(ABS_DEBUG_VIEW); if (debugView == null) { // open view if it does not exist yet try { debugView = (DebugView) activePage.showView(ABS_DEBUG_VIEW); } catch (PartInitException e) { e.printStackTrace(); UtilityFunctions.showErrorMessage("Could not open debug view."); } } return debugView; } /** * Gets the Viewer of the Debug View. * @return The viewer of the debug view, if a view exists, null otherwise. */ public static Viewer getDebugViewer(){ DebugView debugView = getDebugView(); if(debugView == null){ return null; } else{ return debugView.getViewer(); } } //TODO: use this method instead of getting debugViewer and do getSelection there public static Object getDebugViewerSelection(){ Viewer debugViewer = getDebugViewer(); if(debugViewer == null){ return null; } IStructuredSelection selection = (IStructuredSelection)debugViewer.getSelection(); if(selection == null){ return null; } return selection.getFirstElement(); } /** * Refreshes the display of the tree viewer of the debug view */ public static void refreshDebugViewer(){ Display.getDefault().asyncExec(new Runnable() { @Override public void run(){ getDebugViewer().refresh(); } }); } /** * @return The debugger of the debug view if a debug view exists, null otherwise */ public static Debugger getDebugger(){ if(getDebugView() == null){ return null; } else{ return getDebugView().getDebugger(); } } public static SchedulingStrategy getSchedulerRef(){ //TODO if(schedulerRef != null){ return schedulerRef; } else { //TODO show error message; System.err.println("SchedulingStrategy not found"); return null; } } private static VariableView getVariableView(){ return (VariableView)PlatformUI. getWorkbench() .getActiveWorkbenchWindow() .getActivePage() .findView(ABS_DEBUG_VARIABLE_VIEW); } /** * Loads the current selection of the debug view in the variable view, but does not open the view. * If no ObjectView or TaskStackFrame is selected, the variable view will be empty. */ public static void refreshVariableView() { refreshVariableView(getDebugViewerSelection()); } /** * Loads a specific object in the variable view, but does not open the view. * @param o The object to be shown in the variable view. */ public static void refreshVariableView(Object o) { VariableView view = getVariableView(); if(view != null){ if(o instanceof TaskStackFrameView || o instanceof ObjectView){ getVariableView().getViewer().setInput(o); } else if(o instanceof TaskView){ if(((TaskView)o).getStack().hasFrames()){ getVariableView().getViewer().setInput(((TaskView)o).getStack().getCurrentFrame()); } else { getVariableView().getViewer().setInput(null); } } } } /** * Opens the variable view and load a given object to it. * @param o Object to be shown in the newly opened view */ public static void openVariableView(Object o){ openVariableView(); refreshVariableView(o); } /** * Opens the variable view without showing an object. */ public static void openVariableView(){ try { PlatformUI .getWorkbench() .getActiveWorkbenchWindow() .getActivePage() .showView(Constants.ABS_DEBUG_VARIABLE_VIEW); } catch (PartInitException e) { UtilityFunctions.showErrorMessage("Fatal Error while opening variable view: " + e.getMessage()); } } /** * Sets the selection of the TreeViewer of the DebugView to the next schedulable task. */ public static void selectNextTask(){ if(getSchedulerRef().getSchedulableTasks() != null){ setDebugTreeSelection(getSchedulerRef().getSchedulableTasks().get(0)); } } /** * Sets the selection of the TreeViewer of the DebugView to a given object * @param o The object to be selected by the TreeViewer */ public static void setDebugTreeSelection(final Object o){ Display.getDefault().asyncExec(new Runnable() { @Override public void run() { getDebugViewer().setSelection(new StructuredSelection(o)); } }); } public static Scheduler getScheduler() { return scheduler; } public static void setScheduler(Scheduler s) { scheduler = s; Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if(getSchedulerRef() != null) getSchedulerRef().updateScheduler(); } }); } public static void setCurrentProject(IProject project) { currentProject = project; } public static void setRunAutomatically(boolean ra) { runAutomatically = ra; } public static boolean getRunAutomatically() { return runAutomatically; } public static void setHistoryFile(String hf) { historyFile = hf; } public static String getHistoryFile() { return historyFile; } }