/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.management.internal.cli.help.utils;
import org.apache.geode.management.cli.CliMetaData;
import org.apache.geode.management.internal.cli.help.format.*;
import org.apache.geode.management.internal.cli.modes.CommandModes;
import org.apache.geode.management.internal.cli.modes.CommandModes.CommandMode;
import org.apache.geode.management.internal.cli.parser.Argument;
import org.apache.geode.management.internal.cli.parser.CommandTarget;
import org.apache.geode.management.internal.cli.parser.Option;
import org.apache.geode.management.internal.cli.parser.SyntaxConstants;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @since GemFire 7.0
*/
public class HelpUtils {
public static final String EXE_PREFIX_FOR_EXTERNAL_HELP =
org.apache.geode.management.internal.cli.shell.Gfsh.GFSH_APP_NAME + " ";
public static final String HELP__COMMAND_AVAILABLE = "Available";
public static final String HELP__COMMAND_NOTAVAILABLE = "Not Available";
private static final String NAME_NAME = "NAME";
private static final String SYNONYMS_NAME = "SYNONYMS";
private static final String SYNOPSIS_NAME = "SYNOPSIS";
private static final String SYNTAX_NAME = "SYNTAX";
private static final String ARGUMENTS_NAME = "ARGUMENTS";
private static final String OPTIONS_NAME = "PARAMETERS";
private static final String IS_AVAILABLE_NAME = "IS AVAILABLE";
private static final String MODES = "MODES";
private static final String REQUIRED_SUB_NAME = "Required: ";
private static final String DEFAULTVALUE_SUB_NAME = "Default value: ";
private static final String SYNONYMS_SUB_NAME = "Synonyms: ";
private static final String SPECIFIEDDEFAULTVALUE_SUB_NAME =
"Default (if the parameter is specified without value): ";
private static final String UNSPECIFIEDDEFAULTVALUE_VALUE_SUB_NAME =
"Default (if the parameter is not specified): ";
private static final String VALUE_FIELD = "value";
private static final String TRUE_TOKEN = "true";
private static final String FALSE_TOKEN = "false";
private static Help help(Block[] blocks) {
return new Help().setBlocks(blocks);
}
private static Block block(String heading, Row... rows) {
return new Block().setHeading(heading).setRows(rows);
}
private static Row row(String... info) {
return new Row().setInfo(info);
}
@Deprecated
public static Help getHelp(CommandTarget commandTarget) {
List<Block> blocks = new ArrayList<Block>();
// First we will have the block for NAME of the command
blocks.add(block(NAME_NAME, row(commandTarget.getCommandName())));
// Now add synonyms if any
if (commandTarget.getSynonyms() != null) {
blocks.add(block(SYNONYMS_NAME, row(commandTarget.getSynonyms())));
}
// Now comes the turn to display synopsis if any
if (commandTarget.getCommandHelp() != null && !commandTarget.getCommandHelp().equals("")) {
blocks.add(block(SYNOPSIS_NAME, row(commandTarget.getCommandHelp())));
}
// Now display the syntax for the command
StringBuffer buffer = new StringBuffer();
buffer.append(commandTarget.getCommandName());
// Create a list which will store optional arguments
List<Argument> optionalArguments = new ArrayList<Argument>();
for (Argument argument : commandTarget.getOptionParser().getArguments()) {
if (argument.isRequired()) {
buffer.append(" " + argument.getArgumentName());
} else {
optionalArguments.add(argument);
}
}
for (Argument argument : optionalArguments) {
buffer.append(" " + "[" + argument.getArgumentName() + "]");
}
// Create a list which will store optional options
List<Option> optionalOptions = new ArrayList<Option>();
for (Option option : commandTarget.getOptionParser().getOptions()) {
if (option.isRequired()) {
buffer.append(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption());
// String temp = SyntaxConstants.OPTION_VALUE_SPECIFIER + VALUE_TOKEN + "("
// + SyntaxConstants.OPTION_VALUE_SEPARATOR + VALUE_TOKEN + ")*";
String temp = buildOptionHelpText(option);
//
if (option.getSpecifiedDefaultValue() != null
&& !option.getSpecifiedDefaultValue().equals("")) {
buffer.append("(");
buffer.append(temp);
buffer.append(")?");
} else {
buffer.append(temp);
}
} else {
optionalOptions.add(option);
}
}
for (Option option : optionalOptions) {
buffer.append(" " + "[" + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption());
// String temp = SyntaxConstants.OPTION_VALUE_SPECIFIER + VALUE_TOKEN + "("
// + SyntaxConstants.OPTION_VALUE_SEPARATOR + VALUE_TOKEN + ")*";
String temp = buildOptionHelpText(option);
//
if (option.getSpecifiedDefaultValue() != null
&& !option.getSpecifiedDefaultValue().equals("")) {
buffer.append("(");
buffer.append(temp);
buffer.append(")?");
} else {
buffer.append(temp);
}
buffer.append("]");
}
blocks.add(block(SYNTAX_NAME, row(buffer.toString())));
// Detailed description of Arguments
if (commandTarget.getOptionParser().getArguments().size() > 0) {
List<Row> rows = new ArrayList<Row>();
for (Argument argument : commandTarget.getOptionParser().getArguments()) {
rows.add(row(argument.getArgumentName()
+ ((argument.getHelp() != null && !argument.getHelp().equals(""))
? ":" + argument.getHelp() : "")));
}
Row[] rowsArray = new Row[rows.size()];
blocks.add(block(ARGUMENTS_NAME, rows.toArray(rowsArray)));
}
// Detailed description of Options
if (commandTarget.getOptionParser().getOptions().size() > 0) {
List<Row> rows = new ArrayList<Row>();
for (Option option : commandTarget.getOptionParser().getOptions()) {
rows.add(
row(option.getLongOption() + ((option.getHelp() != null && !option.getHelp().equals(""))
? ":" + option.getHelp() : "")));
}
Row[] rowsArray = new Row[rows.size()];
blocks.add(block(OPTIONS_NAME, rows.toArray(rowsArray)));
}
Block[] blocksArray = new Block[blocks.size()];
for (int i = 0; i < blocks.size(); i++) {
blocksArray[i] = blocks.get(i);
}
return help(blocksArray);
}
/**
* Builds help for the specified command.
*
* @param commandTarget command specific target to use to generate help
* @param withinShell if <code>true</code> includes availabilty & doesn't include application name
* @return built NewHelp object for the given command target
*/
public static NewHelp getNewHelp(CommandTarget commandTarget, boolean withinShell) {
DataNode root = new DataNode(null, new ArrayList<DataNode>());
// First we will have the block for NAME of the command
DataNode name = new DataNode(NAME_NAME, new ArrayList<DataNode>());
name.addChild(new DataNode(commandTarget.getCommandName(), null));
root.addChild(name);
if (withinShell) {// include availabilty info
DataNode availability = new DataNode(IS_AVAILABLE_NAME, new ArrayList<DataNode>());
boolean isAvailable = false;
try {
isAvailable = commandTarget.isAvailable();
} catch (Exception e) {
isAvailable = false;
}
availability.addChild(new DataNode(String.valueOf(isAvailable), null));
root.addChild(availability);
}
// Now add synonyms if any
if (commandTarget.getSynonyms() != null) {
DataNode synonyms = new DataNode(SYNONYMS_NAME, new ArrayList<DataNode>());
for (String string : commandTarget.getSynonyms()) {
synonyms.addChild(new DataNode(string, null));
}
root.addChild(synonyms);
}
// Now comes the turn to display synopsis if any
if (commandTarget.getCommandHelp() != null && !commandTarget.getCommandHelp().equals("")) {
DataNode synopsis = new DataNode(SYNOPSIS_NAME, new ArrayList<DataNode>());
synopsis.addChild(new DataNode(commandTarget.getCommandHelp(), null));
root.addChild(synopsis);
}
// Now display the syntax for the command
StringBuffer buffer = new StringBuffer();
if (withinShell) {
buffer.append(commandTarget.getCommandName());
} else { // add app name in the syntax
buffer.append(EXE_PREFIX_FOR_EXTERNAL_HELP).append(commandTarget.getCommandName());
}
appendArguments(buffer, commandTarget);
appendOptions(buffer, commandTarget);
DataNode syntax = new DataNode(SYNTAX_NAME, new ArrayList<DataNode>());
syntax.addChild(new DataNode(buffer.toString(), null));
root.addChild(syntax);
// Detailed description of Arguments
if (commandTarget.getOptionParser().getArguments().size() > 0) {
DataNode arguments = new DataNode(ARGUMENTS_NAME, new ArrayList<DataNode>());
for (Argument argument : commandTarget.getOptionParser().getArguments()) {
DataNode argumentNode = new DataNode(argument.getArgumentName(), new ArrayList<DataNode>());
argumentNode
.addChild(new DataNode(((argument.getHelp() != null && !argument.getHelp().equals(""))
? argument.getHelp() : ""), null));
argumentNode.addChild(new DataNode(
REQUIRED_SUB_NAME + ((argument.isRequired()) ? TRUE_TOKEN : FALSE_TOKEN), null));
if (argument.getUnspecifiedDefaultValue() != null) {
argumentNode.addChild(
new DataNode(DEFAULTVALUE_SUB_NAME + argument.getUnspecifiedDefaultValue(), null));
}
arguments.addChild(argumentNode);
}
root.addChild(arguments);
}
try {
CommandModes modes = CommandModes.getInstance();
Collection<CommandMode> comModes = modes.getCommandModes(commandTarget.getCommandName());
DataNode modesDN = new DataNode(MODES, new ArrayList<DataNode>());
if (comModes != null) {
for (CommandMode cmd : comModes) {
StringBuffer sb = new StringBuffer();
List<Option> optionalOptions = new ArrayList<Option>();
sb.append(commandTarget.getCommandName()).append(" ");
if (!cmd.name.equals("default"))
appendRequiredOption(sb, getOption(commandTarget, cmd.leadOption));
for (String opt : cmd.options) {
if (!opt.equals(cmd.leadOption)) {
Option option = getOption(commandTarget, opt);
if (option.isRequired()) {
appendRequiredOption(sb, option);
} else
optionalOptions.add(option);
}
}
for (Option optOpt : optionalOptions)
appendOption(sb, optOpt);
DataNode modeDN = new DataNode(cmd.text, new ArrayList<DataNode>());
modeDN.addChild(new DataNode(sb.toString(), null));
modesDN.addChild(modeDN);
}
root.addChild(modesDN);
} else {
// modesDN.addChild(new DataNode("No command modes found", null));
// root.addChild(modesDN);
}
} catch (Exception e) {
} finally {
}
// Detailed description of Options
if (commandTarget.getOptionParser().getOptions().size() > 0) {
DataNode options = new DataNode(OPTIONS_NAME, new ArrayList<DataNode>());
for (Option option : commandTarget.getOptionParser().getOptions()) {
DataNode optionNode = new DataNode(option.getLongOption(), new ArrayList<DataNode>());
optionNode.addChild(new DataNode(
((option.getHelp() != null && !option.getHelp().equals("")) ? option.getHelp() : ""),
null));
if (option.getSynonyms() != null && option.getSynonyms().size() > 0) {
StringBuilder builder = new StringBuilder();
for (String string : option.getSynonyms()) {
if (builder.length() > 0) {
builder.append(",");
}
builder.append(string);
}
optionNode.addChild(new DataNode(SYNONYMS_SUB_NAME + builder.toString(), null));
}
optionNode.addChild(new DataNode(
REQUIRED_SUB_NAME + ((option.isRequired()) ? TRUE_TOKEN : FALSE_TOKEN), null));
if (option.getSpecifiedDefaultValue() != null
&& !option.getSpecifiedDefaultValue().equals("")) {
optionNode.addChild(new DataNode(
SPECIFIEDDEFAULTVALUE_SUB_NAME + option.getSpecifiedDefaultValue(), null));
}
if (option.getUnspecifiedDefaultValue() != null
&& !option.getUnspecifiedDefaultValue().equals("")) {
optionNode.addChild(new DataNode(
UNSPECIFIEDDEFAULTVALUE_VALUE_SUB_NAME + option.getUnspecifiedDefaultValue(), null));
}
options.addChild(optionNode);
}
root.addChild(options);
}
return new NewHelp(root);
}
private static Option getOption(CommandTarget commandTarget, String opt) {
for (Option option : commandTarget.getOptionParser().getOptions()) {
if (option.getLongOption().equals(opt))
return option;
}
return null;
}
private static void appendOptions(StringBuffer buffer, CommandTarget commandTarget) {
List<Option> optionalOptions = new ArrayList<Option>();
for (Option option : commandTarget.getOptionParser().getOptions()) {
if (option.isRequired()) {
appendRequiredOption(buffer, option);
} else {
optionalOptions.add(option);
}
}
for (Option option : optionalOptions) {
appendOption(buffer, option);
}
}
private static void appendRequiredOption(StringBuffer buffer, Option option) {
buffer.append(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption());
String temp = buildOptionHelpText(option);
if (option.getSpecifiedDefaultValue() != null
&& !option.getSpecifiedDefaultValue().equals("")) {
buffer.append("(").append(temp).append(")?");
} else {
buffer.append(temp);
}
}
private static void appendOption(StringBuffer buffer, Option option) {
buffer.append(" " + "[" + SyntaxConstants.LONG_OPTION_SPECIFIER + option.getLongOption());
String temp = buildOptionHelpText(option);
if (option.getSpecifiedDefaultValue() != null
&& !option.getSpecifiedDefaultValue().equals("")) {
buffer.append("(").append(temp).append(")?");
} else {
buffer.append(temp);
}
buffer.append("]");
}
private static void appendArguments(StringBuffer buffer, CommandTarget commandTarget) {
// Create a list which will store optional arguments
List<Argument> optionalArguments = new ArrayList<Argument>();
for (Argument argument : commandTarget.getOptionParser().getArguments()) {
if (argument.isRequired()) {
buffer.append(" " + argument.getArgumentName());
} else {
optionalArguments.add(argument);
}
}
for (Argument argument : optionalArguments) {
buffer.append(" " + "[" + argument.getArgumentName() + "]");
}
}
public static String buildOptionHelpText(Option option) {
String temp = SyntaxConstants.OPTION_VALUE_SPECIFIER + VALUE_FIELD;
if ((option.getValueSeparator() != null
&& !CliMetaData.ANNOTATION_NULL_VALUE.equals(option.getValueSeparator())
&& !option.getValueSeparator().equals(""))
|| isCollectionOrArrayType(option.getDataType())) {
temp += "(" + option.getValueSeparator() + VALUE_FIELD + ")*";
}
return temp;
}
private static boolean isCollectionOrArrayType(Class<?> typeToCheck) {
return typeToCheck != null
&& (typeToCheck.isArray() || Collection.class.isAssignableFrom(typeToCheck));
}
}