1 11 package org.eclipse.jdt.internal.ui.viewsupport; 12 13 import java.util.HashMap ; 14 import java.util.Map ; 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 46 public class SelectionListenerWithASTManager { 47 48 private static SelectionListenerWithASTManager fgDefault; 49 50 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 71 private final Object fJobLock= new Object (); 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 try { 155 CompilationUnit astRoot= JavaPlugin.getDefault().getASTProvider().getAST(input, ASTProvider.WAIT_ACTIVE_ONLY, monitor); 156 157 if (astRoot != null && !monitor.isCanceled()) { 158 Object [] 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 } 173 return Status.CANCEL_STATUS; 174 } 175 } 176 177 178 private Map fListenerGroups; 179 180 private SelectionListenerWithASTManager() { 181 fListenerGroups= new HashMap (); 182 } 183 184 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 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 |