private void commandKill(StringTokenizer t) throws NoSessionException {
   // ### Should change the way in which thread ids and threadgroup names
   // ### are distinguished.
   if (!t.hasMoreTokens()) {
     env.error("Usage: kill <threadgroup name> or <thread id>");
     return;
   }
   while (t.hasMoreTokens()) {
     String idToken = t.nextToken();
     ThreadReference thread = findThread(idToken);
     if (thread != null) {
       runtime.stopThread(thread);
       env.notice("Thread " + thread.name() + " killed.");
       return;
     } else {
       /* Check for threadgroup name, NOT skipping "system". */
       // ### Should skip "system"?  Classic 'jdb' does this.
       // ### Should deal with possible non-uniqueness of threadgroup names.
       ThreadGroupIterator itg = allThreadGroups();
       while (itg.hasNext()) {
         ThreadGroupReference tg = itg.nextThreadGroup();
         if (tg.name().equals(idToken)) {
           ThreadIterator it = new ThreadIterator(tg);
           while (it.hasNext()) {
             runtime.stopThread(it.nextThread());
           }
           env.notice("Threadgroup " + tg.name() + "killed.");
           return;
         }
       }
       env.failure("\"" + idToken + "\" is not a valid threadgroup or id.");
     }
   }
 }
  private void commandClear(StringTokenizer t) throws NoSessionException {
    if (!t.hasMoreTokens()) {
      // Print set breakpoints
      listEventRequests();
      return;
    }
    // ### need 'clear all'
    BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken());
    if (bpSpec != null) {
      List<EventRequestSpec> specs = runtime.eventRequestSpecs();

      if (specs.isEmpty()) {
        env.notice("No breakpoints set.");
      } else {
        List<EventRequestSpec> toDelete = new ArrayList<EventRequestSpec>();
        for (EventRequestSpec spec : specs) {
          if (spec.equals(bpSpec)) {
            toDelete.add(spec);
          }
        }
        // The request used for matching should be found
        if (toDelete.size() <= 1) {
          env.notice("No matching breakpoint set.");
        }
        for (EventRequestSpec spec : toDelete) {
          runtime.delete(spec);
        }
      }
    } else {
      env.error("Ill-formed breakpoint specification.");
    }
  }
  private void commandStop(StringTokenizer t) throws NoSessionException {
    String token;

    if (!t.hasMoreTokens()) {
      listEventRequests();
    } else {
      token = t.nextToken();
      // Ignore optional "at" or "in" token.
      // Allowed for backward compatibility.
      if (token.equals("at") || token.equals("in")) {
        if (t.hasMoreTokens()) {
          token = t.nextToken();
        } else {
          env.error("Missing breakpoint specification.");
          return;
        }
      }
      BreakpointSpec bpSpec = parseBreakpointSpec(token);
      if (bpSpec != null) {
        // ### Add sanity-checks for deferred breakpoint.
        runtime.install(bpSpec);
      } else {
        env.error("Ill-formed breakpoint specification.");
      }
    }
  }
 private void commandStep(StringTokenizer t) throws NoSessionException {
   ThreadReference current = context.getCurrentThread();
   if (current == null) {
     env.failure("No current thread.");
     return;
   }
   try {
     if (t.hasMoreTokens() && t.nextToken().toLowerCase().equals("up")) {
       runtime.stepOut(current);
     } else {
       runtime.stepIntoLine(current);
     }
   } catch (AbsentInformationException e) {
     env.failure(
         "No linenumber information available -- " + "Try \"stepi\" to step by instructions.");
   }
 }
 private void commandNexti() throws NoSessionException {
   ThreadReference current = context.getCurrentThread();
   if (current == null) {
     env.failure("No current thread.");
     return;
   }
   runtime.stepOverInstruction(current);
 }
 private ReferenceType findClass(String pattern) throws NoSessionException {
   List<ReferenceType> results = runtime.findClassesMatchingPattern(pattern);
   if (results.size() > 0) {
     // ### Should handle multiple results sensibly.
     return results.get(0);
   }
   return null;
 }
 private void commandClasses() throws NoSessionException {
   OutputSink out = env.getOutputSink();
   // out.println("** classes list **");
   for (ReferenceType refType : runtime.allClasses()) {
     out.println(refType.name());
   }
   out.show();
 }
 private void commandCont() throws NoSessionException {
   try {
     runtime.go();
   } catch (VMNotInterruptedException e) {
     // ### failure?
     env.notice("Target VM is already running.");
   }
 }
  private boolean doLoad(boolean suspended, StringTokenizer t) throws NoSessionException {

    String clname;

    if (!t.hasMoreTokens()) {
      clname = context.getMainClassName();
      if (!clname.equals("")) {
        // Run from prevously-set class name.
        try {
          String vmArgs = context.getVmArguments();
          runtime.run(suspended, vmArgs, clname, context.getProgramArguments());
          return true;
        } catch (VMLaunchFailureException e) {
          env.failure("Attempt to launch main class \"" + clname + "\" failed.");
        }
      } else {
        env.failure("No main class specifed and no current default defined.");
      }
    } else {
      clname = t.nextToken();
      StringBuffer sbuf = new StringBuffer();
      // Allow VM arguments to be specified here?
      while (t.hasMoreTokens()) {
        String tok = t.nextToken();
        sbuf.append(tok);
        if (t.hasMoreTokens()) {
          sbuf.append(' ');
        }
      }
      String args = sbuf.toString();
      try {
        String vmArgs = context.getVmArguments();
        runtime.run(suspended, vmArgs, clname, args);
        context.setMainClassName(clname);
        // context.setVmArguments(vmArgs);
        context.setProgramArguments(args);
        return true;
      } catch (VMLaunchFailureException e) {
        env.failure("Attempt to launch main class \"" + clname + "\" failed.");
      }
    }
    return false;
  }
 private void commandNext() throws NoSessionException {
   ThreadReference current = context.getCurrentThread();
   if (current == null) {
     env.failure("No current thread.");
     return;
   }
   try {
     runtime.stepOverLine(current);
   } catch (AbsentInformationException e) {
     env.failure(
         "No linenumber information available -- " + "Try \"nexti\" to step by instructions.");
   }
 }
 private void commandAttach(StringTokenizer t) {
   String portName;
   if (!t.hasMoreTokens()) {
     portName = context.getRemotePort();
     if (!portName.equals("")) {
       try {
         runtime.attach(portName);
       } catch (VMLaunchFailureException e) {
         env.failure("Attempt to attach to port \"" + portName + "\" failed.");
       }
     } else {
       env.failure("No port specifed and no current default defined.");
     }
   } else {
     portName = t.nextToken();
     try {
       runtime.attach(portName);
     } catch (VMLaunchFailureException e) {
       env.failure("Attempt to attach to port \"" + portName + "\" failed.");
     }
     context.setRemotePort(portName);
   }
 }
 private void listEventRequests() throws NoSessionException {
   // Print set breakpoints
   List<EventRequestSpec> specs = runtime.eventRequestSpecs();
   if (specs.isEmpty()) {
     env.notice("No breakpoints/watchpoints/exceptions set.");
   } else {
     OutputSink out = env.getOutputSink();
     out.println("Current breakpoints/watchpoints/exceptions set:");
     for (EventRequestSpec bp : specs) {
       out.println("\t" + bp);
     }
     out.show();
   }
 }
 private void commandPrint(StringTokenizer t, boolean dumpObject) throws NoSessionException {
   if (!t.hasMoreTokens()) {
     // ### Probably confused if expresion contains whitespace.
     env.error("No expression specified.");
     return;
   }
   ThreadReference current = context.getCurrentThread();
   if (current == null) {
     env.failure("No default thread specified: " + "use the \"thread\" command first.");
     return;
   }
   StackFrame frame;
   try {
     frame = context.getCurrentFrame(current);
     if (frame == null) {
       env.failure("Thread has not yet created any stack frames.");
       return;
     }
   } catch (VMNotInterruptedException e) {
     env.failure("Target VM must be in interrupted state.");
     return;
   }
   while (t.hasMoreTokens()) {
     String expr = t.nextToken("");
     Value val = null;
     try {
       val = runtime.evaluate(frame, expr);
     } catch (Exception e) {
       env.error("Exception: " + e);
       // ### Fix this!
     }
     if (val == null) {
       return; // Error message already printed
     }
     OutputSink out = env.getOutputSink();
     if (dumpObject && (val instanceof ObjectReference) && !(val instanceof StringReference)) {
       ObjectReference obj = (ObjectReference) val;
       ReferenceType refType = obj.referenceType();
       out.println(expr + " = " + val.toString() + " {");
       dump(out, obj, refType, refType);
       out.println("}");
     } else {
       out.println(expr + " = " + val.toString());
     }
     out.show();
   }
 }
 private void commandResume(StringTokenizer t) throws NoSessionException {
   if (!t.hasMoreTokens()) {
     // Suspend all threads in the current thread group.
     // ### Issue: help message says default is all threads.
     // ### Behavior here agrees with 'jdb', however.
     ThreadIterator ti = currentThreadGroupThreads();
     while (ti.hasNext()) {
       // TODO - don't suspend debugger threads
       ti.nextThread().resume();
     }
     env.notice("All threads resumed.");
   } else {
     while (t.hasMoreTokens()) {
       ThreadReference thread = findThread(t.nextToken());
       if (thread != null) {
         // thread.resume();
         runtime.resumeThread(thread);
       }
     }
   }
 }
 private void commandInterrupt(StringTokenizer t) throws NoSessionException {
   runtime.interrupt();
 }
 private ThreadGroupIterator allThreadGroups() throws NoSessionException {
   threads = null;
   return new ThreadGroupIterator(runtime.topLevelThreadGroups());
 }
 private BreakpointSpec parseBreakpointSpec(String bptSpec) {
   StringTokenizer t = new StringTokenizer(bptSpec);
   BreakpointSpec bpSpec = null;
   //        try {
   String token = t.nextToken("@:( \t\n\r");
   // We can't use hasMoreTokens here because it will cause any leading
   // paren to be lost.
   String rest;
   try {
     rest = t.nextToken("").trim();
   } catch (NoSuchElementException e) {
     rest = null;
   }
   if ((rest != null) && rest.startsWith("@")) {
     t = new StringTokenizer(rest.substring(1));
     String sourceName = token;
     String lineToken = t.nextToken();
     int lineNumber = Integer.valueOf(lineToken).intValue();
     if (t.hasMoreTokens()) {
       return null;
     }
     bpSpec = runtime.createSourceLineBreakpoint(sourceName, lineNumber);
   } else if ((rest != null) && rest.startsWith(":")) {
     t = new StringTokenizer(rest.substring(1));
     String classId = token;
     String lineToken = t.nextToken();
     int lineNumber = Integer.valueOf(lineToken).intValue();
     if (t.hasMoreTokens()) {
       return null;
     }
     bpSpec = runtime.createClassLineBreakpoint(classId, lineNumber);
   } else {
     // Try stripping method from class.method token.
     int idot = token.lastIndexOf(".");
     if ((idot <= 0) || /* No dot or dot in first char */ (idot >= token.length() - 1)) {
       /* dot in last char */
       return null;
     }
     String methodName = token.substring(idot + 1);
     String classId = token.substring(0, idot);
     List<String> argumentList = null;
     if (rest != null) {
       if (!rest.startsWith("(") || !rest.endsWith(")")) {
         // ### Should throw exception with error message
         // out.println("Invalid method specification: "
         //            + methodName + rest);
         return null;
       }
       // Trim the parens
       // ### What about spaces in arglist?
       rest = rest.substring(1, rest.length() - 1);
       argumentList = new ArrayList<String>();
       t = new StringTokenizer(rest, ",");
       while (t.hasMoreTokens()) {
         argumentList.add(t.nextToken());
       }
     }
     bpSpec = runtime.createMethodBreakpoint(classId, methodName, argumentList);
   }
   //        } catch (Exception e) {
   //            env.error("Exception attempting to create breakpoint: " + e);
   //            return null;
   //        }
   return bpSpec;
 }
 public void executeCommand(String command) {
   // ### Treatment of 'out' here is dirty...
   out = env.getOutputSink();
   if (echo) {
     out.println(">>> " + command);
   }
   StringTokenizer t = new StringTokenizer(command);
   try {
     String cmd;
     if (t.hasMoreTokens()) {
       cmd = t.nextToken().toLowerCase();
       lastCommand = cmd;
     } else {
       cmd = lastCommand;
     }
     if (cmd.equals("print")) {
       commandPrint(t, false);
     } else if (cmd.equals("eval")) {
       commandPrint(t, false);
     } else if (cmd.equals("dump")) {
       commandPrint(t, true);
     } else if (cmd.equals("locals")) {
       commandLocals();
     } else if (cmd.equals("classes")) {
       commandClasses();
     } else if (cmd.equals("methods")) {
       commandMethods(t);
     } else if (cmd.equals("threads")) {
       commandThreads(t);
     } else if (cmd.equals("thread")) {
       commandThread(t);
     } else if (cmd.equals("suspend")) {
       commandSuspend(t);
     } else if (cmd.equals("resume")) {
       commandResume(t);
     } else if (cmd.equals("cont")) {
       commandCont();
     } else if (cmd.equals("threadgroups")) {
       commandThreadGroups();
     } else if (cmd.equals("threadgroup")) {
       commandThreadGroup(t);
     } else if (cmd.equals("run")) {
       commandRun(t);
     } else if (cmd.equals("load")) {
       commandLoad(t);
     } else if (cmd.equals("connect")) {
       commandConnect(t);
     } else if (cmd.equals("attach")) {
       commandAttach(t);
     } else if (cmd.equals("detach")) {
       commandDetach(t);
     } else if (cmd.equals("interrupt")) {
       commandInterrupt(t);
       // ### Not implemented.
       //          } else if (cmd.equals("catch")) {
       //              commandCatchException(t);
       // ### Not implemented.
       //          } else if (cmd.equals("ignore")) {
       //              commandIgnoreException(t);
     } else if (cmd.equals("step")) {
       commandStep(t);
     } else if (cmd.equals("stepi")) {
       commandStepi();
     } else if (cmd.equals("next")) {
       commandNext();
     } else if (cmd.equals("nexti")) {
       commandNexti();
     } else if (cmd.equals("kill")) {
       commandKill(t);
     } else if (cmd.equals("where")) {
       commandWhere(t, false);
     } else if (cmd.equals("wherei")) {
       commandWhere(t, true);
     } else if (cmd.equals("up")) {
       commandUp(t);
     } else if (cmd.equals("down")) {
       commandDown(t);
     } else if (cmd.equals("frame")) {
       commandFrame(t);
     } else if (cmd.equals("stop")) {
       commandStop(t);
     } else if (cmd.equals("clear")) {
       commandClear(t);
     } else if (cmd.equals("list")) {
       commandList(t);
     } else if (cmd.equals("use")) {
       commandUse(t);
     } else if (cmd.equals("sourcepath")) {
       commandSourcepath(t);
     } else if (cmd.equals("classpath")) {
       commandClasspath(t);
     } else if (cmd.equals("monitor")) {
       commandMonitor(t);
     } else if (cmd.equals("unmonitor")) {
       commandUnmonitor(t);
     } else if (cmd.equals("view")) {
       commandView(t);
       //          } else if (cmd.equals("read")) {
       //              readCommand(t);
     } else if (cmd.equals("help") || cmd.equals("?")) {
       help();
     } else if (cmd.equals("quit") || cmd.equals("exit")) {
       try {
         runtime.detach();
       } catch (NoSessionException e) {
         // ignore
       }
       env.terminate();
     } else {
       // ### Dubious repeat-count feature inherited from 'jdb'
       if (t.hasMoreTokens()) {
         try {
           int repeat = Integer.parseInt(cmd);
           String subcom = t.nextToken("");
           while (repeat-- > 0) {
             executeCommand(subcom);
           }
           return;
         } catch (NumberFormatException exc) {
         }
       }
       out.println("huh? Try help...");
       out.flush();
     }
   } catch (NoSessionException e) {
     out.println("There is no currently attached VM session.");
     out.flush();
   } catch (Exception e) {
     out.println("Internal exception: " + e.toString());
     out.flush();
     System.out.println("JDB internal exception: " + e.toString());
     e.printStackTrace();
   }
   out.show();
 }
 private ThreadGroupReference getDefaultThreadGroup() throws NoSessionException {
   if (defaultThreadGroup == null) {
     defaultThreadGroup = runtime.systemThreadGroup();
   }
   return defaultThreadGroup;
 }
 private void commandDetach(StringTokenizer t) throws NoSessionException {
   runtime.detach();
 }
 private ThreadIterator allThreads() throws NoSessionException {
   threads = null;
   // ### Why not use runtime.allThreads().iterator() ?
   return new ThreadIterator(runtime.topLevelThreadGroups());
 }