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