net.sourceforge.jencrypt.lib.FolderList.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.jencrypt.lib.FolderList.java

Source

/*******************************************************************************
 * Copyright (c) 2013 "Ivo van Kamp"
 *
 * jEncrypt is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package net.sourceforge.jencrypt.lib;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.io.filefilter.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

/**
 * This class contains methods to retrieve all subdirectories from a given
 * folder and store the paths of all files relative to and including this
 * folder.
 */
public class FolderList {

    private File topFolder;
    private String archiveTopFolder;

    private Collection<File> fileTree;
    private Collection<String> fileStringTree;

    private Collection<File> folderTree;
    private Collection<String> folderStringTree;

    public FolderList(String topFolderString) {

        // Make relative pathname absolute
        topFolder = new File(new File(topFolderString).getAbsolutePath());

        // If the path ends in a dot the archive will not have a top folder.
        if (topFolderString.charAt(topFolderString.length() - 1) == '.') {

            // Make the archive top folder equal to the top folder (i.e. don't
            // use an archive top folder)
            archiveTopFolder = topFolder.getPath();

        } else {

            if (topFolder.isDirectory()) {
                archiveTopFolder = getParent(topFolder);
            } else
                throw new IllegalArgumentException("Parameter " + topFolder.getName() + " is not a folder");
        }
        // Normalize (remove double and single dot path steps)
        archiveTopFolder = FilenameUtils.normalize(archiveTopFolder);
    }

    /**
     * Return the parent folder or the drive letter on Windows systems
     */
    private String getParent(File topFolder) {

        File topFolderParent = topFolder.getParentFile();

        if (topFolderParent == null) {
            return FilenameUtils.getPrefix(topFolder.getAbsolutePath());
        } else
            return topFolderParent.getPath();
    }

    public String getArchiveTopFolder() {
        return archiveTopFolder;
    }

    public Collection<File> getFolderTree() {
        if (folderTree == null)
            getFolderList();
        return folderTree;
    }

    public Collection<String> getFoldersAsString() {
        if (folderStringTree == null)
            getFolderList();
        return folderStringTree;
    }

    public Collection<File> getFilesTree() throws IOException {
        if (fileTree == null)
            getFileList();
        return fileTree;
    }

    public Collection<String> getFilesAsString() throws IOException {
        if (fileStringTree == null)
            getFileList();
        return fileStringTree;
    }

    /**
     * This method returns the path of a file to encrypt relative to the given
     * folder on the commandline.
     * 
     * E.g. Folder to encrypt: \tmp\test. File in folder to encrypt:
     * \tmp\test\readme.txt. Relative path: test\readme.txt.
     * 
     * @param fileToEncrypt
     * @return path of fileToEncrypt relative to the commandline argument of the
     *         folder to encrypt.
     */
    private String getRelativePathString(File fileToEncrypt) {

        // Remove the parent of top folder from the full path of the current
        // file.
        String relativePath = fileToEncrypt.getAbsolutePath().substring(getArchiveTopFolder().length());

        // If the top folder was e.g. 'C:' then the first separator wasn't
        // removed
        if (relativePath.charAt(0) == File.separatorChar)
            relativePath = relativePath.substring(1);

        return relativePath;
    }

    private void getFileList() throws IOException {
        fileTree = new ArrayList<File>();
        fileStringTree = new ArrayList<String>();
        getFilesRecursively();
    }

    private void getFolderList() {
        folderTree = new ArrayList<File>();
        folderStringTree = new ArrayList<String>();
        getFoldersRecursively();
    }

    /**
     * Retrieve all files for a given folder recursively.
     * 
     * @param folder
     *            the folder to recursively list
     * @param fileTree
     *            an ArrayList object to store the tree of folders
     * @throws IOException
     */
    private void getFilesRecursively() throws IOException {

        Collection<File> files = FileUtils.listFiles(topFolder, TrueFileFilter.TRUE, DirectoryFileFilter.DIRECTORY);

        for (File f : files) {

            // Ignore broken symbolic links
            if (!f.exists()) {
                continue;
            }

            fileTree.add(f);
            fileStringTree.add(getRelativePathString(f));
        }
    }

    /**
     * Retrieve all folders beneath a given folder recursively.
     * 
     * @param folder
     *            the folder to recursively list
     * @param fileTree
     *            an ArrayList object to store the tree of folders
     */
    private void getFoldersRecursively() {

        Collection<File> files = FileUtils.listFilesAndDirs(topFolder, new NotFileFilter(TrueFileFilter.INSTANCE),
                DirectoryFileFilter.DIRECTORY);

        for (File f : files) {

            // Don't return "." or "" as a folder (i.e. skip root)
            if (f.getName().equals(".") || f.getName().equals("")) {
                continue;
            }
            folderTree.add(f);
            folderStringTree.add(getRelativePathString(f));
        }
    }

}