1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.sitemesh;
19
20 import java.io.IOException;
21 import java.util.Locale;
22
23 import javax.servlet.ServletContext;
24 import javax.servlet.ServletException;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.struts2.views.freemarker.FreemarkerManager;
31
32 import com.opensymphony.module.sitemesh.Decorator;
33 import com.opensymphony.module.sitemesh.HTMLPage;
34 import com.opensymphony.module.sitemesh.Page;
35 import com.opensymphony.xwork2.ActionContext;
36 import com.opensymphony.xwork2.ActionInvocation;
37 import com.opensymphony.xwork2.LocaleProvider;
38 import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
39
40 import freemarker.template.Configuration;
41 import freemarker.template.SimpleHash;
42 import freemarker.template.Template;
43
44 /***
45 * Applies FreeMarker-based sitemesh decorators.
46 *
47 * <!-- START SNIPPET: javadoc -->
48 *
49 * The following variables are available to the decorating freemarker page :-
50 * <ul>
51 * <li>${title} - content of <title> tag in the decorated page</li>
52 * <li>${head} - content of <head> tag in the decorated page</li>
53 * <li>${body} - content of t<body> tag in the decorated page</li>
54 * <li>${page.properties} - content of the page properties</li>
55 * </ul>
56 * <p/>
57 * With the following decorated page :-
58 * <pre>
59 * <html>
60 * <meta name="author" content="tm_jee" />
61 * <head>
62 * <title>My Title</title>
63 * <link rel="stylesheet" type="text/css" href="mycss.css" />
64 * <style type="text/javascript" language="javascript" src="myjavascript.js"></script>
65 * </head>
66 * <body<
67 * <h1>Sample</h1>
68 * </body>
69 * </html>
70 * </pre>
71 * <p/>
72 * <table border="1">
73 * <tr>
74 * <td>Properties</td>
75 * <td>Content</td>
76 * </tr>
77 * <tr>
78 * <td>${title}</td>
79 * <td>My Title</td>
80 * </tr>
81 * <tr>
82 * <td>${head}</td>
83 * <td>
84 * <link rel="stylesheet" type="text/css" href="mycss.css" />
85 * <style type="text/javascript" language="javascript" src="myjavascript.js"></script>
86 * </td>
87 * </tr>
88 * <tr>
89 * <td>${body}</td>
90 * <td>
91 * <h1>Sample</h1>
92 * </td>
93 * </tr>
94 * <tr>
95 * <td>${page.properties.meta.author}</td>
96 * <td>tm_jee</td>
97 * </tr>
98 * </table>
99 *
100 * <!-- END SNIPPET: javadoc -->
101 *
102 * @version $Date: 2006-10-10 07:33:25 -0500 (Tue, 10 Oct 2006) $ $Id: FreeMarkerPageFilter.java 454721 2006-10-10 12:33:25Z tmjee $
103 */
104 public class FreeMarkerPageFilter extends TemplatePageFilter {
105 private static final Log LOG = LogFactory.getLog(FreeMarkerPageFilter.class);
106
107 /***
108 * Applies the decorator, using the relevent contexts
109 *
110 * @param page The page
111 * @param decorator The decorator
112 * @param req The servlet request
113 * @param res The servlet response
114 * @param servletContext The servlet context
115 * @param ctx The action context for this request, populated with the server state
116 */
117 protected void applyDecorator(Page page, Decorator decorator,
118 HttpServletRequest req, HttpServletResponse res,
119 ServletContext servletContext, ActionContext ctx)
120 throws ServletException, IOException {
121
122 String timerKey = "FreemarkerPageFilter_applyDecorator: ";
123 try {
124 UtilTimerStack.push(timerKey);
125
126 FreemarkerManager fmm = FreemarkerManager.getInstance();
127
128
129 Configuration config = fmm.getConfiguration(servletContext);
130 Template template = config.getTemplate(decorator.getPage(), getLocale(ctx.getActionInvocation(), config));
131
132
133 SimpleHash model = fmm.buildTemplateModel(ctx.getValueStack(), null, servletContext, req, res, config.getObjectWrapper());
134
135
136 model.put("page", page);
137 if (page instanceof HTMLPage) {
138 HTMLPage htmlPage = ((HTMLPage) page);
139 model.put("head", htmlPage.getHead());
140 }
141 model.put("title",page.getTitle());
142 model.put("body",page.getBody());
143 model.put("page.properties", new SimpleHash(page.getProperties()));
144
145
146 template.process(model, res.getWriter());
147 } catch (Exception e) {
148 String msg = "Error applying decorator: " + e.getMessage();
149 LOG.error(msg, e);
150 throw new ServletException(msg, e);
151 }
152 finally {
153 UtilTimerStack.pop(timerKey);
154 }
155 }
156
157 /***
158 * Returns the locale used for the {@link Configuration#getTemplate(String, Locale)} call. The base implementation
159 * simply returns the locale setting of the action (assuming the action implements {@link LocaleProvider}) or, if
160 * the action does not the configuration's locale is returned. Override this method to provide different behaviour,
161 */
162 protected Locale getLocale(ActionInvocation invocation, Configuration configuration) {
163 if (invocation.getAction() instanceof LocaleProvider) {
164 return ((LocaleProvider) invocation.getAction()).getLocale();
165 } else {
166 return configuration.getLocale();
167 }
168 }
169
170 }