KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > webwork > dispatcher > VelocityResult


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

5 package com.opensymphony.webwork.dispatcher;
6
7 import com.opensymphony.webwork.ServletActionContext;
8 import com.opensymphony.webwork.config.Configuration;
9 import com.opensymphony.webwork.views.JspSupportServlet;
10 import com.opensymphony.webwork.views.velocity.VelocityManager;
11 import com.opensymphony.xwork.ActionContext;
12 import com.opensymphony.xwork.ActionInvocation;
13 import com.opensymphony.xwork.util.OgnlValueStack;
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16 import org.apache.velocity.Template;
17 import org.apache.velocity.app.VelocityEngine;
18 import org.apache.velocity.context.Context;
19
20 import javax.servlet.Servlet JavaDoc;
21 import javax.servlet.ServletContext JavaDoc;
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24 import javax.servlet.jsp.JspFactory JavaDoc;
25 import javax.servlet.jsp.PageContext JavaDoc;
26 import java.io.Writer JavaDoc;
27 import java.io.OutputStreamWriter JavaDoc;
28
29
30 /**
31  * Using the Servlet container's {@link JspFactory}, this result mocks a JSP execution environment
32  * and then displays a Velocity template that will be streamed directly to the servlet output. <p>
33  * <p/>
34  * This result follows the same rules from {@link WebWorkResultSupport}.
35  *
36  * @author <a HREF="mailto:matt@indigoegg.com">Matt Ho</a>
37  */

38 public class VelocityResult extends WebWorkResultSupport {
39     //~ Static fields/initializers /////////////////////////////////////////////
40

41     private static final Log log = LogFactory.getLog(VelocityResult.class);
42
43     //~ Methods ////////////////////////////////////////////////////////////////
44

45     /**
46      * Creates a Velocity context from the action, loads a Velocity template and executes the
47      * template. Output is written to the servlet output stream.
48      *
49      * @param finalLocation the location of the Velocity template
50      * @param invocation an encapsulation of the action execution state.
51      * @throws Exception if an error occurs when creating the Velocity context, loading or executing
52      * the template or writing output to the servlet response stream.
53      */

54     public void doExecute(String JavaDoc finalLocation, ActionInvocation invocation) throws Exception JavaDoc {
55         OgnlValueStack stack = ActionContext.getContext().getValueStack();
56
57         HttpServletRequest JavaDoc request = ServletActionContext.getRequest();
58         HttpServletResponse JavaDoc response = ServletActionContext.getResponse();
59         JspFactory JavaDoc jspFactory = null;
60         ServletContext JavaDoc servletContext = ServletActionContext.getServletContext();
61         Servlet servlet = JspSupportServlet.jspSupportServlet;
62
63         VelocityManager.getInstance().init(servletContext);
64
65         boolean usedJspFactory = false;
66         PageContext JavaDoc pageContext = (PageContext JavaDoc) ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT);
67
68         if (pageContext == null && servlet != null) {
69             jspFactory = JspFactory.getDefaultFactory();
70             pageContext = jspFactory.getPageContext(servlet, request, response, null, true, 8192, true);
71             ActionContext.getContext().put(ServletActionContext.PAGE_CONTEXT, pageContext);
72             usedJspFactory = true;
73         }
74
75         try {
76             String JavaDoc encoding = getEncoding(finalLocation);
77             String JavaDoc contentType = getContentType(finalLocation);
78
79             if (encoding != null) {
80                 contentType = contentType + ";charset=" + encoding;
81             }
82
83             VelocityManager velocityManager = VelocityManager.getInstance();
84             Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding);
85
86             Context context = createContext(velocityManager, stack, request, response, finalLocation);
87             Writer JavaDoc writer = new OutputStreamWriter JavaDoc(response.getOutputStream(), encoding);
88
89
90             response.setContentType(contentType);
91
92             t.merge(context, writer);
93
94             if (usedJspFactory) {
95                 writer.flush();
96             }
97         } catch (Exception JavaDoc e) {
98             log.error("Unable to render Velocity Template, '" + finalLocation + "'", e);
99             throw e;
100         } finally {
101             if (usedJspFactory) {
102                 jspFactory.releasePageContext(pageContext);
103             }
104         }
105
106         return;
107     }
108
109     /**
110      * Retrieve the content type for this template.
111      * <p/>
112      * People can override this method if they want to provide specific content types for specific templates (eg text/xml).
113      *
114      * @return The content type associated with this template (default "text/html")
115      */

116     protected String JavaDoc getContentType(String JavaDoc templateLocation) {
117         return "text/html";
118     }
119
120     /**
121      * Retrieve the encoding for this template.
122      * <p/>
123      * People can override this method if they want to provide specific encodings for specific templates.
124      *
125      * @return The encoding associated with this template (defaults to the value of 'webwork.i18n.encoding' property)
126      */

127     protected String JavaDoc getEncoding(String JavaDoc templateLocation) {
128         String JavaDoc encoding = (String JavaDoc) Configuration.get("webwork.i18n.encoding");
129         if (encoding == null) {
130             encoding = System.getProperty("file.encoding");
131         }
132         if (encoding == null) {
133             encoding = "UTF-8";
134         }
135         return encoding;
136     }
137
138     /**
139      * Given a value stack, a Velocity engine, and an action invocation, this method returns the appropriate
140      * Velocity template to render.
141      *
142      * @param stack the value stack to resolve the location again (when parse equals true)
143      * @param velocity the velocity engine to process the request against
144      * @param invocation an encapsulation of the action execution state.
145      * @param location the location of the template
146      * @param encoding the charset encoding of the template
147      * @return the template to render
148      * @throws Exception when the requested template could not be found
149      */

150     protected Template getTemplate(OgnlValueStack stack, VelocityEngine velocity, ActionInvocation invocation, String JavaDoc location, String JavaDoc encoding) throws Exception JavaDoc {
151         if (!location.startsWith("/")) {
152             location = invocation.getProxy().getNamespace() + "/" + location;
153         }
154
155         Template template = velocity.getTemplate(location, encoding);
156
157         return template;
158     }
159
160     /**
161      * Creates the VelocityContext that we'll use to render this page.
162      *
163      * @param velocityManager a reference to the velocityManager to use
164      * @param stack the value stack to resolve the location against (when parse equals true)
165      * @param location the name of the template that is being used
166      * @return the a minted Velocity context.
167      */

168     protected Context createContext(VelocityManager velocityManager, OgnlValueStack stack, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc location) {
169         return velocityManager.createContext(stack, request, response);
170     }
171 }
172
Popular Tags