|
@@ -0,0 +1,300 @@
|
|
|
+/**
|
|
|
+ * MCS Media Computer Software
|
|
|
+ * Copyright 2018 by Wilfried Klaas
|
|
|
+ * Project: MCSUtils
|
|
|
+ * File: ProcessCommandline.java
|
|
|
+ * EMail: W.Klaas@gmx.de
|
|
|
+ * Created: 29.11.2018 wklaa_000
|
|
|
+ *
|
|
|
+ * 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 de.mcs.utils.jsap;
|
|
|
+
|
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
|
+import java.lang.reflect.Method;
|
|
|
+import java.net.URL;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+import org.reflections.Reflections;
|
|
|
+import org.reflections.scanners.FieldAnnotationsScanner;
|
|
|
+import org.reflections.scanners.MethodAnnotationsScanner;
|
|
|
+import org.reflections.scanners.TypeAnnotationsScanner;
|
|
|
+import org.reflections.util.ClasspathHelper;
|
|
|
+import org.reflections.util.ConfigurationBuilder;
|
|
|
+
|
|
|
+import com.martiansoftware.jsap.FlaggedOption;
|
|
|
+import com.martiansoftware.jsap.JSAP;
|
|
|
+import com.martiansoftware.jsap.JSAPException;
|
|
|
+import com.martiansoftware.jsap.JSAPResult;
|
|
|
+import com.martiansoftware.jsap.UnflaggedOption;
|
|
|
+import com.martiansoftware.jsap.stringparsers.FileStringParser;
|
|
|
+import com.martiansoftware.jsap.stringparsers.StringStringParser;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author wklaa_000
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class CommandlineProcessor {
|
|
|
+
|
|
|
+ private static JSAP parser;
|
|
|
+ private static JSAPResult commandLineArgs;
|
|
|
+
|
|
|
+ private static Map<String, Method> parameterMethods;
|
|
|
+ private static Reflections reflections;
|
|
|
+ private static Command helpContext;
|
|
|
+
|
|
|
+ public static void processCommandline(Class class1, String[] args) {
|
|
|
+ parameterMethods = new HashMap<>();
|
|
|
+ parseParameters(class1, args);
|
|
|
+ checkParams();
|
|
|
+ processParameters();
|
|
|
+ };
|
|
|
+
|
|
|
+ private static void processParameters() {
|
|
|
+ parameterMethods.entrySet().forEach(e -> {
|
|
|
+ String name = e.getKey();
|
|
|
+ Method method = e.getValue();
|
|
|
+ processSwitchOption(name, method);
|
|
|
+ processStringOption(name, method);
|
|
|
+ processFileOption(name, method);
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processFileOption(String name, Method method) {
|
|
|
+ FileOption annotation = method.getAnnotation(FileOption.class);
|
|
|
+ if (annotation != null) {
|
|
|
+ try {
|
|
|
+ method.invoke(null, commandLineArgs.getFile(annotation.name()));
|
|
|
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
|
|
|
+ e1.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processStringOption(String name, Method method) {
|
|
|
+ StringOption annotation = method.getAnnotation(StringOption.class);
|
|
|
+ if (annotation != null) {
|
|
|
+ try {
|
|
|
+ method.invoke(null, commandLineArgs.getString(annotation.name()));
|
|
|
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
|
|
|
+ e1.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processSwitchOption(String name, Method method) {
|
|
|
+ SwitchOption annotation = method.getAnnotation(SwitchOption.class);
|
|
|
+ if (annotation != null) {
|
|
|
+ try {
|
|
|
+ method.invoke(null, commandLineArgs.getBoolean(name));
|
|
|
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
|
|
|
+ e1.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * checking commandline parameters.
|
|
|
+ */
|
|
|
+ private static void checkParams() {
|
|
|
+ if (!commandLineArgs.success()) {
|
|
|
+
|
|
|
+ System.err.println();
|
|
|
+
|
|
|
+ // print out specific error messages describing the problems
|
|
|
+ // with the command line, THEN print usage, THEN print full
|
|
|
+ // help. This is called "beating the user with a clue stick."
|
|
|
+ for (@SuppressWarnings("rawtypes")
|
|
|
+ Iterator errs = commandLineArgs.getErrorMessageIterator(); errs.hasNext();) {
|
|
|
+ System.err.println("Error: " + errs.next());
|
|
|
+ }
|
|
|
+ showHelp("error");
|
|
|
+ System.exit(-1);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * showing the actual help page in console.
|
|
|
+ */
|
|
|
+ public static void showHelp() {
|
|
|
+ showHelp(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * showing the actual help page in console.
|
|
|
+ */
|
|
|
+ public static void showHelp(String message) {
|
|
|
+ if (helpContext != null) {
|
|
|
+ System.out.println(helpContext.help());
|
|
|
+ }
|
|
|
+ if (message != null) {
|
|
|
+ System.out.println(message);
|
|
|
+ }
|
|
|
+ System.out.println(parser.getHelp());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This function parses the commandline parameters. If the parameter -h or --help is avalible, generate a little help
|
|
|
+ * text.
|
|
|
+ *
|
|
|
+ * @param class1
|
|
|
+ *
|
|
|
+ * @param args
|
|
|
+ * Commadline arguments
|
|
|
+ */
|
|
|
+ public static void parseParameters(Class class1, final String[] args) {
|
|
|
+ List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
|
|
|
+ classLoadersList.add(ClasspathHelper.contextClassLoader());
|
|
|
+ classLoadersList.add(ClasspathHelper.staticClassLoader());
|
|
|
+
|
|
|
+ URL urlList = ClasspathHelper.forClass(Thread.class);
|
|
|
+ System.out.println(urlList.toString());
|
|
|
+
|
|
|
+ reflections = new Reflections(new ConfigurationBuilder().setUrls(urlList).setScanners(new TypeAnnotationsScanner(),
|
|
|
+ new FieldAnnotationsScanner(), new MethodAnnotationsScanner()));
|
|
|
+
|
|
|
+ // reflections = new Reflections("", new TypeAnnotationsScanner(), new MethodAnnotationsScanner(),
|
|
|
+ // new FieldAnnotationsScanner());
|
|
|
+
|
|
|
+ parser = new JSAP();
|
|
|
+ try {
|
|
|
+ registerHelpContext(class1);
|
|
|
+ // registering the parameters with default values
|
|
|
+ registerDefaultParameter();
|
|
|
+
|
|
|
+ // parsing the commadline
|
|
|
+ commandLineArgs = parser.parse(args);
|
|
|
+ } catch (JSAPException e) {
|
|
|
+ // Something goes wrong
|
|
|
+ System.out.println("Parsing exception:" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ System.exit(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void registerHelpContext(Class class1) {
|
|
|
+ Command annotation = (Command) class1.getAnnotation(Command.class);
|
|
|
+ if (annotation != null) {
|
|
|
+ helpContext = annotation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * registering the parameters to the JSAP Parser.
|
|
|
+ *
|
|
|
+ * @throws JSAPException
|
|
|
+ * Something is going wrong
|
|
|
+ */
|
|
|
+ private static void registerDefaultParameter() throws JSAPException {
|
|
|
+ Map<Integer, UnflaggedOption> unflaggedOptions = new HashMap<>();
|
|
|
+
|
|
|
+ // MethodAnnotationsScanner
|
|
|
+ Set<Method> methodes = reflections.getMethodsAnnotatedWith(SwitchOption.class);
|
|
|
+ for (Method method : methodes) {
|
|
|
+ System.out.println("sw");
|
|
|
+ SwitchOption annotation = method.getAnnotation(SwitchOption.class);
|
|
|
+ // System.out.printf("short: %s, long: %s, name: %s, help: %s, def: %s,
|
|
|
+ // req: %s\r\n", annotation.shortKey(),
|
|
|
+ // annotation.longKey(), annotation.name(), annotation.help(),
|
|
|
+ // annotation.defaultValue(), annotation.required());
|
|
|
+
|
|
|
+ com.martiansoftware.jsap.Switch swtOption = new com.martiansoftware.jsap.Switch(annotation.name(),
|
|
|
+ annotation.shortKey(), annotation.longKey());
|
|
|
+ if (annotation.defaultValue()) {
|
|
|
+ swtOption.setDefault(Boolean.TRUE.toString());
|
|
|
+ }
|
|
|
+ swtOption.setHelp(annotation.help());
|
|
|
+ parser.registerParameter(swtOption);
|
|
|
+ parameterMethods.put(annotation.name(), method);
|
|
|
+ }
|
|
|
+
|
|
|
+ // // FieldAnnotationsScanner
|
|
|
+ // Set<Field> fields = reflections.getFieldsAnnotatedWith(Switch.class);
|
|
|
+ // for (Field field : fields) {
|
|
|
+ // System.out.println(field.getName());
|
|
|
+ // }
|
|
|
+
|
|
|
+ // MethodAnnotationsScanner
|
|
|
+ methodes = reflections.getMethodsAnnotatedWith(StringOption.class);
|
|
|
+ for (Method method : methodes) {
|
|
|
+ System.out.println("so");
|
|
|
+ StringOption annotation = method.getAnnotation(StringOption.class);
|
|
|
+ // System.out.printf("short: %s, long: %s, name: %s, help: %s, def: %s,
|
|
|
+ // req: %s\r\n", annotation.shortKey(),
|
|
|
+ // annotation.longKey(), annotation.name(), annotation.help(),
|
|
|
+ // annotation.defaultValue(), annotation.required());
|
|
|
+
|
|
|
+ StringStringParser stringParser = StringStringParser.getParser();
|
|
|
+ if (annotation.index() > 0) {
|
|
|
+ UnflaggedOption unflgopt = new UnflaggedOption(annotation.name(), stringParser, annotation.defaultValue(),
|
|
|
+ annotation.required(), false, annotation.help());
|
|
|
+ unflaggedOptions.put(annotation.index(), unflgopt);
|
|
|
+ parameterMethods.put(Integer.toString(annotation.index()), method);
|
|
|
+ } else {
|
|
|
+ FlaggedOption flgopt = new FlaggedOption(annotation.name(), stringParser, annotation.defaultValue(),
|
|
|
+ annotation.required(), annotation.shortKey(), annotation.longKey());
|
|
|
+ flgopt.setHelp(annotation.help());
|
|
|
+ parser.registerParameter(flgopt);
|
|
|
+ parameterMethods.put(annotation.name(), method);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // MethodAnnotationsScanner
|
|
|
+ methodes = reflections.getMethodsAnnotatedWith(FileOption.class);
|
|
|
+ for (Method method : methodes) {
|
|
|
+ System.out.println("fo");
|
|
|
+ FileOption annotation = method.getAnnotation(FileOption.class);
|
|
|
+ // System.out.printf("short: %s, long: %s, name: %s, help: %s, def: %s,
|
|
|
+ // req: %s\r\n", annotation.shortKey(),
|
|
|
+ // annotation.longKey(), annotation.name(), annotation.help(),
|
|
|
+ // annotation.defaultValue(), annotation.required());
|
|
|
+
|
|
|
+ FileStringParser fileStringParser = FileStringParser.getParser();
|
|
|
+ fileStringParser.setMustBeDirectory(annotation.mustBeDirectory());
|
|
|
+ fileStringParser.setMustExist(annotation.mustExists());
|
|
|
+
|
|
|
+ if (annotation.index() > 0) {
|
|
|
+ UnflaggedOption unflgopt = new UnflaggedOption(annotation.name(), fileStringParser, annotation.defaultValue(),
|
|
|
+ annotation.required(), false, annotation.help());
|
|
|
+ unflaggedOptions.put(annotation.index(), unflgopt);
|
|
|
+ parameterMethods.put(Integer.toString(annotation.index()), method);
|
|
|
+ } else {
|
|
|
+ FlaggedOption flgopt = new FlaggedOption(annotation.name(), fileStringParser, annotation.defaultValue(),
|
|
|
+ annotation.required(), annotation.shortKey(), annotation.longKey());
|
|
|
+ flgopt.setHelp(annotation.help());
|
|
|
+ parser.registerParameter(flgopt);
|
|
|
+ parameterMethods.put(annotation.name(), method);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Integer> indexes = new ArrayList<>();
|
|
|
+ unflaggedOptions.keySet().forEach(e -> indexes.add(e));
|
|
|
+ indexes.sort((x, y) -> {
|
|
|
+ int diff = x - y;
|
|
|
+ return (diff == 0) ? 1 : diff;
|
|
|
+ });
|
|
|
+
|
|
|
+ for (Integer e : indexes) {
|
|
|
+ parser.registerParameter(unflaggedOptions.get(e));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|