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.DynamicServletRequest;
020 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
021 import com.liferay.portal.kernel.servlet.StringServletResponse;
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.StringUtil;
032 import com.liferay.portal.kernel.util.UnicodeProperties;
033 import com.liferay.portal.kernel.workflow.WorkflowConstants;
034 import com.liferay.portal.model.Layout;
035 import com.liferay.portal.model.LayoutRevision;
036 import com.liferay.portal.model.LayoutTypePortlet;
037 import com.liferay.portal.model.Portlet;
038 import com.liferay.portal.security.permission.ActionKeys;
039 import com.liferay.portal.security.permission.PermissionChecker;
040 import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
041 import com.liferay.portal.service.LayoutServiceUtil;
042 import com.liferay.portal.service.PortletLocalServiceUtil;
043 import com.liferay.portal.service.ServiceContext;
044 import com.liferay.portal.service.ServiceContextFactory;
045 import com.liferay.portal.service.permission.LayoutPermissionUtil;
046 import com.liferay.portal.servlet.NamespaceServletRequest;
047 import com.liferay.portal.struts.JSONAction;
048 import com.liferay.portal.theme.ThemeDisplay;
049 import com.liferay.portal.util.LayoutClone;
050 import com.liferay.portal.util.LayoutCloneFactory;
051 import com.liferay.portal.util.PortalUtil;
052 import com.liferay.portal.util.WebKeys;
053 import com.liferay.portlet.PortletPreferencesFactoryUtil;
054
055 import java.util.LinkedHashSet;
056 import java.util.List;
057 import java.util.Set;
058
059 import javax.portlet.MimeResponse;
060 import javax.portlet.PortletPreferences;
061
062 import javax.servlet.http.HttpServletRequest;
063 import javax.servlet.http.HttpServletResponse;
064
065 import org.apache.struts.action.Action;
066 import org.apache.struts.action.ActionForm;
067 import org.apache.struts.action.ActionMapping;
068
069
072 public class UpdateLayoutAction extends JSONAction {
073
074 @Override
075 public String getJSON(
076 ActionMapping actionMapping, ActionForm actionForm,
077 HttpServletRequest request, HttpServletResponse response)
078 throws Exception {
079
080 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
081 WebKeys.THEME_DISPLAY);
082
083 long userId = themeDisplay.getUserId();
084
085 Layout layout = themeDisplay.getLayout();
086 LayoutTypePortlet layoutTypePortlet =
087 themeDisplay.getLayoutTypePortlet();
088
089 PermissionChecker permissionChecker =
090 themeDisplay.getPermissionChecker();
091
092 String cmd = ParamUtil.getString(request, Constants.CMD);
093
094 String portletId = ParamUtil.getString(request, "p_p_id");
095
096 boolean updateLayout = true;
097
098 if (cmd.equals(Constants.ADD)) {
099 String columnId = ParamUtil.getString(request, "p_p_col_id", null);
100 int columnPos = ParamUtil.getInteger(request, "p_p_col_pos", -1);
101
102 portletId = layoutTypePortlet.addPortletId(
103 userId, portletId, columnId, columnPos);
104
105 if (layoutTypePortlet.isCustomizable() &&
106 layoutTypePortlet.isCustomizedView() &&
107 !layoutTypePortlet.isColumnDisabled(columnId)) {
108
109 updateLayout = false;
110 }
111 }
112 else if (cmd.equals(Constants.DELETE)) {
113 if (layoutTypePortlet.hasPortletId(portletId)) {
114 layoutTypePortlet.removePortletId(userId, portletId);
115
116 if (layoutTypePortlet.isCustomizable() &&
117 layoutTypePortlet.isCustomizedView()) {
118
119 updateLayout = false;
120 }
121 }
122 }
123 else if (cmd.equals("drag")) {
124 if (LayoutPermissionUtil.contains(
125 permissionChecker, layout, ActionKeys.UPDATE)) {
126
127 String height = ParamUtil.getString(request, "height");
128 String width = ParamUtil.getString(request, "width");
129 String top = ParamUtil.getString(request, "top");
130 String left = ParamUtil.getString(request, "left");
131
132 PortletPreferences preferences =
133 PortletPreferencesFactoryUtil.getLayoutPortletSetup(
134 layout, portletId);
135
136 StringBundler sb = new StringBundler(12);
137
138 sb.append("height=");
139 sb.append(height);
140 sb.append("\n");
141 sb.append("width=");
142 sb.append(width);
143 sb.append("\n");
144 sb.append("top=");
145 sb.append(top);
146 sb.append("\n");
147 sb.append("left=");
148 sb.append(left);
149 sb.append("\n");
150
151 preferences.setValue("portlet-freeform-styles", sb.toString());
152
153 preferences.store();
154 }
155 }
156 else if (cmd.equals("minimize")) {
157 boolean restore = ParamUtil.getBoolean(request, "p_p_restore");
158
159 if (restore) {
160 layoutTypePortlet.removeStateMinPortletId(portletId);
161 }
162 else {
163 layoutTypePortlet.addStateMinPortletId(portletId);
164 }
165
166 updateLayout = false;
167 }
168 else if (cmd.equals("move")) {
169 String columnId = ParamUtil.getString(request, "p_p_col_id");
170 int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
171
172 layoutTypePortlet.movePortletId(
173 userId, portletId, columnId, columnPos);
174
175 if (layoutTypePortlet.isCustomizable() &&
176 layoutTypePortlet.isCustomizedView() &&
177 !layoutTypePortlet.isColumnDisabled(columnId)) {
178
179 updateLayout = false;
180 }
181 }
182 else if (cmd.equals("redo_layout_revision")) {
183 long layoutRevisionId = ParamUtil.getLong(
184 request, "layoutRevisionId");
185 long layoutSetBranchId = ParamUtil.getLong(
186 request, "layoutSetBranchId");
187
188 ServiceContext serviceContext = ServiceContextFactory.getInstance(
189 request);
190
191 LayoutRevisionLocalServiceUtil.updateStatus(
192 userId, layoutRevisionId, WorkflowConstants.STATUS_DRAFT,
193 serviceContext);
194
195 StagingUtil.setRecentLayoutRevisionId(
196 request, layoutSetBranchId, layout.getPlid(), layoutRevisionId);
197
198 updateLayout = false;
199 }
200 else if (cmd.equals("select_layout_revision")) {
201 long layoutRevisionId = ParamUtil.getLong(
202 request, "layoutRevisionId");
203 long layoutSetBranchId = ParamUtil.getLong(
204 request, "layoutSetBranchId");
205
206 StagingUtil.setRecentLayoutRevisionId(
207 request, layoutSetBranchId, layout.getPlid(), layoutRevisionId);
208
209 updateLayout = false;
210 }
211 else if (cmd.equals("toggle_customized_view")) {
212 updateLayout = false;
213 }
214 else if (cmd.equals("update_type_settings")) {
215 UnicodeProperties layoutTypeSettingsProperties =
216 layout.getTypeSettingsProperties();
217
218 UnicodeProperties formTypeSettingsProperties =
219 PropertiesParamUtil.getProperties(
220 request, "TypeSettingsProperties--");
221
222 layoutTypeSettingsProperties.putAll(formTypeSettingsProperties);
223 }
224 else if (cmd.equals("undo_layout_revision")) {
225 long layoutRevisionId = ParamUtil.getLong(
226 request, "layoutRevisionId");
227 long layoutSetBranchId = ParamUtil.getLong(
228 request, "layoutSetBranchId");
229
230 ServiceContext serviceContext = ServiceContextFactory.getInstance(
231 request);
232
233 LayoutRevision layoutRevision =
234 LayoutRevisionLocalServiceUtil.updateStatus(
235 userId, layoutRevisionId, WorkflowConstants.STATUS_INACTIVE,
236 serviceContext);
237
238 StagingUtil.setRecentLayoutRevisionId(
239 request, layoutSetBranchId, layout.getPlid(),
240 layoutRevision.getParentLayoutRevisionId());
241
242 updateLayout = false;
243 }
244
245 if (updateLayout) {
246
247
248
249 layoutTypePortlet.resetModes();
250 layoutTypePortlet.resetStates();
251
252 layout = LayoutServiceUtil.updateLayout(
253 layout.getGroupId(), layout.isPrivateLayout(),
254 layout.getLayoutId(), layout.getTypeSettings());
255 }
256 else {
257 LayoutClone layoutClone = LayoutCloneFactory.getInstance();
258
259 if (layoutClone != null) {
260 layoutClone.update(
261 request, layout.getPlid(), layout.getTypeSettings());
262 }
263 }
264
265 if (cmd.equals(Constants.ADD) && (portletId != null)) {
266 addPortlet(actionMapping, actionForm, request, response, portletId);
267 }
268
269 return StringPool.BLANK;
270 }
271
272 protected void addPortlet(
273 ActionMapping actionMapping, ActionForm actionForm,
274 HttpServletRequest request, HttpServletResponse response,
275 String portletId)
276 throws Exception {
277
278
279
280 Action renderPortletAction = (Action)InstancePool.get(
281 RenderPortletAction.class.getName());
282
283
284
285
286 long companyId = PortalUtil.getCompanyId(request);
287
288 Portlet portlet = PortletLocalServiceUtil.getPortletById(
289 companyId, portletId);
290
291 DynamicServletRequest dynamicRequest = null;
292
293 if (portlet.isPrivateRequestAttributes()) {
294 String portletNamespace = PortalUtil.getPortletNamespace(
295 portlet.getPortletId());
296
297 dynamicRequest = new NamespaceServletRequest(
298 request, portletNamespace, portletNamespace);
299 }
300 else {
301 dynamicRequest = new DynamicServletRequest(request);
302 }
303
304 dynamicRequest.setParameter("p_p_id", portletId);
305
306 String dataType = ParamUtil.getString(request, "dataType");
307
308 if (dataType.equals("json")) {
309 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
310
311 StringServletResponse stringResponse = new StringServletResponse(
312 response);
313
314 renderPortletAction.execute(
315 actionMapping, actionForm, dynamicRequest, stringResponse);
316
317 populatePortletJSONObject(
318 request, stringResponse, portlet, jsonObject);
319
320 response.setContentType(ContentTypes.APPLICATION_JSON);
321
322 ServletResponseUtil.write(response, jsonObject.toString());
323 }
324 else {
325 renderPortletAction.execute(
326 actionMapping, actionForm, 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, StringServletResponse stringResponse,
342 Portlet portlet, 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("refresh", !portlet.isAjaxable());
352 jsonObject.put("portletHTML", stringResponse.getString().trim());
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 List<String> markupHeadElements = (List<String>)request.getAttribute(
523 MimeResponse.MARKUP_HEAD_ELEMENT);
524
525 if (markupHeadElements != null) {
526 jsonObject.put(
527 "markupHeadElements",
528 StringUtil.merge(markupHeadElements, StringPool.BLANK));
529 }
530 }
531
532 }