1 11 package org.eclipse.debug.internal.ui.views; 12 13 import java.util.ArrayList ; 14 import java.util.HashSet ; 15 import java.util.List ; 16 import java.util.ListIterator ; 17 import java.util.Set ; 18 import java.util.Vector ; 19 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.IStatus; 22 import org.eclipse.core.runtime.Status; 23 import org.eclipse.core.runtime.jobs.ISchedulingRule; 24 import org.eclipse.core.runtime.jobs.Job; 25 import org.eclipse.debug.core.DebugEvent; 26 import org.eclipse.debug.core.DebugException; 27 import org.eclipse.debug.core.DebugPlugin; 28 import org.eclipse.debug.core.IDebugEventSetListener; 29 import org.eclipse.debug.core.model.IDebugTarget; 30 import org.eclipse.debug.core.model.IStackFrame; 31 import org.eclipse.debug.core.model.IThread; 32 import org.eclipse.debug.internal.ui.DebugUIPlugin; 33 import org.eclipse.debug.ui.IDebugModelPresentation; 34 import org.eclipse.jface.viewers.ILabelDecorator; 35 import org.eclipse.jface.viewers.LabelProvider; 36 import org.eclipse.swt.graphics.Image; 37 38 42 public class DebugViewLabelDecorator extends LabelProvider implements ILabelDecorator, IDebugEventSetListener { 43 44 47 private IDebugModelPresentation fPresentation; 48 51 private DebugViewDecoratingLabelProvider fLabelProvider; 52 56 protected LabelJob fNextJob= null; 57 63 private Set resumedThreads= new HashSet (); 64 68 private IStackFrame fCurrentStackFrame= null; 69 73 private Object fCurrentStackFrameLock= new Object (); 74 75 80 public DebugViewLabelDecorator(IDebugModelPresentation presentation) { 81 fPresentation= presentation; 82 DebugPlugin.getDefault().addDebugEventListener(this); 83 } 84 85 92 public void setLabelProvider(DebugViewDecoratingLabelProvider labelProvider) { 93 fLabelProvider= labelProvider; 94 } 95 96 99 public Image decorateImage(Image image, Object element) { 100 return image; 101 } 102 103 106 public String decorateText(String text, final Object element) { 107 computeText(element); 108 return text; 109 } 110 111 116 public void computeText(Object element) { 117 synchronized(this) { 118 if (fNextJob == null) { 119 fNextJob= new LabelJob(DebugUIViewsMessages.DebugViewLabelDecorator_0, fPresentation); } 121 fNextJob.computeText(element); 122 } 123 } 124 125 132 public void labelsComputed(final Object [] computedElements) { 133 DebugUIPlugin.getStandardDisplay().asyncExec(new Runnable () { 134 public void run() { 135 fLabelProvider.labelsComputed(computedElements); 136 } 137 }); 138 } 139 140 143 public void handleDebugEvents(DebugEvent[] events) { 144 for (int i = 0; i < events.length; i++) { 145 DebugEvent event= events[i]; 146 if (event.getKind() == DebugEvent.SUSPEND) { 147 handleSuspendEvent(event); 148 } else if (event.getKind() == DebugEvent.TERMINATE) { 149 handleTerminateEvent(event); 150 } else if (event.getKind() == DebugEvent.RESUME) { 151 handleResumeEvent(event); 152 } 153 } 154 } 155 156 165 private void handleResumeEvent(DebugEvent event) { 166 if (event.getSource() instanceof IThread && (event.isEvaluation() || event.isStepStart())) { 167 IThread thread= (IThread) event.getSource(); 168 IStackFrame frame; 169 synchronized (fCurrentStackFrameLock) { 170 if (fCurrentStackFrame == null) { 171 return; 172 } 173 frame= fCurrentStackFrame; 174 } 175 if (thread == frame.getThread()) { 176 resumedThreads.add(thread); 177 } 178 } 179 } 180 181 189 private void handleSuspendEvent(DebugEvent event) { 190 Object source= event.getSource(); 191 synchronized (resumedThreads) { 192 if (!resumedThreads.remove(source)) { 193 return; 194 } 195 } 196 if (!event.isEvaluation() && (event.getDetail() & DebugEvent.STEP_END) == 0) { 197 return; 198 } 199 IThread thread= (IThread) source; 200 try { 201 IStackFrame[] frames= thread.getStackFrames(); 202 for (int i = 0; i < frames.length; i++) { 203 computeText(frames[i]); 204 } 205 } catch (DebugException e) { 206 } 207 } 208 209 217 private void handleTerminateEvent(DebugEvent event) { 218 Object source= event.getSource(); 219 if (source instanceof IDebugTarget) { 220 List copiedThreads= new ArrayList (resumedThreads); 221 ListIterator iterator = copiedThreads.listIterator(); 222 while (iterator.hasNext()) { 223 IThread thread = (IThread) iterator.next(); 224 if (thread.getDebugTarget() == source) { 225 iterator.remove(); 226 } 227 } 228 synchronized(resumedThreads) { 229 resumedThreads.retainAll(copiedThreads); 230 } 231 } 232 } 233 234 237 public void dispose() { 238 super.dispose(); 239 DebugPlugin.getDefault().removeDebugEventListener(this); 240 } 241 242 247 protected class LabelJob extends Job implements ISchedulingRule { 248 private Vector fElementQueue= new Vector (); 249 private IDebugModelPresentation fJobPresentation; 250 251 258 public LabelJob(String name, IDebugModelPresentation presentation) { 259 super(name); 260 fJobPresentation= presentation; 261 setSystem(true); 264 } 265 266 271 public void computeText(Object element) { 272 if (!fElementQueue.contains(element)) { 273 if (element instanceof IStackFrame) { 274 fElementQueue.add(element); 275 } else { 276 fElementQueue.add(0, element); 279 } 280 } 281 schedule(); 282 } 283 284 287 public IStatus run(IProgressMonitor monitor) { 288 while (!fElementQueue.isEmpty() && !monitor.isCanceled()) { 289 int blockSize= 10; 290 if (fElementQueue.size() < blockSize) { 291 blockSize= fElementQueue.size(); 292 } 293 final List computedElements= new ArrayList (); 294 for (int i= 0; i < blockSize; i++) { 295 Object element= fElementQueue.remove(0); 296 if (element == null) { 297 break; 298 } 299 if (element instanceof IStackFrame) { 300 synchronized (fCurrentStackFrameLock) { 301 fCurrentStackFrame= (IStackFrame) element; 302 } 303 IThread thread= fCurrentStackFrame.getThread(); 308 synchronized(resumedThreads) { 309 if (!thread.isTerminated() && !thread.isSuspended()) { 310 resumedThreads.add(thread); 311 continue; 313 } 314 } 315 } 316 fLabelProvider.textComputed(element, fJobPresentation.getText(element)); 317 synchronized (fCurrentStackFrameLock) { 318 fCurrentStackFrame= null; 319 } 320 computedElements.add(element); 321 } 322 labelsComputed(computedElements.toArray()); 323 } 324 monitor.done(); 325 return Status.OK_STATUS; 326 } 327 328 331 public boolean contains(ISchedulingRule rule) { 332 return (rule instanceof LabelJob) && fJobPresentation == ((LabelJob)rule).fJobPresentation; 333 } 334 335 338 public boolean isConflicting(ISchedulingRule rule) { 339 return (rule instanceof LabelJob) && fJobPresentation == ((LabelJob)rule).fJobPresentation; 340 } 341 } 342 } 343 | Popular Tags |