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.staging.LayoutStagingUtil;
022 import com.liferay.portal.kernel.staging.StagingUtil;
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.User;
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.PortalUtil;
043 import com.liferay.portal.util.PropsValues;
044 import com.liferay.portal.util.SessionClicks;
045 import com.liferay.portlet.sites.util.SitesUtil;
046
047 import java.util.ArrayList;
048 import java.util.Collections;
049 import java.util.Iterator;
050 import java.util.List;
051
052 import javax.servlet.http.HttpServletRequest;
053 import javax.servlet.http.HttpSession;
054
055
063 public class LayoutsTreeUtil {
064
065 public static String getLayoutsJSON(
066 HttpServletRequest request, long groupId, boolean privateLayout,
067 long parentLayoutId, boolean incomplete, String treeId)
068 throws Exception {
069
070 return getLayoutsJSON(
071 request, groupId, privateLayout, parentLayoutId, null, incomplete,
072 treeId);
073 }
074
075 public static String getLayoutsJSON(
076 HttpServletRequest request, long groupId, boolean privateLayout,
077 long parentLayoutId, long[] expandedLayoutIds, boolean incomplete,
078 String treeId)
079 throws Exception {
080
081 LayoutTreeNodes layoutTreeNodes = _getLayoutTreeNodes(
082 request, groupId, privateLayout, parentLayoutId, incomplete,
083 expandedLayoutIds, treeId);
084
085 return _toJSON(request, groupId, layoutTreeNodes);
086 }
087
088 public static String getLayoutsJSON(
089 HttpServletRequest request, long groupId, String treeId)
090 throws Exception {
091
092 LayoutTreeNodes layoutTreeNodes = new LayoutTreeNodes();
093
094 layoutTreeNodes.addAll(
095 _getLayoutTreeNodes(
096 request, groupId, true,
097 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, false, null, treeId));
098 layoutTreeNodes.addAll(
099 _getLayoutTreeNodes(
100 request, groupId, false,
101 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, false, null, treeId));
102
103 return _toJSON(request, groupId, layoutTreeNodes);
104 }
105
106 private static List<Layout> _getAncestorLayouts(HttpServletRequest request)
107 throws Exception {
108
109 long selPlid = ParamUtil.getLong(request, "selPlid");
110
111 if (selPlid == 0) {
112 return Collections.emptyList();
113 }
114
115 List<Layout> ancestorLayouts = LayoutServiceUtil.getAncestorLayouts(
116 selPlid);
117
118 Layout layout = LayoutLocalServiceUtil.getLayout(selPlid);
119
120 ancestorLayouts.add(layout);
121
122 return ancestorLayouts;
123 }
124
125 private static LayoutTreeNodes _getLayoutTreeNodes(
126 HttpServletRequest request, long groupId, boolean privateLayout,
127 long parentLayoutId, boolean incomplete, long[] expandedLayoutIds,
128 String treeId)
129 throws Exception {
130
131 List<LayoutTreeNode> layoutTreeNodes = new ArrayList<LayoutTreeNode>();
132
133 List<Layout> ancestorLayouts = _getAncestorLayouts(request);
134
135 List<Layout> layouts = LayoutServiceUtil.getLayouts(
136 groupId, privateLayout, parentLayoutId, incomplete,
137 QueryUtil.ALL_POS, QueryUtil.ALL_POS);
138
139 for (Layout layout :
140 _paginateLayouts(
141 request, groupId, privateLayout, parentLayoutId, layouts,
142 treeId)) {
143
144 LayoutTreeNode layoutTreeNode = new LayoutTreeNode(layout);
145
146 LayoutTreeNodes childLayoutTreeNodes = null;
147
148 if (_isExpandableLayout(
149 request, ancestorLayouts, expandedLayoutIds, layout)) {
150
151 if (layout instanceof VirtualLayout) {
152 VirtualLayout virtualLayout = (VirtualLayout)layout;
153
154 childLayoutTreeNodes = _getLayoutTreeNodes(
155 request, virtualLayout.getSourceGroupId(),
156 virtualLayout.isPrivateLayout(),
157 virtualLayout.getLayoutId(), incomplete,
158 expandedLayoutIds, treeId);
159 }
160 else {
161 childLayoutTreeNodes = _getLayoutTreeNodes(
162 request, groupId, layout.isPrivateLayout(),
163 layout.getLayoutId(), incomplete, expandedLayoutIds,
164 treeId);
165 }
166 }
167 else {
168 int childLayoutsCount = LayoutServiceUtil.getLayoutsCount(
169 groupId, privateLayout, layout.getLayoutId());
170
171 childLayoutTreeNodes = new LayoutTreeNodes(
172 new ArrayList<LayoutTreeNode>(), childLayoutsCount);
173 }
174
175 layoutTreeNode.setChildLayoutTreeNodes(childLayoutTreeNodes);
176
177 layoutTreeNodes.add(layoutTreeNode);
178 }
179
180 return new LayoutTreeNodes(layoutTreeNodes, layouts.size());
181 }
182
183 private static int _getLoadedLayoutsCount(
184 HttpSession session, long groupId, boolean privateLayout,
185 long layoutId, String treeId)
186 throws Exception {
187
188 StringBundler sb = new StringBundler(7);
189
190 sb.append(treeId);
191 sb.append(StringPool.COLON);
192 sb.append(groupId);
193 sb.append(StringPool.COLON);
194 sb.append(privateLayout);
195 sb.append(StringPool.COLON);
196 sb.append("Pagination");
197
198 String paginationJSON = SessionClicks.get(
199 session, sb.toString(), JSONFactoryUtil.getNullJSON());
200
201 JSONObject paginationJSONObject = JSONFactoryUtil.createJSONObject(
202 paginationJSON);
203
204 return paginationJSONObject.getInt(String.valueOf(layoutId), 0);
205 }
206
207 private static boolean _isExpandableLayout(
208 HttpServletRequest request, List<Layout> ancestorLayouts,
209 long[] expandedLayoutIds, Layout layout) {
210
211 boolean expandParentLayouts = ParamUtil.getBoolean(
212 request, "expandParentLayouts");
213
214 if (expandParentLayouts || ancestorLayouts.contains(layout) ||
215 ArrayUtil.contains(expandedLayoutIds, layout.getLayoutId())) {
216
217 return true;
218 }
219
220 return false;
221 }
222
223 private static boolean _isPaginationEnabled(HttpServletRequest request) {
224 boolean paginate = ParamUtil.getBoolean(request, "paginate", true);
225
226 if (paginate &&
227 (PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN > -1)) {
228
229 return true;
230 }
231
232 return false;
233 }
234
235 private static List<Layout> _paginateLayouts(
236 HttpServletRequest request, long groupId, boolean privateLayout,
237 long parentLayoutId, List<Layout> layouts, String treeId)
238 throws Exception {
239
240 if (!_isPaginationEnabled(request)) {
241 return layouts;
242 }
243
244 HttpSession session = request.getSession();
245
246 int loadedLayoutsCount = _getLoadedLayoutsCount(
247 session, groupId, privateLayout, parentLayoutId, treeId);
248
249 int start = ParamUtil.getInteger(request, "start");
250
251 start = Math.max(0, Math.min(start, layouts.size()));
252
253 int end = ParamUtil.getInteger(
254 request, "end",
255 start + PropsValues.LAYOUT_MANAGE_PAGES_INITIAL_CHILDREN);
256
257 if (loadedLayoutsCount > end) {
258 end = loadedLayoutsCount;
259 }
260
261 end = Math.max(start, Math.min(end, layouts.size()));
262
263 return layouts.subList(start, end);
264 }
265
266 private static String _toJSON(
267 HttpServletRequest request, long groupId,
268 LayoutTreeNodes layoutTreeNodes)
269 throws Exception {
270
271 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
272 WebKeys.THEME_DISPLAY);
273
274 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
275
276 boolean hasManageLayoutsPermission = GroupPermissionUtil.contains(
277 themeDisplay.getPermissionChecker(), groupId,
278 ActionKeys.MANAGE_LAYOUTS);
279
280 for (LayoutTreeNode layoutTreeNode : layoutTreeNodes) {
281 JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
282
283 String childrenJSON = _toJSON(
284 request, groupId, layoutTreeNode.getChildLayoutTreeNodes());
285
286 jsonObject.put(
287 "children", JSONFactoryUtil.createJSONObject(childrenJSON));
288
289 Layout layout = layoutTreeNode.getLayout();
290
291 jsonObject.put("contentDisplayPage", layout.isContentDisplayPage());
292 jsonObject.put("friendlyURL", layout.getFriendlyURL());
293
294 if (layout instanceof VirtualLayout) {
295 VirtualLayout virtualLayout = (VirtualLayout)layout;
296
297 jsonObject.put("groupId", virtualLayout.getSourceGroupId());
298 }
299 else {
300 jsonObject.put("groupId", layout.getGroupId());
301 }
302
303 jsonObject.put("hasChildren", layout.hasChildren());
304 jsonObject.put("layoutId", layout.getLayoutId());
305 jsonObject.put("name", layout.getName(themeDisplay.getLocale()));
306 jsonObject.put("parentable", PortalUtil.isLayoutParentable(layout));
307 jsonObject.put("parentLayoutId", layout.getParentLayoutId());
308 jsonObject.put("plid", layout.getPlid());
309 jsonObject.put("priority", layout.getPriority());
310 jsonObject.put("privateLayout", layout.isPrivateLayout());
311 jsonObject.put(
312 "sortable",
313 hasManageLayoutsPermission &&
314 SitesUtil.isLayoutSortable(layout));
315 jsonObject.put("type", layout.getType());
316 jsonObject.put(
317 "updateable",
318 LayoutPermissionUtil.contains(
319 themeDisplay.getPermissionChecker(), layout,
320 ActionKeys.UPDATE));
321 jsonObject.put("uuid", layout.getUuid());
322
323 LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
324 layout);
325
326 if (layoutRevision != null) {
327 User user = themeDisplay.getUser();
328
329 long recentLayoutSetBranchId =
330 StagingUtil.getRecentLayoutSetBranchId(
331 user, layout.getLayoutSet().getLayoutSetId());
332
333 if (StagingUtil.isIncomplete(layout, recentLayoutSetBranchId)) {
334 jsonObject.put("incomplete", true);
335 }
336
337 long layoutSetBranchId = layoutRevision.getLayoutSetBranchId();
338
339 LayoutSetBranch layoutSetBranch =
340 LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
341 layoutSetBranchId);
342
343 LayoutBranch layoutBranch = layoutRevision.getLayoutBranch();
344
345 if (!layoutBranch.isMaster()) {
346 jsonObject.put(
347 "layoutBranchId", layoutBranch.getLayoutBranchId());
348 jsonObject.put("layoutBranchName", layoutBranch.getName());
349 }
350
351 if (layoutRevision.isHead()) {
352 jsonObject.put("layoutRevisionHead", true);
353 }
354
355 jsonObject.put(
356 "layoutRevisionId", layoutRevision.getLayoutRevisionId());
357 jsonObject.put("layoutSetBranchId", layoutSetBranchId);
358 jsonObject.put(
359 "layoutSetBranchName", layoutSetBranch.getName());
360 }
361
362 jsonArray.put(jsonObject);
363 }
364
365 JSONObject responseJSONObject = JSONFactoryUtil.createJSONObject();
366
367 responseJSONObject.put("layouts", jsonArray);
368 responseJSONObject.put("total", layoutTreeNodes.getTotal());
369
370 return responseJSONObject.toString();
371 }
372
373 private static class LayoutTreeNode {
374
375 public LayoutTreeNode(Layout layout) {
376 _layout = layout;
377 }
378
379 public Layout getLayout() {
380 return _layout;
381 }
382
383 public LayoutTreeNodes getChildLayoutTreeNodes() {
384 return _childLayoutTreeNodes;
385 }
386
387 public void setChildLayoutTreeNodes(
388 LayoutTreeNodes childLayoutTreeNodes) {
389
390 _childLayoutTreeNodes = childLayoutTreeNodes;
391 }
392
393 private LayoutTreeNodes _childLayoutTreeNodes = new LayoutTreeNodes();
394 private Layout _layout;
395
396 }
397
398 private static class LayoutTreeNodes implements Iterable<LayoutTreeNode> {
399
400 public LayoutTreeNodes() {
401 }
402
403 public LayoutTreeNodes(
404 List<LayoutTreeNode> layoutTreeNodesList, int total) {
405
406 _layoutTreeNodesList = layoutTreeNodesList;
407 _total = total;
408 }
409
410 public void addAll(LayoutTreeNodes layoutTreeNodes) {
411 _layoutTreeNodesList.addAll(
412 layoutTreeNodes.getLayoutTreeNodesList());
413
414 _total += layoutTreeNodes.getTotal();
415 }
416
417 public int getTotal() {
418 return _total;
419 }
420
421 public List<LayoutTreeNode> getLayoutTreeNodesList() {
422 return _layoutTreeNodesList;
423 }
424
425 @Override
426 public Iterator<LayoutTreeNode> iterator() {
427 return _layoutTreeNodesList.iterator();
428 }
429
430 private List<LayoutTreeNode> _layoutTreeNodesList =
431 new ArrayList<LayoutTreeNode>();
432 private int _total;
433
434 }
435
436 }