1 12 package org.eclipse.jdt.internal.debug.ui.snippeteditor; 13 14 15 import java.io.ByteArrayOutputStream ; 16 import java.io.PrintStream ; 17 import java.lang.reflect.InvocationTargetException ; 18 import java.util.ArrayList ; 19 import java.util.List ; 20 21 import org.eclipse.core.resources.IFile; 22 import org.eclipse.core.resources.IProject; 23 import org.eclipse.core.resources.IWorkspace; 24 import org.eclipse.core.resources.IncrementalProjectBuilder; 25 import org.eclipse.core.resources.ResourcesPlugin; 26 import org.eclipse.core.runtime.CoreException; 27 import org.eclipse.core.runtime.IPath; 28 import org.eclipse.core.runtime.IProgressMonitor; 29 import org.eclipse.core.runtime.IStatus; 30 import org.eclipse.core.runtime.QualifiedName; 31 import org.eclipse.core.runtime.Status; 32 import org.eclipse.debug.core.DebugEvent; 33 import org.eclipse.debug.core.DebugException; 34 import org.eclipse.debug.core.DebugPlugin; 35 import org.eclipse.debug.core.IDebugEventFilter; 36 import org.eclipse.debug.core.ILaunchConfiguration; 37 import org.eclipse.debug.core.model.IBreakpoint; 38 import org.eclipse.debug.core.model.IDebugElement; 39 import org.eclipse.debug.core.model.IDebugTarget; 40 import org.eclipse.debug.core.model.IStackFrame; 41 import org.eclipse.debug.core.model.IThread; 42 import org.eclipse.debug.core.model.IValue; 43 import org.eclipse.debug.ui.DebugUITools; 44 import org.eclipse.debug.ui.IDebugModelPresentation; 45 import org.eclipse.debug.ui.IDebugUIConstants; 46 import org.eclipse.debug.ui.IValueDetailListener; 47 import org.eclipse.debug.ui.InspectPopupDialog; 48 import org.eclipse.jdt.core.CompletionRequestor; 49 import org.eclipse.jdt.core.IJavaElement; 50 import org.eclipse.jdt.core.IJavaProject; 51 import org.eclipse.jdt.core.JavaCore; 52 import org.eclipse.jdt.core.JavaModelException; 53 import org.eclipse.jdt.core.eval.IEvaluationContext; 54 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 55 import org.eclipse.jdt.debug.core.IJavaStackFrame; 56 import org.eclipse.jdt.debug.core.IJavaThread; 57 import org.eclipse.jdt.debug.core.IJavaType; 58 import org.eclipse.jdt.debug.core.IJavaValue; 59 import org.eclipse.jdt.debug.core.JDIDebugModel; 60 import org.eclipse.jdt.debug.eval.EvaluationManager; 61 import org.eclipse.jdt.debug.eval.IClassFileEvaluationEngine; 62 import org.eclipse.jdt.debug.eval.IEvaluationListener; 63 import org.eclipse.jdt.debug.eval.IEvaluationResult; 64 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; 65 import org.eclipse.jdt.internal.debug.ui.JDIContentAssistPreference; 66 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 67 import org.eclipse.jdt.internal.debug.ui.JDISourceViewer; 68 import org.eclipse.jdt.internal.debug.ui.JavaDebugImages; 69 import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager; 70 import org.eclipse.jdt.internal.debug.ui.actions.DisplayAction; 71 import org.eclipse.jdt.internal.debug.ui.actions.EvaluateAction; 72 import org.eclipse.jdt.internal.debug.ui.actions.PopupInspectAction; 73 import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression; 74 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; 75 import org.eclipse.jdt.launching.IVMInstall; 76 import org.eclipse.jdt.launching.JavaRuntime; 77 import org.eclipse.jdt.ui.IContextMenuConstants; 78 import org.eclipse.jdt.ui.JavaUI; 79 import org.eclipse.jdt.ui.PreferenceConstants; 80 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; 81 import org.eclipse.jface.action.Action; 82 import org.eclipse.jface.action.IMenuManager; 83 import org.eclipse.jface.dialogs.ErrorDialog; 84 import org.eclipse.jface.dialogs.MessageDialog; 85 import org.eclipse.jface.operation.IRunnableWithProgress; 86 import org.eclipse.jface.preference.IPreferenceStore; 87 import org.eclipse.jface.text.BadLocationException; 88 import org.eclipse.jface.text.IDocument; 89 import org.eclipse.jface.text.ITextSelection; 90 import org.eclipse.jface.text.contentassist.ContentAssistant; 91 import org.eclipse.jface.text.contentassist.IContentAssistant; 92 import org.eclipse.jface.text.source.ISourceViewer; 93 import org.eclipse.jface.text.source.IVerticalRuler; 94 import org.eclipse.jface.text.source.SourceViewerConfiguration; 95 import org.eclipse.jface.util.PropertyChangeEvent; 96 import org.eclipse.swt.custom.BusyIndicator; 97 import org.eclipse.swt.graphics.Image; 98 import org.eclipse.swt.widgets.Composite; 99 import org.eclipse.swt.widgets.Control; 100 import org.eclipse.swt.widgets.Display; 101 import org.eclipse.swt.widgets.Shell; 102 import org.eclipse.ui.IEditorInput; 103 import org.eclipse.ui.IEditorSite; 104 import org.eclipse.ui.IPageLayout; 105 import org.eclipse.ui.IPartListener2; 106 import org.eclipse.ui.IViewPart; 107 import org.eclipse.ui.IWorkbenchPage; 108 import org.eclipse.ui.IWorkbenchPartReference; 109 import org.eclipse.ui.PartInitException; 110 import org.eclipse.ui.PlatformUI; 111 import org.eclipse.ui.actions.WorkspaceModifyOperation; 112 import org.eclipse.ui.dialogs.SaveAsDialog; 113 import org.eclipse.ui.editors.text.EditorsUI; 114 import org.eclipse.ui.part.EditorActionBarContributor; 115 import org.eclipse.ui.part.FileEditorInput; 116 import org.eclipse.ui.part.IShowInTargetList; 117 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; 118 import org.eclipse.ui.texteditor.ChainedPreferenceStore; 119 import org.eclipse.ui.texteditor.IDocumentProvider; 120 import org.eclipse.ui.texteditor.ITextEditorActionConstants; 121 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; 122 import org.eclipse.ui.texteditor.TextOperationAction; 123 124 import com.sun.jdi.InvocationException; 125 import com.sun.jdi.ObjectReference; 126 127 130 public class JavaSnippetEditor extends AbstractDecoratedTextEditor implements IDebugEventFilter, IEvaluationListener, IValueDetailListener { 131 public static final String IMPORTS_CONTEXT = "SnippetEditor.imports"; 133 public final static int RESULT_DISPLAY= 1; 134 public final static int RESULT_RUN= 2; 135 public final static int RESULT_INSPECT= 3; 136 137 private int fResultMode; 139 private IJavaProject fJavaProject; 140 private IEvaluationContext fEvaluationContext; 141 private IDebugTarget fVM; 142 private String [] fLaunchedClassPath; 143 private String fLaunchedWorkingDir; 144 private String fLaunchedVMArgs; 145 private IVMInstall fLaunchedVM; 146 private List fSnippetStateListeners; 147 148 private boolean fEvaluating; 149 private IJavaThread fThread; 150 private boolean fStepFiltersSetting; 151 152 private int fSnippetStart; 153 private int fSnippetEnd; 154 155 private String [] fImports= null; 156 157 private Image fOldTitleImage= null; 158 private IClassFileEvaluationEngine fEngine= null; 159 160 163 private IDebugModelPresentation fPresentation= DebugUITools.newDebugModelPresentation(JDIDebugModel.getPluginIdentifier()); 164 168 private String fResult; 169 170 174 private static class WaitThread extends Thread { 175 178 private Display fDisplay; 179 180 183 private volatile boolean fContinueEventDispatching = true; 184 185 private Object fLock; 186 192 private WaitThread(Display display, Object lock) { 193 super("Snippet Wait Thread"); setDaemon(true); 195 fDisplay = display; 196 fLock= lock; 197 } 198 public void run() { 199 try { 200 synchronized (fLock) { 201 fLock.wait(10000); 203 } 204 } catch (InterruptedException e) { 205 } finally { 206 fDisplay.syncExec(new Runnable () { 209 public void run() { 210 } 212 }); 213 214 fContinueEventDispatching= false; 216 217 fDisplay.asyncExec(null); 220 } 221 } 222 225 protected void block() { 226 if (fDisplay == Display.getCurrent()) { 227 while (fContinueEventDispatching) { 228 if (!fDisplay.readAndDispatch()) 229 fDisplay.sleep(); 230 } 231 } 232 } 233 } 234 235 239 private IPartListener2 fActivationListener = new IPartListener2() { 240 241 public void partActivated(IWorkbenchPartReference partRef) { 242 if ("org.eclipse.jdt.debug.ui.SnippetEditor".equals(partRef.getId())) { System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "true"); } else { 245 System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "false"); } 247 } 248 249 public void partBroughtToTop(IWorkbenchPartReference partRef) { 250 } 251 252 public void partClosed(IWorkbenchPartReference partRef) { 253 } 254 255 public void partDeactivated(IWorkbenchPartReference partRef) { 256 } 257 258 public void partHidden(IWorkbenchPartReference partRef) { 259 } 260 261 public void partInputChanged(IWorkbenchPartReference partRef) { 262 } 263 264 public void partOpened(IWorkbenchPartReference partRef) { 265 } 266 267 public void partVisible(IWorkbenchPartReference partRef) { 268 } 269 270 }; 271 272 public JavaSnippetEditor() { 273 super(); 274 setDocumentProvider(JDIDebugUIPlugin.getDefault().getSnippetDocumentProvider()); 275 IPreferenceStore store = new ChainedPreferenceStore(new IPreferenceStore[] { 276 PreferenceConstants.getPreferenceStore(), 277 EditorsUI.getPreferenceStore()}); 278 setSourceViewerConfiguration(new JavaSnippetViewerConfiguration(JDIDebugUIPlugin.getDefault().getJavaTextTools(), store, this)); 279 fSnippetStateListeners= new ArrayList (4); 280 setPreferenceStore(store); 281 setEditorContextMenuId("#JavaSnippetEditorContext"); setRulerContextMenuId("#JavaSnippetRulerContext"); } 284 285 288 protected void doSetInput(IEditorInput input) throws CoreException { 289 super.doSetInput(input); 290 IFile file= getFile(); 291 if (file != null) { 292 String property= file.getPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT)); 293 if (property != null) { 294 fImports = JavaDebugOptionsManager.parseList(property); 295 } 296 } 297 } 298 299 public void init(IEditorSite site, IEditorInput input) throws PartInitException { 300 super.init(site, input); 301 site.getWorkbenchWindow().getPartService().addPartListener(fActivationListener); 302 } 303 304 307 public void dispose() { 308 shutDownVM(); 309 fPresentation.dispose(); 310 fSnippetStateListeners= null; 311 ((JDISourceViewer) getSourceViewer()).dispose(); 312 getSite().getWorkbenchWindow().getPartService().removePartListener(fActivationListener); 313 super.dispose(); 314 } 315 316 320 protected void createActions() { 321 super.createActions(); 322 if (getFile() != null) { 323 Action action = new TextOperationAction(SnippetMessages.getBundle(), "SnippetEditor.ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); 325 setAction("ContentAssistProposal", action); setAction("ShowInPackageView", new ShowInPackageViewAction(this)); setAction("Stop", new StopAction(this)); setAction("SelectImports", new SelectImportsAction(this)); } 330 } 331 332 335 protected void editorContextMenuAboutToShow(IMenuManager menu) { 336 super.editorContextMenuAboutToShow(menu); 337 addGroup(menu, ITextEditorActionConstants.GROUP_EDIT, IContextMenuConstants.GROUP_GENERATE); 338 addGroup(menu, ITextEditorActionConstants.GROUP_FIND, IContextMenuConstants.GROUP_SEARCH); 339 addGroup(menu, IContextMenuConstants.GROUP_SEARCH, IContextMenuConstants.GROUP_SHOW); 340 if (getFile() != null) { 341 addAction(menu, IContextMenuConstants.GROUP_SHOW, "ShowInPackageView"); addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Run"); addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Stop"); addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "SelectImports"); } 346 } 347 348 protected boolean isVMLaunched() { 349 return fVM != null; 350 } 351 352 public boolean isEvaluating() { 353 return fEvaluating; 354 } 355 356 public void evalSelection(int resultMode) { 357 if (!isInJavaProject()) { 358 reportNotInJavaProjectError(); 359 return; 360 } 361 if (isEvaluating()) { 362 return; 363 } 364 365 checkCurrentProject(); 366 367 evaluationStarts(); 368 369 fResultMode= resultMode; 370 buildAndLaunch(); 371 372 if (fVM == null) { 373 evaluationEnds(); 374 return; 375 } 376 fireEvalStateChanged(); 377 378 ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection(); 379 String snippet= selection.getText(); 380 fSnippetStart= selection.getOffset(); 381 fSnippetEnd= fSnippetStart + selection.getLength(); 382 383 evaluate(snippet); 384 } 385 386 390 protected void checkCurrentProject() { 391 IFile file= getFile(); 392 if (file == null) { 393 return; 394 } 395 try { 396 ILaunchConfiguration config = ScrapbookLauncher.getLaunchConfigurationTemplate(file); 397 if (config != null) { 398 String projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String )null); 399 IJavaProject pro = JavaCore.create(file.getProject()); 400 if (!pro.getElementName().equals(projectName)) { 401 ScrapbookLauncher.setLaunchConfigMemento(file, null); 403 } 404 } 405 } catch (CoreException ce) { 406 JDIDebugUIPlugin.log(ce); 407 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, ce.getStatus()); evaluationEnds(); 409 return; 410 411 } 412 } 413 414 protected void buildAndLaunch() { 415 IJavaProject javaProject= getJavaProject(); 416 if (javaProject == null) { 417 return; 418 } 419 boolean build = !javaProject.getProject().getWorkspace().isAutoBuilding() 420 || !javaProject.hasBuildState(); 421 422 if (build) { 423 if (!performIncrementalBuild()) { 424 return; 425 } 426 } 427 428 boolean changed= classPathHasChanged(); 429 if (!changed) { 430 changed = workingDirHasChanged(); 431 } 432 if (!changed) { 433 changed = vmHasChanged(); 434 } 435 if (!changed) { 436 changed = vmArgsChanged(); 437 } 438 boolean launch= fVM == null || changed; 439 440 if (changed) { 441 shutDownVM(); 442 } 443 444 if (fVM == null) { 445 checkMultipleEditors(); 446 } 447 if (launch && fVM == null) { 448 launchVM(); 449 fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile()); 450 } 451 } 452 453 protected boolean performIncrementalBuild() { 454 IRunnableWithProgress r= new IRunnableWithProgress() { 455 public void run(IProgressMonitor pm) throws InvocationTargetException { 456 try { 457 getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, pm); 458 } catch (CoreException e) { 459 throw new InvocationTargetException (e); 460 } 461 } 462 }; 463 try { 464 PlatformUI.getWorkbench().getProgressService().run(true, false, r); 465 } catch (InterruptedException e) { 466 JDIDebugUIPlugin.log(e); 467 evaluationEnds(); 468 return false; 469 } catch (InvocationTargetException e) { 470 JDIDebugUIPlugin.log(e); 471 evaluationEnds(); 472 return false; 473 } 474 return true; 475 } 476 477 protected void checkMultipleEditors() { 478 fVM= ScrapbookLauncher.getDefault().getDebugTarget(getFile()); 479 if (fVM != null) { 481 DebugPlugin.getDefault().addDebugEventFilter(this); 482 try { 483 IThread[] threads= fVM.getThreads(); 484 for (int i = 0; i < threads.length; i++) { 485 IThread iThread = threads[i]; 486 if (iThread.isSuspended()) { 487 iThread.resume(); 488 } 489 } 490 } catch (DebugException de) { 491 JDIDebugUIPlugin.log(de); 492 } 493 } 494 } 495 496 protected void setImports(String [] imports) { 497 fImports= imports; 498 IFile file= getFile(); 499 if (file == null) { 500 return; 501 } 502 String serialized= null; 503 if (imports != null) { 504 serialized= JavaDebugOptionsManager.serializeList(imports); 505 } 506 try { 508 file.setPersistentProperty(new QualifiedName(JDIDebugUIPlugin.getUniqueIdentifier(), IMPORTS_CONTEXT), serialized); 509 } catch (CoreException e) { 510 JDIDebugUIPlugin.log(e); 511 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.imports"), null, e.getStatus()); } 513 } 514 515 protected String [] getImports() { 516 return fImports; 517 } 518 519 protected IEvaluationContext getEvaluationContext() { 520 if (fEvaluationContext == null) { 521 IJavaProject project= getJavaProject(); 522 if (project != null) { 523 fEvaluationContext= project.newEvaluationContext(); 524 } 525 } 526 if (fEvaluationContext != null) { 527 if (getImports() != null) { 528 fEvaluationContext.setImports(getImports()); 529 } else { 530 fEvaluationContext.setImports(new String []{}); 531 } 532 } 533 return fEvaluationContext; 534 } 535 536 protected IJavaProject getJavaProject() { 537 if (fJavaProject == null) { 538 try { 539 fJavaProject = findJavaProject(); 540 } catch (JavaModelException e) { 541 JDIDebugUIPlugin.log(e); 542 showError(e.getStatus()); 543 } 544 } 545 return fJavaProject; 546 } 547 548 protected void shutDownVM() { 549 DebugPlugin.getDefault().removeDebugEventFilter(this); 550 551 IDebugTarget target= fVM; 553 if (fVM != null) { 554 try { 555 IBreakpoint bp = ScrapbookLauncher.getDefault().getMagicBreakpoint(fVM); 556 if (bp != null) { 557 fVM.breakpointRemoved(bp, null); 558 } 559 if (getThread() != null) { 560 getThread().resume(); 561 } 562 563 fVM.terminate(); 564 } catch (DebugException e) { 565 JDIDebugUIPlugin.log(e); 566 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.shutdown"), null, e.getStatus()); return; 568 } 569 vmTerminated(); 570 ScrapbookLauncher.getDefault().cleanup(target); 571 } 572 } 573 574 577 protected void vmTerminated() { 578 fVM= null; 579 fThread= null; 580 fEvaluationContext= null; 581 fLaunchedClassPath= null; 582 if (fEngine != null) { 583 fEngine.dispose(); 584 } 585 fEngine= null; 586 fireEvalStateChanged(); 587 } 588 589 public void addSnippetStateChangedListener(ISnippetStateChangedListener listener) { 590 if (fSnippetStateListeners != null && !fSnippetStateListeners.contains(listener)) { 591 fSnippetStateListeners.add(listener); 592 } 593 } 594 595 public void removeSnippetStateChangedListener(ISnippetStateChangedListener listener) { 596 if (fSnippetStateListeners != null) { 597 fSnippetStateListeners.remove(listener); 598 } 599 } 600 601 protected void fireEvalStateChanged() { 602 Runnable r= new Runnable () { 603 public void run() { 604 Shell shell= getShell(); 605 if (fSnippetStateListeners != null && shell != null && !shell.isDisposed()) { 606 List v= new ArrayList (fSnippetStateListeners); 607 for (int i= 0; i < v.size(); i++) { 608 ISnippetStateChangedListener l= (ISnippetStateChangedListener) v.get(i); 609 l.snippetStateChanged(JavaSnippetEditor.this); 610 } 611 } 612 } 613 }; 614 Shell shell= getShell(); 615 if (shell != null) { 616 getShell().getDisplay().asyncExec(r); 617 } 618 } 619 620 protected void evaluate(String snippet) { 621 if (getThread() == null) { 622 WaitThread eThread= new WaitThread(Display.getCurrent(), this); 623 eThread.start(); 624 eThread.block(); 625 } 626 if (getThread() == null) { 627 IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, 628 SnippetMessages.getString("SnippetEditor.error.nocontext"), null); ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, status); evaluationEnds(); 631 return; 632 } 633 boolean hitBreakpoints= JDIDebugModel.getPreferences().getBoolean(JDIDebugModel.PREF_SUSPEND_FOR_BREAKPOINTS_DURING_EVALUATION); 634 try { 635 getEvaluationEngine().evaluate(snippet,getThread(), this, hitBreakpoints); 636 } catch (DebugException e) { 637 JDIDebugUIPlugin.log(e); 638 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, e.getStatus()); evaluationEnds(); 640 } 641 } 642 643 646 public void evaluationComplete(IEvaluationResult result) { 647 boolean severeErrors = false; 648 if (result.hasErrors()) { 649 String [] errors = result.getErrorMessages(); 650 severeErrors = errors.length > 0; 651 if (result.getException() != null) { 652 showException(result.getException()); 653 } 654 showAllErrors(errors); 655 } 656 IJavaValue value= result.getValue(); 657 if (value != null && !severeErrors) { 658 switch (fResultMode) { 659 case RESULT_DISPLAY: 660 displayResult(value); 661 break; 662 case RESULT_INSPECT: 663 String snippet= result.getSnippet().trim(); 664 int snippetLength= snippet.length(); 665 if (snippetLength > 30) { 666 snippet = snippet.substring(0, 15) + SnippetMessages.getString("SnippetEditor.ellipsis") + snippet.substring(snippetLength - 15, snippetLength); } 668 snippet= snippet.replace('\n', ' '); 669 snippet= snippet.replace('\r', ' '); 670 snippet= snippet.replace('\t', ' '); 671 JavaInspectExpression exp = new JavaInspectExpression(snippet, value); 672 showExpression(exp); 673 break; 674 case RESULT_RUN: 675 break; 677 } 678 } 679 evaluationEnds(); 680 } 681 682 686 protected void showExpressionView() { 687 Runnable r = new Runnable () { 688 public void run() { 689 IWorkbenchPage page = JDIDebugUIPlugin.getActivePage(); 690 if (page != null) { 691 IViewPart part = page.findView(IDebugUIConstants.ID_EXPRESSION_VIEW); 692 if (part == null) { 693 try { 694 page.showView(IDebugUIConstants.ID_EXPRESSION_VIEW); 695 } catch (PartInitException e) { 696 JDIDebugUIPlugin.log(e); 697 showError(e.getStatus()); 698 } 699 } else { 700 page.bringToTop(part); 701 } 702 } 703 } 704 }; 705 706 async(r); 707 } 708 709 protected void codeComplete(CompletionRequestor requestor) throws JavaModelException { 710 ITextSelection selection= (ITextSelection)getSelectionProvider().getSelection(); 711 int start= selection.getOffset(); 712 String snippet= getSourceViewer().getDocument().get(); 713 IEvaluationContext e= getEvaluationContext(); 714 if (e != null) { 715 e.codeComplete(snippet, start, requestor); 716 } 717 } 718 719 protected IJavaElement[] codeResolve() throws JavaModelException { 720 ISourceViewer viewer= getSourceViewer(); 721 if (viewer == null) { 722 return null; 723 } 724 ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection(); 725 int start= selection.getOffset(); 726 int len= selection.getLength(); 727 728 String snippet= viewer.getDocument().get(); 729 IEvaluationContext e= getEvaluationContext(); 730 if (e != null) { 731 return e.codeSelect(snippet, start, len); 732 } 733 return null; 734 } 735 736 protected void showError(IStatus status) { 737 evaluationEnds(); 738 if (!status.isOK()) { 739 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating2"), null, status); } 741 } 742 743 protected void showError(String message) { 744 Status status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message, null); 745 showError(status); 746 } 747 748 protected void displayResult(IJavaValue result) { 749 StringBuffer resultString= new StringBuffer (); 750 try { 751 IJavaType type = result.getJavaType(); 752 if (type != null) { 753 String sig= type.getSignature(); 754 if ("V".equals(sig)) { resultString.append(SnippetMessages.getString("SnippetEditor.noreturnvalue")); } else { 757 if (sig != null) { 758 resultString.append(SnippetMessages.getFormattedString("SnippetEditor.typename", result.getReferenceTypeName())); } else { 760 resultString.append(" "); } 762 resultString.append(DisplayAction.trimDisplayResult(evaluateToString(result))); 763 } 764 } else { 765 resultString.append(DisplayAction.trimDisplayResult(result.getValueString())); 766 } 767 } catch(DebugException e) { 768 JDIDebugUIPlugin.log(e); 769 ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.toString"), null, e.getStatus()); } 771 772 final String message = resultString.toString(); 773 Runnable r = new Runnable () { 774 public void run() { 775 try { 776 getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); 777 selectAndReveal(fSnippetEnd, message.length()); 778 } catch (BadLocationException e) { 779 } 780 } 781 }; 782 async(r); 783 } 784 785 795 protected synchronized String evaluateToString(IJavaValue value) { 796 fResult= null; 797 fPresentation.computeDetail(value, this); 798 if (fResult == null) { 799 try { 800 wait(10000); 801 } catch (InterruptedException e) { 802 return SnippetMessages.getString("SnippetEditor.error.interrupted"); } 804 } 805 return fResult; 806 } 807 808 811 public synchronized void detailComputed(IValue value, final String result) { 812 fResult= result; 813 this.notifyAll(); 814 } 815 816 protected void showAllErrors(final String [] errors) { 817 IDocument document = getSourceViewer().getDocument(); 818 String delimiter = document.getLegalLineDelimiters()[0]; 819 820 final StringBuffer errorString = new StringBuffer (); 821 for (int i = 0; i < errors.length; i++) { 822 errorString.append(errors[i] + delimiter); 823 } 824 825 Runnable r = new Runnable () { 826 public void run() { 827 try { 828 getSourceViewer().getDocument().replace(fSnippetStart, 0, errorString.toString()); 829 selectAndReveal(fSnippetStart, errorString.length()); 830 } catch (BadLocationException e) { 831 } 832 } 833 }; 834 async(r); 835 } 836 837 private void showExpression(final JavaInspectExpression expression) { 838 Runnable r = new Runnable () { 839 public void run() { 840 new InspectPopupDialog(getShell(), EvaluateAction.getPopupAnchor(getSourceViewer().getTextWidget()), PopupInspectAction.ACTION_DEFININITION_ID, expression).open(); 841 } 842 }; 843 async(r); 844 } 845 846 847 protected void showException(Throwable exception) { 848 if (exception instanceof DebugException) { 849 DebugException de = (DebugException)exception; 850 Throwable t= de.getStatus().getException(); 851 if (t != null) { 852 showUnderlyingException(t); 854 return; 855 } 856 } 857 ByteArrayOutputStream bos= new ByteArrayOutputStream (); 858 PrintStream ps= new PrintStream (bos, true); 859 exception.printStackTrace(ps); 860 861 final String message = bos.toString(); 862 Runnable r = new Runnable () { 863 public void run() { 864 try { 865 getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); 866 selectAndReveal(fSnippetEnd, message.length()); 867 } catch (BadLocationException e) { 868 } 869 } 870 }; 871 async(r); 872 } 873 874 protected void showUnderlyingException(Throwable t) { 875 if (t instanceof InvocationException) { 876 InvocationException ie= (InvocationException)t; 877 ObjectReference ref= ie.exception(); 878 String eName= ref.referenceType().name(); 879 final String message= SnippetMessages.getFormattedString("SnippetEditor.exception", eName); Runnable r = new Runnable () { 881 public void run() { 882 try { 883 getSourceViewer().getDocument().replace(fSnippetEnd, 0, message); 884 selectAndReveal(fSnippetEnd, message.length()); 885 } catch (BadLocationException e) { 886 } 887 } 888 }; 889 async(r); 890 } else { 891 showException(t); 892 } 893 } 894 895 protected IJavaProject findJavaProject() throws JavaModelException { 896 IFile file = getFile(); 897 if (file != null) { 898 IProject p= file.getProject(); 899 try { 900 if (p.getNature(JavaCore.NATURE_ID) != null) { 901 return JavaCore.create(p); 902 } 903 } catch (CoreException ce) { 904 throw new JavaModelException(ce); 905 } 906 } 907 return null; 908 } 909 910 protected boolean classPathHasChanged() { 911 String [] classpath= getClassPath(getJavaProject()); 912 if (fLaunchedClassPath != null && !classPathsEqual(fLaunchedClassPath, classpath)) { 913 MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.warning"), SnippetMessages.getString("SnippetEditor.warning.cpchange")); return true; 915 } 916 return false; 917 } 918 919 protected boolean workingDirHasChanged() { 920 String wd = getWorkingDirectoryAttribute(); 921 boolean changed = false; 922 if (wd == null || fLaunchedWorkingDir == null) { 923 if (wd != fLaunchedWorkingDir) { 924 changed = true; 925 } 926 } else { 927 if (!wd.equals(fLaunchedWorkingDir)) { 928 changed = true; 929 } 930 } 931 if (changed && fVM != null) { 932 MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_working_directory_has_changed._Restarting_the_evaluation_context._2")); } 934 return changed; 935 } 936 937 protected boolean vmArgsChanged() { 938 String args = getVMArgsAttribute(); 939 boolean changed = false; 940 if (args == null || fLaunchedVMArgs == null) { 941 if (args != fLaunchedVMArgs) { 942 changed = true; 943 } 944 } else { 945 if (!args.equals(fLaunchedVMArgs)) { 946 changed = true; 947 } 948 } 949 if (changed && fVM != null) { 950 MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.1")); } 952 return changed; 953 } 954 955 protected boolean vmHasChanged() { 956 IVMInstall vm = getVMInstall(); 957 boolean changed = false; 958 if (vm == null || fLaunchedVM == null) { 959 if (vm != fLaunchedVM) { 960 changed = true; 961 } 962 } else { 963 if (!vm.equals(fLaunchedVM)) { 964 changed = true; 965 } 966 } 967 if (changed && fVM != null) { 968 MessageDialog.openWarning(getShell(), SnippetMessages.getString("SnippetEditor.Warning_1"), SnippetMessages.getString("SnippetEditor.The_JRE_has_changed._Restarting_the_evaluation_context._2")); } 970 return changed; 971 } 972 973 protected boolean classPathsEqual(String [] path1, String [] path2) { 974 if (path1.length != path2.length) { 975 return false; 976 } 977 for (int i= 0; i < path1.length; i++) { 978 if (!path1[i].equals(path2[i])) { 979 return false; 980 } 981 } 982 return true; 983 } 984 985 protected synchronized void evaluationStarts() { 986 if (fThread != null) { 987 try { 988 IThread thread = fThread; 989 fThread = null; 990 thread.resume(); 991 } catch (DebugException e) { 992 JDIDebugUIPlugin.log(e); 993 showException(e); 994 return; 995 } 996 } 997 fEvaluating = true; 998 setTitleImage(); 999 fireEvalStateChanged(); 1000 showStatus(SnippetMessages.getString("SnippetEditor.evaluating")); getSourceViewer().setEditable(false); 1002 } 1003 1004 1008 protected void setTitleImage() { 1009 Image image=null; 1010 if (fEvaluating) { 1011 fOldTitleImage= getTitleImage(); 1012 image= JavaDebugImages.get(JavaDebugImages.IMG_OBJS_SNIPPET_EVALUATING); 1013 } else { 1014 image= fOldTitleImage; 1015 fOldTitleImage= null; 1016 } 1017 if (image != null) { 1018 setTitleImage(image); 1019 } 1020 } 1021 1022 protected void evaluationEnds() { 1023 Runnable r = new Runnable () { 1024 public void run() { 1025 fEvaluating= false; 1026 setTitleImage(); 1027 fireEvalStateChanged(); 1028 showStatus(""); getSourceViewer().setEditable(true); 1030 } 1031 }; 1032 async(r); 1033 } 1034 1035 protected void showStatus(String message) { 1036 IEditorSite site=(IEditorSite)getSite(); 1037 EditorActionBarContributor contributor= (EditorActionBarContributor)site.getActionBarContributor(); 1038 contributor.getActionBars().getStatusLineManager().setMessage(message); 1039 } 1040 1041 protected String [] getClassPath(IJavaProject project) { 1042 try { 1043 return JavaRuntime.computeDefaultRuntimeClassPath(project); 1044 } catch (CoreException e) { 1045 JDIDebugUIPlugin.log(e); 1046 return new String [0]; 1047 } 1048 } 1049 1050 protected Shell getShell() { 1051 return getSite().getShell(); 1052 } 1053 1054 1057 public DebugEvent[] filterDebugEvents(DebugEvent[] events) { 1058 for (int i = 0; i < events.length; i++) { 1059 DebugEvent e = events[i]; 1060 Object source = e.getSource(); 1061 if (source instanceof IDebugElement) { 1062 IDebugElement de = (IDebugElement)source; 1063 if (de instanceof IDebugTarget) { 1064 if (de.getDebugTarget().equals(fVM)) { 1065 if (e.getKind() == DebugEvent.TERMINATE) { 1066 setThread(null); 1067 Runnable r = new Runnable () { 1068 public void run() { 1069 vmTerminated(); 1070 } 1071 }; 1072 getShell().getDisplay().asyncExec(r); 1073 } 1074 } 1075 } else if (de instanceof IJavaThread) { 1076 if (e.getKind() == DebugEvent.SUSPEND) { 1077 IJavaThread jt = (IJavaThread)de; 1078 try { 1079 if (jt.equals(getThread()) && e.getDetail() == DebugEvent.EVALUATION) { 1080 return null; 1081 } 1082 IJavaStackFrame f= (IJavaStackFrame)jt.getTopStackFrame(); 1083 if (f != null) { 1084 IJavaDebugTarget target = (IJavaDebugTarget) f.getDebugTarget(); 1085 IBreakpoint[] bps = jt.getBreakpoints(); 1086 int lineNumber = f.getLineNumber(); 1088 if (e.getDetail() == DebugEvent.STEP_END && (lineNumber == 20 || lineNumber == 21) 1089 && f.getDeclaringTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") && jt.getDebugTarget() == fVM) { 1091 target.setStepFiltersEnabled(fStepFiltersSetting); 1093 setThread(jt); 1094 return null; 1095 } else if (e.getDetail() == DebugEvent.BREAKPOINT && bps.length > 0 && bps[0].equals(ScrapbookLauncher.getDefault().getMagicBreakpoint(jt.getDebugTarget()))) { 1096 IStackFrame[] frames = jt.getStackFrames(); 1098 for (int j = 0; j < frames.length; j++) { 1099 IJavaStackFrame frame = (IJavaStackFrame)frames[j]; 1100 if (frame.getReceivingTypeName().equals("org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain1") && frame.getName().equals("eval")) { fStepFiltersSetting = target.isStepFiltersEnabled(); 1103 target.setStepFiltersEnabled(false); 1104 frame.stepOver(); 1105 return null; 1106 } 1107 } 1108 } 1109 } 1110 } catch (DebugException ex) { 1111 JDIDebugUIPlugin.log(ex); 1112 } 1113 } 1114 } 1115 } 1116 } 1117 return events; 1118 } 1119 1120 1123 protected boolean affectsTextPresentation(PropertyChangeEvent event) { 1124 JavaSourceViewerConfiguration sourceViewerConfiguration = (JavaSourceViewerConfiguration) getSourceViewerConfiguration(); 1125 return sourceViewerConfiguration.affectsTextPresentation(event); 1126 } 1127 1128 1131 protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { 1132 JDISourceViewer isv= (JDISourceViewer) getSourceViewer(); 1133 if (isv != null) { 1134 IContentAssistant assistant= isv.getContentAssistant(); 1135 if (assistant instanceof ContentAssistant) { 1136 JDIContentAssistPreference.changeConfiguration((ContentAssistant) assistant, event); 1137 } 1138 SourceViewerConfiguration configuration = getSourceViewerConfiguration(); 1139 if (configuration instanceof JavaSourceViewerConfiguration) { 1140 JavaSourceViewerConfiguration jsv = (JavaSourceViewerConfiguration) configuration; 1141 if (jsv.affectsTextPresentation(event)) { 1142 jsv.handlePropertyChangeEvent(event); 1143 isv.invalidateTextPresentation(); 1144 } 1145 } 1146 super.handlePreferenceStoreChanged(event); 1147 } 1148 } 1149 1150 protected IJavaThread getThread() { 1151 return fThread; 1152 } 1153 1154 1159 protected synchronized void setThread(IJavaThread thread) { 1160 fThread= thread; 1161 notifyAll(); 1162 } 1163 1164 protected void launchVM() { 1165 DebugPlugin.getDefault().addDebugEventFilter(this); 1166 fLaunchedClassPath = getClassPath(getJavaProject()); 1167 fLaunchedWorkingDir = getWorkingDirectoryAttribute(); 1168 fLaunchedVMArgs = getVMArgsAttribute(); 1169 fLaunchedVM = getVMInstall(); 1170 Runnable r = new Runnable () { 1171 public void run() { 1172 ScrapbookLauncher.getDefault().launch(getFile()); 1173 } 1174 }; 1175 BusyIndicator.showWhile(getShell().getDisplay(), r); 1176 } 1177 1178 1183 public IFile getFile() { 1184 IEditorInput input= getEditorInput(); 1185 return (IFile) input.getAdapter(IFile.class); 1186 } 1187 1188 1191 protected void updateSelectionDependentActions() { 1192 super.updateSelectionDependentActions(); 1193 fireEvalStateChanged(); 1194 } 1195 1196 1199 protected void setTitle(String title) { 1200 cleanupOnRenameOrMove(); 1201 super.setTitle(title); 1202 } 1203 1204 1208 protected void cleanupOnRenameOrMove() { 1209 if(isVMLaunched()) { 1210 shutDownVM(); 1211 } else { 1212 fThread= null; 1213 fEvaluationContext= null; 1214 fLaunchedClassPath= null; 1215 1216 if (fEngine != null) { 1217 fEngine.dispose(); 1218 fEngine= null; 1219 } 1220 } 1221 fJavaProject= null; 1222 } 1223 1224 1228 protected boolean isInJavaProject() { 1229 try { 1230 return findJavaProject() != null; 1231 } catch (JavaModelException jme) { 1232 JDIDebugUIPlugin.log(jme); 1233 } 1234 return false; 1235 } 1236 1237 1241 protected void reportNotInJavaProjectError() { 1242 String projectName= null; 1243 IFile file= getFile(); 1244 if (file != null) { 1245 IProject p= file.getProject(); 1246 projectName= p.getName(); 1247 } 1248 String message= ""; if (projectName != null) { 1250 message = projectName + SnippetMessages.getString("JavaSnippetEditor._is_not_a_Java_Project._n_1"); } 1252 showError(message + SnippetMessages.getString("JavaSnippetEditor.Unable_to_perform_evaluation_outside_of_a_Java_Project_2")); } 1254 1255 1260 protected void performSaveAs(IProgressMonitor progressMonitor) { 1261 Shell shell= getSite().getShell(); 1262 SaveAsDialog dialog= new SaveAsDialog(shell); 1263 dialog.open(); 1264 IPath path= dialog.getResult(); 1265 1266 if (path == null) { 1267 if (progressMonitor != null) 1268 progressMonitor.setCanceled(true); 1269 return; 1270 } 1271 1272 IWorkspace workspace= ResourcesPlugin.getWorkspace(); 1273 IFile file= workspace.getRoot().getFile(path); 1274 final IEditorInput newInput= new FileEditorInput(file); 1275 1276 WorkspaceModifyOperation op= new WorkspaceModifyOperation() { 1277 public void execute(final IProgressMonitor monitor) throws CoreException { 1278 IDocumentProvider dp= getDocumentProvider(); 1279 dp.saveDocument(monitor, newInput, dp.getDocument(getEditorInput()), true); 1280 } 1281 }; 1282 1283 boolean success= false; 1284 try { 1285 getDocumentProvider().aboutToChange(newInput); 1286 PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op); 1287 success= true; 1288 } catch (InterruptedException x) { 1289 } catch (InvocationTargetException x) { 1290 JDIDebugUIPlugin.log(x); 1291 String title= SnippetMessages.getString("JavaSnippetEditor.Problems_During_Save_As..._3"); String msg= SnippetMessages.getString("JavaSnippetEditor.Save_could_not_be_completed.__4") + x.getTargetException().getMessage(); MessageDialog.openError(shell, title, msg); 1294 } finally { 1295 getDocumentProvider().changed(newInput); 1296 if (success) { 1297 setInput(newInput); 1298 } 1299 } 1300 1301 if (progressMonitor != null) { 1302 progressMonitor.setCanceled(!success); 1303 } 1304 } 1305 1306 1309 public boolean isSaveAsAllowed() { 1310 return true; 1311 } 1312 1313 protected IClassFileEvaluationEngine getEvaluationEngine() { 1314 if (fEngine == null) { 1315 IPath outputLocation = getJavaProject().getProject().getWorkingLocation(JDIDebugUIPlugin.getUniqueIdentifier()); 1316 java.io.File f = new java.io.File (outputLocation.toOSString()); 1317 fEngine = EvaluationManager.newClassFileEvaluationEngine(getJavaProject(), (IJavaDebugTarget)getThread().getDebugTarget(), f); 1318 } 1319 if (getImports() != null) { 1320 fEngine.setImports(getImports()); 1321 } else { 1322 fEngine.setImports(new String []{}); 1323 } 1324 return fEngine; 1325 } 1326 1327 1330 protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { 1331 return new JDISourceViewer(parent, ruler, styles); 1332 } 1333 1334 1337 protected String getWorkingDirectoryAttribute() { 1338 IFile file= getFile(); 1339 if (file != null) { 1340 try { 1341 return ScrapbookLauncher.getWorkingDirectoryAttribute(file); 1342 } catch (CoreException e) { 1343 JDIDebugUIPlugin.log(e); 1344 } 1345 } 1346 return null; 1347 } 1348 1349 1352 protected String getVMArgsAttribute() { 1353 IFile file= getFile(); 1354 if (file != null) { 1355 try { 1356 return ScrapbookLauncher.getVMArgsAttribute(file); 1357 } catch (CoreException e) { 1358 JDIDebugUIPlugin.log(e); 1359 } 1360 } 1361 return null; 1362 } 1363 1364 1367 protected IVMInstall getVMInstall() { 1368 IFile file= getFile(); 1369 if (file != null) { 1370 try { 1371 return ScrapbookLauncher.getVMInstall(file); 1372 } catch (CoreException e) { 1373 JDIDebugUIPlugin.log(e); 1374 } 1375 } 1376 return null; 1377 } 1378 1379 1382 protected void async(Runnable r) { 1383 Control control= getVerticalRuler().getControl(); 1384 if (!control.isDisposed()) { 1385 control.getDisplay().asyncExec(r); 1386 } 1387 } 1388 1389 protected void showAndSelect(final String text, final int offset) { 1390 Runnable r = new Runnable () { 1391 public void run() { 1392 try { 1393 getSourceViewer().getDocument().replace(offset, 0, text); 1394 } catch (BadLocationException e) { 1395 JDIDebugUIPlugin.log(e); 1396 } 1397 selectAndReveal(offset, text.length()); 1398 } 1399 }; 1400 async(r); 1401 } 1402 1405 public Object getAdapter(Class required) { 1406 if (required == IShowInTargetList.class) { 1407 return new IShowInTargetList() { 1408 public String [] getShowInTargetIds() { 1409 return new String [] { JavaUI.ID_PACKAGES, IPageLayout.ID_RES_NAV }; 1410 } 1411 1412 }; 1413 } 1414 return super.getAdapter(required); 1415 } 1416 1417} 1418 | Popular Tags |