package jadx.gui.jobs;
import jadx.gui.JadxWrapper;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class BackgroundJob {
private static final Logger LOG = LoggerFactory.getLogger(DecompileJob.class);
protected final JadxWrapper wrapper;
private final ThreadPoolExecutor executor;
private Future<Boolean> future;
public BackgroundJob(JadxWrapper wrapper, int threadsCount) {
this.wrapper = wrapper;
this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadsCount);
}
public synchronized Future<Boolean> process() {
if (future != null) {
return future;
}
ExecutorService shutdownExecutor = Executors.newSingleThreadExecutor();
FutureTask<Boolean> task = new ShutdownTask();
shutdownExecutor.execute(task);
shutdownExecutor.shutdown();
future = task;
return future;
}
private class ShutdownTask extends FutureTask<Boolean> {
public ShutdownTask() {
super(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
runJob();
executor.shutdown();
return executor.awaitTermination(5, TimeUnit.MINUTES);
}
});
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
executor.shutdownNow();
return super.cancel(mayInterruptIfRunning);
}
}
protected abstract void runJob();
public abstract String getInfoString();
protected void addTask(Runnable runnable) {
executor.execute(runnable);
}
public void processAndWait() {
try {
process().get();
} catch (Exception e) {
LOG.error("BackgroundJob.processAndWait failed", e);
}
}
public synchronized boolean isComplete() {
try {
return future != null && future.isDone();
} catch (Exception e) {
LOG.error("BackgroundJob.isComplete failed", e);
return false;
}
}
public int getProgress() {
return (int) (executor.getCompletedTaskCount() * 100 / (double) executor.getTaskCount());
}
}