001    /**
002     * Copyright (c) 2000-2012 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.portlet.LiferayPortlet;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.struts.PortletRequestProcessor;
022    import com.liferay.portal.struts.StrutsUtil;
023    import com.liferay.portal.util.PortalUtil;
024    import com.liferay.portal.util.WebKeys;
025    
026    import java.io.IOException;
027    
028    import java.util.Map;
029    
030    import javax.portlet.ActionRequest;
031    import javax.portlet.ActionResponse;
032    import javax.portlet.EventRequest;
033    import javax.portlet.EventResponse;
034    import javax.portlet.PortletConfig;
035    import javax.portlet.PortletContext;
036    import javax.portlet.PortletException;
037    import javax.portlet.RenderRequest;
038    import javax.portlet.RenderResponse;
039    import javax.portlet.ResourceRequest;
040    import javax.portlet.ResourceResponse;
041    
042    import javax.servlet.ServletException;
043    
044    /**
045     * @author Brian Wing Shun Chan
046     */
047    public class StrutsPortlet extends LiferayPortlet {
048    
049            @Override
050            public void doAbout(
051                            RenderRequest renderRequest, RenderResponse renderResponse)
052                    throws IOException, PortletException {
053    
054                    renderRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, aboutAction);
055    
056                    include(renderRequest, renderResponse);
057            }
058    
059            @Override
060            public void doConfig(
061                            RenderRequest renderRequest, RenderResponse renderResponse)
062                    throws IOException, PortletException {
063    
064                    renderRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, configAction);
065    
066                    include(renderRequest, renderResponse);
067            }
068    
069            @Override
070            public void doEdit(
071                            RenderRequest renderRequest, RenderResponse renderResponse)
072                    throws IOException, PortletException {
073    
074                    if (renderRequest.getPreferences() == null) {
075                            super.doEdit(renderRequest, renderResponse);
076                    }
077                    else {
078                            renderRequest.setAttribute(
079                                    WebKeys.PORTLET_STRUTS_ACTION, editAction);
080    
081                            include(renderRequest, renderResponse);
082                    }
083            }
084    
085            @Override
086            public void doEditDefaults(
087                            RenderRequest renderRequest, RenderResponse renderResponse)
088                    throws IOException, PortletException {
089    
090                    if (renderRequest.getPreferences() == null) {
091                            super.doEdit(renderRequest, renderResponse);
092                    }
093                    else {
094                            renderRequest.setAttribute(
095                                    WebKeys.PORTLET_STRUTS_ACTION, editDefaultsAction);
096    
097                            include(renderRequest, renderResponse);
098                    }
099            }
100    
101            @Override
102            public void doEditGuest(
103                            RenderRequest renderRequest, RenderResponse renderResponse)
104                    throws IOException, PortletException {
105    
106                    if (renderRequest.getPreferences() == null) {
107                            super.doEdit(renderRequest, renderResponse);
108                    }
109                    else {
110                            renderRequest.setAttribute(
111                                    WebKeys.PORTLET_STRUTS_ACTION, editGuestAction);
112    
113                            include(renderRequest, renderResponse);
114                    }
115            }
116    
117            @Override
118            public void doHelp(
119                            RenderRequest renderRequest, RenderResponse renderResponse)
120                    throws IOException, PortletException {
121    
122                    renderRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, helpAction);
123    
124                    include(renderRequest, renderResponse);
125            }
126    
127            @Override
128            public void doPreview(
129                            RenderRequest renderRequest, RenderResponse renderResponse)
130                    throws IOException, PortletException {
131    
132                    renderRequest.setAttribute(
133                            WebKeys.PORTLET_STRUTS_ACTION, previewAction);
134    
135                    include(renderRequest, renderResponse);
136            }
137    
138            @Override
139            public void doPrint(
140                            RenderRequest renderRequest, RenderResponse renderResponse)
141                    throws IOException, PortletException {
142    
143                    renderRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, printAction);
144    
145                    include(renderRequest, renderResponse);
146            }
147    
148            @Override
149            public void doView(
150                            RenderRequest renderRequest, RenderResponse renderResponse)
151                    throws IOException, PortletException {
152    
153                    renderRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, viewAction);
154    
155                    include(renderRequest, renderResponse);
156            }
157    
158            @Override
159            public void init(PortletConfig portletConfig) throws PortletException {
160                    super.init(portletConfig);
161    
162                    templatePath = getInitParameter("template-path");
163    
164                    if (Validator.isNull(templatePath)) {
165                            templatePath = StringPool.SLASH;
166                    }
167                    else if (templatePath.contains(StringPool.BACK_SLASH) ||
168                                     templatePath.contains(StringPool.DOUBLE_SLASH) ||
169                                     templatePath.contains(StringPool.PERIOD) ||
170                                     templatePath.contains(StringPool.SPACE)) {
171    
172                            throw new PortletException(
173                                    "template-path " + templatePath + " has invalid characters");
174                    }
175                    else if (!templatePath.startsWith(StringPool.SLASH) ||
176                                     !templatePath.endsWith(StringPool.SLASH)) {
177    
178                            throw new PortletException(
179                                    "template-path " + templatePath +
180                                            " must start and end with a /");
181                    }
182    
183                    aboutAction = getInitParameter("about-action");
184                    configAction = getInitParameter("config-action");
185                    editAction = getInitParameter("edit-action");
186                    editDefaultsAction = getInitParameter("edit-defaults-action");
187                    editGuestAction = getInitParameter("edit-guest-action");
188                    helpAction = getInitParameter("help-action");
189                    previewAction = getInitParameter("preview-action");
190                    printAction = getInitParameter("print-action");
191                    viewAction = getInitParameter("view-action");
192    
193                    copyRequestParameters = GetterUtil.getBoolean(
194                            getInitParameter("copy-request-parameters"), true);
195    
196                    _portletConfig = (PortletConfigImpl)portletConfig;
197            }
198    
199            @Override
200            public void processAction(
201                            ActionRequest actionRequest, ActionResponse actionResponse)
202                    throws IOException, PortletException {
203    
204                    String path = actionRequest.getParameter("struts_action");
205    
206                    if (Validator.isNotNull(path)) {
207    
208                            // Call processAction of com.liferay.portal.struts.PortletAction
209    
210                            try {
211                                    PortletRequestProcessor processor =
212                                            _getPortletRequestProcessor();
213    
214                                    processor.process(actionRequest, actionResponse, path);
215                            }
216                            catch (ServletException se) {
217                                    throw new PortletException(se);
218                            }
219                    }
220    
221                    if (copyRequestParameters) {
222                            PortalUtil.copyRequestParameters(actionRequest, actionResponse);
223                    }
224            }
225    
226            @Override
227            public void processEvent(EventRequest request, EventResponse response)
228                    throws IOException, PortletException {
229    
230                    request.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, viewAction);
231    
232                    // Call processEvent of com.liferay.portal.struts.PortletAction
233    
234                    try {
235                            PortletRequestProcessor processor = _getPortletRequestProcessor();
236    
237                            processor.process(request, response);
238                    }
239                    catch (ServletException se) {
240                            throw new PortletException(se);
241                    }
242            }
243    
244            @Override
245            public void serveResource(
246                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
247                    throws IOException, PortletException {
248    
249                    String resourceId = resourceRequest.getResourceID();
250    
251                    checkPath(resourceId);
252    
253                    resourceRequest.setAttribute(WebKeys.PORTLET_STRUTS_ACTION, viewAction);
254    
255                    // Call serveResource of com.liferay.portal.struts.PortletAction
256    
257                    try {
258                            PortletRequestProcessor processor = _getPortletRequestProcessor();
259    
260                            processor.process(resourceRequest, resourceResponse);
261                    }
262                    catch (ServletException se) {
263                            throw new PortletException(se);
264                    }
265            }
266    
267            protected void checkPath(String path) throws PortletException {
268                    if (Validator.isNotNull(path) &&
269                            (!path.startsWith(templatePath) ||
270                             !PortalUtil.isValidResourceId(path) ||
271                             !Validator.isFilePath(path, false))) {
272    
273                            throw new PortletException(
274                                    "Path " + path + " is not accessible by this portlet");
275                    }
276            }
277    
278            protected void include(
279                            RenderRequest renderRequest, RenderResponse renderResponse)
280                    throws IOException, PortletException {
281    
282                    // Call render of com.liferay.portal.struts.PortletAction
283    
284                    Map<String, Object> strutsAttributes = null;
285    
286                    if (_portletConfig.isWARFile()) {
287                            strutsAttributes = StrutsUtil.removeStrutsAttributes(
288                                    getPortletContext(), renderRequest);
289                    }
290    
291                    try {
292                            PortletRequestProcessor processor = _getPortletRequestProcessor();
293    
294                            processor.process(renderRequest, renderResponse);
295                    }
296                    catch (ServletException se) {
297                            throw new PortletException(se);
298                    }
299                    finally {
300                            if (_portletConfig.isWARFile()) {
301                                    StrutsUtil.setStrutsAttributes(renderRequest, strutsAttributes);
302                            }
303                    }
304    
305                    if (copyRequestParameters) {
306                            PortalUtil.clearRequestParameters(renderRequest);
307                    }
308            }
309    
310            protected String aboutAction;
311            protected String configAction;
312            protected boolean copyRequestParameters;
313            protected String editAction;
314            protected String editDefaultsAction;
315            protected String editGuestAction;
316            protected String helpAction;
317            protected String previewAction;
318            protected String printAction;
319            protected String templatePath;
320            protected String viewAction;
321    
322            private PortletRequestProcessor _getPortletRequestProcessor() {
323                    PortletContext portletContext = getPortletContext();
324    
325                    return (PortletRequestProcessor)portletContext.getAttribute(
326                            WebKeys.PORTLET_STRUTS_PROCESSOR);
327            }
328    
329            private PortletConfigImpl _portletConfig;
330    
331    }