All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.gdface.cli.BaseAppConfig Maven / Gradle / Ivy
package net.gdface.cli;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
/**
* 应用程序配置参数抽象类
* @author guyadong
*
*/
public abstract class BaseAppConfig extends AbstractConfiguration
implements CommonCliConstants {
protected static final Logger logger = Logger.getLogger(BaseAppConfig.class.getSimpleName());
/**
* 定义命令行参数
*/
protected final Options options = new Options();
/**
* 定义命令行参数的默认值
*/
protected final Context defaultValue = Context.builder().build();
private boolean trace;
protected BaseAppConfig() {
this(false);
}
/**
* 构造方法
* @param withTrace 是否使用 trace 选项,为{@code true}时会将'{@code -X --trace}'自动添加到命令行参数定义中
*/
protected BaseAppConfig(boolean withTrace) {
super(withTrace);
}
@Override
protected Map getDefaultValueMap() {
return defaultValue.getContext();
}
private void showError(Throwable e){
if(isTrace()){
e.printStackTrace();
}else{
logger.warning(String.format("%s:%s",e.getClass().getSimpleName(),e.getMessage()));
}
}
/**
* 解析命令行参数
* @param args
* @return 当前对象
*/
public BaseAppConfig parseCommandLine(String[] args) {
HelpFormatter formatter = new HelpFormatter();
CommandLineParser parser = new CmdParser();
CommandLine cl = null;
Options opts = getOptions();
opts.addOption(HELP_OPTION, HELP_OPTION_LONG, false, HELP_OPTION_DESC);
if(withTrace){
opts.addOption(TRACE_OPTION, TRACE_OPTION_LONG, false, TRACE_OPTION_DESC);
}
boolean exit = false;
try {
// 处理Options和参数
cl = parser.parse(opts, args);
trace = cl.hasOption(TRACE_OPTION_LONG);
if (!cl.hasOption(HELP_OPTION)) {
if (cl.hasOption(DEFINE_OPTION)) {
setSystemProperty(cl.getOptionValues(DEFINE_OPTION));
}
loadConfig(opts, cl);
} else{
exit = true;
}
}catch (RuntimeException e) {
if(e.getCause() instanceof InvocationTargetException){
Throwable targetException = ((InvocationTargetException)e.getCause()).getTargetException();
showError(targetException);
}else{
showError(e);
}
exit = true;
}catch (Exception e) {
showError(e);
exit = true;
}
if (exit) {
// 如果发生异常,则打印出帮助信息
formatter.printHelp(getCmdLineSyntax(), getHeader(),getOptions(),getFooter());
System.exit(1);
}
doAfterParse();
return this;
}
private void setSystemProperty(String[] properties) {
if(properties.length %2 != 0){
throw new IllegalArgumentException("INVALID properties length");
}
for (int i = 0; i < properties.length; i += 2) {
System.setProperty(properties[i], properties[i + 1]);
logger.info(String.format("set property [%s]=[%s]", properties[i], properties[i + 1]));
}
}
protected String getCmdLineSyntax() {
return String.format("%s [options]", getAppName());
}
public Options getOptions() {
return options;
}
protected String getAppName(){
return "Appname";
}
/**
* @return header string
* @see HelpFormatter#printHelp(String, String, Options, String)
*/
protected String getHeader() {
return null;
}
/**
* @return footer string
* @see HelpFormatter#printHelp(String, String, Options, String)
*/
protected String getFooter() {
return null;
}
/**
* {@link #parseCommandLine(String[])}结束时调用,
* 子类可以重写此方法,定义{@link #parseCommandLine(String[])}结束时的动作
*/
protected void doAfterParse() {
}
/**
* 子类重写此方法,返回常量定义
* @return 常量定义值对
*/
protected Map doGetConstants() {
return Collections.emptyMap();
}
/**
* 返回指定名字的常量定义
* @param name 常量名
* @return name定义的常量值,未定义则返回{@code null}
*/
@SuppressWarnings("unchecked")
public final T getConstant(String name) {
return name == null ? null : (T) doGetConstants().get(name);
}
/**
* @return 发生异常时是否输出详细堆栈信息
*/
public boolean isTrace() {
return trace;
}
/**
* 将当前对象转为type指定的类型返回,用于链式调用返回子类对象
* @param type 当前对象的类型
* @return 当前类的子类对象
*/
@SuppressWarnings("unchecked")
public final T self(Classtype){
return (T) this;
}
/**
* 重写parse方法,当命令行包含{@code -h}选项时不抛出异常
* @author guyadong
*
*/
private class CmdParser extends DefaultParser {
@Override
public CommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption)
throws ParseException {
try {
return super.parse(options, arguments, properties, stopAtNonOption);
} catch (ParseException e) {
if(cmd.hasOption(HELP_OPTION)){
return cmd;
}
throw e;
}
}
}
}