package aQute.bnd.util.repository;
import java.io.File;
import java.io.FileNotFoundException;
import org.osgi.util.promise.Failure;
import org.osgi.util.promise.Promise;
import org.osgi.util.promise.Success;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import aQute.bnd.service.RepositoryPlugin;
import aQute.bnd.service.RepositoryPlugin.DownloadListener;
import aQute.lib.exceptions.Exceptions;
import aQute.lib.io.IO;
import aQute.libg.reporter.slf4j.Slf4jReporter;
import aQute.service.reporter.Reporter;
/**
* Uses promises to signal the Download Listener from {@link RepositoryPlugin}
*/
public class DownloadListenerPromise implements Success<File,Void>, Failure {
private final static Logger logger = LoggerFactory.getLogger(DownloadListenerPromise.class);
final DownloadListener dls[];
final Promise<File> promise;
private final Reporter reporter;
private final String task;
private File linked;
/**
* Use the promise to signal the Download Listeners
*
* @param reporter a reporter or null (will use a SLF4 in that case)
* @param task
* @param promise
* @param downloadListeners
*/
public DownloadListenerPromise(Reporter reporter, String task, Promise<File> promise,
DownloadListener... downloadListeners) {
this.reporter = Slf4jReporter.getAlternative(DownloadListenerPromise.class, reporter);
this.task = task;
this.promise = promise;
this.dls = downloadListeners;
logger.debug("{}: starting", task);
promise.then(this).then(null, this);
}
@Override
public Promise<Void> call(Promise<File> resolved) throws Exception {
File file = resolved.getValue();
if (file == null) {
throw new FileNotFoundException("Download failed");
}
logger.debug("{}: success {}", this, file);
if (linked != null) {
IO.createSymbolicLinkOrCopy(linked, file);
}
for (DownloadListener dl : dls) {
try {
dl.success(file);
} catch (Throwable e) {
reporter.warning("%s: Success callback failed to %s: %s", this, dl, e);
}
}
return null;
}
@Override
public void fail(Promise< ? > resolved) throws Exception {
Throwable failure = resolved.getFailure();
logger.debug("{}: failure", this, failure);
String reason = Exceptions.toString(failure);
for (DownloadListener dl : dls) {
try {
dl.failure(null, reason);
} catch (Throwable e) {
reporter.warning("%s: Fail callback failed to %s: %s", this, dl, e);
}
}
}
@Override
public String toString() {
return task;
}
public void linkTo(File linked) {
this.linked = linked;
}
}