/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.common.taskrunner;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.ResultHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class TaskRunner<T extends Model> {
private static final Logger log = LoggerFactory.getLogger(TaskRunner.class);
private final Queue<Class<? extends Task>> tasks = new LinkedBlockingQueue<>();
private final T sharedModel;
private final Class<T> sharedModelClass;
private final ResultHandler resultHandler;
private final ErrorMessageHandler errorMessageHandler;
private boolean failed = false;
private boolean isCanceled;
private Class<? extends Task> currentTask;
public TaskRunner(T sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
this(sharedModel, (Class<T>) sharedModel.getClass(), resultHandler, errorMessageHandler);
}
public TaskRunner(T sharedModel, Class<T> sharedModelClass, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
this.sharedModel = sharedModel;
this.resultHandler = resultHandler;
this.errorMessageHandler = errorMessageHandler;
this.sharedModelClass = sharedModelClass;
}
public final void addTasks(Class<? extends Task<T>>... items) {
tasks.addAll(Arrays.asList(items));
}
public void run() {
next();
}
private void next() {
if (!failed && !isCanceled) {
if (tasks.size() > 0) {
try {
currentTask = tasks.poll();
log.trace("Run task: " + currentTask.getSimpleName());
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModelClass).newInstance(this, sharedModel).run();
} catch (Throwable throwable) {
throwable.printStackTrace();
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
}
} else {
resultHandler.handleResult();
}
}
}
public void cancel() {
isCanceled = true;
}
void handleComplete() {
log.trace("Task completed: " + currentTask.getSimpleName());
sharedModel.persist();
next();
}
void handleErrorMessage(String errorMessage) {
log.error("Task failed: " + currentTask.getSimpleName() + " / errorMessage: " + errorMessage);
failed = true;
errorMessageHandler.handleErrorMessage(errorMessage);
}
}