| 1 11 package org.eclipse.jdt.internal.debug.ui; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.StringTokenizer ; 18 19 import org.eclipse.core.resources.IMarker; 20 import org.eclipse.core.resources.IResource; 21 import org.eclipse.core.runtime.CoreException; 22 import org.eclipse.core.runtime.IAdaptable; 23 import org.eclipse.debug.core.DebugException; 24 import org.eclipse.debug.core.DebugPlugin; 25 import org.eclipse.debug.core.model.IBreakpoint; 26 import org.eclipse.debug.core.model.IDisconnect; 27 import org.eclipse.debug.core.model.IExpression; 28 import org.eclipse.debug.core.model.IStackFrame; 29 import org.eclipse.debug.core.model.ITerminate; 30 import org.eclipse.debug.core.model.IThread; 31 import org.eclipse.debug.core.model.IValue; 32 import org.eclipse.debug.core.model.IWatchExpression; 33 import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; 34 import org.eclipse.debug.core.sourcelookup.containers.ZipEntryStorage; 35 import org.eclipse.debug.ui.DebugUITools; 36 import org.eclipse.debug.ui.IDebugModelPresentation; 37 import org.eclipse.debug.ui.IDebugUIConstants; 38 import org.eclipse.debug.ui.IValueDetailListener; 39 import org.eclipse.jdt.core.IMember; 40 import org.eclipse.jdt.core.IType; 41 import org.eclipse.jdt.core.Signature; 42 import org.eclipse.jdt.debug.core.IJavaArray; 43 import org.eclipse.jdt.debug.core.IJavaBreakpoint; 44 import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint; 45 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 46 import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint; 47 import org.eclipse.jdt.debug.core.IJavaFieldVariable; 48 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; 49 import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; 50 import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint; 51 import org.eclipse.jdt.debug.core.IJavaModifiers; 52 import org.eclipse.jdt.debug.core.IJavaObject; 53 import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint; 54 import org.eclipse.jdt.debug.core.IJavaReferenceType; 55 import org.eclipse.jdt.debug.core.IJavaStackFrame; 56 import org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint; 57 import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint; 58 import org.eclipse.jdt.debug.core.IJavaThread; 59 import org.eclipse.jdt.debug.core.IJavaType; 60 import org.eclipse.jdt.debug.core.IJavaValue; 61 import org.eclipse.jdt.debug.core.IJavaVariable; 62 import org.eclipse.jdt.debug.core.IJavaWatchpoint; 63 import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint; 64 import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIAllInstancesValue; 65 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListEntryVariable; 66 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListValue; 67 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListVariable; 68 import org.eclipse.jdt.internal.debug.core.model.JDIThread; 69 import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression; 70 import org.eclipse.jdt.internal.debug.ui.monitors.JavaContendedMonitor; 71 import org.eclipse.jdt.internal.debug.ui.monitors.JavaOwnedMonitor; 72 import org.eclipse.jdt.internal.debug.ui.monitors.JavaOwningThread; 73 import org.eclipse.jdt.internal.debug.ui.monitors.JavaWaitingThread; 74 import org.eclipse.jdt.internal.debug.ui.monitors.NoMonitorInformationElement; 75 import org.eclipse.jdt.internal.debug.ui.monitors.ThreadMonitorManager; 76 import org.eclipse.jdt.internal.ui.JavaPlugin; 77 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; 78 import org.eclipse.jdt.internal.ui.viewsupport.ImageDescriptorRegistry; 79 import org.eclipse.jdt.ui.ISharedImages; 80 import org.eclipse.jdt.ui.JavaElementImageDescriptor; 81 import org.eclipse.jdt.ui.JavaElementLabelProvider; 82 import org.eclipse.jdt.ui.JavaUI; 83 import org.eclipse.jface.resource.ImageDescriptor; 84 import org.eclipse.jface.viewers.IColorProvider; 85 import org.eclipse.jface.viewers.LabelProvider; 86 import org.eclipse.swt.graphics.Color; 87 import org.eclipse.swt.graphics.Image; 88 import org.eclipse.swt.graphics.Point; 89 import org.eclipse.ui.IEditorDescriptor; 90 import org.eclipse.ui.IEditorInput; 91 import org.eclipse.ui.IWorkbenchWindow; 92 import org.eclipse.ui.PartInitException; 93 import org.eclipse.ui.PlatformUI; 94 import org.eclipse.ui.ide.IDE; 95 96 import com.ibm.icu.text.MessageFormat; 97 import com.sun.jdi.ObjectCollectedException; 98 99 103 public class JDIModelPresentation extends LabelProvider implements IDebugModelPresentation, IColorProvider { 104 105 113 public final static String DISPLAY_QUALIFIED_NAMES= "DISPLAY_QUALIFIED_NAMES"; 115 protected HashMap fAttributes= new HashMap (3); 116 117 static final Point BIG_SIZE= new Point(16, 16); 118 119 private static ImageDescriptorRegistry fgJavaElementImageRegistry; 120 private static org.eclipse.jdt.internal.debug.ui.ImageDescriptorRegistry fgDebugImageRegistry; 121 122 125 private static boolean fInitialized = false; 126 127 protected static final String fgStringName= "java.lang.String"; 129 private JavaElementLabelProvider fJavaLabelProvider; 130 131 public JDIModelPresentation() { 132 super(); 133 } 134 135 138 public void dispose() { 139 super.dispose(); 140 if (fJavaLabelProvider != null) { 141 fJavaLabelProvider.dispose(); 142 } 143 fAttributes.clear(); 144 } 145 146 149 public void computeDetail(IValue value, IValueDetailListener listener) { 150 IJavaThread thread = getEvaluationThread((IJavaDebugTarget)value.getDebugTarget()); 151 if (thread == null) { 152 listener.detailComputed(value, DebugUIMessages.JDIModelPresentation_no_suspended_threads); 153 } else { 154 JavaDetailFormattersManager.getDefault().computeValueDetail((IJavaValue)value, thread, listener); 155 } 156 } 157 158 167 public static IJavaThread getEvaluationThread(IJavaDebugTarget target) { 168 IJavaStackFrame frame = EvaluationContextManager.getEvaluationContext((IWorkbenchWindow)null); 169 IJavaThread thread = null; 170 if (frame != null) { 171 thread = (IJavaThread) frame.getThread(); 172 } 173 if (thread != null && (!thread.getDebugTarget().equals(target) || (!thread.isSuspended() && !thread.isPerformingEvaluation()))) { 174 thread = null; 176 } 177 if (thread == null) { 178 try { 179 IThread[] threads = target.getThreads(); 180 for (int i = 0; i < threads.length; i++) { 181 if (threads[i].isSuspended()) { 182 thread = (IJavaThread)threads[i]; 183 break; 184 } 185 } 186 } catch (DebugException e) { 187 JDIDebugUIPlugin.log(e); 188 } 189 } 190 return thread; 191 } 192 193 196 public String getText(Object item) { 197 try { 198 boolean showQualified= isShowQualifiedNames(); 199 if (item instanceof IJavaVariable) { 200 return getVariableText((IJavaVariable) item); 201 } else if (item instanceof IStackFrame) { 202 StringBuffer label= new StringBuffer (getStackFrameText((IStackFrame) item)); 203 if (item instanceof IJavaStackFrame) { 204 if (((IJavaStackFrame)item).isOutOfSynch()) { 205 label.append(DebugUIMessages.JDIModelPresentation___out_of_synch__1); 206 } 207 } 208 return label.toString(); 209 } else if (item instanceof IMarker) { 210 IBreakpoint breakpoint = getBreakpoint((IMarker)item); 211 if (breakpoint != null) { 212 return getBreakpointText(breakpoint); 213 } 214 return null; 215 } else if (item instanceof IBreakpoint) { 216 return getBreakpointText((IBreakpoint)item); 217 } else if (item instanceof IWatchExpression) { 218 return getWatchExpressionText((IWatchExpression)item); 219 } else if (item instanceof IExpression) { 220 return getExpressionText((IExpression)item); 221 } else if (item instanceof JavaOwnedMonitor) { 222 return getJavaOwnedMonitorText((JavaOwnedMonitor)item); 223 } else if (item instanceof JavaContendedMonitor) { 224 return getJavaContendedMonitorText((JavaContendedMonitor)item); 225 } else if (item instanceof JavaOwningThread) { 226 return getJavaOwningTreadText((JavaOwningThread)item); 227 } else if (item instanceof JavaWaitingThread) { 228 return getJavaWaitingTreadText((JavaWaitingThread)item); 229 } else if (item instanceof NoMonitorInformationElement) { 230 return DebugUIMessages.JDIModelPresentation_5; 231 } else { 232 StringBuffer label= new StringBuffer (); 233 if (item instanceof IJavaThread) { 234 label.append(getThreadText((IJavaThread) item, showQualified)); 235 if (((IJavaThread)item).isOutOfSynch()) { 236 label.append(DebugUIMessages.JDIModelPresentation___out_of_synch__1); 237 } else if (((IJavaThread)item).mayBeOutOfSynch()) { 238 label.append(DebugUIMessages.JDIModelPresentation___may_be_out_of_synch__2); 239 } 240 } else if (item instanceof IJavaDebugTarget) { 241 label.append(getDebugTargetText((IJavaDebugTarget) item)); 242 if (((IJavaDebugTarget)item).isOutOfSynch()) { 243 label.append(DebugUIMessages.JDIModelPresentation___out_of_synch__1); 244 } else if (((IJavaDebugTarget)item).mayBeOutOfSynch()) { 245 label.append(DebugUIMessages.JDIModelPresentation___may_be_out_of_synch__2); 246 } 247 } else if (item instanceof IJavaValue) { 248 label.append(getValueText((IJavaValue) item)); 249 } 250 if (item instanceof ITerminate) { 251 if (((ITerminate) item).isTerminated()) { 252 label.insert(0, DebugUIMessages.JDIModelPresentation__terminated__2); 253 return label.toString(); 254 } 255 } 256 if (item instanceof IDisconnect) { 257 if (((IDisconnect) item).isDisconnected()) { 258 label.insert(0, DebugUIMessages.JDIModelPresentation__disconnected__4); 259 return label.toString(); 260 } 261 } 262 if (label.length() > 0) { 263 return label.toString(); 264 } 265 } 266 } catch (CoreException e) { 267 return DebugUIMessages.JDIModelPresentation__not_responding__6; 268 } 269 return null; 270 } 271 272 private String getJavaOwningTreadText(JavaOwningThread thread) throws CoreException { 273 return getFormattedString(DebugUIMessages.JDIModelPresentation_0, getThreadText(thread.getThread().getThread(), isShowQualifiedNames())); 274 } 275 276 private String getJavaWaitingTreadText(JavaWaitingThread thread) throws CoreException { 277 return getFormattedString(DebugUIMessages.JDIModelPresentation_1, getThreadText(thread.getThread().getThread(), isShowQualifiedNames())); 278 } 279 280 private String getJavaContendedMonitorText(JavaContendedMonitor monitor) throws DebugException { 281 return getFormattedString(DebugUIMessages.JDIModelPresentation_2, getValueText(monitor.getMonitor().getMonitor())); 282 } 283 284 private String getJavaOwnedMonitorText(JavaOwnedMonitor monitor) throws DebugException { 285 return getFormattedString(DebugUIMessages.JDIModelPresentation_3, getValueText(monitor.getMonitor().getMonitor())); 286 } 287 288 protected IBreakpoint getBreakpoint(IMarker marker) { 289 return DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker); 290 } 291 292 295 protected String getThreadText(IJavaThread thread, boolean qualified) throws CoreException { 296 StringBuffer key = new StringBuffer ("thread_"); String [] args = null; 298 IBreakpoint[] breakpoints= thread.getBreakpoints(); 299 if (thread.isDaemon()) { 300 key.append("daemon_"); } 302 if (thread.isSystemThread()) { 303 key.append("system_"); } 305 if (thread.isTerminated()) { 306 key.append("terminated"); args = new String [] {thread.getName()}; 308 } else if (thread.isStepping()) { 309 key.append("stepping"); args = new String [] {thread.getName()}; 311 } else if (thread.isPerformingEvaluation() && breakpoints.length == 0) { 312 key.append("evaluating"); args = new String [] {thread.getName()}; 314 } else if (!thread.isSuspended() || (thread instanceof JDIThread && ((JDIThread)thread).isSuspendedQuiet())) { 315 key.append("running"); args = new String [] {thread.getName()}; 317 } else { 318 key.append("suspended"); if (breakpoints.length > 0) { 320 IJavaBreakpoint breakpoint= (IJavaBreakpoint)breakpoints[0]; 321 for (int i= 0, numBreakpoints= breakpoints.length; i < numBreakpoints; i++) { 322 if (BreakpointUtils.isProblemBreakpoint(breakpoints[i])) { 323 breakpoint= (IJavaBreakpoint)breakpoints[i]; 325 break; 326 } 327 } 328 String typeName= getMarkerTypeName(breakpoint, qualified); 329 if (BreakpointUtils.isProblemBreakpoint(breakpoint)) { 330 IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); 331 IMarker problem = null; 332 if (frame != null) { 333 problem = JavaDebugOptionsManager.getDefault().getProblem(frame); 334 } 335 if (problem != null) { 336 key.append("_problem"); String message = problem.getAttribute(IMarker.MESSAGE, DebugUIMessages.JDIModelPresentation_Compilation_error_1); 338 args = new String [] {thread.getName(), message}; 339 } 340 } 341 if (breakpoint instanceof IJavaExceptionBreakpoint && args == null) { 343 key.append("_exception"); String exName = ((IJavaExceptionBreakpoint)breakpoint).getExceptionTypeName(); 345 if (exName == null) { 346 exName = typeName; 347 } else if (!qualified) { 348 int index = exName.lastIndexOf('.'); 349 exName = exName.substring(index + 1); 350 } 351 args = new String [] {thread.getName(), exName}; 352 } else if (breakpoint instanceof IJavaWatchpoint) { 353 IJavaWatchpoint wp = (IJavaWatchpoint)breakpoint; 354 String fieldName = wp.getFieldName(); 355 args = new String [] {thread.getName(), fieldName, typeName}; 356 if (wp.isAccessSuspend(thread.getDebugTarget())) { 357 key.append("_fieldaccess"); } else { 359 key.append("_fieldmodification"); } 361 } else if (breakpoint instanceof IJavaMethodBreakpoint) { 362 IJavaMethodBreakpoint me= (IJavaMethodBreakpoint)breakpoint; 363 String methodName= me.getMethodName(); 364 args = new String [] {thread.getName(), methodName, typeName}; 365 if (me.isEntrySuspend(thread.getDebugTarget())) { 366 key.append("_methodentry"); } else { 368 key.append("_methodexit"); } 370 } else if (breakpoint instanceof IJavaLineBreakpoint) { 371 IJavaLineBreakpoint jlbp = (IJavaLineBreakpoint)breakpoint; 372 int lineNumber= jlbp.getLineNumber(); 373 if (lineNumber > -1) { 374 args = new String [] {thread.getName(), String.valueOf(lineNumber), typeName}; 375 if (BreakpointUtils.isRunToLineBreakpoint(jlbp)) { 376 key.append("_runtoline"); } else { 378 key.append("_linebreakpoint"); } 380 } 381 } else if (breakpoint instanceof IJavaClassPrepareBreakpoint) { 382 key.append("_classprepare"); args = new String []{thread.getName(), getQualifiedName(breakpoint.getTypeName())}; 384 } 385 } 386 387 if (args == null) { 388 args = new String [] {thread.getName()}; 390 } 391 } 392 try { 393 return getFormattedString((String )DebugUIMessages.class.getDeclaredField(key.toString()).get(null), args); 394 } catch (IllegalArgumentException e) { 395 JDIDebugUIPlugin.log(e); 396 } catch (SecurityException e) { 397 JDIDebugUIPlugin.log(e); 398 } catch (IllegalAccessException e) { 399 JDIDebugUIPlugin.log(e); 400 } catch (NoSuchFieldException e) { 401 JDIDebugUIPlugin.log(e); 402 } 403 return DebugUIMessages.JDIModelPresentation_unknown_name__1; 404 } 405 406 409 protected String getDebugTargetText(IJavaDebugTarget debugTarget) throws DebugException { 410 String labelString= debugTarget.getName(); 411 if (debugTarget.isSuspended()) { 412 labelString += DebugUIMessages.JDIModelPresentation_target_suspended; 413 } 414 return labelString; 415 } 416 417 420 public String getValueText(IJavaValue value) throws DebugException { 421 422 String refTypeName= value.getReferenceTypeName(); 423 String valueString= value.getValueString(); 424 boolean isString= refTypeName.equals(fgStringName); 425 IJavaType type= value.getJavaType(); 426 String signature= null; 427 if (type != null) { 428 signature= type.getSignature(); 429 } 430 if ("V".equals(signature)) { valueString= DebugUIMessages.JDIModelPresentation__No_explicit_return_value__30; 432 } 433 boolean isObject= isObjectValue(signature); 434 boolean isArray= value instanceof IJavaArray; 435 StringBuffer buffer= new StringBuffer (); 436 if (isObject && !isString && (refTypeName.length() > 0)) { 438 if (!(value instanceof JDIReferenceListValue || value instanceof JDIAllInstancesValue)){ 440 String qualTypeName= getQualifiedName(refTypeName); 441 if (isArray) { 442 qualTypeName= adjustTypeNameForArrayIndex(qualTypeName, ((IJavaArray)value).getLength()); 443 } 444 buffer.append(qualTypeName); 445 buffer.append(' '); 446 } 447 } 448 449 if (valueString != null && (isString || valueString.length() > 0)) { 451 if (isString) { 452 buffer.append('"'); 453 } 454 buffer.append(valueString); 455 if (isString) { 456 buffer.append('"'); 457 } 458 } 459 460 if (isShowUnsignedValues()) { 462 buffer= appendUnsignedText(value, buffer); 463 } 464 if (isShowHexValues()) { 466 buffer= appendHexText(value, buffer); 467 } 468 if (isShowCharValues()) { 470 buffer= appendCharText(value, buffer); 471 } 472 473 return buffer.toString(); 474 } 475 476 477 private StringBuffer appendUnsignedText(IJavaValue value, StringBuffer buffer) throws DebugException { 478 String unsignedText= getValueUnsignedText(value); 479 if (unsignedText != null) { 480 buffer.append(" ["); buffer.append(unsignedText); 482 buffer.append("]"); } 484 return buffer; 485 } 486 487 protected StringBuffer appendHexText(IJavaValue value, StringBuffer buffer) throws DebugException { 488 String hexText = getValueHexText(value); 489 if (hexText != null) { 490 buffer.append(" ["); buffer.append(hexText); 492 buffer.append("]"); } 494 return buffer; 495 } 496 497 protected StringBuffer appendCharText(IJavaValue value, StringBuffer buffer) throws DebugException { 498 String charText= getValueCharText(value); 499 if (charText != null) { 500 buffer.append(" ["); buffer.append(charText); 502 buffer.append("]"); } 504 return buffer; 505 } 506 507 511 public static boolean isObjectValue(String signature) { 512 if (signature == null) { 513 return false; 514 } 515 char sigChar= ' '; 516 for (int i= 0; i < signature.length(); i++) { 517 sigChar= signature.charAt(i); 518 if (sigChar == '[') { 519 return true; 520 } 521 break; 522 } 523 if ((sigChar == 'L') || (sigChar == 'Q')) { 524 return true; 525 } 526 return false; 527 } 528 529 534 public static boolean isInitialized() { 535 return fgJavaElementImageRegistry != null && fgDebugImageRegistry != null; 536 } 537 538 542 protected String getPrimitiveValueTypeSignature(IJavaValue value) throws DebugException { 543 IJavaType type= value.getJavaType(); 544 if (type != null) { 545 String sig= type.getSignature(); 546 if (sig != null && sig.length() == 1) { 547 return sig; 548 } 549 } 550 return null; 551 } 552 556 protected String getValueCharText(IJavaValue value) throws DebugException { 557 String sig= getPrimitiveValueTypeSignature(value); 558 if (sig == null) { 559 return null; 560 } 561 String valueString= value.getValueString(); 562 long longValue; 563 try { 564 longValue= Long.parseLong(valueString); 565 } catch (NumberFormatException e) { 566 return null; 567 } 568 switch (sig.charAt(0)) { 569 case 'B' : longValue= longValue & 0xFF; break; 572 case 'I' : longValue= longValue & 0xFFFFFFFF; if (longValue > 0xFFFF || longValue < 0) { 575 return null; 576 } 577 break; 578 case 'S' : longValue= longValue & 0xFFFF; break; 581 case 'J' : 582 if (longValue > 0xFFFF || longValue < 0) { 583 return null; 585 } 586 break; 587 default : 588 return null; 589 } 590 char charValue= (char)longValue; 591 StringBuffer charText = new StringBuffer (); 592 if (Character.getType(charValue) == Character.CONTROL) { 593 Character ctrl = new Character ((char) (charValue + 64)); 594 charText.append('^'); 595 charText.append(ctrl); 596 switch (charValue) { case 0: charText.append(" (NUL)"); break; case 8: charText.append(" (BS)"); break; case 9: charText.append(" (TAB)"); break; case 10: charText.append(" (LF)"); break; case 13: charText.append(" (CR)"); break; case 21: charText.append(" (NL)"); break; case 27: charText.append(" (ESC)"); break; case 127: charText.append(" (DEL)"); break; } 606 } else { 607 charText.append(new Character (charValue)); 608 } 609 return charText.toString(); 610 } 611 612 protected String getMarkerTypeName(IJavaBreakpoint breakpoint, boolean qualified) throws CoreException { 613 String typeName= null; 614 if (breakpoint instanceof IJavaPatternBreakpoint) { 615 typeName = breakpoint.getMarker().getResource().getName(); 616 } else { 617 typeName = breakpoint.getTypeName(); 618 } 619 if (!qualified) { 620 |