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