Liferay:如何在AssetPublisher Portlet中找到具有特定日志文章的所有版面?
要求很简单。有人发布了一篇带有一些标签(TagA,TagB)的日志文章。在其他页面(布局)上,我们有AssetPublisher端口,显示所有带有这些标记(例如TagA或TagB)的日志文章。问题是,如何让这个布局程序实用呢?我突然想到了这一点:-)Liferay:如何在AssetPublisher Portlet中找到具有特定日志文章的所有版面?,liferay,Liferay,要求很简单。有人发布了一篇带有一些标签(TagA,TagB)的日志文章。在其他页面(布局)上,我们有AssetPublisher端口,显示所有带有这些标记(例如TagA或TagB)的日志文章。问题是,如何让这个布局程序实用呢?我突然想到了这一点:-) 列出资产发布器布局; 列表布局=LayoutLocalServiceUtil.getLayouts(groupId,privateLayout); 用于(布局:布局) { if(layout.getTypeSettings()包含(“101_实例
列出资产发布器布局;
列表布局=LayoutLocalServiceUtil.getLayouts(groupId,privateLayout);
用于(布局:布局)
{
if(layout.getTypeSettings()包含(“101_实例”)){
assetPublisherLayouts.add(布局);
}
}
101是Asset publisher的Prolet ID,可实例化 我可以想出两种方法:
DynamicQuery
获取包含Asset Publisher
portlet的Layouts
,然后处理为具有Asset Publisher
的TagA
和TagB
的特定版面检索的Layout
列表代码可能是这样的(免责声明:它只是伪代码):-):
layoutDynamicQuery.add(RestrictionFactoryUtil.ilike(“typeSettings”,“%101\u INSTANCE%”);
List layoutList=LayoutLocalServiceUtil.dynamicQuery(layoutDynamicQuery);
List finalLayoutList=newarraylist();
用于(布局:布局列表){
//1)获取此布局的PortletID
//2)获取AssetPublisher portlet实例id的相关PortletPreferences,可以使用PortletPreferencesLocalServiceUtil
//3)检查检索到的首选项中是否存在标签(TagA和TagB)。
//4)如果第3点为真,则:finalLayoutList.add(布局);
}
自定义sql
在单个复杂sql查询中获取布局
s,方法是连接/子查询所需的表,如AssetTags
、Layout
、PortletPreferences
等希望这能有所帮助。我用递归
动态查询解决它,享受:
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;
}
publicstaticset getLayoutsWithThisTags(SortedSet标记)引发系统异常,PortalException{
Set layouts=新的HashSet();
//构建包含“assetTags”作为“queryName0”的DynamicQuery,请参阅AssetPublisher的配置
DynamicQuery query=DynamicQueryFactoryUtil.forClass(com.liferay.portal.model.PortletPreferences.class,PortalClassLoaderUtil.getClassLoader())
.add(PropertyFactoryUtil.forName(“首选项”).like(“%queryName0assetTags%”)
.add(getTagConditions(tags));
Set preferences=newhashset(PortletPreferencesLocalServiceUtil.dynamicQuery(查询));
对于(PortletPreferences PortletPreferences:preferences){
long plid=portletPreferences.getPlid();
layouts.add(LayoutLocalServiceUtil.getLayout(plid));
}
返回布局;
}
专用静态标准getTagConditions(SortedSet标签){
//创建包含任何标记的递归或条件
标准=限制FactoryUtil.或(
PropertyFactoryUtil.forName(“首选项”)。例如(“%queryValues0%”+tags.first()+“%”),
(tags.size()>2)?获取条件(tail(tags)):
PropertyFactoryUtil.forName(“首选项”)。例如(“%queryValues0%”+tags.last()+“%”);
返回准则;
}
专用静态分拣集尾部(分拣集标签){
tags.remove(tags.first());
返回标签;
}
对于具有250页(布局)的门户,此代码需要12毫秒。我只查找配置了特定标记的布局(AssetPublisher),像TagA或TagB一样。我不完全确定这是否可行,因为数据库中没有直接的API访问PortletProperties表,该表存储了诸如为AssetPublisher显示哪些标记之类的信息。您必须查看Liferay源代码,以了解它们如何在内部实现对此表的访问。我认为您可能需要采用自定义sql
的方式来连接/子查询表,如PortletPreferences、Layout、AssetEntry、AssetTags、JournalArticle。这是一次完成,而不是多次循环。哇!递归的创新使用。此代码layouts.add(LayoutLocalServiceUtil.getLayout(plid))可以通过收集所有plid
s,然后只触发一个查询来获得所有布局来优化code>。但是,对于Oracle,它最多只能接受1000个条目(在in子句中)
。我认为这可以通过使用for
循环而不是递归来实现。但答案很好。谢谢
layoutDynamicQuery.add(RestrictionFactoryUtil.ilike("typeSettings","%101_INSTANCE%"));
List<Layout> layoutList = LayoutLocalServiceUtil.dynamicQuery(layoutDynamicQuery);
List<Layout> finalLayoutList = new ArrayList<Layout>();
for (Layout layout : layoutList) {
// 1) fetch portletIds for this layout
// 2) fetch relevant PortletPreferences for the instance-id for the AssetPublisher portlet, can use PortletPreferencesLocalServiceUtil
// 3) Check if the tags (TagA & TagB) are present in the preference retrieved.
// 4) if point-3 is true then: finalLayoutList.add(layout);
}
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;
}