KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > viewsupport > SelectionListenerWithASTManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.viewsupport;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.ListenerList;
19 import org.eclipse.core.runtime.NullProgressMonitor;
20 import org.eclipse.core.runtime.OperationCanceledException;
21 import org.eclipse.core.runtime.Status;
22 import org.eclipse.core.runtime.jobs.Job;
23
24 import org.eclipse.jface.viewers.ISelection;
25 import org.eclipse.jface.viewers.ISelectionChangedListener;
26 import org.eclipse.jface.viewers.ISelectionProvider;
27 import org.eclipse.jface.viewers.SelectionChangedEvent;
28
29 import org.eclipse.jface.text.ITextSelection;
30
31 import org.eclipse.ui.ISelectionListener;
32 import org.eclipse.ui.IWorkbenchPart;
33 import org.eclipse.ui.texteditor.ITextEditor;
34
35 import org.eclipse.jdt.core.IJavaElement;
36 import org.eclipse.jdt.core.dom.CompilationUnit;
37
38 import org.eclipse.jdt.internal.ui.JavaPlugin;
39 import org.eclipse.jdt.internal.ui.JavaUIMessages;
40 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
41 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
42
43 /**
44  * Infrastructure to share an AST for editor post selection listeners.
45  */

46 public class SelectionListenerWithASTManager {
47     
48     private static SelectionListenerWithASTManager fgDefault;
49     
50     /**
51      * @return Returns the default manager instance.
52      */

53     public static SelectionListenerWithASTManager getDefault() {
54         if (fgDefault == null) {
55             fgDefault= new SelectionListenerWithASTManager();
56         }
57         return fgDefault;
58     }
59     
60     
61     private final static class PartListenerGroup {
62         private ITextEditor fPart;
63         private ISelectionListener fPostSelectionListener;
64         private ISelectionChangedListener fSelectionListener;
65         private Job fCurrentJob;
66         private ListenerList fAstListeners;
67         /**
68          * Lock to avoid having more than one calculateAndInform job in parallel.
69          * Only jobs may synchronize on this as otherwise deadlocks are possible.
70          */

71         private final Object JavaDoc fJobLock= new Object JavaDoc();
72         
73         public PartListenerGroup(ITextEditor editorPart) {
74             fPart= editorPart;
75             fCurrentJob= null;
76             fAstListeners= new ListenerList(ListenerList.IDENTITY);
77             
78             fSelectionListener= new ISelectionChangedListener() {
79                 public void selectionChanged(SelectionChangedEvent event) {
80                     ISelection selection= event.getSelection();
81                     if (selection instanceof ITextSelection) {
82                         fireSelectionChanged((ITextSelection) selection);
83                     }
84                 }
85             };
86             
87             fPostSelectionListener= new ISelectionListener() {
88                 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
89                     if (part == fPart && selection instanceof ITextSelection)
90                         firePostSelectionChanged((ITextSelection) selection);
91                 }
92             };
93         }
94
95         public boolean isEmpty() {
96             return fAstListeners.isEmpty();
97         }
98
99         public void install(ISelectionListenerWithAST listener) {
100             if (isEmpty()) {
101                 fPart.getEditorSite().getPage().addPostSelectionListener(fPostSelectionListener);
102                 ISelectionProvider selectionProvider= fPart.getSelectionProvider();
103                 if (selectionProvider != null)
104                         selectionProvider.addSelectionChangedListener(fSelectionListener);
105             }
106             fAstListeners.add(listener);
107         }
108         
109         public void uninstall(ISelectionListenerWithAST listener) {
110             fAstListeners.remove(listener);
111             if (isEmpty()) {
112                 fPart.getEditorSite().getPage().removePostSelectionListener(fPostSelectionListener);
113                 ISelectionProvider selectionProvider= fPart.getSelectionProvider();
114                 if (selectionProvider != null)
115                     selectionProvider.removeSelectionChangedListener(fSelectionListener);
116             }
117         }
118         
119         public void fireSelectionChanged(final ITextSelection selection) {
120             if (fCurrentJob != null) {
121                 fCurrentJob.cancel();
122             }
123         }
124         
125         public void firePostSelectionChanged(final ITextSelection selection) {
126             if (fCurrentJob != null) {
127                 fCurrentJob.cancel();
128             }
129             final IJavaElement input= EditorUtility.getEditorInputJavaElement(fPart, false);
130             if (input == null) {
131                 return;
132             }
133             
134             fCurrentJob= new Job(JavaUIMessages.SelectionListenerWithASTManager_job_title) {
135                 public IStatus run(IProgressMonitor monitor) {
136                     if (monitor == null) {
137                         monitor= new NullProgressMonitor();
138                     }
139                     synchronized (fJobLock) {
140                         return calculateASTandInform(input, selection, monitor);
141                     }
142                 }
143             };
144             fCurrentJob.setPriority(Job.DECORATE);
145             fCurrentJob.setSystem(true);
146             fCurrentJob.schedule();
147         }
148         
149         protected IStatus calculateASTandInform(IJavaElement input, ITextSelection selection, IProgressMonitor monitor) {
150             if (monitor.isCanceled()) {
151                 return Status.CANCEL_STATUS;
152             }
153             // create AST
154
try {
155                 CompilationUnit astRoot= JavaPlugin.getDefault().getASTProvider().getAST(input, ASTProvider.WAIT_ACTIVE_ONLY, monitor);
156             
157                 if (astRoot != null && !monitor.isCanceled()) {
158                     Object JavaDoc[] listeners;
159                     synchronized (PartListenerGroup.this) {
160                         listeners= fAstListeners.getListeners();
161                     }
162                     for (int i= 0; i < listeners.length; i++) {
163                         ((ISelectionListenerWithAST) listeners[i]).selectionChanged(fPart, selection, astRoot);
164                         if (monitor.isCanceled()) {
165                             return Status.CANCEL_STATUS;
166                         }
167                     }
168                     return Status.OK_STATUS;
169                 }
170             } catch (OperationCanceledException e) {
171                 // thrown when canceling the AST creation
172
}
173             return Status.CANCEL_STATUS;
174         }
175     }
176     
177         
178     private Map JavaDoc fListenerGroups;
179     
180     private SelectionListenerWithASTManager() {
181         fListenerGroups= new HashMap JavaDoc();
182     }
183     
184     /**
185      * Registers a selection listener for the given editor part.
186      * @param part The editor part to listen to.
187      * @param listener The listener to register.
188      */

189     public void addListener(ITextEditor part, ISelectionListenerWithAST listener) {
190         synchronized (this) {
191             PartListenerGroup partListener= (PartListenerGroup) fListenerGroups.get(part);
192             if (partListener == null) {
193                 partListener= new PartListenerGroup(part);
194                 fListenerGroups.put(part, partListener);
195             }
196             partListener.install(listener);
197         }
198     }
199
200     /**
201      * Unregisters a selection listener.
202      * @param part The editor part the listener was registered.
203      * @param listener The listener to unregister.
204      */

205     public void removeListener(ITextEditor part, ISelectionListenerWithAST listener) {
206         synchronized (this) {
207             PartListenerGroup partListener= (PartListenerGroup) fListenerGroups.get(part);
208             if (partListener != null) {
209                 partListener.uninstall(listener);
210                 if (partListener.isEmpty()) {
211                     fListenerGroups.remove(part);
212                 }
213             }
214         }
215     }
216 }
217
Popular Tags