View Javadoc

1   /*
2    * $Id: FreeMarkerPageFilter.java 454721 2006-10-10 12:33:25Z tmjee $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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 &lt;title&gt; tag in the decorated page</li>
52   *      <li>${head}            - content of &lt;head&gt; tag in the decorated page</li>
53   *      <li>${body}            - content of t&lt;body&gt; 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   *  &lt;html&gt;
60   *      &lt;meta name="author" content="tm_jee" /&gt;
61   *      &lt;head&gt;
62   *          &lt;title&gt;My Title&lt;/title&gt;
63   *          &lt;link rel="stylesheet" type="text/css" href="mycss.css" /&gt;
64   *          &lt;style type="text/javascript" language="javascript" src="myjavascript.js"&gt;&lt;/script&gt;
65   *      &lt;/head&gt;
66   *      &lt;body&lt;
67   *          &lt;h1&gt;Sample&lt;/h1&gt;
68   *      &lt;/body&gt;
69   *  &lt;/html&gt;
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   *              &lt;link rel="stylesheet" type="text/css" href="mycss.css" /&gt;
85   *              &lt;style type="text/javascript" language="javascript" src="myjavascript.js"&gt;&lt;/script&gt;
86   *          </td>
87   *      </tr>
88   *      <tr>
89   *          <td>${body}</td>
90   *          <td>
91   *              &lt;h1&gt;Sample&lt;/h1&gt;
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             // get the configuration and template
129             Configuration config = fmm.getConfiguration(servletContext);
130             Template template = config.getTemplate(decorator.getPage(), getLocale(ctx.getActionInvocation(), config)); // WW-1181
131 
132             // get the main hash
133             SimpleHash model = fmm.buildTemplateModel(ctx.getValueStack(), null, servletContext, req, res, config.getObjectWrapper());
134 
135             // populate the hash with the page
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             // finally, render it
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 }