1 package org.apache.velocity.runtime.directive;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.Reader;
25 import java.io.StringReader;
26 import java.io.Writer;
27
28 import org.apache.velocity.context.EvaluateContext;
29 import org.apache.velocity.context.InternalContextAdapter;
30 import org.apache.velocity.context.InternalContextAdapterImpl;
31 import org.apache.velocity.exception.MethodInvocationException;
32 import org.apache.velocity.exception.ParseErrorException;
33 import org.apache.velocity.exception.ResourceNotFoundException;
34 import org.apache.velocity.exception.TemplateInitException;
35 import org.apache.velocity.runtime.RuntimeServices;
36 import org.apache.velocity.runtime.parser.ParseException;
37 import org.apache.velocity.runtime.parser.ParserTreeConstants;
38 import org.apache.velocity.runtime.parser.node.Node;
39 import org.apache.velocity.runtime.parser.node.SimpleNode;
40 import org.apache.velocity.util.introspection.Info;
41
42
43
44
45
46
47
48
49 public class Evaluate extends Directive
50 {
51
52
53
54
55
56 public String getName()
57 {
58 return "evaluate";
59 }
60
61
62
63
64
65 public int getType()
66 {
67 return LINE;
68 }
69
70
71
72
73
74
75
76
77 public void init(RuntimeServices rs, InternalContextAdapter context,
78 Node node)
79 throws TemplateInitException
80 {
81 super.init( rs, context, node );
82
83
84
85
86
87 int argCount = node.jjtGetNumChildren();
88 if (argCount == 0)
89 {
90 throw new TemplateInitException(
91 "#" + getName() + "() requires exactly one argument",
92 context.getCurrentTemplateName(),
93 node.getColumn(),
94 node.getLine());
95 }
96 if (argCount > 1)
97 {
98
99
100
101
102 throw new TemplateInitException(
103 "#" + getName() + "() requires exactly one argument",
104 context.getCurrentTemplateName(),
105 node.jjtGetChild(1).getColumn(),
106 node.jjtGetChild(1).getLine());
107 }
108
109 Node childNode = node.jjtGetChild(0);
110 if ( childNode.getType() != ParserTreeConstants.JJTSTRINGLITERAL &&
111 childNode.getType() != ParserTreeConstants.JJTREFERENCE )
112 {
113 throw new TemplateInitException(
114 "#" + getName() + "() argument must be a string literal or reference",
115 context.getCurrentTemplateName(),
116 childNode.getColumn(),
117 childNode.getLine());
118 }
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133 public boolean render(InternalContextAdapter context, Writer writer,
134 Node node) throws IOException, ResourceNotFoundException,
135 ParseErrorException, MethodInvocationException
136 {
137
138
139
140
141
142
143 Object value = node.jjtGetChild(0).value( context );
144 String sourceText;
145 if ( value != null )
146 {
147 sourceText = value.toString();
148 }
149 else
150 {
151 sourceText = "";
152 }
153
154
155
156
157
158 Reader reader = new BufferedReader(new StringReader(sourceText));
159 String templateName = context.getCurrentTemplateName();
160 SimpleNode nodeTree = null;
161
162 try
163 {
164 nodeTree = rsvc.parse(reader, templateName);
165 }
166 catch (ParseException pex)
167 {
168
169 Info info = new Info( templateName, node.getLine(), node.getColumn() );
170 throw new ParseErrorException( pex.getMessage(), info );
171 }
172 catch (TemplateInitException pex)
173 {
174 Info info = new Info( templateName, node.getLine(), node.getColumn() );
175 throw new ParseErrorException( pex.getMessage(), info );
176 }
177
178
179
180
181
182
183 if (nodeTree != null)
184 {
185 InternalContextAdapterImpl ica =
186 new InternalContextAdapterImpl( new EvaluateContext(context, rsvc) );
187
188 ica.pushCurrentTemplateName( templateName );
189
190 try
191 {
192 try
193 {
194 nodeTree.init( ica, rsvc );
195 }
196 catch (TemplateInitException pex)
197 {
198 Info info = new Info( templateName, node.getLine(), node.getColumn() );
199 throw new ParseErrorException( pex.getMessage(), info );
200 }
201
202 try
203 {
204
205
206
207 nodeTree.render( ica, writer );
208 }
209 catch (ParseErrorException pex)
210 {
211
212 Info info = new Info( templateName, node.getLine(), node.getColumn() );
213 throw new ParseErrorException( pex.getMessage(), info );
214 }
215 }
216 finally
217 {
218 ica.popCurrentTemplateName();
219 }
220
221 return true;
222 }
223
224
225 return false;
226 }
227
228 }