spring Command 源码
springboot Command 代码
文件路径:/spring-boot-project/spring-boot-tools/spring-boot-jarmode-layertools/src/main/java/org/springframework/boot/jarmode/layertools/Command.java
/*
* Copyright 2012-2020 the original author or authors.
*
* 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
*
* https://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.springframework.boot.jarmode.layertools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
/**
* A command that can be launched from the layertools jarmode.
*
* @author Phillip Webb
* @author Scott Frederick
*/
abstract class Command {
private final String name;
private final String description;
private final Options options;
private final Parameters parameters;
/**
* Create a new {@link Command} instance.
* @param name the name of the command
* @param description a description of the command
* @param options the command options
* @param parameters the command parameters
*/
Command(String name, String description, Options options, Parameters parameters) {
this.name = name;
this.description = description;
this.options = options;
this.parameters = parameters;
}
/**
* Return the name of this command.
* @return the command name
*/
String getName() {
return this.name;
}
/**
* Return the description of this command.
* @return the command description
*/
String getDescription() {
return this.description;
}
/**
* Return options that this command accepts.
* @return the command options
*/
Options getOptions() {
return this.options;
}
/**
* Return parameters that this command accepts.
* @return the command parameters
*/
Parameters getParameters() {
return this.parameters;
}
/**
* Run the command by processing the remaining arguments.
* @param args a mutable deque of the remaining arguments
*/
final void run(Deque<String> args) {
List<String> parameters = new ArrayList<>();
Map<Option, String> options = new HashMap<>();
while (!args.isEmpty()) {
String arg = args.removeFirst();
Option option = this.options.find(arg);
if (option != null) {
options.put(option, option.claimArg(args));
}
else {
parameters.add(arg);
}
}
run(options, parameters);
}
/**
* Run the actual command.
* @param options any options extracted from the arguments
* @param parameters any parameters extracted from the arguments
*/
protected abstract void run(Map<Option, String> options, List<String> parameters);
/**
* Static method that can be used to find a single command from a collection.
* @param commands the commands to search
* @param name the name of the command to find
* @return a {@link Command} instance or {@code null}.
*/
static Command find(Collection<? extends Command> commands, String name) {
for (Command command : commands) {
if (command.getName().equals(name)) {
return command;
}
}
return null;
}
/**
* Parameters that the command accepts.
*/
protected static final class Parameters {
private final List<String> descriptions;
private Parameters(String[] descriptions) {
this.descriptions = Collections.unmodifiableList(Arrays.asList(descriptions));
}
/**
* Return the parameter descriptions.
* @return the descriptions
*/
List<String> getDescriptions() {
return this.descriptions;
}
@Override
public String toString() {
return this.descriptions.toString();
}
/**
* Factory method used if there are no expected parameters.
* @return a new {@link Parameters} instance
*/
protected static Parameters none() {
return of();
}
/**
* Factory method used to create a new {@link Parameters} instance with specific
* descriptions.
* @param descriptions the parameter descriptions
* @return a new {@link Parameters} instance with the given descriptions
*/
protected static Parameters of(String... descriptions) {
return new Parameters(descriptions);
}
}
/**
* Options that the command accepts.
*/
protected static final class Options {
private final Option[] values;
private Options(Option[] values) {
this.values = values;
}
private Option find(String arg) {
if (arg.startsWith("--")) {
String name = arg.substring(2);
for (Option candidate : this.values) {
if (candidate.getName().equals(name)) {
return candidate;
}
}
throw new UnknownOptionException(name);
}
return null;
}
/**
* Return if this options collection is empty.
* @return if there are no options
*/
boolean isEmpty() {
return this.values.length == 0;
}
/**
* Return a stream of each option.
* @return a stream of the options
*/
Stream<Option> stream() {
return Arrays.stream(this.values);
}
/**
* Factory method used if there are no expected options.
* @return a new {@link Options} instance
*/
protected static Options none() {
return of();
}
/**
* Factory method used to create a new {@link Options} instance with specific
* values.
* @param values the option values
* @return a new {@link Options} instance with the given values
*/
protected static Options of(Option... values) {
return new Options(values);
}
}
/**
* An individual option that the command can accepts. Can either be an option with a
* value (e.g. {@literal --log debug}) or a flag (e.g. {@literal
* --verbose}).
*/
protected static final class Option {
private final String name;
private final String valueDescription;
private final String description;
private Option(String name, String valueDescription, String description) {
this.name = name;
this.description = description;
this.valueDescription = valueDescription;
}
/**
* Return the name of the option.
* @return the options name
*/
String getName() {
return this.name;
}
/**
* Return the description of the expected argument value or {@code null} if this
* option is a flag/switch.
* @return the option value description
*/
String getValueDescription() {
return this.valueDescription;
}
/**
* Return the name and the value description combined.
* @return the name and value description
*/
String getNameAndValueDescription() {
return this.name + ((this.valueDescription != null) ? " " + this.valueDescription : "");
}
/**
* Return a description of the option.
* @return the option description
*/
String getDescription() {
return this.description;
}
private String claimArg(Deque<String> args) {
if (this.valueDescription != null) {
if (args.isEmpty()) {
throw new MissingValueException(this.name);
}
return args.removeFirst();
}
return null;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return this.name.equals(((Option) obj).name);
}
@Override
public int hashCode() {
return this.name.hashCode();
}
@Override
public String toString() {
return this.name;
}
/**
* Factory method to create a flag/switch option.
* @param name the name of the option
* @param description a description of the option
* @return a new {@link Option} instance
*/
protected static Option flag(String name, String description) {
return new Option(name, null, description);
}
/**
* Factory method to create value option.
* @param name the name of the option
* @param valueDescription a description of the expected value
* @param description a description of the option
* @return a new {@link Option} instance
*/
protected static Option of(String name, String valueDescription, String description) {
return new Option(name, valueDescription, description);
}
}
}
相关信息
相关文章
spring MissingValueException 源码
0
赞
- 所属分类: 后端技术
- 本文标签: Spring Boot Spring Java
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦