4 * @author Roman Blazevic
8 package xelfi.debugger;
10 import java.io.IOException;
12 import java.awt.Color;
13 import java.awt.Panel;
14 import xelfi.util.EnhProperties;
16 import xelfi.editor.*;
17 import xelfi.xedit.JavaEditorFrame;
18 import xelfi.compiler.Output;
19 import xelfi.execution.RunOptions;
21 //import symantec.tools.debug.*; // doesn't need TCP/IP
24 * This is a main class of the Xelfi debugger.
25 * It is also a document on which several views can exist
26 * (LocalsView, CallStackView and ThreadsView).
29 public class Debugger implements DebuggerCallback, BackgroundCallback, XFColorCallback, XelfiOptions
31 private DebuggerOptions options;
33 private Vector remoteDebuggers;
35 private boolean debuggingSession; // just debugging
37 private RemoteDebugger remoteDebugger;
38 private RemoteThreadGroup currentThreadGroup;
39 private RemoteThread currentThread;
41 private Watches watches;
42 private Breakpoints breakpoints;
44 private LocalsView localsView;
45 private CallStackView callStackView;
46 private ThreadsView threadsView;
48 private Position currentPosition = null; //some position on the current line
50 private Breakpoint temporaryBreakpoint = null; //used "while going to cursor"
52 // bude se delat trochu jinak
53 private Color currentLineBackgroundColor;
54 private Color breakpointLineBackgroundColor;
55 private Color currentLineForegroundColor;
56 private Color breakpointLineForegroundColor;
57 private Color foregroundColor; // filled in getBackground()
59 private boolean canEnableGoFlag = true;
60 private boolean canEnableGoToCursorFlag = true;
63 * Debugger constructor.
67 options = new DebuggerOptions();
69 remoteDebuggers = new Vector();
71 watches = new Watches(this);
72 breakpoints = new Breakpoints(this);
74 localsView = new LocalsView(this);
75 callStackView = new CallStackView(this);
76 threadsView = new ThreadsView(this);
77 remoteDebugger = null;
78 currentThreadGroup = null;
80 debuggingSession = false;
82 XFColor.addCallback(this);
83 TopLevel.addOption(this);
87 * Implementation of the breakpointEvent from the DebuggerCallback
89 public void breakpointEvent(RemoteThread t) throws Exception
91 canEnableGoFlag = true;
92 canEnableGoToCursorFlag = true;
94 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
95 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);
96 TopLevel.getMenu().enableItem(MainMenu.miDebugTraceOver);
97 TopLevel.getMenu().enableItem(MainMenu.miDebugTraceInto);
99 RemoteStackFrame[] stack = t.dumpStack();
101 if (stack.length > 0)
103 //TopLevel.getOutput().println(stack[0].toString());
108 TopLevel.getOutput().show();
109 TopLevel.getOutput().println("invalid thread specified in breakpoint");
112 if (getCurrentStackFrameIndex() == stack.length-1)
114 internalFinishDebugging(); // nebo vyber dalsi thread, ktery je na breakpointu;
118 String className = new String();
122 // try to find out the class name and the line number on which we has stopped
123 StringTokenizer st = new StringTokenizer(stack[0].toString(), ".()");
125 int nTokens = st.countTokens();
127 for(int i = 3; i < nTokens; i++) // n-3 times
128 className = className+st.nextToken()+".";
130 className += st.nextToken();
134 lineNumber = Integer.valueOf(st.nextToken(":)")).intValue();
136 // decide if we have stopped on the temporary breakpoint
137 if (temporaryBreakpoint != null)
138 if (lineNumber == temporaryBreakpoint.getLineNumber()
139 && className.equals(temporaryBreakpoint.getClassName()))
141 // destroy the temporary breakpoint
142 int numberOfBreakpoints = breakpoints.getNumberOfBreakpoints();
143 boolean canDestroy = true;
145 for(int i = 0; i < numberOfBreakpoints; i++)
147 Breakpoint breakpoint = breakpoints.getBreakpoint(i);
149 if (breakpoint.getLineNumber() == temporaryBreakpoint.getLineNumber()
150 && breakpoint.getClassName() == temporaryBreakpoint.getClassName()
151 && breakpoint.isEnabled() && breakpoint.isValid())
157 boolean success = true; // breakpoint was successfully removed from the remoteDebugger (if exists)
161 RemoteClass rc = remoteDebugger.findClass(className);
166 result = rc.clearBreakpointLine(lineNumber);
167 if (!result.equals(""))
179 // if the breakpoint was succesfully removed from the debugger, we must also remove breakpoint
183 TopLevel.getOutput().show();
184 TopLevel.getOutput().println("temporary breakpoint \""+className+":"+lineNumber+"\" cannot be removed");
187 temporaryBreakpoint = null;
191 // get a source and a position on which we have stopped
194 s = new Source(className, false);
196 //JARDA - az Jaroslav opravi editor, nebude se mazat current line
197 //Position oldPosition = currentPosition;
198 currentPosition = TopLevel.getCurrentSnapshot().getPosition(s, lineNumber-1).beginOfLine();
199 JavaEditorFrame jef = TopLevel.showEditor(s, currentPosition, true);
201 //if (oldPosition != null)
202 // Block.line(oldPosition).redraw();
204 Block.line(currentPosition).redraw();
206 catch (IOException e)
208 TopLevel.getOutput().show();
209 TopLevel.getOutput().println("class '"+className+"' not found");
211 catch (NoSuchElementException e)
213 TopLevel.getOutput().show();
214 TopLevel.getOutput().println("cannot get debug info for the class '"+className+"'");
215 TopLevel.getOutput().println(" ( is the class compiled with the -g option? )");
218 watches.updateContent();
219 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
220 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
221 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
222 //threadsView.highlightThread(t);
226 * Implementation of the exceptionEvent from the DebuggerCallback
228 public void exceptionEvent(RemoteThread t, String s) throws Exception
230 Output output = TopLevel.getOutput();
233 output.println("exception in thread \""+t.getName()+"\": "+s);
237 * Implementation of the threadDeathEvent from the DebuggerCallback
239 public void threadDeathEvent(RemoteThread t)
241 if (t == currentThread)
242 internalFinishDebugging();
244 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
248 * Implementation of the quitEvent from the DebuggerCallback
250 public void quitEvent()
252 internalFinishDebugging();
256 * Implementation of the printToConsole from the DebuggerCallback
258 public synchronized void printToConsole(String s)
260 TopLevel.getOutput().println(s);
264 * Implementation of the getForeground method from the BackgroundCallback
266 public Color getForeground()
268 return foregroundColor;
272 * Implementation of the getBackground method from the BackgroundCallback
274 // musi se delat efektivneji - nejlepe hashovat , zatim se to dela v O(n) !!!
275 public Color getBackground(Position p)
277 if (debuggingSession)
278 if (currentPosition != null)
279 if (p.sameLine(currentPosition))
281 foregroundColor = currentLineForegroundColor;
282 return currentLineBackgroundColor;
285 // jeste se musime podivat, zda to neni breakpoint line
286 PositionInfo pInfo = TopLevel.getCurrentSnapshot().getPositionInfo(p);
287 String className = pInfo.getSource().getName();
288 int lineNumber = pInfo.getLine();
290 int numberOfBreakpoints = breakpoints.getNumberOfBreakpoints();
292 for(int i = 0; i < numberOfBreakpoints; i++)
293 if (breakpoints.getBreakpoint(i).getLineNumber()-1 == lineNumber)
294 if (breakpoints.getBreakpoint(i).getClassName().compareTo(className) == 0)
295 if (breakpoints.getBreakpoint(i).isValid() && breakpoints.getBreakpoint(i).isEnabled())
297 foregroundColor = breakpointLineForegroundColor;
298 return breakpointLineBackgroundColor;
305 * Implementation of the colorsChanged from the XFColorCallback
307 public void colorsChanged()
309 currentLineBackgroundColor = XFColor.getBgColor(XFColor.CurrentLine);
310 currentLineForegroundColor = XFColor.getFgColor(XFColor.CurrentLine);
311 breakpointLineBackgroundColor = XFColor.getBgColor(XFColor.BreakpointLine);
312 breakpointLineForegroundColor = XFColor.getFgColor(XFColor.BreakpointLine);
316 * Implementation of the loadProperies from the XelfiOptions
318 public void loadProperties(EnhProperties properties)
320 options.getProperties(properties);
322 watches.getProperties(properties);
323 breakpoints.getProperties(properties);
327 * Implementation of the storeProperties from the XelfiOptions
329 public void storeProperties(EnhProperties properties)
331 options.putProperties(properties);
333 watches.putProperties(properties);
334 breakpoints.putProperties(properties);
338 * Implementation of the getPanel from the XelfiOptions
340 public Panel getPanel()
342 return new DebuggerOptionsPanel(options);
346 * Implementation of the getTabName from the XelfiOptions
348 public String getTabName()
354 * Implementation of the onOK from the XelfiOptions
356 public void onOK(Panel p)
358 options = ((DebuggerOptionsPanel)p).getDebuggerOptions();
360 watches.updateContent();
361 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
362 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
366 * Handles Debug|Go command.
370 canEnableGoFlag = false;
371 canEnableGoToCursorFlag = false;
373 TopLevel.getMenu().disableItem(MainMenu.miDebugGo);
374 TopLevel.getMenu().disableItem(MainMenu.miDebugGoCursor);
375 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceOver);
376 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceInto);
378 if (!debuggingSession)
382 if (!initDebuggingSession())
385 /*canEnableGoFlag = false;
386 canEnableGoToCursorFlag = false;
388 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
389 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);*/
394 if (remoteDebugger.listBreakpoints().length == 0)
395 if (!setDefaultBreakpoint())
398 /*canEnableGoFlag = false;
399 canEnableGoToCursorFlag = false;
401 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
402 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);*/
408 StringTokenizer st = new StringTokenizer(RunOptions.getArguments());
409 int nTokens = st.countTokens();
410 String args[] = new String[1+nTokens];
412 args[0] = new String(getClassToDebug());
413 for(int i = 1; i <= nTokens; i++)
414 args[i] = st.nextToken();
416 currentThreadGroup = remoteDebugger.run(1+nTokens, args);
426 if (currentThread == null)
428 System.err.println("nothing suspended");
434 currentThread.cont();
441 currentThread.resetCurrentFrameIndex();
444 // JARDA - dokud Jarda neopravi, bude se to delat az v breakpointEvent
445 // decolor the current line
446 if (currentPosition != null)
448 Position oldPosition = currentPosition;
450 currentPosition = null;
451 Block.line(oldPosition).redraw();
456 * Handles Debug|GoToCursor command.
458 public void goToCursor(Source s, Position p)
460 canEnableGoFlag = false;
461 canEnableGoToCursorFlag = false;
463 TopLevel.getMenu().disableItem(MainMenu.miDebugGo);
464 TopLevel.getMenu().disableItem(MainMenu.miDebugGoCursor);
465 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceOver);
466 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceInto);
468 if (!debuggingSession)
472 if (!initDebuggingSession())
474 canEnableGoFlag = false;
475 canEnableGoToCursorFlag = false;
477 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
478 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);
483 setTemporaryBreakpoint(s, p);
485 StringTokenizer st = new StringTokenizer(RunOptions.getArguments());
486 int nTokens = st.countTokens();
487 String args[] = new String[1+nTokens];
489 args[0] = new String(getClassToDebug());
490 for(int i = 1; i <= nTokens; i++)
491 args[i] = st.nextToken();
493 currentThreadGroup = remoteDebugger.run(1+nTokens, args);
503 if (currentThread == null)
505 System.err.println("nothing suspended");
511 setTemporaryBreakpoint(s, p);
512 currentThread.cont();
519 currentThread.resetCurrentFrameIndex();
522 // JARDA - dokud Jarda neopravi, bude se to delat az v breakpointEvent
523 // decolor the current line
524 if (currentPosition != null)
526 Position oldPosition = currentPosition;
528 currentPosition = null;
529 Block.line(oldPosition).redraw();
533 void internalFinishDebugging()
535 canEnableGoFlag = true;
536 canEnableGoToCursorFlag = true;
538 Position oldPosition = currentPosition;
540 doneDebuggingSession(false);
542 currentPosition = null;
543 if (oldPosition != null)
544 Block.line(oldPosition).redraw();
546 watches.updateContent();
547 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
548 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
549 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
553 * Handles Debug|FinishDebugging command.
555 public void finishDebugging()
557 canEnableGoFlag = true;
558 canEnableGoToCursorFlag = true;
560 Position oldPosition = currentPosition;
562 doneDebuggingSession(true);
564 currentPosition = null;
565 if (oldPosition != null)
566 Block.line(oldPosition).redraw();
568 watches.updateContent();
569 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
570 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
571 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
575 * Handles Debug|RestartDebugging command.
577 public void restartDebugging()
591 * Handles Debug|TraceOver command.
593 public void traceOver()
595 canEnableGoFlag = false;
596 canEnableGoToCursorFlag = false;
598 TopLevel.getMenu().disableItem(MainMenu.miDebugGo);
599 TopLevel.getMenu().disableItem(MainMenu.miDebugGoCursor);
600 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceOver);
601 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceInto);
603 if (currentThread == null)
605 System.err.println("nothing suspended");
611 currentThread.next();
613 catch(IllegalAccessError e)
615 //"Current thread is not at breakpoint."
623 // JARDA - dokud Jarda neopravi, bude se to delat az v breakpointEvent
624 // decolor the current line
625 if (currentPosition != null)
627 Position oldPosition = currentPosition;
629 currentPosition = null;
630 Block.line(oldPosition).redraw();
635 * Handles Debug|TraceInto command.
637 public void traceInto()
639 canEnableGoFlag = false;
640 canEnableGoToCursorFlag = false;
642 TopLevel.getMenu().disableItem(MainMenu.miDebugGo);
643 TopLevel.getMenu().disableItem(MainMenu.miDebugGoCursor);
644 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceOver);
645 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceInto);
647 if (currentThread == null)
649 System.err.println("nothing suspended");
655 currentThread.step(true);
657 catch(IllegalAccessError e)
659 //"Current thread is not at breakpoint."
667 // JARDA - dokud Jarda neopravi, bude se to delat az v breakpointEvent
668 // decolor the current line
669 if (currentPosition != null)
671 Position oldPosition = currentPosition;
673 currentPosition = null;
674 Block.line(oldPosition).redraw();
679 * Handles Debug|ToggleBreakpoint command.
681 public void toggleBreakpoint(Source s, Position p)
683 PositionInfo pInfo = TopLevel.getCurrentSnapshot().getPositionInfo(p);
684 String className = pInfo.getSource().getName();
685 int lineNumber = pInfo.getLine()+1;
686 int numberOfBreakpoints = breakpoints.getNumberOfBreakpoints();
689 for(int i = 0; i < numberOfBreakpoints; i++)
691 Breakpoint breakpoint = breakpoints.getBreakpoint(i);
693 if (className.equals(breakpoint.getClassName()) &&
694 lineNumber == breakpoint.getLineNumber())
697 break; // breakpoint is already set
702 breakpoints.addBreakpoint(new Breakpoint(className, lineNumber));
704 breakpoints.removeBreakpoint(index);
708 * Handles Debug|AddWatch command.
710 public void addWatch()
712 watches.getView().addWatch();
716 * Initializes the debugging session.
717 * Returns false if it is not possible to continue (don't know which class to start).
719 boolean initDebuggingSession() throws Exception
721 TopLevel.getOutput().clear();
723 if (getClassToDebug().equals(""))
725 TopLevel.getOutput().show();
726 TopLevel.getOutput().println("don't know which class to start");
730 TopLevel.getMenu().enableItem(MainMenu.miDebugFinish);
731 TopLevel.getMenu().enableItem(MainMenu.miDebugRestart);
735 TopLevel.getOutput().show();
736 TopLevel.getOutput().println("debugger session is starting ...");
738 remoteDebugger = new RemoteDebugger("", this, false);
739 remoteDebuggers.addElement(remoteDebugger);
741 TopLevel.getOutput().clear();
742 TopLevel.getOutput().println("debugger session has started");
749 int numberOfBreakpoints = breakpoints.getNumberOfBreakpoints();
751 debuggingSession = true;
752 for(int i = 0; i < numberOfBreakpoints; i++)
754 Breakpoint breakpoint = breakpoints.getBreakpoint(i);
756 if (breakpoint.isEnabled())
757 addBreakpoint(breakpoint);
760 breakpoints.updateContent();
765 * Closes the debugging session.
767 void doneDebuggingSession(boolean closeDebugger)
771 if (remoteDebugger != null)
774 RemoteThreadGroup[] rtg = getThreadGroups();
777 for(int i = 0; i < rtg.length; i++)
781 //without system thread group
782 if (rtg[i].getName().equals("system"))
785 RemoteThread rt[] = rtg[i].listThreads(true);
789 for(int j = 0; j < rt.length; j++)
795 //e.printStackTrace();
801 remoteDebugger.close();
802 remoteDebuggers.removeElement(remoteDebugger);
805 remoteDebuggers.removeElement(remoteDebugger);
807 if (debuggingSession)
809 debuggingSession = false;
811 TopLevel.getOutput().show();
812 TopLevel.getOutput().println("debugger session has finished");
815 currentThread = null;
816 currentThreadGroup = null;
817 remoteDebugger = null;
820 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
821 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);
822 TopLevel.getMenu().disableItem(MainMenu.miDebugFinish);
823 TopLevel.getMenu().disableItem(MainMenu.miDebugRestart);
825 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceOver);
826 TopLevel.getMenu().disableItem(MainMenu.miDebugTraceInto);
833 * This method is called by the CallStackView when
834 * a stack frame is chosen.
836 void stackFrameChosen(RemoteStackFrame rsf)
838 String className = null;
842 RemoteStackFrame.Name rc = rsf.getRemoteClass();
845 System.out.println("invalid stack frame");
849 className = rc.getName();
857 int lineNumber = rsf.getLineNumber();
859 if (className == null)
860 System.out.println("invalid class name");
862 // get a source and a position
863 Source s = new Source(className, false);
864 Position p = TopLevel.getCurrentSnapshot().getPosition(s, lineNumber-1).beginOfLine();
866 TopLevel.showEditor(s, p, true);
868 catch (IOException e)
870 TopLevel.getOutput().show();
871 TopLevel.getOutput().println("source code for class '"+className+"' not found");
876 * Called when final clean up is neccessary.
878 public void shutdown()
880 for(int i = 0; i < remoteDebuggers.size(); i++)
884 remoteDebugger = (RemoteDebugger)remoteDebuggers.elementAt(i);
887 RemoteThreadGroup[] rtg = getThreadGroups();
890 for(int k = 0; k < rtg.length; k++)
894 //without system thread group
895 if (rtg[k].getName().equals("system"))
898 RemoteThread rt[] = rtg[k].listThreads(true);
902 for(int j = 0; j < rt.length; j++)
912 remoteDebugger.close();
913 remoteDebuggers.removeElement(remoteDebugger);
914 //((RemoteDebugger)remoteDebuggers.elementAt(i)).close();
918 //e.printStackTrace();
919 //because some RemoteDebuggers are already closed
925 * Sets the default breakpoint (on method <main class>.main).
927 boolean setDefaultBreakpoint()
929 boolean success = true; // breakpoint was successfully added into the remoteDebugger (if exists)
933 RemoteClass rc = remoteDebugger.findClass(getClassToDebug());
938 RemoteField rf = rc.getMethod("main");
942 result = rc.setBreakpointMethod(rf);;
943 if (!result.equals(""))
960 TopLevel.getOutput().show();
961 TopLevel.getOutput().println("default breakpoint \""+getClassToDebug()+".main\" cannot be set");
962 TopLevel.getOutput().println(" ( is the class compiled with the -g option? )");
970 * Sets the temporary breakpoint.
972 void setTemporaryBreakpoint(Source s, Position p)
974 PositionInfo pInfo = TopLevel.getCurrentSnapshot().getPositionInfo(p);
975 String className = pInfo.getSource().getName();
976 int lineNumber = pInfo.getLine()+1;
978 boolean success = true; // breakpoint was successfully added into the remoteDebugger (if exists)
982 RemoteClass rc = remoteDebugger.findClass(className);
987 result = rc.setBreakpointLine(lineNumber);
989 if (!result.equals(""))
991 rc.clearBreakpointLine(lineNumber);
1000 e.printStackTrace();
1006 TopLevel.getOutput().show();
1007 TopLevel.getOutput().println("temporary breakpoint \""+className+":"+lineNumber+"\" cannot be set");
1008 temporaryBreakpoint = null;
1011 temporaryBreakpoint = new Breakpoint(className, lineNumber);
1015 * Returns true if the debugger allows to enable the Debug|Go command.
1017 public boolean canEnableGo()
1019 return canEnableGoFlag;
1023 * Returns true if the debugger allows to enable the Debug|GoToCursor command.
1025 public boolean canEnableGoToCursor()
1027 return canEnableGoToCursorFlag;
1031 * Called by the LocalsView class after its instance has been shown.
1033 void localsViewShown()
1035 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
1039 * Called by the CallStackView class after its instance has been shown.
1041 void callStackViewShown()
1043 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
1047 * Called by the ThreadsView class after its instance has been shown.
1049 void threadsViewShown()
1051 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
1055 * Returns the current value of the variable specified by the name variableName
1057 String getCurrentValue(String variableName)
1059 if (!debuggingSession)
1060 return "is not defined";
1062 if (currentThread == null)
1063 return "is not defined";
1067 StringTokenizer st = new StringTokenizer(variableName, ".[]", true);
1069 if (!st.hasMoreTokens())
1070 return "invalid expression";
1072 String token = st.nextToken();
1073 RemoteStackVariable rsv = currentThread.getStackVariable(token);
1076 return "is not defined";
1078 return "is not in scope.";
1080 RemoteValue obj = rsv.getValue();
1083 return "null"; // is it correct?
1085 while (st.hasMoreTokens())
1087 token = st.nextToken();
1088 if (token.equals("["))
1090 if (!st.hasMoreTokens())
1091 return "index missing";
1092 token = st.nextToken();
1094 if (!st.hasMoreTokens())
1095 return "invalid expression";
1096 if (!st.nextToken().equals("]"))
1097 return "invalid expression";
1105 index = Integer.valueOf(token).intValue();
1107 catch (NumberFormatException e)
1109 index = Integer.valueOf(getCurrentValue(token)).intValue();
1112 obj = ((RemoteArray)obj).getElement(index);
1115 return "null"; // is it correct?
1117 catch (NumberFormatException e)
1119 return "invalid index";
1121 catch (ArrayIndexOutOfBoundsException e)
1123 return "out of bounds";
1125 catch (ClassCastException e)
1127 return "is not an array element";
1131 if (token.equals("."))
1133 if (!st.hasMoreTokens())
1134 return "field missing";
1135 token = st.nextToken();
1139 obj = ((RemoteObject)obj).getFieldValue(token);
1142 return "null"; // is it correct?
1144 catch (ClassCastException e)
1146 return "is not a class field";
1151 return getCurrentValue(obj, options.getDepthOfRecursiveWatching());
1155 e.printStackTrace();
1161 * Returns the string containing a value of the RemoteValue instance.
1162 * Depth - how deep we can scan the value (it must be 0 at least).
1164 String getCurrentValue(RemoteValue obj, int depth)
1169 if (obj instanceof RemoteChar)
1170 return "'"+obj.toString()+"'";
1172 if (obj instanceof RemoteString)
1173 return "\""+obj.toString()+"\"";
1175 if (obj instanceof RemoteArray)
1178 return "[...]"; // don't continue in recursive watching
1180 RemoteValue elements[];
1184 elements = ((RemoteArray)obj).getElements();
1188 e.printStackTrace();
1192 String returnValue = "[";
1194 for(int i = 0; i < elements.length-1; i++)
1195 if (options.showArrayIndexes())
1196 returnValue += i+": "+getCurrentValue(elements[i], depth-1)+", ";
1198 returnValue += getCurrentValue(elements[i], depth-1)+", ";
1200 if (elements.length > 0)
1201 if (options.showArrayIndexes())
1202 returnValue += (elements.length-1)+": "+getCurrentValue(elements[elements.length-1], depth-1)+"]";
1204 returnValue += getCurrentValue(elements[elements.length-1], depth-1)+"]";
1211 if (obj instanceof RemoteObject)
1214 return "{...}"; // don't continue in recursive watching
1216 RemoteObject ro = (RemoteObject)obj;
1217 RemoteField fields[];
1221 fields = ro.getFields();
1225 e.printStackTrace();
1229 String returnValue = "{";
1231 RemoteValue fieldValue;
1233 if (fields.length == 0)
1234 return returnValue+"}";
1236 for(int i = 0; i < fields.length-1; i++)
1238 fieldName = fields[i].getName();
1241 fieldValue = ro.getFieldValue(fieldName);
1242 returnValue += fieldName+": "+getCurrentValue(fieldValue, depth-1)+", ";
1246 returnValue += fieldName+": ?, ";
1250 fieldName = fields[fields.length-1].getName();
1253 fieldValue = ro.getFieldValue(fieldName);
1254 returnValue = returnValue+fieldName+": "+getCurrentValue(fieldValue, depth-1)+"}";
1258 returnValue = returnValue+fieldName+": ?}";
1264 // process the RemoteThread and RemoteTreadGroup instances
1267 return obj.toString();
1271 * Returns the name of the class which will be started in the debugger
1274 String getClassToDebug()
1276 String returnValue = RunOptions.getMainClass();
1278 if (returnValue != null)
1285 * This method is called by the Breakpoints class after a breakpoint
1286 * has been added into the breakpoints document or after a breakpoint
1287 * has been successfully enabled in the breakpoints document.
1288 * This method can change the breakpoint state from valid to invalid
1289 * if it can not be added into the remote debugger.
1290 * This method is also called by the Debugger class while the debugging session is starting.
1292 void addBreakpoint(Breakpoint breakpoint)
1294 boolean success = true; // breakpoint was successfully added into the remoteDebugger (if exists)
1296 if (debuggingSession)
1300 RemoteClass rc = remoteDebugger.findClass(breakpoint.getClassName());
1305 result = rc.setBreakpointLine(breakpoint.getLineNumber());
1306 if (!result.equals(""))
1308 rc.clearBreakpointLine(breakpoint.getLineNumber());
1317 e.printStackTrace();
1322 // if the breakpoint was succesfully enabled or added into the remote debugger,
1323 // we must also add breakpoint line (if possible)
1326 breakpoint.setInvalid();
1327 TopLevel.getOutput().show();
1328 TopLevel.getOutput().println("breakpoint \""+breakpoint.getClassName()+":"+breakpoint.getLineNumber()+"\" cannot be set");
1332 Position breakpointPosition;
1333 JavaEditorFrame jef = TopLevel.findEditor(breakpoint.getClassName());
1337 breakpointPosition = TopLevel.getCurrentSnapshot().getPosition(jef.getSource(), breakpoint.getLineNumber()-1);
1338 Block.line(breakpointPosition).redraw();
1343 // mozna by se vyjimka mela jenom sezrat
1344 e.printStackTrace();
1349 breakpoint.setValid();
1353 Position breakpointPosition;
1354 JavaEditorFrame jef = TopLevel.findEditor(breakpoint.getClassName());
1358 breakpointPosition = TopLevel.getCurrentSnapshot().getPosition(jef.getSource(), breakpoint.getLineNumber()-1);
1359 Block.line(breakpointPosition).redraw();
1364 // mozna by se vyjimka mela jenom sezrat
1365 e.printStackTrace();
1371 * This method is called by the Breakpoints class after a breakpoint
1372 * has been removed or disabled in the breakpoints document.
1374 void removeBreakpoint(String className, int lineNumber)
1376 boolean success = true; // breakpoint was successfully removed from the remoteDebugger (if exists)
1378 if (debuggingSession)
1382 RemoteClass rc = remoteDebugger.findClass(className);
1387 result = rc.clearBreakpointLine(lineNumber);
1388 if (!result.equals(""))
1396 e.printStackTrace();
1401 // if the breakpoint was succesfully removed from the debugger, we must also remove breakpoint
1407 Position breakpointPosition;
1408 JavaEditorFrame jef = TopLevel.findEditor(className);
1412 breakpointPosition = TopLevel.getCurrentSnapshot().getPosition(jef.getSource(), lineNumber-1);
1413 Block.line(breakpointPosition).redraw();
1418 // mozna by se vyjimka mela jenom sezrat
1419 e.printStackTrace();
1425 * Returns the stack frames of the current thread
1427 RemoteStackFrame[] getCurrentStackFrames()
1429 RemoteStackFrame[] rsf = null;
1431 if (currentThread == null)
1436 rsf = currentThread.dumpStack();
1440 e.printStackTrace();
1447 * Returns the stack frame index of the current thread
1449 int getCurrentStackFrameIndex()
1451 if (currentThread == null)
1454 return currentThread.getCurrentFrameIndex();
1458 * Returns the stack variables of the current thread
1460 RemoteStackVariable[] getStackVariables()
1462 RemoteStackVariable[] rsv = null;
1464 if (currentThread == null)
1469 rsv = currentThread.getStackVariables();
1473 e.printStackTrace();
1480 * Returns the current stack frame of the current thread
1482 RemoteStackFrame getCurrentStackFrame()
1484 RemoteStackFrame rsf = null;
1486 if (currentThread == null)
1491 rsf = currentThread.getCurrentFrame();
1495 e.printStackTrace();
1502 * Returns the thread groups
1504 RemoteThreadGroup[] getThreadGroups()
1506 RemoteThreadGroup[] rtg = null;
1508 if (remoteDebugger == null)
1513 rtg = remoteDebugger.listThreadGroups(null);
1517 e.printStackTrace();
1524 * Returns the current thread
1526 RemoteThread getCurrentThread()
1528 return currentThread;
1532 * Returns the Watches document
1534 public Watches getWatches()
1540 * Returns the Breakpoints document
1542 public Breakpoints getBreakpoints()
1548 * Returns the LocalsView on the Debugger
1550 public LocalsView getLocalsView()
1556 * Returns the CallStackView on the Debugger
1558 public CallStackView getCallStackView()
1560 return callStackView;
1564 * Returns the ThreadsView on the Debugger
1566 public ThreadsView getThreadsView()
1571 ////////////////////////////////////////////////////////////////
1573 /* void threadChosen(RemoteThreadGroup tg, RemoteThread t)
1575 canEnableGoFlag = true;
1576 canEnableGoToCursorFlag = true;
1578 TopLevel.getMenu().enableItem(MainMenu.miDebugGo);
1579 TopLevel.getMenu().enableItem(MainMenu.miDebugGoCursor);
1580 TopLevel.getMenu().enableItem(MainMenu.miDebugTraceOver);
1581 TopLevel.getMenu().enableItem(MainMenu.miDebugTraceInto);
1583 RemoteStackFrame[] stack;
1587 stack = t.dumpStack();
1591 e.printStackTrace();
1595 currentThreadGroup = tg;
1597 if (stack.length > 0)
1599 for(int i = 0; i < stack.length; i++)
1601 System.out.println(i+" "+stack[i].toString());
1607 TopLevel.getOutput().show();
1608 TopLevel.getOutput().println("invalid thread specified in breakpoint");
1611 StringTokenizer st = new StringTokenizer(stack[getCurrentStackFrameIndex()].toString(), ".()");
1612 String className = new String();
1613 int lineNumber = -1;
1614 int nTokens = st.countTokens();
1616 for(int i = 3; i < nTokens; i++) // n-3 times
1617 className = className+st.nextToken()+".";
1619 className += st.nextToken();
1623 lineNumber = Integer.valueOf(st.nextToken(":)")).intValue();
1627 // get a source and a position on which we stopped
1630 s = new Source(className, false);
1632 // JARDA - az Jaroslav opravi editor, nebude se mazat current line
1633 Position oldPosition = currentPosition;
1634 currentPosition = TopLevel.getCurrentSnapshot().getPosition(s, lineNumber-1).beginOfLine();
1635 JavaEditorFrame jef = TopLevel.showEditor(s, currentPosition, true);
1637 if (oldPosition != null)
1638 Block.line(oldPosition).redraw();
1640 Block.line(currentPosition).redraw();
1642 catch (IOException e)
1644 TopLevel.getOutput().show();
1645 TopLevel.getOutput().println("class '"+className+"' not found");
1648 watches.updateContent();
1649 localsView.update(LocalsView.HINT_COMPLETE_UPDATE, -1);
1650 callStackView.update(CallStackView.HINT_COMPLETE_UPDATE, -1);
1651 threadsView.update(ThreadsView.HINT_COMPLETE_UPDATE, -1);
1652 // threadsView.highlightThread(t);
1656 * Returns the current value of the variable specified by the name variableName
1657 * The argument i indexes the current stack frame of the current thread.
1659 /* String getCurrentValue(String variableName, int i)
1663 if (currentThread == null)
1664 return "is not defined";
1666 int currentIndex = currentThread.getCurrentFrameIndex();
1668 currentThread.resetCurrentFrameIndex();
1669 currentThread.setCurrentFrameIndex(currentIndex);
1670 returnValue = getCurrentValue(variableName);
1671 currentThread.setCurrentFrameIndex(currentIndex);
1672 currentThread.resetCurrentFrameIndex();
1677 public void currentSnapshotHasChanged(Snapshot oldSnapshot)
1679 int numberOfBreakpoints = breakpoints.getNumberOfBreakpoints();
1681 for(int i = 0; i < numberOfBreakpoints; i++)
1685 Breakpoint breakpoint = breakpoints.getBreakpoint(i);
1687 Source s = new Source(breakpoint.getClassName());
1688 Position position = oldSnapshot.getPosition(s, breakpoint.getLineNumber()-1).beginOfLine();
1689 PositionInfo pi = TopLevel.getCurrentSnapshot().getPositionInfo(position);
1691 breakpoint.setLineNumber(pi.getLine()+1);
1695 //e.printStackTrace();
1699 breakpoints.updateContent();