in compat/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultWagonManager.java [304:473]
public void getRemoteFile(
ArtifactRepository repository,
File destination,
String remotePath,
TransferListener downloadMonitor,
String checksumPolicy,
boolean force)
throws TransferFailedException, ResourceDoesNotExistException {
String protocol = repository.getProtocol();
Wagon wagon;
try {
wagon = getWagon(protocol);
} catch (UnsupportedProtocolException e) {
throw new TransferFailedException("Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e);
}
if (downloadMonitor != null) {
wagon.addTransferListener(downloadMonitor);
}
File temp = new File(destination + ".tmp");
temp.deleteOnExit();
boolean downloaded = false;
try {
connectWagon(wagon, repository);
boolean firstRun = true;
boolean retry = true;
// this will run at most twice. The first time, the firstRun flag is turned off, and if the retry flag
// is set on the first run, it will be turned off and not re-set on the second try. This is because the
// only way the retry flag can be set is if ( firstRun == true ).
while (firstRun || retry) {
ChecksumObserver md5ChecksumObserver = null;
ChecksumObserver sha1ChecksumObserver = null;
try {
// TODO configure on repository
md5ChecksumObserver = addChecksumObserver(wagon, "MD5");
sha1ChecksumObserver = addChecksumObserver(wagon, "SHA-1");
// reset the retry flag.
retry = false;
// This should take care of creating destination directory now on
if (destination.exists() && !force) {
try {
downloaded = wagon.getIfNewer(remotePath, temp, destination.lastModified());
if (!downloaded) {
// prevent additional checks of this artifact until it expires again
destination.setLastModified(System.currentTimeMillis());
}
} catch (UnsupportedOperationException e) {
// older wagons throw this. Just get() instead
wagon.get(remotePath, temp);
downloaded = true;
}
} else {
wagon.get(remotePath, temp);
downloaded = true;
}
} finally {
wagon.removeTransferListener(md5ChecksumObserver);
wagon.removeTransferListener(sha1ChecksumObserver);
}
if (downloaded) {
// keep the checksum files from showing up on the download monitor...
if (downloadMonitor != null) {
wagon.removeTransferListener(downloadMonitor);
}
// try to verify the SHA-1 checksum for this file.
try {
verifyChecksum(sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon);
} catch (ChecksumFailedException e) {
// if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the
// checksum doesn't match. This could be a problem with the server (ibiblio HTTP-200 error
// page), so we'll try this up to two times. On the second try, we'll handle it as a bona-fide
// error, based on the repository's checksum checking policy.
if (firstRun) {
logger.warn("*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING");
retry = true;
} else {
handleChecksumFailure(checksumPolicy, e.getMessage(), e.getCause());
}
} catch (ResourceDoesNotExistException sha1TryException) {
logger.debug("SHA1 not found, trying MD5: " + sha1TryException.getMessage());
// if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum
// file...we'll try again with the MD5 checksum.
try {
verifyChecksum(md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon);
} catch (ChecksumFailedException e) {
// if we also fail to verify based on the MD5 checksum, and the checksum transfer/read
// succeeded, then we need to determine whether to retry or handle it as a failure.
if (firstRun) {
retry = true;
} else {
handleChecksumFailure(checksumPolicy, e.getMessage(), e.getCause());
}
} catch (ResourceDoesNotExistException md5TryException) {
// this was a failed transfer, and we don't want to retry.
handleChecksumFailure(
checksumPolicy,
"Error retrieving checksum file for " + remotePath,
md5TryException);
}
}
// reinstate the download monitor...
if (downloadMonitor != null) {
wagon.addTransferListener(downloadMonitor);
}
}
// unset the firstRun flag, so we don't get caught in an infinite loop...
firstRun = false;
}
} catch (ConnectionException e) {
throw new TransferFailedException("Connection failed: " + e.getMessage(), e);
} catch (AuthenticationException e) {
throw new TransferFailedException("Authentication failed: " + e.getMessage(), e);
} catch (AuthorizationException e) {
throw new TransferFailedException("Authorization failed: " + e.getMessage(), e);
} finally {
// Remove remaining TransferListener instances (checksum handlers removed in above finally clause)
if (downloadMonitor != null) {
wagon.removeTransferListener(downloadMonitor);
}
disconnectWagon(wagon);
releaseWagon(protocol, wagon);
}
if (downloaded) {
if (!temp.exists()) {
throw new ResourceDoesNotExistException("Downloaded file does not exist: " + temp);
}
// The temporary file is named destination + ".tmp" and is done this way to ensure
// that the temporary file is in the same file system as the destination because the
// File.renameTo operation doesn't really work across file systems.
// So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails
// then we will use a brute force copy and delete the temporary file.
if (!temp.renameTo(destination)) {
try {
Files.copy(
temp.toPath(),
destination.toPath(),
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
if (!temp.delete()) {
temp.deleteOnExit();
}
} catch (IOException e) {
throw new TransferFailedException(
"Error copying temporary file to the final destination: " + e.getMessage(), e);
}
}
}
}