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.util.bridges.mvc;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.portlet.LiferayPortlet;
20  import com.liferay.portal.kernel.util.GetterUtil;
21  import com.liferay.portal.kernel.util.ParamUtil;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.Validator;
24  import com.liferay.portal.kernel.util.WebKeys;
25  import com.liferay.portal.util.PortalUtil;
26  
27  import java.io.IOException;
28  
29  import java.util.List;
30  
31  import javax.portlet.ActionRequest;
32  import javax.portlet.ActionResponse;
33  import javax.portlet.PortletException;
34  import javax.portlet.PortletRequest;
35  import javax.portlet.PortletRequestDispatcher;
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  import javax.portlet.WindowState;
42  
43  /**
44   * <a href="MVCPortlet.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   */
48  public class MVCPortlet extends LiferayPortlet {
49  
50      public void doAbout(
51              RenderRequest renderRequest, RenderResponse renderResponse)
52          throws IOException, PortletException {
53  
54          include(aboutJSP, renderRequest, renderResponse);
55      }
56  
57      public void doConfig(
58              RenderRequest renderRequest, RenderResponse renderResponse)
59          throws IOException, PortletException {
60  
61          include(configJSP, renderRequest, renderResponse);
62      }
63  
64      public void doEdit(
65              RenderRequest renderRequest, RenderResponse renderResponse)
66          throws IOException, PortletException {
67  
68          if (renderRequest.getPreferences() == null) {
69              super.doEdit(renderRequest, renderResponse);
70          }
71          else {
72              include(editJSP, renderRequest, renderResponse);
73          }
74      }
75  
76      public void doEditDefaults(
77              RenderRequest renderRequest, RenderResponse renderResponse)
78          throws IOException, PortletException {
79  
80          if (renderRequest.getPreferences() == null) {
81              super.doEdit(renderRequest, renderResponse);
82          }
83          else {
84              include(editDefaultsJSP, renderRequest, renderResponse);
85          }
86      }
87  
88      public void doEditGuest(
89              RenderRequest renderRequest, RenderResponse renderResponse)
90          throws IOException, PortletException {
91  
92          if (renderRequest.getPreferences() == null) {
93              super.doEdit(renderRequest, renderResponse);
94          }
95          else {
96              include(editGuestJSP, renderRequest, renderResponse);
97          }
98      }
99  
100     public void doHelp(
101             RenderRequest renderRequest, RenderResponse renderResponse)
102         throws IOException, PortletException {
103 
104         include(helpJSP, renderRequest, renderResponse);
105     }
106 
107     public void doPreview(
108             RenderRequest renderRequest, RenderResponse renderResponse)
109         throws IOException, PortletException {
110 
111         include(previewJSP, renderRequest, renderResponse);
112     }
113 
114     public void doPrint(
115             RenderRequest renderRequest, RenderResponse renderResponse)
116         throws IOException, PortletException {
117 
118         include(printJSP, renderRequest, renderResponse);
119     }
120 
121     public void doView(
122             RenderRequest renderRequest, RenderResponse renderResponse)
123         throws IOException, PortletException {
124 
125         include(viewJSP, renderRequest, renderResponse);
126     }
127 
128     public void init() throws PortletException {
129         super.init();
130 
131         jspPath = getInitParameter("jsp-path");
132 
133         if (Validator.isNull(jspPath)) {
134             jspPath = StringPool.SLASH;
135         }
136         else if (jspPath.contains(StringPool.BACK_SLASH) ||
137                  jspPath.contains(StringPool.DOUBLE_SLASH) ||
138                  jspPath.contains(StringPool.PERIOD) ||
139                  jspPath.contains(StringPool.SPACE)) {
140 
141             throw new PortletException(
142                 "jsp-path " + jspPath + " has invalid characters");
143         }
144         else if (!jspPath.startsWith(StringPool.SLASH) ||
145                  !jspPath.endsWith(StringPool.SLASH)) {
146 
147             throw new PortletException(
148                 "jsp-path " + jspPath + " must start and end with a /");
149         }
150 
151         aboutJSP = getInitParameter("about-jsp");
152         configJSP = getInitParameter("config-jsp");
153         editJSP = getInitParameter("edit-jsp");
154         editDefaultsJSP = getInitParameter("edit-defaults-jsp");
155         editGuestJSP = getInitParameter("edit-guest-jsp");
156         helpJSP = getInitParameter("help-jsp");
157         previewJSP = getInitParameter("preview-jsp");
158         printJSP = getInitParameter("print-jsp");
159         viewJSP = getInitParameter("view-jsp");
160 
161         clearRequestParameters = GetterUtil.getBoolean(
162             getInitParameter("clear-request-parameters"));
163         copyRequestParameters = GetterUtil.getBoolean(
164             getInitParameter("copy-request-parameters"));
165 
166         String packagePrefix = getInitParameter(
167             ActionCommandCache.ACTION_PACKAGE_NAME);
168 
169         if (Validator.isNotNull(packagePrefix)) {
170             _actionCommandCache = new ActionCommandCache(packagePrefix);
171         }
172     }
173 
174     public void processAction(
175             ActionRequest actionRequest, ActionResponse actionResponse)
176         throws IOException, PortletException {
177 
178         super.processAction(actionRequest, actionResponse);
179 
180         if (copyRequestParameters) {
181             PortalUtil.copyRequestParameters(actionRequest, actionResponse);
182         }
183     }
184 
185     public void serveResource(
186             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
187         throws IOException, PortletException {
188 
189         String jspPage = resourceRequest.getParameter("jspPage");
190 
191         if (jspPage != null) {
192             include(
193                 jspPage, resourceRequest, resourceResponse,
194                 PortletRequest.RESOURCE_PHASE);
195         }
196         else {
197             super.serveResource(resourceRequest, resourceResponse);
198         }
199     }
200 
201     protected boolean callActionMethod(
202             ActionRequest request, ActionResponse response)
203         throws PortletException {
204 
205         if ((_actionCommandCache == null) || _actionCommandCache.isEmpty()) {
206             return super.callActionMethod(request, response);
207         }
208 
209         String actionName = ParamUtil.getString(
210             request, ActionRequest.ACTION_NAME);
211 
212         if (!actionName.contains(StringPool.COMMA)) {
213             ActionCommand actionCommand = _actionCommandCache.getActionCommand(
214                 actionName);
215 
216             if (actionCommand != ActionCommandCache.EMPTY) {
217                 return actionCommand.processCommand(request, response);
218             }
219         }
220         else {
221             List<ActionCommand> actionCommands =
222                 _actionCommandCache.getActionCommandChain(actionName);
223 
224             if (actionCommands.isEmpty()) {
225                 return false;
226             }
227 
228             for (ActionCommand actionCommand : actionCommands) {
229                 if (!actionCommand.processCommand(request, response)) {
230                     return false;
231                 }
232             }
233 
234             return true;
235         }
236 
237         return false;
238     }
239 
240     protected void checkJSPPath(String path) throws PortletException {
241         if (!path.startsWith(jspPath) ||
242             path.contains(StringPool.DOUBLE_PERIOD)) {
243 
244             throw new PortletException(
245                 "Path " + path + " is not accessible by this portlet");
246         }
247     }
248 
249     protected void doDispatch(
250             RenderRequest renderRequest, RenderResponse renderResponse)
251         throws IOException, PortletException {
252 
253         String jspPage = renderRequest.getParameter("jspPage");
254 
255         if (jspPage != null) {
256             if (!isProcessRenderRequest(renderRequest)) {
257                 renderRequest.setAttribute(
258                     WebKeys.PORTLET_DECORATE, Boolean.FALSE);
259 
260                 return;
261             }
262 
263             WindowState windowState = renderRequest.getWindowState();
264 
265             if (windowState.equals(WindowState.MINIMIZED)) {
266                 return;
267             }
268 
269             include(jspPage, renderRequest, renderResponse);
270         }
271         else {
272             super.doDispatch(renderRequest, renderResponse);
273         }
274     }
275 
276     protected void include(
277             String path, PortletRequest portletRequest,
278             PortletResponse portletResponse)
279         throws IOException, PortletException {
280 
281         include(
282             path, portletRequest, portletResponse, PortletRequest.RENDER_PHASE);
283     }
284 
285     protected void include(
286             String path, PortletRequest portletRequest,
287             PortletResponse portletResponse, String lifecycle)
288         throws IOException, PortletException {
289 
290         PortletRequestDispatcher portletRequestDispatcher =
291             getPortletContext().getRequestDispatcher(path);
292 
293         if (portletRequestDispatcher == null) {
294             _log.error(path + " is not a valid include");
295         }
296         else {
297             checkJSPPath(path);
298 
299             portletRequestDispatcher.include(portletRequest, portletResponse);
300         }
301 
302         if (clearRequestParameters) {
303             if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
304                 portletResponse.setProperty("clear-request-parameters", "true");
305             }
306         }
307     }
308 
309     private static Log _log = LogFactoryUtil.getLog(MVCPortlet.class);
310 
311     protected ActionCommandCache _actionCommandCache;
312 
313     protected String aboutJSP;
314     protected boolean clearRequestParameters;
315     protected String configJSP;
316     protected boolean copyRequestParameters;
317     protected String editDefaultsJSP;
318     protected String editGuestJSP;
319     protected String editJSP;
320     protected String helpJSP;
321     protected String jspPath;
322     protected String previewJSP;
323     protected String printJSP;
324     protected String viewJSP;
325 
326 }