Example usage for java.nio.file Path getNameCount

List of usage examples for java.nio.file Path getNameCount

Introduction

In this page you can find the example usage for java.nio.file Path getNameCount.

Prototype

int getNameCount();

Source Link

Document

Returns the number of name elements in the path.

Usage

From source file:org.apache.openaz.xacml.pdp.test.TestBase.java

/**
 * This processes a response. Saves the response out to disk. If there is a corresponding response file
 * for the request located in the "responses" sub-directory, then this method will compare that response
 * file with what the engine returned to see if it matched.
 *
 * @param requestFile//from   w w w. j av a2 s.  co  m
 * @param request
 * @param response
 * @param group
 * @param count
 * @throws Exception
 */
protected void processResponse(Path requestFile, Request request, Response response, String group, int count)
        throws Exception {
    //
    // Construct the output filename
    //
    Path responseFile = null;
    Path resultFile = null;
    int num = requestFile.getNameCount();
    if (num < 2) {
        logger.error("Too few dir's in request filename.");
        throw new Exception(
                "Too few dir's in request filename. Format should be Request.[0-9]+.{Permit|Deny|NA|Indeterminate}.{json|xml}");
    }
    String filename = requestFile.getFileName().toString();
    if (group.equals("Generate")) {
        //
        // Using count variable, construct a filename
        //
        // i.e. Response.03.Generate.{count}.json
        //
        filename = "Response" + filename.substring(filename.indexOf('.'), filename.lastIndexOf('.'))
                + String.format("%03d", count) + filename.substring(filename.lastIndexOf('.'));
    } else {
        //
        // Construct filename
        //
        filename = "Response" + filename.substring(filename.indexOf('.'));
    }
    //
    // Determine equivalent response file path
    //
    responseFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "responses");
    if (Files.notExists(responseFile)) {
        //
        // Create it
        //
        logger.warn(responseFile.toString() + " does NOT exist, creating...");
        try {
            Files.createDirectories(responseFile);
        } catch (IOException e) {
            logger.error(e);
            throw new Exception("Cannot proceed without an output directory.");
        }
    }
    responseFile = Paths.get(responseFile.toString(), filename);
    //
    // Determine path to write result file
    //
    if (this.output != null) {
        //
        // User specified an output path
        //
        resultFile = this.output;
    } else {
        //
        // Default path
        //
        resultFile = Paths.get(requestFile.subpath(0, num - 2).toString(), "results");
    }
    //
    // Check if the path exists
    //
    if (Files.notExists(resultFile)) {
        //
        // Create it
        //
        logger.warn(resultFile.toString() + " does NOT exist, creating...");
        try {
            Files.createDirectories(resultFile);
        } catch (IOException e) {
            logger.error(e);
            throw new Exception("Cannot proceed without an output directory.");
        }
    }
    //
    // Add the filename to the path
    //
    resultFile = Paths.get(resultFile.toString(), filename);
    //
    // Check if there is an equivalent response in the response
    // directory. If so, compare our response result with that one.
    //
    boolean succeeded = true;
    if (responseFile != null && Files.exists(responseFile)) {
        //
        // Do comparison
        //
        Response expectedResponse = null;
        if (TestBase.isJSON(responseFile)) {
            expectedResponse = JSONResponse.load(responseFile);
        } else if (TestBase.isXML(responseFile)) {
            expectedResponse = DOMResponse.load(responseFile);
        }
        if (expectedResponse != null) {
            //
            // Do the compare
            //
            if (response == null) {
                logger.error("NULL response returned.");
                this.responseNotMatches++;
                succeeded = false;
            } else {
                if (response.equals(expectedResponse)) {
                    logger.info("Response matches expected response.");
                    this.responseMatches++;
                } else {
                    logger.error("Response does not match expected response.");
                    logger.error("Expected: ");
                    logger.error(expectedResponse.toString());
                    this.responseNotMatches++;
                    succeeded = false;
                }
            }
        }
    }
    //
    // Write the response to the result file
    //
    logger.info("Request: " + requestFile.getFileName() + " response is: "
            + (response == null ? "null" : response.toString()));
    if (resultFile != null && response != null) {
        if (TestBase.isJSON(resultFile)) {
            Files.write(resultFile, JSONResponse.toString(response, true).getBytes());
        } else if (TestBase.isXML(resultFile)) {
            Files.write(resultFile, DOMResponse.toString(response, true).getBytes());
        }
    }
    //
    // Stats
    //
    if (group.equals("Permit")) {
        this.expectedPermits++;
    } else if (group.equals("Deny")) {
        this.expectedDenies++;
    } else if (group.equals("NA")) {
        this.expectedNotApplicables++;
    } else if (group.equals("Indeterminate")) {
        this.expectedIndeterminates++;
    }
    if (response != null) {
        for (Result result : response.getResults()) {
            Decision decision = result.getDecision();
            if (group.equals("Generate")) {
                if (decision.equals(Decision.PERMIT)) {
                    this.generatedpermits++;
                } else if (decision.equals(Decision.DENY)) {
                    this.generateddenies++;
                } else if (decision.equals(Decision.NOTAPPLICABLE)) {
                    this.generatednotapplicables++;
                } else if (decision.equals(Decision.INDETERMINATE)) {
                    this.generatedindeterminates++;
                }
                continue;
            }
            if (decision.equals(Decision.PERMIT)) {
                this.permits++;
                if (!group.equals("Permit")) {
                    succeeded = false;
                    logger.error("Expected " + group + " got " + decision);
                }
            } else if (decision.equals(Decision.DENY)) {
                this.denies++;
                if (!group.equals("Deny")) {
                    succeeded = false;
                    logger.error("Expected " + group + " got " + decision);
                }
            } else if (decision.equals(Decision.NOTAPPLICABLE)) {
                this.notapplicables++;
                if (!group.equals("NA")) {
                    succeeded = false;
                    logger.error("Expected " + group + " got " + decision);
                }
            } else if (decision.equals(Decision.INDETERMINATE)) {
                this.indeterminates++;
                if (!group.equals("Indeterminate")) {
                    succeeded = false;
                    logger.error("Expected " + group + " got " + decision);
                }
            }
        }
    }
    if (succeeded) {
        logger.info("REQUEST SUCCEEDED");
    } else {
        logger.info("REQUEST FAILED");
    }
}

From source file:org.sleuthkit.autopsy.experimental.autoingest.SingleUserCaseImporter.java

/**
 * This causes iteration over all .aut files in the baseCaseInput path,
 * calling SingleUserCaseConverter.importCase() for each one.
 *///  w w  w  . j  av a2  s.  c o  m
public void importCases() throws Exception {
    openLog(baseCaseOutput.toFile());
    log(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.StartingBatch")
            + baseCaseInput.toString() + " "
            + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
            + baseCaseOutput.toString()); //NON-NLS

    // iterate for .aut files
    FindDotAutFolders dotAutFolders = new FindDotAutFolders();
    try {
        Path walked = Files.walkFileTree(baseCaseInput, dotAutFolders);
    } catch (IOException ex) {
        log(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.ErrorFindingAutFiles")
                + " " + ex.getMessage()); //NON-NLS
    }

    ArrayList<ImportCaseData> ableToProcess = new ArrayList<>();
    ArrayList<ImportCaseData> unableToProcess = new ArrayList<>();

    SingleUserCaseConverter scc = new SingleUserCaseConverter();

    // validate we can convert the .aut file, one by one
    for (FoundAutFile f : dotAutFolders.getCandidateList()) {
        this.oldCaseName = f.getPath().getFileName().toString();

        // Test image output folder for uniqueness, find a unique folder for it if we can
        File specificOutputFolder = baseImageOutput.resolve(oldCaseName).toFile();
        String newImageName = oldCaseName;
        if (specificOutputFolder.exists()) {
            // Not unique. add numbers before timestamp to specific image output name
            String timeStamp = TimeStampUtils.getTimeStampOnly(oldCaseName);
            newImageName = TimeStampUtils.removeTimeStamp(oldCaseName);
            int number = 1;
            String temp = ""; //NON-NLS
            while (specificOutputFolder.exists()) {
                if (number == Integer.MAX_VALUE) {
                    // It never became unique, so give up.
                    throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class,
                            "SingleUserCaseImporter.NonUniqueOutputFolder") + newImageName); //NON-NLS
                }
                temp = newImageName + "_" + Integer.toString(number) + timeStamp; //NON-NLS
                specificOutputFolder = baseImageOutput.resolve(temp).toFile();
                ++number;
            }
            newImageName = temp;
        }
        Path imageOutput = baseImageOutput.resolve(newImageName);
        imageOutput.toFile().mkdirs(); // Create image output folder

        // Test case output folder for uniqueness, find a unique folder for it if we can
        specificOutputFolder = baseCaseOutput.resolve(oldCaseName).toFile();
        newCaseName = oldCaseName;
        if (specificOutputFolder.exists()) {
            // not unique. add numbers before timestamp to specific case output name
            String timeStamp = TimeStampUtils.getTimeStampOnly(oldCaseName); //NON-NLS
            newCaseName = TimeStampUtils.removeTimeStamp(oldCaseName);
            int number = 1;
            String temp = ""; //NON-NLS
            while (specificOutputFolder.exists()) {
                if (number == Integer.MAX_VALUE) {
                    // It never became unique, so give up.
                    throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class,
                            "SingleUserCaseImporter.NonUniqueOutputFolder") + newCaseName); //NON-NLS
                }
                temp = newCaseName + "_" + Integer.toString(number) + timeStamp; //NON-NLS
                specificOutputFolder = baseCaseOutput.resolve(temp).toFile();
                ++number;
            }
            newCaseName = temp;
        }
        Path caseOutput = baseCaseOutput.resolve(newCaseName);
        caseOutput.toFile().mkdirs(); // Create case output folder

        /**
         * Test if the input path has a corresponding image input folder and
         * no repeated case names in the path. If both of these conditions
         * are true, we can process this case, otherwise not.
         */
        // Check that there is an image folder if they are trying to copy it
        boolean canProcess = true;
        Path imageInput = null;
        String relativeCaseName = TimeStampUtils
                .removeTimeStamp(baseCaseInput.relativize(f.getPath()).toString());
        Path testImageInputsFromOldCase = Paths.get(baseImageInput.toString(), relativeCaseName);
        if (copyImages) {
            if (!testImageInputsFromOldCase.toFile().isDirectory()) {
                // Mark that we are unable to process this item
                canProcess = false;
            } else {
                imageInput = testImageInputsFromOldCase;
            }
            if (imageInput == null) {
                throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class,
                        "SingleUserCaseImporter.SourceImageMissing") + " " + f.getPath()); //NON-NLS
            }

            // If case name is in the image path, it causes bad things to happen with the parsing. Test for this.
            for (int x = 0; x < imageInput.getNameCount(); ++x) {
                if (oldCaseName.toLowerCase().equals(imageInput.getName(x).toString().toLowerCase())) {
                    // Mark that we are unable to process this item
                    canProcess = false;
                }
            }
        } else {
            imageInput = testImageInputsFromOldCase;
        }

        // Create an Import Case Data object for this case
        SingleUserCaseConverter.ImportCaseData icd = scc.new ImportCaseData(imageInput, f.getPath(),
                imageOutput, caseOutput, oldCaseName, newCaseName, f.getAutFile().toString(),
                f.getFolderName().toString(), copyImages, deleteCase);

        if (canProcess) {
            ableToProcess.add(icd);
        } else {
            unableToProcess.add(icd);
        }
    }

    // Create text to be populated in the confirmation dialog
    StringBuilder casesThatWillBeProcessed = new StringBuilder();
    StringBuilder casesThatWillNotBeProcessed = new StringBuilder();

    casesThatWillBeProcessed
            .append(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.WillImport"))
            .append(SEP); // NON-NLS
    if (ableToProcess.isEmpty()) {
        casesThatWillBeProcessed
                .append(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.None"))
                .append(SEP); // NON-NLS
    } else {
        for (ImportCaseData i : ableToProcess) {
            casesThatWillBeProcessed.append(i.getCaseInputFolder().toString()).append(SEP);
        }
    }

    if (!unableToProcess.isEmpty()) {
        casesThatWillNotBeProcessed.append(
                NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.WillNotImport"))
                .append(SEP); // NON-NLS
        for (ImportCaseData i : unableToProcess) {
            casesThatWillNotBeProcessed.append(i.getCaseInputFolder().toString()).append(SEP);
        }
    }

    JTextArea jta = new JTextArea(
            casesThatWillBeProcessed.toString() + SEP + casesThatWillNotBeProcessed.toString());
    jta.setEditable(false);
    JScrollPane jsp = new JScrollPane(jta) {
        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(700, 480);
        }
    };

    // Show confirmation dialog
    SwingUtilities.invokeLater(() -> {
        userAnswer = JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), jsp,
                NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.ContinueWithImport"), // NON-NLS
                OK_CANCEL_OPTION);
        synchronized (threadWaitNotifyLock) {
            threadWaitNotifyLock.notify();
        }
    });

    // Wait while the user handles the confirmation dialog
    synchronized (threadWaitNotifyLock) {
        try {
            threadWaitNotifyLock.wait();
        } catch (InterruptedException ex) {
            Logger.getLogger(SingleUserCaseImporter.class.getName()).log(Level.SEVERE, "Threading Issue", ex); //NON-NLS
            throw new Exception(ex);
        }
    }

    // If the user wants to proceed, do so.
    if (userAnswer == JOptionPane.OK_OPTION) {
        boolean result = true; // if anything went wrong, result becomes false.
        // Feed .aut files in one by one for processing
        for (ImportCaseData i : ableToProcess) {
            try {
                log(NbBundle.getMessage(SingleUserCaseImporter.class,
                        "SingleUserCaseImporter.StartedProcessing") + i.getCaseInputFolder() + " "
                        + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
                        + i.getCaseOutputFolder()); //NON-NLS
                SingleUserCaseConverter.importCase(i);
                handleAutoIngestLog(i);
                log(NbBundle.getMessage(SingleUserCaseImporter.class,
                        "SingleUserCaseImporter.FinishedProcessing") + i.getCaseInputFolder() + " "
                        + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
                        + i.getCaseOutputFolder()); //NON-NLS

            } catch (Exception ex) {
                log(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.FailedToComplete")
                        + i.getCaseInputFolder() + " "
                        + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
                        + i.getCaseOutputFolder() + " " + ex.getMessage()); //NON-NLS
                result = false;
            }
        }

        log(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.CompletedBatch")
                + baseCaseInput.toString() + " "
                + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
                + baseCaseOutput.toString()); //NON-NLS

        closeLog();
        if (notifyOnComplete != null) {
            notifyOnComplete.importDoneCallback(result, ""); // NON-NLS
        }
    } else {
        // The user clicked cancel. Abort.
        log(NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.AbortingBatch")
                + baseCaseInput.toString() + " "
                + NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.to") + " "
                + baseCaseOutput.toString()); //NON-NLS

        closeLog();
        if (notifyOnComplete != null) {
            notifyOnComplete.importDoneCallback(false,
                    NbBundle.getMessage(SingleUserCaseImporter.class, "SingleUserCaseImporter.Cancelled")); // NON-NLS
        }
    }
}

From source file:org.ballerinalang.util.parser.antlr4.BLangAntlr4Listener.java

public BLangAntlr4Listener(BLangModelBuilder modelBuilder, Path sourceFilePath) {
    this.modelBuilder = modelBuilder;
    this.fileName = sourceFilePath.getFileName().toString();

    if (sourceFilePath.getNameCount() >= 2) {
        this.packageDirPath = sourceFilePath.subpath(0, sourceFilePath.getNameCount() - 1).toString();
    } else {/*from  ww w.ja va2  s.c  o  m*/
        this.packageDirPath = null;
    }
}

From source file:org.apache.nifi.controller.repository.FileSystemRepository.java

private void removeIncompleteContent(final String containerName, final Path containerPath,
        final Path fileToRemove) {
    if (Files.isDirectory(fileToRemove)) {
        final Path lastPathName = fileToRemove.subpath(1, fileToRemove.getNameCount());
        final String fileName = lastPathName.toFile().getName();
        if (fileName.equals(ARCHIVE_DIR_NAME)) {
            return;
        }/*from   w  w  w .j  av  a  2  s  .c o m*/

        final File[] children = fileToRemove.toFile().listFiles();
        if (children != null) {
            for (final File child : children) {
                removeIncompleteContent(containerName, containerPath, child.toPath());
            }
        }

        return;
    }

    final Path relativePath = containerPath.relativize(fileToRemove);
    final Path sectionPath = relativePath.subpath(0, 1);
    if (relativePath.getNameCount() < 2) {
        return;
    }

    final Path idPath = relativePath.subpath(1, relativePath.getNameCount());
    final String id = idPath.toFile().getName();
    final String sectionName = sectionPath.toFile().getName();

    final ResourceClaim resourceClaim = resourceClaimManager.newResourceClaim(containerName, sectionName, id,
            false, false);
    if (resourceClaimManager.getClaimantCount(resourceClaim) == 0) {
        removeIncompleteContent(fileToRemove);
    }
}

From source file:org.apache.nifi.controller.repository.FileSystemRepository.java

private synchronized void initializeRepository() throws IOException {
    final Map<String, Path> realPathMap = new HashMap<>();
    final ExecutorService executor = Executors.newFixedThreadPool(containers.size());
    final List<Future<Long>> futures = new ArrayList<>();

    // Run through each of the containers. For each container, create the sections if necessary.
    // Then, we need to scan through the archived data so that we can determine what the oldest
    // archived data is, so that we know when we have to start aging data off.
    for (final Map.Entry<String, Path> container : containers.entrySet()) {
        final String containerName = container.getKey();
        final ContainerState containerState = containerStateMap.get(containerName);
        final Path containerPath = container.getValue();
        final boolean pathExists = Files.exists(containerPath);

        final Path realPath;
        if (pathExists) {
            realPath = containerPath.toRealPath();
        } else {/*w w  w .j a  v  a2  s .co m*/
            realPath = Files.createDirectories(containerPath).toRealPath();
        }

        for (int i = 0; i < SECTIONS_PER_CONTAINER; i++) {
            Files.createDirectories(realPath.resolve(String.valueOf(i)));
        }

        realPathMap.put(containerName, realPath);

        // We need to scan the archive directories to find out the oldest timestamp so that know whether or not we
        // will have to delete archived data based on time threshold. Scanning all of the directories can be very
        // expensive because of all of the disk accesses. So we do this in multiple threads. Since containers are
        // often unique to a disk, we just map 1 thread to each container.
        final Callable<Long> scanContainer = new Callable<Long>() {
            @Override
            public Long call() throws IOException {
                final AtomicLong oldestDateHolder = new AtomicLong(0L);

                // the path already exists, so scan the path to find any files and update maxIndex to the max of
                // all filenames seen.
                Files.walkFileTree(realPath, new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                        LOG.warn("Content repository contains un-readable file or directory '"
                                + file.getFileName() + "'. Skipping. ", exc);
                        return FileVisitResult.SKIP_SUBTREE;
                    }

                    @Override
                    public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
                            throws IOException {
                        if (attrs.isDirectory()) {
                            return FileVisitResult.CONTINUE;
                        }

                        // Check if this is an 'archive' directory
                        final Path relativePath = realPath.relativize(file);
                        if (relativePath.getNameCount() > 3
                                && ARCHIVE_DIR_NAME.equals(relativePath.subpath(1, 2).toString())) {
                            final long lastModifiedTime = getLastModTime(file);

                            if (lastModifiedTime < oldestDateHolder.get()) {
                                oldestDateHolder.set(lastModifiedTime);
                            }
                            containerState.incrementArchiveCount();
                        }

                        return FileVisitResult.CONTINUE;
                    }
                });

                return oldestDateHolder.get();
            }
        };

        // If the path didn't exist to begin with, there's no archive directory, so don't bother scanning.
        if (pathExists) {
            futures.add(executor.submit(scanContainer));
        }
    }

    executor.shutdown();
    for (final Future<Long> future : futures) {
        try {
            final Long oldestDate = future.get();
            if (oldestDate < oldestArchiveDate.get()) {
                oldestArchiveDate.set(oldestDate);
            }
        } catch (final ExecutionException | InterruptedException e) {
            if (e.getCause() instanceof IOException) {
                throw (IOException) e.getCause();
            } else {
                throw new RuntimeException(e);
            }
        }
    }

    containers.clear();
    containers.putAll(realPathMap);
}

From source file:com.github.podd.example.ExamplePoddClient.java

public Map<Path, String> uploadToStorage(final List<Path> bagsToUpload, final String sshServerFingerprint,
        final String sshHost, final int portNo, final String username, final Path pathToPublicKey,
        final Path localRootPath, final Path remoteRootPath, final PasswordFinder keyExtractor)
        throws PoddClientException, NoSuchAlgorithmException, IOException {
    final Map<Path, String> results = new ConcurrentHashMap<>();

    final ConcurrentMap<Path, ConcurrentMap<PoddDigestUtils.Algorithm, String>> digests = PoddDigestUtils
            .getDigests(bagsToUpload);/*from   w  w  w. ja va2s  .  c  o m*/

    try (SSHClient sshClient = new SSHClient(ExamplePoddClient.DEFAULT_CONFIG);) {
        sshClient.useCompression();
        sshClient.addHostKeyVerifier(sshServerFingerprint);
        sshClient.connect(sshHost, portNo);
        if (!Files.exists(pathToPublicKey)) {
            throw new PoddClientException("Could not find public key: " + pathToPublicKey);
        }
        if (!SecurityUtils.isBouncyCastleRegistered()) {
            throw new PoddClientException("Bouncy castle needed");
        }
        final FileKeyProvider rsa = new PKCS8KeyFile();
        rsa.init(pathToPublicKey.toFile(), keyExtractor);
        sshClient.authPublickey(username, rsa);
        // Session session = sshClient.startSession();
        try (SFTPClient sftp = sshClient.newSFTPClient();) {
            for (final Path nextBag : bagsToUpload) {
                // Check to make sure that the bag was under the local root path
                final Path localPath = nextBag.toAbsolutePath();
                if (!localPath.startsWith(localRootPath)) {
                    this.log.error(
                            "Local bag path was not a direct descendant of the local root path: {} {} {}",
                            localRootPath, nextBag, localPath);
                    throw new PoddClientException(
                            "Local bag path was not a direct descendant of the local root path: " + localPath
                                    + " " + localRootPath);
                }

                // Take the local root path out to get the subpath to use on the remote
                final Path remoteSubPath = localPath.subpath(localRootPath.getNameCount(),
                        nextBag.getNameCount() - 1);

                this.log.info("Remote sub path: {}", remoteSubPath);

                final Path remoteDirPath = remoteRootPath.resolve(remoteSubPath);
                this.log.info("Remote dir path: {}", remoteDirPath);

                final Path remoteBagPath = remoteDirPath.resolve(nextBag.getFileName());

                this.log.info("Remote bag path: {}", remoteBagPath);

                boolean fileFound = false;
                boolean sizeCorrect = false;
                try {
                    // check details of a remote bag
                    final FileAttributes attribs = sftp.lstat(remoteBagPath.toAbsolutePath().toString());
                    final long localSize = Files.size(nextBag);
                    final long remoteSize = attribs.getSize();

                    if (localSize <= 0) {
                        this.log.error("Local bag was empty: {}", nextBag);
                        sizeCorrect = false;
                        fileFound = false;
                    } else if (remoteSize <= 0) {
                        this.log.warn("Remote bag was empty: {} {}", nextBag, attribs);
                        sizeCorrect = false;
                        fileFound = false;
                    } else if (localSize == remoteSize) {
                        this.log.info("Found file on remote already with same size as local: {} {}", nextBag,
                                remoteBagPath);
                        sizeCorrect = true;
                        fileFound = true;
                    } else {
                        sizeCorrect = false;
                        fileFound = true;
                        // We always assume that a non-zero local file is correct
                        // The bags contain time-stamps that will be modified when they are
                        // regenerated, likely changing the file-size, and hopefully changing
                        // the digest checksums
                        // throw new PoddClientException(
                        // "Could not automatically compare file sizes (need manual intervention to delete one) : "
                        // + nextBag + " " + remoteBagPath + " localSize=" + localSize
                        // + " remoteSize=" + remoteSize);
                    }
                } catch (final IOException e) {
                    // lstat() throws an IOException if the file does not exist
                    // Ignore
                    sizeCorrect = false;
                    fileFound = false;
                }

                final ConcurrentMap<Algorithm, String> bagDigests = digests.get(nextBag);
                if (bagDigests.isEmpty()) {
                    this.log.error("No bag digests were generated for bag: {}", nextBag);
                }
                for (final Entry<Algorithm, String> entry : bagDigests.entrySet()) {
                    final Path localDigestPath = localPath
                            .resolveSibling(localPath.getFileName() + entry.getKey().getExtension());
                    // Create the local digest file
                    Files.copy(
                            new ReaderInputStream(new StringReader(entry.getValue()), StandardCharsets.UTF_8),
                            localDigestPath);
                    final Path remoteDigestPath = remoteBagPath
                            .resolveSibling(remoteBagPath.getFileName() + entry.getKey().getExtension());
                    boolean nextDigestFileFound = false;
                    boolean nextDigestCorrect = false;
                    try {
                        final Path tempFile = Files.createTempFile("podd-digest-",
                                entry.getKey().getExtension());
                        final SFTPFileTransfer sftpFileTransfer = new SFTPFileTransfer(sftp.getSFTPEngine());
                        sftpFileTransfer.download(remoteBagPath.toAbsolutePath().toString(),
                                tempFile.toAbsolutePath().toString());
                        nextDigestFileFound = true;

                        final List<String> allLines = Files.readAllLines(tempFile, StandardCharsets.UTF_8);
                        if (allLines.isEmpty()) {
                            nextDigestCorrect = false;
                        } else if (allLines.size() > 1) {
                            nextDigestCorrect = false;
                        }
                        // Check if the digests match exactly
                        else if (allLines.get(0).equals(entry.getValue())) {
                            nextDigestCorrect = true;
                        } else {
                            nextDigestCorrect = false;
                        }
                    } catch (final IOException e) {
                        nextDigestFileFound = false;
                        nextDigestCorrect = false;
                    }
                    if (nextDigestFileFound && nextDigestCorrect) {
                        this.log.info(
                                "Not copying digest to remote as it exists and contains the same content as the local digest");
                    } else if (nextDigestFileFound && !nextDigestCorrect) {
                        this.log.error("Found remote digest but content was not correct: {} {}",
                                localDigestPath, remoteDigestPath);
                        sftp.rm(remoteDigestPath.toString());
                        this.log.info("Copying digest to remote: {}", remoteDigestPath);
                        sftp.put(new FileSystemFile(localDigestPath.toString()), remoteDigestPath.toString());
                    } else if (!nextDigestFileFound) {
                        this.log.info("About to make directories on remote: {}", remoteDirPath);
                        sftp.mkdirs(remoteDirPath.toString());
                        this.log.info("Copying digest to remote: {}", remoteDigestPath);
                        sftp.put(new FileSystemFile(localDigestPath.toString()), remoteDigestPath.toString());
                    }
                }

                if (fileFound && sizeCorrect) {
                    this.log.info("Not copying bag to remote as it exists and is the same size as local bag");
                } else if (fileFound && !sizeCorrect) {
                    this.log.error("Found remote bag but size was not correct: {} {}", nextBag, remoteBagPath);
                    sftp.rm(remoteBagPath.toString());
                    this.log.info("Copying bag to remote: {}", remoteBagPath);
                    sftp.put(new FileSystemFile(localPath.toString()), remoteBagPath.toString());
                } else if (!fileFound) {
                    this.log.info("About to make directories on remote: {}", remoteDirPath);
                    sftp.mkdirs(remoteDirPath.toString());
                    this.log.info("Copying bag to remote: {}", remoteBagPath);
                    sftp.put(new FileSystemFile(localPath.toString()), remoteBagPath.toString());
                }

            }
        }
    } catch (final IOException e) {
        throw new PoddClientException("Could not copy a bag to the remote location", e);
    }

    return results;
}