change: 调整指令样式; 调整config指令.

This commit is contained in:
2025-02-04 10:32:41 +08:00
parent 6f88950359
commit 4a05256c59
9 changed files with 272 additions and 84 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -37,6 +37,13 @@ public interface Command {
*/
List<Command> getSubCommands();
/**
* 添加子命令
*
* @param command 子命令
*/
void addSubCommand(Command command);
/**
* 获取该指令的描述
*/

View File

@@ -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));
}
});
}
}
}

View File

@@ -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;
}

View File

@@ -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));
}
}

View File

@@ -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));
}
});
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}