JaStaCry.java
package org.jastacry;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jastacry.GlobalData.Action;
import org.jastacry.GlobalData.Returncode;
import net.sourceforge.cobertura.CoverageIgnore;
/**
* Main JaStaCry class to start.
*
* <p>SPDX-License-Identifier: MIT
*
* @author Kai Kretschmann
*/
public final class JaStaCry
{
/**
* Holder of i18n translations.
*/
private static ResourceBundle bundle;
/**
* Parameter, short version, for "help".
*/
private static final String P_SHORT_HELP = "h";
/**
* Parameter, long version, for "help".
*/
private static final String P_LONG_HELP = "help";
/**
* Parameter, short version, for "verbose".
*/
private static final String P_SHORT_VERBOSE = "v";
/**
* Parameter, short version, for "ASCII".
*/
private static final String P_SHORT_ASCII = "t";
/**
* Parameter, long version, for "ASCII".
*/
private static final String P_LONG_ASCII = "text";
/**
* Parameter, short version, for "encode".
*/
private static final String P_SHORT_ENCODE = "e";
/**
* Parameter, long version, for "encode".
*/
private static final String P_LONG_ENCODE = "encode";
/**
* Parameter, short version, for "decode".
*/
private static final String P_SHORT_DECODE = "d";
/**
* Parameter, long version, for "decode".
*/
private static final String P_LONG_DECODE = "decode";
/**
* Parameter, short version, for "config".
*/
private static final String P_SHORT_CONFFILE = "c";
/**
* Parameter, long version, for "config".
*/
private static final String P_LONG_CONFFILE = "conffile";
/**
* Parameter, short version, for "infile".
*/
private static final String P_SHORT_INFILE = "i";
/**
* Parameter, long version, for "infile".
*/
private static final String P_LONG_INFILE = "infile";
/**
* Parameter, short version, for "outfile".
*/
private static final String P_SHORT_OUTFILE = "o";
/**
* Parameter, long version, for "outfile".
*/
private static final String P_LONG_OUTFILE = "outfile";
/**
* log4j logger object.
*/
private static final Logger LOGGER = LogManager.getLogger(JaStaCry.class.getName());
/**
* boolean status: do we encode to plain text transport format.
*/
private static boolean doASCIItransport;
/**
* Filename of configuration file.
*/
private static String confFilename;
/**
* Some input filename.
*/
private static String inputFilename;
/**
* Some output filename.
*/
private static String outputFilename;
/**
* Be verbose about every step.
*/
private static boolean isVerbose;
/**
* action variable.
*/
private static Action action;
/**
* Hidden constructor.
*/
@CoverageIgnore
private JaStaCry()
{
// not called
}
/**
* Main class for running a command line interface.
*
* @param args parsed by Apache commons CLI package
*/
@CoverageIgnore
@SuppressWarnings("squid:S4823") // Using command line arguments is security-sensitive
public static void main(final String[] args)
{
final int returncode = mainMethod(args);
System.exit(returncode); // NOPMD by kai on 21.11.17 17:04
}
/**
* Main method.
*
* @param args for parsing
* @return int result code
*/
public static int mainMethod(final String... args)
{
LOGGER.traceEntry();
localizer();
int returncode = setup(args);
if (0 != returncode)
{
LOGGER.error(getText("error.setupfound"), returncode);
return returncode; // NOPMD by kai on 21.11.17 16:59
} // if
final Worker worker = new Worker();
worker.setAction(action);
worker.setConfFilename(confFilename);
worker.setDoAsciitransport(doASCIItransport);
worker.setInputFilename(inputFilename);
worker.setOutputFilename(outputFilename);
worker.setVerbose(isVerbose);
returncode = worker.mainWork();
return LOGGER.traceExit(returncode);
}
/**
* Create command line Options object.
*
* @return Options object
*/
private static Options createOptions()
{
LOGGER.traceEntry();
final Options options = new Options();
// optional parameters
options.addOption(P_SHORT_HELP, P_LONG_HELP, false, getText("help.help"));
options.addOption(P_SHORT_VERBOSE, false, getText("help.verbose"));
options.addOption(P_SHORT_ASCII, P_LONG_ASCII, false, getText("help.ascii"));
// either/or arguments, but mandatory as a set
final OptionGroup ogAction = new OptionGroup();
Option option;
option = Option.builder(P_SHORT_ENCODE).required(false).longOpt(P_LONG_ENCODE).desc(getText("help.encode")).build();
ogAction.addOption(option);
option = Option.builder(P_SHORT_DECODE).required(false).longOpt(P_LONG_DECODE).desc(getText("help.decode")).build();
ogAction.addOption(option);
ogAction.setRequired(true);
options.addOptionGroup(ogAction);
// mandatory parameters
option = Option.builder(P_SHORT_CONFFILE).required(true).hasArg().longOpt(P_LONG_CONFFILE).argName("FILE")
.desc("use FILE as stack configuration").build();
options.addOption(option);
option = Option.builder(P_SHORT_INFILE).required(true).hasArg().longOpt(P_LONG_INFILE).argName("FILE")
.desc("use FILE as input stream").build();
options.addOption(option);
option = Option.builder(P_SHORT_OUTFILE).required(true).hasArg().longOpt(P_LONG_OUTFILE).argName("FILE")
.desc("use FILE as output stream").build();
options.addOption(option);
return LOGGER.traceExit(options);
}
/**
* Read current locale and load i18n bundle.
*/
private static void localizer()
{
LOGGER.traceEntry();
final Locale currentLocale = Locale.getDefault();
LOGGER.info("Locale: {}", currentLocale);
// First read locale i18n stuff
bundle = ResourceBundle.getBundle("Bundle");
LOGGER.traceExit();
}
/**
* Helper function to get translated text from bundle.
* @param key String key for value
* @return String as translation
*/
public static String getText(final String key)
{
return bundle.getString(key);
}
/**
* Setup environment via command line arguments.
*
* @param args array of Strings from command line
* @return int error value
*/
private static int setup(final String... args)
{
LOGGER.traceEntry();
// Command line parameters
final Options options = createOptions();
// Manual check for help, ignoring otherwise mandatory arguments
final HelpFormatter formatter = new HelpFormatter();
if (args.length > 0 && "-h".equalsIgnoreCase(args[0]))
{
formatter.printHelp(GlobalData.HELP, options);
return Returncode.RC_HELP.getNumVal();
} // if
final CommandLineParser parser = new DefaultParser();
CommandLine cmdLine;
try
{
cmdLine = parser.parse(options, args);
}
catch (final MissingOptionException exOpt)
{
formatter.printHelp(GlobalData.HELP, options);
return Returncode.RC_ERROR.getNumVal();
}
catch (final ParseException e2)
{
LOGGER.catching(e2);
return LOGGER.traceExit(Returncode.RC_ERROR.getNumVal());
}
if (null == cmdLine)
{
LOGGER.error("cmdLine null");
return LOGGER.traceExit(Returncode.RC_ERROR.getNumVal());
}
// No need to check for P_SHORT_HELP here anymore.
// Is verbose?
isVerbose = cmdLine.hasOption(P_SHORT_VERBOSE);
if (isVerbose)
{
LOGGER.info("JaStaCry starting");
}
action = Action.UNKOWN;
// is it called with all needed parameters?
if (cmdLine.hasOption(P_SHORT_ENCODE) || cmdLine.hasOption(P_LONG_ENCODE))
{
action = Action.ENCODE;
} // if
if (cmdLine.hasOption(P_SHORT_DECODE) || cmdLine.hasOption(P_LONG_DECODE))
{
action = Action.DECODE;
} // if
// Use text format?
doASCIItransport = cmdLine.hasOption(P_SHORT_ASCII) || cmdLine.hasOption(P_LONG_ASCII);
// Get file names for config, input and output
confFilename = cmdLine.getOptionValue(P_LONG_CONFFILE);
inputFilename = cmdLine.getOptionValue(P_LONG_INFILE);
outputFilename = cmdLine.getOptionValue(P_LONG_OUTFILE);
return LOGGER.traceExit(0);
}
}