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