/* * This file is part of the OpenJML plug-in project. * Copyright (c) 2006-2013 David R. Cok * @author David R. Cok */ package org.jmlspecs.openjml.eclipse; import java.io.File; import java.io.FileWriter; import java.util.Arrays; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IResourceRuleFactory; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.handlers.HandlerUtil; import org.jmlspecs.openjml.JmlTree.JmlClassDecl; import org.jmlspecs.openjml.Main.Cmd; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.util.List; /** * This class holds the implementations of utility classes registered against * menu items in the menubar and toolbar by plugin.xml */ abstract public class Commands extends AbstractHandler { /** Caches the value of the window, when informed of it. */ protected IWorkbenchWindow window; /** Caches the value of the shell in which the window exists. */ protected Shell shell = null; /** The current selection. */ protected ISelection selection; /** Cached value of the utility object */ protected Utils utils = Activator.utils(); /** Populates the class fields with data about the event, for use in the * derived classes. */ protected void getInfo(ExecutionEvent event) throws ExecutionException { window = HandlerUtil.getActiveWorkbenchWindowChecked(event); shell = window.getShell(); selection = window.getSelectionService().getSelection(); } /** * We can use this method to dispose of any system * resources we previously allocated. * @see org.eclipse.core.commands.IHandler#dispose() */ @Override public void dispose() { super.dispose(); } /** Called by the system in response to a menu selection (or other command). * This should be overridden for individual menu items. */ @Override abstract public Object execute(ExecutionEvent event); /** * This action enables the JML nature on the selected projects, * so that checking happens as part of compilation. * * @author David Cok * */ static public class ClearAllProofResults extends Commands { // This is all done in the UI thread with no progress monitor @Override public Object execute(ExecutionEvent event) { try { if (Options.uiverboseness) { Log.log(this.getClass().getSimpleName() + " command initiated"); //$NON-NLS-1$ } getInfo(event); utils.findView().clearProofResults(); } catch (Exception e) { utils.topLevelException(shell,this.getClass().getSimpleName(),e); } return null; } } static public class ClearSelectedProofResults extends Commands { // This is all done in the UI thread with no progress monitor @Override public Object execute(ExecutionEvent event) { try { if (Options.uiverboseness) { Log.log(this.getClass().getSimpleName() + " command initiated"); //$NON-NLS-1$ } getInfo(event); utils.findView().clearSelectedProofResults(); } catch (Exception e) { utils.topLevelException(shell,this.getClass().getSimpleName(),e); } return null; } } static public class ExportProofResults extends Commands { @Override public Object execute(ExecutionEvent event) { try (FileWriter fw = new FileWriter(new File(System.getProperty("user.home") + "/resultsOutput"))) { if (Options.uiverboseness) { Log.log(this.getClass().getSimpleName() + " command initiated"); //$NON-NLS-1$ } getInfo(event); OpenJMLView.exportProofResults(fw); } catch (Exception e) { utils.topLevelException(shell,this.getClass().getSimpleName(),e); } return null; } } static public class RerunStaticCheck extends Commands { // This is all done in the UI thread with no progress monitor @Override public Object execute(ExecutionEvent event) { try { if (Options.uiverboseness) { Log.log(this.getClass().getSimpleName() + " command initiated"); //$NON-NLS-1$ } getInfo(event); if (!utils.checkForDirtyEditors()) return null; final OpenJMLView view = utils.findView(); TreeItem ti = view.selected; OpenJMLView.Info info = (OpenJMLView.Info)ti.getData(); utils.findView().clearSelectedProofResults(); if (info == null) return null; final String key = info.key; final IJavaElement je = info.javaElement; if (je == null) return null; // FIXME - this can happen if a default constuctor is selected - but we should still run on the file final IJavaProject jp = je.getJavaProject(); final String filepath = je.getResource().getLocation().toOSString(); final OpenJMLInterface iface = utils.getInterface(utils.findView().currentProject); utils.showView(); // Must be called from a UI thread Job j = new Job("Rerunning compilation unit " + je.getResource().getName()) { public IStatus run(IProgressMonitor monitor) { monitor.beginTask("Static checking of " + jp.getElementName(), 1); boolean c = false; try { java.util.List<String> args = iface.getOptions(iface.jproject,Cmd.ESC); args.add("-esc"); args.add(filepath); iface.api.execute(null,args.toArray(new String[args.size()])); utils.setTraceView(key,jp); } catch (Exception e) { // FIXME - this will block, preventing progress on the rest of the projects Log.errorlog("Exception during Static Checking - " + je.getElementName(), e); utils.showExceptionInUI(null, "Exception during Static Checking - " + jp.getElementName(), e); c = true; } return c ? Status.CANCEL_STATUS : Status.OK_STATUS; } }; // IResourceRuleFactory ruleFactory = // ResourcesPlugin.getWorkspace().getRuleFactory(); j.setRule(jp.getProject()); j.setUser(true); // true since the job has been initiated by an end-user j.schedule(); // FIXME - update trace and highlighting also? } catch (Exception e) { utils.topLevelException(shell,this.getClass().getSimpleName(),e); } return null; } } static public class ShowResultsForProblem extends Commands { // This is all done in the UI thread with no progress monitor @Override public Object execute(ExecutionEvent event) { try { if (true || Options.uiverboseness) { Log.log(this.getClass().getSimpleName() + " command initiated"); //$NON-NLS-1$ } getInfo(event); utils.showMessageInUI(shell, "OpenJML", "This operation is not yet implemented"); //utils.changeJmlNatureSelection(true,selection,window,shell); } catch (Exception e) { utils.topLevelException(shell,this.getClass().getSimpleName(),e); } return null; } } }