1 21 22 package org.armedbear.j.jdb; 23 24 import com.sun.jdi.AbsentInformationException; 25 import com.sun.jdi.ArrayReference; 26 import com.sun.jdi.Field; 27 import com.sun.jdi.LocalVariable; 28 import com.sun.jdi.Location; 29 import com.sun.jdi.Method; 30 import com.sun.jdi.ObjectReference; 31 import com.sun.jdi.ReferenceType; 32 import com.sun.jdi.StackFrame; 33 import com.sun.jdi.StringReference; 34 import com.sun.jdi.ThreadReference; 35 import com.sun.jdi.VMDisconnectedException; 36 import com.sun.jdi.Value; 37 import com.sun.jdi.VirtualMachine; 38 import com.sun.jdi.event.ClassPrepareEvent; 39 import com.sun.jdi.event.LocatableEvent; 40 import com.sun.jdi.request.ClassPrepareRequest; 41 import com.sun.jdi.request.EventRequest; 42 import com.sun.jdi.request.EventRequestManager; 43 import com.sun.jdi.request.ExceptionRequest; 44 import com.sun.jdi.request.StepRequest; 45 import com.sun.jdi.request.ThreadDeathRequest; 46 import com.sun.jdi.request.ThreadStartRequest; 47 import java.io.IOException ; 48 import java.io.InputStream ; 49 import java.io.OutputStream ; 50 import java.util.ArrayList ; 51 import java.util.Iterator ; 52 import java.util.List ; 53 import java.util.Map ; 54 import java.util.Set ; 55 import java.util.StringTokenizer ; 56 import javax.swing.Icon ; 57 import javax.swing.SwingUtilities ; 58 import org.armedbear.j.Annotation; 59 import org.armedbear.j.Buffer; 60 import org.armedbear.j.BufferIterator; 61 import org.armedbear.j.Debug; 62 import org.armedbear.j.Editor; 63 import org.armedbear.j.EditorIterator; 64 import org.armedbear.j.EditorList; 65 import org.armedbear.j.File; 66 import org.armedbear.j.FastStringBuffer; 67 import org.armedbear.j.JavaMode; 68 import org.armedbear.j.JavaSource; 69 import org.armedbear.j.Line; 70 import org.armedbear.j.Log; 71 import org.armedbear.j.Platform; 72 import org.armedbear.j.Position; 73 import org.armedbear.j.ReaderThread; 74 import org.armedbear.j.SimpleEdit; 75 import org.armedbear.j.Utilities; 76 77 public final class Jdb extends Buffer implements JdbConstants 78 { 79 private static int catchMode = CATCH_UNCAUGHT; 80 81 private JdbSession session; 82 private VirtualMachine vm; 83 private ThreadReference currentThread; 84 private StackFrame currentStackFrame; 85 private Location location; 86 private String mainClass; 87 private String mainClassArgs; 88 private String classPath; 89 private String javaHome; 90 private String javaExecutable; 91 private String vmArgs; 92 private boolean startSuspended; 93 private boolean isSuspended = true; 94 private String sourcePath; 95 private JdbControlDialog controlDialog; 96 private Position posEndOfBuffer; 97 private ArrayList breakpointListeners = new ArrayList (); 98 private ArrayList contextListeners = new ArrayList (); 99 private int lastCommand; 100 private final List breakpoints = new ArrayList (); 101 102 public static synchronized void jdb() 103 { 104 final Editor editor = Editor.currentEditor(); 105 final Buffer buffer = editor.getBuffer(); 106 Jdb jdb = findJdb(); 107 if (jdb != null) { 108 if (!jdb.equals(buffer)) { 109 editor.getFrame().unsplitWindow(); 110 editor.makeNext(jdb); 111 editor.activateInOtherWindow(jdb); 112 editor.updateDisplay(); 113 } 114 if (jdb.getVM() != null) 115 return; } 117 JdbDialog d = new JdbDialog(editor); 118 editor.centerDialog(d); 119 d.show(); 120 editor.getFrame().setWaitCursor(); 121 editor.repaintNow(); 122 if (!d.cancelled()) { 123 JdbSession session = d.getSession(); 124 if (jdb != null) { 125 jdb.setSession(session); 126 jdb.startProcess(); 127 } else { 128 jdb = new Jdb(session); 129 if (jdb != null) { 130 JavaMode.setJdb(jdb); 131 editor.getFrame().unsplitWindow(); 132 editor.makeNext(jdb); 133 editor.activateInOtherWindow(jdb); 134 jdb.showControlDialog(); 135 jdb.startProcess(); 136 } 137 } 138 } 139 editor.getFrame().setDefaultCursor(); 140 } 141 142 private Jdb(JdbSession session) 143 { 144 super(); 145 supportsUndo = false; 146 mode = JdbMode.getMode(); 147 formatter = mode.getFormatter(this); 148 readOnly = true; 149 setSession(session); 150 } 151 152 public VirtualMachine getVM() 153 { 154 return vm; 155 } 156 157 public void setVM(VirtualMachine vm) 158 { 159 this.vm = vm; 160 if (vm == null) { 161 isSuspended = true; 162 currentThread = null; 163 currentStackFrame = null; 164 } 165 } 166 167 public String getMainClass() 168 { 169 return mainClass; 170 } 171 172 public String getMainClassArgs() 173 { 174 return mainClassArgs; 175 } 176 177 public String getClassPath() 178 { 179 return classPath; 180 } 181 182 public String getJavaHome() 183 { 184 return javaHome; 185 } 186 187 public String getJavaExecutable() 188 { 189 return javaExecutable; 190 } 191 192 public String getVMArgs() 193 { 194 return vmArgs; 195 } 196 197 public boolean getStartSuspended() 198 { 199 return startSuspended; 200 } 201 202 public String getSourcePath() 203 { 204 return sourcePath; 205 } 206 207 public int getLastCommand() 208 { 209 return lastCommand; 210 } 211 212 public void setLocation(Location location) 213 { 214 this.location = location; 215 } 216 217 public void setCurrentThread(ThreadReference threadRef) 218 { 219 currentThread = threadRef; 220 } 221 222 public ThreadReference getCurrentThread() 223 { 224 return currentThread; 225 } 226 227 public boolean isSuspended() 228 { 229 return isSuspended; 230 } 231 232 public void setSuspended(boolean b) 233 { 234 isSuspended = b; 235 } 236 237 public synchronized void setCurrentStackFrame(StackFrame stackFrame) 238 { 239 currentStackFrame = stackFrame; 240 } 241 242 public synchronized StackFrame getCurrentStackFrame() 243 { 244 return currentStackFrame; 245 } 246 247 public List getBreakpoints() 248 { 249 return breakpoints; 250 } 251 252 public void addBreakpointListener(BreakpointListener listener) 253 { 254 synchronized(breakpointListeners) { 255 breakpointListeners.add(listener); 256 } 257 } 258 259 public void fireBreakpointChanged() 260 { 261 synchronized(breakpointListeners) { 262 Iterator iter = breakpointListeners.iterator(); 263 while (iter.hasNext()) 264 ((BreakpointListener)iter.next()).breakpointChanged(); 265 } 266 } 267 268 public void addContextListener(ContextListener listener) 269 { 270 synchronized(contextListeners) { 271 contextListeners.add(listener); 272 } 273 } 274 275 private final Runnable fireContextChangedRunnable = new Runnable () { 276 public void run() 277 { 278 synchronized (contextListeners) { 279 for (Iterator it = contextListeners.iterator(); it.hasNext();) 280 ((ContextListener)it.next()).contextChanged(); 281 } 282 } 283 }; 284 285 public void fireContextChanged() 286 { 287 if (SwingUtilities.isEventDispatchThread()) 288 fireContextChangedRunnable.run(); 289 else 290 SwingUtilities.invokeLater(fireContextChangedRunnable); 291 } 292 293 public void initialize() 294 { 295 } 297 298 public synchronized int load() 299 { 300 if (!isLoaded()) { 301 try { 302 lockWrite(); 303 } 304 catch (InterruptedException e) { 305 Log.debug(e); 306 return LOAD_FAILED; } 308 try { 309 appendLine(""); 310 setLoaded(true); 311 posEndOfBuffer = new Position(getFirstLine(), 0); 312 } 313 finally { 314 unlockWrite(); 315 } 316 } 317 return LOAD_COMPLETED; 318 } 319 320 private void showControlDialog() 321 { 322 if (controlDialog == null) { 323 controlDialog = new JdbControlDialog(this); 324 controlDialog.show(); 325 } 326 } 327 328 public JdbControlDialog getControlDialog() 329 { 330 return controlDialog; 331 } 332 333 public void doCommand(String input) 334 { 335 String s = input.trim(); 336 String cmd, args; 337 int index = s.indexOf(' '); 338 if (index >= 0) { 339 cmd = s.substring(0, index); 340 args = s.substring(index+1).trim(); 341 } else { 342 cmd = s; 343 args = null; 344 } 345 int command = JdbCommands.findCommand(cmd); 347 if (command < 0) { 348 logCommand(cmd); 350 log("Command not found"); 351 } else { 352 doCommand(command, args); 353 lastCommand = command; 354 } 355 } 356 357 public void doCommand(int command, String args) 358 { 359 switch (command) { 360 case JDB_BREAK: 361 logCommand("break", args); 362 doBreak(args, false); 363 break; 364 case JDB_CATCH: 365 logCommand("catch", args); 366 doCatch(args); 367 break; 368 case JDB_CLEAR: 369 logCommand("clear", args); 370 doClear(args); 371 break; 372 case JDB_FINISH: 373 logCommand("finish"); 374 doFinish(); 375 break; 376 case JDB_LOCALS: 377 logCommand("locals"); 378 doLocals(); 379 break; 380 case JDB_NEXT: 381 logCommand("next"); 382 doNext(args); 383 break; 384 case JDB_PRINT: 385 logCommand("print", args); 386 doPrint(args); 387 break; 388 case JDB_QUIT: 389 logCommand("quit"); 390 quit(); 391 break; 392 case JDB_RESTART: 393 logCommand("restart"); 394 restart(); 395 break; 396 case JDB_CONTINUE: 397 logCommand("continue"); 398 doContinue(); 399 break; 400 case JDB_STDIN: 401 doStdin(args); 402 break; 403 case JDB_STEP: 404 logCommand("step", args); 405 doStep(args); 406 break; 407 case JDB_SUSPEND: 408 logCommand("suspend"); 409 doSuspend(); 410 break; 411 case JDB_TBREAK: 412 logCommand("tbreak", args); 413 doBreak(args, true); 414 break; 415 default: 416 Log.error("Jdb.doCommand unknown command " + command); 417 Debug.bug(); 418 break; 419 } 420 } 421 422 private static final String prompt = "jdb> "; 423 424 public static final String getPrompt() 425 { 426 return prompt; 427 } 428 429 public void prompt() 430 { 431 Runnable r = new Runnable () { 432 public void run() 433 { 434 appendString(prompt, true, JdbFormatter.JDB_FORMAT_PROMPT); 435 } 436 }; 437 if (SwingUtilities.isEventDispatchThread()) 438 r.run(); 439 else 440 SwingUtilities.invokeLater(r); 441 } 442 443 private void logCommand(String command) 444 { 445 log(prompt.concat(command)); 446 } 447 448 private void logCommand(String command, String remainder) 449 { 450 FastStringBuffer sb = new FastStringBuffer(prompt); 451 sb.append(command); 452 if (remainder != null && remainder.length() > 0) { 453 sb.append(' '); 454 sb.append(remainder); 455 } 456 log(sb.toString()); 457 } 458 459 public void log(String s) 460 { 461 log(s, true); 462 } 463 464 private void log(String s, boolean forceNewLine) 465 { 466 log(s, forceNewLine, JdbFormatter.JDB_FORMAT_LOG); 467 } 468 469 private void log(final String s, final boolean forceNewLine, final int flags) 470 { 471 Runnable r = new Runnable () { 472 public void run() 473 { 474 Log.debug(s); 475 appendString(s.concat("\n"), forceNewLine, 476 flags); 477 } 478 }; 479 if (SwingUtilities.isEventDispatchThread()) 480 r.run(); 481 else 482 SwingUtilities.invokeLater(r); 483 } 484 485 private void appendString(String s, boolean forceNewLine, int flags) 486 { 487 try { 488 lockWrite(); 489 } 490 catch (InterruptedException e) { 491 Log.error(e); 492 return; 493 } 494 try { 495 Position posStart = posEndOfBuffer.copy(); 496 if (forceNewLine) { 497 if (posEndOfBuffer.getOffset() > 0) { 498 if (!posEndOfBuffer.getLine().getText().equals(prompt)) { 499 insertLineSeparator(posEndOfBuffer); 500 posEndOfBuffer.getLine().setFlags(flags); 501 } 502 } 503 } 504 if (posEndOfBuffer.getOffset() > 0 && s.startsWith(prompt)) { 505 if (posEndOfBuffer.getLine().getText().equals(prompt)) 506 s = s.substring(prompt.length()); 507 } 508 insertString(posEndOfBuffer, s); 509 if (needsRenumbering()) 510 renumber(); 511 Line line = posStart.getLine(); 512 if (posStart.getOffset() > 0) 513 line = line.next(); 514 while (line != null) { 515 line.setFlags(flags); 516 line = line.next(); 517 } 518 } 519 finally { 520 unlockWrite(); 521 } 522 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 523 Editor ed = it.nextEditor(); 524 if (ed.getBuffer() == this) { 525 ed.eob(); 526 ed.getDisplay().setReframe(-2); 527 ed.setUpdateFlag(REPAINT); 528 ed.updateDisplay(); 529 } 530 } 531 } 532 533 public void printCurrentLocation(LocatableEvent event) 534 { 535 printCurrentLocation(event.thread(), event.location()); 536 } 537 538 public void printCurrentLocation(ThreadReference threadRef, Location location) 539 { 540 FastStringBuffer sb = new FastStringBuffer("["); 541 sb.append(threadRef.name()); 542 sb.append("] "); 543 sb.append(location.declaringType().name()); 544 sb.append('.'); 545 Method method = location.method(); 546 sb.append(method.name()); 547 try { 548 sb.append(" ("); 549 if (method.isNative()) { 550 sb.append("native method"); 551 } else { 552 String sourceName = location.sourceName(); 553 sb.append(location.sourceName()); 554 int lineNumber = location.lineNumber(); 555 if (lineNumber > 0) { 556 sb.append(':'); 557 sb.append(lineNumber); 558 } 559 } 560 sb.append(')'); 561 } 562 catch (AbsentInformationException e) { 563 Log.error(e); 564 } 565 log(sb.toString()); 566 } 567 568 public void displayRemoteOutput(InputStream inputStream) { 569 ReaderThread readerThread = new ReaderThread(inputStream) { 570 public void update(final String s) 571 { 572 Runnable runnable = new Runnable () { 573 public void run() 574 { 575 appendString(s, false, JdbFormatter.JDB_FORMAT_OUTPUT); 576 } 577 }; 578 SwingUtilities.invokeLater(runnable); 579 } 580 }; 581 readerThread.setPriority(Thread.MAX_PRIORITY-1); 582 readerThread.start(); 583 } 584 585 private void addBreakpoint(ResolvableBreakpoint bp) 586 { 587 breakpoints.add(bp); 588 FastStringBuffer sb = new FastStringBuffer(); 589 if (bp.isTemporary()) 590 sb.append("Temporary b"); 591 else 592 sb.append('B'); 593 sb.append("reakpoint added: "); 594 sb.append(bp.getLocationString()); 595 log(sb.toString()); 596 if (isSuspended()) 597 prompt(); 598 } 599 600 public void deleteBreakpoint(ResolvableBreakpoint bp) 601 { 602 bp.clear(); 603 breakpoints.remove(bp); 604 FastStringBuffer sb = new FastStringBuffer(); 605 if (bp.isTemporary()) 606 sb.append("Temporary b"); 607 else 608 sb.append('B'); 609 sb.append("reakpoint deleted: "); 610 sb.append(bp.getLocationString()); 611 log(sb.toString()); 612 if (isSuspended()) 613 prompt(); 614 } 615 616 public static void jdbToggleBreakpoint() 617 { 618 Jdb jdb = findJdb(); 619 if (jdb == null) 620 return; 621 final Editor editor = Editor.currentEditor(); 622 final Line line = editor.getDotLine(); 623 Annotation annotation = line.getAnnotation(); 624 if (annotation instanceof BreakpointAnnotation) 625 jdbDeleteBreakpoint(); 626 else 627 jdbSetBreakpoint(); 628 } 629 630 public static void jdbSetBreakpoint() 631 { 632 setBreakpointAtCurrentLine(false); 633 } 634 635 public static void jdbRunToCurrentLine() 636 { 637 Jdb jdb = findJdb(); 638 if (jdb == null) 639 return; 640 setBreakpointAtCurrentLine(true); 641 jdb.logCommand("continue"); 642 jdb.doContinue(); 643 } 644 645 private static void setBreakpointAtCurrentLine(boolean temporary) 646 { 647 Jdb jdb = findJdb(); 648 if (jdb == null) 649 return; 650 final Editor editor = Editor.currentEditor(); 651 final Buffer buffer = editor.getBuffer(); 652 final File file = buffer.getFile(); 653 if (file != null && file.getName().toLowerCase().endsWith(".java")) { 654 final Line line = editor.getDotLine(); 655 FastStringBuffer sb = new FastStringBuffer(); 656 if (temporary) 657 sb.append('t'); 658 sb.append("break "); 659 sb.append(file.getName()); 660 sb.append(':'); 661 sb.append(line.lineNumber() + 1); 662 jdb.logCommand(sb.toString()); 663 LineNumberBreakpoint bp = 664 new LineNumberBreakpoint(jdb, buffer, editor.getDotLine()); 665 if (temporary) 666 bp.setTemporary(); 667 try { 668 EventRequest eventRequest = bp.resolveAgainstPreparedClasses(); 669 if (eventRequest != null) { 670 eventRequest.enable(); 671 } else { 672 EventRequestManager mgr = jdb.getVM().eventRequestManager(); 673 ClassPrepareRequest cpr = mgr.createClassPrepareRequest(); 674 String packageName = JavaSource.getPackageName(buffer); 675 String classFilter; 676 if (packageName != null) { 677 classFilter = 678 packageName.concat(".").concat(file.getName()); 679 } else { 680 classFilter = file.getName(); 681 } 682 if (classFilter.toLowerCase().endsWith(".java")) { 683 classFilter = 684 classFilter.substring(0, classFilter.length()-5); 685 } 686 cpr.addClassFilter(classFilter); 687 cpr.enable(); 688 } 689 jdb.addBreakpoint(bp); 690 jdb.saveSession(); 691 jdb.fireBreakpointChanged(); 692 } 693 catch (AbsentInformationException absent) { 694 jdb.log("Line number information is not available."); 695 } 696 catch (Exception e) { 697 Log.error(e); 698 } 699 } 700 } 701 702 public static void jdbDeleteBreakpoint() 703 { 704 Jdb jdb = findJdb(); 705 if (jdb == null) 706 return; 707 final Editor editor = Editor.currentEditor(); 708 final Line line = editor.getDotLine(); 709 Annotation annotation = line.getAnnotation(); 710 if (annotation instanceof BreakpointAnnotation) { 711 ResolvableBreakpoint bp = 712 ((BreakpointAnnotation)annotation).getBreakpoint(); 713 jdb.log("clear " + bp.getLocationString()); 714 jdb.deleteBreakpoint(bp); 715 File file = bp.getFile(); 716 if (file != null) { 717 Buffer buffer = Editor.getBufferList().findBuffer(file); 718 if (buffer != null) 719 buffer.repaint(); 720 } 721 jdb.saveSession(); 722 jdb.fireBreakpointChanged(); 723 } 724 } 725 726 public synchronized void doContinue() 727 { 728 if (vm != null) { 729 currentThread = null; 730 currentStackFrame = null; 731 vm.resume(); 732 isSuspended = false; 733 fireContextChanged(); 734 } 735 } 736 737 public synchronized void doSuspend() 738 { 739 if (vm != null && !isSuspended) { 740 vm.suspend(); 741 isSuspended = true; 742 log("VM suspended"); 743 ThreadReference threadRef = null; 744 List threads = vm.allThreads(); 745 for (int i = 0; i < threads.size(); i++) { 746 ThreadReference tr = (ThreadReference) threads.get(i); 747 if ("main".equals(tr.name())) 748 threadRef = tr; 749 } 750 if (threadRef == null) { 751 if (threads.size() > 0) 752 threadRef = (ThreadReference) threads.get(0); 753 } 754 setCurrentThread(threadRef); 755 fireContextChanged(); 756 prompt(); 757 } 758 } 759 760 public static Jdb findJdb() 761 { 762 return (Jdb) JavaMode.getJdb(); 763 } 764 765 public void startProcess() 766 { 767 Runnable r = new Runnable () { 768 public void run() 769 { 770 startProcessInternal(); 771 } 772 }; 773 new Thread (r).start(); 774 } 775 776 private void startProcessInternal() 777 { 778 VMConnection connection = VMConnection.getConnection(this); 779 if (connection != null) { 780 vm = connection.open(this); 781 if (vm != null) { 782 EventRequestManager mgr = vm.eventRequestManager(); 783 if (catchMode != CATCH_NONE) { 784 ExceptionRequest exceptionRequest = 785 mgr.createExceptionRequest(null, 786 catchMode == CATCH_ALL, true); 787 exceptionRequest.enable(); 788 } 789 ThreadStartRequest tsr = mgr.createThreadStartRequest(); 790 tsr.enable(); 791 ThreadDeathRequest tdr = mgr.createThreadDeathRequest(); 792 tdr.enable(); 793 if (breakpoints.size() > 0) { 794 Iterator iter = breakpoints.iterator(); 795 while (iter.hasNext()) { 796 Object obj = iter.next(); 797 if (obj instanceof ResolvableBreakpoint) { 798 ResolvableBreakpoint bp = 799 (ResolvableBreakpoint) obj; 800 String className = bp.getClassName(); 801 if (className != null) { 802 Log.debug("adding class prepare request for |" + className + "|"); 803 ClassPrepareRequest cpr = 804 mgr.createClassPrepareRequest(); 805 cpr.addClassFilter(className); 806 cpr.enable(); 807 } 808 } 809 } 810 } else { 811 Log.debug("startProcessInternal adding default breakpoint"); 812 breakpoints.add(new MethodBreakpoint(this, mainClass, 813 "main")); 814 fireBreakpointChanged(); 815 } 816 ClassPrepareRequest cpr = mgr.createClassPrepareRequest(); 817 cpr.addClassFilter(mainClass); 818 cpr.enable(); 819 if (!startSuspended) { 820 vm.resume(); 821 isSuspended = false; 822 fireContextChanged(); 823 } 824 } 825 } 826 } 827 828 public void resolveDeferredRequests(ClassPrepareEvent event) 829 { 830 synchronized (breakpoints) { 831 Iterator iter = breakpoints.iterator(); 832 while (iter.hasNext()) { 833 ResolvableBreakpoint bp = (ResolvableBreakpoint) iter.next(); 834 if (!bp.isResolved()) { 835 try { 836 Log.debug("bp.getClassName() = " + bp.getClassName()); 837 EventRequest eventRequest = bp.resolveAgainstPreparedClasses(); 838 if (eventRequest != null) { 839 Log.debug("bp was resolved"); 840 eventRequest.enable(); 841 } else 842 Log.debug("bp was NOT resolved"); 843 } 844 catch (Exception e) { 845 Log.error(e); 846 } 847 } 848 } 849 } 850 } 851 852 public JdbSession getSession() 853 { 854 return session; 855 } 856 857 private void setSession(JdbSession session) 858 { 859 this.session = session; 860 mainClass = session.getMainClass(); 861 mainClassArgs = session.getMainClassArgs(); 862 classPath = session.getClassPath(); 863 javaHome = session.getJavaHome(); 864 javaExecutable = session.getJavaExecutable(); 865 vmArgs = session.getVMArgs(); 866 startSuspended = session.getStartSuspended(); 867 sourcePath = session.getSourcePath(); 868 initializeBreakpoints(); 869 } 870 871 private void initializeBreakpoints() 872 { 873 breakpoints.clear(); 874 List breakpointSpecifications = session.getBreakpointSpecifications(); 875 if (breakpointSpecifications != null) { 876 Iterator iter = breakpointSpecifications.iterator(); 877 while (iter.hasNext()) { 878 BreakpointSpecification spec = 879 (BreakpointSpecification) iter.next(); 880 Log.debug(spec.toString()); 881 int lineNumber = spec.getLineNumber(); 882 if (spec.getLineNumber() > 0){ 883 File file = File.getInstance(spec.getFileName()); 884 if (file != null && file.isFile()) { 885 LineNumberBreakpoint bp = 886 new LineNumberBreakpoint(this, spec.getClassName(), 887 file, lineNumber); 888 breakpoints.add(bp); 889 } 890 } else { 891 String className = spec.getClassName(); 892 String methodName = spec.getMethodName(); 893 if (className != null && methodName != null) { 894 MethodBreakpoint bp = 895 new MethodBreakpoint(this, className, methodName); 896 breakpoints.add(bp); 897 } 898 } 899 } 900 } 901 fireBreakpointChanged(); 902 } 903 904 public void saveSession() 905 { 906 session.setBreakpoints(breakpoints); 907 session.saveDefaults(); 908 } 909 910 public void source() 911 { 912 source(Editor.currentEditor()); 913 } 914 915 public void source(final Editor editor) 916 { 917 Runnable r = new Runnable () { 918 public void run() 919 { 920 if (location == null) 921 return; 922 Method method = location.method(); 923 if (method != null && method.isNative()) 924 return; 925 String className = location.declaringType().name(); 926 String sourceName = null; 927 try { 928 sourceName = location.sourceName(); 929 Log.debug("sourceName = |" + sourceName + "|"); 930 } 931 catch (AbsentInformationException e) { 932 Log.error(e); 933 } 934 int lineNumber = location.lineNumber(); 935 Log.debug("lineNumber = " + lineNumber); 936 Log.debug(location.declaringType().name()); 937 if (sourceName != null) 938 follow(editor, className, sourceName, lineNumber - 1); 939 } 940 }; 941 if (SwingUtilities.isEventDispatchThread()) 942 r.run(); 943 else 944 SwingUtilities.invokeLater(r); 945 } 946 947 private boolean follow(Editor editor, String className, String fileName, 948 int lineNumber) 949 { 950 int index = className.indexOf('$'); 951 if (index >= 0) 952 className = className.substring(0, index); 953 File file = JavaSource.findSource(className, sourcePath); 954 if (file == null) { 955 file = Utilities.findFileInPath(fileName, sourcePath, 956 getCurrentDirectory()); 957 } 958 if (file == null) 959 return false; 960 if (!file.exists()) 961 return false; 962 final Buffer buf = Editor.getBuffer(file); 963 if (buf == null) 964 return false; 965 Editor ed = null; 966 final Buffer currentBuffer = editor.getBuffer(); 967 if (buf == currentBuffer) { 968 ed = editor; 969 } else { 970 editor.makeNext(buf); 971 if (currentBuffer instanceof Jdb) { 972 ed = editor.activateInOtherWindow(buf); 973 } else { 974 ed = editor; 976 ed.activate(buf); 977 } 978 } 979 Line line = buf.getLine(lineNumber); 980 if (line == null) { 981 ed.eob(); 982 } else { 983 ed.addUndo(SimpleEdit.MOVE); 984 ed.unmark(); 985 ed.update(ed.getDotLine()); 986 ed.setDot(line, 0); 987 ed.update(ed.getDotLine()); 988 ed.moveCaretToDotCol(); 989 ed.updateDisplay(); 990 } 991 return true; 992 } 993 994 public void dispose() 995 { 996 killVM(); 997 if (controlDialog != null) { 998 controlDialog.dispose(); 999 controlDialog = null; 1000 } 1001 saveSession(); 1002 removeAnnotations(); 1003 synchronized (Jdb.class) { 1004 if (JavaMode.getJdb() != this) 1005 Debug.bug(); 1006 JavaMode.setJdb(null); 1007 } 1008 } 1009 1010 private void removeAnnotations() 1011 { 1012 if (breakpoints != null) { 1013 for (Iterator it = breakpoints.iterator(); it.hasNext();) { 1014 Object obj = it.next(); 1015 if (obj instanceof ResolvableBreakpoint) { 1016 ResolvableBreakpoint bp = (ResolvableBreakpoint) obj; 1017 Line line = bp.getLine(); 1018 if (line != null) 1019 line.setAnnotation(null); 1020 } 1021 } 1022 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 1024 Editor ed = it.nextEditor(); 1025 if (ed.getModeId() == JAVA_MODE) 1026 ed.repaint(); 1027 } 1028 } 1029 } 1030 1031 private void quit() 1032 { 1033 killVM(); 1034 removeAnnotations(); 1035 ArrayList editors = new ArrayList (); 1037 for (EditorIterator it = new EditorIterator(); it.hasNext();) 1038 editors.add(it.next()); 1039 EditorList editorList = Editor.getEditorList(); 1040 for (Iterator it = editors.iterator(); it.hasNext();) { 1041 Editor ed = (Editor) it.next(); 1042 if (editorList.contains(ed)) { 1043 if (ed.getBuffer() == this) { 1044 Editor other = ed.getOtherEditor(); 1045 if (other != null) { 1046 Editor.setCurrentEditor(other); 1047 ed.getFrame().unsplitWindow(); 1048 } 1049 } 1050 } 1051 } 1052 kill(); 1053 } 1054 1055 private void restart() 1056 { 1057 killVM(); 1058 saveSession(); 1059 removeAnnotations(); 1060 session.loadDefaults(); 1061 initializeBreakpoints(); 1062 startProcess(); 1063 fireContextChanged(); 1064 } 1065 1066 private synchronized void killVM() 1067 { 1068 if (vm != null) { 1069 try { 1070 vm.exit(0); 1071 } 1072 catch (VMDisconnectedException e) { 1073 } 1075 setVM(null); 1076 } 1077 } 1078 1079 private void doBreak(String arg, boolean temporary) 1080 { 1081 try { 1082 if (vm == null) 1083 return; 1084 if (arg == null) { 1085 log("No location specified"); 1086 return; 1087 } 1088 int index = arg.indexOf(':'); 1089 if (index >= 0) { 1090 String fileName = arg.substring(0, index); 1091 try { 1092 int lineNumber = 1093 Integer.parseInt(arg.substring(index + 1).trim()); 1094 doBreakAtLineNumber(fileName, lineNumber, temporary); 1095 } 1096 catch (NumberFormatException e) { 1097 log("Invalid line number"); 1098 } 1099 } else { 1100 index = arg.lastIndexOf('.'); 1101 if (index < 0) { 1102 log("No class specified"); 1103 return; 1104 } 1105 String className = arg.substring(0, index); 1106 String methodName = arg.substring(index + 1); 1107 doBreakAtMethod(className, methodName, temporary); 1108 } 1109 } 1110 finally { 1111 if (isSuspended()) 1112 prompt(); 1113 } 1114 } 1115 1116 private void doBreakAtLineNumber(String fileName, int lineNumber, 1117 boolean temporary) 1118 { 1119 File file = findSourceFile(fileName); 1120 if (file == null) { 1121 log("File not found: ".concat(fileName)); 1122 return; 1123 } 1124 String className = file.getName(); 1125 if (className.toLowerCase().endsWith(".java")) 1126 className = className.substring(0, className.length() - 5); 1127 Buffer buffer = Editor.getBuffer(file); 1128 if (buffer != null) { 1129 if (!buffer.initialized()) 1130 buffer.initialize(); 1131 if (!buffer.isLoaded()) 1132 buffer.load(); 1133 String packageName = JavaSource.getPackageName(buffer); 1134 if (packageName != null) 1135 className = packageName.concat(".").concat(className); 1136 LineNumberBreakpoint bp = 1137 new LineNumberBreakpoint(this, className, file, lineNumber); 1138 if (temporary) 1139 bp.setTemporary(); 1140 try { 1141 EventRequest eventRequest = bp.resolveAgainstPreparedClasses(); 1142 if (eventRequest != null) { 1143 eventRequest.enable(); 1144 } else { 1145 EventRequestManager mgr = vm.eventRequestManager(); 1146 ClassPrepareRequest cpr = mgr.createClassPrepareRequest(); 1147 String classFilter = className; 1148 cpr.addClassFilter(classFilter); 1149 cpr.enable(); 1150 } 1151 addBreakpoint(bp); 1152 saveSession(); 1153 fireBreakpointChanged(); 1154 } 1155 catch (AbsentInformationException absent) { 1156 log("Line number information is not available."); 1157 } 1158 catch (Exception e) { 1159 Log.error(e); 1160 } 1161 } 1162 } 1163 1164 private File findSourceFile(String fileName) 1165 { 1166 String canonicalPath = null; 1167 if (Utilities.isFilenameAbsolute(fileName)) { 1168 File file = File.getInstance(fileName); 1169 if (file != null && file.isFile()) 1170 return file; 1171 return null; 1173 } 1174 File mainFile = JavaSource.findSource(mainClass, sourcePath); 1176 if (mainFile != null && mainFile.isFile()) { 1177 File dir = mainFile.getParentFile(); 1178 if (dir != null) { 1179 File file = File.getInstance(dir, fileName); 1180 if (file != null && file.isFile()) 1181 return file; 1182 } 1183 } 1184 File dir = Editor.currentEditor().getCurrentDirectory(); 1186 Log.debug("trying dir = " + dir); 1187 File file = File.getInstance(dir, fileName); 1188 if (file != null && file.isFile()) 1189 return file; 1190 List dirs = Utilities.getDirectoriesInPath(sourcePath); 1192 for (BufferIterator iter = new BufferIterator(); iter.hasNext();) { 1193 Buffer b = iter.nextBuffer(); 1194 file = b.getFile(); 1195 if (file.getName().equals(fileName)) { 1196 File rootDir = JavaSource.getPackageRootDirectory(b); 1197 for (Iterator it = dirs.iterator(); it.hasNext();) { 1198 String dirname = (String ) it.next(); 1199 if (dirname.equals(rootDir.canonicalPath())) 1200 return file; 1201 } 1202 } 1203 if (Platform.isPlatformWindows()) { 1204 if (file.getName().equalsIgnoreCase(fileName)) { 1205 File rootDir = JavaSource.getPackageRootDirectory(b); 1206 for (Iterator it = dirs.iterator(); it.hasNext();) { 1207 String dirname = (String ) it.next(); 1208 if (dirname.equalsIgnoreCase(rootDir.canonicalPath())) 1209 return file; 1210 } 1211 } 1212 } 1213 } 1214 return null; 1216 } 1217 1218 private void doBreakAtMethod(String className, String methodName, 1219 boolean temporary) 1220 { 1221 if (className.indexOf(".") < 0) { 1222 String fileName = className.concat(".java"); 1224 File file = findSourceFile(fileName); 1225 if (file != null) { 1226 Buffer buffer = Editor.getBuffer(file); 1227 if (buffer != null) { 1228 if (!buffer.initialized()) 1229 buffer.initialize(); 1230 if (!buffer.isLoaded()) 1231 buffer.load(); 1232 String packageName = JavaSource.getPackageName(buffer); 1233 if (packageName != null) 1234 className = packageName.concat(".").concat(className); 1235 } 1236 } 1237 } 1238 MethodBreakpoint bp = new MethodBreakpoint(this, className, methodName); 1239 if (temporary) 1240 bp.setTemporary(); 1241 try { 1242 EventRequest eventRequest = bp.resolveAgainstPreparedClasses(); 1243 if (eventRequest != null) { 1244 eventRequest.enable(); 1245 } else { 1246 EventRequestManager mgr = vm.eventRequestManager(); 1247 ClassPrepareRequest cpr = mgr.createClassPrepareRequest(); 1248 cpr.addClassFilter(className); 1249 cpr.enable(); 1250 } 1251 addBreakpoint(bp); 1252 saveSession(); 1253 fireBreakpointChanged(); 1254 } 1255 catch (Exception e) { 1256 Log.error(e); 1257 } 1258 } 1259 1260 private void doClear(String arg) 1262 { 1263 if (arg == null) { 1264 log("No breakpoint specified"); 1265 return; 1266 } 1267 if (arg.equals("all")) 1268 doClearAll(); 1269 else if (arg.indexOf(':') >= 0) 1270 doClearLineNumberBreakpoint(arg); 1271 else 1272 doClearMethodBreakpoint(arg); 1273 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 1275 Editor ed = it.nextEditor(); 1276 if (ed.getModeId() == JAVA_MODE) 1277 ed.repaint(); 1278 } 1279 } 1280 1281 private void doClearAll() 1282 { 1283 for (Iterator it = breakpoints.iterator(); it.hasNext();) { 1285 Object obj = it.next(); 1286 if (obj instanceof ResolvableBreakpoint) 1287 ((ResolvableBreakpoint)obj).clear(); 1288 } 1289 breakpoints.clear(); 1291 fireBreakpointChanged(); 1292 if (isSuspended()) 1293 prompt(); 1294 } 1295 1296 private void doClearLineNumberBreakpoint(String arg) 1297 { 1298 int index = arg.indexOf(':'); 1299 String fileName = arg.substring(0, index); 1300 if (!fileName.toLowerCase().endsWith(".java")) 1301 fileName = fileName.concat(".java"); 1302 int lineNumber = -1; 1303 try { 1304 lineNumber = Integer.parseInt(arg.substring(index + 1)); 1305 } 1306 catch (NumberFormatException e) {} 1307 if (lineNumber < 1) { 1308 log("Invalid breakpoint"); 1309 return; 1310 } 1311 for (Iterator it = breakpoints.iterator(); it.hasNext();) { 1312 Object obj = it.next(); 1313 if (obj instanceof LineNumberBreakpoint) { 1314 LineNumberBreakpoint bp = (LineNumberBreakpoint) obj; 1315 File file = bp.getFile(); 1316 if (file != null) { 1317 if (fileName.equals(file.getName())) { 1318 if (lineNumber == bp.getLineNumber()) { 1319 deleteBreakpoint(bp); 1321 fireBreakpointChanged(); 1322 return; 1323 } 1324 } 1325 } 1326 } 1327 } 1328 log("No breakpoint at " + arg); 1329 } 1330 1331 private void doClearMethodBreakpoint(String arg) 1332 { 1333 String className, methodName; 1334 int index = arg.lastIndexOf('.'); 1335 if (index >= 0) { 1336 className = arg.substring(0, index); 1337 methodName = arg.substring(index + 1); 1338 } else { 1339 className = null; 1340 methodName = arg; 1341 } 1342 for (Iterator it = breakpoints.iterator(); it.hasNext();) { 1343 Object obj = it.next(); 1344 if (obj instanceof MethodBreakpoint) { 1345 MethodBreakpoint bp = (MethodBreakpoint) obj; 1346 if (className != null) { 1347 if (className.equals(bp.getClassName())) { 1348 if (methodName.equals(bp.getMethodName())) { 1349 deleteBreakpoint(bp); 1351 fireBreakpointChanged(); 1352 return; 1353 } 1354 } 1355 } else { 1356 if (methodName.equals(bp.getMethodName())) { 1358 deleteBreakpoint(bp); 1360 fireBreakpointChanged(); 1361 return; 1362 } 1363 } 1364 } 1365 } 1366 log("No breakpoint at " + arg); 1367 } 1368 1369 private synchronized void doCatch(String arg) 1370 { 1371 try { 1372 if (vm == null) 1373 return; 1374 int newCatchMode = -1; 1375 if (arg.equals("none")) 1376 newCatchMode = CATCH_NONE; 1377 else if (arg.equals("uncaught")) 1378 newCatchMode = CATCH_UNCAUGHT; 1379 else if (arg.equals("all")) 1380 newCatchMode = CATCH_ALL; 1381 else { 1382 log("Invalid argument"); 1383 return; 1384 } 1385 if (newCatchMode == catchMode) 1386 return; EventRequestManager mgr = vm.eventRequestManager(); 1388 if (catchMode != CATCH_NONE) { 1389 List list = mgr.exceptionRequests(); 1390 Log.debug("exception request count = " + list.size()); 1391 mgr.deleteEventRequests(list); 1392 } 1393 if (newCatchMode != CATCH_NONE) { 1394 ExceptionRequest exceptionRequest = 1395 mgr.createExceptionRequest(null, 1396 newCatchMode == CATCH_ALL, true); 1397 exceptionRequest.enable(); 1398 } 1399 catchMode = newCatchMode; 1400 } 1401 finally { 1402 if (isSuspended()) 1403 prompt(); 1404 } 1405 } 1406 1407 private void doNext(String args) 1408 { 1409 if (vm == null) 1410 return; 1411 if (currentThread == null) { 1412 Log.debug("currentThread is null"); 1413 return; 1414 } 1415 Log.debug("currentThread = " + currentThread.name()); 1416 int count = 1; 1417 if (args != null) { 1418 try { 1419 count = Integer.parseInt(args); 1420 } 1421 catch (NumberFormatException e) { 1422 log("Invalid argument"); 1423 return; 1424 } 1425 } 1426 clearStepForThread(currentThread); 1427 EventRequestManager erm = vm.eventRequestManager(); 1428 StepRequest request = erm.createStepRequest(currentThread, 1429 StepRequest.STEP_LINE, StepRequest.STEP_OVER); 1430 request.addCountFilter(count); 1431 request.enable(); 1432 doContinue(); 1433 } 1434 1435 private void doStep(String args) 1436 { 1437 if (vm == null) 1438 return; 1439 if (currentThread == null) { 1440 Log.debug("currentThread is null"); 1441 return; 1442 } 1443 Log.debug("currentThread = " + currentThread.name()); 1444 boolean out = false; 1445 int count = 1; 1446 if (args != null) { 1447 if (args.equals("out")) { 1448 out = true; 1449 } else { 1450 try { 1451 count = Integer.parseInt(args); 1452 } 1453 catch (NumberFormatException e) { 1454 log("Invalid argument"); 1455 return; 1456 } 1457 } 1458 } 1459 clearStepForThread(currentThread); 1460 EventRequestManager erm = vm.eventRequestManager(); 1461 StepRequest request = 1462 erm.createStepRequest(currentThread, StepRequest.STEP_LINE, 1463 out ? StepRequest.STEP_OUT : StepRequest.STEP_INTO); 1464 request.addCountFilter(count); 1465 request.enable(); 1466 doContinue(); 1467 } 1468 1469 private void doFinish() 1470 { 1471 if (vm == null) 1472 return; 1473 if (currentThread == null) { 1474 Log.debug("currentThread is null"); 1475 return; 1476 } 1477 clearStepForThread(currentThread); 1478 EventRequestManager erm = vm.eventRequestManager(); 1479 StepRequest request = 1480 erm.createStepRequest(currentThread, StepRequest.STEP_LINE, 1481 StepRequest.STEP_OUT); 1482 request.addCountFilter(1); 1483 request.enable(); 1484 doContinue(); 1485 } 1486 1487 private void doPrint(String what) 1488 { 1489 if (!isSuspended()) { 1490 log("VM is not suspended"); 1491 return; 1492 } 1493 try { 1494 if (what == null || what.length() < 1) { 1495 log("Missing argument"); 1496 return; 1497 } 1498 if (currentStackFrame == null) { 1499 log("No stack frame"); 1500 return; 1501 } 1502 Value value = getValue(what, currentStackFrame); 1503 if (value == null) { 1504 log("null"); 1505 } else if (value instanceof StringReference) { 1506 log(value.toString()); 1507 } else if (value instanceof ArrayReference) { 1508 log(value.toString()); 1509 log(getStringValueOfArray(what, (ArrayReference)value)); 1510 } else { 1511 log(value.toString()); 1512 if (value instanceof ObjectReference) { 1513 String s = getStringValueOfObject((ObjectReference)value, 1514 currentThread); 1515 if (s != null) { 1516 Log.debug(s); 1517 log(s); 1518 } 1519 Log.debug("doPrint calling fireContextChanged"); 1522 fireContextChanged(); 1523 } 1524 } 1525 } 1526 catch (AbsentInformationException e) { 1527 Log.debug(e); 1528 log("Local variable information is not available."); 1529 log("Compile with -g to generate local variable information."); 1530 } 1531 catch (NoSuchFieldException e) { 1532 log("No such field"); 1533 } 1534 catch (Exception e) { 1535 log(e.toString()); 1536 Log.error(e); 1537 } 1538 finally { 1539 if (isSuspended()) 1540 prompt(); 1541 } 1542 } 1543 1544 private void doStdin(String s) 1545 { 1546 Process process = vm.process(); 1547 if (process != null) { 1548 OutputStream out = process.getOutputStream(); 1549 try { 1550 if (s != null) { 1551 out.write(s.getBytes()); 1552 log(s, false, JdbFormatter.JDB_FORMAT_OUTPUT); 1555 } 1556 out.write('\n'); 1557 out.flush(); 1558 } 1559 catch (IOException e) { 1560 Log.error(e); 1561 } 1562 } 1563 } 1564 1565 private void doLocals() 1566 { 1567 if (vm == null) 1568 return; 1569 if (currentThread == null) { 1570 Log.debug("currentThread is null"); 1571 return; 1572 } 1573 boolean contextChanged = false; 1574 try { 1575 StackFrame stackFrame = currentStackFrame; 1576 if (stackFrame == null && currentThread.frameCount() > 0) 1577 stackFrame = currentThread.frame(0); 1578 List variables = stackFrame.visibleVariables(); 1579 Map map = stackFrame.getValues(variables); 1580 Set entrySet = map.entrySet(); 1581 Iterator iter = entrySet.iterator(); 1582 while (iter.hasNext()) { 1583 Map.Entry entry = (Map.Entry ) iter.next(); 1584 LocalVariable variable = (LocalVariable) entry.getKey(); 1585 Value value = (Value) entry.getValue(); 1586 FastStringBuffer sb = new FastStringBuffer(variable.typeName()); 1587 sb.append(' '); 1588 sb.append(variable.name()); 1589 sb.append(" = "); 1590 sb.append(value); 1591 if (value instanceof StringReference) { 1592 ; 1593 } else if (value instanceof ArrayReference) { 1594 String s = getStringValueOfArray(variable.name(), 1595 (ArrayReference)value); 1596 if (s.length() > 0) { 1597 sb.append('\n'); 1598 sb.append(s); 1599 } 1600 } else if (value instanceof ObjectReference) { 1601 String s = getStringValueOfObject((ObjectReference)value, 1602 currentThread); 1603 if (s != null) { 1604 sb.append(' '); 1605 sb.append(s); 1606 } 1607 contextChanged = true; 1610 } 1611 log(sb.toString()); 1612 } 1613 } 1614 catch (AbsentInformationException e) { 1615 Log.debug(e); 1616 log("Local variable information is not available."); 1617 log("Compile with -g to generate local variable information."); 1618 } 1619 catch (Exception e) { 1620 Log.error(e); 1621 } 1622 if (contextChanged) 1623 fireContextChanged(); 1624 if (isSuspended()) 1625 prompt(); 1626 } 1627 1628 private String getStringValueOfObject(ObjectReference objRef, 1629 ThreadReference threadRef) 1630 { 1631 try { 1632 List frames = threadRef.frames(); 1634 int index = -1; 1635 if (frames.size() > 0) { 1636 for (int i = 0; i < frames.size(); i++) { 1637 StackFrame frame = (StackFrame) frames.get(i); 1638 if (frame != null && frame.equals(currentStackFrame)) { 1639 index = i; 1640 break; 1641 } 1642 } 1643 } 1644 1645 ReferenceType refType = objRef.referenceType(); 1646 List methods = 1647 refType.methodsByName("toString", "()Ljava/lang/String;"); 1648 Method method = (Method) methods.get(0); 1649 Value value = objRef.invokeMethod(threadRef, method, 1650 new ArrayList (), ObjectReference.INVOKE_SINGLE_THREADED); 1651 1652 frames = threadRef.frames(); 1654 if (frames != null && index >= 0 && index < frames.size()) 1655 currentStackFrame = (StackFrame) frames.get(index); 1656 1657 if (value != null) 1658 return value.toString(); 1659 } 1660 catch (Exception e) { 1661 Log.error(e); 1662 } 1663 return null; 1664 } 1665 1666 private static String getStringValueOfArray(String name, ArrayReference ar) 1667 { 1668 FastStringBuffer sb = new FastStringBuffer(); 1669 final int limit = ar.length(); 1670 for (int i = 0; i < limit; i++) { 1671 sb.append(" "); 1672 sb.append(name); 1673 sb.append('['); 1674 sb.append(i); 1675 sb.append("]: "); 1676 Value v = ar.getValue(i); 1677 sb.append(v == null ? "null" : v.toString()); 1678 if (i < limit-1) 1679 sb.append('\n'); 1680 } 1681 return sb.toString(); 1682 } 1683 1684 private void clearStepForThread(ThreadReference threadRef) 1685 { 1686 EventRequestManager erm = vm.eventRequestManager(); 1687 List requests = erm.stepRequests(); 1688 Iterator iter = requests.iterator(); 1689 while (iter.hasNext()) { 1690 StepRequest request = (StepRequest) iter.next(); 1691 if (request.thread().equals(threadRef)) { 1692 erm.deleteEventRequest(request); 1693 break; } 1695 } 1696 } 1697 1698 private static Value getValue(String expression, StackFrame frame) 1699 throws Exception 1700 { 1701 Log.debug("getValue"); 1702 StringTokenizer st = new StringTokenizer (expression, "[]."); 1703 if (!st.hasMoreTokens()) { 1704 Log.debug("no more tokens"); 1705 throw new NoSuchFieldException (); 1706 } 1707 String token = st.nextToken(); 1708 Log.debug("token = |" + token + "|"); 1709 Value currentValue = null; 1710 Field currentField = null; 1711 ObjectReference obj = null; 1712 LocalVariable local = null; 1713 if (token.equals("this")) { 1714 currentValue = frame.thisObject(); 1715 if (currentValue == null) 1716 throw new NoSuchFieldException (token); 1717 } else { 1718 Log.debug("calling visibleVariableByName"); 1719 local = frame.visibleVariableByName(token); 1720 Log.debug("local = " + local); 1721 if (local != null) { 1722 currentValue = frame.getValue(local); 1723 Log.debug("currentValue = " + currentValue); 1724 } else { 1725 ReferenceType refType = frame.location().declaringType(); 1726 Log.debug("refType = " + refType); 1727 obj = frame.thisObject(); 1728 if (obj == null) { 1729 Log.debug("static method"); 1731 currentField = refType.fieldByName(token); 1732 if (currentField != null && currentField.isStatic()) 1733 currentValue = refType.getValue(currentField); 1734 else 1735 throw new NoSuchFieldException (); 1736 } else { 1737 currentField = refType.fieldByName(token); 1738 if (currentField != null) 1739 currentValue = obj.getValue(currentField); 1740 else { 1741 Log.debug("throwing NoSuchFieldException ..."); 1742 throw new NoSuchFieldException (); 1743 } 1744 } 1745 } 1746 } 1747 while (st.hasMoreTokens() && currentValue != null) { 1748 String prevToken = token; 1749 token = st.nextToken(); 1750 Log.debug("while loop token = |" + token + "|"); 1751 Object arg; 1752 try { 1753 arg = new Integer (token); 1754 } catch (NumberFormatException e) { 1755 arg = token; 1756 } 1757 if (currentValue instanceof ArrayReference) { 1758 int count = -1; 1759 if (arg instanceof Integer ) 1760 count = ((Integer )arg).intValue(); 1761 if (count >= 0 && count < ((ArrayReference)currentValue).length()) 1762 currentValue = ((ArrayReference)currentValue).getValue(count); 1763 else 1764 throw new ArrayIndexOutOfBoundsException (); 1765 } else if (currentValue instanceof ObjectReference && 1766 arg instanceof String ) { 1767 Log.debug("object reference, string"); 1768 obj = (ObjectReference) currentValue; 1769 ReferenceType refType = obj.referenceType(); 1770 currentField = refType.fieldByName(token); 1771 if (currentField != null) 1772 currentValue = obj.getValue(currentField); 1773 } else 1774 throw new Exception (); 1775 } 1776 Log.debug("getValue returning currentValue = " + currentValue); 1777 return currentValue; 1778 } 1779 1780 public boolean isModified() 1781 { 1782 return false; 1783 } 1784 1785 public String toString() 1787 { 1788 return "jdb"; 1789 } 1790 1791 public String getTitle() 1792 { 1793 return "jdb"; 1794 } 1795 1796 public Icon getIcon() 1797 { 1798 return Utilities.getIconFromFile("jpty.png"); 1799 } 1800} 1801 | Popular Tags |