public void discardJob(String jobId) {
   AbstractExecutable job = getJob(jobId);
   if (job instanceof DefaultChainedExecutable) {
     List<AbstractExecutable> tasks = ((DefaultChainedExecutable) job).getTasks();
     for (AbstractExecutable task : tasks) {
       if (!task.getStatus().isFinalState()) {
         updateJobOutput(task.getId(), ExecutableState.DISCARDED, null, null);
       }
     }
   }
   updateJobOutput(jobId, ExecutableState.DISCARDED, null, null);
 }
 protected void waitForJob(String jobId) {
   while (true) {
     AbstractExecutable job = jobService.getJob(jobId);
     if (job.getStatus() == ExecutableState.SUCCEED || job.getStatus() == ExecutableState.ERROR) {
       break;
     } else {
       try {
         Thread.sleep(5000);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
   }
 }
 private static ExecutablePO parse(AbstractExecutable executable) {
   ExecutablePO result = new ExecutablePO();
   result.setName(executable.getName());
   result.setUuid(executable.getId());
   result.setType(executable.getClass().getName());
   result.setParams(executable.getParams());
   if (executable instanceof DefaultChainedExecutable) {
     List<ExecutablePO> tasks = Lists.newArrayList();
     for (AbstractExecutable task : ((DefaultChainedExecutable) executable).getTasks()) {
       tasks.add(parse(task));
     }
     result.setTasks(tasks);
   }
   return result;
 }
 public void resumeJob(String jobId) {
   AbstractExecutable job = getJob(jobId);
   if (job == null) {
     return;
   }
   updateJobOutput(jobId, ExecutableState.READY, null, null);
   if (job instanceof DefaultChainedExecutable) {
     List<AbstractExecutable> tasks = ((DefaultChainedExecutable) job).getTasks();
     for (AbstractExecutable task : tasks) {
       if (task.getStatus() == ExecutableState.ERROR) {
         updateJobOutput(task.getId(), ExecutableState.READY, null, null);
         break;
       }
     }
   }
 }
 public void addJob(AbstractExecutable executable) {
   try {
     executableDao.addJob(parse(executable));
     addJobOutput(executable);
   } catch (PersistentException e) {
     logger.error("fail to submit job:" + executable.getId(), e);
     throw new RuntimeException(e);
   }
 }
 private void addJobOutput(AbstractExecutable executable) throws PersistentException {
   ExecutableOutputPO executableOutputPO = new ExecutableOutputPO();
   executableOutputPO.setUuid(executable.getId());
   executableDao.addJobOutput(executableOutputPO);
   if (executable instanceof DefaultChainedExecutable) {
     for (AbstractExecutable subTask : ((DefaultChainedExecutable) executable).getTasks()) {
       addJobOutput(subTask);
     }
   }
 }
 private static AbstractExecutable parseTo(ExecutablePO executablePO) {
   if (executablePO == null) {
     return null;
   }
   String type = executablePO.getType();
   try {
     Class<? extends AbstractExecutable> clazz = ClassUtil.forName(type, AbstractExecutable.class);
     Constructor<? extends AbstractExecutable> constructor = clazz.getConstructor();
     AbstractExecutable result = constructor.newInstance();
     result.setId(executablePO.getUuid());
     result.setName(executablePO.getName());
     result.setParams(executablePO.getParams());
     List<ExecutablePO> tasks = executablePO.getTasks();
     if (tasks != null && !tasks.isEmpty()) {
       Preconditions.checkArgument(result instanceof DefaultChainedExecutable);
       for (ExecutablePO subTask : tasks) {
         ((DefaultChainedExecutable) result).addTask(parseTo(subTask));
       }
     }
     return result;
   } catch (ReflectiveOperationException e) {
     throw new IllegalArgumentException("cannot parse this job:" + executablePO.getId(), e);
   }
 }