/*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#getWorkflowInstanceMetadata(java.lang.String)
   */
  public Metadata getWorkflowInstanceMetadata(String workflowInstId) {
    // okay, try and look up that worker thread in our hash map
    IterativeWorkflowProcessorThread worker =
        (IterativeWorkflowProcessorThread) workerMap.get(workflowInstId);
    if (worker == null) {
      // try and get the metadata
      // from the workflow instance repository (as it was persisted)
      try {
        WorkflowInstance inst = instRep.getWorkflowInstanceById(workflowInstId);
        return inst.getSharedContext();
      } catch (InstanceRepositoryException e) {
        LOG.log(
            Level.FINEST,
            "WorkflowEngine: Attempt to get metadata "
                + "for workflow instance id: "
                + workflowInstId
                + ", however, this engine is "
                + "not tracking its execution and the id: ["
                + workflowInstId
                + "] "
                + "was never persisted to "
                + "the instance repository");
        e.printStackTrace();
        return new Metadata();
      }
    }

    return worker.getWorkflowInstance().getSharedContext();
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#startWorkflow(org.apache.oodt.cas.workflow.structs.Workflow,
   *      org.apache.oodt.cas.metadata.Metadata)
   */
  public synchronized WorkflowInstance startWorkflow(Workflow workflow, Metadata metadata)
      throws EngineException {
    // to start the workflow, we create a default workflow instance
    // populate it
    // persist it
    // add it to the worker map
    // start it

    WorkflowInstance wInst = new WorkflowInstance();
    wInst.setWorkflow(workflow);
    wInst.setCurrentTaskId(((WorkflowTask) workflow.getTasks().get(0)).getTaskId());
    wInst.setSharedContext(metadata);
    wInst.setStatus(CREATED);
    persistWorkflowInstance(wInst);

    IterativeWorkflowProcessorThread worker =
        new IterativeWorkflowProcessorThread(wInst, instRep, this.wmgrUrl);
    worker.setRClient(rClient);
    workerMap.put(wInst.getId(), worker);

    wInst.setStatus(QUEUED);
    persistWorkflowInstance(wInst);

    try {
      pool.execute(worker);
    } catch (InterruptedException e) {
      throw new EngineException(e);
    }

    return wInst;
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#updateMetadata(java.lang.String,
   *      org.apache.oodt.cas.metadata.Metadata)
   */
  public synchronized boolean updateMetadata(String workflowInstId, Metadata met) {
    // okay, try and look up that worker thread in our hash map
    IterativeWorkflowProcessorThread worker =
        (IterativeWorkflowProcessorThread) workerMap.get(workflowInstId);
    if (worker == null) {
      LOG.log(
          Level.WARNING,
          "WorkflowEngine: Attempt to update metadata context "
              + "for workflow instance id: "
              + workflowInstId
              + ", however, this engine is "
              + "not tracking its execution");
      return false;
    }

    worker.getWorkflowInstance().setSharedContext(met);
    try {
      persistWorkflowInstance(worker.getWorkflowInstance());
    } catch (Exception e) {
      LOG.log(
          Level.WARNING,
          "Exception persisting workflow instance: ["
              + worker.getWorkflowInstance().getId()
              + "]: Message: "
              + e.getMessage());
      return false;
    }

    return true;
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#resumeWorkflowInstance(java.lang.String)
   */
  public synchronized void resumeWorkflowInstance(String workflowInstId) {
    // okay, try and look up that worker thread in our hash map
    IterativeWorkflowProcessorThread worker =
        (IterativeWorkflowProcessorThread) workerMap.get(workflowInstId);
    if (worker == null) {
      LOG.log(
          Level.WARNING,
          "WorkflowEngine: Attempt to resume workflow instance id: "
              + workflowInstId
              + ", however, this engine is "
              + "not tracking its execution");
      return;
    }

    // also check to make sure that the worker is currently paused
    // only can resume WorkflowInstances that are paused, right?
    if (!worker.isPaused()) {
      LOG.log(
          Level.WARNING,
          "WorkflowEngine: Attempt to resume a workflow that "
              + "isn't paused currently: instance id: "
              + workflowInstId);
      return;
    }

    // okay, all good
    worker.resume();
  }
  /*
   * (non-Javadoc)
   *
   * @see org.apache.oodt.cas.workflow.engine.WorkflowEngine#stopWorkflow(java.lang.String)
   */
  public synchronized void stopWorkflow(String workflowInstId) {
    // okay, try and look up that worker thread in our hash map
    IterativeWorkflowProcessorThread worker =
        (IterativeWorkflowProcessorThread) workerMap.get(workflowInstId);
    if (worker == null) {
      LOG.log(
          Level.WARNING,
          "WorkflowEngine: Attempt to stop workflow instance id: "
              + workflowInstId
              + ", however, this engine is "
              + "not tracking its execution");
      return;
    }

    worker.stop();
  }