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.portal.action;
16  
17  import com.liferay.portal.kernel.json.JSONFactoryUtil;
18  import com.liferay.portal.kernel.json.JSONObject;
19  import com.liferay.portal.kernel.servlet.StringServletResponse;
20  import com.liferay.portal.kernel.util.Constants;
21  import com.liferay.portal.kernel.util.InstancePool;
22  import com.liferay.portal.kernel.util.ParamUtil;
23  import com.liferay.portal.kernel.util.StringBundler;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.portal.model.Layout;
26  import com.liferay.portal.model.LayoutTypePortlet;
27  import com.liferay.portal.model.Portlet;
28  import com.liferay.portal.model.PortletConstants;
29  import com.liferay.portal.model.ResourceConstants;
30  import com.liferay.portal.security.permission.ActionKeys;
31  import com.liferay.portal.security.permission.PermissionChecker;
32  import com.liferay.portal.service.LayoutServiceUtil;
33  import com.liferay.portal.service.PortletLocalServiceUtil;
34  import com.liferay.portal.service.ResourceLocalServiceUtil;
35  import com.liferay.portal.service.permission.LayoutPermissionUtil;
36  import com.liferay.portal.service.permission.PortletPermissionUtil;
37  import com.liferay.portal.servlet.NamespaceServletRequest;
38  import com.liferay.portal.struts.ActionConstants;
39  import com.liferay.portal.theme.ThemeDisplay;
40  import com.liferay.portal.util.LayoutClone;
41  import com.liferay.portal.util.LayoutCloneFactory;
42  import com.liferay.portal.util.PortalUtil;
43  import com.liferay.portal.util.WebKeys;
44  import com.liferay.portlet.PortletPreferencesFactoryUtil;
45  import com.liferay.util.servlet.DynamicServletRequest;
46  import com.liferay.util.servlet.ServletResponseUtil;
47  
48  import javax.portlet.PortletPreferences;
49  
50  import javax.servlet.http.HttpServletRequest;
51  import javax.servlet.http.HttpServletResponse;
52  
53  import org.apache.struts.action.Action;
54  import org.apache.struts.action.ActionForm;
55  import org.apache.struts.action.ActionForward;
56  import org.apache.struts.action.ActionMapping;
57  
58  /**
59   * <a href="UpdateLayoutAction.java.html"><b><i>View Source</i></b></a>
60   *
61   * @author Brian Wing Shun Chan
62   */
63  public class UpdateLayoutAction extends Action {
64  
65      public ActionForward execute(
66              ActionMapping mapping, ActionForm form, HttpServletRequest request,
67              HttpServletResponse response)
68          throws Exception {
69  
70          ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
71              WebKeys.THEME_DISPLAY);
72  
73          long userId = themeDisplay.getUserId();
74  
75          Layout layout = themeDisplay.getLayout();
76          LayoutTypePortlet layoutTypePortlet =
77              themeDisplay.getLayoutTypePortlet();
78  
79          PermissionChecker permissionChecker =
80              themeDisplay.getPermissionChecker();
81  
82          String cmd = ParamUtil.getString(request, Constants.CMD);
83  
84          String portletId = ParamUtil.getString(request, "p_p_id");
85  
86          boolean updateLayout = true;
87          boolean deletePortlet = false;
88  
89          if (cmd.equals(Constants.ADD)) {
90              portletId = layoutTypePortlet.addPortletId(userId, portletId);
91  
92              String columnId = ParamUtil.getString(request, "p_p_col_id");
93              int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
94  
95              if (Validator.isNotNull(columnId) &&
96                  Validator.isNotNull(portletId)) {
97  
98                  layoutTypePortlet.movePortletId(
99                      userId, portletId, columnId, columnPos);
100             }
101         }
102         else if (cmd.equals(Constants.DELETE)) {
103             if (layoutTypePortlet.hasPortletId(portletId)) {
104                 deletePortlet = true;
105 
106                 layoutTypePortlet.removePortletId(userId, portletId);
107             }
108         }
109         else if (cmd.equals("drag")) {
110             if (LayoutPermissionUtil.contains(
111                     permissionChecker, layout.getGroupId(),
112                     layout.isPrivateLayout(), layout.getLayoutId(),
113                     ActionKeys.UPDATE)) {
114 
115                 String height = ParamUtil.getString(request, "height");
116                 String width = ParamUtil.getString(request, "width");
117                 String top = ParamUtil.getString(request, "top");
118                 String left = ParamUtil.getString(request, "left");
119 
120                 PortletPreferences preferences =
121                     PortletPreferencesFactoryUtil.getLayoutPortletSetup(
122                         layout, portletId);
123 
124                 StringBundler sb = new StringBundler(12);
125 
126                 sb.append("height=");
127                 sb.append(height);
128                 sb.append("\n");
129                 sb.append("width=");
130                 sb.append(width);
131                 sb.append("\n");
132                 sb.append("top=");
133                 sb.append(top);
134                 sb.append("\n");
135                 sb.append("left=");
136                 sb.append(left);
137                 sb.append("\n");
138 
139                 preferences.setValue("portlet-freeform-styles", sb.toString());
140 
141                 preferences.store();
142             }
143         }
144         else if (cmd.equals("minimize")) {
145             boolean restore = ParamUtil.getBoolean(request, "p_p_restore");
146 
147             if (restore) {
148                 layoutTypePortlet.removeStateMinPortletId(portletId);
149             }
150             else {
151                 layoutTypePortlet.addStateMinPortletId(portletId);
152             }
153 
154             updateLayout = false;
155         }
156         else if (cmd.equals("move")) {
157             String columnId = ParamUtil.getString(request, "p_p_col_id");
158             int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
159 
160             layoutTypePortlet.movePortletId(
161                 userId, portletId, columnId, columnPos);
162         }
163         else if (cmd.equals("template")) {
164             String layoutTemplateId = ParamUtil.getString(
165                 request, "layoutTemplateId");
166 
167             layoutTypePortlet.setLayoutTemplateId(userId, layoutTemplateId);
168         }
169 
170         if (updateLayout) {
171 
172             // LEP-3648
173 
174             layoutTypePortlet.resetStates();
175 
176             LayoutServiceUtil.updateLayout(
177                 layout.getGroupId(), layout.isPrivateLayout(),
178                 layout.getLayoutId(), layout.getTypeSettings());
179 
180             // See LEP-1411. Delay the delete of extraneous portlet resources
181             // only after the user has proven that he has the valid permissions.
182 
183             if (deletePortlet) {
184                 String rootPortletId = PortletConstants.getRootPortletId(
185                     portletId);
186 
187                 ResourceLocalServiceUtil.deleteResource(
188                     layout.getCompanyId(), rootPortletId,
189                     ResourceConstants.SCOPE_INDIVIDUAL,
190                     PortletPermissionUtil.getPrimaryKey(
191                         layout.getPlid(), portletId));
192             }
193         }
194         else {
195             LayoutClone layoutClone = LayoutCloneFactory.getInstance();
196 
197             if (layoutClone != null) {
198                 layoutClone.update(
199                     request, layout.getPlid(), layout.getTypeSettings());
200             }
201         }
202 
203         // The check for the refresh variable can be removed in the future. See
204         // LEP-6910.
205 
206         if (ParamUtil.getBoolean(request, "refresh")) {
207             return mapping.findForward(ActionConstants.COMMON_REFERER);
208         }
209         else {
210             if (cmd.equals(Constants.ADD) && (portletId != null)) {
211                 addPortlet(mapping, form, request, response, portletId);
212             }
213 
214             return null;
215         }
216     }
217 
218     protected void addPortlet(
219             ActionMapping mapping, ActionForm form, HttpServletRequest request,
220             HttpServletResponse response, String portletId)
221         throws Exception {
222 
223         // Run the render portlet action to add a portlet without refreshing.
224 
225         Action renderPortletAction = (Action)InstancePool.get(
226             RenderPortletAction.class.getName());
227 
228         // Pass in the portlet id because the portlet id may be the instance id.
229         // Namespace the request if necessary. See LEP-4644.
230 
231         long companyId = PortalUtil.getCompanyId(request);
232 
233         Portlet portlet = PortletLocalServiceUtil.getPortletById(
234             companyId, portletId);
235 
236         DynamicServletRequest dynamicRequest = null;
237 
238         if (portlet.isPrivateRequestAttributes()) {
239             String portletNamespace =
240                 PortalUtil.getPortletNamespace(portlet.getPortletId());
241 
242             dynamicRequest = new NamespaceServletRequest(
243                 request, portletNamespace, portletNamespace);
244         }
245         else {
246             dynamicRequest = new DynamicServletRequest(request);
247         }
248 
249         dynamicRequest.setParameter("p_p_id", portletId);
250 
251         String dataType = ParamUtil.getString(request, "dataType");
252 
253         if (dataType.equals("json")) {
254             JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
255 
256             if (portlet.isAjaxable()) {
257                 StringServletResponse stringResponse =
258                     new StringServletResponse(response);
259 
260                 renderPortletAction.execute(
261                     mapping, form, dynamicRequest, stringResponse);
262 
263                 jsonObj.put("refresh", false);
264                 jsonObj.put("portletHTML", stringResponse.getString().trim());
265             }
266             else {
267                 jsonObj.put("refresh", true);
268             }
269 
270             ServletResponseUtil.write(response, jsonObj.toString());
271         }
272         else {
273             renderPortletAction.execute(
274                 mapping, form, dynamicRequest, response);
275         }
276     }
277 
278 }