001
014
015 package com.liferay.portal.util;
016
017 import com.liferay.portal.kernel.cache.thread.local.Lifecycle;
018 import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCache;
019 import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCacheManager;
020 import com.liferay.portal.kernel.util.LocaleUtil;
021 import com.liferay.portal.kernel.util.ObjectValuePair;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.model.Layout;
026 import com.liferay.portal.model.LayoutConstants;
027 import com.liferay.portal.model.impl.LayoutImpl;
028 import com.liferay.portal.service.LayoutLocalServiceUtil;
029
030 import java.util.ArrayList;
031 import java.util.Deque;
032 import java.util.LinkedList;
033 import java.util.List;
034 import java.util.ListIterator;
035 import java.util.Locale;
036
037
041 public class LayoutListUtil {
042
043 public static List<LayoutDescription> getLayoutDescriptions(
044 long groupId, boolean privateLayout, String rootNodeName,
045 Locale locale) {
046
047 ThreadLocalCache<List<LayoutDescription>> threadLocalCache =
048 ThreadLocalCacheManager.getThreadLocalCache(
049 Lifecycle.REQUEST, LayoutListUtil.class.getName());
050
051 String cacheKey = buildCacheKey(
052 groupId, privateLayout, rootNodeName, locale);
053
054 List<LayoutDescription> layoutDescriptions = threadLocalCache.get(
055 cacheKey);
056
057 if (layoutDescriptions == null) {
058 layoutDescriptions = doGetLayoutDescriptions(
059 groupId, privateLayout, rootNodeName, locale);
060
061 threadLocalCache.put(cacheKey, layoutDescriptions);
062 }
063
064 return layoutDescriptions;
065 }
066
067 protected static String buildCacheKey(
068 long groupId, boolean privateLayout, String rootNodeName,
069 Locale locale) {
070
071 StringBundler sb = new StringBundler(7);
072
073 sb.append(StringUtil.toHexString(groupId));
074 sb.append(StringPool.POUND);
075 sb.append(privateLayout);
076 sb.append(StringPool.POUND);
077 sb.append(rootNodeName);
078 sb.append(StringPool.POUND);
079 sb.append(LocaleUtil.toLanguageId(locale));
080
081 return sb.toString();
082 }
083
084 protected static List<LayoutDescription> doGetLayoutDescriptions(
085 long groupId, boolean privateLayout, String rootNodeName,
086 Locale locale) {
087
088 List<LayoutDescription> layoutDescriptions = new ArrayList<>();
089
090 List<Layout> layouts = new ArrayList<>(
091 LayoutLocalServiceUtil.getLayouts(groupId, privateLayout));
092
093 Deque<ObjectValuePair<Layout, Integer>> deque = new LinkedList<>();
094
095 Layout rootLayout = new LayoutImpl();
096
097 rootLayout.setPlid(LayoutConstants.DEFAULT_PLID);
098 rootLayout.setName(rootNodeName);
099
100 deque.push(new ObjectValuePair<Layout, Integer>(rootLayout, 0));
101
102 ObjectValuePair<Layout, Integer> objectValuePair = null;
103
104 while ((objectValuePair = deque.pollFirst()) != null) {
105 Layout currentLayout = objectValuePair.getKey();
106
107 Integer currentDepth = objectValuePair.getValue();
108
109 layoutDescriptions.add(
110 new LayoutDescription(
111 currentLayout.getPlid(), currentLayout.getName(locale),
112 currentDepth));
113
114 ListIterator<Layout> listIterator = layouts.listIterator(
115 layouts.size());
116
117 while (listIterator.hasPrevious()) {
118 Layout previousLayout = listIterator.previous();
119
120 if (previousLayout.getParentLayoutId() ==
121 currentLayout.getLayoutId()) {
122
123 listIterator.remove();
124
125 deque.push(
126 new ObjectValuePair<Layout, Integer>(
127 previousLayout, currentDepth + 1));
128 }
129 }
130 }
131
132 return layoutDescriptions;
133 }
134
135 }