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.util.bridges.mvc;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.portlet.LiferayPortlet;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.kernel.util.WebKeys;
025    import com.liferay.portal.util.PortalUtil;
026    
027    import java.io.IOException;
028    
029    import java.util.List;
030    
031    import javax.portlet.ActionRequest;
032    import javax.portlet.ActionResponse;
033    import javax.portlet.EventRequest;
034    import javax.portlet.EventResponse;
035    import javax.portlet.PortletConfig;
036    import javax.portlet.PortletContext;
037    import javax.portlet.PortletException;
038    import javax.portlet.PortletPreferences;
039    import javax.portlet.PortletRequest;
040    import javax.portlet.PortletRequestDispatcher;
041    import javax.portlet.PortletResponse;
042    import javax.portlet.RenderRequest;
043    import javax.portlet.RenderResponse;
044    import javax.portlet.ResourceRequest;
045    import javax.portlet.ResourceResponse;
046    import javax.portlet.WindowState;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Raymond Aug??
051     */
052    public class MVCPortlet extends LiferayPortlet {
053    
054            @Override
055            public void doAbout(
056                            RenderRequest renderRequest, RenderResponse renderResponse)
057                    throws IOException, PortletException {
058    
059                    include(aboutTemplate, renderRequest, renderResponse);
060            }
061    
062            @Override
063            public void doConfig(
064                            RenderRequest renderRequest, RenderResponse renderResponse)
065                    throws IOException, PortletException {
066    
067                    include(configTemplate, renderRequest, renderResponse);
068            }
069    
070            @Override
071            public void doEdit(
072                            RenderRequest renderRequest, RenderResponse renderResponse)
073                    throws IOException, PortletException {
074    
075                    PortletPreferences portletPreferences = renderRequest.getPreferences();
076    
077                    if (portletPreferences == null) {
078                            super.doEdit(renderRequest, renderResponse);
079                    }
080                    else {
081                            include(editTemplate, renderRequest, renderResponse);
082                    }
083            }
084    
085            @Override
086            public void doEditDefaults(
087                            RenderRequest renderRequest, RenderResponse renderResponse)
088                    throws IOException, PortletException {
089    
090                    PortletPreferences portletPreferences = renderRequest.getPreferences();
091    
092                    if (portletPreferences == null) {
093                            super.doEdit(renderRequest, renderResponse);
094                    }
095                    else {
096                            include(editDefaultsTemplate, renderRequest, renderResponse);
097                    }
098            }
099    
100            @Override
101            public void doEditGuest(
102                            RenderRequest renderRequest, RenderResponse renderResponse)
103                    throws IOException, PortletException {
104    
105                    PortletPreferences portletPreferences = renderRequest.getPreferences();
106    
107                    if (portletPreferences == null) {
108                            super.doEdit(renderRequest, renderResponse);
109                    }
110                    else {
111                            include(editGuestTemplate, renderRequest, renderResponse);
112                    }
113            }
114    
115            @Override
116            public void doHelp(
117                            RenderRequest renderRequest, RenderResponse renderResponse)
118                    throws IOException, PortletException {
119    
120                    include(helpTemplate, renderRequest, renderResponse);
121            }
122    
123            @Override
124            public void doPreview(
125                            RenderRequest renderRequest, RenderResponse renderResponse)
126                    throws IOException, PortletException {
127    
128                    include(previewTemplate, renderRequest, renderResponse);
129            }
130    
131            @Override
132            public void doPrint(
133                            RenderRequest renderRequest, RenderResponse renderResponse)
134                    throws IOException, PortletException {
135    
136                    include(printTemplate, renderRequest, renderResponse);
137            }
138    
139            @Override
140            public void doView(
141                            RenderRequest renderRequest, RenderResponse renderResponse)
142                    throws IOException, PortletException {
143    
144                    include(viewTemplate, renderRequest, renderResponse);
145            }
146    
147            @Override
148            public void init() throws PortletException {
149                    super.init();
150    
151                    templatePath = _getInitParameter("template-path");
152    
153                    if (Validator.isNull(templatePath)) {
154                            templatePath = StringPool.SLASH;
155                    }
156                    else if (templatePath.contains(StringPool.BACK_SLASH) ||
157                                     templatePath.contains(StringPool.DOUBLE_SLASH) ||
158                                     templatePath.contains(StringPool.PERIOD) ||
159                                     templatePath.contains(StringPool.SPACE)) {
160    
161                            throw new PortletException(
162                                    "template-path " + templatePath + " has invalid characters");
163                    }
164                    else if (!templatePath.startsWith(StringPool.SLASH) ||
165                                     !templatePath.endsWith(StringPool.SLASH)) {
166    
167                            throw new PortletException(
168                                    "template-path " + templatePath +
169                                            " must start and end with a /");
170                    }
171    
172                    aboutTemplate = _getInitParameter("about-template");
173                    configTemplate = _getInitParameter("config-template");
174                    editTemplate = _getInitParameter("edit-template");
175                    editDefaultsTemplate = _getInitParameter("edit-defaults-template");
176                    editGuestTemplate = _getInitParameter("edit-guest-template");
177                    helpTemplate = _getInitParameter("help-template");
178                    previewTemplate = _getInitParameter("preview-template");
179                    printTemplate = _getInitParameter("print-template");
180                    viewTemplate = _getInitParameter("view-template");
181    
182                    clearRequestParameters = GetterUtil.getBoolean(
183                            getInitParameter("clear-request-parameters"));
184                    copyRequestParameters = GetterUtil.getBoolean(
185                            getInitParameter("copy-request-parameters"));
186    
187                    String packagePrefix = getInitParameter(
188                            ActionCommandCache.ACTION_PACKAGE_NAME);
189    
190                    if (Validator.isNotNull(packagePrefix)) {
191                            _actionCommandCache = new ActionCommandCache(packagePrefix);
192                    }
193    
194                    initValidPaths(templatePath, ".jsp");
195            }
196    
197            public void invokeTaglibDiscussion(
198                            ActionRequest actionRequest, ActionResponse actionResponse)
199                    throws Exception {
200    
201                    PortletConfig portletConfig = getPortletConfig();
202    
203                    PortalUtil.invokeTaglibDiscussion(
204                            portletConfig, actionRequest, actionResponse);
205            }
206    
207            @Override
208            public void processAction(
209                            ActionRequest actionRequest, ActionResponse actionResponse)
210                    throws IOException, PortletException {
211    
212                    super.processAction(actionRequest, actionResponse);
213    
214                    if (copyRequestParameters) {
215                            PortalUtil.copyRequestParameters(actionRequest, actionResponse);
216                    }
217            }
218    
219            @Override
220            public void serveResource(
221                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
222                    throws IOException, PortletException {
223    
224                    String path = getPath(resourceRequest);
225    
226                    if (path != null) {
227                            include(
228                                    path, resourceRequest, resourceResponse,
229                                    PortletRequest.RESOURCE_PHASE);
230                    }
231                    else {
232                            super.serveResource(resourceRequest, resourceResponse);
233                    }
234            }
235    
236            @Override
237            protected boolean callActionMethod(
238                            ActionRequest actionRequest, ActionResponse actionResponse)
239                    throws PortletException {
240    
241                    try {
242                            checkPermissions(actionRequest);
243                    }
244                    catch (Exception e) {
245                            throw new PortletException(e);
246                    }
247    
248                    if (_actionCommandCache == null) {
249                            return super.callActionMethod(actionRequest, actionResponse);
250                    }
251    
252                    String actionName = ParamUtil.getString(
253                            actionRequest, ActionRequest.ACTION_NAME);
254    
255                    if (!actionName.contains(StringPool.COMMA)) {
256                            ActionCommand actionCommand = _actionCommandCache.getActionCommand(
257                                    actionName);
258    
259                            if (actionCommand != ActionCommandCache.EMPTY) {
260                                    return actionCommand.processCommand(
261                                            actionRequest, actionResponse);
262                            }
263                    }
264                    else {
265                            List<ActionCommand> actionCommands =
266                                    _actionCommandCache.getActionCommandChain(actionName);
267    
268                            if (actionCommands.isEmpty()) {
269                                    return false;
270                            }
271    
272                            for (ActionCommand actionCommand : actionCommands) {
273                                    if (!actionCommand.processCommand(
274                                                    actionRequest, actionResponse)) {
275    
276                                            return false;
277                                    }
278                            }
279    
280                            return true;
281                    }
282    
283                    return false;
284            }
285    
286            protected void checkPermissions(PortletRequest portletRequest)
287                    throws Exception {
288            }
289    
290            @Override
291            protected void doDispatch(
292                            RenderRequest renderRequest, RenderResponse renderResponse)
293                    throws IOException, PortletException {
294    
295                    String path = getPath(renderRequest);
296    
297                    if (path != null) {
298                            if (!isProcessRenderRequest(renderRequest)) {
299                                    renderRequest.setAttribute(
300                                            WebKeys.PORTLET_DECORATE, Boolean.FALSE);
301    
302                                    return;
303                            }
304    
305                            WindowState windowState = renderRequest.getWindowState();
306    
307                            if (windowState.equals(WindowState.MINIMIZED)) {
308                                    return;
309                            }
310    
311                            include(path, renderRequest, renderResponse);
312                    }
313                    else {
314                            super.doDispatch(renderRequest, renderResponse);
315                    }
316            }
317    
318            protected String getPath(PortletRequest portletRequest) {
319                    String mvcPath = portletRequest.getParameter("mvcPath");
320    
321                    // Check deprecated parameter
322    
323                    if (mvcPath == null) {
324                            mvcPath = portletRequest.getParameter("jspPage");
325                    }
326    
327                    return mvcPath;
328            }
329    
330            protected void include(
331                            String path, ActionRequest actionRequest,
332                            ActionResponse actionResponse)
333                    throws IOException, PortletException {
334    
335                    include(
336                            path, actionRequest, actionResponse, PortletRequest.ACTION_PHASE);
337            }
338    
339            protected void include(
340                            String path, EventRequest eventRequest, EventResponse eventResponse)
341                    throws IOException, PortletException {
342    
343                    include(path, eventRequest, eventResponse, PortletRequest.EVENT_PHASE);
344            }
345    
346            protected void include(
347                            String path, PortletRequest portletRequest,
348                            PortletResponse portletResponse, String lifecycle)
349                    throws IOException, PortletException {
350    
351                    PortletContext portletContext = getPortletContext();
352    
353                    PortletRequestDispatcher portletRequestDispatcher =
354                            portletContext.getRequestDispatcher(path);
355    
356                    if (portletRequestDispatcher == null) {
357                            _log.error(path + " is not a valid include");
358                    }
359                    else {
360                            checkPath(path);
361    
362                            portletRequestDispatcher.include(portletRequest, portletResponse);
363                    }
364    
365                    if (clearRequestParameters) {
366                            if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
367                                    portletResponse.setProperty(
368                                            "clear-request-parameters", Boolean.TRUE.toString());
369                            }
370                    }
371            }
372    
373            protected void include(
374                            String path, RenderRequest renderRequest,
375                            RenderResponse renderResponse)
376                    throws IOException, PortletException {
377    
378                    include(
379                            path, renderRequest, renderResponse, PortletRequest.RENDER_PHASE);
380            }
381    
382            protected void include(
383                            String path, ResourceRequest resourceRequest,
384                            ResourceResponse resourceResponse)
385                    throws IOException, PortletException {
386    
387                    include(
388                            path, resourceRequest, resourceResponse,
389                            PortletRequest.RESOURCE_PHASE);
390            }
391    
392            protected String aboutTemplate;
393            protected boolean clearRequestParameters;
394            protected String configTemplate;
395            protected boolean copyRequestParameters;
396            protected String editDefaultsTemplate;
397            protected String editGuestTemplate;
398            protected String editTemplate;
399            protected String helpTemplate;
400            protected String previewTemplate;
401            protected String printTemplate;
402            protected String templatePath;
403            protected String viewTemplate;
404    
405            private String _getInitParameter(String name) {
406                    String value = getInitParameter(name);
407    
408                    if (value != null) {
409                            return value;
410                    }
411    
412                    // Check deprecated parameter
413    
414                    if (name.equals("template-path")) {
415                            return getInitParameter("jsp-path");
416                    }
417                    else if (name.endsWith("-template")) {
418                            name = name.substring(0, name.length() - 9) + "-jsp";
419    
420                            return getInitParameter(name);
421                    }
422    
423                    return null;
424            }
425    
426            private static Log _log = LogFactoryUtil.getLog(MVCPortlet.class);
427    
428            private ActionCommandCache _actionCommandCache;
429    
430    }