首页 > 代码库 > Beetl通过JAVA接口获取JAVA中的变量

Beetl通过JAVA接口获取JAVA中的变量

模板语言绑定变量都是程序主动绑定到beetl,经过努力现在在beetl上实现了模板语言主动发出请求,来执行绑定。


最近做项目用到beetl,因为模板需要用到的变量很多,如果直接绑定,系统消耗很大。

产生了一个想法,当beetl解析不到变量的时候,通过JAVA接口直接获取对象返回给BEETL继续进行解析。

最终实现了Beetl主动发起绑定变量的功能。


修改的代码见最后。

调用时的代码如下:

StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
Configuration conf =  Configuration.defaultConfiguration();
conf.setEngine("org.koron.ebs.permission.beetl.MyEngine");//这里是改写过的引擎
GroupTemplate gt = new GroupTemplate(resourceLoader, conf);
Template t = gt.getTemplate("${sdf.name}<%for(u in user){print(u);}%>");
t.binding("user",new String[]{"IBM","GOOGLE"});
t.binding("VAR_NOT_DEFINED",new VarListener() {//绑定一个全局变量用来解析变量未定义变量
@Override
public Object parse(String var) {
if(java.util.regex.Pattern.compile("sdf\\.?").matcher(var).find())
{
POJO pj = new POJO();
pj.name="我试试";
pj.id="1111";
return pj;
}
return null;
}
});
t.renderTo(System.out);


package org.koron.ebs.permission.beetl;


import java.util.EventListener;


public interface VarListener extends EventListener{//用来解析变量用
/**
* 解析变量成一个实例,为NULL时,表示不解析
* @param var 变量名
* @return 实例
*/
public Object parse(String var);
}

第一次实现由模板语言主动调JAVA方法,感觉不错:)



修改的代码:

package org.koron.ebs.permission.beetl;



import java.io.Reader;
import java.util.Map;
import java.util.Stack;


import org.beetl.core.*;
import org.beetl.core.engine.FastRuntimeEngine;
import org.beetl.core.engine.FilterProgram;
import org.beetl.core.engine.StatementParser;
import org.beetl.core.exception.BeetlException;
import org.beetl.core.statement.*;


public class MyEngine extends FastRuntimeEngine {


/*
* (non-Javadoc)

* @see org.beetl.core.engine.DefaultTemplateEngine#createProgram(org.beetl
* .core.Resource, java.io.Reader, java.util.Map, java.lang.String,
* org.beetl.core.GroupTemplate)
*/
@Override
public Program createProgram(Resource resource, Reader reader, Map<Integer, String> textMap, String cr, GroupTemplate gt) {
FilterProgram program = (FilterProgram) super.createProgram(resource, reader, textMap, cr, gt);
modifyStatemetn(resource, program, gt);
modifyStatemetn(resource, program.getCopy(), gt);
return program;


}


private void modifyStatemetn(Resource resource, Program program, GroupTemplate gt) {
Statement[] sts = program.metaData.statements;
StatementParser parser = new StatementParser(sts, gt, resource.getId());
parser.addListener(VarRef.class, new VarRefListener());
parser.parse();
}


class VarRefListener implements Listener {
@Override
public Object onEvent(Event e) {
Stack<?> stack = (Stack<?>) e.getEventTaget();
Object o = stack.peek();
if (o instanceof VarRef)
return new MyVarRef((VarRef) o);
return null;


}
}


class MyVarRef extends VarRef implements IVarIndex {
private GrammarToken firstToken;
private VarRef var;


public MyVarRef(VarRef var) {
this(var.attributes, var.hasSafe, var.safe, var.token);
this.var = var;
this.varIndex = var.getVarIndex();
}


private MyVarRef(VarAttribute[] attributes, boolean hasSafe, Expression safe, GrammarToken token) {
this(attributes, hasSafe, safe, token, token);
}


private MyVarRef(VarAttribute[] attributes, boolean hasSafe, Expression safe, GrammarToken token, GrammarToken firstToken) {
super(attributes, hasSafe, safe, token, firstToken);
}


@Override
public Object evaluate(Context ctx) {
Object value = http://www.mamicode.com/ctx.vars[varIndex];
if (value =http://www.mamicode.com/= Context.NOT_EXIST_OBJECT) {
if (hasSafe) {
return safe == null ? null : safe.evaluate(ctx);
} else {
Object o = ctx.globalVar.get("VAR_NOT_DEFINED");
if (o == null || !(o instanceof VarListener)) {
BeetlException ex = new BeetlException(BeetlException.VAR_NOT_DEFINED);
ex.pushToken(firstToken);
throw ex;
}
o = ((VarListener) o).parse(var.token.text);
if (o != null) {
ctx.vars[varIndex] = o;
value = http://www.mamicode.com/ctx.vars[varIndex];
} else {
BeetlException ex = new BeetlException(BeetlException.VAR_NOT_DEFINED);
ex.pushToken(firstToken);
throw ex;
}
}
}


if (value =http://www.mamicode.com/= null) {
if (hasSafe) {
return safe == null ? null : safe.evaluate(ctx);
}
}


if (attributes.length == 0) {
return value;
}


for (int i = 0; i < attributes.length; i++) {
VarAttribute attr = attributes[i];
if (value =http://www.mamicode.com/= null) {
if (hasSafe) {
return safe == null ? null : safe.evaluate(ctx);
} else {
BeetlException be = new BeetlException(BeetlException.NULL, "空指针");
if (i == 0) {
be.pushToken(this.firstToken);
} else {
be.pushToken(attributes[i - 1].token);
}


throw be;
}


}


try {
value = http://www.mamicode.com/attr.evaluate(ctx, value);
} catch (BeetlException ex) {
ex.pushToken(attr.token);
throw ex;


} catch (RuntimeException ex) {
BeetlException be = new BeetlException(BeetlException.ATTRIBUTE_INVALID, "属性访问出错", ex);
be.pushToken(attr.token);
throw be;
}


}


if (value =http://www.mamicode.com/= null && hasSafe) {
return safe == null ? null : safe.evaluate(ctx);
} else {
return value;
}


}


@Override
public void setVarIndex(int index) {
this.varIndex = index;


}


@Override
public int getVarIndex() {
return this.varIndex;
}


@Override
public void infer(InferContext inferCtx) {


Type type = inferCtx.types[this.varIndex];
Type lastType = type;
Type t = null;
for (VarAttribute attr : attributes) {
inferCtx.temp = lastType;
attr.infer(inferCtx);
t = lastType;
lastType = attr.type;
attr.type = t;


}
this.type = lastType;
if (safe != null) {
safe.infer(inferCtx);
if (!safe.type.equals(this.type)) {
this.type = Type.ObjectType;
}
}
}


/**
* @return 获取#{bare_field_comment}
*/
public GrammarToken getFirstToken() {
return firstToken;
}
}
}

Beetl通过JAVA接口获取JAVA中的变量