mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-19 00:35:20 +01:00
Run tool tasks from one entry point
- Create scanner which scans for existing tasks - Unify options management (mostly because multiple Scanner's are a bad idea)
This commit is contained in:
parent
a14e3260dc
commit
23d6801baa
136
src/tools/ToolsRunner.java
Normal file
136
src/tools/ToolsRunner.java
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import utils.ScannerHelper;
|
||||||
|
import utils.TaskOption;
|
||||||
|
import utils.ToolTask;
|
||||||
|
import utils.ToolsConstants;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for tool tasks.
|
||||||
|
*/
|
||||||
|
public class ToolsRunner {
|
||||||
|
|
||||||
|
private static final String DIR_SEPARATOR = File.separator;
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
// Collect tasks and show them
|
||||||
|
File toolsFolder = new File(ToolsConstants.TOOLS_SOURCE_ROOT);
|
||||||
|
Map<String, ToolTask> tasks = new HashMap<>();
|
||||||
|
collectTasksInDirectory(toolsFolder, tasks);
|
||||||
|
showHelp(tasks);
|
||||||
|
|
||||||
|
// Prompt user for task and handle input
|
||||||
|
System.out.println("Please enter the task to run:");
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
String inputTask = scanner.nextLine();
|
||||||
|
ToolTask task = tasks.get(inputTask);
|
||||||
|
|
||||||
|
if (task != null) {
|
||||||
|
executeTask(task, scanner);
|
||||||
|
} else {
|
||||||
|
System.out.println("Unknown task");
|
||||||
|
}
|
||||||
|
scanner.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the given tool task after prompting the user for the required options.
|
||||||
|
*
|
||||||
|
* @param task The task to run
|
||||||
|
* @param scanner The scanner instance
|
||||||
|
*/
|
||||||
|
private static void executeTask(ToolTask task, Scanner scanner) {
|
||||||
|
Iterable<TaskOption> options = task.getOptions();
|
||||||
|
Map<String, String> inputOptions = new HashMap<>();
|
||||||
|
for (TaskOption option : options) {
|
||||||
|
System.out.println(option.getDescription());
|
||||||
|
String input = ScannerHelper.getAnswer(option.getDefaultOption(), scanner, option.getOptions());
|
||||||
|
inputOptions.put(option.getName(), input);
|
||||||
|
}
|
||||||
|
|
||||||
|
task.execute(inputOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showHelp(Map<String, ToolTask> taskCollection) {
|
||||||
|
System.out.println("The following tasks are available:");
|
||||||
|
for (String key : taskCollection.keySet()) {
|
||||||
|
System.out.println("- " + key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note ljacqu 20151212: If the tools folder becomes a lot bigger, it will make sense to restrict the depth
|
||||||
|
// of this recursive collector
|
||||||
|
private static void collectTasksInDirectory(File dir, Map<String, ToolTask> taskCollection) {
|
||||||
|
File[] files = dir.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
throw new RuntimeException("Cannot read folder '" + dir + "'");
|
||||||
|
}
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
collectTasksInDirectory(file, taskCollection);
|
||||||
|
} else if (file.isFile()) {
|
||||||
|
ToolTask task = getTaskFromFile(file);
|
||||||
|
if (task != null) {
|
||||||
|
taskCollection.put(task.getTaskName(), task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link ToolTask} instance from the given file.
|
||||||
|
*
|
||||||
|
* @param file The file to load
|
||||||
|
* @return ToolTask instance or null if not applicable
|
||||||
|
*/
|
||||||
|
private static ToolTask getTaskFromFile(File file) {
|
||||||
|
Class<? extends ToolTask> taskClass = loadTaskClassFromFile(file);
|
||||||
|
if (taskClass == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Constructor<? extends ToolTask> constructor = taskClass.getConstructor();
|
||||||
|
return constructor.newInstance();
|
||||||
|
} catch (NoSuchMethodException | InvocationTargetException |
|
||||||
|
IllegalAccessException | InstantiationException e) {
|
||||||
|
throw new RuntimeException("Cannot instantiate task '" + taskClass + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the class the file defines if it implements a {@link ToolTask}.
|
||||||
|
*
|
||||||
|
* @return The class instance, or null if not applicable
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Class<? extends ToolTask> loadTaskClassFromFile(File file) {
|
||||||
|
if (!file.getName().endsWith(".java")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String filePath = file.getPath();
|
||||||
|
String className = filePath
|
||||||
|
.substring(ToolsConstants.TOOLS_SOURCE_ROOT.length(), filePath.length() - 5)
|
||||||
|
.replace(DIR_SEPARATOR, ".");
|
||||||
|
try {
|
||||||
|
Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(className);
|
||||||
|
return ToolTask.class.isAssignableFrom(clazz) && isInstantiable(clazz)
|
||||||
|
? (Class<? extends ToolTask>) clazz
|
||||||
|
: null;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInstantiable(Class<?> clazz) {
|
||||||
|
return !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,10 +2,13 @@ package messages;
|
|||||||
|
|
||||||
import fr.xephi.authme.util.StringUtils;
|
import fr.xephi.authme.util.StringUtils;
|
||||||
import utils.FileUtils;
|
import utils.FileUtils;
|
||||||
|
import utils.TaskOption;
|
||||||
|
import utils.ToolTask;
|
||||||
import utils.ToolsConstants;
|
import utils.ToolsConstants;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,27 +20,23 @@ import java.util.regex.Pattern;
|
|||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point of the messages verifier.
|
* Task to verify the keys in the messages files.
|
||||||
*/
|
*/
|
||||||
public final class MessagesVerifierRunner {
|
public final class VerifyMessagesTask implements ToolTask {
|
||||||
|
|
||||||
private static final String MESSAGES_FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/";
|
private static final String MESSAGES_FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/";
|
||||||
|
private static final Pattern MESSAGE_FILE_PATTERN = Pattern.compile("messages_[a-z]{2,7}\\.yml");
|
||||||
private static final String SOURCES_TAG = "{msgdir}";
|
private static final String SOURCES_TAG = "{msgdir}";
|
||||||
|
|
||||||
private MessagesVerifierRunner() {
|
@Override
|
||||||
|
public String getTaskName() {
|
||||||
|
return "verifyMessages";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
@Override
|
||||||
// Prompt user for options
|
public void execute(Map<String, String> options) {
|
||||||
Scanner scanner = new Scanner(System.in);
|
String inputFile = options.get("custom.file");
|
||||||
System.out.println("Check a specific file only?");
|
boolean addMissingKeys = options.get("add.missing.keys").equals("y");
|
||||||
System.out.println("- Empty line will check all files in the resources messages folder (default)");
|
|
||||||
System.out.println(format("- %s will be replaced to the messages folder %s", SOURCES_TAG, MESSAGES_FOLDER));
|
|
||||||
String inputFile = scanner.nextLine();
|
|
||||||
|
|
||||||
System.out.println("Add any missing keys to files? ['y' = yes]");
|
|
||||||
boolean addMissingKeys = "y".equals(scanner.nextLine());
|
|
||||||
scanner.close();
|
|
||||||
|
|
||||||
// Set up needed objects
|
// Set up needed objects
|
||||||
Map<String, String> defaultMessages = null;
|
Map<String, String> defaultMessages = null;
|
||||||
@ -69,6 +68,18 @@ public final class MessagesVerifierRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<TaskOption> getOptions() {
|
||||||
|
String customFileDescription = StringUtils.join(System.getProperty("line.separator"),
|
||||||
|
"Check a specific file only? (optional - enter custom filename)",
|
||||||
|
"- Empty line will check all files in the resources messages folder",
|
||||||
|
format("- %s will be replaced to the messages folder %s", SOURCES_TAG, MESSAGES_FOLDER));
|
||||||
|
|
||||||
|
return Arrays.asList(
|
||||||
|
new TaskOption("custom.file", customFileDescription, "", null),
|
||||||
|
new TaskOption("add.missing.keys", "Add missing keys to files? [y/n]", "n", "y", "n"));
|
||||||
|
}
|
||||||
|
|
||||||
private static void verifyFile(MessageFileVerifier verifier) {
|
private static void verifyFile(MessageFileVerifier verifier) {
|
||||||
Map<String, Boolean> missingKeys = verifier.getMissingKeys();
|
Map<String, Boolean> missingKeys = verifier.getMissingKeys();
|
||||||
if (!missingKeys.isEmpty()) {
|
if (!missingKeys.isEmpty()) {
|
||||||
@ -132,7 +143,6 @@ public final class MessagesVerifierRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<File> getMessagesFiles() {
|
private static List<File> getMessagesFiles() {
|
||||||
final Pattern messageFilePattern = Pattern.compile("messages_[a-z]{2,7}\\.yml");
|
|
||||||
File folder = new File(MESSAGES_FOLDER);
|
File folder = new File(MESSAGES_FOLDER);
|
||||||
File[] files = folder.listFiles();
|
File[] files = folder.listFiles();
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
@ -141,7 +151,7 @@ public final class MessagesVerifierRunner {
|
|||||||
|
|
||||||
List<File> messageFiles = new ArrayList<>();
|
List<File> messageFiles = new ArrayList<>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
if (messageFilePattern.matcher(file.getName()).matches()) {
|
if (MESSAGE_FILE_PATTERN.matcher(file.getName()).matches()) {
|
||||||
messageFiles.add(file);
|
messageFiles.add(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,32 +3,32 @@ package permissions;
|
|||||||
import utils.ANewMap;
|
import utils.ANewMap;
|
||||||
import utils.FileUtils;
|
import utils.FileUtils;
|
||||||
import utils.TagReplacer;
|
import utils.TagReplacer;
|
||||||
|
import utils.TaskOption;
|
||||||
|
import utils.ToolTask;
|
||||||
import utils.ToolsConstants;
|
import utils.ToolsConstants;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for formatting a permissions node list and
|
* Task responsible for formatting a permissions node list and
|
||||||
* for writing it to a file if desired.
|
* for writing it to a file if desired.
|
||||||
*/
|
*/
|
||||||
public class PermissionsListWriter {
|
public class PermissionsListWriter implements ToolTask {
|
||||||
|
|
||||||
private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md";
|
private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md";
|
||||||
|
|
||||||
public static void main(String[] args) {
|
@Override
|
||||||
// Ask if result should be written to file
|
public String getTaskName() {
|
||||||
Scanner scanner = new Scanner(System.in);
|
return "writePermissionsList";
|
||||||
System.out.println("Include description? [Enter 'n' for no]");
|
|
||||||
boolean includeDescription = !matches("n", scanner);
|
|
||||||
|
|
||||||
boolean writeToFile = false;
|
|
||||||
if (includeDescription) {
|
|
||||||
System.out.println("Write to file? [Enter 'y' for yes]");
|
|
||||||
writeToFile = matches("y", scanner);
|
|
||||||
}
|
}
|
||||||
scanner.close();
|
|
||||||
|
@Override
|
||||||
|
public void execute(Map<String, String> options) {
|
||||||
|
// Ask if result should be written to file
|
||||||
|
boolean includeDescription = options.get("include.description").equals("y");
|
||||||
|
boolean writeToFile = options.get("write.to.file").equals("y");
|
||||||
|
|
||||||
if (!includeDescription) {
|
if (!includeDescription) {
|
||||||
outputSimpleList();
|
outputSimpleList();
|
||||||
@ -39,6 +39,12 @@ public class PermissionsListWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<TaskOption> getOptions() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new TaskOption("include.description", "Include description? [y/n]", "y", "y", "n"),
|
||||||
|
new TaskOption("write.to.file", "Write to file? [y/n]", "n", "y", "n"));
|
||||||
|
}
|
||||||
|
|
||||||
private static void generateAndWriteFile() {
|
private static void generateAndWriteFile() {
|
||||||
final String permissionsTagValue = generatePermissionsList();
|
final String permissionsTagValue = generatePermissionsList();
|
||||||
@ -77,9 +83,4 @@ public class PermissionsListWriter {
|
|||||||
System.out.println("Total: " + nodes.size());
|
System.out.println("Total: " + nodes.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean matches(String answer, Scanner sc) {
|
|
||||||
String userInput = sc.nextLine();
|
|
||||||
return answer.equalsIgnoreCase(userInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
33
src/tools/utils/ScannerHelper.java
Normal file
33
src/tools/utils/ScannerHelper.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import fr.xephi.authme.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for retrieving an answer from a Scanner.
|
||||||
|
*/
|
||||||
|
public class ScannerHelper {
|
||||||
|
|
||||||
|
// def may be null to force the selection of one of the options
|
||||||
|
// options may be null to just select whatever comes in
|
||||||
|
public static String getAnswer(String def, Scanner scanner, String... options) {
|
||||||
|
while (true) {
|
||||||
|
String input = scanner.nextLine();
|
||||||
|
if (StringUtils.isEmpty(input) && def != null) {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options == null) {
|
||||||
|
return input;
|
||||||
|
} else {
|
||||||
|
for (String option : options) {
|
||||||
|
if (input.equals(option)) {
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Invalid answer, please try again");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/tools/utils/TaskOption.java
Normal file
35
src/tools/utils/TaskOption.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Option required by a tool task.
|
||||||
|
*/
|
||||||
|
public class TaskOption {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String description;
|
||||||
|
private final String defaultOption;
|
||||||
|
private final String[] options;
|
||||||
|
|
||||||
|
public TaskOption(String name, String description, String defaultOption, String... options) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.defaultOption = defaultOption;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultOption() {
|
||||||
|
return defaultOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getOptions() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
17
src/tools/utils/ToolTask.java
Normal file
17
src/tools/utils/ToolTask.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common interface for tool tasks. Note that the implementing tasks are instantiated
|
||||||
|
* with the default constructor. It is required that it be public.
|
||||||
|
*/
|
||||||
|
public interface ToolTask {
|
||||||
|
|
||||||
|
void execute(Map<String, String> options);
|
||||||
|
|
||||||
|
String getTaskName();
|
||||||
|
|
||||||
|
Iterable<TaskOption> getOptions();
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user