您的位置:首页 > 编程语言 > Java开发

一个简单的Java模板工具类(二)—简单表达式解析实现

2015-06-23 19:13 731 查看
以前写过一个, 用正则比较不高效, 所以用表达式解析方式又实现了一个, 练手.

以前的: /article/3507853.html

现在的:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* 非常非常简单的模板实现
*
* @author desheng.tu
* @date 2015年6月23日 下午4:38:05
*
*/
public class SimpleTmpl {

public static void main(String[] args) {
String t1 = "你好 $$name$$, 您的验证码是:$$code$$";
String t2 = "你好 #{name}, 您的验证码是:${code}";

Map<String, Object> param = MapBuilder.makeO("name", "haogrgr").build("code", "1314");
for (int i = 0; i < 100; i++) {
SimpleTempletUtil.render(t1, param);
Templ.of(t2).render(param);
}

String result = "";
long start = 0;

start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
param.put("code", i);
result = SimpleTempletUtil.render(t1, param);
}
System.out.println(System.currentTimeMillis() - start);
System.out.println(result);

start = System.currentTimeMillis();
Templ templ = Templ.of(t2);
for (int i = 0; i < 100000; i++) {
param.put("code", i);
result = templ.render(param);
}
System.out.println(System.currentTimeMillis() - start);
System.out.println(result);

}

}

abstract class Exp {

abstract String resolve(Map<String, Object> context);

static Exp of(String exp) {
Objects.requireNonNull(exp);
if (exp.startsWith("#{") || exp.startsWith("${")) {
return new VarExp(exp);
}
return new StrExp(exp);
}
}

class StrExp extends Exp {

String value;

StrExp(String exp) {
this.value = exp;
}

@Override
public String resolve(Map<String, Object> context) {
return this.value;
}

@Override
public String toString() {
return "StrExp [value=" + value + "]";
}

}

class VarExp extends Exp {

String varName;
String defaultValue;
Boolean nullable = false;

VarExp(String varName, String defaultValue, Boolean nullable) {
this.varName = varName;
this.defaultValue = defaultValue;
this.nullable = nullable;
}

VarExp(String exp) {
Objects.requireNonNull(exp);
if (!(exp.startsWith("#{") || exp.startsWith("${")) || !exp.endsWith("}")) {
throw new IllegalArgumentException("表达式[" + exp + "]必须类似于#{}或${}");
}

String[] nodes = exp.substring(2, exp.length() - 1).split(",");
if (nodes.length > 2) {
throw new IllegalArgumentException("表达式[" + exp + "]只能出现一个','");
}

this.varName = nodes[0].trim();
this.defaultValue = nodes.length == 2 ? nodes[1].trim() : "";
this.nullable = exp.startsWith("$");
}

@Override
public String resolve(Map<String, Object> context) {
Object value = context.get(varName);
if (value == null && nullable) {
value = defaultValue == null ? "" : defaultValue;
}
if (value == null) {
throw new NullPointerException("上下文中没有指定的变量:var=" + varName + " map=" + context);
}
return value.toString();
}

@Override
public String toString() {
return "VarExp [varName=" + varName + ", defaultValue=" + defaultValue + ", nullable="
+ nullable + "]";
}

}

class Templ {

List<Exp> exps = new ArrayList<>();

static Templ of(String templStr) {
Objects.requireNonNull(templStr, "模板为空");

Templ templ = new Templ();
StringBuilder sb = new StringBuilder();

char[] chars = templStr.toCharArray();
for (int i = 0; i < chars.length; i++) {
switch (chars[i]) {
case '#':
case '$':
if(i < chars.length - 1 && chars[i+1] == '{'){
templ.addExp(Exp.of(sb.toString()));
sb.setLength(0);
}
sb.append(chars[i]);
break;
case '}':
sb.append('}');
if(sb.length() > 1 && sb.charAt(1) == '{'){
templ.addExp(Exp.of(sb.toString()));
sb.setLength(0);
}
break;
default:
sb.append(chars[i]);
break;
}
}

if(sb.length() > 0){
templ.addExp(Exp.of(sb.toString()));
}

return templ;
}

Templ addExp(Exp exp) {
Objects.requireNonNull(exp, "表达式为空");
exps.add(exp);
return this;
}

String render(Map<String, Object> context) {
StringBuilder sb = new StringBuilder(128);
for (Exp exp : exps) {
sb.append(exp.resolve(context));
}
return sb.toString();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: