001    /**
002     * Copyright (c) 2000-2010 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.io.unsync.UnsyncPrintWriter;
018    import com.liferay.portal.kernel.util.StringBundler;
019    import com.liferay.portal.kernel.util.Validator;
020    import com.liferay.portal.kernel.velocity.VelocityContext;
021    import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
022    import com.liferay.portal.struts.StrutsUtil;
023    import com.liferay.portal.util.PortalUtil;
024    import com.liferay.portal.velocity.VelocityResourceListener;
025    
026    import java.io.IOException;
027    import java.io.PrintWriter;
028    
029    import javax.portlet.ActionRequest;
030    import javax.portlet.ActionResponse;
031    import javax.portlet.GenericPortlet;
032    import javax.portlet.MimeResponse;
033    import javax.portlet.PortletConfig;
034    import javax.portlet.PortletContext;
035    import javax.portlet.PortletException;
036    import javax.portlet.PortletRequest;
037    import javax.portlet.PortletResponse;
038    import javax.portlet.RenderRequest;
039    import javax.portlet.RenderResponse;
040    import javax.portlet.ResourceRequest;
041    import javax.portlet.ResourceResponse;
042    
043    import org.apache.velocity.io.VelocityWriter;
044    import org.apache.velocity.util.SimplePool;
045    
046    /**
047     * @author Brian Wing Shun Chan
048     * @author Steven P. Goldsmith
049     * @author Raymond Augé
050     */
051    public class VelocityPortlet extends GenericPortlet {
052    
053            public void init(PortletConfig portletConfig) throws PortletException {
054                    super.init(portletConfig);
055    
056                    PortletContext portletContext = portletConfig.getPortletContext();
057    
058                    _portletContextName = portletContext.getPortletContextName();
059    
060                    _actionTemplateId = getVelocityTemplateId(
061                            getInitParameter("action-template"));
062                    _editTemplateId = getVelocityTemplateId(
063                            getInitParameter("edit-template"));
064                    _helpTemplateId = getVelocityTemplateId(
065                            getInitParameter("help-template"));
066                    _resourceTemplateId = getVelocityTemplateId(
067                            getInitParameter("resource-template"));
068                    _viewTemplateId = getVelocityTemplateId(
069                            getInitParameter("view-template"));
070            }
071    
072            public void processAction(
073                            ActionRequest actionRequest, ActionResponse actionResponse)
074                    throws PortletException {
075    
076                    if (Validator.isNull(_actionTemplateId)) {
077                            return;
078                    }
079    
080                    try {
081                            mergeTemplate(_actionTemplateId, actionRequest, actionResponse);
082                    }
083                    catch (Exception e) {
084                            throw new PortletException(e);
085                    }
086            }
087    
088            public void serveResource(
089                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
090                    throws PortletException, IOException {
091    
092                    if (Validator.isNull(_resourceTemplateId)) {
093                            String resourceId = resourceRequest.getResourceID();
094    
095                            if (!PortalUtil.isValidResourceId(resourceId)) {
096                                    return;
097                            }
098    
099                            super.serveResource(resourceRequest, resourceResponse);
100    
101                            return;
102                    }
103    
104                    try {
105                            mergeTemplate(
106                                    _resourceTemplateId, resourceRequest, resourceResponse);
107                    }
108                    catch (Exception e) {
109                            throw new PortletException(e);
110                    }
111            }
112    
113            public void doEdit(
114                            RenderRequest renderRequest, RenderResponse renderResponse)
115                    throws IOException, PortletException {
116    
117                    if (renderRequest.getPreferences() == null) {
118                            super.doEdit(renderRequest, renderResponse);
119    
120                            return;
121                    }
122    
123                    try {
124                            mergeTemplate(_editTemplateId, renderRequest, renderResponse);
125                    }
126                    catch (Exception e) {
127                            throw new PortletException(e);
128                    }
129            }
130    
131            public void doHelp(
132                            RenderRequest renderRequest, RenderResponse renderResponse)
133                    throws PortletException {
134    
135                    try {
136                            mergeTemplate(_helpTemplateId, renderRequest, renderResponse);
137                    }
138                    catch (Exception e) {
139                            throw new PortletException(e);
140                    }
141            }
142    
143            public void doView(
144                            RenderRequest renderRequest, RenderResponse renderResponse)
145                    throws PortletException {
146    
147                    try {
148                            mergeTemplate(_viewTemplateId, renderRequest, renderResponse);
149                    }
150                    catch (Exception e) {
151                            throw new PortletException(e);
152                    }
153            }
154    
155            protected VelocityContext getVelocityContext(
156                    PortletRequest portletRequest, PortletResponse portletResponse) {
157    
158                    VelocityContext velocityContext =
159                            VelocityEngineUtil.getWrappedStandardToolsContext();
160    
161                    velocityContext.put("portletConfig", getPortletConfig());
162                    velocityContext.put("portletContext", getPortletContext());
163                    velocityContext.put("preferences", portletRequest.getPreferences());
164                    velocityContext.put(
165                            "userInfo", portletRequest.getAttribute(PortletRequest.USER_INFO));
166    
167                    velocityContext.put("portletRequest", portletRequest);
168    
169                    if (portletRequest instanceof ActionRequest) {
170                            velocityContext.put("actionRequest", portletRequest);
171                    }
172                    else if (portletRequest instanceof RenderRequest) {
173                            velocityContext.put("renderRequest", portletRequest);
174                    }
175                    else {
176                            velocityContext.put("resourceRequest", portletRequest);
177                    }
178    
179                    velocityContext.put("portletResponse", portletResponse);
180    
181                    if (portletResponse instanceof ActionResponse) {
182                            velocityContext.put("actionResponse", portletResponse);
183                    }
184                    else if (portletRequest instanceof RenderResponse) {
185                            velocityContext.put("renderResponse", portletResponse);
186                    }
187                    else {
188                            velocityContext.put("resourceResponse", portletResponse);
189                    }
190    
191                    return velocityContext;
192            }
193    
194            protected String getVelocityTemplateId(String name) {
195                    if (Validator.isNull(name)) {
196                            return name;
197                    }
198    
199                    StringBundler sb = new StringBundler(4);
200    
201                    sb.append(_portletContextName);
202                    sb.append(VelocityResourceListener.SERVLET_SEPARATOR);
203                    sb.append(StrutsUtil.TEXT_HTML_DIR);
204                    sb.append(name);
205    
206                    return sb.toString();
207            }
208    
209            protected void mergeTemplate(
210                            String velocityTemplateId, PortletRequest portletRequest,
211                            PortletResponse portletResponse)
212                    throws Exception {
213    
214                    mergeTemplate(
215                            velocityTemplateId,
216                            getVelocityContext(portletRequest, portletResponse),
217                            portletRequest, portletResponse);
218            }
219    
220            protected void mergeTemplate(
221                            String velocityTemplateId, VelocityContext velocityContext,
222                            PortletRequest portletRequest, PortletResponse portletResponse)
223                    throws Exception {
224    
225                    if (portletResponse instanceof MimeResponse) {
226                            MimeResponse mimeResponse = (MimeResponse)portletResponse;
227    
228                            mimeResponse.setContentType(
229                                    portletRequest.getResponseContentType());
230                    }
231    
232                    VelocityWriter velocityWriter = null;
233    
234                    try {
235                            velocityWriter = (VelocityWriter)_writerPool.get();
236    
237                            PrintWriter output = null;
238    
239                            if (portletResponse instanceof MimeResponse) {
240                                    MimeResponse mimeResponse = (MimeResponse)portletResponse;
241    
242                                    output = mimeResponse.getWriter();
243                            }
244                            else {
245                                    output = new UnsyncPrintWriter(System.out);
246                            }
247    
248                            if (velocityWriter == null) {
249                                    velocityWriter = new VelocityWriter(output, 4 * 1024, true);
250                            }
251                            else {
252                                    velocityWriter.recycle(output);
253                            }
254    
255                            VelocityEngineUtil.mergeTemplate(
256                                    velocityTemplateId, null, velocityContext, velocityWriter);
257                    }
258                    finally {
259                            try {
260                                    if (velocityWriter != null) {
261                                            velocityWriter.flush();
262                                            velocityWriter.recycle(null);
263    
264                                            _writerPool.put(velocityWriter);
265                                    }
266                            }
267                            catch (Exception e) {
268                            }
269                    }
270            }
271    
272            private static SimplePool _writerPool = new SimplePool(40);
273    
274            private String _portletContextName;
275            private String _actionTemplateId;
276            private String _editTemplateId;
277            private String _helpTemplateId;
278            private String _resourceTemplateId;
279            private String _viewTemplateId;
280    
281    }