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 = ctx.vars[varIndex];

if (value == 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 = ctx.vars[varIndex];

} else {

BeetlException ex = new BeetlException(BeetlException.VAR_NOT_DEFINED);

ex.pushToken(firstToken);

throw ex;

}

}

}

if (value == 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 == 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 = 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 == 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;

}

}

}

时间: 2024-11-03 16:37:53

Beetl通过JAVA接口获取JAVA中的变量的相关文章

selenium+java:获取列表中的值

selenium+java:获取列表中的值 (2011-08-23 17:14:48) 标签: 杂谈 分类: selenium 初步研究利用java+testNg框架下写selenium测试用例,今天学会了几个API:(1)获取页面上列表中的值,并打印输出:System.out.println(selenium.getTable("xpath=/html/body/div[3]/form/table.1.1")); //输出列表中第1行第1列的值(2)判断页面上是否有某个文本:(只能判

使用javax.script包实现Java设置JS脚本中的变量

下面例子中,我们通过javax.script包ScriptEngine.put()方法设置JS脚本中的变量,JS把所有在线用户输出. package ajava.code.javase; import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; import javax.script.ScriptException; import java.util.Date; public class AjavaAcc

Java接口获取系统配置信息

Java获取当前运行系统的配置信息 接口:System.getProperty() 参数 描述 java.version Java运行时环境版本 java.vendor Java运行时环境供应商 java.vendor.url Java供应商的URL java.home Java安装目录 java.vm.specification.version Java虚拟机规范版本 java.vm.specification.vendor Java虚拟机规范供应商 java.vm.specification

java &quot;aababcabcdabcde&quot;,获取字符串中每一个字母出现的次数

需求:"aababcabcdabcde",获取字符串中每一个字母出现的次数 分析: * A:定义一个字符串(可以改进为键盘录入) * B:定义一个TreeMap集合 * 键:Character * 值:Integer * C:把字符串转换为字符数组 * D:遍历字符数组,得到每一个字符 * E:拿刚才得到的字符作为键到集合中去找值,看返回值 * 是null:说明该键不存在,就把该字符作为键,1作为值存储 * 不是null:说明该键存在,就把值加1,然后重写存储该键和值 * F:定义字符

Java入门系列-04-java中的变量

这篇文章为你搞懂三个问题 什么是变量? 如何使用变量? 变量命名有哪些规范? 变量 计算机的内存类似于人的大脑,电脑使用内存来存储计算所需要的数据. 内存像旅馆一样,不同的房间类型对应不同的数据类型,内存存储数据时会根据数据的需求为它申请一块合适的空间.用于存储数据的这个空间就是变量. 变量名 内存地址 值 name 0x5c2a0c3f.. 张三 age 0xcd4d72a... 10 变量名.内存和存储的值如上表↑ 可以看到内存地址长而不方便记忆,但是变量名可以像给一个人起外号一样,方便记忆

java 反射获取设置私有成员变量的值

for (Object arg:args) { //处理applicationCode Class<?> argClass = arg.getClass(); Field applicationCode =null; try { applicationCode =argClass.getDeclaredField("applicationCode"); }catch (NoSuchFieldException e){ } JWTData jwtData = CurrentU

Java中接口和Sala中的特质的区别?

1.先要区分是Java中哪个版本的接口,因为Java中不同版本接口是不一样2.Java8之前的接口(不包含Java8),这个版本的接口只能属性和抽象方法,和Scala中的特质有完全的不用因为Scala特质除了定义属性和抽象方法之外,还可以定实现方法和抽象属性3.Java8之后的接口(包含Java8),这个版本的接口即可以实现属性和抽象方法,也可以实现default和static修饰的方法,这两个方法在接口中是有方法体,此时Java接口和Scala中特质近乎于完全相同,有一些区别,Scala中提供

Java 接口和抽象类区别

1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于

对接第三方平台JAVA接口问题推送和解决

前言 本节所讲为实际项目中与第三方对接出现的问题最后还是靠老大解决了问题以此作为备忘录,本篇分为三小节,一小节解析Java加密接口数据,二小节解析XML文件需注意问题,最后一节则是请求Java Soap协议接口.因为第三方平台都是采用JAVA语言,所以这种情况应该对大家有所帮助. DES加密/解密Java接口 关于Java中序列化为XML文件就不搞了,我们首先需要讲解的是关于加密问题,由于是第三方是采用的DES加密,所以我们只讲解DES,有很多人可能有疑问了,这不过时了么且不安全,不必纠结,这个