package cn.org.rapid_framework.velocity.directive;
import java.io.IOException;
import java.io.Writer;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
/**
* @author badqiu
*/
public class OverrideDirective extends org.apache.velocity.runtime.directive.Directive{
@Override
public String getName() {
return "override";
}
@Override
public int getType() {
return BLOCK;
}
@Override
public boolean render(InternalContextAdapter context, Writer writer, Node node)
throws IOException, ResourceNotFoundException, ParseErrorException,MethodInvocationException {
String name = Utils.getRequiredArgument(context, node, 0,getName());
OverrideNodeWrapper override = (OverrideNodeWrapper)context.get(Utils.getOverrideVariableName(name));
if(override == null) {
Node body = node.jjtGetChild(1);
context.put(Utils.getOverrideVariableName(name), new OverrideNodeWrapper(body));
}else {
OverrideNodeWrapper current = new OverrideNodeWrapper(node.jjtGetChild(1));
Utils.setParentForTop(current,override);
}
return true;
}
private boolean isOverrided(InternalContextAdapter context,String name) {
return context.get(Utils.getOverrideVariableName(name)) != null;
}
static class OverrideNodeWrapper extends SimpleNode {
Node current;
OverrideNodeWrapper parentNode;
public OverrideNodeWrapper(Node node) {
super(1);
this.current = node;
}
public boolean render(InternalContextAdapter context, Writer writer)
throws IOException, MethodInvocationException,
ParseErrorException, ResourceNotFoundException {
OverrideNodeWrapper preNode = (OverrideNodeWrapper)context.get(Utils.OVERRIDE_CURRENT_NODE);
try {
context.put(Utils.OVERRIDE_CURRENT_NODE,this);
return current.render(context, writer);
}finally {
context.put(Utils.OVERRIDE_CURRENT_NODE,preNode);
}
}
}
}