1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.kernel.language.LanguageUtil;
26 import com.liferay.portal.kernel.servlet.BrowserSniffer;
27 import com.liferay.portal.kernel.servlet.HttpHeaders;
28 import com.liferay.portal.kernel.servlet.StringServletResponse;
29 import com.liferay.portal.kernel.util.ContentTypes;
30 import com.liferay.portal.kernel.util.JavaConstants;
31 import com.liferay.portal.kernel.util.ParamUtil;
32 import com.liferay.portal.kernel.util.StringPool;
33 import com.liferay.portal.kernel.util.Validator;
34 import com.liferay.portal.model.Layout;
35 import com.liferay.portal.model.Portlet;
36 import com.liferay.portal.model.PortletPreferencesIds;
37 import com.liferay.portal.model.User;
38 import com.liferay.portal.model.impl.LayoutImpl;
39 import com.liferay.portal.service.PortletLocalServiceUtil;
40 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
41 import com.liferay.portal.struts.ActionConstants;
42 import com.liferay.portal.struts.StrutsUtil;
43 import com.liferay.portal.theme.ThemeDisplay;
44 import com.liferay.portal.util.PortalUtil;
45 import com.liferay.portal.util.PropsValues;
46 import com.liferay.portal.util.WebKeys;
47 import com.liferay.portlet.ActionRequestFactory;
48 import com.liferay.portlet.ActionRequestImpl;
49 import com.liferay.portlet.ActionResponseFactory;
50 import com.liferay.portlet.ActionResponseImpl;
51 import com.liferay.portlet.CachePortlet;
52 import com.liferay.portlet.PortletConfigFactory;
53 import com.liferay.portlet.PortletInstanceFactory;
54 import com.liferay.portlet.PortletPreferencesFactoryUtil;
55 import com.liferay.portlet.PortletURLImpl;
56 import com.liferay.portlet.RenderParametersPool;
57 import com.liferay.portlet.RenderRequestFactory;
58 import com.liferay.portlet.RenderRequestImpl;
59 import com.liferay.portlet.RenderResponseFactory;
60 import com.liferay.portlet.RenderResponseImpl;
61 import com.liferay.util.Http;
62 import com.liferay.util.servlet.ServletResponseUtil;
63 import com.liferay.util.servlet.UploadServletRequest;
64
65 import java.io.ByteArrayInputStream;
66 import java.io.InputStream;
67
68 import java.util.Iterator;
69 import java.util.Map;
70
71 import javax.portlet.PortletConfig;
72 import javax.portlet.PortletContext;
73 import javax.portlet.PortletMode;
74 import javax.portlet.PortletPreferences;
75 import javax.portlet.PortletURL;
76 import javax.portlet.WindowState;
77
78 import javax.servlet.RequestDispatcher;
79 import javax.servlet.ServletContext;
80 import javax.servlet.http.HttpServletRequest;
81 import javax.servlet.http.HttpServletResponse;
82 import javax.servlet.http.HttpSession;
83 import javax.servlet.jsp.PageContext;
84
85 import org.apache.commons.logging.Log;
86 import org.apache.commons.logging.LogFactory;
87 import org.apache.struts.action.Action;
88 import org.apache.struts.action.ActionForm;
89 import org.apache.struts.action.ActionForward;
90 import org.apache.struts.action.ActionMapping;
91
92
98 public class LayoutAction extends Action {
99
100 public ActionForward execute(
101 ActionMapping mapping, ActionForm form, HttpServletRequest req,
102 HttpServletResponse res)
103 throws Exception {
104
105 ThemeDisplay themeDisplay =
106 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
107
108 Layout layout = themeDisplay.getLayout();
109
110 Boolean layoutDefault = (Boolean)req.getAttribute(
111 WebKeys.LAYOUT_DEFAULT);
112
113 if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
114 Layout requestedLayout =
115 (Layout)req.getAttribute(WebKeys.REQUESTED_LAYOUT);
116
117 if (requestedLayout != null) {
118 String redirect =
119 themeDisplay.getURLSignIn() + "?redirect=" +
120 PortalUtil.getLayoutURL(requestedLayout, themeDisplay);
121
122 if (_log.isDebugEnabled()) {
123 _log.debug("Redirect requested layout to " + redirect);
124 }
125
126 res.sendRedirect(redirect);
127 }
128 else {
129 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
130
131 if (_log.isDebugEnabled()) {
132 _log.debug("Redirect default layout to " + redirect);
133 }
134
135 res.sendRedirect(redirect);
136 }
137
138 return null;
139 }
140
141 long plid = ParamUtil.getLong(req, "p_l_id");
142 boolean resetLayout = ParamUtil.getBoolean(
143 req, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
144 String action = ParamUtil.getString(req, "p_p_action");
145
146 if (plid > 0) {
147 try {
148 if (resetLayout) {
149 RenderParametersPool.clear(req, plid);
150 }
151
152 if (action.equals("1")) {
153 Portlet portlet = processActionRequest(req, res);
154
155 if (portlet != null) {
156 ActionResponseImpl actionResponseImpl =
157 (ActionResponseImpl)req.getAttribute(
158 JavaConstants.JAVAX_PORTLET_RESPONSE);
159
160 String redirectLocation =
161 actionResponseImpl.getRedirectLocation();
162
163 if (Validator.isNotNull(redirectLocation)) {
164 res.sendRedirect(redirectLocation);
165
166 return null;
167 }
168
169 if (portlet.isActionURLRedirect()) {
170 redirectActionURL(
171 req, res, actionResponseImpl, portlet);
172 }
173 }
174 }
175 else if (action.equals("0")) {
176 processRenderRequest(req, res);
177 }
178
179 if (layout != null) {
180
181
185 includeLayoutContent(req, res, themeDisplay, layout);
186
187 if (themeDisplay.isStateExclusive()) {
188 serverExclusiveResource(req, res, themeDisplay);
189
190 return null;
191 }
192 }
193
194 return mapping.findForward("portal.layout");
195 }
196 catch (Exception e) {
197 req.setAttribute(PageContext.EXCEPTION, e);
198
199 return mapping.findForward(ActionConstants.COMMON_ERROR);
200 }
201 finally {
202 try {
203 if (action.equals("1")) {
204 ActionRequestImpl actionRequestImpl =
205 (ActionRequestImpl)req.getAttribute(
206 JavaConstants.JAVAX_PORTLET_REQUEST);
207
208 ActionRequestFactory.recycle(actionRequestImpl);
209 }
210 }
211 catch (Exception e) {
212 _log.error(e);
213 }
214
215 req.removeAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);
216
217 try {
218 if (action.equals("1")) {
219 ActionResponseImpl actionResponseImpl =
220 (ActionResponseImpl)req.getAttribute(
221 JavaConstants.JAVAX_PORTLET_RESPONSE);
222
223 ActionResponseFactory.recycle(actionResponseImpl);
224 }
225 }
226 catch (Exception e) {
227 _log.error(e);
228 }
229
230 req.removeAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);
231 }
232 }
233 else {
234 try {
235 forwardLayout(req);
236
237 return mapping.findForward(ActionConstants.COMMON_FORWARD);
238 }
239 catch (Exception e) {
240 req.setAttribute(PageContext.EXCEPTION, e);
241
242 return mapping.findForward(ActionConstants.COMMON_ERROR);
243 }
244 }
245 }
246
247 protected void forwardLayout(HttpServletRequest req) throws Exception {
248 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
249 long plid = LayoutImpl.DEFAULT_PLID;
250 String layoutFriendlyURL = null;
251
252 ThemeDisplay themeDisplay =
253 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
254
255 if (layout != null) {
256 plid = layout.getPlid();
257 layoutFriendlyURL =
258 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay);
259 }
260
261 String forwardURL = layoutFriendlyURL;
262
263 if (Validator.isNull(forwardURL)) {
264 forwardURL =
265 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
266
267 if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
268 forwardURL = Http.addParameter(
269 forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
270 }
271 }
272
273 if (_log.isDebugEnabled()) {
274 _log.debug("Forward layout to " + forwardURL);
275 }
276
277 req.setAttribute(WebKeys.FORWARD_URL, forwardURL);
278 }
279
280 protected void includeLayoutContent(
281 HttpServletRequest req, HttpServletResponse res,
282 ThemeDisplay themeDisplay, Layout layout)
283 throws Exception {
284
285 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
286
287 String path = StrutsUtil.TEXT_HTML_DIR;
288
289 if (BrowserSniffer.is_wap_xhtml(req)) {
290 path = StrutsUtil.TEXT_WAP_DIR;
291 }
292
293
295 if (themeDisplay.isStateExclusive() ||
296 Validator.isNotNull(ParamUtil.getString(req, "p_p_id"))) {
297
298 path += "/portal/layout/view/portlet.jsp";
299 }
300 else {
301 path += PortalUtil.getLayoutViewPage(layout);
302 }
303
304 RequestDispatcher rd = ctx.getRequestDispatcher(path);
305
306 StringServletResponse stringServletRes = new StringServletResponse(res);
307
308 rd.include(req, stringServletRes);
309
310 req.setAttribute(WebKeys.LAYOUT_CONTENT, stringServletRes.getString());
311 }
312
313 protected Portlet processActionRequest(
314 HttpServletRequest req, HttpServletResponse res)
315 throws Exception {
316
317 return processPortletRequest(req, res, true);
318 }
319
320 protected Portlet processPortletRequest(
321 HttpServletRequest req, HttpServletResponse res, boolean action)
322 throws Exception {
323
324 HttpSession ses = req.getSession();
325
326 long companyId = PortalUtil.getCompanyId(req);
327 User user = PortalUtil.getUser(req);
328 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
329 String portletId = ParamUtil.getString(req, "p_p_id");
330
331 Portlet portlet = PortletLocalServiceUtil.getPortletById(
332 companyId, portletId);
333
334 if (portlet == null) {
335 return null;
336 }
337
338 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
339
340 CachePortlet cachePortlet = PortletInstanceFactory.create(portlet, ctx);
341
342 if (user != null) {
343 CachePortlet.clearResponse(
344 ses, layout.getPrimaryKey(), portletId,
345 LanguageUtil.getLanguageId(req));
346 }
347
348 PortletPreferencesIds portletPreferencesIds =
349 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
350 req, portletId);
351
352 PortletPreferences portletPreferences =
353 PortletPreferencesLocalServiceUtil.getPreferences(
354 portletPreferencesIds);
355
356 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
357 PortletContext portletCtx = portletConfig.getPortletContext();
358
359 WindowState windowState = new WindowState(
360 ParamUtil.getString(req, "p_p_state"));
361
362 PortletMode portletMode = new PortletMode(
363 ParamUtil.getString(req, "p_p_mode"));
364
365 if (action) {
366 String contentType = req.getHeader(HttpHeaders.CONTENT_TYPE);
367
368 if (_log.isDebugEnabled()) {
369 _log.debug("Content type " + contentType);
370 }
371
372 UploadServletRequest uploadReq = null;
373
374 try {
375 if ((contentType != null) &&
376 (contentType.startsWith(
377 ContentTypes.MULTIPART_FORM_DATA))) {
378
379 if (!cachePortlet.getPortletConfig().isWARFile() ||
380 cachePortlet.isStrutsPortlet()) {
381
382 uploadReq = new UploadServletRequest(req);
383
384 req = uploadReq;
385 }
386 }
387
388 ActionRequestImpl actionRequestImpl =
389 ActionRequestFactory.create(
390 req, portlet, cachePortlet, portletCtx, windowState,
391 portletMode, portletPreferences, layout.getPlid());
392
393 ActionResponseImpl actionResponseImpl =
394 ActionResponseFactory.create(
395 actionRequestImpl, res, portletId, user, layout,
396 windowState, portletMode);
397
398 actionRequestImpl.defineObjects(
399 portletConfig, actionResponseImpl);
400
401 cachePortlet.processAction(
402 actionRequestImpl, actionResponseImpl);
403
404 RenderParametersPool.put(
405 req, layout.getPlid(), portletId,
406 actionResponseImpl.getRenderParameters());
407 }
408 finally {
409 if (uploadReq != null) {
410 uploadReq.cleanUp();
411 }
412 }
413 }
414 else {
415 PortalUtil.updateWindowState(
416 portletId, user, layout, windowState, req);
417
418 PortalUtil.updatePortletMode(
419 portletId, user, layout, portletMode, req);
420 }
421
422 return portlet;
423 }
424
425 protected Portlet processRenderRequest(
426 HttpServletRequest req, HttpServletResponse res)
427 throws Exception {
428
429 return processPortletRequest(req, res, false);
430 }
431
432 protected void redirectActionURL(
433 HttpServletRequest req, HttpServletResponse res,
434 ActionResponseImpl actionResponseImpl, Portlet portlet)
435 throws Exception {
436
437 ActionRequestImpl actionRequestImpl =
438 (ActionRequestImpl)req.getAttribute(
439 JavaConstants.JAVAX_PORTLET_REQUEST);
440
441 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
442
443 PortletURL portletURL = new PortletURLImpl(
444 actionRequestImpl, actionRequestImpl.getPortletName(),
445 layout.getLayoutId(), false);
446
447 Map renderParameters = actionResponseImpl.getRenderParameters();
448
449 Iterator itr = renderParameters.entrySet().iterator();
450
451 while (itr.hasNext()) {
452 Map.Entry entry = (Map.Entry)itr.next();
453
454 String key = (String)entry.getKey();
455 Object value = entry.getValue();
456
457 if (value instanceof String) {
458 portletURL.setParameter(key, (String)value);
459 }
460 else if (value instanceof String[]) {
461 portletURL.setParameter(key, (String[])value);
462 }
463 }
464
465 res.sendRedirect(portletURL.toString());
466 }
467
468 protected void serverExclusiveResource(
469 HttpServletRequest req, HttpServletResponse res,
470 ThemeDisplay themeDisplay)
471 throws Exception {
472
473 RenderRequestImpl renderRequestImpl = (RenderRequestImpl)
474 req.getAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);
475
476 RenderResponseImpl renderResponseImpl = (RenderResponseImpl)
477 req.getAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);
478
479 StringServletResponse stringServletResponse = (StringServletResponse)
480 renderRequestImpl.getAttribute(WebKeys.STRING_SERVLET_RESPONSE);
481
482 renderResponseImpl.transferHeaders(res);
483
484 if (stringServletResponse.isCalledGetOutputStream()) {
485 InputStream is = new ByteArrayInputStream(
486 stringServletResponse.getByteArrayMaker().toByteArray());
487
488 ServletResponseUtil.sendFile(
489 res, renderResponseImpl.getResourceName(), is,
490 renderResponseImpl.getContentType());
491 }
492 else {
493 byte[] content = stringServletResponse.getString().getBytes(
494 StringPool.UTF8);
495
496 ServletResponseUtil.sendFile(
497 res, renderResponseImpl.getResourceName(), content,
498 renderResponseImpl.getContentType());
499 }
500
501 RenderRequestFactory.recycle(renderRequestImpl);
502 RenderResponseFactory.recycle(renderResponseImpl);
503 }
504
505 private static Log _log = LogFactory.getLog(LayoutAction.class);
506
507 }