001
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.BufferCacheServletResponse;
020 import com.liferay.portal.kernel.servlet.DynamicServletRequest;
021 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
022 import com.liferay.portal.kernel.staging.StagingUtil;
023 import com.liferay.portal.kernel.util.Constants;
024 import com.liferay.portal.kernel.util.ContentTypes;
025 import com.liferay.portal.kernel.util.HttpUtil;
026 import com.liferay.portal.kernel.util.InstancePool;
027 import com.liferay.portal.kernel.util.ParamUtil;
028 import com.liferay.portal.kernel.util.PropertiesParamUtil;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.util.UnicodeProperties;
032 import com.liferay.portal.kernel.workflow.WorkflowConstants;
033 import com.liferay.portal.model.Layout;
034 import com.liferay.portal.model.LayoutRevision;
035 import com.liferay.portal.model.LayoutTypePortlet;
036 import com.liferay.portal.model.Portlet;
037 import com.liferay.portal.security.permission.ActionKeys;
038 import com.liferay.portal.security.permission.PermissionChecker;
039 import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
040 import com.liferay.portal.service.LayoutServiceUtil;
041 import com.liferay.portal.service.PortletLocalServiceUtil;
042 import com.liferay.portal.service.ServiceContext;
043 import com.liferay.portal.service.ServiceContextFactory;
044 import com.liferay.portal.service.permission.LayoutPermissionUtil;
045 import com.liferay.portal.servlet.NamespaceServletRequest;
046 import com.liferay.portal.struts.JSONAction;
047 import com.liferay.portal.theme.ThemeDisplay;
048 import com.liferay.portal.util.LayoutClone;
049 import com.liferay.portal.util.LayoutCloneFactory;
050 import com.liferay.portal.util.PortalUtil;
051 import com.liferay.portal.util.WebKeys;
052 import com.liferay.portlet.PortletPreferencesFactoryUtil;
053
054 import java.util.LinkedHashSet;
055 import java.util.Set;
056
057 import javax.portlet.PortletPreferences;
058
059 import javax.servlet.http.HttpServletRequest;
060 import javax.servlet.http.HttpServletResponse;
061
062 import org.apache.struts.action.Action;
063 import org.apache.struts.action.ActionForm;
064 import org.apache.struts.action.ActionMapping;
065
066
069 public class UpdateLayoutAction extends JSONAction {
070
071 @Override
072 public String getJSON(
073 ActionMapping mapping, ActionForm form, HttpServletRequest request,
074 HttpServletResponse response)
075 throws Exception {
076
077 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
078 WebKeys.THEME_DISPLAY);
079
080 long userId = themeDisplay.getUserId();
081
082 Layout layout = themeDisplay.getLayout();
083 LayoutTypePortlet layoutTypePortlet =
084 themeDisplay.getLayoutTypePortlet();
085
086 PermissionChecker permissionChecker =
087 themeDisplay.getPermissionChecker();
088
089 String cmd = ParamUtil.getString(request, Constants.CMD);
090
091 String portletId = ParamUtil.getString(request, "p_p_id");
092
093 boolean updateLayout = true;
094
095 if (cmd.equals(Constants.ADD)) {
096 String columnId = ParamUtil.getString(request, "p_p_col_id", null);
097 int columnPos = ParamUtil.getInteger(request, "p_p_col_pos", -1);
098
099 portletId = layoutTypePortlet.addPortletId(
100 userId, portletId, columnId, columnPos);
101
102 if (layoutTypePortlet.isCustomizable() &&
103 layoutTypePortlet.isCustomizedView() &&
104 !layoutTypePortlet.isColumnDisabled(columnId)) {
105
106 updateLayout = false;
107 }
108 }
109 else if (cmd.equals(Constants.DELETE)) {
110 if (layoutTypePortlet.hasPortletId(portletId)) {
111 layoutTypePortlet.removePortletId(userId, portletId);
112
113 if (layoutTypePortlet.isCustomizable() &&
114 layoutTypePortlet.isCustomizedView()) {
115
116 updateLayout = false;
117 }
118 }
119 }
120 else if (cmd.equals("drag")) {
121 if (LayoutPermissionUtil.contains(
122 permissionChecker, layout, ActionKeys.UPDATE)) {
123
124 String height = ParamUtil.getString(request, "height");
125 String width = ParamUtil.getString(request, "width");
126 String top = ParamUtil.getString(request, "top");
127 String left = ParamUtil.getString(request, "left");
128
129 PortletPreferences preferences =
130 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
131 layout, portletId);
132
133 StringBundler sb = new StringBundler(12);
134
135 sb.append("height=");
136 sb.append(height);
137 sb.append("\n");
138 sb.append("width=");
139 sb.append(width);
140 sb.append("\n");
141 sb.append("top=");
142 sb.append(top);
143 sb.append("\n");
144 sb.append("left=");
145 sb.append(left);
146 sb.append("\n");
147
148 preferences.setValue("portlet-freeform-styles", sb.toString());
149
150 preferences.store();
151 }
152 }
153 else if (cmd.equals("minimize")) {
154 boolean restore = ParamUtil.getBoolean(request, "p_p_restore");
155
156 if (restore) {
157 layoutTypePortlet.removeStateMinPortletId(portletId);
158 }
159 else {
160 layoutTypePortlet.addStateMinPortletId(portletId);
161 }
162
163 updateLayout = false;
164 }
165 else if (cmd.equals("move")) {
166 String columnId = ParamUtil.getString(request, "p_p_col_id");
167 int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
168
169 layoutTypePortlet.movePortletId(
170 userId, portletId, columnId, columnPos);
171
172 if (layoutTypePortlet.isCustomizable() &&
173 layoutTypePortlet.isCustomizedView() &&
174 !layoutTypePortlet.isColumnDisabled(columnId)) {
175
176 updateLayout = false;
177 }
178 }
179 else if (cmd.equals("redo_layout_revision")) {
180 long layoutRevisionId = ParamUtil.getLong(
181 request, "layoutRevisionId");
182 long layoutSetBranchId = ParamUtil.getLong(
183 request, "layoutSetBranchId");
184
185 ServiceContext serviceContext = ServiceContextFactory.getInstance(
186 request);
187
188 LayoutRevisionLocalServiceUtil.updateStatus(
189 userId, layoutRevisionId, WorkflowConstants.STATUS_DRAFT,
190 serviceContext);
191
192 StagingUtil.setRecentLayoutRevisionId(
193 request, layoutSetBranchId, layout.getPlid(), layoutRevisionId);
194
195 updateLayout = false;
196 }
197 else if (cmd.equals("select_layout_revision")) {
198 long layoutRevisionId = ParamUtil.getLong(
199 request, "layoutRevisionId");
200 long layoutSetBranchId = ParamUtil.getLong(
201 request, "layoutSetBranchId");
202
203 StagingUtil.setRecentLayoutRevisionId(
204 request, layoutSetBranchId, layout.getPlid(), layoutRevisionId);
205
206 updateLayout = false;
207 }
208 else if (cmd.equals("toggle_customized_view")) {
209 updateLayout = false;
210 }
211 else if (cmd.equals("update_type_settings")) {
212 UnicodeProperties layoutTypeSettingsProperties =
213 layout.getTypeSettingsProperties();
214
215 UnicodeProperties formTypeSettingsProperties =
216 PropertiesParamUtil.getProperties(
217 request, "TypeSettingsProperties--");
218
219 layoutTypeSettingsProperties.putAll(formTypeSettingsProperties);
220 }
221 else if (cmd.equals("undo_layout_revision")) {
222 long layoutRevisionId = ParamUtil.getLong(
223 request, "layoutRevisionId");
224 long layoutSetBranchId = ParamUtil.getLong(
225 request, "layoutSetBranchId");
226
227 ServiceContext serviceContext = ServiceContextFactory.getInstance(
228 request);
229
230 LayoutRevision layoutRevision =
231 LayoutRevisionLocalServiceUtil.updateStatus(
232 userId, layoutRevisionId, WorkflowConstants.STATUS_INACTIVE,
233 serviceContext);
234
235 StagingUtil.setRecentLayoutRevisionId(
236 request, layoutSetBranchId, layout.getPlid(),
237 layoutRevision.getParentLayoutRevisionId());
238
239 updateLayout = false;
240 }
241
242 if (updateLayout) {
243
244
245
246 layoutTypePortlet.resetModes();
247 layoutTypePortlet.resetStates();
248
249 layout = LayoutServiceUtil.updateLayout(
250 layout.getGroupId(), layout.isPrivateLayout(),
251 layout.getLayoutId(), layout.getTypeSettings());
252 }
253 else {
254 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
255
256 if (layoutClone != null) {
257 layoutClone.update(
258 request, layout.getPlid(), layout.getTypeSettings());
259 }
260 }
261
262 if (cmd.equals(Constants.ADD) && (portletId != null)) {
263 addPortlet(mapping, form, request, response, portletId);
264 }
265
266 return StringPool.BLANK;
267 }
268
269 protected void addPortlet(
270 ActionMapping mapping, ActionForm form, HttpServletRequest request,
271 HttpServletResponse response, String portletId)
272 throws Exception {
273
274
275
276 Action renderPortletAction = (Action)InstancePool.get(
277 RenderPortletAction.class.getName());
278
279
280
281
282 long companyId = PortalUtil.getCompanyId(request);
283
284 Portlet portlet = PortletLocalServiceUtil.getPortletById(
285 companyId, portletId);
286
287 DynamicServletRequest dynamicRequest = null;
288
289 if (portlet.isPrivateRequestAttributes()) {
290 String portletNamespace = PortalUtil.getPortletNamespace(
291 portlet.getPortletId());
292
293 dynamicRequest = new NamespaceServletRequest(
294 request, portletNamespace, portletNamespace);
295 }
296 else {
297 dynamicRequest = new DynamicServletRequest(request);
298 }
299
300 dynamicRequest.setParameter("p_p_id", portletId);
301
302 String dataType = ParamUtil.getString(request, "dataType");
303
304 if (dataType.equals("json")) {
305 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
306
307 BufferCacheServletResponse bufferCacheServletResponse =
308 new BufferCacheServletResponse(response);
309
310 renderPortletAction.execute(
311 mapping, form, dynamicRequest, bufferCacheServletResponse);
312
313 String portletHTML = bufferCacheServletResponse.getString();
314
315 portletHTML = portletHTML.trim();
316
317 populatePortletJSONObject(
318 request, portletHTML, portlet, jsonObject);
319
320 response.setContentType(ContentTypes.TEXT_JAVASCRIPT);
321
322 ServletResponseUtil.write(response, jsonObject.toString());
323 }
324 else {
325 renderPortletAction.execute(
326 mapping, form, dynamicRequest, response);
327 }
328 }
329
330 protected String getRootPortletId(Portlet portlet) {
331
332
333
334
335 Portlet rootPortlet = portlet.getRootPortlet();
336
337 return rootPortlet.getPortletId();
338 }
339
340 protected void populatePortletJSONObject(
341 HttpServletRequest request, String portletHTML, Portlet portlet,
342 JSONObject jsonObject)
343 throws Exception {
344
345 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
346 WebKeys.THEME_DISPLAY);
347
348 LayoutTypePortlet layoutTypePortlet =
349 themeDisplay.getLayoutTypePortlet();
350
351 jsonObject.put("portletHTML", portletHTML);
352 jsonObject.put("refresh", !portlet.isAjaxable());
353
354 Set<String> footerCssSet = new LinkedHashSet<String>();
355 Set<String> footerJavaScriptSet = new LinkedHashSet<String>();
356 Set<String> headerCssSet = new LinkedHashSet<String>();
357 Set<String> headerJavaScriptSet = new LinkedHashSet<String>();
358
359 boolean portletOnLayout = false;
360
361 String rootPortletId = getRootPortletId(portlet);
362 String portletId = portlet.getPortletId();
363
364 for (Portlet layoutPortlet : layoutTypePortlet.getAllPortlets()) {
365
366
367
368
369 String layoutPortletRootPortletId = getRootPortletId(layoutPortlet);
370
371 if (rootPortletId.equals(layoutPortletRootPortletId) &&
372 !portletId.equals(layoutPortlet.getPortletId())) {
373
374 portletOnLayout = true;
375
376 break;
377 }
378 }
379
380 if (!portletOnLayout && portlet.isAjaxable()) {
381 Portlet rootPortlet = portlet.getRootPortlet();
382
383 for (String footerPortalCss : portlet.getFooterPortalCss()) {
384 if (!HttpUtil.hasProtocol(footerPortalCss)) {
385 footerPortalCss =
386 PortalUtil.getPathContext() + footerPortalCss;
387
388 footerPortalCss = PortalUtil.getStaticResourceURL(
389 request, footerPortalCss, rootPortlet.getTimestamp());
390 }
391
392 footerCssSet.add(footerPortalCss);
393 }
394
395 for (String footerPortalJavaScript :
396 portlet.getFooterPortalJavaScript()) {
397
398 if (!HttpUtil.hasProtocol(footerPortalJavaScript)) {
399 footerPortalJavaScript =
400 PortalUtil.getPathContext() + footerPortalJavaScript;
401
402 footerPortalJavaScript = PortalUtil.getStaticResourceURL(
403 request, footerPortalJavaScript,
404 rootPortlet.getTimestamp());
405 }
406
407 footerJavaScriptSet.add(footerPortalJavaScript);
408 }
409
410 for (String footerPortletCss : portlet.getFooterPortletCss()) {
411 if (!HttpUtil.hasProtocol(footerPortletCss)) {
412 footerPortletCss =
413 portlet.getStaticResourcePath() + footerPortletCss;
414
415 footerPortletCss = PortalUtil.getStaticResourceURL(
416 request, footerPortletCss, rootPortlet.getTimestamp());
417 }
418
419 footerCssSet.add(footerPortletCss);
420 }
421
422 for (String footerPortletJavaScript :
423 portlet.getFooterPortletJavaScript()) {
424
425 if (!HttpUtil.hasProtocol(footerPortletJavaScript)) {
426 footerPortletJavaScript =
427 portlet.getStaticResourcePath() +
428 footerPortletJavaScript;
429
430 footerPortletJavaScript = PortalUtil.getStaticResourceURL(
431 request, footerPortletJavaScript,
432 rootPortlet.getTimestamp());
433 }
434
435 footerJavaScriptSet.add(footerPortletJavaScript);
436 }
437
438 for (String headerPortalCss : portlet.getHeaderPortalCss()) {
439 if (!HttpUtil.hasProtocol(headerPortalCss)) {
440 headerPortalCss =
441 PortalUtil.getPathContext() + headerPortalCss;
442
443 headerPortalCss = PortalUtil.getStaticResourceURL(
444 request, headerPortalCss, rootPortlet.getTimestamp());
445 }
446
447 headerCssSet.add(headerPortalCss);
448 }
449
450 for (String headerPortalJavaScript :
451 portlet.getHeaderPortalJavaScript()) {
452
453 if (!HttpUtil.hasProtocol(headerPortalJavaScript)) {
454 headerPortalJavaScript =
455 PortalUtil.getPathContext() + headerPortalJavaScript;
456
457 headerPortalJavaScript = PortalUtil.getStaticResourceURL(
458 request, headerPortalJavaScript,
459 rootPortlet.getTimestamp());
460 }
461
462 headerJavaScriptSet.add(headerPortalJavaScript);
463 }
464
465 for (String headerPortletCss : portlet.getHeaderPortletCss()) {
466 if (!HttpUtil.hasProtocol(headerPortletCss)) {
467 headerPortletCss =
468 portlet.getStaticResourcePath() + headerPortletCss;
469
470 headerPortletCss = PortalUtil.getStaticResourceURL(
471 request, headerPortletCss, rootPortlet.getTimestamp());
472 }
473
474 headerCssSet.add(headerPortletCss);
475 }
476
477 for (String headerPortletJavaScript :
478 portlet.getHeaderPortletJavaScript()) {
479
480 if (!HttpUtil.hasProtocol(headerPortletJavaScript)) {
481 headerPortletJavaScript =
482 portlet.getStaticResourcePath() +
483 headerPortletJavaScript;
484
485 headerPortletJavaScript = PortalUtil.getStaticResourceURL(
486 request, headerPortletJavaScript,
487 rootPortlet.getTimestamp());
488 }
489
490 headerJavaScriptSet.add(headerPortletJavaScript);
491 }
492 }
493
494 String footerCssPaths = JSONFactoryUtil.serialize(
495 footerCssSet.toArray(new String[footerCssSet.size()]));
496
497 jsonObject.put(
498 "footerCssPaths", JSONFactoryUtil.createJSONArray(footerCssPaths));
499
500 String footerJavaScriptPaths = JSONFactoryUtil.serialize(
501 footerJavaScriptSet.toArray(
502 new String[footerJavaScriptSet.size()]));
503
504 jsonObject.put(
505 "footerJavaScriptPaths",
506 JSONFactoryUtil.createJSONArray(footerJavaScriptPaths));
507
508 String headerCssPaths = JSONFactoryUtil.serialize(
509 headerCssSet.toArray(new String[headerCssSet.size()]));
510
511 jsonObject.put(
512 "headerCssPaths", JSONFactoryUtil.createJSONArray(headerCssPaths));
513
514 String headerJavaScriptPaths = JSONFactoryUtil.serialize(
515 headerJavaScriptSet.toArray(
516 new String[headerJavaScriptSet.size()]));
517
518 jsonObject.put(
519 "headerJavaScriptPaths",
520 JSONFactoryUtil.createJSONArray(headerJavaScriptPaths));
521 }
522
523 }