001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.action;
016    
017    import com.liferay.portal.kernel.json.JSONFactoryUtil;
018    import com.liferay.portal.kernel.json.JSONObject;
019    import com.liferay.portal.kernel.servlet.StringServletResponse;
020    import com.liferay.portal.kernel.util.Constants;
021    import com.liferay.portal.kernel.util.ContentTypes;
022    import com.liferay.portal.kernel.util.InstancePool;
023    import com.liferay.portal.kernel.util.ParamUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.model.Layout;
027    import com.liferay.portal.model.LayoutTypePortlet;
028    import com.liferay.portal.model.Portlet;
029    import com.liferay.portal.model.PortletConstants;
030    import com.liferay.portal.model.ResourceConstants;
031    import com.liferay.portal.security.permission.ActionKeys;
032    import com.liferay.portal.security.permission.PermissionChecker;
033    import com.liferay.portal.service.LayoutServiceUtil;
034    import com.liferay.portal.service.PortletLocalServiceUtil;
035    import com.liferay.portal.service.ResourceLocalServiceUtil;
036    import com.liferay.portal.service.permission.LayoutPermissionUtil;
037    import com.liferay.portal.service.permission.PortletPermissionUtil;
038    import com.liferay.portal.servlet.NamespaceServletRequest;
039    import com.liferay.portal.struts.ActionConstants;
040    import com.liferay.portal.theme.ThemeDisplay;
041    import com.liferay.portal.util.LayoutClone;
042    import com.liferay.portal.util.LayoutCloneFactory;
043    import com.liferay.portal.util.PortalUtil;
044    import com.liferay.portal.util.WebKeys;
045    import com.liferay.portlet.PortletPreferencesFactoryUtil;
046    import com.liferay.util.servlet.DynamicServletRequest;
047    import com.liferay.util.servlet.ServletResponseUtil;
048    
049    import javax.portlet.PortletPreferences;
050    
051    import javax.servlet.http.HttpServletRequest;
052    import javax.servlet.http.HttpServletResponse;
053    
054    import org.apache.struts.action.Action;
055    import org.apache.struts.action.ActionForm;
056    import org.apache.struts.action.ActionForward;
057    import org.apache.struts.action.ActionMapping;
058    
059    /**
060     * @author Brian Wing Shun Chan
061     */
062    public class UpdateLayoutAction extends Action {
063    
064            public ActionForward execute(
065                            ActionMapping mapping, ActionForm form, HttpServletRequest request,
066                            HttpServletResponse response)
067                    throws Exception {
068    
069                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
070                            WebKeys.THEME_DISPLAY);
071    
072                    long userId = themeDisplay.getUserId();
073    
074                    Layout layout = themeDisplay.getLayout();
075                    LayoutTypePortlet layoutTypePortlet =
076                            themeDisplay.getLayoutTypePortlet();
077    
078                    PermissionChecker permissionChecker =
079                            themeDisplay.getPermissionChecker();
080    
081                    String cmd = ParamUtil.getString(request, Constants.CMD);
082    
083                    String portletId = ParamUtil.getString(request, "p_p_id");
084    
085                    boolean updateLayout = true;
086                    boolean deletePortlet = false;
087    
088                    if (cmd.equals(Constants.ADD)) {
089                            portletId = layoutTypePortlet.addPortletId(userId, portletId);
090    
091                            String columnId = ParamUtil.getString(request, "p_p_col_id");
092                            int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
093    
094                            if (Validator.isNotNull(columnId) &&
095                                    Validator.isNotNull(portletId)) {
096    
097                                    layoutTypePortlet.movePortletId(
098                                            userId, portletId, columnId, columnPos);
099                            }
100                    }
101                    else if (cmd.equals(Constants.DELETE)) {
102                            if (layoutTypePortlet.hasPortletId(portletId)) {
103                                    deletePortlet = true;
104    
105                                    layoutTypePortlet.removePortletId(userId, portletId);
106                            }
107                    }
108                    else if (cmd.equals("drag")) {
109                            if (LayoutPermissionUtil.contains(
110                                            permissionChecker, layout.getGroupId(),
111                                            layout.isPrivateLayout(), layout.getLayoutId(),
112                                            ActionKeys.UPDATE)) {
113    
114                                    String height = ParamUtil.getString(request, "height");
115                                    String width = ParamUtil.getString(request, "width");
116                                    String top = ParamUtil.getString(request, "top");
117                                    String left = ParamUtil.getString(request, "left");
118    
119                                    PortletPreferences preferences =
120                                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
121                                                    layout, portletId);
122    
123                                    StringBundler sb = new StringBundler(12);
124    
125                                    sb.append("height=");
126                                    sb.append(height);
127                                    sb.append("\n");
128                                    sb.append("width=");
129                                    sb.append(width);
130                                    sb.append("\n");
131                                    sb.append("top=");
132                                    sb.append(top);
133                                    sb.append("\n");
134                                    sb.append("left=");
135                                    sb.append(left);
136                                    sb.append("\n");
137    
138                                    preferences.setValue("portlet-freeform-styles", sb.toString());
139    
140                                    preferences.store();
141                            }
142                    }
143                    else if (cmd.equals("minimize")) {
144                            boolean restore = ParamUtil.getBoolean(request, "p_p_restore");
145    
146                            if (restore) {
147                                    layoutTypePortlet.removeStateMinPortletId(portletId);
148                            }
149                            else {
150                                    layoutTypePortlet.addStateMinPortletId(portletId);
151                            }
152    
153                            updateLayout = false;
154                    }
155                    else if (cmd.equals("move")) {
156                            String columnId = ParamUtil.getString(request, "p_p_col_id");
157                            int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
158    
159                            layoutTypePortlet.movePortletId(
160                                    userId, portletId, columnId, columnPos);
161                    }
162                    else if (cmd.equals("template")) {
163                            String layoutTemplateId = ParamUtil.getString(
164                                    request, "layoutTemplateId");
165    
166                            layoutTypePortlet.setLayoutTemplateId(userId, layoutTemplateId);
167                    }
168    
169                    if (updateLayout) {
170    
171                            // LEP-3648
172    
173                            layoutTypePortlet.resetModes();
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                            response.setContentType(ContentTypes.TEXT_JAVASCRIPT);
271    
272                            ServletResponseUtil.write(response, jsonObj.toString());
273                    }
274                    else {
275                            renderPortletAction.execute(
276                                    mapping, form, dynamicRequest, response);
277                    }
278            }
279    
280    }