public ProgressableProcess(
      final URI uri, final String statusTName, final String statusQName, StatusBean bean) {

    this.uri = uri;
    this.statusTName = statusTName;
    this.statusQName = statusQName;
    this.bean = bean;
    this.broadcaster = new Broadcaster(uri, statusQName, statusTName);
    bean.setStatus(Status.QUEUED);
    try {
      bean.setHostName(InetAddress.getLocalHost().getHostName());
    } catch (UnknownHostException e) {
      logger.warn("Cannot find local host!", e);
    }
    broadcast(bean);
  }
 /** Cancels the current topic monitor, if there is one. Prints exception if cannot. */
 private void cancelMonitor() {
   if (bean.getStatus().isFinal() && topicConnection != null) {
     try {
       topicConnection.close();
     } catch (Exception ne) {
       logger.error("Cannot close topic", ne);
     }
   }
 }
  @Override
  public final void run() {
    try {
      execute();
      if (out != System.out) {
        out.close();
        out = System.out;
      }
    } catch (Exception ne) {
      ne.printStackTrace(out);
      logger.error("Cannot run process!", ne);

      bean.setStatus(Status.FAILED);
      bean.setMessage(ne.getMessage());
      bean.setPercentComplete(0);
      broadcast(bean);
    }
  }
 /**
  * Notify any clients of the beans status
  *
  * @param bean
  */
 @Override
 public void broadcast(StatusBean tbean) {
   try {
     bean.merge(tbean);
     cancelMonitor();
     broadcaster.broadcast(bean, false);
   } catch (Exception e) {
     logger.error("Cannot broadcast", e);
   }
 }
  /**
   * Starts a connection which listens to the topic and if a cancel is found published, tries to
   * terminate the subprocess.
   *
   * @param p
   */
  protected void createTerminateListener() throws Exception {

    ConnectionFactory connectionFactory = ConnectionFactoryFacade.createConnectionFactory(uri);
    ProgressableProcess.this.topicConnection = connectionFactory.createConnection();
    topicConnection.start();

    Session session = topicConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);

    final Topic topic = session.createTopic(statusTName);
    final MessageConsumer consumer = session.createConsumer(topic);

    final Class<? extends StatusBean> clazz = bean.getClass();
    final ObjectMapper mapper = new ObjectMapper();

    MessageListener listener =
        new MessageListener() {
          public void onMessage(Message message) {
            try {
              if (message instanceof TextMessage) {
                TextMessage t = (TextMessage) message;
                final StatusBean tbean = mapper.readValue(t.getText(), clazz);

                if (bean.getStatus().isFinal()) { // Something else already happened
                  topicConnection.close();
                  return;
                }

                if (bean.getUniqueId().equals(tbean.getUniqueId())) {
                  if (tbean.getStatus() == Status.REQUEST_TERMINATE) {
                    bean.merge(tbean);
                    out.println("Terminating job '" + tbean.getName() + "'");

                    terminate();
                    topicConnection.close();

                    bean.setStatus(Status.TERMINATED);
                    bean.setMessage("Foricibly terminated before finishing.");
                    broadcast(bean);

                    return;
                  }
                }
              }
            } catch (Exception e) {
              logger.error("Cannot deal with message " + message, e);
            }
          }
        };
    consumer.setMessageListener(listener);
  }
  protected void dryRun(int size, boolean complete) {
    for (int i = 0; i < size; i++) {

      if (bean.getStatus() == Status.REQUEST_TERMINATE || bean.getStatus() == Status.TERMINATED) {
        return;
      }
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        logger.error("Dry run sleeping failed", e);
      }
      System.out.println("Dry run : " + bean.getPercentComplete());
      bean.setPercentComplete(i);
      broadcast(bean);
    }

    bean.setStatus(Status.COMPLETE);
    bean.setPercentComplete(100);
    bean.setMessage("Dry run complete (no software run)");
    broadcast(bean);
  }