要求很简单。有人使用一些标签(TagA,TagB)发布JournalArticle。在其他页面(布局)上,我们有AssetPublisher端口,显示所有带有这些标签的JournalArticles(例如TagA或TagB)。问题是,如何使这个布局成为程序化的?
答案 0 :(得分:2)
我用递归DynamicQuery
解决它,享受:
public static Set<Layout> getLayoutsWithThisTags(SortedSet<String> tags) throws SystemException, PortalException {
Set<Layout> layouts = new HashSet<Layout>();
//build DynamicQuery that contains "assetTags" as "queryName0", see configuration of AssetPublisher
DynamicQuery query = DynamicQueryFactoryUtil.forClass(com.liferay.portal.model.PortletPreferences.class, PortalClassLoaderUtil.getClassLoader())
.add(PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryName0</name><value>assetTags</value></preference>%"))
.add(getTagConditions(tags));
Set<PortletPreferences> preferences = new HashSet<PortletPreferences>(PortletPreferencesLocalServiceUtil.dynamicQuery(query));
for (PortletPreferences portletPreferences : preferences) {
long plid = portletPreferences.getPlid();
layouts.add(LayoutLocalServiceUtil.getLayout(plid));
}
return layouts;
}
private static Criterion getTagConditions(SortedSet<String> tags) {
//create recursive OR-Criterion that contains any of the tags
Criterion criterion = RestrictionsFactoryUtil.or(
PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.first() +"</value>%"),
(tags.size() > 2) ? getTagConditions(tail(tags)) :
PropertyFactoryUtil.forName("preferences").like("%<preference><name>queryValues0</name>%<value>" + tags.last() +"</value>%"));
return criterion;
}
private static SortedSet<String> tail(SortedSet<String> tags) {
tags.remove(tags.first());
return tags;
}
对于包含250页(布局)的Portal,此代码需要12毫秒。
答案 1 :(得分:0)
突然间我想起了这样的事情:-)
List assetPublisherLayouts;
List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout);
for (Layout layout : layouts)
{
if(layout.getTypeSettings().contains("101_INSTANCE")) {
assetPublisherLayouts.add(layout);
}
}
虽然101是资产发布者的protlet ID,但它是可实例化的..