1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.components.template;
19
20 import java.io.IOException;
21 import java.io.Writer;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import javax.servlet.ServletContext;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.struts2.ServletActionContext;
33 import org.apache.struts2.views.freemarker.FreemarkerManager;
34
35 import com.opensymphony.xwork2.util.ClassLoaderUtil;
36 import com.opensymphony.xwork2.ActionContext;
37 import com.opensymphony.xwork2.ActionInvocation;
38 import com.opensymphony.xwork2.util.ValueStack;
39
40 import freemarker.template.Configuration;
41 import freemarker.template.SimpleHash;
42
43 /***
44 * Freemarker based template engine.
45 */
46 public class FreemarkerTemplateEngine extends BaseTemplateEngine {
47 static Class bodyContent = null;
48
49 static {
50 try {
51 bodyContent = ClassLoaderUtil.loadClass("javax.servlet.jsp.tagext.BodyContent",
52 FreemarkerTemplateEngine.class);
53 } catch (ClassNotFoundException e) {
54
55
56
57
58 }
59 }
60
61 private static final Log LOG = LogFactory.getLog(FreemarkerTemplateEngine.class);
62
63 public void renderTemplate(TemplateRenderingContext templateContext) throws Exception {
64
65 ValueStack stack = templateContext.getStack();
66 Map context = stack.getContext();
67 ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT);
68 HttpServletRequest req = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST);
69 HttpServletResponse res = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE);
70
71
72 FreemarkerManager freemarkerManager = FreemarkerManager.getInstance();
73 Configuration config = freemarkerManager.getConfiguration(servletContext);
74
75
76 List templates = templateContext.getTemplate().getPossibleTemplates(this);
77
78
79 freemarker.template.Template template = null;
80 String templateName = null;
81 Exception exception = null;
82 for (Iterator iterator = templates.iterator(); iterator.hasNext();) {
83 Template t = (Template) iterator.next();
84 templateName = getFinalTemplateName(t);
85 try {
86
87 template = config.getTemplate(templateName);
88 break;
89 } catch (IOException e) {
90 if (exception == null) {
91 exception = e;
92 }
93 }
94 }
95
96 if (template == null) {
97 LOG.error("Could not load template " + templateContext.getTemplate());
98 if (exception != null) {
99 throw exception;
100 } else {
101 return;
102 }
103 }
104
105 if (LOG.isDebugEnabled()) {
106 LOG.debug("Rendering template " + templateName);
107 }
108
109 ActionInvocation ai = ActionContext.getContext().getActionInvocation();
110
111 Object action = (ai == null) ? null : ai.getAction();
112 SimpleHash model = freemarkerManager.buildTemplateModel(stack, action, servletContext, req, res, config.getObjectWrapper());
113
114 model.put("tag", templateContext.getTag());
115 model.put("themeProperties", getThemeProps(templateContext.getTemplate()));
116
117
118
119 Writer writer = templateContext.getWriter();
120 if (bodyContent != null && bodyContent.isAssignableFrom(writer.getClass())) {
121 final Writer wrapped = writer;
122 writer = new Writer() {
123 public void write(char cbuf[], int off, int len) throws IOException {
124 wrapped.write(cbuf, off, len);
125 }
126
127 public void flush() throws IOException {
128
129 }
130
131 public void close() throws IOException {
132 wrapped.close();
133 }
134 };
135 }
136
137 try {
138 stack.push(templateContext.getTag());
139 template.process(model, writer);
140 } finally {
141 stack.pop();
142 }
143 }
144
145 protected String getSuffix() {
146 return "ftl";
147 }
148 }