/**
* 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 io.nuun.kernel.api.plugin.InitState;
import io.nuun.kernel.api.plugin.context.InitContext;
import io.nuun.kernel.api.plugin.request.ClasspathScanRequest;
import org.seedstack.seed.core.internal.AbstractSeedPlugin;
import org.seedstack.seed.command.Argument;
import org.seedstack.seed.command.Command;
import org.seedstack.seed.command.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Nuun plugin in charge of collecting all commands definitions.
*/
public class CommandPlugin extends AbstractSeedPlugin {
private static final Logger LOGGER = LoggerFactory.getLogger(CommandPlugin.class);
private final Map<String, CommandDefinition> commandDefinitions = new HashMap<>();
@Override
public String name() {
return "command";
}
@Override
public InitState initialize(InitContext initContext) {
Map<Class<? extends Annotation>, Collection<Class<?>>> scannedClassesByAnnotationClass = initContext.scannedClassesByAnnotationClass();
Collection<Class<?>> commandAnnotatedClasses = scannedClassesByAnnotationClass.get(org.seedstack.seed.command.CommandDefinition.class);
for (Class<?> candidate : commandAnnotatedClasses) {
if (Command.class.isAssignableFrom(candidate)) {
org.seedstack.seed.command.CommandDefinition commandDefinitionAnnotation = candidate.getAnnotation(org.seedstack.seed.command.CommandDefinition.class);
if (commandDefinitionAnnotation != null) {
CommandDefinition commandDefinition = new CommandDefinition(commandDefinitionAnnotation, candidate.asSubclass(Command.class));
for (Field field : candidate.getDeclaredFields()) {
Argument argumentAnnotation = field.getAnnotation(Argument.class);
Option optionAnnotation = field.getAnnotation(Option.class);
field.setAccessible(true);
if (argumentAnnotation != null) {
commandDefinition.addArgumentField(argumentAnnotation, field);
} else if (optionAnnotation != null) {
commandDefinition.addOptionField(optionAnnotation, field);
}
}
commandDefinitions.put(commandDefinition.getQualifiedName(), commandDefinition);
LOGGER.trace("Command {} registered with {}", commandDefinition.getQualifiedName(), commandDefinition.getCommandActionClass().getCanonicalName());
}
}
}
LOGGER.debug("Registered " + commandDefinitions.size() + " command(s)");
return InitState.INITIALIZED;
}
@Override
public Collection<ClasspathScanRequest> classpathScanRequests() {
return classpathScanRequestBuilder().annotationType(org.seedstack.seed.command.CommandDefinition.class).build();
}
@Override
public Object nativeUnitModule() {
return new CommandModule(commandDefinitions);
}
}