1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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.PortalClassInvoker;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.portal.kernel.util.WebKeys;
26  import com.liferay.portal.util.PortalUtil;
27  
28  import java.io.IOException;
29  
30  import java.util.List;
31  
32  import javax.portlet.ActionRequest;
33  import javax.portlet.ActionResponse;
34  import javax.portlet.EventRequest;
35  import javax.portlet.EventResponse;
36  import javax.portlet.PortletConfig;
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         PortletConfig portletConfig = getPortletConfig();
183 
184         PortalClassInvoker.invoke(
185             true,
186             "com.liferay.portlet.messageboards.action.EditDiscussionAction",
187             "processAction",
188             new String[] {
189                 "org.apache.struts.action.ActionMapping",
190                 "org.apache.struts.action.ActionForm",
191                 PortletConfig.class.getName(), ActionRequest.class.getName(),
192                 ActionResponse.class.getName()
193             },
194             null, null, portletConfig, actionRequest, actionResponse);
195     }
196 
197     public void processAction(
198             ActionRequest actionRequest, ActionResponse actionResponse)
199         throws IOException, PortletException {
200 
201         super.processAction(actionRequest, actionResponse);
202 
203         if (copyRequestParameters) {
204             PortalUtil.copyRequestParameters(actionRequest, actionResponse);
205         }
206     }
207 
208     public void serveResource(
209             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
210         throws IOException, PortletException {
211 
212         String jspPage = resourceRequest.getParameter("jspPage");
213 
214         if (jspPage != null) {
215             include(
216                 jspPage, resourceRequest, resourceResponse,
217                 PortletRequest.RESOURCE_PHASE);
218         }
219         else {
220             super.serveResource(resourceRequest, resourceResponse);
221         }
222     }
223 
224     protected boolean callActionMethod(
225             ActionRequest request, ActionResponse response)
226         throws PortletException {
227 
228         if (_actionCommandCache == null) {
229             return super.callActionMethod(request, response);
230         }
231 
232         String actionName = ParamUtil.getString(
233             request, ActionRequest.ACTION_NAME);
234 
235         if (!actionName.contains(StringPool.COMMA)) {
236             ActionCommand actionCommand = _actionCommandCache.getActionCommand(
237                 actionName);
238 
239             if (actionCommand != ActionCommandCache.EMPTY) {
240                 return actionCommand.processCommand(request, response);
241             }
242         }
243         else {
244             List<ActionCommand> actionCommands =
245                 _actionCommandCache.getActionCommandChain(actionName);
246 
247             if (actionCommands.isEmpty()) {
248                 return false;
249             }
250 
251             for (ActionCommand actionCommand : actionCommands) {
252                 if (!actionCommand.processCommand(request, response)) {
253                     return false;
254                 }
255             }
256 
257             return true;
258         }
259 
260         return false;
261     }
262 
263     protected void checkJSPPath(String path) throws PortletException {
264         if (!path.startsWith(jspPath) ||
265             path.contains(StringPool.DOUBLE_PERIOD) ||
266             !PortalUtil.isValidResourceId(path)) {
267 
268             throw new PortletException(
269                 "Path " + path + " is not accessible by this portlet");
270         }
271     }
272 
273     protected void doDispatch(
274             RenderRequest renderRequest, RenderResponse renderResponse)
275         throws IOException, PortletException {
276 
277         String jspPage = renderRequest.getParameter("jspPage");
278 
279         if (jspPage != null) {
280             if (!isProcessRenderRequest(renderRequest)) {
281                 renderRequest.setAttribute(
282                     WebKeys.PORTLET_DECORATE, Boolean.FALSE);
283 
284                 return;
285             }
286 
287             WindowState windowState = renderRequest.getWindowState();
288 
289             if (windowState.equals(WindowState.MINIMIZED)) {
290                 return;
291             }
292 
293             include(jspPage, renderRequest, renderResponse);
294         }
295         else {
296             super.doDispatch(renderRequest, renderResponse);
297         }
298     }
299 
300     protected void include(
301             String path, ActionRequest actionRequest,
302             ActionResponse actionResponse)
303         throws IOException, PortletException {
304 
305         include(
306             path, actionRequest, actionResponse, PortletRequest.ACTION_PHASE);
307     }
308 
309     protected void include(
310             String path, EventRequest eventRequest, EventResponse eventResponse)
311         throws IOException, PortletException {
312 
313         include(path, eventRequest, eventResponse, PortletRequest.EVENT_PHASE);
314     }
315 
316     protected void include(
317             String path, PortletRequest portletRequest,
318             PortletResponse portletResponse, String lifecycle)
319         throws IOException, PortletException {
320 
321         PortletRequestDispatcher portletRequestDispatcher =
322             getPortletContext().getRequestDispatcher(path);
323 
324         if (portletRequestDispatcher == null) {
325             _log.error(path + " is not a valid include");
326         }
327         else {
328             checkJSPPath(path);
329 
330             portletRequestDispatcher.include(portletRequest, portletResponse);
331         }
332 
333         if (clearRequestParameters) {
334             if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
335                 portletResponse.setProperty("clear-request-parameters", "true");
336             }
337         }
338     }
339 
340     protected void include(
341             String path, RenderRequest renderRequest,
342             RenderResponse renderResponse)
343         throws IOException, PortletException {
344 
345         include(
346             path, renderRequest, renderResponse, PortletRequest.RENDER_PHASE);
347     }
348 
349     protected void include(
350             String path, ResourceRequest resourceRequest,
351             ResourceResponse resourceResponse)
352         throws IOException, PortletException {
353 
354         include(
355             path, resourceRequest, resourceResponse,
356             PortletRequest.RESOURCE_PHASE);
357     }
358 
359     private static Log _log = LogFactoryUtil.getLog(MVCPortlet.class);
360 
361     protected ActionCommandCache _actionCommandCache;
362 
363     protected String aboutJSP;
364     protected boolean clearRequestParameters;
365     protected String configJSP;
366     protected boolean copyRequestParameters;
367     protected String editDefaultsJSP;
368     protected String editGuestJSP;
369     protected String editJSP;
370     protected String helpJSP;
371     protected String jspPath;
372     protected String previewJSP;
373     protected String printJSP;
374     protected String viewJSP;
375 
376 }