transferProgress), getObjectRequest.getProgressListener());
getObjectRequest.setProgressListener(listenerChain);
final ObjectMetadata objectMetadata = s3.getObjectMetadata(getObjectRequest.getBucketName(), getObjectRequest.getKey());
final StartDownloadLock startDownloadLock = new StartDownloadLock();
final DownloadImpl download = new DownloadImpl(description, transferProgress, listenerChain, null, stateListener);
long contentLength = objectMetadata.getContentLength();
if (getObjectRequest.getRange() != null && getObjectRequest.getRange().length == 2) {
long startingByte = getObjectRequest.getRange()[0];
long lastByte = getObjectRequest.getRange()[1];
contentLength = lastByte - startingByte;
}
transferProgress.setTotalBytesToTransfer(contentLength);
Future<?> future = threadPool.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
synchronized (startDownloadLock) {
if ( !startDownloadLock.downloadReady ) {
try {
startDownloadLock.wait();
} catch ( InterruptedException e ) {
throw new AmazonClientException("Couldn't wait for setting future into the monitor");
}
}
}
download.setState(TransferState.InProgress);
S3Object s3Object = ServiceUtils.retryableDownloadS3ObjectToFile(file, new ServiceUtils.RetryableS3DownloadTask() {
@Override
public S3Object getS3ObjectStream() {
S3Object s3Object = s3.getObject(getObjectRequest);
download.setS3Object(s3Object);
return s3Object;
}
@Override
public boolean needIntegrityCheck() {
// Don't perform the integrity check if the stream data is wrapped
// in a decryption stream, or if we're only looking at a range of
// the data, since otherwise the checksum won't match up.
boolean performIntegrityCheck = true;
if (getObjectRequest.getRange() != null) performIntegrityCheck = false;
if (s3 instanceof AmazonS3EncryptionClient) performIntegrityCheck = false;
return performIntegrityCheck;
}
});
if (s3Object == null) {
download.setState(TransferState.Canceled);
download.setMonitor(new DownloadMonitor(download, null));
return download;
}
download.setState(TransferState.Completed);
return true;
} catch (Exception e) {
// Downloads aren't allowed to move from canceled to failed
if (download.getState() != TransferState.Canceled) {
download.setState(TransferState.Failed);
}
throw e;
}
}
});
download.setMonitor(new DownloadMonitor(download, future));
synchronized (startDownloadLock) {
startDownloadLock.downloadReady = true;
startDownloadLock.notify();
}
return download;