From 7f5f3c5cea37b5b9fc33262a2ebfc5cd2cbc9843 Mon Sep 17 00:00:00 2001 From: Fabian Becker Date: Sun, 16 Nov 2014 14:47:17 +0100 Subject: [PATCH] Show useful info for classes with subtypes. closes #35 - Show assignable subtypes - Rename YamlStatistics to CommandLineStatistics --- src/eva2/cli/Main.java | 75 ++++++++++++++++++++++++--- src/eva2/cli/OptimizationBuilder.java | 6 +-- src/eva2/cli/ParameterGenerator.java | 2 +- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/eva2/cli/Main.java b/src/eva2/cli/Main.java index fe600fed..773d19a0 100644 --- a/src/eva2/cli/Main.java +++ b/src/eva2/cli/Main.java @@ -12,10 +12,12 @@ import eva2.optimization.statistics.*; import eva2.optimization.strategies.InterfaceOptimizer; import eva2.problems.InterfaceAdditionalPopulationInformer; import eva2.problems.InterfaceOptimizationProblem; +import eva2.tools.ReflectPackage; import eva2.util.annotation.Description; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +import java.lang.reflect.Modifier; import java.util.*; /** @@ -35,7 +37,7 @@ public class Main { Class clazz = Class.forName(className); printHelpFor(clazz); } catch (ClassNotFoundException e) { - System.out.printf("Class %s does not exist.\n", className); + System.out.printf("No help available for %s.\n", className); } System.exit(-1); } else { @@ -51,13 +53,49 @@ public class Main { printHelpFor(StatisticsParameters.class); } + /** + * Prints formatted help output for a specific class. + * + * If the class is an interface or abstract class additional information + * on assignable subclasses will be shown. + * + * @param clazz The class to show help for. + */ private static void printHelpFor(Class clazz) { System.out.println(clazz.getName() + "\n"); if (clazz.isAnnotationPresent(Description.class)) { Description description = clazz.getAnnotation(Description.class); - System.out.println(description.value()); + System.out.printf("%s\n\n", description.value()); } + /** + * In case we have an Abstract class or Interface show available + * sub types. + */ + if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) { + Class[] subTypes = ReflectPackage.getAssignableClassesInPackage(clazz.getPackage().getName(), clazz, true, true); + if (subTypes.length > 0) { + System.out.printf("Available types for %s\n\n", clazz.getName()); + for (Class type : subTypes) { + if (Modifier.isAbstract(type.getModifiers())) { + continue; + } + Description description = clazz.getAnnotation(Description.class); + System.out.printf("\t\033[1m%s\033[0m\n", type.getName()); + if (description != null) { + System.out.printf("\t\t%s", description.value()); + } else { + System.out.println("\t\tNo description available."); + } + } + System.out.println(); + } + } + + /** + * Get available parameters for this class and list them with their + * description. + */ ParameterGenerator generator = new ParameterGenerator(clazz, false); generator.generate(); Map> paramList = generator.getParameterList(); @@ -67,13 +105,35 @@ public class Main { System.out.println("Options:"); for (Parameter key : parameters) { - System.out.printf("\t\033[1m--%s\033[0m \033[4m%s\033[0m\n", key.getName(), key.getType().getName()); + Class type = key.getType(); + String typeDefinition; + if (type.isEnum()) { + Enum[] enumConstants = (Enum[])type.getEnumConstants(); + typeDefinition = "{"; + for (int i = 0; i < enumConstants.length; i++) { + typeDefinition += enumConstants[i].name(); + if (i != enumConstants.length - 1) { + typeDefinition += ","; + } + } + typeDefinition += "}"; + } else { + typeDefinition = key.getType().getName(); + } + System.out.printf("\t\033[1m--%s\033[0m \033[4m%s\033[0m\n", key.getName(), typeDefinition); System.out.printf("\t\t%s\n", key.getDescription()); } } System.out.print("\n\n"); } + /** + * This method takes a set of command line arguments and tries to construct + * OptimizationParameters and StatisticsParameters from it. It will use defaults if + * not otherwise configured. + * + * @param args Command line arguments + */ private static void executeArguments(String[] args) { InterfaceOptimizationParameters parameters = OptimizationBuilder.parseOptimizerArguments(args); InterfaceStatisticsParameters statisticsParameters = OptimizationBuilder.parseStatisticsArguments(args); @@ -88,7 +148,7 @@ public class Main { optimizationLog.put("numberOfRuns", statisticsParameters.getMultiRuns()); optimizationLog.put("seed", parameters.getRandomSeed()); - YamlStatistics yamlStatistics = new YamlStatistics(statisticsParameters); + CommandLineStatistics yamlStatistics = new CommandLineStatistics(statisticsParameters); /** * Runs optimization @@ -115,7 +175,10 @@ public class Main { } } -final class YamlStatistics implements InterfaceStatistics { +/** + * + */ +final class CommandLineStatistics implements InterfaceStatistics { private InterfaceStatisticsParameters statisticsParameters; private List> runs; private LinkedHashMap currentRun; @@ -124,7 +187,7 @@ final class YamlStatistics implements InterfaceStatistics { private int currentGeneration; - public YamlStatistics(InterfaceStatisticsParameters statisticsParameters) { + public CommandLineStatistics(InterfaceStatisticsParameters statisticsParameters) { super(); this.statisticsParameters = statisticsParameters; this.runs = new ArrayList<>(statisticsParameters.getMultiRuns()); diff --git a/src/eva2/cli/OptimizationBuilder.java b/src/eva2/cli/OptimizationBuilder.java index 1e4fe05e..56299663 100644 --- a/src/eva2/cli/OptimizationBuilder.java +++ b/src/eva2/cli/OptimizationBuilder.java @@ -170,10 +170,8 @@ public final class OptimizationBuilder { } else if (type.isArray() && ((ArgumentTree)tree.get(name)).getValue() != null) { // ToDo: Implement array parsing } else if (type.isEnum() && ((ArgumentTree)tree.get(name)).getValue() != null) { - int enumIndex = Integer.parseInt((String)((ArgumentTree)tree.get(name)).getValue()); - - // ToDo: Properly check - obj = type.getEnumConstants()[enumIndex]; + String enumName = (String)((ArgumentTree)tree.get(name)).getValue(); + obj = Enum.valueOf((Class)type, enumName); } else { // The subtree has the name of the class String className = (String)((ArgumentTree)tree.get(name)).getValue(); diff --git a/src/eva2/cli/ParameterGenerator.java b/src/eva2/cli/ParameterGenerator.java index 26dfbcf1..921b53ea 100644 --- a/src/eva2/cli/ParameterGenerator.java +++ b/src/eva2/cli/ParameterGenerator.java @@ -79,7 +79,7 @@ public class ParameterGenerator { } parameter = new Parameter(name, param.description(), type); } else { - parameter = new Parameter(name, "No description available", type); + parameter = new Parameter(name, "No description available.", type); } parameters.add(parameter);