/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.seed.core.internal.command; import com.google.common.base.Strings; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import org.seedstack.seed.command.CommandRegistry; import org.seedstack.seed.SeedException; import org.seedstack.seed.command.Argument; import org.seedstack.seed.command.Command; import org.seedstack.seed.command.Option; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * Implementation of the {@link CommandRegistry}. */ class CommandRegistryImpl implements CommandRegistry { @Inject private Map<String, CommandDefinition> commandDefinitions; @Inject private Injector injector; @Override public Set<String> getCommandList() { return commandDefinitions.keySet(); } @Override public List<Option> getOptionsInfo(String scope, String name) { String qualifiedName = buildQualifiedName(scope, name); // Lookup for command definition CommandDefinition commandDefinitionDefinition = commandDefinitions.get(qualifiedName); if (commandDefinitionDefinition == null) { throw SeedException.createNew(CommandErrorCode.COMMAND_DEFINITION_NOT_FOUND).put("command", qualifiedName); } List<Option> options = new ArrayList<>(); for (OptionDefinition optionDefinition : commandDefinitionDefinition.getOptionDefinitions()) { options.add(optionDefinition.getAnnotation()); } return options; } @Override public List<Argument> getArgumentsInfo(String scope, String name) { String qualifiedName = buildQualifiedName(scope, name); // Lookup for command definition CommandDefinition commandDefinitionDefinition = commandDefinitions.get(qualifiedName); if (commandDefinitionDefinition == null) { throw SeedException.createNew(CommandErrorCode.COMMAND_DEFINITION_NOT_FOUND).put("command", qualifiedName); } List<Argument> arguments = new ArrayList<>(); for (ArgumentDefinition argumentDefinition : commandDefinitionDefinition.getArgumentDefinitions()) { arguments.add(argumentDefinition.getAnnotation()); } return arguments; } @Override public org.seedstack.seed.command.CommandDefinition getCommandInfo(String scope, String name) { String qualifiedName = buildQualifiedName(scope, name); // Lookup for command definition CommandDefinition commandDefinitionDefinition = commandDefinitions.get(qualifiedName); if (commandDefinitionDefinition == null) { throw SeedException.createNew(CommandErrorCode.COMMAND_DEFINITION_NOT_FOUND).put("command", qualifiedName); } return commandDefinitionDefinition.getAnnotation(); } @Override public Command createCommand(String scope, String name, List<String> args, Map<String, String> options) { String qualifiedName = buildQualifiedName(scope, name); // Lookup for command definition CommandDefinition commandDefinitionDefinition = commandDefinitions.get(qualifiedName); if (commandDefinitionDefinition == null) { throw SeedException.createNew(CommandErrorCode.COMMAND_DEFINITION_NOT_FOUND).put("command", qualifiedName); } // Retrieve the command instance Command command; try { command = injector.getInstance(Key.get(Command.class, Names.named(qualifiedName))); } catch (Exception e) { throw SeedException.wrap(e, CommandErrorCode.UNABLE_TO_INSTANTIATE_COMMAND).put("command", qualifiedName); } // Check the number of arguments if (args.size() > commandDefinitionDefinition.getArgumentDefinitions().size()) { throw SeedException.createNew(CommandErrorCode.TOO_MANY_ARGUMENTS).put("command", qualifiedName).put("accepted", commandDefinitionDefinition.getArgumentDefinitions().size()).put("given", args.size()); } // Set command arguments int i = 0; for (ArgumentDefinition argumentDefinition : commandDefinitionDefinition.getArgumentDefinitions()) { String value = null; if (i >= args.size()) { if (argumentDefinition.isMandatory()) { throw SeedException.createNew(CommandErrorCode.MISSING_ARGUMENTS).put("command", qualifiedName).put("required", i + 1).put("given", args.size()); } else if (!Strings.isNullOrEmpty(argumentDefinition.getDefaultValue())) { value = argumentDefinition.getDefaultValue(); } } else { value = args.get(i); } if (value != null) { try { argumentDefinition.getField().set(command, value); } catch (IllegalAccessException e) { throw SeedException.wrap(e, CommandErrorCode.UNABLE_TO_INJECT_ARGUMENT).put("command", qualifiedName).put("argument", argumentDefinition.getName()); } } i++; } // Set command options for (OptionDefinition optionDefinition : commandDefinitionDefinition.getOptionDefinitions()) { String value = null; if (optionDefinition.hasArgument()) { if (options.containsKey(optionDefinition.getName())) { value = options.get(optionDefinition.getName()); } else { if (optionDefinition.isMandatory()) { if (Strings.isNullOrEmpty(optionDefinition.getDefaultValue())) { throw SeedException.createNew(CommandErrorCode.MISSING_MANDATORY_OPTION).put("command", qualifiedName).put("option", optionDefinition.getName()); } else { value = optionDefinition.getDefaultValue(); } } else if (!Strings.isNullOrEmpty(optionDefinition.getDefaultValue())) { value = optionDefinition.getDefaultValue(); } } if (value != null) { try { optionDefinition.getField().set(command, value); } catch (IllegalAccessException e) { throw SeedException.wrap(e, CommandErrorCode.UNABLE_TO_INJECT_OPTION).put("command", qualifiedName).put("option", optionDefinition.getName()); } } } else { try { optionDefinition.getField().set(command, options.containsKey(optionDefinition.getName())); } catch (IllegalAccessException e) { throw SeedException.wrap(e, CommandErrorCode.UNABLE_TO_INJECT_OPTION).put("command", qualifiedName).put("option", optionDefinition.getName()); } } } return command; } private String buildQualifiedName(String scope, String name) { return (Strings.isNullOrEmpty(scope) ? "" : scope + ":") + name; } }