Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.aesh.command.impl.internal.ProcessedCommand Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.aesh.command.impl.internal;
import org.aesh.command.Command;
import org.aesh.command.activator.CommandActivator;
import org.aesh.command.impl.activator.NullCommandActivator;
import org.aesh.command.impl.parser.CompleteStatus;
import org.aesh.command.impl.populator.AeshCommandPopulator;
import org.aesh.command.impl.result.NullResultHandler;
import org.aesh.command.invocation.CommandInvocation;
import org.aesh.command.invocation.InvocationProviders;
import org.aesh.command.parser.CommandLineParserException;
import org.aesh.command.parser.OptionParserException;
import org.aesh.command.populator.CommandPopulator;
import org.aesh.command.result.ResultHandler;
import org.aesh.command.validator.CommandValidator;
import org.aesh.readline.terminal.formatting.TerminalString;
import org.aesh.readline.util.Parser;
import org.aesh.selector.SelectorType;
import org.aesh.terminal.utils.Config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Ståle W. Pedersen
*/
public class ProcessedCommand, CI extends CommandInvocation> {
private final String name;
private final String description;
private final CommandValidator validator;
private final ResultHandler resultHandler;
private final CommandPopulator populator;
private final boolean disableParsing;
private CommandActivator activator;
private final boolean generateHelp;
private String version;
private List options;
private ProcessedOption arguments;
private ProcessedOption argument;
private final C command;
private final List aliases;
private List parserExceptions;
private CompleteStatus completeStatus;
public ProcessedCommand(String name, List aliases, C command,
String description, CommandValidator validator,
ResultHandler resultHandler,
boolean generateHelp, boolean disableParsing,
String version,
ProcessedOption arguments, List options,
ProcessedOption argument,
CommandPopulator populator, CommandActivator activator) throws OptionParserException {
this.name = name;
this.description = description;
this.aliases = aliases == null ? Collections.emptyList() : aliases;
this.validator = validator;
this.generateHelp = generateHelp;
this.disableParsing = disableParsing;
if(resultHandler != null)
this.resultHandler = resultHandler;
else
this.resultHandler = new NullResultHandler();
this.arguments = arguments;
this.argument = argument;
if(argument != null && arguments != null)
throw new OptionParserException("Argument and Arguments cannot be defined in the same Command");
this.options = new ArrayList<>();
this.command = command;
this.activator = activator == null ? new NullCommandActivator() : activator;
if(populator == null)
this.populator = new AeshCommandPopulator<>(this.command);
else
this.populator = populator;
setOptions(options);
if(generateHelp)
doGenerateHelp();
if(version != null && version.length() > 0) {
this.version = version;
doGenerateVersion();
}
parserExceptions = new ArrayList<>();
}
public List getOptions() {
return options;
}
public CommandActivator getActivator() {
return activator;
}
public List getAliases() {
return aliases;
}
public void addOption(ProcessedOption opt) throws OptionParserException {
this.options.add(new ProcessedOption(verifyThatNamesAreUnique(opt.shortName(), opt.name()), opt.name(),
opt.description(), opt.getArgument(), opt.isRequired(), opt.getValueSeparator(), opt.askIfNotSet(), opt.selectorType(),
opt.getDefaultValues(), opt.type(), opt.getFieldName(), opt.getOptionType(), opt.converter(),
opt.completer(), opt.validator(), opt.activator(), opt.getRenderer(), opt.parser(), opt.doOverrideRequired()));
options.get(options.size()-1).setParent(this);
}
private void setOptions(List options) throws OptionParserException {
for(ProcessedOption opt : options) {
this.options.add(new ProcessedOption(verifyThatNamesAreUnique(opt.shortName(), opt.name()), opt.name(),
opt.description(), opt.getArgument(), opt.isRequired(), opt.getValueSeparator(), opt.askIfNotSet(), opt.selectorType(),
opt.getDefaultValues(), opt.type(), opt.getFieldName(), opt.getOptionType(),
opt.converter(), opt.completer(), opt.validator(), opt.activator(), opt.getRenderer(),
opt.parser(), opt.doOverrideRequired()));
this.options.get(this.options.size()-1).setParent(this);
}
}
public String name() {
return name;
}
public String description() {
return description;
}
public CommandValidator validator() {
return validator;
}
public ResultHandler resultHandler() {
return resultHandler;
}
public boolean hasArguments() {
return arguments != null && arguments.hasMultipleValues();
}
public ProcessedOption getArguments() {
return arguments;
}
public void setArguments(ProcessedOption arguments) {
this.arguments = arguments;
this.arguments.setParent(this);
}
public CommandPopulator getCommandPopulator() {
return populator;
}
public C getCommand() {
return command;
}
public boolean generateHelp() {
return generateHelp;
}
public boolean disableParsing() {
return disableParsing;
}
public String version() {
return version;
}
private char verifyThatNamesAreUnique(String name, String longName) throws OptionParserException {
if(name != null)
return verifyThatNamesAreUnique(name.charAt(0), longName);
else
return verifyThatNamesAreUnique('\u0000', longName);
}
private char verifyThatNamesAreUnique(char name, String longName) throws OptionParserException {
if(longName != null && longName.length() > 0 && findLongOption(longName) != null) {
throw new OptionParserException("Option --"+longName+" is already added to Param: "+this.toString());
}
if(name != '\u0000' && findOption(String.valueOf(name)) != null) {
throw new OptionParserException("Option -"+name+" is already added to Param: "+this.toString());
}
//if name is null, use one based on name
if(name == '\u0000' && (longName == null || longName.length() == 0))
throw new OptionParserException("Neither option name and option long name can be both null");
return name;
}
private char findPossibleName(String longName) throws OptionParserException {
for(int i=0; i < longName.length(); i++) {
if(findOption(String.valueOf(longName.charAt(i))) == null)
return longName.charAt(i);
}
//all chars are taken
throw new OptionParserException("All option names are taken, please specify a unique name");
}
public ProcessedOption findOption(String name) {
for (ProcessedOption option : getOptions())
if(option.shortName() != null &&
option.shortName().equals(name) &&
option.activator().isActivated(new ParsedCommand(this)))
return option;
return null;
}
public ProcessedOption findOptionNoActivatorCheck(String name) {
for (ProcessedOption option : getOptions())
if(option.shortName() != null &&
option.shortName().equals(name))
return option;
return null;
}
/**
* Generic search for matching options with input that start with either -- or -
*
* @param input input
* @return matching option
*/
public ProcessedOption searchAllOptions(String input) {
if (input.startsWith("--")) {
ProcessedOption currentOption = findLongOptionNoActivatorCheck(input.substring(2));
if(currentOption == null && input.contains("="))
currentOption = startWithLongOptionNoActivatorCheck(input.substring(2));
if (currentOption != null)
currentOption.setLongNameUsed(true);
//need to handle spaces in option names
else if(Parser.containsNonEscapedSpace(input)) {
return searchAllOptions(Parser.switchSpacesToEscapedSpacesInWord(input));
}
return currentOption;
}
else if (input.startsWith("-")) {
ProcessedOption currentOption = findOption(input.substring(1));
if(currentOption == null)
currentOption = startWithOption(input.substring(1));
if (currentOption != null)
currentOption.setLongNameUsed(false);
return currentOption;
}
else {
return null;
}
}
public ProcessedOption findLongOption(String name) {
for (ProcessedOption option : getOptions())
if(option.name() != null &&
option.name().equals(name) &&
option.activator().isActivated(new ParsedCommand(this)))
return option;
return null;
}
public ProcessedOption findLongOptionNoActivatorCheck(String name) {
for (ProcessedOption option : getOptions())
if(option.name() != null && option.name().equals(name))
return option;
return null;
}
public ProcessedOption startWithOption(String name) {
for (ProcessedOption option : getOptions())
if(option.shortName() != null && name.startsWith(option.shortName()) &&
option.activator().isActivated(new ParsedCommand(this)))
return option;
return null;
}
public ProcessedOption startWithLongOption(String name) {
for (ProcessedOption option : getOptions())
if(name.startsWith(option.name()) &&
option.activator().isActivated(new ParsedCommand(this)))
return option;
return null;
}
public ProcessedOption startWithLongOptionNoActivatorCheck(String name) {
ProcessedOption longestMatch = null;
for (ProcessedOption option : getOptions()) {
if (name.startsWith(option.name())) {
if (longestMatch == null) {
longestMatch = option;
} else if (option.name().length() > longestMatch.name().length()) {
longestMatch = option;
}
}
}
return longestMatch;
}
public void clear() {
clearOptions();
if(arguments != null)
arguments.clear();
if(argument != null)
argument.clear();
parserExceptions.clear();
completeStatus = null;
}
protected void clearOptions() {
for (ProcessedOption processedOption : getOptions()) {
processedOption.clear();
}
}
private void doGenerateHelp() {
//only generate a help option if there is no other option already called help
if(findOption("help") == null) {
try {
ProcessedOption helpOption = ProcessedOptionBuilder
.builder()
.name("help")
.shortName('h')
.description("Displays information of the command and all options")
.hasValue(false)
.required(false)
.optionType(OptionType.BOOLEAN)
.type(Boolean.class)
.overrideRequired(true)
.fieldName("generatedHelp")
.build();
options.add(helpOption);
}
catch (OptionParserException e) {
e.printStackTrace();
}
}
}
public boolean isGenerateHelpOptionSet() {
ProcessedOption helpOption = findLongOptionNoActivatorCheck("help");
return helpOption != null && helpOption.getValue() != null;
}
private void doGenerateVersion() {
//only generate a version option if there is no other option already called version
if(findOption("version") == null) {
try {
ProcessedOption versionOption = ProcessedOptionBuilder
.builder()
.name("version")
.shortName('v')
.description("Displays version information of the command")
.hasValue(false)
.required(false)
.optionType(OptionType.BOOLEAN)
.type(Boolean.class)
.overrideRequired(true)
.fieldName("generatedVersion")
.build();
options.add(versionOption);
}
catch (OptionParserException e) {
e.printStackTrace();
}
}
}
public boolean isGenerateVersionOptionSet() {
ProcessedOption versionOption = findLongOptionNoActivatorCheck("version");
return versionOption != null && versionOption.getValue() != null;
}
/**
* Return all option names that not already have a value
* and is enabled
*/
public List getOptionLongNamesWithDash() {
List opts = getOptions();
List names = new ArrayList<>(opts.size());
for (ProcessedOption o : opts) {
if(o.getValues().size() == 0 &&
o.activator().isActivated(new ParsedCommand(this)))
names.add(o.getRenderedNameWithDashes());
}
return names;
}
public List findPossibleLongNamesWithDash(String name) {
List opts = getOptions();
List names = new ArrayList<>(opts.size());
for (ProcessedOption o : opts) {
if(((o.shortName() != null && o.shortName().equals(name) &&
!o.isLongNameUsed() && o.getValues().size() == 0) ||
(o.name().startsWith(name) && o.getValues().size() == 0)) &&
o.activator().isActivated(new ParsedCommand(this)))
names.add(o.getRenderedNameWithDashes());
}
return names;
}
public List findPossibleLongNames(String name) {
if(name.startsWith("--"))
name = name.substring(2);
List opts = getOptions();
List names = new ArrayList<>(opts.size());
for (ProcessedOption o : opts) {
if(((o.shortName() != null && o.shortName().equals(name) &&
!o.isLongNameUsed() && o.getValues().size() == 0) ||
(o.name().startsWith(name) && o.getValues().size() == 0)) &&
o.activator().isActivated(new ParsedCommand(this)))
names.add(o.name());
}
return names;
}
/**
* @return returns true if the command has any options with askIfNotSet to true
* and its value is not set.
*/
public boolean hasAskIfNotSet() {
for(ProcessedOption opt : getOptions()) {
if(opt.askIfNotSet() && opt.hasValue() && opt.getValues().isEmpty() && !opt.hasDefaultValue())
return true;
}
return false;
}
public List getAllAskIfNotSet() {
List options = new ArrayList<>();
for(ProcessedOption opt : getOptions()) {
if(opt.askIfNotSet() && opt.hasValue() && opt.getValues().isEmpty() && !opt.hasDefaultValue())
options.add(opt);
}
if(argument != null && argument.askIfNotSet() && argument.hasValue() && argument.getValues().isEmpty() && !argument.hasDefaultValue())
options.add(argument);
if(arguments != null && arguments.askIfNotSet() && arguments.hasValue() && arguments.getValues().isEmpty() && !arguments.hasDefaultValue())
options.add(arguments);
return options;
}
/**
* Returns a description String based on the defined command and options.
* Useful when printing "help" info etc.
*
*/
public String printHelp(String commandName) {
int maxLength = 0;
int width = 80;
List opts = getOptions();
for (ProcessedOption o : opts) {
if(o.getFormattedLength() > maxLength)
maxLength = o.getFormattedLength();
}
StringBuilder sb = new StringBuilder();
//first line
sb.append("Usage: ");
if(commandName == null || commandName.length() == 0)
sb.append(name());
else
sb.append(commandName);
if(opts.size() > 0)
sb.append(" []");
if(argument != null) {
if(argument.isTypeAssignableByResourcesOrFile())
sb.append(" ");
else
sb.append(" <").append(argument.getFieldName()).append(">");
}
if(arguments != null) {
if(arguments.isTypeAssignableByResourcesOrFile())
sb.append(" []");
else
sb.append(" [<").append(arguments.getFieldName()).append(">]");
}
sb.append(Config.getLineSeparator());
//second line
sb.append(description()).append(Config.getLineSeparator());
//options and arguments
if (opts.size() > 0)
sb.append(Config.getLineSeparator()).append("Options:").append(Config.getLineSeparator());
for (ProcessedOption o : opts)
sb.append(o.getFormattedOption(2, maxLength+4, width)).append(Config.getLineSeparator());
if(arguments != null) {
sb.append(Config.getLineSeparator()).append("Arguments:").append(Config.getLineSeparator());
sb.append(arguments.getFormattedOption(2, maxLength+4, width)).append(Config.getLineSeparator());
}
if(argument != null) {
sb.append(Config.getLineSeparator()).append("Argument:").append(Config.getLineSeparator());
sb.append(argument.getFormattedOption(2, maxLength+4, width)).append(Config.getLineSeparator());
}
return sb.toString();
}
@Override
public String toString() {
return "ProcessedCommand{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", options=" + getOptions()
+ '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ProcessedCommand)) return false;
ProcessedCommand that = (ProcessedCommand) o;
if (!name.equals(that.name)) return false;
if (description != null ? !description.equals(that.description) : that.description != null) return false;
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + (description != null ? description.hashCode() : 0);
return result;
}
public boolean anyOptionsSet() {
for(ProcessedOption o : getOptions()) {
if (o.hasValue() && o.getValue() != null || !o.hasValue() && o.getValue() != null)
return true;
}
if(hasArgument() && argument.getValue() != null)
return true;
if(hasArguments() && arguments.getValue() != null)
return true;
return false;
}
public boolean hasLongOption(String optionName) {
for(ProcessedOption o : getOptions()) {
if (o.name().equals(optionName))
return true;
}
return false;
}
public boolean hasOptions() {
List opts = getOptions();
return opts != null && opts.size() > 0;
}
//will only return true if the optionName equals an option and it does
//not start with another option name
public boolean hasUniqueLongOption(String optionName) {
if(hasLongOption(optionName)) {
for(ProcessedOption o : getOptions()) {
if(o.name().startsWith(optionName) && !o.name().equals(optionName))
return false;
}
return true;
}
return false;
}
public void updateInvocationProviders(InvocationProviders invocationProviders) {
updateOptionsInvocationProviders(invocationProviders);
if (argument != null) {
argument.updateInvocationProviders(invocationProviders);
}
if (arguments != null) {
arguments.updateInvocationProviders(invocationProviders);
}
activator = invocationProviders.getCommandActivatorProvider().enhanceCommandActivator(activator);
}
protected void updateOptionsInvocationProviders(InvocationProviders invocationProviders) {
for (ProcessedOption option : getOptions()) {
option.updateInvocationProviders(invocationProviders);
}
}
public void addParserException(CommandLineParserException exception) {
parserExceptions.add(exception);
}
public List parserExceptions() {
return parserExceptions;
}
public boolean hasOptionsWithInjectedValues() {
for(ProcessedOption option : options)
if(option.getValue() != null)
return true;
return false;
}
public boolean hasOptionWithOverrideRequired() {
for(ProcessedOption option : options) {
if(option.getValue() != null && option.doOverrideRequired())
return true;
}
return false;
}
public CompleteStatus completeStatus() {
return completeStatus;
}
public void setCompleteStatus(CompleteStatus completeStatus) {
this.completeStatus = completeStatus;
}
public void setArgument(ProcessedOption arg) {
this.argument = arg;
this.argument.setParent(this);
}
public ProcessedOption getArgument() {
return argument;
}
public boolean hasArgument() {
return argument != null;
}
public boolean hasArgumentWithNoValue() {
return argument != null && argument.getValue() == null;
}
public boolean hasArgumentsWithNoValue() {
return arguments != null && arguments.getValue() == null;
}
public boolean hasSelector() {
boolean selector = false;
for(ProcessedOption opt : getOptions()) {
// if we have an option that's marked with override required and is set
// it should override selector
if(opt.doOverrideRequired() && opt.getValue() != null)
return false;
if(opt.selectorType() != SelectorType.NO_OP && opt.hasValue())
selector = true;
}
return selector;
}
public List getAllSelectors() {
List options = new ArrayList<>();
for(ProcessedOption opt : getOptions()) {
if(opt.selectorType() != SelectorType.NO_OP && opt.hasValue() && opt.getValue() == null)
options.add(opt);
}
if(argument != null && argument.selectorType() != SelectorType.NO_OP &&
(argument.hasValue() || argument.getOptionType().equals(OptionType.BOOLEAN)))
options.add(argument);
if(arguments != null && arguments.selectorType() != SelectorType.NO_OP && arguments.hasValue())
options.add(arguments);
return options;
}
}