KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > webwork > views > freemarker > FreemarkerManager


1 /*
2  * Copyright (c) 2002-2003 by OpenSymphony
3  * All rights reserved.
4  */

5 /*
6  * Created on 18/04/2004
7  */

8 package com.opensymphony.webwork.views.freemarker;
9
10 import com.opensymphony.util.FileManager;
11 import com.opensymphony.webwork.config.Configuration;
12 import com.opensymphony.webwork.views.JspSupportServlet;
13 import com.opensymphony.webwork.views.freemarker.tags.WebWorkModels;
14 import com.opensymphony.webwork.views.util.ContextUtil;
15 import com.opensymphony.xwork.ActionContext;
16 import com.opensymphony.xwork.ObjectFactory;
17 import com.opensymphony.xwork.util.OgnlValueStack;
18 import freemarker.cache.*;
19 import freemarker.ext.beans.BeansWrapper;
20 import freemarker.ext.jsp.TaglibFactory;
21 import freemarker.ext.servlet.HttpRequestHashModel;
22 import freemarker.ext.servlet.HttpSessionHashModel;
23 import freemarker.ext.servlet.ServletContextHashModel;
24 import freemarker.template.*;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import javax.servlet.GenericServlet JavaDoc;
29 import javax.servlet.ServletContext JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32 import javax.servlet.http.HttpSession JavaDoc;
33 import java.io.File JavaDoc;
34 import java.io.IOException JavaDoc;
35 import java.io.InputStream JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Properties JavaDoc;
38
39
40 /**
41  * Static Configuration Manager for the FreemarkerResult's configuration
42  *
43  * @author CameronBraid
44  */

45 public class FreemarkerManager {
46     //~ Static fields/initializers /////////////////////////////////////////////
47

48     private static final Log log = LogFactory.getLog(FreemarkerManager.class);
49     public static final String JavaDoc CONFIG_SERVLET_CONTEXT_KEY = "freemarker.Configuration";
50     public static final String JavaDoc KEY_EXCEPTION = "exception";
51
52     // coppied from freemarker servlet - since they are private
53
private static final String JavaDoc ATTR_APPLICATION_MODEL = ".freemarker.Application";
54     private static final String JavaDoc ATTR_JSP_TAGLIBS_MODEL = ".freemarker.JspTaglibs";
55     private static final String JavaDoc ATTR_SESSION_MODEL = ".freemarker.Session";
56     private static final String JavaDoc ATTR_REQUEST_MODEL = ".freemarker.Request";
57
58     // coppied from freemarker servlet - so that there is no dependency on it
59
public static final String JavaDoc KEY_APPLICATION = "Application";
60     public static final String JavaDoc KEY_REQUEST_MODEL = "Request";
61     public static final String JavaDoc KEY_SESSION_MODEL = "Session";
62     public static final String JavaDoc KEY_JSP_TAGLIBS = "JspTaglibs";
63     private static FreemarkerManager instance = null;
64
65     //~ Methods ////////////////////////////////////////////////////////////////
66

67     /**
68      * To allow for custom configuration of freemarker, sublcass this class "ConfigManager" and
69      * set the webwork configuration property
70      * <b>webwork.freemarker.configmanager.classname</b> to the fully qualified classname.
71      * <p/>
72      * This allows you to override the protected methods in the ConfigMangaer
73      * to programatically create your own Configuration instance
74      */

75     public final static synchronized FreemarkerManager getInstance() {
76         if (instance == null) {
77             String JavaDoc classname = FreemarkerManager.class.getName();
78
79             if (Configuration.isSet("webwork.freemarker.manager.classname")) {
80                 classname = Configuration.getString("webwork.freemarker.manager.classname").trim();
81             }
82
83             try {
84                 log.info("Instantiating Freemarker ConfigManager!, " + classname);
85                 instance = (FreemarkerManager) ObjectFactory.getObjectFactory().buildBean(Class.forName(classname));
86             } catch (Exception JavaDoc e) {
87                 log.fatal("Fatal exception occurred while trying to instantiate a Freemarker ConfigManager instance, " + classname, e);
88             }
89         }
90
91         // if the instance creation failed, make sure there is a default instance
92
if (instance == null) {
93             instance = new FreemarkerManager();
94         }
95
96         return instance;
97     }
98
99     public final synchronized freemarker.template.Configuration getConfigruation(ServletContext JavaDoc servletContext) throws TemplateException {
100         freemarker.template.Configuration config = (freemarker.template.Configuration) servletContext.getAttribute(CONFIG_SERVLET_CONTEXT_KEY);
101
102         if (config == null) {
103             config = createConfiguration(servletContext);
104
105             // store this configuration in the servlet context
106
servletContext.setAttribute(CONFIG_SERVLET_CONTEXT_KEY, config);
107         }
108
109         config.setWhitespaceStripping(true);
110
111         return config;
112     }
113
114     public ScopesHashModel buildScopesHashModel(ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ObjectWrapper wrapper, OgnlValueStack stack) {
115         ScopesHashModel model = new ScopesHashModel(wrapper, servletContext, request, stack);
116
117         // Create hash model wrapper for servlet context (the application)
118
// only need one thread to do this once, per servlet context
119
synchronized (servletContext) {
120             ServletContextHashModel servletContextModel = (ServletContextHashModel) servletContext.getAttribute(ATTR_APPLICATION_MODEL);
121
122             if (servletContextModel == null) {
123
124                 GenericServlet JavaDoc servlet = JspSupportServlet.jspSupportServlet;
125                 // TODO if the jsp support servlet isn't load-on-startup then it won't exist
126
// if it hasn't been accessed, and a JSP page is accessed
127
if (servlet != null) {
128                     servletContextModel = new ServletContextHashModel(servlet, wrapper);
129                     servletContext.setAttribute(ATTR_APPLICATION_MODEL, servletContextModel);
130                     TaglibFactory taglibs = new TaglibFactory(servletContext);
131                     servletContext.setAttribute(ATTR_JSP_TAGLIBS_MODEL, taglibs);
132                 }
133
134             }
135
136             model.put(KEY_APPLICATION, servletContextModel);
137             model.put(KEY_JSP_TAGLIBS, (TemplateModel) servletContext.getAttribute(ATTR_JSP_TAGLIBS_MODEL));
138         }
139
140         // Create hash model wrapper for session
141
TemplateHashModel sessionModel;
142
143         HttpSession JavaDoc session = request.getSession(false);
144         if (session != null) {
145             model.put(KEY_SESSION_MODEL, new HttpSessionHashModel(session, wrapper));
146         } else {
147             // no session means no attributes ???
148
// model.put(KEY_SESSION_MODEL, new SimpleHash());
149
}
150
151         // Create hash model wrapper for the request
152
HttpRequestHashModel requestModel = (HttpRequestHashModel) request.getAttribute(ATTR_REQUEST_MODEL);
153
154         if ((requestModel == null) || (requestModel.getRequest() != request)) {
155             requestModel = new HttpRequestHashModel(request, response, wrapper);
156             request.setAttribute(ATTR_REQUEST_MODEL, requestModel);
157         }
158
159         model.put(KEY_REQUEST_MODEL, requestModel);
160
161         return model;
162     }
163
164     /**
165      * @deprecated please use buildScopesHashModel(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response, ObjectWrapper wrapper, OgnlValueStack stack)
166      */

167     public ScopesHashModel buildScopesHashModel(ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ObjectWrapper wrapper) {
168         return buildScopesHashModel(servletContext, request, response, wrapper, ActionContext.getContext().getValueStack());
169     }
170
171     public void populateContext(ScopesHashModel model, OgnlValueStack stack, Object JavaDoc action, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
172         // put the same objects into the context that the velocity result uses
173
Map JavaDoc standard = ContextUtil.getStandardContext(stack, request, response);
174         model.putAll(standard);
175
176         // support for JSP exception pages, exposing the servlet or JSP exception
177
Throwable JavaDoc exception = (Throwable JavaDoc) request.getAttribute("javax.servlet.error.exception");
178
179         if (exception == null) {
180             exception = (Throwable JavaDoc) request.getAttribute("javax.servlet.error.JspException");
181         }
182
183         if (exception != null) {
184             model.put(KEY_EXCEPTION, exception);
185         }
186     }
187
188     protected BeansWrapper getObjectWrapper() {
189         BeansWrapper beansWrapper = new BeansWrapper();
190         beansWrapper.setSimpleMapWrapper(true);
191
192         return beansWrapper;
193     }
194
195     /**
196      * The default template loader is a MultiTemplateLoader which includes
197      * a ClassTemplateLoader and a WebappTemplateLoader (and a FileTemplateLoader depending on
198      * the init-parameter 'TemplatePath').
199      * <p/>
200      * The ClassTemplateLoader will resolve fully qualified template includes
201      * that begin with a slash. for example /com/company/template/common.ftl
202      * <p/>
203      * The WebappTemplateLoader attempts to resolve templates relative to the web root folder
204      */

205     protected TemplateLoader getTemplateLoader(ServletContext JavaDoc servletContext) {
206         // construct a FileTemplateLoader for the init-param 'TemplatePath'
207
FileTemplateLoader templatePathLoader = null;
208
209         String JavaDoc templatePath = servletContext.getInitParameter("TemplatePath");
210         if (templatePath == null) {
211             templatePath = servletContext.getInitParameter("templatePath");
212         }
213
214         if (templatePath != null) {
215             try {
216                 templatePathLoader = new FileTemplateLoader(new File JavaDoc(templatePath));
217             } catch (IOException JavaDoc e) {
218                 log.error("Invalid template path specified: " + e.getMessage(), e);
219             }
220         }
221
222         // presume that most apps will require the class and webapp template loader
223
// if people wish to
224
return templatePathLoader != null ?
225                 new MultiTemplateLoader(new TemplateLoader[]{
226                         templatePathLoader,
227                         new WebappTemplateLoader(servletContext),
228                         new WebWorkClassTemplateLoader()
229                 })
230                 : new MultiTemplateLoader(new TemplateLoader[]{
231                 new WebappTemplateLoader(servletContext),
232                 new WebWorkClassTemplateLoader()
233         });
234     }
235
236     /**
237      * Create the instance of the freemarker Configuration object.
238      * <p/>
239      * this implementation
240      * <ul>
241      * <li>obtains the default configuration from Configuration.getDefaultConfiguration()
242      * <li>sets up template loading from a ClassTemplateLoader and a WebappTemplateLoader
243      * <li>sets up the object wrapper to be the BeansWrapper
244      * <li>loads settings from the classpath file /freemarker.properties
245      * </ul>
246      *
247      * @param servletContext
248      */

249     protected freemarker.template.Configuration createConfiguration(ServletContext JavaDoc servletContext) throws TemplateException {
250         freemarker.template.Configuration configuration = freemarker.template.Configuration.getDefaultConfiguration();
251
252         configuration.setTemplateLoader(getTemplateLoader(servletContext));
253
254         configuration.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
255
256         configuration.setObjectWrapper(getObjectWrapper());
257
258         loadSettings(servletContext, configuration);
259
260         return configuration;
261     }
262
263     /**
264      * Load the settings from the /freemarker.properties file on the classpath
265      *
266      * @see freemarker.template.Configuration#setSettings for the definition of valid settings
267      */

268     protected void loadSettings(ServletContext JavaDoc servletContext, freemarker.template.Configuration configuration) {
269         try {
270             InputStream JavaDoc in = FileManager.loadFile("freemarker.properties", FreemarkerManager.class);
271
272             if (in != null) {
273                 Properties JavaDoc p = new Properties JavaDoc();
274                 p.load(in);
275                 configuration.setSettings(p);
276             }
277         } catch (IOException JavaDoc e) {
278             log.error("Error while loading freemarker settings from /freemarker.properties", e);
279         } catch (TemplateException e) {
280             log.error("Error while loading freemarker settings from /freemarker.properties", e);
281         }
282     }
283
284     public SimpleHash buildTemplateModel(OgnlValueStack stack, Object JavaDoc action, ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, ObjectWrapper wrapper) {
285         ScopesHashModel model = buildScopesHashModel(servletContext, request, response, wrapper);
286         populateContext(model, stack, action, request, response);
287         model.put("ww", new WebWorkModels(stack, request, response));
288         return model;
289     }
290 }
291
Popular Tags