org.zodiac.template.velocity.impl.VelocityRuntimeInstance Maven / Gradle / Ivy
package org.zodiac.template.velocity.impl;
import java.io.Reader;
import org.apache.velocity.Template;
import org.apache.velocity.runtime.RuntimeInstance;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.node.ASTStringLiteral;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.zodiac.template.velocity.impl.parser.ASTStringLiteralEnhanced;
import org.zodiac.template.velocity.impl.parser.SimpleNodeUtil;
/**
* 扩展了velocity的RuntimeInstance
类,实现一个功能,使 ReferenceInsertionEventHandler
可以感知被拦截的引用是否位于
* StringLiteral
中。 例如:
*
* EscapeSupport
可以根据引用的位置,来决定是否要对结果进行escape转义。下面的velocity语句将不会被转义:
*
*
*
* #set ($value = "hello, $name")
*
*
* 通过调用InterpolationUtil.isInInterpolation(context)
即可知晓此细节。
*
*
* 通过velocity configuration: runtime.interpolate.string.literals.hack
可以开关此特性,默认值为 true
。
*
*
*/
public class VelocityRuntimeInstance extends RuntimeInstance {
private static final String INTERPOLATION_HACK_KEY = "runtime.interpolate.string.literals.hack";
private static final Boolean INTERPOLATION_HACK_DEFAULT = true;
private boolean interpolationHack;
public VelocityRuntimeInstance() {
super();
}
@Override
public synchronized void init() {
super.init();
interpolationHack = getConfiguration().getBoolean(INTERPOLATION_HACK_KEY, INTERPOLATION_HACK_DEFAULT);
}
@Override
public SimpleNode parse(Reader reader, Template template) throws ParseException {
SimpleNode node = super.parse(reader, template);
if (interpolationHack) {
node = traversNode(node);
}
return node;
}
private SimpleNode traversNode(SimpleNode node) {
int length = node.jjtGetNumChildren();
for (int i = 0; i < length; i++) {
Node child = node.jjtGetChild(i);
if (child instanceof ASTStringLiteral) {
replaceStringLiteral(node, (ASTStringLiteral)child, i);
}
if (child instanceof SimpleNode) {
traversNode((SimpleNode)child);
}
}
return node;
}
private void replaceStringLiteral(SimpleNode parent, ASTStringLiteral strLit, int index) {
if (!(strLit instanceof ASTStringLiteralEnhanced)) {
SimpleNodeUtil.jjtSetChild(parent, new ASTStringLiteralEnhanced(strLit), index);
}
}
}