package mil.nga.giat.geowave.core.cli.operations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameters;
import mil.nga.giat.geowave.core.cli.annotations.GeowaveOperation;
import mil.nga.giat.geowave.core.cli.api.Command;
import mil.nga.giat.geowave.core.cli.api.DefaultOperation;
import mil.nga.giat.geowave.core.cli.api.Operation;
import mil.nga.giat.geowave.core.cli.api.OperationParams;
import mil.nga.giat.geowave.core.cli.parser.CommandLineOperationParams;
import mil.nga.giat.geowave.core.cli.prefix.JCommanderPrefixTranslator;
import mil.nga.giat.geowave.core.cli.prefix.JCommanderTranslationMap;
import mil.nga.giat.geowave.core.cli.spi.OperationEntry;
import mil.nga.giat.geowave.core.cli.spi.OperationRegistry;
@GeowaveOperation(name = "help", parentOperation = GeowaveTopLevelSection.class)
@Parameters(commandDescription = "Get descriptions of arguments for " + "any GeoWave command")
public class HelpCommand extends
DefaultOperation implements
Command
{
@Override
public boolean prepare(
OperationParams inputParams ) {
super.prepare(inputParams);
CommandLineOperationParams params = (CommandLineOperationParams) inputParams;
params.setValidate(false);
params.setAllowUnknown(true);
// Prepared successfully.
return true;
}
@Override
public void execute(
OperationParams inputParams ) {
CommandLineOperationParams params = (CommandLineOperationParams) inputParams;
List<String> nameArray = new ArrayList<String>();
OperationRegistry registry = OperationRegistry.getInstance();
StringBuilder builder = new StringBuilder();
Operation lastOperation = null;
for (Map.Entry<String, Operation> entry : params.getOperationMap().entrySet()) {
if (entry.getValue() == this) {
continue;
}
nameArray.add(entry.getKey());
lastOperation = entry.getValue();
}
if (lastOperation == null) {
lastOperation = registry.getOperation(
GeowaveTopLevelSection.class).createInstance();
}
if (lastOperation != null) {
String usage = lastOperation.usage();
if (usage != null) {
System.out.println(usage);
}
else {
// This is done because if we don't, then JCommander will
// consider the given parameters as the Default parameters.
// It's also done so that we can parse prefix annotations
// and special delegate processing.
JCommanderPrefixTranslator translator = new JCommanderPrefixTranslator();
translator.addObject(lastOperation);
JCommanderTranslationMap map = translator.translate();
map.createFacadeObjects();
// Copy default parameters over for help display.
map.transformToFacade();
// Execute a prepare
// Add processed objects
JCommander jc = new JCommander();
for (Object obj : map.getObjects()) {
jc.addObject(obj);
}
String programName = StringUtils.join(
nameArray,
" ");
jc.setProgramName(programName);
jc.usage(builder);
// Trim excess newlines.
String operations = builder.toString().trim();
builder = new StringBuilder();
builder.append(operations);
builder.append("\n\n");
// Add sub-commands
OperationEntry lastEntry = registry.getOperation(lastOperation.getClass());
// Cast to list so we can sort it based on operation name.
List<OperationEntry> children = new ArrayList<OperationEntry>(
lastEntry.getChildren());
Collections.sort(
children,
getOperationComparator());
if (children.size() > 0) {
builder.append(" Commands:\n");
for (OperationEntry childEntry : children) {
// Get description annotation
Parameters p = childEntry.getOperationClass().getAnnotation(
Parameters.class);
// If not hidden, then output it.
if (p == null || !p.hidden()) {
builder.append(String.format(
" %s%n",
childEntry.getOperationName()));
if (p != null) {
String description = p.commandDescription();
builder.append(String.format(
" %s%n",
description));
}
else {
builder.append(" <no description>\n");
}
builder.append("\n");
}
}
}
// Trim excess newlines.
String output = builder.toString().trim();
System.out.println(output);
}
}
}
/**
* This will sort operations based on their name. Just looks prettier on
* output.
*
* @return
*/
private Comparator<OperationEntry> getOperationComparator() {
return new Comparator<OperationEntry>() {
@Override
public int compare(
OperationEntry o1,
OperationEntry o2 ) {
return o1.getOperationName().compareTo(
o2.getOperationName());
}
};
}
}