Source Code Cross Referenced for FreemarkerServlet.java in  » Template-Engine » freemarker-2.3.10 » freemarker » ext » servlet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » freemarker 2.3.10 » freemarker.ext.servlet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2003 The Visigoth Software Society. All rights
003:         * reserved.
004:         *
005:         * Redistribution and use in source and binary forms, with or without
006:         * modification, are permitted provided that the following conditions
007:         * are met:
008:         *
009:         * 1. Redistributions of source code must retain the above copyright
010:         *    notice, this list of conditions and the following disclaimer.
011:         *
012:         * 2. Redistributions in binary form must reproduce the above copyright
013:         *    notice, this list of conditions and the following disclaimer in
014:         *    the documentation and/or other materials provided with the
015:         *    distribution.
016:         *
017:         * 3. The end-user documentation included with the redistribution, if
018:         *    any, must include the following acknowledgement:
019:         *       "This product includes software developed by the
020:         *        Visigoth Software Society (http://www.visigoths.org/)."
021:         *    Alternately, this acknowledgement may appear in the software itself,
022:         *    if and wherever such third-party acknowledgements normally appear.
023:         *
024:         * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the 
025:         *    project contributors may be used to endorse or promote products derived
026:         *    from this software without prior written permission. For written
027:         *    permission, please contact visigoths@visigoths.org.
028:         *
029:         * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
030:         *    nor may "FreeMarker" or "Visigoth" appear in their names
031:         *    without prior written permission of the Visigoth Software Society.
032:         *
033:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036:         * DISCLAIMED.  IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
037:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044:         * SUCH DAMAGE.
045:         * ====================================================================
046:         *
047:         * This software consists of voluntary contributions made by many
048:         * individuals on behalf of the Visigoth Software Society. For more
049:         * information on the Visigoth Software Society, please see
050:         * http://www.visigoths.org/
051:         */
052:
053:        package freemarker.ext.servlet;
054:
055:        import java.io.File;
056:        import java.io.FileNotFoundException;
057:        import java.io.IOException;
058:        import java.text.SimpleDateFormat;
059:        import java.util.Calendar;
060:        import java.util.Enumeration;
061:        import java.util.GregorianCalendar;
062:
063:        import javax.servlet.ServletContext;
064:        import javax.servlet.ServletException;
065:        import javax.servlet.http.HttpServlet;
066:        import javax.servlet.http.HttpServletRequest;
067:        import javax.servlet.http.HttpServletResponse;
068:        import javax.servlet.http.HttpSession;
069:
070:        import freemarker.cache.WebappTemplateLoader;
071:        import freemarker.core.Configurable;
072:        import freemarker.ext.jsp.TaglibFactory;
073:        import freemarker.log.Logger;
074:        import freemarker.template.Configuration;
075:        import freemarker.template.ObjectWrapper;
076:        import freemarker.template.Template;
077:        import freemarker.template.TemplateException;
078:        import freemarker.template.TemplateExceptionHandler;
079:        import freemarker.template.TemplateModel;
080:        import freemarker.template.TemplateModelException;
081:        import freemarker.template.utility.StringUtil;
082:        import java.util.Locale;
083:
084:        /**
085:         * <p>This is a general-purpose FreeMarker view servlet.</p>
086:         * 
087:         * <p>The main features are:
088:         * 
089:         * <ul>
090:         * 
091:         * <li>It makes all request, request parameters, session, and servlet
092:         * context attributes available to templates through <code>Request</code>,
093:         * <code>RequestParameters</code>, <code>Session</code>, and <code>Application</code>
094:         * variables.
095:         * 
096:         * <li>The scope variables are also available via automatic scope discovery. That is,
097:         * writing <code>Application.attrName</code>, <code>Session.attrName</code>,
098:         * <code>Request.attrName</code> is not mandatory; it's enough to write <code>attrName</code>,
099:         * and if no such variable was created in the template, it will search the
100:         * variable in <code>Request</code>, and then in <code>Session</code>,
101:         * and finally in <code>Application</code>.  
102:         * 
103:         * <li>It creates a variable with name <code>JspTaglibs</code>, that can be used
104:         * to load JSP taglibs. For example:<br>
105:         * <code>&lt;#assign tiles=JspTaglibs["/WEB-INF/struts-tiles.tld"]></code>
106:         * 
107:         * </ul>
108:         * 
109:         * <p>The servlet will rethrow the errors occurring during template processing,
110:         * wrapped into <code>ServletException</code>, except if the class name of the
111:         * class set by the <code>template_exception_handler</code> contains the
112:         * substring <code>"Debug"</code>. If it contains <code>"Debug"</code>, then it
113:         * is assumed that the template exception handler prints the error message to the
114:         * page, thus <code>FreemarkerServlet</code> will suppress the  exception, and
115:         * logs the problem with the servlet logger
116:         * (<code>javax.servlet.GenericServlet.log(...)</code>). 
117:         * 
118:         * <p>Supported init-params are:</p>
119:         * 
120:         * <ul>
121:         * 
122:         * <li><strong>TemplatePath</strong> specifies the location of the templates.
123:         * By default, this is interpreted as web application directory relative URI.<br>
124:         * Alternatively, you can prepend it with <tt>file://</tt> to indicate a literal
125:         * path in the file system (i.e. <tt>file:///var/www/project/templates/</tt>). 
126:         * Note that three slashes were used to specify an absolute path.<br>
127:         * Also, you can prepend it with <tt>class://path/to/template/package</tt> to
128:         * indicate that you want to load templates from the specified package
129:         * accessible through the classloader of the servlet.<br>
130:         * Default value is <tt>class://</tt> (that is, the root of the class hierarchy).
131:         * <i>Note that this default is different than the default in FreeMarker 1.x, when
132:         * it defaulted <tt>/</tt>, that is to loading from the webapp root directory.</i></li>
133:         * 
134:         * <li><strong>NoCache</strong> if set to true, generates headers in the response
135:         * that advise the HTTP client not to cache the returned page.
136:         * The default is <tt>false</tt>.</li>
137:         * 
138:         * <li><strong>ContentType</strong> if specified, response uses the specified
139:         * Content-type HTTP header. The value may include the charset (e.g.
140:         * <tt>"text/html; charset=ISO-8859-1"</tt>). If not specified, <tt>"text/html"</tt>
141:         * is used. If the charset is not specified in this init-param, then the charset
142:         * (encoding) of the actual template file will be used (in the response HTTP header
143:         * and for encoding the output stream). Note that this setting can be overridden
144:         * on a per-template basis by specifying a custom attribute named 
145:         * <tt>content_type</tt> in the <tt>attributes</tt> parameter of the 
146:         * <tt>&lt;#ftl></tt> directive. 
147:         * </li>
148:         * 
149:         * <li>The following init-params are supported only for backward compatibility, and
150:         * their usage is discouraged: TemplateUpdateInterval, DefaultEncoding,
151:         * ObjectWrapper, TemplateExceptionHandler. Use setting init-params such as
152:         * object_wrapper instead. 
153:         * 
154:         * <li>Any other init-param will be interpreted as <code>Configuration</code>
155:         * level setting. See {@link Configuration#setSetting}</li>
156:         * 
157:         * </ul>
158:         * 
159:         * @author Attila Szegedi
160:         * @version $Id: FreemarkerServlet.java,v 1.82.2.5 2006/06/21 13:02:01 ddekany Exp $
161:         */
162:
163:        public class FreemarkerServlet extends HttpServlet {
164:            private static final Logger logger = Logger
165:                    .getLogger("freemarker.servlet");
166:
167:            public static final long serialVersionUID = -2440216393145762479L;
168:
169:            private static final String INITPARAM_TEMPLATE_PATH = "TemplatePath";
170:            private static final String INITPARAM_NOCACHE = "NoCache";
171:            private static final String INITPARAM_CONTENT_TYPE = "ContentType";
172:            private static final String DEFAULT_CONTENT_TYPE = "text/html";
173:            private static final String INITPARAM_DEBUG = "Debug";
174:
175:            private static final String DEPR_INITPARAM_TEMPLATE_DELAY = "TemplateDelay";
176:            private static final String DEPR_INITPARAM_ENCODING = "DefaultEncoding";
177:            private static final String DEPR_INITPARAM_OBJECT_WRAPPER = "ObjectWrapper";
178:            private static final String DEPR_INITPARAM_WRAPPER_SIMPLE = "simple";
179:            private static final String DEPR_INITPARAM_WRAPPER_BEANS = "beans";
180:            private static final String DEPR_INITPARAM_WRAPPER_JYTHON = "jython";
181:            private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER = "TemplateExceptionHandler";
182:            private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW = "rethrow";
183:            private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG = "debug";
184:            private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_HTML_DEBUG = "htmlDebug";
185:            private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_IGNORE = "ignore";
186:            private static final String DEPR_INITPARAM_DEBUG = "debug";
187:
188:            public static final String KEY_REQUEST = "Request";
189:            public static final String KEY_REQUEST_PRIVATE = "__FreeMarkerServlet.Request__";
190:            public static final String KEY_REQUEST_PARAMETERS = "RequestParameters";
191:            public static final String KEY_SESSION = "Session";
192:            public static final String KEY_APPLICATION = "Application";
193:            public static final String KEY_APPLICATION_PRIVATE = "__FreeMarkerServlet.Application__";
194:            public static final String KEY_JSP_TAGLIBS = "JspTaglibs";
195:
196:            // Note these names start with dot, so they're essentially invisible from
197:            // a freemarker script.
198:            private static final String ATTR_REQUEST_MODEL = ".freemarker.Request";
199:            private static final String ATTR_REQUEST_PARAMETERS_MODEL = ".freemarker.RequestParameters";
200:            private static final String ATTR_SESSION_MODEL = ".freemarker.Session";
201:            private static final String ATTR_APPLICATION_MODEL = ".freemarker.Application";
202:            private static final String ATTR_JSP_TAGLIBS_MODEL = ".freemarker.JspTaglibs";
203:
204:            private static final String EXPIRATION_DATE;
205:
206:            static {
207:                // Generate expiration date that is one year from now in the past
208:                GregorianCalendar expiration = new GregorianCalendar();
209:                expiration.roll(Calendar.YEAR, -1);
210:                SimpleDateFormat httpDate = new SimpleDateFormat(
211:                        "EEE, dd MMM yyyy HH:mm:ss z", java.util.Locale.US);
212:                EXPIRATION_DATE = httpDate.format(expiration.getTime());
213:            }
214:
215:            private String templatePath;
216:            private boolean nocache;
217:            protected boolean debug;
218:            private Configuration config;
219:            private ObjectWrapper wrapper;
220:            private String contentType;
221:            private boolean noCharsetInContentType;
222:
223:            public void init() throws ServletException {
224:                try {
225:                    config = createConfiguration();
226:
227:                    // Set defaults:
228:                    config
229:                            .setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
230:                    contentType = DEFAULT_CONTENT_TYPE;
231:
232:                    // Process object_wrapper init-param out of order: 
233:                    wrapper = createObjectWrapper();
234:                    if (logger.isDebugEnabled()) {
235:                        logger.debug("Using object wrapper of class "
236:                                + wrapper.getClass().getName());
237:                    }
238:                    config.setObjectWrapper(wrapper);
239:
240:                    // Process TemplatePath init-param out of order:
241:                    templatePath = getInitParameter(INITPARAM_TEMPLATE_PATH);
242:                    if (templatePath == null)
243:                        templatePath = "class://";
244:                    if (templatePath.startsWith("class://")) {
245:                        // substring(7) is intentional as we "reuse" the last slash
246:                        config.setClassForTemplateLoading(getClass(),
247:                                templatePath.substring(7));
248:                    } else {
249:                        if (templatePath.startsWith("file://")) {
250:                            templatePath = templatePath.substring(7);
251:                            config.setDirectoryForTemplateLoading(new File(
252:                                    templatePath));
253:                        } else {
254:                            config.setTemplateLoader(new WebappTemplateLoader(
255:                                    this .getServletContext(), templatePath));
256:                        }
257:                    }
258:
259:                    // Process all other init-params:
260:                    Enumeration initpnames = getServletConfig()
261:                            .getInitParameterNames();
262:                    while (initpnames.hasMoreElements()) {
263:                        String name = (String) initpnames.nextElement();
264:                        String value = getInitParameter(name);
265:
266:                        if (name == null) {
267:                            throw new ServletException(
268:                                    "init-param without param-name. "
269:                                            + "Maybe the web.xml is not well-formed?");
270:                        }
271:                        if (value == null) {
272:                            throw new ServletException(
273:                                    "init-param without param-value. "
274:                                            + "Maybe the web.xml is not well-formed?");
275:                        }
276:
277:                        if (name.equals(DEPR_INITPARAM_OBJECT_WRAPPER)
278:                                || name.equals(Configurable.OBJECT_WRAPPER_KEY)
279:                                || name.equals(INITPARAM_TEMPLATE_PATH)) {
280:                            // ignore: we have already processed these
281:                        } else if (name.equals(DEPR_INITPARAM_ENCODING)) { // BC
282:                            if (getInitParameter(Configuration.DEFAULT_ENCODING_KEY) != null) {
283:                                throw new ServletException(
284:                                        "Conflicting init-params: "
285:                                                + Configuration.DEFAULT_ENCODING_KEY
286:                                                + " and "
287:                                                + DEPR_INITPARAM_ENCODING);
288:                            }
289:                            config.setDefaultEncoding(value);
290:                        } else if (name.equals(DEPR_INITPARAM_TEMPLATE_DELAY)) { // BC
291:                            if (getInitParameter(Configuration.TEMPLATE_UPDATE_DELAY_KEY) != null) {
292:                                throw new ServletException(
293:                                        "Conflicting init-params: "
294:                                                + Configuration.TEMPLATE_UPDATE_DELAY_KEY
295:                                                + " and "
296:                                                + DEPR_INITPARAM_TEMPLATE_DELAY);
297:                            }
298:                            try {
299:                                config.setTemplateUpdateDelay(Integer
300:                                        .parseInt(value));
301:                            } catch (NumberFormatException e) {
302:                                // Intentionally ignored
303:                            }
304:                        } else if (name
305:                                .equals(DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER)) { // BC
306:                            if (getInitParameter(Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY) != null) {
307:                                throw new ServletException(
308:                                        "Conflicting init-params: "
309:                                                + Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY
310:                                                + " and "
311:                                                + DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER);
312:                            }
313:
314:                            if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW
315:                                    .equals(value)) {
316:                                config
317:                                        .setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
318:                            } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG
319:                                    .equals(value)) {
320:                                config
321:                                        .setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
322:                            } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_HTML_DEBUG
323:                                    .equals(value)) {
324:                                config
325:                                        .setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
326:                            } else if (DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_IGNORE
327:                                    .equals(value)) {
328:                                config
329:                                        .setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
330:                            } else {
331:                                throw new ServletException(
332:                                        "Invalid value for servlet init-param "
333:                                                + DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER
334:                                                + ": " + value);
335:                            }
336:                        } else if (name.equals(INITPARAM_NOCACHE)) {
337:                            nocache = StringUtil.getYesNo(value);
338:                        } else if (name.equals(DEPR_INITPARAM_DEBUG)) { // BC
339:                            if (getInitParameter(INITPARAM_DEBUG) != null) {
340:                                throw new ServletException(
341:                                        "Conflicting init-params: "
342:                                                + INITPARAM_DEBUG + " and "
343:                                                + DEPR_INITPARAM_DEBUG);
344:                            }
345:                            debug = StringUtil.getYesNo(value);
346:                        } else if (name.equals(INITPARAM_DEBUG)) {
347:                            debug = StringUtil.getYesNo(value);
348:                        } else if (name.equals(INITPARAM_CONTENT_TYPE)) {
349:                            contentType = value;
350:                        } else {
351:                            config.setSetting(name, value);
352:                        }
353:                    } // while initpnames
354:
355:                    noCharsetInContentType = true;
356:                    int i = contentType.toLowerCase().indexOf("charset=");
357:                    if (i != -1) {
358:                        char c = ' ';
359:                        i--;
360:                        while (i >= 0) {
361:                            c = contentType.charAt(i);
362:                            if (!Character.isWhitespace(c))
363:                                break;
364:                            i--;
365:                        }
366:                        if (i == -1 || c == ';') {
367:                            noCharsetInContentType = false;
368:                        }
369:                    }
370:                } catch (ServletException e) {
371:                    throw e;
372:                } catch (Exception e) {
373:                    throw new ServletException(e);
374:                }
375:            }
376:
377:            public void doGet(HttpServletRequest request,
378:                    HttpServletResponse response) throws ServletException,
379:                    IOException {
380:                process(request, response);
381:            }
382:
383:            public void doPost(HttpServletRequest request,
384:                    HttpServletResponse response) throws ServletException,
385:                    IOException {
386:                process(request, response);
387:            }
388:
389:            private void process(HttpServletRequest request,
390:                    HttpServletResponse response) throws ServletException,
391:                    IOException {
392:                // Give chance to subclasses to perform preprocessing
393:                if (preprocessRequest(request, response)) {
394:                    return;
395:                }
396:
397:                String path = requestUrlToTemplatePath(request);
398:
399:                if (debug) {
400:                    log("Requested template: " + path);
401:                }
402:
403:                Template template = null;
404:                try {
405:                    template = config.getTemplate(path, deduceLocale(path,
406:                            request, response));
407:                } catch (FileNotFoundException e) {
408:                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
409:                    return;
410:                }
411:
412:                Object attrContentType = template
413:                        .getCustomAttribute("content_type");
414:                if (attrContentType != null) {
415:                    response.setContentType(attrContentType.toString());
416:                } else {
417:                    if (noCharsetInContentType) {
418:                        response.setContentType(contentType + "; charset="
419:                                + template.getEncoding());
420:                    } else {
421:                        response.setContentType(contentType);
422:                    }
423:                }
424:
425:                // Set cache policy
426:                setBrowserCachingPolicy(response);
427:
428:                ServletContext servletContext = getServletContext();
429:                try {
430:                    TemplateModel model = createModel(wrapper, servletContext,
431:                            request, response);
432:
433:                    // Give subclasses a chance to hook into preprocessing
434:                    if (preTemplateProcess(request, response, template, model)) {
435:                        try {
436:                            // Process the template
437:                            template.process(model, response.getWriter());
438:                        } finally {
439:                            // Give subclasses a chance to hook into postprocessing
440:                            postTemplateProcess(request, response, template,
441:                                    model);
442:                        }
443:                    }
444:                } catch (TemplateException te) {
445:                    if (config.getTemplateExceptionHandler().getClass()
446:                            .getName().indexOf("Debug") != -1) {
447:                        this .log("Error executing FreeMarker template", te);
448:                    } else {
449:                        ServletException e = new ServletException(
450:                                "Error executing FreeMarker template", te);
451:                        // Attempt to set init cause, but don't freak out if the method
452:                        // is not available (i.e. pre-1.4 JRE). This is required as the
453:                        // constructor-passed throwable won't show up automatically in
454:                        // stack traces.
455:                        try {
456:                            e.getClass().getMethod("initCause",
457:                                    new Class[] { Throwable.class }).invoke(e,
458:                                    new Object[] { te });
459:                        } catch (Exception ex) {
460:                            // Can't set init cause, we're probably running on a pre-1.4
461:                            // JDK, oh well...
462:                        }
463:                        throw e;
464:                    }
465:                }
466:            }
467:
468:            /**
469:             * Returns the locale used for the 
470:             * {@link Configuration#getTemplate(String, Locale)} call.
471:             * The base implementation simply returns the locale setting of the
472:             * configuration. Override this method to provide different behaviour, i.e.
473:             * to use the locale indicated in the request.
474:             */
475:            protected Locale deduceLocale(String templatePath,
476:                    HttpServletRequest request, HttpServletResponse response) {
477:                return config.getLocale();
478:            }
479:
480:            protected TemplateModel createModel(ObjectWrapper wrapper,
481:                    ServletContext servletContext, HttpServletRequest request,
482:                    HttpServletResponse response) throws TemplateModelException {
483:                try {
484:                    AllHttpScopesHashModel params = new AllHttpScopesHashModel(
485:                            wrapper, servletContext, request);
486:
487:                    // Create hash model wrapper for servlet context (the application)
488:                    ServletContextHashModel servletContextModel = (ServletContextHashModel) servletContext
489:                            .getAttribute(ATTR_APPLICATION_MODEL);
490:                    if (servletContextModel == null) {
491:                        servletContextModel = new ServletContextHashModel(this ,
492:                                wrapper);
493:                        servletContext.setAttribute(ATTR_APPLICATION_MODEL,
494:                                servletContextModel);
495:                        TaglibFactory taglibs = new TaglibFactory(
496:                                servletContext);
497:                        servletContext.setAttribute(ATTR_JSP_TAGLIBS_MODEL,
498:                                taglibs);
499:                        initializeServletContext(request, response);
500:                    }
501:                    params.putUnlistedModel(KEY_APPLICATION,
502:                            servletContextModel);
503:                    params.putUnlistedModel(KEY_APPLICATION_PRIVATE,
504:                            servletContextModel);
505:                    params.putUnlistedModel(KEY_JSP_TAGLIBS,
506:                            (TemplateModel) servletContext
507:                                    .getAttribute(ATTR_JSP_TAGLIBS_MODEL));
508:                    // Create hash model wrapper for session
509:                    HttpSessionHashModel sessionModel;
510:                    HttpSession session = request.getSession(false);
511:                    if (session != null) {
512:                        sessionModel = (HttpSessionHashModel) session
513:                                .getAttribute(ATTR_SESSION_MODEL);
514:                        if (sessionModel == null || sessionModel.isZombie()) {
515:                            sessionModel = new HttpSessionHashModel(session,
516:                                    wrapper);
517:                            session.setAttribute(ATTR_SESSION_MODEL,
518:                                    sessionModel);
519:                            if (!sessionModel.isZombie()) {
520:                                initializeSession(request, response);
521:                            }
522:                        }
523:                    } else {
524:                        sessionModel = new HttpSessionHashModel(this , request,
525:                                response, wrapper);
526:                    }
527:                    params.putUnlistedModel(KEY_SESSION, sessionModel);
528:
529:                    // Create hash model wrapper for request
530:                    HttpRequestHashModel requestModel = (HttpRequestHashModel) request
531:                            .getAttribute(ATTR_REQUEST_MODEL);
532:                    if (requestModel == null
533:                            || requestModel.getRequest() != request) {
534:                        requestModel = new HttpRequestHashModel(request,
535:                                response, wrapper);
536:                        request.setAttribute(ATTR_REQUEST_MODEL, requestModel);
537:                        request.setAttribute(ATTR_REQUEST_PARAMETERS_MODEL,
538:                                createRequestParametersHashModel(request));
539:                    }
540:                    params.putUnlistedModel(KEY_REQUEST, requestModel);
541:                    params.putUnlistedModel(KEY_REQUEST_PRIVATE, requestModel);
542:
543:                    // Create hash model wrapper for request parameters
544:                    HttpRequestParametersHashModel requestParametersModel = (HttpRequestParametersHashModel) request
545:                            .getAttribute(ATTR_REQUEST_PARAMETERS_MODEL);
546:                    params.putUnlistedModel(KEY_REQUEST_PARAMETERS,
547:                            requestParametersModel);
548:                    return params;
549:                } catch (ServletException e) {
550:                    throw new TemplateModelException(e);
551:                } catch (IOException e) {
552:                    throw new TemplateModelException(e);
553:                }
554:            }
555:
556:            /**
557:             * Maps the request URL to a template path that is passed to 
558:             * {@link Configuration#getTemplate(String, Locale)}. You can override it
559:             * (i.e. to provide advanced rewriting capabilities), but you are strongly
560:             * encouraged to call the overridden method first, then only modify its
561:             * return value. 
562:             * @param request the currently processed request
563:             * @return a String representing the template path
564:             */
565:            protected String requestUrlToTemplatePath(HttpServletRequest request) {
566:                // First, see if it is an included request
567:                String includeServletPath = (String) request
568:                        .getAttribute("javax.servlet.include.servlet_path");
569:                if (includeServletPath != null) {
570:                    // Try path info; only if that's null (servlet is mapped to an
571:                    // URL extension instead of to prefix) use servlet path.
572:                    String includePathInfo = (String) request
573:                            .getAttribute("javax.servlet.include.path_info");
574:                    return includePathInfo == null ? includeServletPath
575:                            : includePathInfo;
576:                }
577:                // Seems that the servlet was not called as the result of a 
578:                // RequestDispatcher.include(...). Try pathInfo then servletPath again,
579:                // only now directly on the request object:
580:                String path = request.getPathInfo();
581:                if (path != null)
582:                    return path;
583:                path = request.getServletPath();
584:                if (path != null)
585:                    return path;
586:                // Seems that it is a servlet mapped with prefix, and there was no extra path info.
587:                return "";
588:            }
589:
590:            /**
591:             * Called as the first step in request processing, before the templating mechanism
592:             * is put to work. By default does nothing and returns false. This method is
593:             * typically overridden to manage serving of non-template resources (i.e. images)
594:             * that reside in the template directory.
595:             * @param request the HTTP request
596:             * @param response the HTTP response
597:             * @return true to indicate this method has processed the request entirely,
598:             * and that the further request processing should not take place.
599:             */
600:            protected boolean preprocessRequest(HttpServletRequest request,
601:                    HttpServletResponse response) throws ServletException,
602:                    IOException {
603:                return false;
604:            }
605:
606:            /**
607:             * This method is called from {@link #init()} to create the
608:             * FreeMarker configuration object that this servlet will use
609:             * for template loading. This is a hook that allows you
610:             * to custom-configure the configuration object in a subclass.
611:             * The default implementation returns a new {@link Configuration}
612:             * instance.
613:             */
614:            protected Configuration createConfiguration() {
615:                return new Configuration();
616:            }
617:
618:            /**
619:             * This method is called from {@link #init()} to create the
620:             * FreeMarker object wrapper object that this servlet will use
621:             * for adapting request, session, and servlet context attributes into 
622:             * template models.. This is a hook that allows you
623:             * to custom-configure the wrapper object in a subclass.
624:             * The default implementation returns a wrapper that depends on the value
625:             * of <code>ObjectWrapper</code> init parameter. If <code>simple</code> is
626:             * specified, {@link ObjectWrapper#SIMPLE_WRAPPER} is used; if <code>jython</code>
627:             * is specified, {@link freemarker.ext.jython.JythonWrapper} is used. In
628:             * every other case {@link ObjectWrapper#DEFAULT_WRAPPER} is used.
629:             */
630:            protected ObjectWrapper createObjectWrapper() {
631:                String wrapper = getServletConfig().getInitParameter(
632:                        DEPR_INITPARAM_OBJECT_WRAPPER);
633:                if (wrapper != null) { // BC
634:                    if (getInitParameter(Configurable.OBJECT_WRAPPER_KEY) != null) {
635:                        throw new RuntimeException("Conflicting init-params: "
636:                                + Configurable.OBJECT_WRAPPER_KEY + " and "
637:                                + DEPR_INITPARAM_OBJECT_WRAPPER);
638:                    }
639:                    if (DEPR_INITPARAM_WRAPPER_BEANS.equals(wrapper)) {
640:                        return ObjectWrapper.BEANS_WRAPPER;
641:                    }
642:                    if (DEPR_INITPARAM_WRAPPER_SIMPLE.equals(wrapper)) {
643:                        return ObjectWrapper.SIMPLE_WRAPPER;
644:                    }
645:                    if (DEPR_INITPARAM_WRAPPER_JYTHON.equals(wrapper)) {
646:                        // Avoiding compile-time dependency on Jython package
647:                        try {
648:                            return (ObjectWrapper) Class.forName(
649:                                    "freemarker.ext.jython.JythonWrapper")
650:                                    .newInstance();
651:                        } catch (InstantiationException e) {
652:                            throw new InstantiationError(e.getMessage());
653:                        } catch (IllegalAccessException e) {
654:                            throw new IllegalAccessError(e.getMessage());
655:                        } catch (ClassNotFoundException e) {
656:                            throw new NoClassDefFoundError(e.getMessage());
657:                        }
658:                    }
659:                    //            return BeansWrapper.getDefaultInstance();
660:                    return ObjectWrapper.DEFAULT_WRAPPER;
661:                } else {
662:                    wrapper = getInitParameter(Configurable.OBJECT_WRAPPER_KEY);
663:                    if (wrapper == null) {
664:                        //                return BeansWrapper.getDefaultInstance();
665:                        return ObjectWrapper.DEFAULT_WRAPPER;
666:                    } else {
667:                        try {
668:                            config.setSetting(Configurable.OBJECT_WRAPPER_KEY,
669:                                    wrapper);
670:                        } catch (TemplateException e) {
671:                            throw new RuntimeException(e.toString());
672:                        }
673:                        return config.getObjectWrapper();
674:                    }
675:                }
676:            }
677:
678:            protected ObjectWrapper getObjectWrapper() {
679:                return wrapper;
680:            }
681:
682:            protected final String getTemplatePath() {
683:                return templatePath;
684:            }
685:
686:            protected HttpRequestParametersHashModel createRequestParametersHashModel(
687:                    HttpServletRequest request) {
688:                return new HttpRequestParametersHashModel(request);
689:            }
690:
691:            /**
692:             * Called when servlet detects in a request processing that
693:             * application-global (that is, ServletContext-specific) attributes are not yet
694:             * set.
695:             * This is a generic hook you might use in subclasses to perform a specific
696:             * action on first request in the context. By default it does nothing.
697:             * @param request the actual HTTP request
698:             * @param response the actual HTTP response
699:             */
700:            protected void initializeServletContext(HttpServletRequest request,
701:                    HttpServletResponse response) throws ServletException,
702:                    IOException {
703:            }
704:
705:            /**
706:             * Called when servlet detects in a request processing that session-global 
707:             * (that is, HttpSession-specific) attributes are not yet set.
708:             * This is a generic hook you might use in subclasses to perform a specific
709:             * action on first request in the session. By default it does nothing. It
710:             * is only invoked on newly created sessions; it is not invoked when a
711:             * replicated session is reinstantiated in another servlet container.
712:             * 
713:             * @param request the actual HTTP request
714:             * @param response the actual HTTP response
715:             */
716:            protected void initializeSession(HttpServletRequest request,
717:                    HttpServletResponse response) throws ServletException,
718:                    IOException {
719:            }
720:
721:            /**
722:             * Called before the execution is passed to template.process().
723:             * This is a generic hook you might use in subclasses to perform a specific
724:             * action before the template is processed. By default does nothing.
725:             * A typical action to perform here is to inject application-specific
726:             * objects into the model root
727:             * @param request the actual HTTP request
728:             * @param response the actual HTTP response
729:             * @param template the template that will get executed
730:             * @param data the data that will be passed to the template
731:             * @return true to process the template, false to suppress template processing.
732:             */
733:            protected boolean preTemplateProcess(HttpServletRequest request,
734:                    HttpServletResponse response, Template template,
735:                    TemplateModel data) throws ServletException, IOException {
736:                return true;
737:            }
738:
739:            /**
740:             * Called after the execution returns from template.process().
741:             * This is a generic hook you might use in subclasses to perform a specific
742:             * action after the template is processed. It will be invoked even if the
743:             * template processing throws an exception. By default does nothing.
744:             * @param request the actual HTTP request
745:             * @param response the actual HTTP response
746:             * @param template the template that was executed
747:             * @param data the data that was passed to the template
748:             */
749:            protected void postTemplateProcess(HttpServletRequest request,
750:                    HttpServletResponse response, Template template,
751:                    TemplateModel data) throws ServletException, IOException {
752:            }
753:
754:            /**
755:             * Returns the {@link freemarker.template.Configuration} object used by this servlet.
756:             * Please don't forget that {@link freemarker.template.Configuration} is not thread-safe
757:             * when you modify it.
758:             */
759:            protected Configuration getConfiguration() {
760:                return config;
761:            }
762:
763:            /**
764:             * If the parameter "nocache" was set to true, generate a set of headers
765:             * that will advise the HTTP client not to cache the returned page.
766:             */
767:            private void setBrowserCachingPolicy(HttpServletResponse res) {
768:                if (nocache) {
769:                    // HTTP/1.1 + IE extensions
770:                    res.setHeader("Cache-Control",
771:                            "no-store, no-cache, must-revalidate, "
772:                                    + "post-check=0, pre-check=0");
773:                    // HTTP/1.0
774:                    res.setHeader("Pragma", "no-cache");
775:                    // Last resort for those that ignore all of the above
776:                    res.setHeader("Expires", EXPIRATION_DATE);
777:                }
778:            }
779:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.