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