
org.tinygroup.command.CommandSystem Maven / Gradle / Ivy
/**
* Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
*
* Licensed under the GPL, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/gpl.html
*
* 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.tinygroup.command;
import org.apache.commons.beanutils.BeanUtils;
import org.tinygroup.command.config.Command;
import org.tinygroup.command.config.CommandGoal;
import org.tinygroup.command.config.Commands;
import org.tinygroup.command.config.Parameter;
import org.tinygroup.context.Context;
import org.tinygroup.context.impl.ContextImpl;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 命令执行系统,采用多例实现,因此可以支持多个命令体系
*
* @author luoguo
*
*/
public final class CommandSystem {
public static final String COMMANDS_XSTREAM = "commands";
private static final Logger LOGGER = LoggerFactory
.getLogger(CommandSystem.class);
private static final int ASCII_MAX = 256;
private static final int MAX_LINE_LENGTH = 80;
// 命令系统
private static Map commandHelperTable = new HashMap();
private Map commands = new HashMap();// 命令集名称对应的命令集
private Map> goalInCommand = new HashMap>();// 命令所在的命令集名称集合
private Context context = new ContextImpl();
private static Pattern commandPattern = Pattern.compile("(\\w|[:]|[-])+");
private static Pattern parameterPattern = Pattern
.compile("(\\b(\\w|[\u4e00-\u9fa5]|[/]|[.]|[-])+\\s*=\"[^\"]*\")|(\\b(\\w|[\u4e00-\u9fa5]|[/]|[.]|[-])+='[^\']*')|(\\b(\\w|[\u4e00-\u9fa5]|[/]|[.]|[-])+=(\\w|[\u4e00-\u9fa5]|[.]|[*]|[%]|[-]|[\\\\]|[/])+)|(\"[^\"]*\"|'[^\']*'|(\\w|[\u4e00-\u9fa5]|[.]|[*]|[%]|[-]|[\\\\]|[/])+)");
private OutputStream out;
/**
* 构造函数
*
* @param type
*/
private CommandSystem(Commands commands) {
for (Command cmd : commands.getCommandList()) {
addCommand(cmd);
}
}
/**
* 获得输入流
*
* @return
*/
public OutputStream getOutputStream() {
return out;
}
/**
* 获得命令执行系统实例
*
* @param type
* @param out
* @return
*/
public static CommandSystem getInstance(String name, Commands commands,
OutputStream out) {
CommandSystem commandSystem = commandHelperTable.get(name);
if (commandSystem == null) {
commandSystem = new CommandSystem(commands);
commandHelperTable.put(name, commandSystem);
} else if (commands != null) {
for (Command command : commands.getCommandList()) {
commandSystem.addCommand(command);
}
}
if (out != null) {
commandSystem.out = out;
}
return commandSystem;
}
public static CommandSystem getInstance(String name) {
return commandHelperTable.get(name);
}
public Map getCommands() {
return commands;
}
/**
* 返回环境
*
* @return
*/
public Context getContext() {
return context;
}
/**
* 添加命令
*
* @param set
*/
private void addCommand(Command set) {
// 处理command与loader的映射
commands.put(set.getName(), set);
for (CommandGoal commandgoal : set.getCommandGoals()) {
List cmdSetNames = goalInCommand.get(commandgoal.getName());
if (cmdSetNames == null) {
cmdSetNames = new ArrayList();
goalInCommand.put(commandgoal.getName(), cmdSetNames);
}
cmdSetNames.add(set.getName());
}
}
/**
* 执行一个命令
*
* @param cmd
*/
public void execute(String cmd) {
// 分解命令为命令和参数
List cmds = parseCmd(cmd);
if (cmds.isEmpty()) {
println("请输入有效的命令及goal! 获取帮助为: h|help");
return;
}
execute(cmds);
}
private void execute(List cmds) {
Map parameter = new HashMap();
String[] str = cmds.get(0).split(":");
Command command = null;
CommandGoal goal = null;
switch (str.length) {
case 1:// 只有goal,没有命令
List setsName = goalInCommand.get(str[0]);
if (setsName == null) {
println("info:invalid-commands");// 无效命令
return;
} else if (setsName.size() != 1) {
print("Goal:" + str[0] + "在命令[");
for (int i = 0; i < setsName.size(); i++) {
if (i > 0) {
print(",");
}
print(setsName.get(i));
}
println("]中出现,请在goal前添加命令。");
return;
} else {
command = commands.get(setsName.get(0));
for (CommandGoal c : command.getCommandGoals()) {
if (c.getName().equals(str[0])) {
goal = c;
break;
}
}
}
break;
case 2:// 有命令集,也有命令
command = commands.get(str[0]);
if (command != null) {
for (CommandGoal c : command.getCommandGoals()) {
if (c.getName().equals(str[1])) {
goal = c;
break;
}
}
}
break;
}
// 输入的命令有效
if (goal != null && command != null) {
// 输入参数 统一放到parameter里
for (int i = 1; i < cmds.size(); i++) {
String strCmd = cmds.get(i);
int index = strCmd.indexOf('=');
if (index > 0) {
String key = strCmd.substring(0, index);
if (goal.getParameters() != null) {
for (Parameter p : goal.getParameters()) {
if (p.getName().equals(key)) {
String value = strCmd.substring(index + 1);
parameter.put(key, value);
break;
}
}
}
} else {
if (goal.getDefaultParameter() != null) {
if (goal.getDefaultParameter() == null
|| goal.getDefaultParameter().length() == 0) {
println("无效的参数:" + strCmd);
return;
}
parameter.put(goal.getDefaultParameter(), strCmd);
}
}
}
// 把没有指定参数的参数值用默认值
if (goal.getParameters() != null) {
for (Parameter p : goal.getParameters()) {
if (parameter.get(p.getName()) == null) {
if (p.getDefaultValue() != null
&& p.getDefaultValue().length() > 0) {
parameter.put(p.getName(), p.getDefaultValue());
} else {
if (p.isNecessary()) {
// 不能忽略参数
println("参数" + p.getName() + "不能为空。");
return;
}
}
}
}
}
CommandGoalExecutor commandGoalExecutor = goal
.getCommandGoalExecutor();
for (String property : parameter.keySet()) {
String v = parameter.get(property);
try {
if (v != null && v.length() > 0) {
BeanUtils.setProperty(commandGoalExecutor, property,
parameter.get(property));
}
} catch (Exception e1) {
LOGGER.errorMessage("属性设置错误!属性名:{0},属性值:{1}。", e1,
property, v);
}
}
commandGoalExecutor.execute(this, context);
} else {
println("无效的命令:" + cmds.get(0));
}
}
/**
* 分解命令行为一个一个单元
*
* @param cmd
* @return
*/
private List parseCmd(String cmd) {
List ret = new ArrayList();
Matcher m = commandPattern.matcher(cmd);
if (m.find()) {
ret.add(m.group());
} else {
return ret;
}
int s = m.end();
m = parameterPattern.matcher(cmd);
while (m.find(s)) {
String str = m.group();
if (str.startsWith("\"") || str.startsWith("'")) {
ret.add(str.substring(1, str.length() - 1));
} else {
ret.add(str);
}
s = m.end();
}
return ret;
}
public void println(String str) {
print(str);
print("\n");
}
public void println() {
print("\n");
}
public void print(String str) {
try {
if (str != null) {
out.write(str.getBytes());
}
} catch (IOException e) {
LOGGER.errorMessage("内容({0})输入时出现异常:。", e, str);
}
}
public int indentPrint(String str, int tab) {
this.printTab(tab);
int count = tab;
for (int i = 0; i < str.length(); i++) {
String s = str.substring(i, i + 1);
if (str.charAt(i) >= 0 && str.charAt(i) <= ASCII_MAX) {
if (count > MAX_LINE_LENGTH) {
println("");
this.printTab(tab);
count = tab;
}
print(s);
count += 1;
} else {
if (count > MAX_LINE_LENGTH) {
println("");
this.printTab(tab);
count = tab;
}
print(s);
count += 2;
}
}
return count;
}
private void printTab(int tab) {
for (int i = 0; i < tab; i++) {
print(String.format(" ", ""));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy