KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > ui > snippeteditor > JavaSnippetEditor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - bug 38919
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.debug.ui.snippeteditor;
13
14  
15 import java.io.ByteArrayOutputStream JavaDoc;
16 import java.io.PrintStream JavaDoc;
17 import java.lang.reflect.InvocationTargetException JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.List JavaDoc;
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 /**
128  * An editor for Java snippets.
129  */

130 public class JavaSnippetEditor extends AbstractDecoratedTextEditor implements IDebugEventFilter, IEvaluationListener, IValueDetailListener {
131     public static final String JavaDoc IMPORTS_CONTEXT = "SnippetEditor.imports"; //$NON-NLS-1$
132

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; // one of the RESULT_* constants
138

139     private IJavaProject fJavaProject;
140     private IEvaluationContext fEvaluationContext;
141     private IDebugTarget fVM;
142     private String JavaDoc[] fLaunchedClassPath;
143     private String JavaDoc fLaunchedWorkingDir;
144     private String JavaDoc fLaunchedVMArgs;
145     private IVMInstall fLaunchedVM;
146     private List JavaDoc 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 JavaDoc[] fImports= null;
156     
157     private Image fOldTitleImage= null;
158     private IClassFileEvaluationEngine fEngine= null;
159     
160     /**
161      * The debug model presentation used for computing toString
162      */

163     private IDebugModelPresentation fPresentation= DebugUITools.newDebugModelPresentation(JDIDebugModel.getPluginIdentifier());
164     /**
165      * The result of a toString evaluation returned asynchronously by the
166      * debug model.
167      */

168     private String JavaDoc fResult;
169
170     /**
171      * A thread that waits to have a
172      * thread to perform an evaluation in.
173      */

174     private static class WaitThread extends Thread JavaDoc {
175         /**
176          * The display used for event dispatching.
177          */

178         private Display fDisplay;
179         
180         /**
181          * Indicates whether to continue event queue dispatching.
182          */

183         private volatile boolean fContinueEventDispatching = true;
184         
185         private Object JavaDoc fLock;
186         /**
187          * Creates a "wait" thread
188          *
189          * @param display the display to be used to read and dispatch events
190          * @param lock the monitor to wait on
191          */

192         private WaitThread(Display display, Object JavaDoc lock) {
193             super("Snippet Wait Thread"); //$NON-NLS-1$
194
setDaemon(true);
195             fDisplay = display;
196             fLock= lock;
197         }
198         public void run() {
199             try {
200                 synchronized (fLock) {
201                     //should be notified out of #setThread(IJavaThread)
202
fLock.wait(10000);
203                 }
204             } catch (InterruptedException JavaDoc e) {
205             } finally {
206                 // Make sure that all events in the asynchronous event queue
207
// are dispatched.
208
fDisplay.syncExec(new Runnable JavaDoc() {
209                     public void run() {
210                         // do nothing
211
}
212                 });
213                 
214                 // Stop event dispatching
215
fContinueEventDispatching= false;
216                 
217                 // Force the event loop to return from sleep () so that
218
// it stops event dispatching.
219
fDisplay.asyncExec(null);
220             }
221         }
222         /**
223          * Processes events.
224          */

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     /**
236      * Listens for part activation to set scrapbook active system property
237      * for action enablement.
238      */

239     private IPartListener2 fActivationListener = new IPartListener2() {
240
241         public void partActivated(IWorkbenchPartReference partRef) {
242             if ("org.eclipse.jdt.debug.ui.SnippetEditor".equals(partRef.getId())) { //$NON-NLS-1$
243
System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "true"); //$NON-NLS-1$ //$NON-NLS-2$
244
} else {
245                 System.setProperty(JDIDebugUIPlugin.getUniqueIdentifier() + ".scrapbookActive", "false"); //$NON-NLS-1$ //$NON-NLS-2$
246
}
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 JavaDoc(4);
280         setPreferenceStore(store);
281         setEditorContextMenuId("#JavaSnippetEditorContext"); //$NON-NLS-1$
282
setRulerContextMenuId("#JavaSnippetRulerContext"); //$NON-NLS-1$
283
}
284     
285     /* (non-Javadoc)
286      * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
287      */

288     protected void doSetInput(IEditorInput input) throws CoreException {
289         super.doSetInput(input);
290         IFile file= getFile();
291         if (file != null) {
292             String JavaDoc 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     /* (non-Javadoc)
305      * @see org.eclipse.ui.IWorkbenchPart#dispose()
306      */

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     /**
317      * Actions for the editor popup menu
318      * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
319      */

320     protected void createActions() {
321         super.createActions();
322         if (getFile() != null) {
323             Action action = new TextOperationAction(SnippetMessages.getBundle(), "SnippetEditor.ContentAssistProposal.", this, ISourceViewer.CONTENTASSIST_PROPOSALS); //$NON-NLS-1$
324
action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
325             setAction("ContentAssistProposal", action);//$NON-NLS-1$
326
setAction("ShowInPackageView", new ShowInPackageViewAction(this)); //$NON-NLS-1$
327
setAction("Stop", new StopAction(this)); //$NON-NLS-1$
328
setAction("SelectImports", new SelectImportsAction(this)); //$NON-NLS-1$
329
}
330     }
331     
332     /* (non-Javadoc)
333      * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
334      */

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"); //$NON-NLS-1$
342
addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Run"); //$NON-NLS-1$
343
addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "Stop"); //$NON-NLS-1$
344
addAction(menu, IContextMenuConstants.GROUP_ADDITIONS, "SelectImports"); //$NON-NLS-1$
345
}
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 JavaDoc snippet= selection.getText();
380         fSnippetStart= selection.getOffset();
381         fSnippetEnd= fSnippetStart + selection.getLength();
382         
383         evaluate(snippet);
384     }
385     
386     /**
387      * Checks if the page has been copied/moved to a different project or the project has been renamed.
388      * Updates the launch configuration template if a copy/move/rename has occurred.
389      */

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 JavaDoc projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String JavaDoc)null);
399                 IJavaProject pro = JavaCore.create(file.getProject());
400                 if (!pro.getElementName().equals(projectName)) {
401                     //the page has been moved to a "different" project
402
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()); //$NON-NLS-1$
408
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 JavaDoc {
456                 try {
457                     getJavaProject().getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, pm);
458                 } catch (CoreException e) {
459                     throw new InvocationTargetException JavaDoc(e);
460                 }
461             }
462         };
463         try {
464             PlatformUI.getWorkbench().getProgressService().run(true, false, r);
465         } catch (InterruptedException JavaDoc e) {
466             JDIDebugUIPlugin.log(e);
467             evaluationEnds();
468             return false;
469         } catch (InvocationTargetException JavaDoc 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         //multiple editors are opened on the same page
480
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 JavaDoc[] imports) {
497         fImports= imports;
498         IFile file= getFile();
499         if (file == null) {
500             return;
501         }
502         String JavaDoc serialized= null;
503         if (imports != null) {
504             serialized= JavaDebugOptionsManager.serializeList(imports);
505         }
506         // persist
507
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()); //$NON-NLS-1$
512
}
513     }
514     
515     protected String JavaDoc[] 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 JavaDoc[]{});
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         // The real shut down
552
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()); //$NON-NLS-1$
567
return;
568             }
569             vmTerminated();
570             ScrapbookLauncher.getDefault().cleanup(target);
571         }
572     }
573     
574     /**
575      * The VM has terminated, update state
576      */

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 JavaDoc r= new Runnable JavaDoc() {
603             public void run() {
604                 Shell shell= getShell();
605                 if (fSnippetStateListeners != null && shell != null && !shell.isDisposed()) {
606                     List JavaDoc v= new ArrayList JavaDoc(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 JavaDoc 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); //$NON-NLS-1$
629
ErrorDialog.openError(getShell(), SnippetMessages.getString("SnippetEditor.error.evaluating"), null, status); //$NON-NLS-1$
630
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()); //$NON-NLS-1$
639
evaluationEnds();
640         }
641     }
642     
643     /* (non-Javadoc)
644      * @see org.eclipse.jdt.debug.eval.IEvaluationListener#evaluationComplete(org.eclipse.jdt.debug.eval.IEvaluationResult)
645      */

646     public void evaluationComplete(IEvaluationResult result) {
647             boolean severeErrors = false;
648             if (result.hasErrors()) {
649                 String JavaDoc[] 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 JavaDoc 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); //$NON-NLS-1$
667
}
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                     // no action
676
break;
677                 }
678             }
679             evaluationEnds();
680     }
681     
682     /**
683      * Make the expression view visible or open one
684      * if required.
685      */

686     protected void showExpressionView() {
687         Runnable JavaDoc r = new Runnable JavaDoc() {
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 JavaDoc 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