Java tutorial
/******************************************************************************* * 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; import java.io.File; import java.io.IOException; import java.util.Comparator; import javax.crypto.Cipher; import org.apache.commons.cli.*; /** * This class contains methods to parse and fetch all jEncrypt commandline * options with the Apache CLI library. */ final class CommandLineHelper { /* Array of 3 -enc or -dec arguments */ private String[] cipherOptions; /* Full path to configuration file or relative to user.dir */ private String configFileString; /* Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE */ private int cipherMode; /* Full path to key file or relative to user.dir */ private String passwordString; /* Source file to decrypt or folder to encrypt */ private String sourceFileOrFolder; private String targetPath; // Order and list of options private final String orderOfOptions = "edpi"; CommandLineHelper(String[] args) throws ParseException { // Build the Apache CLI options and parse commandline arguments CommandLine commandLine = parseCommandline(args, getOptions(orderOfOptions)); // Check command line options and store them in class variables getCommandlineOptions(commandLine); } /** * Build the Apache CLI Options collection based on the given string of * short opts. * * @param selectOptions * String of first characters of commandline options. * @return */ private Options getOptions(String selectOptions) { Options options = new Options(); Option newOption = null; // Walk through string of short opts and build CLI Options collection for (char s : selectOptions.toCharArray()) { switch (s) { case 'e': newOption = new Option("e", "enc", true, "[File or folder to encrypt] [Destination file]"); newOption.setArgs(3); break; case 'd': newOption = new Option("d", "dec", true, "[File to decrypt] [Destination folder]"); newOption.setArgs(3); break; case 'i': newOption = new Option("i", "ini", false, "[Configuration file]"); newOption.setArgs(1); break; case 'p': newOption = new Option("p", "pwd", false, "[Password to use for en-/decryption]"); newOption.setArgs(1); break; } if (newOption != null) { newOption.setArgName(""); options.addOption(newOption); } } return options; } public String getTargetFolder() { return targetPath; } public String getSourceFileOrFolder() { return sourceFileOrFolder; } public String getPassword() { return passwordString; } public String getConfigFileString() { return configFileString; } public int getCipherMode() { return cipherMode; } /** * Formatter for printing the help text describing command line options. The * options are ordered as they appear in indexOfOptions. * * @param indexOfOptions * @return */ private HelpFormatter getHelpFormatter(final String indexOfOptions) { HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.setOptionComparator(new Comparator<Option>() { public int compare(Option o1, Option o2) { return indexOfOptions.indexOf(o1.getOpt()) - indexOfOptions.indexOf(o2.getOpt()); } }); return helpFormatter; } /** * Parse the arguments according to the specified options * * @param args * @param options * @return * @throws ParseException */ private CommandLine parseCommandline(String[] args, Options options) throws ParseException { CommandLine commandLine = null; CommandLineParser parser = new GnuParser(); try { // parse the command-line arguments commandLine = parser.parse(options, args); } catch (ParseException exp) { throw new ParseException("Parsing failed. Reason: " + exp.getMessage()); } return commandLine; } /** * Print the help information for the options that have their short opt * letter appearing in listAndOrderOfOptions and print the options in order * of appearance. * * @param listAndOrderOfOptions */ public void printHelp(final String listAndOrderOfOptions) { Options options = getOptions(listAndOrderOfOptions); getHelpFormatter(listAndOrderOfOptions).printHelp("jencrypt", options); } /** * Print help information */ public void printHelp() { // If the configuration file has already been specified // then don't print the ini option. if (getConfigFileString() != null) { printHelp(orderOfOptions.replace('i', ' ')); } else printHelp(orderOfOptions); } /** * Check and store jEncrypt command line options * * @param commandLine */ private void getCommandlineOptions(CommandLine commandLine) { // Read and check command-line options String[] cipherOptionsEnc = commandLine.getOptionValues("enc"); String[] cipherOptionsDec = commandLine.getOptionValues("dec"); // Only encrypt or decrypt not both at the same time if (cipherOptionsEnc != null ^ cipherOptionsDec != null) { // Options -enc takes 2 arguments and -dec takes 1 or 2 arguments if (cipherOptionsEnc != null && cipherOptionsEnc.length == 2) { cipherMode = Cipher.ENCRYPT_MODE; cipherOptions = cipherOptionsEnc; } else if (cipherOptionsDec != null && (cipherOptionsDec.length < 3)) { cipherMode = Cipher.DECRYPT_MODE; // If no second argument was given assume current directory if (cipherOptionsDec.length == 1) { cipherOptions = new String[] { cipherOptionsDec[0], "." }; } else { cipherOptions = cipherOptionsDec; } } if (cipherOptions != null) { sourceFileOrFolder = cipherOptions[0]; targetPath = cipherOptions[1]; } } configFileString = commandLine.getOptionValue("ini"); passwordString = commandLine.getOptionValue("pwd"); } /** * Check if the decryption destination directory, base directory and key * file exists. * * @throws IOException */ public boolean isValid() throws IOException { // Cipheroptions contains -end or -dec if (cipherOptions != null && configFileString != null && passwordString != null) { File source = new File(sourceFileOrFolder); if (this.getCipherMode() == Cipher.DECRYPT_MODE) { if (targetPath == "") { targetPath = System.getProperty("user.dir"); } File target = new File(targetPath); if (!source.exists()) { throw new IOException("Source archive '" + sourceFileOrFolder + "' does not exist."); } else if (!source.isFile()) { throw new IOException("Source archive '" + sourceFileOrFolder + "' is not a file"); } if (!target.exists() || !target.canWrite()) { throw new IOException("Destination '" + target.getName() + "' not found or access denied"); } } if (this.getCipherMode() == Cipher.ENCRYPT_MODE) { File targetFile = new File(targetPath); if (targetFile.isDirectory()) { throw new IOException("Destination '" + targetFile.getName() + "' is not a file"); } else if (targetFile.exists()) { throw new IOException("File '" + targetFile.getName() + "' already exists"); } else { try { targetFile.createNewFile(); } catch (IOException e) { throw new SecurityException("Can't create file '" + targetPath + "': " + e.getMessage()); } finally { targetFile.delete(); } } if (!source.exists() || !source.canRead()) { throw new IOException( "Folder to encrypt '" + source.getName() + "' not found or access denied"); } } return true; } return false; } }