/**
   * Uses <code>generator</code> to generate a command, execute it, then send the appropriate
   * response.
   *
   * <p>The following steps occur:
   *
   * <ul>
   *   <li>The command and its assigned command runner are generated by the generator
   *   <li>The command is scheduled to execute on the command runner
   *   <li>The method blocks until the command is executed, or the timeout occurs, (the timeout
   *       period is a servlet configuration parameter)
   *   <li>When execution is complete, a response is sent using {@link
   *       JMSCommandGenerator#sendResponse(HttpServletResponse)}
   * </ul>
   *
   * @param generator the selected <code>JMSCommandGenerator</code>
   * @param request a <code>HttpServletRequest</code>
   * @param response a <code>HttpResponse</code>
   * @throws ServletException if there is a problem accessing the servlets <code>HJBRoot</code>
   * @throws IOException if a problem occurs while writing the response
   */
  protected void handleUsingSelectedGenerator(
      JMSCommandGenerator generator, HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    generator.generateCommand(request, getRoot());
    JMSCommand generatedCommand = generator.getGeneratedCommand();

    synchronized (generatedCommand) {
      HJBApplication.CommandTimeoutTask timeIsUp = new HJBApplication.CommandTimeoutTask();
      try {
        // Schedule the command with the command runner, then start a
        // timer to time it out
        generator.getAssignedCommandRunner().schedule(generatedCommand);
        getTimeoutTimer().schedule(timeIsUp, getCommandTimeout());
        while (!generatedCommand.isComplete()) {
          // N.B. for this to work, JMSCommand#setComplete MUST be
          // synchronized (and they all are! see
          // BaseJMSCommand#completed)
          generatedCommand.wait(getCommandTimeout());
          if (timeIsUp.barIsClosed()) {
            handleCommandExecutionWasTimedOut(generator, response, generatedCommand);
            return;
          }
        }
      } catch (InterruptedException e) {
        handleExecutionThreadWasInterrupted(response, generatedCommand, e);
        return;
      } finally {
        timeIsUp.cancel();
      }
    }
    generator.sendResponse(response);
  }
 protected void handleCommandExecutionWasTimedOut(
     JMSCommandGenerator generator, HttpServletResponse response, JMSCommand generatedCommand)
     throws IOException {
   // Instruct the command runner to ignore the command
   // The command runner **will** log the instruction
   // If the command has not run yet (i.e, the
   // timeout occurred while the command was waiting to be
   // run), the command runner will discard the ignored
   // command
   // Otherwise, at least both HJB and the HTTP user agent
   // will have a message showing that something went
   // wrong...
   generator.getAssignedCommandRunner().ignore(generatedCommand);
   String message =
       strings()
           .getString(
               HJBStrings.COMMAND_EXECUTION_TIMED_OUT,
               generatedCommand.getDescription(),
               new Long(getCommandTimeout()));
   LOG.error(message);
   HJBException fault = new HJBException(message);
   fault.fillInStackTrace();
   new RuntimeExceptionHandler().sendHJBFault(response, fault);
 }