Created
November 18, 2010 06:36
-
-
Save rednaxelafx/704698 to your computer and use it in GitHub Desktop.
Generate DOT graphs to visualize a Velocity template's AST. To run this program, the following dependencies are needed: velocity-1.6.4.jar/commons-collections-3.2.1.jar/commons-lang-2.5.jar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.apache.commons.lang.StringEscapeUtils.escapeJava; | |
import static org.apache.commons.lang.StringUtils.isEmpty; | |
import java.util.HashMap; | |
import java.util.Map; | |
import org.apache.velocity.runtime.parser.node.ASTAddNode; | |
import org.apache.velocity.runtime.parser.node.ASTAndNode; | |
import org.apache.velocity.runtime.parser.node.ASTAssignment; | |
import org.apache.velocity.runtime.parser.node.ASTBlock; | |
import org.apache.velocity.runtime.parser.node.ASTComment; | |
import org.apache.velocity.runtime.parser.node.ASTDirective; | |
import org.apache.velocity.runtime.parser.node.ASTDivNode; | |
import org.apache.velocity.runtime.parser.node.ASTEQNode; | |
import org.apache.velocity.runtime.parser.node.ASTElseIfStatement; | |
import org.apache.velocity.runtime.parser.node.ASTElseStatement; | |
import org.apache.velocity.runtime.parser.node.ASTEscape; | |
import org.apache.velocity.runtime.parser.node.ASTEscapedDirective; | |
import org.apache.velocity.runtime.parser.node.ASTExpression; | |
import org.apache.velocity.runtime.parser.node.ASTFalse; | |
import org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral; | |
import org.apache.velocity.runtime.parser.node.ASTGENode; | |
import org.apache.velocity.runtime.parser.node.ASTGTNode; | |
import org.apache.velocity.runtime.parser.node.ASTIdentifier; | |
import org.apache.velocity.runtime.parser.node.ASTIfStatement; | |
import org.apache.velocity.runtime.parser.node.ASTIntegerLiteral; | |
import org.apache.velocity.runtime.parser.node.ASTIntegerRange; | |
import org.apache.velocity.runtime.parser.node.ASTLENode; | |
import org.apache.velocity.runtime.parser.node.ASTLTNode; | |
import org.apache.velocity.runtime.parser.node.ASTMap; | |
import org.apache.velocity.runtime.parser.node.ASTMethod; | |
import org.apache.velocity.runtime.parser.node.ASTModNode; | |
import org.apache.velocity.runtime.parser.node.ASTMulNode; | |
import org.apache.velocity.runtime.parser.node.ASTNENode; | |
import org.apache.velocity.runtime.parser.node.ASTNotNode; | |
import org.apache.velocity.runtime.parser.node.ASTObjectArray; | |
import org.apache.velocity.runtime.parser.node.ASTOrNode; | |
import org.apache.velocity.runtime.parser.node.ASTReference; | |
import org.apache.velocity.runtime.parser.node.ASTSetDirective; | |
import org.apache.velocity.runtime.parser.node.ASTStop; | |
import org.apache.velocity.runtime.parser.node.ASTStringLiteral; | |
import org.apache.velocity.runtime.parser.node.ASTSubtractNode; | |
import org.apache.velocity.runtime.parser.node.ASTText; | |
import org.apache.velocity.runtime.parser.node.ASTTrue; | |
import org.apache.velocity.runtime.parser.node.ASTWord; | |
import org.apache.velocity.runtime.parser.node.ASTprocess; | |
import org.apache.velocity.runtime.parser.node.NodeUtils; | |
import org.apache.velocity.runtime.parser.node.ParserVisitor; | |
import org.apache.velocity.runtime.parser.node.SimpleNode; | |
/** | |
* Generate DOT graphs to visualize a Velocity template's AST. | |
* This class is not thread-safe. DO NOT use share between threads. | |
* | |
* @author RednaxelaFX | |
* | |
*/ | |
public class ASTDotGenerator implements ParserVisitor { | |
private StringBuilder output; | |
private Map<SimpleNode, String> nodeNames; | |
private int nodeCount; | |
public String generateDot(SimpleNode node) { | |
init(); | |
output = new StringBuilder(); | |
output.append("digraph {\n node [fontsize=12, font=Courier, shape=ellipse]"); | |
// recursively traverse the AST | |
node.jjtAccept(this, null); | |
output.append("}"); | |
return output.toString(); | |
} | |
private void init() { | |
nodeNames = new HashMap<SimpleNode, String>(); | |
nodeCount = 0; | |
} | |
private void showNodeCommon(SimpleNode node) { | |
// show parent-child relationship | |
SimpleNode parent = (SimpleNode) node.jjtGetParent(); | |
if (parent != null) { | |
showRelationship(parent, node); | |
} | |
// show children | |
node.childrenAccept(this, null); | |
} | |
private String getName(SimpleNode node) { | |
String cachedName = nodeNames.get(node); | |
if (cachedName != null) | |
return cachedName; | |
String newName = "node_" + nodeCount++; | |
nodeNames.put(node, newName); | |
return newName; | |
} | |
private void declareNode(SimpleNode node, String details) { | |
output | |
.append(" ") | |
.append(getName(node)) | |
.append(" [label=\"") | |
.append(node.getClass().getSimpleName()); | |
if (isEmpty(details)) { | |
output.append("\"]\n"); | |
} else { | |
output.append("\\n[").append(escapeJava(details)).append("]\"]\n"); | |
} | |
} | |
private void showRelationship(SimpleNode parent, SimpleNode child) { | |
output | |
.append(" ") | |
.append(getName(parent)) | |
.append(" -> ") | |
.append(getName(child)) | |
.append("\n"); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.SimpleNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(SimpleNode node, Object data) { | |
// NOTE: ParserVisitor interface is missing a visit(ASTMathNode) method, | |
// so calling ASTMathNode.visit(ParserVisitor, Object) will end up | |
// calling this overload. | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTprocess, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTprocess node, Object data) { | |
declareNode(node, "templateName=" + node.getTemplateName()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTEscapedDirective, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTEscapedDirective node, Object data) { | |
declareNode(node, node.literal()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTEscape, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTEscape node, Object data) { | |
declareNode(node, node.val); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTComment, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTComment node, Object data) { | |
declareNode(node, node.literal()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTFloatingPointLiteral, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTFloatingPointLiteral node, Object data) { | |
declareNode(node, node.value(null).toString()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTIntegerLiteral, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTIntegerLiteral node, Object data) { | |
declareNode(node, node.value(null).toString()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTStringLiteral, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTStringLiteral node, Object data) { | |
declareNode(node, "\"" + node.literal() + "\""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTIdentifier, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTIdentifier node, Object data) { | |
declareNode(node, node.literal()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTWord, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTWord node, Object data) { | |
declareNode(node, "keyword=" + node.literal()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTDirective, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTDirective node, Object data) { | |
declareNode(node, "directive=" + node.getDirectiveName()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTBlock, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTBlock node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTMap, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTMap node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTObjectArray, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTObjectArray node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTIntegerRange, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTIntegerRange node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTMethod, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTMethod node, Object data) { | |
declareNode(node, "method=" + node.getMethodName()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTReference, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTReference node, Object data) { | |
declareNode(node, "identifier=" + node.getRootString()); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTTrue, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTTrue node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTFalse, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTFalse node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTText, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTText node, Object data) { | |
declareNode(node, NodeUtils.tokenLiteral(node.getFirstToken())); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTIfStatement, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTIfStatement node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTElseStatement, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTElseStatement node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTElseIfStatement, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTElseIfStatement node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTSetDirective, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTSetDirective node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTStop, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTStop node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTExpression, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTExpression node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTAssignment, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTAssignment node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTOrNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTOrNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTAndNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTAndNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTEQNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTEQNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTNENode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTNENode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTLTNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTLTNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTGTNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTGTNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTLENode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTLENode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTGENode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTGENode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTAddNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTAddNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTSubtractNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTSubtractNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTMulNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTMulNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTDivNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTDivNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTModNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTModNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache | |
* .velocity.runtime.parser.node.ASTNotNode, java.lang.Object) | |
*/ | |
@Override | |
public Object visit(ASTNotNode node, Object data) { | |
declareNode(node, ""); | |
showNodeCommon(node); | |
return null; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
digraph { | |
node [fontsize=12, font=Courier, shape=ellipse] node_0 [label="ASTprocess\n[templateName=vm/test1.vm]"] | |
node_1 [label="ASTText\n[Testing iterative rendering contents:\r\n]"] | |
node_0 -> node_1 | |
node_2 [label="ASTDirective\n[directive=foreach]"] | |
node_0 -> node_2 | |
node_3 [label="ASTReference\n[identifier=i]"] | |
node_2 -> node_3 | |
node_4 [label="ASTWord\n[keyword=in]"] | |
node_2 -> node_4 | |
node_5 [label="ASTIntegerRange"] | |
node_2 -> node_5 | |
node_6 [label="ASTIntegerLiteral\n[0]"] | |
node_5 -> node_6 | |
node_7 [label="ASTIntegerLiteral\n[10]"] | |
node_5 -> node_7 | |
node_8 [label="ASTBlock"] | |
node_2 -> node_8 | |
node_9 [label="ASTSetDirective"] | |
node_8 -> node_9 | |
node_10 [label="ASTReference\n[identifier=a]"] | |
node_9 -> node_10 | |
node_11 [label="ASTExpression"] | |
node_9 -> node_11 | |
node_12 [label="ASTAddNode"] | |
node_11 -> node_12 | |
node_13 [label="ASTReference\n[identifier=i]"] | |
node_12 -> node_13 | |
node_14 [label="ASTIntegerLiteral\n[1]"] | |
node_12 -> node_14 | |
node_15 [label="ASTText\n[ ]"] | |
node_8 -> node_15 | |
node_16 [label="ASTReference\n[identifier=i]"] | |
node_8 -> node_16 | |
node_17 [label="ASTText\n[ is an ]"] | |
node_8 -> node_17 | |
node_18 [label="ASTIfStatement"] | |
node_8 -> node_18 | |
node_19 [label="ASTExpression"] | |
node_18 -> node_19 | |
node_20 [label="ASTEQNode"] | |
node_19 -> node_20 | |
node_21 [label="ASTModNode"] | |
node_20 -> node_21 | |
node_22 [label="ASTReference\n[identifier=i]"] | |
node_21 -> node_22 | |
node_23 [label="ASTIntegerLiteral\n[2]"] | |
node_21 -> node_23 | |
node_24 [label="ASTIntegerLiteral\n[0]"] | |
node_20 -> node_24 | |
node_25 [label="ASTBlock"] | |
node_18 -> node_25 | |
node_26 [label="ASTText\n[even]"] | |
node_25 -> node_26 | |
node_27 [label="ASTElseStatement"] | |
node_18 -> node_27 | |
node_28 [label="ASTBlock"] | |
node_27 -> node_28 | |
node_29 [label="ASTText\n[odd]"] | |
node_28 -> node_29 | |
node_30 [label="ASTText\n[ number.\r\n]"] | |
node_8 -> node_30 | |
node_31 [label="ASTText\n[Done testing\r\n]"] | |
node_0 -> node_31 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Testing iterative rendering contents: | |
#foreach ($i in [0..10]) | |
#set ($a = $i + 1) | |
$i is an #if ($i % 2 == 0)even#{else}odd#end number. | |
#end | |
Done testing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.FileInputStream; | |
import java.io.InputStreamReader; | |
import java.io.Reader; | |
import org.apache.velocity.VelocityContext; | |
import org.apache.velocity.app.Velocity; | |
import org.apache.velocity.context.InternalContextAdapter; | |
import org.apache.velocity.context.InternalContextAdapterImpl; | |
import org.apache.velocity.runtime.RuntimeSingleton; | |
import org.apache.velocity.runtime.parser.node.SimpleNode; | |
/** | |
* Test ASTDotGenerator with a simple Velocity template. | |
* | |
* @author RednaxelaFX | |
* | |
*/ | |
public class TestDrive { | |
private static final String TEMPLATE_FILE_PATH = "vm/test1.vm"; | |
public static void main(String[] args) throws Exception { | |
initVelocity(); | |
SimpleNode ast = getInitedAST(); | |
ASTDotGenerator dotGen = new ASTDotGenerator(); | |
String dot = dotGen.generateDot(ast); | |
System.out.println(dot); | |
} | |
private static void initVelocity() throws Exception { | |
Velocity.init(); | |
} | |
private static SimpleNode getInitedAST() throws Exception { | |
SimpleNode ast = RuntimeSingleton.parse(getTemplateReader(), TEMPLATE_FILE_PATH); | |
InternalContextAdapter context = new InternalContextAdapterImpl(new VelocityContext()); | |
context.pushCurrentTemplateName(TEMPLATE_FILE_PATH); | |
ast.init(context, RuntimeSingleton.getRuntimeServices()); | |
return ast; | |
} | |
private static Reader getTemplateReader() throws Exception { | |
return new BufferedReader(new InputStreamReader(new FileInputStream(TEMPLATE_FILE_PATH))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment