--- dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/tasks/Task.java 2016/01/24 21:48:55 2838 +++ dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/tasks/Task.java 2016/02/04 14:40:36 2918 @@ -1,72 +1,139 @@ package dk.daoas.adressevedligehold.tasks; import dk.daoas.adressevedligehold.util.TimingHelper; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; public abstract class Task implements Runnable { + private TaskLogger logger = TaskLogger.getInstance(); + public enum TaskState { STATE_QUEUED, STATE_RUNNING, STATE_DONE, STATE_ABORTED; } + @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")//bliver læst via gson - og det forvirrer findbugs public static class TaskBean { + public int id; public String description; public String detail; + public String errorMessage; public double percentCompleted; public String state; } - protected boolean abort = false; - protected TaskState state = TaskState.STATE_QUEUED; + protected volatile boolean abort = false;//mark volatile to make sure value isn't cached by threads + protected volatile TaskState state = TaskState.STATE_QUEUED; protected TaskManager manager; + private String errorMsg; + + private String logMessages; - public void setManager(TaskManager manager) { + private int id; + + public final void setManager(TaskManager manager) { this.manager = manager; } @Override public final void run() { + + TaskLogger.getInstance().reset(); + TimingHelper timing = new TimingHelper(); - System.out.println("Starting " + this.getDescription() ); + + + logger.info("Starting " + this.getDescription() ); this.state = TaskState.STATE_RUNNING; manager.setCurrentTask(this); try { taskRun(); - this.state = TaskState.STATE_DONE; + + if (this.state != TaskState.STATE_ABORTED) { //just to make sure we wasn't aborted + this.state = TaskState.STATE_DONE; + } + + } catch (Exception e) { + this.errorMsg = e.getMessage(); + e.printStackTrace(); this.state = TaskState.STATE_ABORTED; } manager.setCurrentTask(null); - System.out.println("Done " + this.getDescription() + " " + timing.getElapsed() + "ms"); + logger.info("Done " + this.getDescription() + " " + timing.getElapsed() + "ms"); + + logMessages = TaskLogger.getInstance().getBuffer(); + } + + public final String getLog() { + if (this.state == TaskState.STATE_RUNNING) { + return TaskLogger.getInstance().getBuffer(); //if live return current log buffer content + } else { + return logMessages; + } + } + + public final void setId(int newId) { + this.id = newId; } + public final int getId() { + return this.id; + } - public TaskState getState() { + public final TaskState getState() { return this.state; } + public boolean isAborted() { + return this.abort; + } + public void doAbort() { this.abort = true; } + public void doAbort(Exception e) { + this.abort = true; + this.errorMsg = e.getMessage(); + } + public TaskBean getTaskBean() { TaskBean bean = new TaskBean(); - + bean.id = this.getId(); bean.description = this.getDescription(); bean.detail = this.getDetail(); bean.percentCompleted = this.getPercentCompleted(); bean.state = this.state.toString(); + bean.errorMessage = this.getErrorMessage(); return bean; } - protected abstract void taskRun(); + public String getErrorMessage() { + return this.errorMsg; + } + + @Override + public final boolean equals(Object o) { + Task otherTask = (Task) o; + + return this.getId() == otherTask.getId(); + } + + /** + * @throws Exception + * + * Implementing classes should not catch terminating exceptions but let it propagate to Task the Task::run() + * method. + */ + protected abstract void taskRun() throws Exception; public abstract String getDescription(); public abstract String getDetail(); - public abstract short getPercentCompleted(); + public abstract double getPercentCompleted(); }