1 11 package org.eclipse.jdt.internal.debug.core; 12 13 import org.eclipse.core.resources.ISaveContext; 14 import org.eclipse.core.resources.ISaveParticipant; 15 import org.eclipse.core.resources.ResourcesPlugin; 16 import org.eclipse.core.runtime.CoreException; 17 import org.eclipse.core.runtime.ISafeRunnable; 18 import org.eclipse.core.runtime.IStatus; 19 import org.eclipse.core.runtime.ListenerList; 20 import org.eclipse.core.runtime.Plugin; 21 import org.eclipse.core.runtime.Preferences; 22 import org.eclipse.core.runtime.SafeRunner; 23 import org.eclipse.core.runtime.Status; 24 import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; 25 import org.eclipse.debug.core.DebugException; 26 import org.eclipse.debug.core.DebugPlugin; 27 import org.eclipse.debug.core.ILaunchManager; 28 import org.eclipse.debug.core.model.IDebugTarget; 29 import org.eclipse.jdi.Bootstrap; 30 import org.eclipse.jdt.core.IJavaProject; 31 import org.eclipse.jdt.core.dom.Message; 32 import org.eclipse.jdt.debug.core.IJavaBreakpoint; 33 import org.eclipse.jdt.debug.core.IJavaBreakpointListener; 34 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 35 import org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener; 36 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; 37 import org.eclipse.jdt.debug.core.IJavaThread; 38 import org.eclipse.jdt.debug.core.IJavaType; 39 import org.eclipse.jdt.debug.core.JDIDebugModel; 40 import org.eclipse.jdt.debug.eval.IAstEvaluationEngine; 41 import org.eclipse.jdt.internal.debug.core.hcr.JavaHotCodeReplaceManager; 42 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; 43 import org.eclipse.jdt.internal.debug.eval.JavaEvaluationEngineManager; 44 import org.osgi.framework.BundleContext; 45 46 import com.sun.jdi.VirtualMachineManager; 47 48 51 public class JDIDebugPlugin extends Plugin implements Preferences.IPropertyChangeListener { 52 53 59 public static final String PREF_DEFAULT_BREAKPOINT_SUSPEND_POLICY = JDIDebugPlugin.getUniqueIdentifier() + ".default_breakpoint_suspend_policy"; 61 66 public static final String PREF_SHOW_REFERENCES_IN_VAR_VIEW = JDIDebugPlugin.getUniqueIdentifier() + ".show_references_in_var_view"; 68 73 public static final String PREF_ALL_REFERENCES_MAX_COUNT = JDIDebugPlugin.getUniqueIdentifier() + "._all_references_max_count"; 75 80 public static final String PREF_ALL_INSTANCES_MAX_COUNT = JDIDebugPlugin.getUniqueIdentifier() + ".all_instances_max_count"; 82 87 public static final String EXTENSION_POINT_JAVA_LOGICAL_STRUCTURES= "javaLogicalStructures"; 89 92 public static final int INTERNAL_ERROR = 120; 93 94 private static JDIDebugPlugin fgPlugin; 95 96 99 private ListenerList fBreakpointListeners = null; 100 101 104 private static final int ADDING = 1; 105 private static final int INSTALLED = 2; 106 private static final int REMOVED = 3; 107 private static final int COMPILATION_ERRORS = 4; 108 private static final int RUNTIME_EXCEPTION = 5; 109 110 114 private boolean fTrace = false; 115 116 119 private static int[] fJDIVersion = null; 120 121 private JavaEvaluationEngineManager fEvaluationEngineManager; 122 123 130 public static final int INFO_EVALUATION_THREAD = 110; 131 132 135 public static final IStatus STATUS_GET_EVALUATION_THREAD = new Status(IStatus.INFO, getUniqueIdentifier(), INFO_EVALUATION_THREAD, "Provides thread context for an evaluation", null); 137 144 public static final int INFO_EVALUATION_STACK_FRAME = 111; 145 146 149 public static IStatus STATUS_GET_EVALUATION_FRAME = new Status(IStatus.INFO, getUniqueIdentifier(), INFO_EVALUATION_STACK_FRAME, "Provides thread context for an evaluation", null); 151 158 public boolean isTraceMode() { 159 return fTrace; 160 } 161 162 167 public static void logTraceMessage(String message) { 168 if (getDefault().isTraceMode()) { 169 IStatus s = new Status(IStatus.WARNING, JDIDebugPlugin.getUniqueIdentifier(), INTERNAL_ERROR, message, null); 170 getDefault().getLog().log(s); 171 } 172 } 173 174 178 public static JDIDebugPlugin getDefault() { 179 return fgPlugin; 180 } 181 182 185 public static String getUniqueIdentifier() { 186 return "org.eclipse.jdt.debug"; } 190 191 199 public static int[] getJDIVersion() { 200 if (fJDIVersion == null) { 201 fJDIVersion = new int[2]; 202 VirtualMachineManager mgr = Bootstrap.virtualMachineManager(); 203 fJDIVersion[0] = mgr.majorInterfaceVersion(); 204 fJDIVersion[1] = mgr.minorInterfaceVersion(); 205 } 206 return fJDIVersion; 207 } 208 209 216 public static boolean isJdiVersionGreaterThanOrEqual(int[] version) { 217 int[] runningVersion = getJDIVersion(); 218 return runningVersion[0] > version[0] || (runningVersion[0] == version[0] && runningVersion[1] >= version[1]); 219 } 220 221 public JDIDebugPlugin() { 222 super(); 223 fgPlugin = this; 224 } 225 226 public void start(BundleContext context) throws Exception { 227 super.start(context); 228 ResourcesPlugin.getWorkspace().addSaveParticipant(this, new ISaveParticipant() { 229 public void doneSaving(ISaveContext context) {} 230 public void prepareToSave(ISaveContext context) throws CoreException {} 231 public void rollback(ISaveContext context) {} 232 public void saving(ISaveContext context) throws CoreException { 233 savePluginPreferences(); 234 } 235 }); 236 JavaHotCodeReplaceManager.getDefault().startup(); 237 fBreakpointListeners = new ListenerList(); 238 fEvaluationEngineManager= new JavaEvaluationEngineManager(); 239 } 240 241 245 public void addHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) { 246 JavaHotCodeReplaceManager.getDefault().addHotCodeReplaceListener(listener); 247 } 248 249 253 public void removeHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) { 254 JavaHotCodeReplaceManager.getDefault().removeHotCodeReplaceListener(listener); 255 } 256 257 262 public void stop(BundleContext context) throws Exception { 263 try { 264 getPluginPreferences().removePropertyChangeListener(this); JavaHotCodeReplaceManager.getDefault().shutdown(); 266 fEvaluationEngineManager.dispose(); 267 ILaunchManager launchManager= DebugPlugin.getDefault().getLaunchManager(); 268 IDebugTarget[] targets= launchManager.getDebugTargets(); 269 for (int i= 0 ; i < targets.length; i++) { 270 IDebugTarget target= targets[i]; 271 if (target instanceof JDIDebugTarget) { 272 ((JDIDebugTarget)target).shutdown(); 273 } 274 } 275 fBreakpointListeners = null; 276 ResourcesPlugin.getWorkspace().removeSaveParticipant(this); 277 } finally { 278 fgPlugin = null; 279 super.stop(context); 280 } 281 } 282 283 288 public static void log(Throwable t) { 289 Throwable top= t; 290 if (t instanceof DebugException) { 291 DebugException de = (DebugException)t; 292 IStatus status = de.getStatus(); 293 if (status.getException() != null) { 294 top = status.getException(); 295 } 296 } 297 log(new Status(IStatus.ERROR, getUniqueIdentifier(), INTERNAL_ERROR, "Internal error logged from JDI Debug: ", top)); } 301 302 307 public static void log(IStatus status) { 308 getDefault().getLog().log(status); 309 } 310 311 314 public void fireBreakpointHasCompilationErrors(IJavaLineBreakpoint breakpoint, Message[] errors) { 315 getBreakpointNotifier().notify(null, breakpoint, COMPILATION_ERRORS, errors, null); 316 } 317 318 321 public void fireBreakpointHasRuntimeException(IJavaLineBreakpoint breakpoint, DebugException exception) { 322 getBreakpointNotifier().notify(null, breakpoint, RUNTIME_EXCEPTION, null, exception); 323 } 324 325 330 public void addJavaBreakpointListener(IJavaBreakpointListener listener) { 331 fBreakpointListeners.add(listener); 332 } 333 334 339 public void removeJavaBreakpointListener(IJavaBreakpointListener listener) { 340 fBreakpointListeners.remove(listener); 341 } 342 343 350 public void fireBreakpointAdding(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { 351 getBreakpointNotifier().notify(target, breakpoint, ADDING, null, null); 352 } 353 354 360 public void fireBreakpointInstalled(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { 361 getBreakpointNotifier().notify(target, breakpoint, INSTALLED, null, null); 362 } 363 364 370 public void fireBreakpointRemoved(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { 371 getBreakpointNotifier().notify(target, breakpoint, REMOVED, null, null); 372 } 373 374 381 public boolean fireBreakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) { 382 return getHitNotifier().notifyHit(thread, breakpoint); 383 } 384 385 395 public boolean fireInstalling(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) { 396 return getInstallingNotifier().notifyInstalling(target, breakpoint, type); 397 } 398 399 404 public void propertyChange(PropertyChangeEvent event) { 405 if (event.getProperty().equals(JDIDebugModel.PREF_REQUEST_TIMEOUT)) { 406 int value = getPluginPreferences().getInt(JDIDebugModel.PREF_REQUEST_TIMEOUT); 407 IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets(); 408 for (int i = 0; i < targets.length; i++) { 409 if (targets[i] instanceof IJavaDebugTarget) { 410 ((IJavaDebugTarget)targets[i]).setRequestTimeout(value); 411 } 412 } 413 } 414 } 415 416 private BreakpointNotifier getBreakpointNotifier() { 417 return new BreakpointNotifier(); 418 } 419 420 class BreakpointNotifier implements ISafeRunnable { 421 422 private IJavaDebugTarget fTarget; 423 private IJavaBreakpoint fBreakpoint; 424 private int fKind; 425 private Message[] fErrors; 426 private DebugException fException; 427 private IJavaBreakpointListener fListener; 428 429 432 public void handleException(Throwable exception) { 433 } 434 435 438 public void run() throws Exception { 439 switch (fKind) { 440 case ADDING: 441 fListener.addingBreakpoint(fTarget, fBreakpoint); 442 break; 443 case INSTALLED: 444 fListener.breakpointInstalled(fTarget, fBreakpoint); 445 break; 446 case REMOVED: 447 fListener.breakpointRemoved(fTarget, fBreakpoint); 448 break; 449 case COMPILATION_ERRORS: 450 fListener.breakpointHasCompilationErrors((IJavaLineBreakpoint)fBreakpoint, fErrors); 451 break; 452 case RUNTIME_EXCEPTION: 453 fListener.breakpointHasRuntimeException((IJavaLineBreakpoint)fBreakpoint, fException); 454 break; 455 } 456 } 457 458 468 public void notify(IJavaDebugTarget target, IJavaBreakpoint breakpoint, int kind, Message[] errors, DebugException exception) { 469 fTarget = target; 470 fBreakpoint = breakpoint; 471 fKind = kind; 472 fErrors = errors; 473 fException = exception; 474 Object [] listeners = fBreakpointListeners.getListeners(); 475 for (int i = 0; i < listeners.length; i++) { 476 fListener = (IJavaBreakpointListener)listeners[i]; 477 SafeRunner.run(this); 478 } 479 fTarget = null; 480 fBreakpoint = null; 481 fErrors = null; 482 fException = null; 483 fListener = null; 484 } 485 } 486 487 private InstallingNotifier getInstallingNotifier() { 488 return new InstallingNotifier(); 489 } 490 491 class InstallingNotifier implements ISafeRunnable { 492 493 private IJavaDebugTarget fTarget; 494 private IJavaBreakpoint fBreakpoint; 495 private IJavaType fType; 496 private IJavaBreakpointListener fListener; 497 private int fInstall; 498 499 502 public void handleException(Throwable exception) { 503 } 504 505 508 public void run() throws Exception { 509 fInstall = fInstall | fListener.installingBreakpoint(fTarget, fBreakpoint, fType); 510 } 511 512 private void dispose() { 513 fTarget = null; 514 fBreakpoint = null; 515 fType = null; 516 fListener = null; 517 } 518 519 529 public boolean notifyInstalling(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) { 530 fTarget = target; 531 fBreakpoint = breakpoint; 532 fType = type; 533 fInstall = IJavaBreakpointListener.DONT_CARE; 534 Object [] listeners = fBreakpointListeners.getListeners(); 535 for (int i = 0; i < listeners.length; i++) { 536 fListener = (IJavaBreakpointListener)listeners[i]; 537 SafeRunner.run(this); 538 } 539 dispose(); 540 return (fInstall & IJavaBreakpointListener.INSTALL) > 0 || 542 (fInstall & IJavaBreakpointListener.DONT_INSTALL) == 0; 543 } 544 } 545 546 private HitNotifier getHitNotifier() { 547 return new HitNotifier(); 548 } 549 550 class HitNotifier implements ISafeRunnable { 551 552 private IJavaThread fThread; 553 private IJavaBreakpoint fBreakpoint; 554 private IJavaBreakpointListener fListener; 555 private int fSuspend; 556 557 560 public void handleException(Throwable exception) { 561 } 562 563 566 public void run() throws Exception { 567 fSuspend = fSuspend | fListener.breakpointHit(fThread, fBreakpoint); 568 } 569 570 578 public boolean notifyHit(IJavaThread thread, IJavaBreakpoint breakpoint) { 579 fThread = thread; 580 fBreakpoint = breakpoint; 581 Object [] listeners = fBreakpointListeners.getListeners(); 582 fSuspend = IJavaBreakpointListener.DONT_CARE; 583 for (int i = 0; i < listeners.length; i++) { 584 fListener = (IJavaBreakpointListener)listeners[i]; 585 SafeRunner.run(this); 586 } 587 fThread = null; 588 fBreakpoint = null; 589 fListener = null; 590 return (fSuspend & IJavaBreakpointListener.SUSPEND) > 0 || 592 (fSuspend & IJavaBreakpointListener.DONT_SUSPEND) == 0; 593 } 594 } 595 596 605 public IAstEvaluationEngine getEvaluationEngine(IJavaProject project, IJavaDebugTarget target) { 606 return fEvaluationEngineManager.getEvaluationEngine(project, target); 607 } 608 } 609 | Popular Tags |