1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.action;
24  
25  import com.liferay.portal.kernel.json.JSONFactoryUtil;
26  import com.liferay.portal.kernel.json.JSONObject;
27  import com.liferay.portal.kernel.servlet.StringServletResponse;
28  import com.liferay.portal.kernel.util.Constants;
29  import com.liferay.portal.kernel.util.InstancePool;
30  import com.liferay.portal.kernel.util.ParamUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.model.Layout;
33  import com.liferay.portal.model.LayoutTypePortlet;
34  import com.liferay.portal.model.Portlet;
35  import com.liferay.portal.model.PortletConstants;
36  import com.liferay.portal.model.ResourceConstants;
37  import com.liferay.portal.security.permission.ActionKeys;
38  import com.liferay.portal.security.permission.PermissionChecker;
39  import com.liferay.portal.service.LayoutServiceUtil;
40  import com.liferay.portal.service.PortletLocalServiceUtil;
41  import com.liferay.portal.service.ResourceLocalServiceUtil;
42  import com.liferay.portal.service.permission.LayoutPermissionUtil;
43  import com.liferay.portal.service.permission.PortletPermissionUtil;
44  import com.liferay.portal.servlet.NamespaceServletRequest;
45  import com.liferay.portal.struts.ActionConstants;
46  import com.liferay.portal.theme.ThemeDisplay;
47  import com.liferay.portal.util.LayoutClone;
48  import com.liferay.portal.util.LayoutCloneFactory;
49  import com.liferay.portal.util.PortalUtil;
50  import com.liferay.portal.util.WebKeys;
51  import com.liferay.portlet.PortletPreferencesFactoryUtil;
52  import com.liferay.util.servlet.DynamicServletRequest;
53  import com.liferay.util.servlet.ServletResponseUtil;
54  
55  import javax.portlet.PortletPreferences;
56  
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpServletResponse;
59  
60  import org.apache.struts.action.Action;
61  import org.apache.struts.action.ActionForm;
62  import org.apache.struts.action.ActionForward;
63  import org.apache.struts.action.ActionMapping;
64  
65  /**
66   * <a href="UpdateLayoutAction.java.html"><b><i>View Source</i></b></a>
67   *
68   * @author Brian Wing Shun Chan
69   *
70   */
71  public class UpdateLayoutAction extends Action {
72  
73      public ActionForward execute(
74              ActionMapping mapping, ActionForm form, HttpServletRequest request,
75              HttpServletResponse response)
76          throws Exception {
77  
78          ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
79              WebKeys.THEME_DISPLAY);
80  
81          long userId = themeDisplay.getUserId();
82  
83          Layout layout = themeDisplay.getLayout();
84          LayoutTypePortlet layoutTypePortlet =
85              themeDisplay.getLayoutTypePortlet();
86  
87          PermissionChecker permissionChecker =
88              themeDisplay.getPermissionChecker();
89  
90          String cmd = ParamUtil.getString(request, Constants.CMD);
91  
92          String portletId = ParamUtil.getString(request, "p_p_id");
93  
94          boolean updateLayout = true;
95          boolean deletePortlet = false;
96  
97          if (cmd.equals(Constants.ADD)) {
98              portletId = layoutTypePortlet.addPortletId(userId, portletId);
99  
100             String columnId = ParamUtil.getString(request, "p_p_col_id");
101             int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
102 
103             if (Validator.isNotNull(columnId) &&
104                 Validator.isNotNull(portletId)) {
105 
106                 layoutTypePortlet.movePortletId(
107                     userId, portletId, columnId, columnPos);
108             }
109         }
110         else if (cmd.equals(Constants.DELETE)) {
111             if (layoutTypePortlet.hasPortletId(portletId)) {
112                 deletePortlet = true;
113 
114                 layoutTypePortlet.removePortletId(userId, portletId);
115             }
116         }
117         else if (cmd.equals("drag")) {
118             if (LayoutPermissionUtil.contains(
119                     permissionChecker, layout.getGroupId(),
120                     layout.isPrivateLayout(), layout.getLayoutId(),
121                     ActionKeys.UPDATE)) {
122 
123                 String height = ParamUtil.getString(request, "height");
124                 String width = ParamUtil.getString(request, "width");
125                 String top = ParamUtil.getString(request, "top");
126                 String left = ParamUtil.getString(request, "left");
127 
128                 PortletPreferences preferences =
129                     PortletPreferencesFactoryUtil.getLayoutPortletSetup(
130                         layout, portletId);
131 
132                 StringBuilder sb = new StringBuilder();
133 
134                 sb.append("height=" + height + "\n");
135                 sb.append("width=" + width + "\n");
136                 sb.append("top=" + top + "\n");
137                 sb.append("left=" + left + "\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 }