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