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