001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet;
016    
017    import com.liferay.portal.kernel.template.Template;
018    import com.liferay.portal.kernel.template.TemplateConstants;
019    import com.liferay.portal.kernel.template.TemplateManagerUtil;
020    import com.liferay.portal.kernel.template.TemplateResource;
021    import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.struts.StrutsUtil;
026    
027    import java.io.IOException;
028    import java.io.PrintWriter;
029    
030    import javax.portlet.ActionRequest;
031    import javax.portlet.ActionResponse;
032    import javax.portlet.GenericPortlet;
033    import javax.portlet.MimeResponse;
034    import javax.portlet.PortletConfig;
035    import javax.portlet.PortletContext;
036    import javax.portlet.PortletException;
037    import javax.portlet.PortletRequest;
038    import javax.portlet.PortletResponse;
039    import javax.portlet.RenderRequest;
040    import javax.portlet.RenderResponse;
041    import javax.portlet.ResourceRequest;
042    import javax.portlet.ResourceResponse;
043    
044    import org.apache.velocity.io.VelocityWriter;
045    import org.apache.velocity.util.SimplePool;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Steven P. Goldsmith
050     * @author Raymond Aug??
051     */
052    public class VelocityPortlet extends GenericPortlet {
053    
054            @Override
055            public void doEdit(
056                            RenderRequest renderRequest, RenderResponse renderResponse)
057                    throws IOException, PortletException {
058    
059                    if (renderRequest.getPreferences() == null) {
060                            super.doEdit(renderRequest, renderResponse);
061    
062                            return;
063                    }
064    
065                    try {
066                            mergeTemplate(_editTemplateId, renderRequest, renderResponse);
067                    }
068                    catch (Exception e) {
069                            throw new PortletException(e);
070                    }
071            }
072    
073            @Override
074            public void doHelp(
075                            RenderRequest renderRequest, RenderResponse renderResponse)
076                    throws PortletException {
077    
078                    try {
079                            mergeTemplate(_helpTemplateId, renderRequest, renderResponse);
080                    }
081                    catch (Exception e) {
082                            throw new PortletException(e);
083                    }
084            }
085    
086            @Override
087            public void doView(
088                            RenderRequest renderRequest, RenderResponse renderResponse)
089                    throws PortletException {
090    
091                    try {
092                            mergeTemplate(_viewTemplateId, renderRequest, renderResponse);
093                    }
094                    catch (Exception e) {
095                            throw new PortletException(e);
096                    }
097            }
098    
099            @Override
100            public void init(PortletConfig portletConfig) throws PortletException {
101                    super.init(portletConfig);
102    
103                    PortletContext portletContext = portletConfig.getPortletContext();
104    
105                    _portletContextName = portletContext.getPortletContextName();
106    
107                    _actionTemplateId = getTemplateId(getInitParameter("action-template"));
108                    _editTemplateId = getTemplateId(getInitParameter("edit-template"));
109                    _helpTemplateId = getTemplateId(getInitParameter("help-template"));
110                    _resourceTemplateId = getTemplateId(
111                            getInitParameter("resource-template"));
112                    _viewTemplateId = getTemplateId(getInitParameter("view-template"));
113            }
114    
115            @Override
116            public void processAction(
117                            ActionRequest actionRequest, ActionResponse actionResponse)
118                    throws PortletException {
119    
120                    if (Validator.isNull(_actionTemplateId)) {
121                            return;
122                    }
123    
124                    try {
125                            mergeTemplate(_actionTemplateId, actionRequest, actionResponse);
126                    }
127                    catch (Exception e) {
128                            throw new PortletException(e);
129                    }
130            }
131    
132            @Override
133            public void serveResource(
134                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
135                    throws IOException, PortletException {
136    
137                    if (Validator.isNull(_resourceTemplateId)) {
138                            super.serveResource(resourceRequest, resourceResponse);
139    
140                            return;
141                    }
142    
143                    try {
144                            mergeTemplate(
145                                    _resourceTemplateId, resourceRequest, resourceResponse);
146                    }
147                    catch (Exception e) {
148                            throw new PortletException(e);
149                    }
150            }
151    
152            protected String getTemplateId(String name) {
153                    if (Validator.isNull(name)) {
154                            return name;
155                    }
156    
157                    StringBundler sb = new StringBundler(4);
158    
159                    sb.append(_portletContextName);
160                    sb.append(TemplateConstants.SERVLET_SEPARATOR);
161                    sb.append(StrutsUtil.TEXT_HTML_DIR);
162                    sb.append(name);
163    
164                    return sb.toString();
165            }
166    
167            protected void mergeTemplate(
168                            String templateId, PortletRequest portletRequest,
169                            PortletResponse portletResponse)
170                    throws Exception {
171    
172                    TemplateResource templateResource =
173                            TemplateResourceLoaderUtil.getTemplateResource(
174                                    TemplateConstants.LANG_TYPE_VM, templateId);
175    
176                    if (templateResource == null) {
177                            throw new Exception(
178                                    "Unable to load template resource " + templateId);
179                    }
180    
181                    Template template = TemplateManagerUtil.getTemplate(
182                            TemplateConstants.LANG_TYPE_VM, templateResource, false);
183    
184                    prepareTemplate(template, portletRequest, portletResponse);
185    
186                    mergeTemplate(templateId, template, portletRequest, portletResponse);
187            }
188    
189            protected void mergeTemplate(
190                            String templateId, Template template, PortletRequest portletRequest,
191                            PortletResponse portletResponse)
192                    throws Exception {
193    
194                    if (portletResponse instanceof MimeResponse) {
195                            MimeResponse mimeResponse = (MimeResponse)portletResponse;
196    
197                            mimeResponse.setContentType(
198                                    portletRequest.getResponseContentType());
199                    }
200    
201                    VelocityWriter velocityWriter = null;
202    
203                    try {
204                            velocityWriter = (VelocityWriter)_writerPool.get();
205    
206                            PrintWriter output = null;
207    
208                            if (portletResponse instanceof MimeResponse) {
209                                    MimeResponse mimeResponse = (MimeResponse)portletResponse;
210    
211                                    output = mimeResponse.getWriter();
212                            }
213                            else {
214                                    output = UnsyncPrintWriterPool.borrow(System.out);
215                            }
216    
217                            if (velocityWriter == null) {
218                                    velocityWriter = new VelocityWriter(output, 4 * 1024, true);
219                            }
220                            else {
221                                    velocityWriter.recycle(output);
222                            }
223    
224                            template.processTemplate(velocityWriter);
225                    }
226                    finally {
227                            try {
228                                    if (velocityWriter != null) {
229                                            velocityWriter.flush();
230                                            velocityWriter.recycle(null);
231    
232                                            _writerPool.put(velocityWriter);
233                                    }
234                            }
235                            catch (Exception e) {
236                            }
237                    }
238            }
239    
240            protected void prepareTemplate(
241                    Template template, PortletRequest portletRequest,
242                    PortletResponse portletResponse) {
243    
244                    template.put("portletConfig", getPortletConfig());
245                    template.put("portletContext", getPortletContext());
246                    template.put("preferences", portletRequest.getPreferences());
247                    template.put(
248                            "userInfo", portletRequest.getAttribute(PortletRequest.USER_INFO));
249    
250                    template.put("portletRequest", portletRequest);
251    
252                    if (portletRequest instanceof ActionRequest) {
253                            template.put("actionRequest", portletRequest);
254                    }
255                    else if (portletRequest instanceof RenderRequest) {
256                            template.put("renderRequest", portletRequest);
257                    }
258                    else {
259                            template.put("resourceRequest", portletRequest);
260                    }
261    
262                    template.put("portletResponse", portletResponse);
263    
264                    if (portletResponse instanceof ActionResponse) {
265                            template.put("actionResponse", portletResponse);
266                    }
267                    else if (portletRequest instanceof RenderResponse) {
268                            template.put("renderResponse", portletResponse);
269                    }
270                    else {
271                            template.put("resourceResponse", portletResponse);
272                    }
273            }
274    
275            private static SimplePool _writerPool = new SimplePool(40);
276    
277            private String _actionTemplateId;
278            private String _editTemplateId;
279            private String _helpTemplateId;
280            private String _portletContextName;
281            private String _resourceTemplateId;
282            private String _viewTemplateId;
283    
284    }