1 package org.apache.velocity.tools.view.jsp;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.StringWriter;
23 import java.io.Writer;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.jsp.JspException;
26 import javax.servlet.jsp.PageContext;
27 import javax.servlet.jsp.tagext.BodyTagSupport;
28 import org.apache.velocity.Template;
29 import org.apache.velocity.app.VelocityEngine;
30 import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
31 import org.apache.velocity.runtime.resource.util.StringResourceRepository;
32 import org.apache.velocity.tools.view.ServletUtils;
33 import org.apache.velocity.tools.view.ViewToolContext;
34 import org.apache.velocity.tools.view.VelocityView;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class VelocityViewTag extends BodyTagSupport
52 {
53 public static final String DEFAULT_BODY_CONTENT_KEY = "bodyContent";
54 private static final long serialVersionUID = -3329444102562079189L;
55
56 protected transient VelocityView view;
57 protected transient ViewToolContext context;
58 protected transient StringResourceRepository repository;
59
60 protected String var;
61 protected String scope;
62 protected String template;
63 protected String bodyContentKey = DEFAULT_BODY_CONTENT_KEY;
64 private boolean cache = false;
65
66
67
68
69
70
71
72 protected void reset()
73 {
74 super.setId(null);
75 var = null;
76 scope = null;
77 template = null;
78 bodyContentKey = DEFAULT_BODY_CONTENT_KEY;
79 cache = false;
80 }
81
82 public void setId(String id)
83 {
84 if (id == null)
85 {
86 throw new NullPointerException("id cannot be null");
87 }
88 super.setId(id);
89
90 cache = true;
91 }
92
93 protected String getLogId()
94 {
95 String id = super.getId();
96 if (id == null)
97 {
98 id = getClass().getSimpleName();
99 }
100 return id;
101 }
102
103 public void setVar(String var)
104 {
105 this.var = var;
106 }
107
108 public String getVar()
109 {
110 return this.var;
111 }
112
113 public void setScope(String scope)
114 {
115 this.scope = scope;
116 }
117
118 public String getScope()
119 {
120 return this.scope;
121 }
122
123 public void setTemplate(String template)
124 {
125 this.template = template;
126 }
127
128 public String getTemplate()
129 {
130 return this.template;
131 }
132
133 public void setBodyContentKey(String key)
134 {
135 this.bodyContentKey = DEFAULT_BODY_CONTENT_KEY;
136 }
137
138 public String getBodyContentKey()
139 {
140 return this.bodyContentKey;
141 }
142
143 public void setCache(String s)
144 {
145 this.cache = "true".equalsIgnoreCase(s);
146 }
147
148 public String getCache()
149 {
150 return String.valueOf(this.cache);
151 }
152
153 public VelocityView getVelocityView()
154 {
155 return this.view;
156 }
157
158 public void setVelocityView(VelocityView view)
159 {
160 this.view = view;
161 }
162
163 public ViewToolContext getViewToolContext()
164 {
165 return this.context;
166 }
167
168 public void setViewToolContext(ViewToolContext context)
169 {
170 this.context = context;
171 }
172
173 public StringResourceRepository getRepository()
174 {
175 if (this.repository == null)
176 {
177 setRepository(StringResourceLoader.getRepository());
178 }
179 return this.repository;
180 }
181
182 public void setRepository(StringResourceRepository repo)
183 {
184 this.repository = repo;
185 }
186
187 public int doStartTag() throws JspException
188 {
189 initializeView();
190
191 return EVAL_BODY_BUFFERED;
192 }
193
194 public int doEndTag() throws JspException
195 {
196 if (hasContent())
197 {
198 try
199 {
200
201 String varname = getVar();
202 if (varname == null)
203 {
204
205 renderContent(this.pageContext.getOut());
206 }
207 else
208 {
209
210 StringWriter out = new StringWriter();
211 renderContent(out);
212
213
214
215 this.pageContext.setAttribute(varname,
216 out.toString(),
217 toScopeInt(getScope()));
218 }
219 }
220 catch (Exception e)
221 {
222 throw new JspException("Failed to render " + getClass() +
223 ": "+getLogId(), e);
224 }
225 }
226 return EVAL_PAGE;
227 }
228
229
230 protected void initializeView()
231 {
232
233 VelocityView view =
234 ServletUtils.getVelocityView(this.pageContext.getServletConfig());
235
236
237 ViewToolContext context =
238 new JspToolContext(view.getVelocityEngine(), this.pageContext);
239
240 view.prepareContext(context, (HttpServletRequest)this.pageContext.getRequest());
241
242 setVelocityView(view);
243 setViewToolContext(context);
244 }
245
246 protected boolean hasContent()
247 {
248 return (getBodyContent() != null || getTemplate() != null);
249 }
250
251 protected void renderContent(Writer out) throws Exception
252 {
253 if (getTemplate() != null)
254 {
255 VelocityView view = getVelocityView();
256 ViewToolContext context = getViewToolContext();
257
258
259 Template template = view.getTemplate(getTemplate());
260
261 if (getBodyContent() != null)
262 {
263 context.put(getBodyContentKey(), getRenderedBody());
264 }
265
266
267 template.merge(context, out);
268 }
269 else
270 {
271
272 renderBody(out);
273 }
274 }
275
276 protected String getRenderedBody() throws Exception
277 {
278
279 StringWriter out = new StringWriter();
280 renderBody(out);
281 return out.toString();
282 }
283
284 protected boolean isCached()
285 {
286 return getRepository().getStringResource(getId()) != null;
287 }
288
289 protected void renderBody(Writer out) throws Exception
290 {
291 String name = getId();
292
293 if (cache && !isCached())
294 {
295 String template = getBodyContent().getString();
296
297 if (name == null)
298 {
299 name = template;
300 }
301 cache(name, template);
302 }
303
304 if (!cache)
305 {
306 evalBody(out);
307 }
308 else
309 {
310
311 Template template = getVelocityView().getTemplate(name);
312 template.merge(getViewToolContext(), out);
313 }
314 }
315
316 protected void evalBody(Writer out) throws Exception
317 {
318 VelocityEngine engine = getVelocityView().getVelocityEngine();
319 engine.evaluate(getViewToolContext(), out, getLogId(),
320 getBodyContent().getReader());
321 }
322
323 protected static int toScopeInt(String scope)
324 {
325 if (scope == null)
326 {
327 return PageContext.PAGE_SCOPE;
328 }
329 if (scope.equalsIgnoreCase("request"))
330 {
331 return PageContext.REQUEST_SCOPE;
332 }
333 if (scope.equalsIgnoreCase("session"))
334 {
335 return PageContext.SESSION_SCOPE;
336 }
337 if (scope.equalsIgnoreCase("application"))
338 {
339 return PageContext.APPLICATION_SCOPE;
340 }
341 if (scope.equalsIgnoreCase("page"))
342 {
343 return PageContext.PAGE_SCOPE;
344 }
345 throw new IllegalArgumentException("Unknown scope: "+scope);
346 }
347
348 protected void cache(String name, String template)
349 {
350 try
351 {
352 getRepository().putStringResource(name, template);
353 }
354 catch (Exception cnfe)
355 {
356 getVelocityView().getLog()
357 .error("Could not cache body in a StringResourceRepository", cnfe);
358 cache = false;
359 }
360 }
361
362
363
364
365
366
367
368 @Override
369 public void release()
370 {
371 super.release();
372 reset();
373 }
374
375 }