001
014
015 package com.liferay.portlet.layoutsadmin.util;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.json.JSONArray;
019 import com.liferay.portal.kernel.json.JSONFactoryUtil;
020 import com.liferay.portal.kernel.json.JSONObject;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.ArrayUtil;
024 import com.liferay.portal.kernel.util.ParamUtil;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.WebKeys;
028 import com.liferay.portal.model.Layout;
029 import com.liferay.portal.model.LayoutBranch;
030 import com.liferay.portal.model.LayoutConstants;
031 import com.liferay.portal.model.LayoutRevision;
032 import com.liferay.portal.model.LayoutSetBranch;
033 import com.liferay.portal.model.LayoutType;
034 import com.liferay.portal.model.impl.VirtualLayout;
035 import com.liferay.portal.security.permission.ActionKeys;
036 import com.liferay.portal.service.LayoutLocalServiceUtil;
037 import com.liferay.portal.service.LayoutServiceUtil;
038 import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
039 import com.liferay.portal.service.permission.GroupPermissionUtil;
040 import com.liferay.portal.service.permission.LayoutPermissionUtil;
041 import com.liferay.portal.theme.ThemeDisplay;
042 import com.liferay.portal.util.PropsValues;
043 import com.liferay.portal.util.SessionClicks;
044 import com.liferay.portlet.exportimport.staging.LayoutStagingUtil;
045 import com.liferay.portlet.exportimport.staging.StagingUtil;
046 import com.liferay.sites.kernel.util.SitesUtil;
047
048 import java.util.ArrayList;
049 import java.util.Collections;
050 import java.util.Iterator;
051 import java.util.List;
052
053 import javax.servlet.http.HttpServletRequest;
054 import javax.servlet.http.HttpSession;
055
056
064 public class LayoutsTreeUtil {
065
066 public static String getLayoutsJSON(
067 HttpServletRequest request, long groupId, boolean privateLayout,
068 long parentLayoutId, boolean incomplete, String treeId)
069 throws Exception {
070
071 return getLayoutsJSON(
072 request, groupId, privateLayout, parentLayoutId, null, incomplete,
073 treeId);
074 }
075
076 public static String getLayoutsJSON(
077 HttpServletRequest request, long groupId, boolean privateLayout,
078 long parentLayoutId, long[] expandedLayoutIds, boolean incomplete,
079 String treeId)
080 throws Exception {
081
082 if (_log.isDebugEnabled()) {
083 StringBundler sb = new StringBundler(13);
084
085 sb.append("getLayoutsJSON(groupId=");
086 sb.append(groupId);
087 sb.append(", privateLayout=");
088 sb.append(privateLayout);
089 sb.append(", parentLayoutId=");
090 sb.append(parentLayoutId);
091 sb.append(", expandedLayoutIds=");
092 sb.append(expandedLayoutIds);
093 sb.append(", incomplete=");
094 sb.append(incomplete);
095 sb.append(", treeId=");
096 sb.append(treeId);
097 sb.append(StringPool.CLOSE_PARENTHESIS);
098
099 _log.debug(sb.toString());
100 }
101
102 LayoutTreeNodes layoutTreeNodes = _getLayoutTreeNodes(
103 request, groupId, privateLayout, parentLayoutId, incomplete,
104 expandedLayoutIds, treeId);
105
106 return _toJSON(request, groupId, layoutTreeNodes);
107 }
108
109 public static String getLayoutsJSON(
110 HttpServletRequest request, long groupId, String treeId)
111 throws Exception {
112
113 if (_log.isDebugEnabled()) {
114 StringBundler sb = new StringBundler(5);
115
116 sb.append("getLayoutsJSON(groupId=");
117 sb.append(groupId);
118 sb.append(", treeId=");
119 sb.append(treeId);
120 sb.append(StringPool.CLOSE_PARENTHESIS);
121
122 _log.debug(sb.toString());
123 }
124
125 LayoutTreeNodes layoutTreeNodes = new LayoutTreeNodes();
126
127 layoutTreeNodes.addAll(
128 _getLayoutTreeNodes(
129 request, groupId, true,
130 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, false, null, treeId));
131 layoutTreeNodes.addAll(
132 _getLayoutTreeNodes(
133 request, groupId, false,
134 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, false, null, treeId));
135
136 return _toJSON(request, groupId, layoutTreeNodes);
137 }
138
139 private static List<Layout> _getAncestorLayouts(HttpServletRequest request)
140 throws Exception {
141
142 long selPlid = ParamUtil.getLong(request, "selPlid");
143
144 if (selPlid == 0) {
145 return Collections.emptyList();
146 }
147
148 List<Layout> ancestorLayouts = LayoutServiceUtil.getAncestorLayouts(
149 selPlid);
150
151 Layout layout = LayoutLocalServiceUtil.getLayout(selPlid);
152
153 if (_log.isDebugEnabled()) {
154 StringBundler sb = new StringBundler(7);
155
156 sb.append("_getAncestorLayouts(selPlid=");
157 sb.append(selPlid);
158 sb.append(", ancestorLayouts=");
159 sb.append(ancestorLayouts);
160 sb.append(", layout=");
161 sb.append(layout);
162 sb.append(StringPool.CLOSE_PARENTHESIS);
163
164 _log.debug(sb.toString());
165 }
166
167 ancestorLayouts.add(layout);
168
169 return ancestorLayouts;
170 }
171
172 private static LayoutTreeNodes _getLayoutTreeNodes(
173 HttpServletRequest request, long groupId, boolean privateLayout,
174 long parentLayoutId, boolean incomplete, long[] expandedLayoutIds,
175 String treeId)
176 throws Exception {
177
178 if (_log.isDebugEnabled()) {
179 StringBundler sb = new StringBundler(13);
180
181 sb.append("_getLayoutTreeNodes(groupId=");
182 sb.append(groupId);
183 sb.append(", privateLayout=");
184 sb.append(privateLayout);
185 sb.append(", parentLayoutId=");
186 sb.append(parentLayoutId);
187 sb.append(", expandedLayoutIds=");
188 sb.append(expandedLayoutIds);
189 sb.append(", incomplete=");
190 sb.append(incomplete);
191 sb.append(", treeId=");
192 sb.append(treeId);
193 sb.append(StringPool.CLOSE_PARENTHESIS);
194
195 _log.debug(sb.toString());
196 }
197
198 List<LayoutTreeNode> layoutTreeNodes = new ArrayList<>();
199
200 List<Layout> ancestorLayouts = _getAncestorLayouts(request);
201
202 List<Layout> layouts = LayoutServiceUtil.getLayouts(
203 groupId, privateLayout, parentLayoutId, incomplete,
204 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
205
206 for (Layout layout :
207 _paginateLayouts(
208 request, groupId, privateLayout, parentLayoutId, layouts,
209 treeId)) {
210
211 LayoutTreeNode layoutTreeNode = new LayoutTreeNode(layout);
212
213 LayoutTreeNodes childLayoutTreeNodes = null;
214
215 if (_isExpandableLayout(
216 request, ancestorLayouts, expandedLayoutIds, layout)) {
217
218 if (layout instanceof VirtualLayout) {
219 VirtualLayout virtualLayout = (VirtualLayout)layout;
220
221 childLayoutTreeNodes = _getLayoutTreeNodes(
222 request, virtualLayout.getSourceGroupId(),
223 virtualLayout.isPrivateLayout(),
224 virtualLayout.getLayoutId(), incomplete,
225 expandedLayoutIds, treeId);
226 }
227 else {
228 childLayoutTreeNodes = _getLayoutTreeNodes(
229 request, groupId, layout.isPrivateLayout(),
230 layout.getLayoutId(), incomplete, expandedLayoutIds,
231 treeId);
232 }
233 }
234 else {
235 int childLayoutsCount = LayoutServiceUtil.getLayoutsCount(
236 groupId, privateLayout, layout.getLayoutId());
237
238 childLayoutTreeNodes = new LayoutTreeNodes(
239 new ArrayList<LayoutTreeNode>(), childLayoutsCount);
240 }
241
242 layoutTreeNode.setChildLayoutTreeNodes(childLayoutTreeNodes);
243
244 layoutTreeNodes.add(layoutTreeNode);
245 }
246
247 return new LayoutTreeNodes(layoutTreeNodes, layouts.size());
248 }
249
250 private static int _getLoadedLayoutsCount(
251 HttpSession session, long groupId, boolean privateLayout,
252 long layoutId, String treeId)
253 throws Exception {
254
255 StringBundler sb = new StringBundler(7);
256
257 sb.append(treeId);
258 sb.append(StringPool.COLON);
259 sb.append(groupId);
260 sb.append(StringPool.COLON);
261 sb.append(privateLayout);
262 sb.append(StringPool.COLON);
263 sb.append("Pagination");
264
265 String key = sb.toString();
266
267 String paginationJSON = SessionClicks.get(
268 session, key, JSONFactoryUtil.getNullJSON());
269
270 JSONObject paginationJSONObject = JSONFactoryUtil.createJSONObject(
271 paginationJSON);
272
273 if (_log.isDebugEnabled()) {
274 sb = new StringBundler(9);
275
276 sb.append("_getLoadedLayoutsCount(key=");
277 sb.append(key);
278 sb.append(", layoutId=");
279 sb.append(layoutId);
280 sb.append(", paginationJSON=");
281 sb.append(paginationJSON);
282 sb.append(", paginationJSONObject");
283 sb.append(paginationJSONObject);
284 sb.append(StringPool.CLOSE_PARENTHESIS);
285
286 _log.debug(sb.toString());
287 }
288
289 return paginationJSONObject.getInt(String.valueOf(layoutId), 0);
290 }
291
292 private static boolean _isExpandableLayout(
293 HttpServletRequest request, List<Layout> ancestorLayouts,
294 long[] expandedLayoutIds, Layout layout) {
295
296 boolean expandParentLayouts = ParamUtil.getBoolean(
297 request, "expandParentLayouts");
298
299 if (expandParentLayouts || ancestorLayouts.contains(layout) ||
300 ArrayUtil.contains(expandedLayoutIds, layout.getLayoutId())) {
301
302 return true;
303 }
304
305 return false;
306 }
307
308 private static boolean _isPaginationEnabled(HttpServletRequest request) {
309 boolean paginate = ParamUtil.getBoolean(request, "paginate", true);
310
311 if (paginate &&
312 (PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN > -1)) {
313
314 return true;
315 }
316
317 return false;
318 }
319
320 private static List<Layout> _paginateLayouts(
321 HttpServletRequest request, long groupId, boolean privateLayout,
322 long parentLayoutId, List<Layout> layouts, String treeId)
323 throws Exception {
324
325 if (!_isPaginationEnabled(request)) {
326 return layouts;
327 }
328
329 HttpSession session = request.getSession();
330
331 int loadedLayoutsCount = _getLoadedLayoutsCount(
332 session, groupId, privateLayout, parentLayoutId, treeId);
333
334 int start = ParamUtil.getInteger(request, "start");
335
336 start = Math.max(0, Math.min(start, layouts.size()));
337
338 int end = ParamUtil.getInteger(
339 request, "end",
340 start + PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN);
341
342 if (loadedLayoutsCount > end) {
343 end = loadedLayoutsCount;
344 }
345
346 end = Math.max(start, Math.min(end, layouts.size()));
347
348 if (_log.isDebugEnabled()) {
349 StringBundler sb = new StringBundler(7);
350
351 sb.append("_paginateLayouts(loadedLayoutsCount=");
352 sb.append(loadedLayoutsCount);
353 sb.append(", start=");
354 sb.append(start);
355 sb.append(", end=");
356 sb.append(end);
357 sb.append(StringPool.CLOSE_PARENTHESIS);
358
359 _log.debug(sb.toString());
360 }
361
362 return layouts.subList(start, end);
363 }
364
365 private static String _toJSON(
366 HttpServletRequest request, long groupId,
367 LayoutTreeNodes layoutTreeNodes)
368 throws Exception {
369
370 if (_log.isDebugEnabled()) {
371 StringBundler sb = new StringBundler(5);
372
373 sb.append("_toJSON(groupId=");
374 sb.append(groupId);
375 sb.append(", layoutTreeNodes=");
376 sb.append(layoutTreeNodes);
377 sb.append(StringPool.CLOSE_PARENTHESIS);
378
379 _log.debug(sb.toString());
380 }
381
382 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
383 WebKeys.THEME_DISPLAY);
384
385 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
386
387 boolean hasManageLayoutsPermission = GroupPermissionUtil.contains(
388 themeDisplay.getPermissionChecker(), groupId,
389 ActionKeys.MANAGE_LAYOUTS);
390
391 for (LayoutTreeNode layoutTreeNode : layoutTreeNodes) {
392 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
393
394 String childrenJSON = _toJSON(
395 request, groupId, layoutTreeNode.getChildLayoutTreeNodes());
396
397 jsonObject.put(
398 "children", JSONFactoryUtil.createJSONObject(childrenJSON));
399
400 Layout layout = layoutTreeNode.getLayout();
401
402 jsonObject.put("contentDisplayPage", layout.isContentDisplayPage());
403 jsonObject.put("friendlyURL", layout.getFriendlyURL());
404
405 if (layout instanceof VirtualLayout) {
406 VirtualLayout virtualLayout = (VirtualLayout)layout;
407
408 jsonObject.put("groupId", virtualLayout.getSourceGroupId());
409 }
410 else {
411 jsonObject.put("groupId", layout.getGroupId());
412 }
413
414 jsonObject.put("hasChildren", layout.hasChildren());
415 jsonObject.put("layoutId", layout.getLayoutId());
416 jsonObject.put("name", layout.getName(themeDisplay.getLocale()));
417
418 LayoutType layoutType = layout.getLayoutType();
419
420 jsonObject.put("parentable", layoutType.isParentable());
421
422 jsonObject.put("parentLayoutId", layout.getParentLayoutId());
423 jsonObject.put("plid", layout.getPlid());
424 jsonObject.put("priority", layout.getPriority());
425 jsonObject.put("privateLayout", layout.isPrivateLayout());
426 jsonObject.put("regularURL", layout.getRegularURL(request));
427 jsonObject.put(
428 "sortable",
429 hasManageLayoutsPermission &&
430 SitesUtil.isLayoutSortable(layout));
431 jsonObject.put("type", layout.getType());
432 jsonObject.put(
433 "updateable",
434 LayoutPermissionUtil.contains(
435 themeDisplay.getPermissionChecker(), layout,
436 ActionKeys.UPDATE));
437 jsonObject.put("uuid", layout.getUuid());
438
439 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
440 layout);
441
442 if (layoutRevision != null) {
443 long layoutSetBranchId = layoutRevision.getLayoutSetBranchId();
444
445 if (StagingUtil.isIncomplete(layout, layoutSetBranchId)) {
446 jsonObject.put("incomplete", true);
447 }
448
449 LayoutSetBranch layoutSetBranch =
450 LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
451 layoutSetBranchId);
452
453 LayoutBranch layoutBranch = layoutRevision.getLayoutBranch();
454
455 if (!layoutBranch.isMaster()) {
456 jsonObject.put(
457 "layoutBranchId", layoutBranch.getLayoutBranchId());
458 jsonObject.put("layoutBranchName", layoutBranch.getName());
459 }
460
461 if (layoutRevision.isHead()) {
462 jsonObject.put("layoutRevisionHead", true);
463 }
464
465 jsonObject.put(
466 "layoutRevisionId", layoutRevision.getLayoutRevisionId());
467 jsonObject.put("layoutSetBranchId", layoutSetBranchId);
468 jsonObject.put(
469 "layoutSetBranchName", layoutSetBranch.getName());
470 }
471
472 jsonArray.put(jsonObject);
473 }
474
475 JSONObject responseJSONObject = JSONFactoryUtil.createJSONObject();
476
477 responseJSONObject.put("layouts", jsonArray);
478 responseJSONObject.put("total", layoutTreeNodes.getTotal());
479
480 return responseJSONObject.toString();
481 }
482
483 private static final Log _log = LogFactoryUtil.getLog(
484 LayoutsTreeUtil.class);
485
486 private static class LayoutTreeNode {
487
488 public LayoutTreeNode(Layout layout) {
489 _layout = layout;
490 }
491
492 public LayoutTreeNodes getChildLayoutTreeNodes() {
493 return _childLayoutTreeNodes;
494 }
495
496 public Layout getLayout() {
497 return _layout;
498 }
499
500 public void setChildLayoutTreeNodes(
501 LayoutTreeNodes childLayoutTreeNodes) {
502
503 _childLayoutTreeNodes = childLayoutTreeNodes;
504 }
505
506 @Override
507 public String toString() {
508 StringBundler sb = new StringBundler(5);
509
510 sb.append("{childLayoutTreeNodes=");
511 sb.append(_childLayoutTreeNodes);
512 sb.append(", layout=");
513 sb.append(_layout);
514 sb.append(StringPool.CLOSE_CURLY_BRACE);
515
516 return sb.toString();
517 }
518
519 private LayoutTreeNodes _childLayoutTreeNodes = new LayoutTreeNodes();
520 private final Layout _layout;
521
522 }
523
524 private static class LayoutTreeNodes implements Iterable<LayoutTreeNode> {
525
526 public LayoutTreeNodes() {
527 _layoutTreeNodesList = new ArrayList<>();
528 }
529
530 public LayoutTreeNodes(
531 List<LayoutTreeNode> layoutTreeNodesList, int total) {
532
533 _layoutTreeNodesList = layoutTreeNodesList;
534 _total = total;
535 }
536
537 public void addAll(LayoutTreeNodes layoutTreeNodes) {
538 _layoutTreeNodesList.addAll(
539 layoutTreeNodes.getLayoutTreeNodesList());
540
541 _total += layoutTreeNodes.getTotal();
542 }
543
544 public List<LayoutTreeNode> getLayoutTreeNodesList() {
545 return _layoutTreeNodesList;
546 }
547
548 public int getTotal() {
549 return _total;
550 }
551
552 @Override
553 public Iterator<LayoutTreeNode> iterator() {
554 return _layoutTreeNodesList.iterator();
555 }
556
557 @Override
558 public String toString() {
559 StringBundler sb = new StringBundler(5);
560
561 sb.append("{layoutTreeNodesList=");
562 sb.append(_layoutTreeNodesList);
563 sb.append(", total=");
564 sb.append(_total);
565 sb.append(StringPool.CLOSE_CURLY_BRACE);
566
567 return sb.toString();
568 }
569
570 private final List<LayoutTreeNode> _layoutTreeNodesList;
571 private int _total;
572
573 }
574
575 }