| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Sebastian Davids <sdavids@gmx.de> - bug 38919 |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui.snippeteditor; |
| |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.PrintStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugEvent; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.IDebugEventFilter; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.debug.core.model.IDebugElement; |
| import org.eclipse.debug.core.model.IDebugTarget; |
| import org.eclipse.debug.core.model.IStackFrame; |
| import org.eclipse.debug.core.model.IThread; |
| import org.eclipse.debug.core.model.IValue; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugModelPresentation; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.IValueDetailListener; |
| import org.eclipse.debug.ui.InspectPopupDialog; |
| import org.eclipse.jdt.core.CompletionRequestor; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.eval.IEvaluationContext; |
| import org.eclipse.jdt.debug.core.IJavaDebugTarget; |
| import org.eclipse.jdt.debug.core.IJavaStackFrame; |
| import org.eclipse.jdt.debug.core.IJavaThread; |
| import org.eclipse.jdt.debug.core.IJavaType; |
| import org.eclipse.jdt.debug.core.IJavaValue; |
| import org.eclipse.jdt.debug.core.JDIDebugModel; |
| import org.eclipse.jdt.debug.eval.EvaluationManager; |
| import org.eclipse.jdt.debug.eval.IClassFileEvaluationEngine; |
| import org.eclipse.jdt.debug.eval.IEvaluationListener; |
| import org.eclipse.jdt.debug.eval.IEvaluationResult; |
| import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; |
| import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin; |
| import org.eclipse.jdt.internal.debug.ui.JDIContentAssistPreference; |
| import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; |
| import org.eclipse.jdt.internal.debug.ui.JDISourceViewer; |
| import org.eclipse.jdt.internal.debug.ui.JavaDebugImages; |
| import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager; |
| import org.eclipse.jdt.internal.debug.ui.actions.DisplayAction; |
| import org.eclipse.jdt.internal.debug.ui.actions.EvaluateAction; |
| import org.eclipse.jdt.internal.debug.ui.actions.PopupInspectAction; |
| import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression; |
| import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
| import org.eclipse.jdt.launching.IVMInstall; |
| import org.eclipse.jdt.launching.JavaRuntime; |
| import org.eclipse.jdt.ui.IContextMenuConstants; |
| import org.eclipse.jdt.ui.JavaUI; |
| import org.eclipse.jdt.ui.PreferenceConstants; |
| import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.text.contentassist.ContentAssistant; |
| import org.eclipse.jface.text.contentassist.IContentAssistant; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.jface.text.source.IVerticalRuler; |
| import org.eclipse.jface.text.source.SourceViewerConfiguration; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IPageLayout; |
| import org.eclipse.ui.IPartListener2; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.actions.WorkspaceModifyOperation; |
| import org.eclipse.ui.dialogs.SaveAsDialog; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| import org.eclipse.ui.part.EditorActionBarContributor; |
| import org.eclipse.ui.part.FileEditorInput; |
| import org.eclipse.ui.part.IShowInTargetList; |
| import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; |
| import org.eclipse.ui.texteditor.ChainedPreferenceStore; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.ITextEditorActionConstants; |
| import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; |
| import org.eclipse.ui.texteditor.TextOperationAction; |
| |
| import com.sun.jdi.InvocationException; |
| import com.sun.jdi.ObjectReference; |
| |
| /** |
| * An editor for Java snippets. |
| */ |
| public class JavaSnippetEditor extends AbstractDecoratedTextEditor implements IDebugEventFilter, IEvaluationListener, IValueDetailListener { |
| public static final String IMPORTS_CONTEXT = "SnippetEditor.imports"; //$NON-NLS-1$ |
| |
| public final static int RESULT_DISPLAY= 1; |
| public final static int RESULT_RUN= 2; |
| public final static int RESULT_INSPECT= 3; |
| |
| private int fResultMode; // one of the RESULT_* constants |
| |
| private IJavaProject fJavaProject; |
| private IEvaluationContext fEvaluationContext; |
| private IDebugTarget fVM; |
| private String[] fLaunchedClassPath; |
| private String fLaunchedWorkingDir; |
| private String fLaunchedVMArgs; |
| private IVMInstall fLaunchedVM; |
| private List<ISnippetStateChangedListener> fSnippetStateListeners; |
| |
| private boolean fEvaluating; |
| private IJavaThread fThread; |
| private boolean fStepFiltersSetting; |
| |
| private int fSnippetStart; |
| private int fSnippetEnd; |
| |
| private String[] fImports= null; |
| |
| private Image fOldTitleImage= null; |
| private IClassFileEvaluationEngine fEngine= null; |
| |
| /** |
| * The debug model presentation used for computing toString |
| */ |
| private IDebugModelPresentation fPresentation= DebugUITools.newDebugModelPresentation(JDIDebugModel.getPluginIdentifier()); |
| /** |
| * The result of a toString evaluation returned asynchronously by the |
| * debug model. |
| */ |
| private String fResult; |
| |
| /** |
| * A thread that waits to have a |
| * thread to perform an evaluation in. |
| */ |
| private static class WaitThread extends Thread { |
| /** |
| * The display used for event dispatching. |
| */ |
| private Display fDisplay; |
| |
| /** |
| * Indicates whether to continue event queue dispatching. |
| */ |
| private volatile boolean fContinueEventDispatching = true; |
| |
| private Object fLock; |
| /** |
| * Creates a "wait" thread |
| * |
| * @param display the display to be used to read and dispatch events |
| * @param lock the monitor to wait on |
| */ |
| private WaitThread(Display display, Object lock) { |
| super("Snippet Wait Thread"); //$NON-NLS-1$ |
| setDaemon(true); |
| fDisplay = display; |
| fLock= lock; |
| } |
| @Override |
| public void run() { |
| try { |
| synchronized (fLock) { |
| //should be notified out of #setThread(IJavaThread) |
| fLock.wait(10000); |
| } |
| } catch (InterruptedException e) { |
| } finally { |
| // Make sure that all events in the asynchronous event queue |
| // are dispatched. |
| fDisplay.syncExec(new Runnable() { |
| @Override |
| public void run() { |
| // do nothing |
| } |
| }); |
| |
| // Stop event dispatching |
| fContinueEventDispatching= false; |
| |
| // Force the event loop to return from sleep () so that |
| // it stops event dispatching. |
| fDisplay.asyncExec(null); |
| } |
| } |
| /** |
| * Processes events. |
| */ |
| protected void block() { |
| if (fDisplay == Display.getCurrent()) { |
| while (fContinueEventDispatching) { |
| if (!fDisplay.readAndDispatch()) { |
| fDisplay.sleep(); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Listens for part activation to set scrapbook active system property |
| * for action enablement. |
| */ |
| private IPartListener2 fActivationListener = new IPartListener2() { |
| |
| @Override |
| public void partActivated(IWorkbenchPartReference partRef) { |
| if ("org.eclipse.jdt.debug.ui.SnippetEditor".equals(partRef.getId())) { //$NON-NLS-1$ |
| System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "true"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } else { |
| System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "false"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| @Override |
| public void partBroughtToTop(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partClosed(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partDeactivated(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partHidden(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partInputChanged(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partOpened(IWorkbenchPartReference partRef) { |
| } |
| |
| @Override |
| public void partVisible(IWorkbenchPartReference partRef) { |
| } |
| |
| }; |
| |
| public JavaSnippetEditor() { |
| super(); |
| setDocumentProvider(JDIDebugUIPlugin.getDefault().getSnippetDocumentProvider()); |
| IPreferenceStore store = new ChainedPreferenceStore(new IPreferenceStore[] { |
| PreferenceConstants.getPreferenceStore(), |
| EditorsUI.getPreferenceStore()}); |
| setSourceViewerConfiguration(new JavaSnippetViewerConfiguration(JDIDebugUIPlugin.getDefault().getJavaTextTools(), store, this)); |
| fSnippetStateListeners = new ArrayList<>(4); |
| setPreferenceStore(store); |
| setEditorContextMenuId("#JavaSnippetEditorContext"); //$NON-NLS-1$ |
| setRulerContextMenuId("#JavaSnippetRulerContext"); //$NON-NLS-1$ |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput) |
| */ |
| @Override |
| protected void doSetInput(IEditorInput input) throws CoreException { |
| super.doSetInput(input); |
| IFile file= getFile(); |
| if (file != null) { |
| String property= file.getPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT)); |
| if (property != null) { |
| fImports = JavaDebugOptionsManager.parseList(property); |
| } |
| } |
| } |
| |
| @Override |
| public void init(IEditorSite site, IEditorInput input) throws PartInitException { |
| super.init(site, input); |
| site.getWorkbenchWindow().getPartService().addPartListener(fActivationListener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart#dispose() |
| */ |
| @Override |
| public void dispose() { |
| shutDownVM(); |
| fPresentation.dispose(); |
| fSnippetStateListeners = null; |
| ISourceViewer viewer = getSourceViewer(); |
| if(viewer != null) { |
| ((JDISourceViewer)viewer).dispose(); |
| } |
| getSite().getWorkbenchWindow().getPartService().removePartListener(fActivationListener); |
| super.dispose(); |
| } |
| |
| /** |
| * Actions for the editor popup menu |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions() |
| */ |
| @Override |
| protected void createActions() { |
| super.createActions(); |
| if (getFile() != null) { |
| Action action = new TextOperationAction(SnippetMessages.getBundle(), "SnippetEditor.ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); //$NON-NLS-1$ |
| action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); |
| setAction("ContentAssistProposal", action);//$NON-NLS-1$ |
| setAction("ShowInPackageView", new ShowInPackageViewAction(this)); //$NON-NLS-1$ |
| setAction("Stop", new StopAction(this)); //$NON-NLS-1$ |
| setAction("SelectImports", new SelectImportsAction(this)); //$NON-NLS-1$ |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager) |
| */ |
| @Override |
| protected void editorContextMenuAboutToShow(IMenuManager menu) { |
| super.editorContextMenuAboutToShow(menu); |
| addGroup(menu, ITextEditorActionConstants.GROUP_EDIT, IContextMenuConstants.GROUP_GENERATE); |
| addGroup(menu, ITextEditorActionConstants.GROUP_FIND, IContextMenuConstants.GROUP_SEARCH); |
| addGroup(menu, IContextMenuConstants.GROUP_SEARCH, IContextMenuConstants.GROUP_SHOW); |
| if (getFile() != null) { |
| addAction(menu, IContextMenuConstants.GROUP_SHOW, "ShowInPackageView"); //$NON-NLS-1$ |
| addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Run"); //$NON-NLS-1$ |
| addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Stop"); //$NON-NLS-1$ |
| addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "SelectImports"); //$NON-NLS-1$ |
| } |
| } |
| |
| protected boolean isVMLaunched() { |
| return fVM != null; |
| } |
| |
| public boolean isEvaluating() { |
| return fEvaluating; |
| } |
| |
| public void evalSelection(int resultMode) { |
| if (!isInJavaProject()) { |
| reportNotInJavaProjectError(); |
| return; |
| } |
| if (isEvaluating()) { |
| return; |
| } |
| |
| checkCurrentProject(); |
| |
| evaluationStarts(); |
| |
| fResultMode= resultMode; |
| buildAndLaunch(); |
| |
| if (fVM == null) { |
| evaluationEnds(); |
| return; |
| } |
| fireEvalStateChanged(); |
| |
| ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection(); |
| String snippet= selection.getText(); |
| fSnippetStart= selection.getOffset(); |
| fSnippetEnd= fSnippetStart + selection.getLength(); |
| |
| evaluate(snippet); |
| } |
| |
| /** |
| * Checks if the page has been copied/moved to a different project or the project has been renamed. |
| * Updates the launch configuration template if a copy/move/rename has occurred. |
| */ |
| protected void checkCurrentProject() { |
| IFile file= getFile(); |
| if (file == null) { |
| return; |
| } |
| try { |
| ILaunchConfiguration config = ScrapbookLauncher.getLaunchConfigurationTemplate(file); |
| if (config != null) { |
| String projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); |
| IJavaProject pro = JavaCore.create(file.getProject()); |
| if (!pro.getElementName().equals(projectName)) { |
| //the page has been moved to a "different" project |
| ScrapbookLauncher.setLaunchConfigMemento(file, null); |
| } |
| } |
| } catch (CoreException ce) { |
| JDIDebugUIPlugin.log(ce); |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, ce.getStatus()); //$NON-NLS-1$ |
| evaluationEnds(); |
| return; |
| |
| } |
| } |
| |
| protected void buildAndLaunch() { |
| IJavaProject javaProject= getJavaProject(); |
| if (javaProject == null) { |
| return; |
| } |
| boolean build = !javaProject.getProject().getWorkspace().isAutoBuilding() |
| || !javaProject.hasBuildState(); |
| |
| if (build) { |
| if (!performIncrementalBuild()) { |
| return; |
| } |
| } |
| |
| boolean changed= classPathHasChanged(); |
| if (!changed) { |
| changed = workingDirHasChanged(); |
| } |
| if (!changed) { |
| changed = vmHasChanged(); |
| } |
| if (!changed) { |
| changed = vmArgsChanged(); |
| } |
| boolean launch= fVM == null || changed; |
| |
| if (changed) { |
| shutDownVM(); |
| } |
| |
| if (fVM == null) { |
| checkMultipleEditors(); |
| } |
| if (launch && fVM == null) { |
| launchVM(); |
| fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile()); |
| } |
| } |
| |
| protected boolean performIncrementalBuild() { |
| IRunnableWithProgress r= new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor pm) throws InvocationTargetException { |
| try { |
| getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, pm); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }; |
| try { |
| PlatformUI.getWorkbench().getProgressService().run(true, false, r); |
| } catch (InterruptedException e) { |
| JDIDebugUIPlugin.log(e); |
| evaluationEnds(); |
| return false; |
| } catch (InvocationTargetException e) { |
| JDIDebugUIPlugin.log(e); |
| evaluationEnds(); |
| return false; |
| } |
| return true; |
| } |
| |
| protected void checkMultipleEditors() { |
| fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile()); |
| //multiple editors are opened on the same page |
| if (fVM != null) { |
| DebugPlugin.getDefault().addDebugEventFilter(this); |
| try { |
| for (IThread thread : fVM.getThreads()) { |
| if (thread.isSuspended()) { |
| thread.resume(); |
| } |
| } |
| } catch (DebugException de) { |
| JDIDebugUIPlugin.log(de); |
| } |
| } |
| } |
| |
| protected void setImports(String[] imports) { |
| fImports= imports; |
| IFile file= getFile(); |
| if (file == null) { |
| return; |
| } |
| String serialized= null; |
| if (imports != null) { |
| serialized= JavaDebugOptionsManager.serializeList(imports); |
| } |
| // persist |
| try { |
| file.setPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT), serialized); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.imports"), null, e.getStatus()); //$NON-NLS-1$ |
| } |
| } |
| |
| protected String[] getImports() { |
| return fImports; |
| } |
| |
| protected IEvaluationContext getEvaluationContext() { |
| if (fEvaluationContext == null) { |
| IJavaProject project= getJavaProject(); |
| if (project != null) { |
| fEvaluationContext= project.newEvaluationContext(); |
| } |
| } |
| if (fEvaluationContext != null) { |
| if (getImports() != null) { |
| fEvaluationContext.setImports(getImports()); |
| } else { |
| fEvaluationContext.setImports(new String[]{}); |
| } |
| } |
| return fEvaluationContext; |
| } |
| |
| protected IJavaProject getJavaProject() { |
| if (fJavaProject == null) { |
| try { |
| fJavaProject = findJavaProject(); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| showError(e.getStatus()); |
| } |
| } |
| return fJavaProject; |
| } |
| |
| protected void shutDownVM() { |
| DebugPlugin.getDefault().removeDebugEventFilter(this); |
| |
| // The real shut down |
| IDebugTarget target= fVM; |
| if (fVM != null) { |
| try { |
| IBreakpoint bp = ScrapbookLauncher.getDefault().getMagicBreakpoint(fVM); |
| if (bp != null) { |
| fVM.breakpointRemoved(bp, null); |
| } |
| if (getThread() != null) { |
| getThread().resume(); |
| } |
| |
| fVM.terminate(); |
| } catch (DebugException e) { |
| JDIDebugUIPlugin.log(e); |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.shutdown"), null, e.getStatus()); //$NON-NLS-1$ |
| return; |
| } |
| vmTerminated(); |
| ScrapbookLauncher.getDefault().cleanup(target); |
| } |
| } |
| |
| /** |
| * The VM has terminated, update state |
| */ |
| protected void vmTerminated() { |
| fVM= null; |
| fThread= null; |
| fEvaluationContext= null; |
| fLaunchedClassPath= null; |
| if (fEngine != null) { |
| fEngine.dispose(); |
| } |
| fEngine= null; |
| fireEvalStateChanged(); |
| } |
| |
| public void addSnippetStateChangedListener(ISnippetStateChangedListener listener) { |
| if (fSnippetStateListeners != null && !fSnippetStateListeners.contains(listener)) { |
| fSnippetStateListeners.add(listener); |
| } |
| } |
| |
| public void removeSnippetStateChangedListener(ISnippetStateChangedListener listener) { |
| if (fSnippetStateListeners != null) { |
| fSnippetStateListeners.remove(listener); |
| } |
| } |
| |
| protected void fireEvalStateChanged() { |
| Runnable r= new Runnable() { |
| @Override |
| public void run() { |
| Shell shell= getShell(); |
| if (fSnippetStateListeners != null && shell != null && !shell.isDisposed()) { |
| for (ISnippetStateChangedListener listener : new ArrayList<>(fSnippetStateListeners)) { |
| listener.snippetStateChanged(JavaSnippetEditor.this); |
| } |
| } |
| } |
| }; |
| Shell shell= getShell(); |
| if (shell != null) { |
| getShell().getDisplay().asyncExec(r); |
| } |
| } |
| |
| protected void evaluate(String snippet) { |
| if (getThread() == null) { |
| WaitThread eThread= new WaitThread(Display.getCurrent(), this); |
| eThread.start(); |
| eThread.block(); |
| } |
| if (getThread() == null) { |
| IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Evaluation failed: internal error - unable to obtain an execution context.", null); //$NON-NLS-1$ |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, status); //$NON-NLS-1$ |
| evaluationEnds(); |
| return; |
| } |
| boolean hitBreakpoints = Platform.getPreferencesService().getBoolean( |
| JDIDebugPlugin.getUniqueIdentifier(), |
| JDIDebugModel.PREF_SUSPEND_FOR_BREAKPOINTS_DURING_EVALUATION, |
| true, |
| null); |
| try { |
| getEvaluationEngine().evaluate(snippet,getThread(), this, hitBreakpoints); |
| } catch (DebugException e) { |
| JDIDebugUIPlugin.log(e); |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, e.getStatus()); //$NON-NLS-1$ |
| evaluationEnds(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.debug.eval.IEvaluationListener#evaluationComplete(org.eclipse.jdt.debug.eval.IEvaluationResult) |
| */ |
| @Override |
| public void evaluationComplete(IEvaluationResult result) { |
| boolean severeErrors = false; |
| if (result.hasErrors()) { |
| String[] errors = result.getErrorMessages(); |
| severeErrors = errors.length > 0; |
| if (result.getException() != null) { |
| showException(result.getException()); |
| } |
| showAllErrors(errors); |
| } |
| IJavaValue value= result.getValue(); |
| if (value != null && !severeErrors) { |
| switch (fResultMode) { |
| case RESULT_DISPLAY: |
| displayResult(value); |
| break; |
| case RESULT_INSPECT: |
| JavaInspectExpression exp = new JavaInspectExpression(result.getSnippet().trim(), value); |
| showExpression(exp); |
| break; |
| case RESULT_RUN: |
| // no action |
| break; |
| } |
| } |
| evaluationEnds(); |
| } |
| |
| /** |
| * Make the expression view visible or open one |
| * if required. |
| */ |
| protected void showExpressionView() { |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| IWorkbenchPage page = JDIDebugUIPlugin.getActivePage(); |
| if (page != null) { |
| IViewPart part = page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW); |
| if (part == null) { |
| try { |
| page.showView(IDebugUIConstants.ID_EXPRESSION_VIEW); |
| } catch (PartInitException e) { |
| JDIDebugUIPlugin.log(e); |
| showError(e.getStatus()); |
| } |
| } else { |
| page.bringToTop(part); |
| } |
| } |
| } |
| }; |
| |
| async(r); |
| } |
| |
| protected void codeComplete(CompletionRequestor requestor) throws JavaModelException { |
| ITextSelection selection= (ITextSelection)getSelectionProvider().getSelection(); |
| int start= selection.getOffset(); |
| String snippet= getSourceViewer().getDocument().get(); |
| IEvaluationContext e= getEvaluationContext(); |
| if (e != null) { |
| e.codeComplete(snippet, start, requestor); |
| } |
| } |
| |
| protected IJavaElement[] codeResolve() throws JavaModelException { |
| ISourceViewer viewer= getSourceViewer(); |
| if (viewer == null) { |
| return null; |
| } |
| ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection(); |
| int start= selection.getOffset(); |
| int len= selection.getLength(); |
| |
| String snippet= viewer.getDocument().get(); |
| IEvaluationContext e= getEvaluationContext(); |
| if (e != null) { |
| return e.codeSelect(snippet, start, len); |
| } |
| return null; |
| } |
| |
| protected void showError(IStatus status) { |
| evaluationEnds(); |
| if (!status.isOK()) { |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating2"), null, status); //$NON-NLS-1$ |
| } |
| } |
| |
| protected void showError(String message) { |
| Status status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message, null); |
| showError(status); |
| } |
| |
| protected void displayResult(IJavaValue result) { |
| StringBuilder resultString= new StringBuilder(); |
| try { |
| IJavaType type = result.getJavaType(); |
| if (type != null) { |
| String sig= type.getSignature(); |
| if ("V".equals(sig)) { //$NON-NLS-1$ |
| resultString.append(SnippetMessages.getString("SnippetEditor.noreturnvalue")); //$NON-NLS-1$ |
| } else { |
| if (sig != null) { |
| resultString.append(SnippetMessages.getFormattedString("SnippetEditor.typename", result.getReferenceTypeName())); //$NON-NLS-1$ |
| } else { |
| resultString.append(" "); //$NON-NLS-1$ |
| } |
| resultString.append(DisplayAction.trimDisplayResult(evaluateToString(result))); |
| } |
| } else { |
| resultString.append(DisplayAction.trimDisplayResult(result.getValueString())); |
| } |
| } catch(DebugException e) { |
| JDIDebugUIPlugin.log(e); |
| ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.toString"), null, e.getStatus()); //$NON-NLS-1$ |
| } |
| |
| final String message = resultString.toString(); |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); |
| selectAndReveal(fSnippetEnd, message.length()); |
| } catch (BadLocationException e) { |
| } |
| } |
| }; |
| async(r); |
| } |
| |
| /** |
| * Returns the result of evaluating 'toString' on the given |
| * value. |
| * |
| * @param value object or primitive data type the 'toString' |
| * is required for |
| * @return the result of evaluating toString |
| * @exception DebugException if an exception occurs during the |
| * evaluation. |
| */ |
| protected synchronized String evaluateToString(IJavaValue value) { |
| fResult= null; |
| fPresentation.computeDetail(value, this); |
| if (fResult == null) { |
| try { |
| wait(10000); |
| } catch (InterruptedException e) { |
| return SnippetMessages.getString("SnippetEditor.error.interrupted"); //$NON-NLS-1$ |
| } |
| } |
| return fResult; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.IValueDetailListener#detailComputed(org.eclipse.debug.core.model.IValue, java.lang.String) |
| */ |
| @Override |
| public synchronized void detailComputed(IValue value, final String result) { |
| fResult= result; |
| this.notifyAll(); |
| } |
| |
| protected void showAllErrors(final String[] errors) { |
| IDocument document = getSourceViewer().getDocument(); |
| String delimiter = document.getLegalLineDelimiters()[0]; |
| |
| final StringBuilder errorString = new StringBuilder(); |
| for (String error : errors) { |
| errorString.append(error + delimiter); |
| } |
| |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| getSourceViewer().getDocument().replace(fSnippetStart, 0, errorString.toString()); |
| selectAndReveal(fSnippetStart, errorString.length()); |
| } catch (BadLocationException e) { |
| } |
| } |
| }; |
| async(r); |
| } |
| |
| private void showExpression(final JavaInspectExpression expression) { |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| new InspectPopupDialog(getShell(), EvaluateAction.getPopupAnchor(getSourceViewer().getTextWidget()), PopupInspectAction.ACTION_DEFININITION_ID, expression).open(); |
| } |
| }; |
| async(r); |
| } |
| |
| |
| protected void showException(Throwable exception) { |
| if (exception instanceof DebugException) { |
| DebugException de = (DebugException)exception; |
| Throwable t= de.getStatus().getException(); |
| if (t != null) { |
| // show underlying exception |
| showUnderlyingException(t); |
| return; |
| } |
| } |
| ByteArrayOutputStream bos= new ByteArrayOutputStream(); |
| PrintStream ps= new PrintStream(bos, true); |
| exception.printStackTrace(ps); |
| |
| final String message = bos.toString(); |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); |
| selectAndReveal(fSnippetEnd, message.length()); |
| } catch (BadLocationException e) { |
| } |
| } |
| }; |
| async(r); |
| } |
| |
| protected void showUnderlyingException(Throwable t) { |
| if (t instanceof InvocationException) { |
| InvocationException ie= (InvocationException)t; |
| ObjectReference ref= ie.exception(); |
| String eName= ref.referenceType().name(); |
| final String message= SnippetMessages.getFormattedString("SnippetEditor.exception", eName); //$NON-NLS-1$ |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); |
| selectAndReveal(fSnippetEnd, message.length()); |
| } catch (BadLocationException e) { |
| } |
| } |
| }; |
| async(r); |
| } else { |
| showException(t); |
| } |
| } |
| |
| protected IJavaProject findJavaProject() throws CoreException { |
| IFile file = getFile(); |
| if (file != null) { |
| IProject p= file.getProject(); |
| if (p.getNature(JavaCore.NATURE_ID) != null) { |
| return JavaCore.create(p); |
| } |
| } |
| return null; |
| } |
| |
| protected boolean classPathHasChanged() { |
| String[] classpath= getClassPath(getJavaProject()); |
| if (fLaunchedClassPath != null && !classPathsEqual(fLaunchedClassPath, classpath)) { |
| MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.warning"), SnippetMessages.getString("SnippetEditor.warning.cpchange")); //$NON-NLS-2$ //$NON-NLS-1$ |
| return true; |
| } |
| return false; |
| } |
| |
| protected boolean workingDirHasChanged() { |
| String wd = getWorkingDirectoryAttribute(); |
| boolean changed = false; |
| if (wd == null || fLaunchedWorkingDir == null) { |
| if (wd != fLaunchedWorkingDir) { |
| changed = true; |
| } |
| } else { |
| if (!wd.equals(fLaunchedWorkingDir)) { |
| changed = true; |
| } |
| } |
| if (changed && fVM != null) { |
| MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_working_directory_has_changed._Restarting_the_evaluation_context._2")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return changed; |
| } |
| |
| protected boolean vmArgsChanged() { |
| String args = getVMArgsAttribute(); |
| boolean changed = false; |
| if (args == null || fLaunchedVMArgs == null) { |
| if (args != fLaunchedVMArgs) { |
| changed = true; |
| } |
| } else { |
| if (!args.equals(fLaunchedVMArgs)) { |
| changed = true; |
| } |
| } |
| if (changed && fVM != null) { |
| MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.1")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return changed; |
| } |
| |
| protected boolean vmHasChanged() { |
| IVMInstall vm = getVMInstall(); |
| boolean changed = false; |
| if (vm == null || fLaunchedVM == null) { |
| if (vm != fLaunchedVM) { |
| changed = true; |
| } |
| } else { |
| if (!vm.equals(fLaunchedVM)) { |
| changed = true; |
| } |
| } |
| if (changed && fVM != null) { |
| MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_JRE_has_changed._Restarting_the_evaluation_context._2")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return changed; |
| } |
| |
| protected boolean classPathsEqual(String[] path1, String[] path2) { |
| if (path1.length != path2.length) { |
| return false; |
| } |
| for (int i= 0; i < path1.length; i++) { |
| if (!path1[i].equals(path2[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| protected synchronized void evaluationStarts() { |
| if (fThread != null) { |
| try { |
| IThread thread = fThread; |
| fThread = null; |
| thread.resume(); |
| } catch (DebugException e) { |
| JDIDebugUIPlugin.log(e); |
| showException(e); |
| return; |
| } |
| } |
| fEvaluating = true; |
| setTitleImage(); |
| fireEvalStateChanged(); |
| showStatus(SnippetMessages.getString("SnippetEditor.evaluating")); //$NON-NLS-1$ |
| getSourceViewer().setEditable(false); |
| } |
| |
| /** |
| * Sets the tab image to indicate whether in the process of |
| * evaluating or not. |
| */ |
| protected void setTitleImage() { |
| Image image=null; |
| if (fEvaluating) { |
| fOldTitleImage= getTitleImage(); |
| image= JavaDebugImages.get(JavaDebugImages.IMG_OBJS_SNIPPET_EVALUATING); |
| } else { |
| image= fOldTitleImage; |
| fOldTitleImage= null; |
| } |
| if (image != null) { |
| setTitleImage(image); |
| } |
| } |
| |
| protected void evaluationEnds() { |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| fEvaluating= false; |
| setTitleImage(); |
| fireEvalStateChanged(); |
| showStatus(""); //$NON-NLS-1$ |
| getSourceViewer().setEditable(true); |
| } |
| }; |
| async(r); |
| } |
| |
| protected void showStatus(String message) { |
| IEditorSite site=(IEditorSite)getSite(); |
| EditorActionBarContributor contributor= (EditorActionBarContributor)site.getActionBarContributor(); |
| contributor.getActionBars().getStatusLineManager().setMessage(message); |
| } |
| |
| protected String[] getClassPath(IJavaProject project) { |
| try { |
| return JavaRuntime.computeDefaultRuntimeClassPath(project); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| return new String[0]; |
| } |
| } |
| |
| protected Shell getShell() { |
| return getSite().getShell(); |
| } |
| |
| /** |
| * @see IDebugEventFilter#filterDebugEvents(DebugEvent[]) |
| */ |
| @Override |
| public DebugEvent[] filterDebugEvents(DebugEvent[] events) { |
| for (DebugEvent e : events) { |
| Object source = e.getSource(); |
| if (source instanceof IDebugElement) { |
| IDebugElement de = (IDebugElement)source; |
| if (de instanceof IDebugTarget) { |
| if (de.getDebugTarget().equals(fVM)) { |
| if (e.getKind() == DebugEvent.TERMINATE) { |
| setThread(null); |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| vmTerminated(); |
| } |
| }; |
| getShell().getDisplay().asyncExec(r); |
| } |
| } |
| } else if (de instanceof IJavaThread) { |
| if (e.getKind() == DebugEvent.SUSPEND) { |
| IJavaThread jt = (IJavaThread)de; |
| try { |
| if (jt.equals(getThread()) && e.getDetail() == DebugEvent.EVALUATION) { |
| return null; |
| } |
| IJavaStackFrame f= (IJavaStackFrame)jt.getTopStackFrame(); |
| if (f != null) { |
| IJavaDebugTarget target = (IJavaDebugTarget) f.getDebugTarget(); |
| IBreakpoint[] bps = jt.getBreakpoints(); |
| //last line of the eval method in ScrapbookMain1? |
| int lineNumber = f.getLineNumber(); |
| if (e.getDetail() == DebugEvent.STEP_END && (lineNumber == 28) |
| && f.getDeclaringTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") //$NON-NLS-1$ |
| && jt.getDebugTarget() == fVM) { |
| // restore step filters |
| target.setStepFiltersEnabled(fStepFiltersSetting); |
| setThread(jt); |
| return null; |
| } else if (e.getDetail() == DebugEvent.BREAKPOINT && bps.length > 0 && bps[0].equals(ScrapbookLauncher.getDefault().getMagicBreakpoint(jt.getDebugTarget()))) { |
| // locate the 'eval' method and step over |
| for (IStackFrame stackframe : jt.getStackFrames()) { |
| IJavaStackFrame frame = (IJavaStackFrame) stackframe; |
| if (frame.getReceivingTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") && frame.getName().equals("eval")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| // ignore step filters for this step |
| fStepFiltersSetting = target.isStepFiltersEnabled(); |
| target.setStepFiltersEnabled(false); |
| frame.stepOver(); |
| return null; |
| } |
| } |
| } |
| } |
| } catch (DebugException ex) { |
| JDIDebugUIPlugin.log(ex); |
| } |
| } |
| } |
| } |
| } |
| return events; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| @Override |
| protected boolean affectsTextPresentation(PropertyChangeEvent event) { |
| JavaSourceViewerConfiguration sourceViewerConfiguration = (JavaSourceViewerConfiguration) getSourceViewerConfiguration(); |
| return sourceViewerConfiguration.affectsTextPresentation(event); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| @Override |
| protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { |
| JDISourceViewer isv= (JDISourceViewer) getSourceViewer(); |
| if (isv != null) { |
| IContentAssistant assistant= isv.getContentAssistant(); |
| if (assistant instanceof ContentAssistant) { |
| JDIContentAssistPreference.changeConfiguration((ContentAssistant) assistant, event); |
| } |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| if (configuration instanceof JavaSourceViewerConfiguration) { |
| JavaSourceViewerConfiguration jsv = (JavaSourceViewerConfiguration) configuration; |
| if (jsv.affectsTextPresentation(event)) { |
| jsv.handlePropertyChangeEvent(event); |
| isv.invalidateTextPresentation(); |
| } |
| } |
| super.handlePreferenceStoreChanged(event); |
| } |
| } |
| |
| protected IJavaThread getThread() { |
| return fThread; |
| } |
| |
| /** |
| * Sets the thread to perform any evaluations in. |
| * Notifies the WaitThread waiting on getting an evaluation thread |
| * to perform an evaluation. |
| */ |
| protected synchronized void setThread(IJavaThread thread) { |
| fThread= thread; |
| notifyAll(); |
| } |
| |
| protected void launchVM() { |
| DebugPlugin.getDefault().addDebugEventFilter(this); |
| fLaunchedClassPath = getClassPath(getJavaProject()); |
| fLaunchedWorkingDir = getWorkingDirectoryAttribute(); |
| fLaunchedVMArgs = getVMArgsAttribute(); |
| fLaunchedVM = getVMInstall(); |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| ScrapbookLauncher.getDefault().launch(getFile()); |
| } |
| }; |
| BusyIndicator.showWhile(getShell().getDisplay(), r); |
| } |
| |
| /** |
| * Return the <code>IFile</code> associated with the current |
| * editor input. Will return <code>null</code> if the current |
| * editor input is for an external file |
| */ |
| public IFile getFile() { |
| IEditorInput input= getEditorInput(); |
| return input.getAdapter(IFile.class); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#updateSelectionDependentActions() |
| */ |
| @Override |
| protected void updateSelectionDependentActions() { |
| super.updateSelectionDependentActions(); |
| fireEvalStateChanged(); |
| } |
| |
| /** |
| * Terminates existing VM on a rename of the editor |
| */ |
| @Override |
| protected void setPartName(String title) { |
| cleanupOnRenameOrMove(); |
| super.setPartName(title); |
| } |
| |
| /** |
| * If the launch configuration has been copied, moved or |
| * renamed, shut down any running VM and clear the relevant cached information. |
| */ |
| protected void cleanupOnRenameOrMove() { |
| if(isVMLaunched()) { |
| shutDownVM(); |
| } else { |
| fThread= null; |
| fEvaluationContext= null; |
| fLaunchedClassPath= null; |
| |
| if (fEngine != null) { |
| fEngine.dispose(); |
| fEngine= null; |
| } |
| } |
| fJavaProject= null; |
| } |
| |
| /** |
| * Returns whether this editor has been opened on a resource that |
| * is in a Java project. |
| */ |
| protected boolean isInJavaProject() { |
| try { |
| return findJavaProject() != null; |
| } catch (CoreException ce) { |
| JDIDebugUIPlugin.log(ce); |
| } |
| return false; |
| } |
| |
| /** |
| * Displays an error dialog indicating that evaluation |
| * cannot occur outside of a Java Project. |
| */ |
| protected void reportNotInJavaProjectError() { |
| String projectName= null; |
| IFile file= getFile(); |
| if (file != null) { |
| IProject p= file.getProject(); |
| projectName= p.getName(); |
| } |
| String message= ""; //$NON-NLS-1$ |
| if (projectName != null) { |
| message = projectName + SnippetMessages.getString("JavaSnippetEditor._is_not_a_Java_Project._n_1"); //$NON-NLS-1$ |
| } |
| showError(message + SnippetMessages.getString("JavaSnippetEditor.Unable_to_perform_evaluation_outside_of_a_Java_Project_2")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Asks the user for the workspace path |
| * of a file resource and saves the document there. |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#performSaveAs(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| protected void performSaveAs(IProgressMonitor progressMonitor) { |
| Shell shell= getSite().getShell(); |
| SaveAsDialog dialog= new SaveAsDialog(shell); |
| dialog.open(); |
| IPath path= dialog.getResult(); |
| |
| if (path == null) { |
| if (progressMonitor != null) { |
| progressMonitor.setCanceled(true); |
| } |
| return; |
| } |
| |
| IWorkspace workspace= ResourcesPlugin.getWorkspace(); |
| IFile file= workspace.getRoot().getFile(path); |
| final IEditorInput newInput= new FileEditorInput(file); |
| |
| WorkspaceModifyOperation op= new WorkspaceModifyOperation() { |
| @Override |
| public void execute(final IProgressMonitor monitor) throws CoreException { |
| IDocumentProvider dp= getDocumentProvider(); |
| dp.saveDocument(monitor, newInput, dp.getDocument(getEditorInput()), true); |
| } |
| }; |
| |
| boolean success= false; |
| try { |
| getDocumentProvider().aboutToChange(newInput); |
| PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op); |
| success= true; |
| } catch (InterruptedException x) { |
| } catch (InvocationTargetException x) { |
| JDIDebugUIPlugin.log(x); |
| String title= SnippetMessages.getString("JavaSnippetEditor.Problems_During_Save_As..._3"); //$NON-NLS-1$ |
| String msg= SnippetMessages.getString("JavaSnippetEditor.Save_could_not_be_completed.__4") + x.getTargetException().getMessage(); //$NON-NLS-1$ |
| MessageDialog.openError(shell, title, msg); |
| } finally { |
| getDocumentProvider().changed(newInput); |
| if (success) { |
| setInput(newInput); |
| } |
| } |
| |
| if (progressMonitor != null) { |
| progressMonitor.setCanceled(!success); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() |
| */ |
| @Override |
| public boolean isSaveAsAllowed() { |
| return true; |
| } |
| |
| protected IClassFileEvaluationEngine getEvaluationEngine() { |
| if (fEngine == null) { |
| IPath outputLocation = getJavaProject().getProject().getWorkingLocation(JDIDebugUIPlugin.getUniqueIdentifier()); |
| java.io.File f = new java.io.File(outputLocation.toOSString()); |
| fEngine = EvaluationManager.newClassFileEvaluationEngine(getJavaProject(), (IJavaDebugTarget)getThread().getDebugTarget(), f); |
| } |
| if (getImports() != null) { |
| fEngine.setImports(getImports()); |
| } else { |
| fEngine.setImports(new String[]{}); |
| } |
| return fEngine; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int) |
| */ |
| @Override |
| protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { |
| fAnnotationAccess= getAnnotationAccess(); |
| fOverviewRuler= createOverviewRuler(getSharedColors()); |
| |
| ISourceViewer viewer= new JDISourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles | SWT.LEFT_TO_RIGHT); |
| |
| // ensure decoration support has been created and configured. |
| getSourceViewerDecorationSupport(viewer); |
| |
| return viewer; |
| } |
| |
| /** |
| * Returns the working directory attribute for this scrapbook |
| */ |
| protected String getWorkingDirectoryAttribute() { |
| IFile file= getFile(); |
| if (file != null) { |
| try { |
| return ScrapbookLauncher.getWorkingDirectoryAttribute(file); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the working directory attribute for this scrapbook |
| */ |
| protected String getVMArgsAttribute() { |
| IFile file= getFile(); |
| if (file != null) { |
| try { |
| return ScrapbookLauncher.getVMArgsAttribute(file); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the vm install for this scrapbook |
| */ |
| protected IVMInstall getVMInstall() { |
| IFile file= getFile(); |
| if (file != null) { |
| try { |
| return ScrapbookLauncher.getVMInstall(file); |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Executes the given runnable in the Display thread |
| */ |
| protected void async(Runnable r) { |
| Control control= getVerticalRuler().getControl(); |
| if (!control.isDisposed()) { |
| control.getDisplay().asyncExec(r); |
| } |
| } |
| |
| protected void showAndSelect(final String text, final int offset) { |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| try { |
| getSourceViewer().getDocument().replace(offset, 0, text); |
| } catch (BadLocationException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| selectAndReveal(offset, text.length()); |
| } |
| }; |
| async(r); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> T getAdapter(Class<T> required) { |
| if (required == IShowInTargetList.class) { |
| return (T) new IShowInTargetList() { |
| @Override |
| public String[] getShowInTargetIds() { |
| return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_RES_NAV }; |
| } |
| |
| }; |
| } |
| return super.getAdapter(required); |
| } |
| |
| } |