要件は簡単です。誰かがいくつかのタグ(TagA、TagB)を含むJournalArticleを公開しています。他のページ(レイアウト)には、それらのタグ(TagAやTagBなど)を持つすべてのJournalArticlesを表示するAssetPublisherポートがあります。問題は、このレイアウトをプログラムで取得する方法です。
3994 次
3 に答える
2
私は recursive でそれを解決し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 ページ (レイアウト) のポータルの場合、このコードには 12 ミリ秒が必要です。
于 2012-08-20T13:31:06.177 に答える
0
次の 2 つの方法が考えられます。
ポートレットを含む
DynamicQuery
フェッチに使用し、 &を持つ特定のレイアウト用に取得したリストを処理します。 コードは次のようになります (免責事項: これは単なる疑似コードです:-) ):Layouts
Asset Publisher
Layout
Asset Publisher
TagA
TagB
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); }
- 、などの必要なテーブルを結合/サブクエリすることにより、単一の複雑な SQL クエリで
custom-sql
をフェッチするために使用します。Layout
AssetTags
Layout
PortletPreferences
これは liferay の一般的な要件シナリオではないため、これを行う直接的な方法がないことは明らかです。
これが何らかの助けになることを願っています。
于 2012-08-17T10:12:35.997 に答える
0
ふと、これが頭に浮かびました:-)
List assetPublisherLayouts;
List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(groupId, privateLayout);
for (Layout layout : layouts)
{
if(layout.getTypeSettings().contains("101_INSTANCE")) {
assetPublisherLayouts.add(layout);
}
}
101 は Asset Publisher の protlet ID であり、インスタンス化可能です。
于 2012-08-16T13:49:45.663 に答える