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