package org.cryptocoinpartners.command; import org.apache.commons.lang.StringUtils; import org.cryptocoinpartners.module.Context; import org.cryptocoinpartners.util.Injector; import org.cryptocoinpartners.util.ReflectionUtil; import org.reflections.Reflections; import javax.inject.Inject; import java.lang.reflect.Modifier; import java.util.*; /** * @author Tim Olson */ public abstract class CommandBase implements Command { @Override public String getUsageHelp() { return StringUtils.join(getCommandNames(getClass()),"|"); } @Override public void parse(String commandArguments) { } // these 2 are injected by ConsoleRunMode @Inject protected Context context; @Inject protected ConsoleWriter out; @Inject protected Injector injector; public static List<String> allCommandNames() { ArrayList<String> names = new ArrayList<>(commandClassesByName.keySet()); Collections.sort(names); return names; } public static Command commandForName( String name, Context context ) { Class<? extends Command> commandClass = commandClassesByName.get(name.toLowerCase()); if( commandClass == null ) return null; return context.attach(commandClass); } private static Map<String,Class<? extends Command>> commandClassesByName; static { commandClassesByName = new HashMap<>(); Reflections reflections = ReflectionUtil.getCommandReflections(); Set<Class<? extends Command>> commandClasses = reflections.getSubTypesOf(Command.class); for( Class<? extends Command> commandClass : commandClasses ) { int modifiers = commandClass.getModifiers(); if( Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) ) continue; for( String commandName : getCommandNames(commandClass) ) commandClassesByName.put(commandName.toLowerCase(),commandClass); } } private static String[] getCommandNames(Class<? extends Command> commandClass) { String[] commandNames; String className; CommandName commandNameAnn = commandClass.getAnnotation(CommandName.class); if( commandNameAnn != null ) { commandNames = commandNameAnn.value(); } else { className = commandClass.getSimpleName(); if( !className.endsWith("Command") ) { throw new Error("If the name of your subclass of CommandBase doesn't end with \"Command\" then you need to use the @CommandName(name) annotation to declare the name of your command"); } commandNames = new String[]{className.substring(0,className.length() - "Command".length()).toLowerCase()}; } return commandNames; } }