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