package ch.bfh.lpdg; import org.apache.commons.cli.*; import java.io.File; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class InteractionHandler { //Definition of all the possible options. Short with one letter, or longer with one word. private static final String PathOption = "p"; private static final String HelpOption = "h"; private static final String DepthOption = "d"; private static final String OverwriteOption = "o"; private static final String MinimizeOption = "m"; private static final String LicenseOptionLong = "license"; private static final String DebugOptionLong = "debug"; private boolean isSingleFile = false; private boolean isDebug = false; private boolean overwriteFlag = false; private boolean minimizeFlag = false; private final Options options; private final String userDirectory; private String path; private int depth = 5; public boolean hasOverwriteFlag() { return overwriteFlag; } public boolean hasMinimizeFlag() { return minimizeFlag; } public String getPath() { return this.path; } public int getDepth() { return this.depth; } public void setPath(final String path) { this.path = path; } public String getUserDirectory() { return userDirectory; } public final static InteractionHandler INSTANCE = new InteractionHandler(); public static InteractionHandler getInstance() { return INSTANCE; } private InteractionHandler() { //The default value is the current directory where the application was called from. userDirectory = System.getProperty("user.dir"); path = userDirectory; options = InitOptions(); } private static Options InitOptions() { Options options = new Options(); options.addOption(Option.builder(HelpOption) .desc("Print this message and quit.") .longOpt("help").build()); options.addOption(Option.builder(DepthOption) .hasArg() .argName("Depth") .desc("The depth of the scan. Default value is 5.") .longOpt("depth").build()); options.addOption(Option.builder(OverwriteOption) .desc("Overwrite the input file(s), with a version that only includes the necessary packages.") .longOpt("overwrite").build()); options.addOption(Option.builder(MinimizeOption) .desc("Creates a minimized version of the input file(s), with only the necessary packages.") .longOpt("minimize").build()); options.addOption(Option.builder(PathOption) .desc("File or path to be scanned. The default value is the current working directory.") .hasArg() .argName("Path") .longOpt("Path").build()); options.addOption(Option.builder() .desc("Print the Licensing information and quit.") .longOpt(LicenseOptionLong).build()); options.addOption(Option.builder() .desc("Print debug information.") .longOpt(DebugOptionLong).build()); return options; } public void handleOptions(String[] args) throws ParseException { CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse(options, args); if (cmd.hasOption(DebugOptionLong)) { this.isDebug = true; printDebugMessage("Debugging."); } if (cmd.hasOption(HelpOption)) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("java -jar LatexDependencyGrapher", "Scan your Latex file(s) to find unused pacakges and create a graph of your dependencies." , options, ""); printDebugMessage("HelpOption called."); System.exit(0); } if (cmd.hasOption(PathOption)) { path = cmd.getOptionValue(PathOption); printDebugMessage("PathOption called. Values is: " + path); if (path.isBlank() || path.isEmpty()) throw new MissingArgumentException("The value for the path is missing."); } if (cmd.hasOption(DepthOption)) { depth = Integer.parseInt(cmd.getOptionValue(DepthOption)); printDebugMessage("DepthOption called. Values is: " + depth); } if (cmd.hasOption(LicenseOptionLong)) { System.out.println("This project uses the Apache Commons CLI Library, which is licensed under Apache License 2.0. See more in the NOTICE.txt File."); printDebugMessage("LicenseOption called. Values is: " + path); System.exit(0); } if (cmd.hasOption(MinimizeOption)) { minimizeFlag = true; printDebugMessage("MinimizeOption called."); } if (cmd.hasOption(OverwriteOption)) { overwriteFlag = true; printDebugMessage("OverwriteOption called."); } var validateResult = validatePath(path); if (!validateResult) throw new InvalidParameterException("The given path is invalid: " + path); } public List getFiles() { List files; if (isSingleFile) { if (path.endsWith(".sty") || path.endsWith(".cls") || path.endsWith(".tex")) { files = new ArrayList<>() {{ add(new File(path)); }}; } else throw new IllegalArgumentException("The given Path is not a LaTeX-File."); } else files = loadLatexFiles(); return files; } public void printDebugMessage(String msg) { if (this.isDebug) System.out.println("\u001B[33m" + "DEBUG: " + msg + "\u001B[0m"); } private Boolean validatePath(String path) { if (path == null) { printDebugMessage("Path is null."); return false; } File file = new File(path); printDebugMessage("Filepath: " + file.getAbsolutePath()); if (!file.isDirectory()) { printDebugMessage("Path is not a directory"); isSingleFile = file.exists(); file = file.getParentFile(); } else { isSingleFile = false; } if(isSingleFile) { printDebugMessage("The path is a single file."); if(!(path.endsWith(".sty") || path.endsWith(".cls") || path.endsWith(".tex"))) { throw new IllegalArgumentException("The given Path is not a LaTeX-File."); } } return file != null && file.exists(); } private List loadLatexFiles() { if (isSingleFile) throw new IllegalCallerException("This method should only be called to load the LaTeX-Files from a directory."); List latexFiles = new ArrayList<>(); File directory = new File(path); if (directory.isDirectory()) { File[] files = directory.listFiles((dir, name) -> name.endsWith(".sty") || name.endsWith(".cls") || name.endsWith(".tex")); if (files != null) { latexFiles.addAll(Arrays.asList(files)); } } return latexFiles; } }