change: 调整指令样式; 调整config指令.
This commit is contained in:
@@ -12,10 +12,10 @@ import com.serliunx.ddns.support.InstanceContextHolder;
|
||||
import com.serliunx.ddns.support.SystemInitializer;
|
||||
import com.serliunx.ddns.support.command.CommandCompleter;
|
||||
import com.serliunx.ddns.support.command.CommandDispatcher;
|
||||
import com.serliunx.ddns.support.command.target.ConfigCommand;
|
||||
import com.serliunx.ddns.support.command.target.HelpCommand;
|
||||
import com.serliunx.ddns.support.command.target.ReloadCommand;
|
||||
import com.serliunx.ddns.support.command.target.StopCommand;
|
||||
import com.serliunx.ddns.support.command.target.config.ConfigCommand;
|
||||
import com.serliunx.ddns.support.log.JLineAdaptAppender;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package com.serliunx.ddns.support.command;
|
||||
|
||||
import com.serliunx.ddns.ManagerLite;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.ParsedLine;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 指令的抽象实现
|
||||
@@ -39,6 +44,11 @@ public abstract class AbstractCommand implements Command {
|
||||
return subCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addSubCommand(Command command) {
|
||||
subCommands.add(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
@@ -49,6 +59,67 @@ public abstract class AbstractCommand implements Command {
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指令逻辑默认实现: 调用子命令
|
||||
*
|
||||
* @param args 当前指令参数
|
||||
* @return 成功执行返回真, 否则返回假. (目前没影响)
|
||||
*/
|
||||
@Override
|
||||
public boolean onCommand(String[] args) {
|
||||
if (!hasArgs(args) ||
|
||||
args.length < 2) {
|
||||
log.warn("用法 => {}", getUsage());
|
||||
return true;
|
||||
}
|
||||
|
||||
final String subCommand = args[0];
|
||||
List<Command> subCommands = getSubCommands();
|
||||
for (Command command : subCommands) {
|
||||
if (command.getName().equalsIgnoreCase(subCommand)) {
|
||||
return command.onCommand(CommandDispatcher.splitArgs(args));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgs() {
|
||||
if (subCommands == null ||
|
||||
subCommands.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return subCommands.stream()
|
||||
.map(Command::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(LineReader reader, ParsedLine line, int index, List<Candidate> candidates) {
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String currentWord = line.word();
|
||||
// 补全子命令
|
||||
final List<Command> subCommands = getSubCommands();
|
||||
if (index == 1) {
|
||||
subCommands.forEach(c -> {
|
||||
if (c.getName().startsWith(currentWord)) {
|
||||
candidates.add(new Candidate(c.getName()));
|
||||
}
|
||||
});
|
||||
} else { // 交给子命令补全
|
||||
for (Command c : subCommands) {
|
||||
if (c.getName().equals(line.words().get(1))) {
|
||||
c.onComplete(reader, line, index, candidates);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasArgs(String[] args) {
|
||||
return args.length > 0;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,13 @@ public interface Command {
|
||||
*/
|
||||
List<Command> getSubCommands();
|
||||
|
||||
/**
|
||||
* 添加子命令
|
||||
*
|
||||
* @param command 子命令
|
||||
*/
|
||||
void addSubCommand(Command command);
|
||||
|
||||
/**
|
||||
* 获取该指令的描述
|
||||
*/
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.serliunx.ddns.support.command.target;
|
||||
|
||||
import com.serliunx.ddns.config.Configuration;
|
||||
import com.serliunx.ddns.support.command.AbstractCommand;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.ParsedLine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 指令: config
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/1/22
|
||||
*/
|
||||
public class ConfigCommand extends AbstractCommand {
|
||||
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
private final Configuration configuration;
|
||||
|
||||
public ConfigCommand(Configuration configuration) {
|
||||
super("config", null, "调整配置信息", "config <配置项> 新的值");
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(String[] args) {
|
||||
if (!hasArgs(args) ||
|
||||
args.length < 2) {
|
||||
log.warn("用法 => {}", getUsage());
|
||||
return true;
|
||||
}
|
||||
final String target = args[0];
|
||||
final String value = args[1];
|
||||
return configuration.modify(target, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgs() {
|
||||
final Map<String, String> allKeyAndValue;
|
||||
if (configuration == null ||
|
||||
(allKeyAndValue = configuration.getAllKeyAndValue()) == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return new ArrayList<>(allKeyAndValue.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(LineReader reader, ParsedLine line, int index, List<Candidate> candidates) {
|
||||
if (index < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String currentWord = line.word();
|
||||
|
||||
// 补全配置键
|
||||
if (index == 1) {
|
||||
final Map<String, String> allKeyAndValue;
|
||||
if (configuration == null ||
|
||||
(allKeyAndValue = configuration.getAllKeyAndValue()) == null) {
|
||||
return;
|
||||
}
|
||||
allKeyAndValue.keySet().forEach(k -> {
|
||||
if (k.startsWith(currentWord)) {
|
||||
candidates.add(new Candidate(k));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,21 @@ public class HelpCommand extends AbstractCommand {
|
||||
public boolean onCommand(String[] args) {
|
||||
final Map<String, Command> commands = getAllCommands();
|
||||
|
||||
log.info("==========================================");
|
||||
if (hasArgs(args)) {
|
||||
final String cmd = args[0];
|
||||
final Command command = commands.get(cmd);
|
||||
if (command == null) {
|
||||
log.warn("无法找到指令 {} 的相关信息, 请使用 help 查看可用的指令及帮助!", cmd);
|
||||
System.out.printf("无法找到指令 %s 的相关信息, 请使用 help 查看可用的指令及帮助!%n", cmd);
|
||||
} else {
|
||||
log.info("指令:{} - {} - {}", cmd, command.getDescription(), command.getUsage());
|
||||
List<Command> subCommands = command.getSubCommands();
|
||||
if (subCommands == null ||
|
||||
subCommands.isEmpty()) {
|
||||
System.out.printf("指令:%s - %s - %s%n", cmd, command.getDescription(), command.getUsage());
|
||||
} else {
|
||||
subCommands.forEach(c -> {
|
||||
System.out.printf("%s - %s - %s%n", c.getName(), c.getDescription(), c.getUsage());
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
commands.forEach((k, v) -> {
|
||||
@@ -43,12 +50,11 @@ public class HelpCommand extends AbstractCommand {
|
||||
if (k.equals(getName())) {
|
||||
return;
|
||||
}
|
||||
log.info("{} - {} - {}", k, v.getDescription(), v.getUsage());
|
||||
System.out.printf("%s - %s - %s%n", k, v.getDescription(), v.getUsage());
|
||||
});
|
||||
log.info("");
|
||||
log.info("使用 help <指令> 来查看更详细的帮助信息.");
|
||||
System.out.println();
|
||||
System.out.println("使用 help <指令> 来查看更详细的帮助信息.");
|
||||
}
|
||||
log.info("==========================================");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.serliunx.ddns.support.command.target.config;
|
||||
|
||||
import com.serliunx.ddns.config.Configuration;
|
||||
import com.serliunx.ddns.support.command.AbstractCommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 指令: config
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/1/22
|
||||
*/
|
||||
public class ConfigCommand extends AbstractCommand {
|
||||
|
||||
public ConfigCommand(Configuration configuration) {
|
||||
super("config", new ArrayList<>(), "调整配置信息", "config <get/set/...>");
|
||||
// 子命令: set
|
||||
addSubCommand(new ConfigSetCommand(configuration));
|
||||
// 子命令: get
|
||||
addSubCommand(new ConfigGetCommand(configuration));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.serliunx.ddns.support.command.target.config;
|
||||
|
||||
import com.serliunx.ddns.config.Configuration;
|
||||
import org.jline.reader.Candidate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* config 指令相关工具方法
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/2/4
|
||||
*/
|
||||
final class ConfigCommandHelper {
|
||||
|
||||
/**
|
||||
* 获取所有配置键, 作为参数返回
|
||||
*
|
||||
* @param configuration 配置信息
|
||||
* @return 配置键集合
|
||||
*/
|
||||
static List<String> getArgs(Configuration configuration) {
|
||||
final Map<String, String> allKeyAndValue;
|
||||
if (configuration == null ||
|
||||
(allKeyAndValue = configuration.getAllKeyAndValue()) == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return new ArrayList<>(allKeyAndValue.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* 补全配置键
|
||||
*
|
||||
* @param configuration 配置键
|
||||
* @param currentWord 当前输入内容
|
||||
* @param candidates 候选参数列表
|
||||
*/
|
||||
static void completeConfigKeys(Configuration configuration, String currentWord, List<Candidate> candidates) {
|
||||
final Map<String, String> allKeyAndValue;
|
||||
if (configuration == null ||
|
||||
(allKeyAndValue = configuration.getAllKeyAndValue()) == null) {
|
||||
return;
|
||||
}
|
||||
allKeyAndValue.keySet().forEach(k -> {
|
||||
if (k.startsWith(currentWord)) {
|
||||
candidates.add(new Candidate(k));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.serliunx.ddns.support.command.target.config;
|
||||
|
||||
import com.serliunx.ddns.config.Configuration;
|
||||
import com.serliunx.ddns.support.command.AbstractCommand;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.ParsedLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 指令: config get
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/2/4
|
||||
*/
|
||||
public final class ConfigGetCommand extends AbstractCommand {
|
||||
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
private final Configuration configuration;
|
||||
|
||||
public ConfigGetCommand(Configuration configuration) {
|
||||
super("get", null, "获取指定配置项的值", "config get <配置项>");
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(String[] args) {
|
||||
if (!hasArgs(args) ||
|
||||
args.length < 1) {
|
||||
log.warn("用法 => {}", getUsage());
|
||||
return true;
|
||||
}
|
||||
System.out.println(configuration.getString(args[0]));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgs() {
|
||||
return ConfigCommandHelper.getArgs(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(LineReader reader, ParsedLine line, int index, List<Candidate> candidates) {
|
||||
if (index == 2)
|
||||
ConfigCommandHelper.completeConfigKeys(configuration, line.word(), candidates);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.serliunx.ddns.support.command.target.config;
|
||||
|
||||
import com.serliunx.ddns.config.Configuration;
|
||||
import com.serliunx.ddns.support.command.AbstractCommand;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.ParsedLine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 指令: config set
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/2/4
|
||||
*/
|
||||
public final class ConfigSetCommand extends AbstractCommand {
|
||||
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
private final Configuration configuration;
|
||||
|
||||
public ConfigSetCommand(Configuration configuration) {
|
||||
super("set", null, "设置指定配置项的值", "config set <配置项> <新的值>");
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(String[] args) {
|
||||
if (!hasArgs(args) ||
|
||||
args.length < 2) {
|
||||
log.warn("用法 => {}", getUsage());
|
||||
return true;
|
||||
}
|
||||
final String target = args[0];
|
||||
final String value = args[1];
|
||||
return configuration.modify(target, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgs() {
|
||||
return ConfigCommandHelper.getArgs(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(LineReader reader, ParsedLine line, int index, List<Candidate> candidates) {
|
||||
if (index == 2)
|
||||
ConfigCommandHelper.completeConfigKeys(configuration, line.word(), candidates);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user