feat: 新增指令调度器.
This commit is contained in:
@@ -6,13 +6,18 @@ import com.serliunx.ddns.config.PropertiesConfiguration;
|
||||
import com.serliunx.ddns.constant.SystemConstants;
|
||||
import com.serliunx.ddns.core.context.FileInstanceContext;
|
||||
import com.serliunx.ddns.core.context.MultipleSourceInstanceContext;
|
||||
import com.serliunx.ddns.support.InstanceContextHolder;
|
||||
import com.serliunx.ddns.support.SystemInitializer;
|
||||
import com.serliunx.ddns.support.command.CommandDispatcher;
|
||||
import com.serliunx.ddns.support.command.target.HelpCommand;
|
||||
import com.serliunx.ddns.support.log.JLineAdaptAppender;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.impl.history.DefaultHistory;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -25,6 +30,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public final class ManagerLite {
|
||||
|
||||
/**
|
||||
* 默认的日志输出
|
||||
*/
|
||||
private static final Logger DEFAULT_LOGGER = LoggerFactory.getLogger(ManagerLite.class);
|
||||
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
@@ -37,9 +47,19 @@ public final class ManagerLite {
|
||||
* 系统初始化器
|
||||
*/
|
||||
private static SystemInitializer systemInitializer;
|
||||
/**
|
||||
* 指令调度
|
||||
*/
|
||||
private static CommandDispatcher commandDispatcher;
|
||||
|
||||
/**
|
||||
* 获取默认的日志输出
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
return DEFAULT_LOGGER;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// 配置初始化
|
||||
initConfiguration(args);
|
||||
|
||||
@@ -49,6 +69,9 @@ public final class ManagerLite {
|
||||
// 系统初始化
|
||||
initSystem();
|
||||
|
||||
// 指令初始化
|
||||
initCommands();
|
||||
|
||||
Terminal terminal;
|
||||
try {
|
||||
terminal = TerminalBuilder.builder()
|
||||
@@ -67,30 +90,35 @@ public final class ManagerLite {
|
||||
|
||||
JLineAdaptAppender.setLineReader(lineReader);
|
||||
|
||||
String prompt = "client> ";
|
||||
final String prompt = "client> ";
|
||||
|
||||
InstanceContextHolder.setAdditional("command-process");
|
||||
while (true) {
|
||||
// 该方法会阻塞,直到用户敲回车
|
||||
try {
|
||||
String cmd = lineReader.readLine(prompt);
|
||||
|
||||
// 当用户输入 exit 或 quit,就退出循环
|
||||
// 当用户输入 exit,就退出循环
|
||||
if ("exit".equalsIgnoreCase(cmd)) {
|
||||
break;
|
||||
}
|
||||
// 在这里可以对用户输入做进一步处理
|
||||
commandDispatcher.onCommand(cmd);
|
||||
terminal.flush();
|
||||
} catch (Exception e) {
|
||||
System.exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
System.exit(0);
|
||||
terminal.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指令初始化
|
||||
*/
|
||||
private static void initCommands() {
|
||||
commandDispatcher = CommandDispatcher.getInstance();
|
||||
// help
|
||||
commandDispatcher.register(new HelpCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.serliunx.ddns.support.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 指令的抽象实现
|
||||
* <li> 实现公共逻辑及定义具体逻辑
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/1/15
|
||||
*/
|
||||
public abstract class AbstractCommand implements Command {
|
||||
|
||||
private final String name;
|
||||
private final List<Command> subCommands;
|
||||
private final String description;
|
||||
private final String usage;
|
||||
|
||||
public AbstractCommand(String name, List<Command> subCommands, String description, String usage) {
|
||||
this.name = name;
|
||||
this.subCommands = subCommands;
|
||||
this.description = description;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Command> getSubCommands() {
|
||||
return subCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return usage;
|
||||
}
|
||||
}
|
||||
44
src/main/java/com/serliunx/ddns/support/command/Command.java
Normal file
44
src/main/java/com/serliunx/ddns/support/command/Command.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.serliunx.ddns.support.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 指令接口定义
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/1/15
|
||||
*/
|
||||
public interface Command {
|
||||
|
||||
/**
|
||||
* 指令执行逻辑
|
||||
*
|
||||
* @param args 当前指令参数
|
||||
* @return 成功执行返回真, 否则返回假. (目前没影响)
|
||||
*/
|
||||
boolean onCommand(String[] args);
|
||||
|
||||
/**
|
||||
* 获取指令名称
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* 获取子命令
|
||||
* <li> 例: cmd c1 c2, 此时 c1为cmd的子命令
|
||||
*
|
||||
* @return 子命令
|
||||
*/
|
||||
List<Command> getSubCommands();
|
||||
|
||||
/**
|
||||
* 获取该指令的描述
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* 获取该指令的用法
|
||||
*/
|
||||
String getUsage();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.serliunx.ddns.support.command;
|
||||
|
||||
import com.serliunx.ddns.ManagerLite;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 指令调度器
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.4
|
||||
* @since 2025/1/15
|
||||
*/
|
||||
public final class CommandDispatcher {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CommandDispatcher.class);
|
||||
private static final CommandDispatcher INSTANCE = new CommandDispatcher();
|
||||
|
||||
// private-ctor
|
||||
private CommandDispatcher() {}
|
||||
|
||||
/**
|
||||
* 最顶层指令缓存
|
||||
*/
|
||||
private final Map<String, Command> commands = new ConcurrentHashMap<>(128);
|
||||
|
||||
/**
|
||||
* 指令注册
|
||||
* @param command 指令
|
||||
*/
|
||||
public void register(Command command) {
|
||||
commands.put(command.getName(), command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指令反注册
|
||||
* @param command 指令
|
||||
*/
|
||||
public void unregister(Command command) {
|
||||
commands.remove(command.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理输入的指令
|
||||
* @param input 指令
|
||||
*/
|
||||
public void onCommand(String input) {
|
||||
if (input == null ||
|
||||
input.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] args = input.split(" ");
|
||||
String cmd = args[0];
|
||||
|
||||
Command command = commands.get(cmd);
|
||||
if (command == null) {
|
||||
logger.warn("未知指令: {}, 请输入 help 查看帮助!", cmd);
|
||||
return;
|
||||
}
|
||||
if (!command.onCommand(splitArgs(args))) {
|
||||
logger.error("指令执行出现了错误: {}", Arrays.toString(args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分割指令参数
|
||||
* <li> cmd x1 x2 => x1 x2
|
||||
*
|
||||
* @param args 参数
|
||||
* @return 去除指令本身的参数部分
|
||||
*/
|
||||
public static String[] splitArgs(String[] args) {
|
||||
String[] newArgs = new String[args.length - 1];
|
||||
System.arraycopy(args, 1, newArgs, 0, args.length - 1);
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
*/
|
||||
public static CommandDispatcher getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.serliunx.ddns.support.command.target;
|
||||
|
||||
import com.serliunx.ddns.ManagerLite;
|
||||
import com.serliunx.ddns.support.command.AbstractCommand;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 指令: help
|
||||
*
|
||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||
* @version 1.0.0
|
||||
* @since 2025/1/15
|
||||
*/
|
||||
public class HelpCommand extends AbstractCommand {
|
||||
|
||||
private static final Logger log = ManagerLite.getLogger();
|
||||
|
||||
public HelpCommand() {
|
||||
super("help", null, "查看帮助信息", "help cmd");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(String[] args) {
|
||||
System.out.println(Arrays.toString(args));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user