Add Task.preExecute and Task.postExecute

This commit is contained in:
huangyuhui
2018-09-05 20:38:00 +08:00
parent 151097a884
commit d8cb93c36a
3 changed files with 55 additions and 49 deletions

View File

@@ -23,12 +23,13 @@ import java.util.jar.Pack200;
import static org.jackhuang.hmcl.util.DigestUtils.digest; import static org.jackhuang.hmcl.util.DigestUtils.digest;
import static org.jackhuang.hmcl.util.Hex.encodeHex; import static org.jackhuang.hmcl.util.Hex.encodeHex;
public final class LibraryDownloadTask extends Task { public class LibraryDownloadTask extends Task {
private final LibraryDownloadTaskHelper helperTask; private FileDownloadTask task;
private final File jar; protected final File jar;
private final File xzFile; private final File xzFile;
private final Library library; protected final Library library;
private boolean xz; protected final String url;
protected boolean xz;
public LibraryDownloadTask(AbstractDependencyManager dependencyManager, File file, Library library) { public LibraryDownloadTask(AbstractDependencyManager dependencyManager, File file, Library library) {
setSignificance(TaskSignificance.MODERATE); setSignificance(TaskSignificance.MODERATE);
@@ -38,17 +39,15 @@ public final class LibraryDownloadTask extends Task {
this.library = library; this.library = library;
String url = dependencyManager.getDownloadProvider().injectURL(library.getDownload().getUrl()); url = dependencyManager.getDownloadProvider().injectURL(library.getDownload().getUrl());
jar = file; jar = file;
xzFile = new File(file.getAbsoluteFile().getParentFile(), file.getName() + ".pack.xz"); xzFile = new File(file.getAbsoluteFile().getParentFile(), file.getName() + ".pack.xz");
helperTask = new LibraryDownloadTaskHelper(file, url);
} }
@Override @Override
public Collection<? extends Task> getDependents() { public Collection<? extends Task> getDependents() {
return Collections.singleton(helperTask); return Collections.singleton(task);
} }
@Override @Override
@@ -59,18 +58,13 @@ public final class LibraryDownloadTask extends Task {
@Override @Override
public void execute() throws Exception { public void execute() throws Exception {
if (!isDependentsSucceeded()) { if (!isDependentsSucceeded()) {
if (helperTask.task == null) { // Since FileDownloadTask wraps the actual exception with another IOException.
// NetworkUtils.URLExists failed. // We should extract it letting the error message clearer.
throw new LibraryDownloadException(library, helperTask.getLastException()); Throwable t = task.getLastException();
} else { if (t.getCause() != null)
// Since FileDownloadTask wraps the actual exception with another IOException. throw new LibraryDownloadException(library, t.getCause());
// We should extract it letting the error message clearer. else
Throwable t = helperTask.task.getLastException(); throw new LibraryDownloadException(library, t);
if (t.getCause() != null && t.getCause() != t)
throw new LibraryDownloadException(library, t.getCause());
else
throw new LibraryDownloadException(library, t);
}
} else { } else {
if (xz) unpackLibrary(jar, FileUtils.readBytes(xzFile)); if (xz) unpackLibrary(jar, FileUtils.readBytes(xzFile));
if (!checksumValid(jar, library.getChecksums())) { if (!checksumValid(jar, library.getChecksums())) {
@@ -80,44 +74,25 @@ public final class LibraryDownloadTask extends Task {
} }
} }
private class LibraryDownloadTaskHelper extends Task { @Override
private FileDownloadTask task; public void preExecute() throws Exception {
private final File file; try {
private final String url;
public LibraryDownloadTaskHelper(File file, String url) {
this.file = file;
this.url = url;
setName(library.getName());
}
@Override
public boolean isRelyingOnDependencies() {
return true;
}
@Override
public Collection<? extends Task> getDependencies() {
return Collections.singleton(task);
}
@Override
public void execute() throws Exception {
URL packXz = NetworkUtils.toURL(url + ".pack.xz"); URL packXz = NetworkUtils.toURL(url + ".pack.xz");
if (NetworkUtils.URLExists(packXz)) { if (NetworkUtils.URLExists(packXz)) {
task = new FileDownloadTask(packXz, xzFile, null); task = new FileDownloadTask(packXz, xzFile, null);
xz = true; xz = true;
} else { } else {
task = new FileDownloadTask(NetworkUtils.toURL(url), task = new FileDownloadTask(NetworkUtils.toURL(url),
file, jar,
library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null); library.getDownload().getSha1() != null ? new IntegrityCheck("SHA-1", library.getDownload().getSha1()) : null);
xz = false; xz = false;
} }
} catch (IOException e) {
throw new LibraryDownloadException(library, e);
} }
} }
private static boolean checksumValid(File libPath, List<String> checksums) { public static boolean checksumValid(File libPath, List<String> checksums) {
try { try {
if (checksums == null || checksums.isEmpty()) { if (checksums == null || checksums.isEmpty()) {
return true; return true;

View File

@@ -129,12 +129,25 @@ public abstract class Task {
this.variables = variables; this.variables = variables;
} }
/**
* @throws InterruptedException if current thread is interrupted
* @see Thread#isInterrupted
*/
public void preExecute() throws Exception {}
/** /**
* @throws InterruptedException if current thread is interrupted * @throws InterruptedException if current thread is interrupted
* @see Thread#isInterrupted * @see Thread#isInterrupted
*/ */
public abstract void execute() throws Exception; public abstract void execute() throws Exception;
/**
* @throws InterruptedException if current thread is interrupted
* @see Thread#isInterrupted
*/
public void postExecute() throws Exception {}
/** /**
* The collection of sub-tasks that should execute **before** this task running. * The collection of sub-tasks that should execute **before** this task running.
*/ */

View File

@@ -141,6 +141,17 @@ public final class TaskExecutor {
boolean flag = false; boolean flag = false;
try { try {
task.setVariables(variables);
try {
task.getScheduler().schedule(task::preExecute).get();
} catch (ExecutionException e) {
if (e.getCause() instanceof Exception)
throw (Exception) e.getCause();
else
throw e;
}
boolean doDependentsSucceeded = executeTasks(task.getDependents()); boolean doDependentsSucceeded = executeTasks(task.getDependents());
if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled) if (!doDependentsSucceeded && task.isRelyingOnDependents() || canceled)
throw new SilentException(); throw new SilentException();
@@ -148,8 +159,6 @@ public final class TaskExecutor {
if (doDependentsSucceeded) if (doDependentsSucceeded)
task.setDependentsSucceeded(); task.setDependentsSucceeded();
task.setVariables(variables);
task.setState(Task.TaskState.RUNNING); task.setState(Task.TaskState.RUNNING);
taskListeners.forEach(it -> it.onRunning(task)); taskListeners.forEach(it -> it.onRunning(task));
@@ -174,6 +183,15 @@ public final class TaskExecutor {
throw new SilentException(); throw new SilentException();
} }
try {
task.getScheduler().schedule(task::postExecute).get();
} catch (ExecutionException e) {
if (e.getCause() instanceof Exception)
throw (Exception) e.getCause();
else
throw e;
}
flag = true; flag = true;
if (task.getSignificance().shouldLog()) { if (task.getSignificance().shouldLog()) {
Logging.LOG.log(Level.FINER, "Task finished: " + task.getName()); Logging.LOG.log(Level.FINER, "Task finished: " + task.getName());