com.dancorder.Archiverify.Parameters.java Source code

Java tutorial

Introduction

Here is the source code for com.dancorder.Archiverify.Parameters.java

Source

//    Archiverify is an archive synching and verification tool
//    Copyright (C) 2014  Daniel Corder (contact: archiverify@dancorder.com)
//
//    This program 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 com.dancorder.Archiverify;

import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

class Parameters {

    private Path path1 = null;
    private Path path2 = null;
    private Path readFile = Paths.get(defaultHashFileName);
    private Path writeFile = Paths.get(defaultHashFileName);
    private boolean isValid = true;
    private String errorMessage = "";
    private Options options = null;
    private CommandLine commandLine = null;

    private static final String OPTION_EXECUTE_ACTIONS = "y";
    private static final String OPTION_SINGLE_DIRECTORY_MODE = "s";
    private static final String OPTION_HASH_FILENAMES = "f";
    private static final String OPTION_HASH_READ_FILENAMES = "fr";
    private static final String OPTION_HASH_WRITE_FILENAMES = "fw";

    private static final String defaultHashFileName = ".hashes";

    Parameters(String[] args) {
        try {
            options = getOptions();
            commandLine = getCommandLine(args, options);
            getPaths(commandLine.getArgs());
            validateOptions();
        } catch (Exception e) {
            isValid = false;
            errorMessage = e.getMessage();
        }
    }

    private void validateOptions() throws Exception {
        if (getIsSingleDirectoryMode()) {
            if (path1 == null) {
                throw new Exception("No directory supplied");
            }
            if (path2 != null) {
                throw new Exception("Only supply one directory in single directory mode");
            }

            validatePath(path1);
            path1 = normalisePath(path1);
        } else {
            if (path1 == null || path2 == null) {
                throw new Exception("Two directories must be supplied");
            }

            validatePath(path1);
            validatePath(path2);
            path1 = normalisePath(path1);
            path2 = normalisePath(path2);
        }

        validateFileNames();
    }

    void printUsage() {
        HelpFormatter formatter = new HelpFormatter();
        // TODO: Improve this and make it testable. Commons.CLI makes it hard to just get a string of the usage message.
        formatter.printHelp("Archiverify [options] <path1> [path2]", options);
    }

    boolean isValid() {
        return isValid;
    }

    String getErrorMessage() {
        return errorMessage;
    }

    Path getPath1() {
        return path1;
    }

    Path getPath2() {
        return path2;
    }

    Path getReadFile() {
        if (commandLine.hasOption(OPTION_HASH_READ_FILENAMES)) {
            readFile = Paths.get(commandLine.getOptionValue(OPTION_HASH_READ_FILENAMES));
        } else if (commandLine.hasOption(OPTION_HASH_FILENAMES)) {
            readFile = Paths.get(commandLine.getOptionValue(OPTION_HASH_FILENAMES));
        }
        return readFile;
    }

    Path getWriteFile() {
        if (commandLine.hasOption(OPTION_HASH_WRITE_FILENAMES)) {
            writeFile = Paths.get(commandLine.getOptionValue(OPTION_HASH_WRITE_FILENAMES));
        } else if (commandLine.hasOption(OPTION_HASH_FILENAMES)) {
            writeFile = Paths.get(commandLine.getOptionValue(OPTION_HASH_FILENAMES));
        }
        return writeFile;
    }

    boolean getExecuteActions() {
        return commandLine.hasOption(OPTION_EXECUTE_ACTIONS);
    }

    boolean getIsSingleDirectoryMode() {
        return commandLine.hasOption(OPTION_SINGLE_DIRECTORY_MODE);
    }

    private Options getOptions() {
        Options options = new Options();
        options.addOption(new Option(OPTION_EXECUTE_ACTIONS, false, "Automatically execute all found actions"));
        options.addOption(new Option(OPTION_SINGLE_DIRECTORY_MODE, false,
                "Generate and check hashes for a single directory"));
        options.addOption(
                new Option(OPTION_HASH_FILENAMES, true, "Use a differnt filename to read and write hashes"));
        options.addOption(new Option(OPTION_HASH_READ_FILENAMES, true,
                "Use a differnt filename to read hashes from, hashes are written to the default filename"));
        options.addOption(new Option(OPTION_HASH_WRITE_FILENAMES, true,
                "Use a differnt filename to write hashes to, hashes are read from the default filename"));

        return options;
    }

    private CommandLine getCommandLine(String[] args, Options options) throws ParseException {
        return new BasicParser().parse(options, args);
    }

    private void getPaths(String[] remainingArgs) throws Exception {
        if (remainingArgs.length > 0) {
            path1 = Paths.get(remainingArgs[0]);
        }
        if (remainingArgs.length > 1) {
            path2 = Paths.get(remainingArgs[1]);
        }
    }

    private void validatePath(Path path) throws Exception {
        if (!path.toFile().exists() || !path.toFile().isDirectory()) {
            throw new Exception("Path must be an existing directory: " + path);
        }
    }

    private Path normalisePath(Path path) {
        return path.toAbsolutePath();
    }

    private void validateFileNames() throws Exception {
        validateOptionIsUnsetOrNotEmpty(OPTION_HASH_FILENAMES, "Hash file name cannot be blank");
        validateOptionIsUnsetOrNotEmpty(OPTION_HASH_READ_FILENAMES, "Hash read file name cannot be blank");
        validateOptionIsUnsetOrNotEmpty(OPTION_HASH_WRITE_FILENAMES, "Hash write file name cannot be blank");
    }

    private void validateOptionIsUnsetOrNotEmpty(String option, String errorMessage) throws Exception {
        if (commandLine.hasOption(option) && "".equals(commandLine.getOptionValue(option))) {
            throw new Exception(errorMessage);
        }
    }
}