public void getRemoteFile()

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);
                }
            }
        }
    }