package com.netifera.platform.tasks.internal;
import java.io.PrintWriter;
import java.io.StringWriter;
import com.netifera.platform.api.dispatcher.IMessenger;
import com.netifera.platform.api.log.ILogger;
import com.netifera.platform.api.tasks.ITask;
import com.netifera.platform.api.tasks.ITaskMessenger;
import com.netifera.platform.api.tasks.ITaskOutput;
import com.netifera.platform.api.tasks.ITaskRunnable;
import com.netifera.platform.api.tasks.TaskException;
import com.netifera.platform.tasks.ITaskProgress;
import com.netifera.platform.tasks.ITaskPrompter;
import com.netifera.platform.tasks.TaskConsoleOutput;
import com.netifera.platform.tasks.TaskLogOutput;
import com.netifera.platform.tasks.TaskStatus;
public class Task implements Runnable, ITaskProgress, ITaskPrompter, ITaskMessenger, ITask {
private final ITaskRunnable runnableInstance;
private Thread taskThread;
/* Not used right now */
private ITaskPrompter prompter;
private final TaskManager taskManager;
private final TaskStatus status;
private volatile boolean canceled;
private boolean started;
private final ILogger logger;
private final TaskProgressHelper progress;
private final TaskOutputHelper output;
Task(TaskStatus record, ITaskRunnable instance, IMessenger messenger,
TaskManager taskManager, ILogger logger) {
assert instance != null;
assert messenger != null;
this.status = record;
this.runnableInstance = instance;
this.taskManager = taskManager;
this.logger = logger;
output = new TaskOutputHelper(this, messenger, logger);
progress = new TaskProgressHelper(this, output);
}
public void start() {
if(!started) {
started = true;
taskManager.runTask(this);
}
}
public void run() {
taskThread = Thread.currentThread();
try {
status.setRunning();
status.setStartTime(System.currentTimeMillis());
output.changed();
/* run the tool */
runnableInstance.run(this);
status.setFinished();
output.changed();
} catch(TaskException e) {
String message = e.getMessage();
if (message == null) message = e.toString();
error(message);
status.setFailed();
output.changed();
} catch (Exception e) {
logger.warning("Unhandled exception in task running tool: " + this, e);
error("Unexpected error, please contact technical support.\n" + e);
status.setFailed();
output.changed();
}
}
public void cancel() {
canceled = true;
if(taskThread != null) {
taskThread.interrupt();
} else {
/*to trigger update in the client when scheduled tasks are canceled */
status.setFinished();
output.changed();
}
}
public void failed() {
logger.debug("Task failed: " + this);
status.setFailed();
/* Fill the progress bar. RunState is not changed on purpose */
status.updateElapsedTime();
output.changed();
}
boolean isStarted() {
return started;
}
/** Running Task methods */
public long getTaskId() {
return status.getTaskId();
}
// public long getProbeId() {
// return record.getProbeId();
// }
@Override
public String toString() {
return status.getTitle();
}
public TaskStatus getStatus() {
return status;
}
public IMessenger getMessenger() {
return output.getMessenger();
}
public void setMessenger(IMessenger messenger) {
output.setMessenger(messenger);
}
public void addMessage(ITaskOutput taskOutput) {
output.addMessage(taskOutput);
}
/** ITaskProgress interface, could be delegated */
public void setTotalWork(int totalWork) {
progress.setTotalWork(totalWork);
}
public void worked(int work) {
progress.worked(work);
}
public void done() {
progress.done();
}
public boolean isCanceled() {
if(taskThread != null && taskThread.isInterrupted()) {
canceled = true;
}
return canceled;
}
public void setTitle(String title) {
this.status.setTitle(title);
output.changed();
}
public void setStatus(String status) {
this.status.setStatus(status);
output.changed();
}
/* XXX Task Logging methods could be implemented in ITaskLogging interface and delegate*/
public void debug(String message) {
log(TaskLogOutput.DEBUG, message);
}
public void info(String message) {
log(TaskLogOutput.INFO, message);
}
public void warning(String message) {
log(TaskLogOutput.WARNING, message);
}
public void error(String message) {
log(TaskLogOutput.ERROR, message);
}
public void log(int logLevel, String message) {
addMessage(new TaskLogOutput(logLevel, message));
}
public void print(String message) {
addMessage(new TaskConsoleOutput(message));
}
public void exception(String message, Throwable throwable) {
final String output = message + "\n" + renderBacktrace(throwable);
addMessage(new TaskConsoleOutput(output));
}
private String renderBacktrace(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
if(throwable.getMessage() != null) {
pw.println(throwable.getMessage());
}
throwable.printStackTrace(pw);
pw.flush();
return sw.toString();
}
public String askPassword(String message) {
if(prompter == null) {
return null;
}
return prompter.askPassword(message);
}
public String askString(String message) {
if(prompter == null) {
return null;
}
return prompter.askString(message);
}
}