1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet;
16  
17  import com.liferay.portal.kernel.util.StringBundler;
18  import com.liferay.portal.kernel.util.Validator;
19  import com.liferay.portal.kernel.velocity.VelocityContext;
20  import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
21  import com.liferay.portal.struts.StrutsUtil;
22  import com.liferay.portal.velocity.VelocityResourceListener;
23  
24  import java.io.IOException;
25  import java.io.PrintWriter;
26  
27  import javax.portlet.ActionRequest;
28  import javax.portlet.ActionResponse;
29  import javax.portlet.GenericPortlet;
30  import javax.portlet.MimeResponse;
31  import javax.portlet.PortletConfig;
32  import javax.portlet.PortletContext;
33  import javax.portlet.PortletException;
34  import javax.portlet.PortletRequest;
35  import javax.portlet.PortletResponse;
36  import javax.portlet.RenderRequest;
37  import javax.portlet.RenderResponse;
38  import javax.portlet.ResourceRequest;
39  import javax.portlet.ResourceResponse;
40  
41  import org.apache.velocity.io.VelocityWriter;
42  import org.apache.velocity.util.SimplePool;
43  
44  /**
45   * <a href="VelocityPortlet.java.html"><b><i>View Source</i></b></a>
46   *
47   * @author Brian Wing Shun Chan
48   * @author Steven P. Goldsmith
49   * @author Raymond Augé
50   */
51  public class VelocityPortlet extends GenericPortlet {
52  
53      public void init(PortletConfig portletConfig) throws PortletException {
54          super.init(portletConfig);
55  
56          PortletContext portletContext = portletConfig.getPortletContext();
57  
58          _portletContextName = portletContext.getPortletContextName();
59  
60          _actionTemplateId = getVelocityTemplateId(
61              getInitParameter("action-template"));
62          _editTemplateId = getVelocityTemplateId(
63              getInitParameter("edit-template"));
64          _helpTemplateId = getVelocityTemplateId(
65              getInitParameter("help-template"));
66          _resourceTemplateId = getVelocityTemplateId(
67              getInitParameter("resource-template"));
68          _viewTemplateId = getVelocityTemplateId(
69              getInitParameter("view-template"));
70      }
71  
72      public void processAction(
73              ActionRequest actionRequest, ActionResponse actionResponse)
74          throws PortletException {
75  
76          if (Validator.isNull(_actionTemplateId)) {
77              return;
78          }
79  
80          try {
81              mergeTemplate(_actionTemplateId, actionRequest, actionResponse);
82          }
83          catch (Exception e) {
84              throw new PortletException(e);
85          }
86      }
87  
88      public void serveResource(
89              ResourceRequest resourceRequest, ResourceResponse resourceResponse)
90          throws PortletException, IOException {
91  
92          if (Validator.isNull(_resourceTemplateId)) {
93              super.serveResource(resourceRequest, resourceResponse);
94  
95              return;
96          }
97  
98          try {
99              mergeTemplate(
100                 _resourceTemplateId, resourceRequest, resourceResponse);
101         }
102         catch (Exception e) {
103             throw new PortletException(e);
104         }
105     }
106 
107     public void doEdit(
108             RenderRequest renderRequest, RenderResponse renderResponse)
109         throws IOException, PortletException {
110 
111         if (renderRequest.getPreferences() == null) {
112             super.doEdit(renderRequest, renderResponse);
113 
114             return;
115         }
116 
117         try {
118             mergeTemplate(_editTemplateId, renderRequest, renderResponse);
119         }
120         catch (Exception e) {
121             throw new PortletException(e);
122         }
123     }
124 
125     public void doHelp(
126             RenderRequest renderRequest, RenderResponse renderResponse)
127         throws PortletException {
128 
129         try {
130             mergeTemplate(_helpTemplateId, renderRequest, renderResponse);
131         }
132         catch (Exception e) {
133             throw new PortletException(e);
134         }
135     }
136 
137     public void doView(
138             RenderRequest renderRequest, RenderResponse renderResponse)
139         throws PortletException {
140 
141         try {
142             mergeTemplate(_viewTemplateId, renderRequest, renderResponse);
143         }
144         catch (Exception e) {
145             throw new PortletException(e);
146         }
147     }
148 
149     protected VelocityContext getVelocityContext(
150         PortletRequest portletRequest, PortletResponse portletResponse) {
151 
152         VelocityContext velocityContext =
153             VelocityEngineUtil.getWrappedStandardToolsContext();
154 
155         velocityContext.put("portletConfig", getPortletConfig());
156         velocityContext.put("portletContext", getPortletContext());
157         velocityContext.put("preferences", portletRequest.getPreferences());
158         velocityContext.put(
159             "userInfo", portletRequest.getAttribute(PortletRequest.USER_INFO));
160 
161         velocityContext.put("portletRequest", portletRequest);
162 
163         if (portletRequest instanceof ActionRequest) {
164             velocityContext.put("actionRequest", portletRequest);
165         }
166         else if (portletRequest instanceof RenderRequest) {
167             velocityContext.put("renderRequest", portletRequest);
168         }
169         else {
170             velocityContext.put("resourceRequest", portletRequest);
171         }
172 
173         velocityContext.put("portletResponse", portletResponse);
174 
175         if (portletResponse instanceof ActionResponse) {
176             velocityContext.put("actionResponse", portletResponse);
177         }
178         else if (portletRequest instanceof RenderResponse) {
179             velocityContext.put("renderResponse", portletResponse);
180         }
181         else {
182             velocityContext.put("resourceResponse", portletResponse);
183         }
184 
185         return velocityContext;
186     }
187 
188     protected String getVelocityTemplateId(String name) {
189         if (Validator.isNull(name)) {
190             return name;
191         }
192 
193         StringBundler sb = new StringBundler(4);
194 
195         sb.append(_portletContextName);
196         sb.append(VelocityResourceListener.SERVLET_SEPARATOR);
197         sb.append(StrutsUtil.TEXT_HTML_DIR);
198         sb.append(name);
199 
200         return sb.toString();
201     }
202 
203     protected void mergeTemplate(
204             String velocityTemplateId, PortletRequest portletRequest,
205             PortletResponse portletResponse)
206         throws Exception {
207 
208         mergeTemplate(
209             velocityTemplateId,
210             getVelocityContext(portletRequest, portletResponse),
211             portletRequest, portletResponse);
212     }
213 
214     protected void mergeTemplate(
215             String velocityTemplateId, VelocityContext velocityContext,
216             PortletRequest portletRequest, PortletResponse portletResponse)
217         throws Exception {
218 
219         if (portletResponse instanceof MimeResponse) {
220             MimeResponse mimeResponse = (MimeResponse)portletResponse;
221 
222             mimeResponse.setContentType(
223                 portletRequest.getResponseContentType());
224         }
225 
226         VelocityWriter velocityWriter = null;
227 
228         try {
229             velocityWriter = (VelocityWriter)_writerPool.get();
230 
231             PrintWriter output = null;
232 
233             if (portletResponse instanceof MimeResponse) {
234                 MimeResponse mimeResponse = (MimeResponse)portletResponse;
235 
236                 output = mimeResponse.getWriter();
237             }
238             else {
239                 output = new PrintWriter(System.out);
240             }
241 
242             if (velocityWriter == null) {
243                 velocityWriter = new VelocityWriter(output, 4 * 1024, true);
244             }
245             else {
246                 velocityWriter.recycle(output);
247             }
248 
249             VelocityEngineUtil.mergeTemplate(
250                 velocityTemplateId, null, velocityContext, velocityWriter);
251         }
252         finally {
253             try {
254                 if (velocityWriter != null) {
255                     velocityWriter.flush();
256                     velocityWriter.recycle(null);
257 
258                     _writerPool.put(velocityWriter);
259                 }
260             }
261             catch (Exception e) {
262             }
263         }
264     }
265 
266     private static SimplePool _writerPool = new SimplePool(40);
267 
268     private String _portletContextName;
269     private String _actionTemplateId;
270     private String _editTemplateId;
271     private String _helpTemplateId;
272     private String _resourceTemplateId;
273     private String _viewTemplateId;
274 
275 }