feat: 新增指令支持.

This commit is contained in:
2024-06-12 14:50:30 +08:00
parent c7a6c3ca80
commit 5832b6b11e
13 changed files with 434 additions and 36 deletions

View File

@@ -1,34 +0,0 @@
package com.serliunx.ddns;
import com.serliunx.ddns.config.PropertiesConfiguration;
import com.serliunx.ddns.constant.SystemConstants;
import com.serliunx.ddns.core.context.FileInstanceContext;
import com.serliunx.ddns.support.SystemInitializer;
import com.serliunx.ddns.support.SystemSupport;
import org.slf4j.MDC;
/**
* 启动类
* @author SerLiunx
* @since 1.0
*/
public final class BootStrap {
public static void main(String[] args) {
beforeInit();
init();
}
private static void beforeInit() {
MDC.put("pid", SystemSupport.getPid());
}
private static void init() {
SystemInitializer systemInitializer = SystemInitializer
.configurer()
.configuration(new PropertiesConfiguration(SystemConstants.USER_SETTINGS_PROPERTIES_PATH))
.instanceContext(new FileInstanceContext())
.done();
systemInitializer.refresh();
}
}

View File

@@ -0,0 +1,70 @@
package com.serliunx.ddns;
import com.serliunx.ddns.config.PropertiesConfiguration;
import com.serliunx.ddns.constant.SystemConstants;
import com.serliunx.ddns.core.context.FileInstanceContext;
import com.serliunx.ddns.support.SystemInitializer;
import com.serliunx.ddns.support.SystemSupport;
import com.serliunx.ddns.support.command.CommandManager;
import com.serliunx.ddns.support.command.cmd.ExitCommand;
import com.serliunx.ddns.support.command.cmd.HelpCommand;
import com.serliunx.ddns.support.command.cmd.IpCommand;
import org.slf4j.MDC;
import java.util.Scanner;
/**
* 启动类
* @author SerLiunx
* @since 1.0
*/
public final class ManagerLite {
public static void main(String[] args) {
// 日志参数调整
beforeInit();
// 容器初始化
SystemInitializer initializer = init();
// 指令注册
CommandManager commandManager = registerCommand(initializer);
// 指令监听
handleCommand(commandManager, initializer);
}
private static void beforeInit() {
MDC.put("pid", SystemSupport.getPid());
}
private static SystemInitializer init() {
SystemInitializer systemInitializer = SystemInitializer
.configurer()
.configuration(new PropertiesConfiguration(SystemConstants.USER_SETTINGS_PROPERTIES_PATH))
.instanceContext(new FileInstanceContext())
.done();
systemInitializer.refresh();
return systemInitializer;
}
private static CommandManager registerCommand(SystemInitializer systemInitializer) {
CommandManager commandManager = new CommandManager(systemInitializer);
commandManager.register(new HelpCommand(commandManager));
commandManager.register(new IpCommand(commandManager));
commandManager.register(new ExitCommand(commandManager));
return commandManager;
}
@SuppressWarnings("all")
private static void handleCommand(CommandManager commandManager, SystemInitializer systemInitializer) {
Scanner scanner = new Scanner(System.in);
String commandString = "";
while (true) {
System.out.print("> ");
commandString = scanner.nextLine();
commandManager.handle(commandString);
}
}
}

View File

@@ -0,0 +1,43 @@
package com.serliunx.ddns.exception;
import com.serliunx.ddns.support.command.cmd.Command;
/**
* 指令相关异常
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public abstract class CommandException extends RuntimeException {
private Command command;
public CommandException() {}
public CommandException(String message) {
super(message);
}
public CommandException(Command command) {
this.command = command;
}
public CommandException(Command command, String message) {
super(message);
this.command = command;
}
public CommandException(Command command, String message, Throwable cause) {
super(message, cause);
this.command = command;
}
public CommandException(Command command, Throwable cause) {
super(cause);
this.command = command;
}
public CommandException(Command command, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
this.command = command;
}
}

View File

@@ -0,0 +1,13 @@
package com.serliunx.ddns.exception;
/**
* 指令相关异常: 指令不存在.
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public class CommandExceptionNotExistsException extends CommandException {
public CommandExceptionNotExistsException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,32 @@
package com.serliunx.ddns.support.command;
/**
* 指令参数信息包装
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public class CommandArg {
/**
* 参数名称
*/
private final String arg;
/**
* 参数说明
*/
private final String description;
public CommandArg(String arg, String description) {
this.arg = arg;
this.description = description;
}
public String getArg() {
return arg;
}
public String getDescription() {
return description;
}
}

View File

@@ -0,0 +1,77 @@
package com.serliunx.ddns.support.command;
import com.serliunx.ddns.exception.CommandExceptionNotExistsException;
import com.serliunx.ddns.support.SystemInitializer;
import com.serliunx.ddns.support.command.cmd.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* 指令管理
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public final class CommandManager {
private static final Logger log = LoggerFactory.getLogger(CommandManager.class);
private final Map<String, Command> commandMap = new HashMap<>();
private final SystemInitializer initializer;
public CommandManager(SystemInitializer systemInitializer) {
this.initializer = systemInitializer;
}
public Command getCommand(String commandName) {
Command command = commandMap.get(commandName);
if (command == null)
throw new CommandExceptionNotExistsException(String.format("指令 %s 不存在!", commandName));
return command;
}
public SystemInitializer getInitializer() {
return initializer;
}
/**
* 注册指令
* @param command 指令
*/
public void register(Command command) {
boolean result = register0(command);
if (result)
log.debug("成功注册指令 => {}", command.getName());
else
log.warn("指令注册失败 => {}", command);
}
public void handle(String commandString) {
String[] args = commandString.split(" ");
if (args.length < 1) {
log.warn("未找到相关指令! 输入 help 查看指令手册.");
return;
}
Command cmd = commandMap.get(args[0]);
if (cmd == null) {
log.warn("未找到相关指令! 输入 help 查看指令手册.");
return;
}
String[] subArgs = new String[args.length - 1];
System.arraycopy(args, 1, subArgs, 0, args.length - 1);
cmd.execute(subArgs);
}
private boolean register0(Command command) {
if (command == null) return false;
String cmdName = command.getName();
if (cmdName == null || cmdName.isEmpty())
return false;
if (commandMap.containsKey(cmdName))
return false;
commandMap.put(cmdName, command);
return true;
}
}

View File

@@ -0,0 +1,54 @@
package com.serliunx.ddns.support.command.cmd;
import com.serliunx.ddns.support.command.CommandArg;
import com.serliunx.ddns.support.command.CommandManager;
import java.util.Collections;
import java.util.List;
/**
* 指令抽象实现
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public abstract class AbstractCommand implements Command {
protected final String name;
protected final Command[] children;
protected final CommandManager commandManager;
public AbstractCommand(String name, Command[] children, CommandManager commandManager) {
this.name = name;
this.children = children;
this.commandManager = commandManager;
}
public AbstractCommand(String name, CommandManager commandManager) {
this(name, null, commandManager);
}
@Override
public String getName() {
return name;
}
@Override
public Command[] getChildren() {
return children;
}
@Override
public List<CommandArg> getArgs() {
return Collections.emptyList();
}
@Override
public abstract boolean execute(String[] args);
@Override
public String toString() {
return "Command{" +
"name='" + name + '\'' +
'}';
}
}

View File

@@ -0,0 +1,39 @@
package com.serliunx.ddns.support.command.cmd;
import com.serliunx.ddns.support.command.CommandArg;
import java.util.List;
/**
* 指令接口
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public interface Command {
/**
* 获取指令名称
* @return 名称
*/
String getName();
/**
* 指令逻辑
* @param args 参数
* @return 执行结果
*/
@SuppressWarnings("all")
boolean execute(String[] args);
/**
* 获取子命令
* @return 子命令
*/
Command[] getChildren();
/**
* 获取指令参数信息
* @return 参数信息
*/
List<CommandArg> getArgs();
}

View File

@@ -0,0 +1,24 @@
package com.serliunx.ddns.support.command.cmd;
import com.serliunx.ddns.support.command.CommandManager;
/**
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public class ExitCommand extends AbstractCommand {
public ExitCommand(Command[] children, CommandManager commandManager) {
super("exit", children, commandManager);
}
public ExitCommand(CommandManager commandManager) {
this(null, commandManager);
}
@Override
public boolean execute(String[] args) {
System.exit(0);
return false;
}
}

View File

@@ -0,0 +1,49 @@
package com.serliunx.ddns.support.command.cmd;
import com.serliunx.ddns.support.command.CommandArg;
import com.serliunx.ddns.support.command.CommandManager;
import java.util.List;
/**
* 帮助指令: help
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public class HelpCommand extends AbstractCommand {
private static final String NO_ARGS_INFORMATION = "未找到相关参数信息";
public HelpCommand(Command[] children, CommandManager commandManager) {
super("help", children, commandManager);
}
public HelpCommand(CommandManager commandManager) {
this(null, commandManager);
}
@Override
public boolean execute(String[] args) {
int length = args.length;
if (length < 1)
return false;
Command targetCommand = commandManager.getCommand(args[0]);
List<CommandArg> commandArgs = targetCommand.getArgs();
if (commandArgs == null || commandArgs.isEmpty()) {
System.out.println(NO_ARGS_INFORMATION);
return true;
}
System.out.println(buildArgs(commandArgs));
return true;
}
private String buildArgs(List<CommandArg> args) {
StringBuilder argsBuilder = new StringBuilder();
for (int i = 0; i < args.size(); i++) {
argsBuilder.append(args.get(i).getArg()).append(" - ").append(args.get(i).getDescription());
if (i != args.size() - 1)
argsBuilder.append("\n");
}
return argsBuilder.toString();
}
}

View File

@@ -0,0 +1,31 @@
package com.serliunx.ddns.support.command.cmd;
import com.serliunx.ddns.support.NetworkContextHolder;
import com.serliunx.ddns.support.command.CommandManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ip 相关指令
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 1.0.0
*/
public class IpCommand extends AbstractCommand {
private static final Logger log = LoggerFactory.getLogger(IpCommand.class);
public IpCommand(Command[] children, CommandManager commandManager) {
super("ip", children, commandManager);
}
public IpCommand(CommandManager commandManager) {
this(null, commandManager);
}
@Override
public boolean execute(String[] args) {
String newestIp = NetworkContextHolder.getIpAddress();
log.info("当前最新IP地址为: {}", newestIp);
return true;
}
}