Skip to content
Snippets Groups Projects
Commit df058071 authored by Guillaume Delhumeau's avatar Guillaume Delhumeau
Browse files

XWIKI-15343: Add a filter to handle page tags.

parent 70e9cac0
No related branches found
No related tags found
No related merge requests found
Showing
with 103 additions and 32 deletions
......@@ -314,6 +314,32 @@
"methodName": "getNotificationsRSS",
"elementKind": "method",
"justification": "Adding a parameter to a REST API is actually not a blocker."
},
{
"code": "java.method.numberOfParametersChanged",
"old": "method javax.ws.rs.core.Response org.xwiki.notifications.rest.NotificationsResource::getNotifications(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws java.lang.Exception",
"new": "method javax.ws.rs.core.Response org.xwiki.notifications.rest.NotificationsResource::getNotifications(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws java.lang.Exception",
"package": "org.xwiki.notifications.rest",
"classQualifiedName": "org.xwiki.notifications.rest.NotificationsResource",
"classSimpleName": "NotificationsResource",
"methodName": "getNotifications",
"oldArchive": "org.xwiki.platform:xwiki-platform-notifications-rest:jar:10.7",
"newArchive": "org.xwiki.platform:xwiki-platform-notifications-rest:jar:10.9-SNAPSHOT",
"elementKind": "method",
"justification": "Adding a parameter to a REST API is actually not a blocker."
},
{
"code": "java.method.numberOfParametersChanged",
"old": "method java.lang.String org.xwiki.notifications.rest.NotificationsResource::getNotificationsRSS(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws java.lang.Exception",
"new": "method java.lang.String org.xwiki.notifications.rest.NotificationsResource::getNotificationsRSS(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws java.lang.Exception",
"package": "org.xwiki.notifications.rest",
"classQualifiedName": "org.xwiki.notifications.rest.NotificationsResource",
"classSimpleName": "NotificationsResource",
"methodName": "getNotificationsRSS",
"oldArchive": "org.xwiki.platform:xwiki-platform-notifications-rest:jar:10.7",
"newArchive": "org.xwiki.platform:xwiki-platform-notifications-rest:jar:10.9-SNAPSHOT",
"elementKind": "method",
"justification": "Adding a parameter to a REST API is actually not a blocker."
}
]
}
......
......@@ -59,7 +59,8 @@ Response getNotifications(
@QueryParam("displaySystemEvents") String displaySystemEvents,
@QueryParam("displayReadEvents") String displayReadEvents,
@QueryParam("displayReadStatus") String displayReadStatus,
@QueryParam("tags") String tags
@QueryParam("tags") String tags,
@QueryParam("currentWiki") String currentWiki
) throws Exception;
/**
......@@ -88,7 +89,8 @@ String getNotificationsRSS(
@QueryParam("displaySystemEvents") String displaySystemEvents,
@QueryParam("displayReadEvents") String displayReadEvents,
@QueryParam("displayReadStatus") String displayReadStatus,
@QueryParam("tags") String tags
@QueryParam("tags") String tags,
@QueryParam("currentWiki") String currentWiki
) throws Exception;
/**
......
......@@ -118,14 +118,16 @@ public Response getNotifications(
String displaySystemEvents,
String displayReadEvents,
String displayReadStatus,
String tags
String tags,
String currentWiki
) throws Exception
{
// 1. Get the events and render them as notifications.
List<CompositeEvent> events =
getCompositeEvents(useUserPreferences, userId, untilDate, blackList, pages, spaces, wikis,
users, count,
displayOwnEvents, displayMinorEvents, displaySystemEvents, displayReadEvents, tags);
displayOwnEvents, displayMinorEvents, displaySystemEvents, displayReadEvents, tags,
currentWiki);
Notifications notifications = new Notifications(
notificationsRenderer.renderNotifications(events, userId, TRUE.equals(displayReadStatus)));
......@@ -142,12 +144,13 @@ public Response getNotifications(
public String getNotificationsRSS(String useUserPreferences, String userId, String untilDate,
String blackList, String pages, String spaces, String wikis, String users, String count,
String displayOwnEvents, String displayMinorEvents, String displaySystemEvents, String displayReadEvents,
String displayReadStatus, String tags) throws Exception
String displayReadStatus, String tags, String currentWiki) throws Exception
{
List<CompositeEvent> events =
getCompositeEvents(useUserPreferences, userId, untilDate, blackList, pages, spaces, wikis,
users, count,
displayOwnEvents, displayMinorEvents, displaySystemEvents, displayReadEvents, tags);
displayOwnEvents, displayMinorEvents, displaySystemEvents, displayReadEvents, tags,
currentWiki);
SyndFeedOutput output = new SyndFeedOutput();
return output.outputString(notificationRSSManager.renderFeed(events));
}
......@@ -155,7 +158,7 @@ public String getNotificationsRSS(String useUserPreferences, String userId, Stri
private List<CompositeEvent> getCompositeEvents(String useUserPreferences, String userId,
String untilDate, String blackList, String pages, String spaces, String wikis, String users, String count,
String displayOwnEvents, String displayMinorEvents, String displaySystemEvents, String displayReadEvents,
String tags)
String tags, String currentWiki)
throws NotificationException, EventStreamException
{
NotificationParameters parameters = new NotificationParameters();
......@@ -178,7 +181,7 @@ private List<CompositeEvent> getCompositeEvents(String useUserPreferences, Strin
useUserPreferences(parameters);
} else {
dontUseUserPreferences(pages, spaces, wikis, users, parameters, displayOwnEvents, displayMinorEvents,
displaySystemEvents, displayReadEvents, tags);
displaySystemEvents, displayReadEvents, tags, currentWiki);
}
return getCompositeEvents(parameters);
......@@ -186,7 +189,7 @@ private List<CompositeEvent> getCompositeEvents(String useUserPreferences, Strin
private void dontUseUserPreferences(String pages, String spaces, String wikis, String users,
NotificationParameters parameters, String displayOwnEvents, String displayMinorEvents,
String displaySystemEvents, String displayReadEvents, String tags)
String displaySystemEvents, String displayReadEvents, String tags, String currentWiki)
throws NotificationException, EventStreamException
{
List<String> excludedFilters = new ArrayList<>();
......@@ -213,7 +216,7 @@ private void dontUseUserPreferences(String pages, String spaces, String wikis, S
handleWikisParameter(wikis, parameters);
usersParameterHandler.handleUsersParameter(users, parameters);
handleTagsParameter(parameters, tags);
handleTagsParameter(parameters, tags, currentWiki);
}
private void useUserPreferences(NotificationParameters parameters) throws NotificationException
......@@ -287,12 +290,12 @@ private void enableAllEventTypes(NotificationParameters parameters) throws Event
}
}
private void handleTagsParameter(NotificationParameters parameters, String tags)
private void handleTagsParameter(NotificationParameters parameters, String tags, String currentWiki)
{
if (StringUtils.isNotBlank(tags)) {
String[] tagArray = tags.split(",");
for (int i = 0; i < tagArray.length; ++i) {
parameters.filterPreferences.add(new TagNotificationFilterPreference(tagArray[i]));
parameters.filterPreferences.add(new TagNotificationFilterPreference(tagArray[i], currentWiki));
}
}
}
......
......@@ -20,14 +20,14 @@
package org.xwiki.notifications.rest.internal;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.xwiki.component.annotation.Component;
import org.xwiki.eventstream.Event;
import org.xwiki.model.reference.DocumentReference;
......@@ -38,6 +38,9 @@
import org.xwiki.notifications.filters.expression.EventProperty;
import org.xwiki.notifications.filters.expression.ExpressionNode;
import org.xwiki.notifications.preferences.NotificationPreference;
import org.xwiki.query.Query;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryManager;
import static org.xwiki.notifications.filters.expression.generics.ExpressionBuilder.value;
......@@ -55,6 +58,12 @@ public class TagNotificationFilter implements NotificationFilter
*/
public static final String NAME = "Tag Notification Filter";
@Inject
private QueryManager queryManager;
@Inject
private Logger logger;
@Override
public FilterPolicy filterEvent(Event event, DocumentReference user,
Collection<NotificationFilterPreference> filterPreferences, NotificationFormat format)
......@@ -93,16 +102,33 @@ public ExpressionNode filterExpression(DocumentReference user,
return null;
}
// This subquery can work only on the current wiki... but it's already that!
Map<String, Object> subQueryProperties = new HashMap<>();
subQueryProperties.put("tagList", enabledTags);
try {
Query query = queryManager.createQuery(
"SELECT DISTINCT doc.fullName FROM XWikiDocument doc, BaseObject obj, "
+ "DBStringListProperty tags JOIN tags.list AS item "
+ "WHERE obj.name = doc.fullName AND obj.className = 'XWiki.TagClass' "
+ "AND obj.id = tags.id.id AND tags.id.name = 'tags' AND lower(item) IN (:tagList)",
Query.HQL);
query.bindValue("tagList", enabledTags);
query.setWiki(findCurrentWiki(filterPreferences));
List<String> pagesHoldingTags = query.execute();
return value(EventProperty.PAGE).inStrings(pagesHoldingTags);
} catch (QueryException e) {
logger.warn("Failed to get the list of documents holding some tags.", e);
return null;
}
}
return value(EventProperty.PAGE).inSubQuery(
"SELECT DISTINCT doc.fullName FROM XWikiDocument doc, BaseObject obj, "
+ "DBStringListProperty tags JOIN tags.list AS item "
+ "WHERE obj.name = doc.fullName AND obj.className = 'XWiki.TagClass' "
+ "AND obj.id = tags.id.id AND tags.id.name = 'tags' AND lower(item) IN (:tagList)",
subQueryProperties);
private String findCurrentWiki(Collection<NotificationFilterPreference> filterPreferences)
{
for (NotificationFilterPreference nfp : filterPreferences) {
if (nfp.isEnabled() && nfp instanceof TagNotificationFilterPreference) {
TagNotificationFilterPreference pref = (TagNotificationFilterPreference) nfp;
return pref.getCurrentWiki();
}
}
// Should never happen
return null;
}
@Override
......
......@@ -36,13 +36,17 @@ public class TagNotificationFilterPreference implements NotificationFilterPrefer
{
private String tag;
private String currentWiki;
/**
* Construct a TagNotificationFilterPreference for the given tag.
* @param tag the tag to watch
* @param currentWiki the current wiki (where the tags should be loaded)
*/
public TagNotificationFilterPreference(String tag)
public TagNotificationFilterPreference(String tag, String currentWiki)
{
this.tag = tag;
this.currentWiki = currentWiki;
}
/**
......@@ -53,6 +57,14 @@ public String getTag()
return tag;
}
/**
* @return the current wiki (where the tags should be loaded)
*/
public String getCurrentWiki()
{
return currentWiki;
}
@Override
public String getId()
{
......
......@@ -292,7 +292,8 @@
'pages': self.pages,
'users': self.users,
'displayReadStatus': self.displayReadStatus,
'tags': self.tags
'tags': self.tags,
'currentWiki': xm.documentReference.extractReferenceValue(XWiki.EntityType.WIKI)
};
if (untilDate) {
params.untilDate = untilDate;
......@@ -795,18 +796,18 @@
{{info}}
{{translation key="notifications.macro.whenNotView" /}}
{{/info}}
#set ($displayMacro = false)
#else
#else
#set ($users = $xcontext.macro.params.users)
#if ("$!xcontext.macro.params.displayWatchedUsersOnly" == 'true')
#set ($watchedUsers = $services.notification.watch.watchedUsers)
#if ($watchedUsers.isEmpty())
{{warning}}
{{translation key="notifications.macro.noWatchedUsers" /}}
{{/warning}}
#set ($displayMacro = false)
#else
#set ($users = $stringtool.join($services.notification.watch.watchedUsers, ','))
......@@ -818,9 +819,9 @@
#set ($discard = $xwiki.ssx.use('XWiki.Notifications.Code.NotificationsMacro'))
#set ($discard = $xwiki.ssx.use('XWiki.Notifications.Code.NotificationsDisplayerUIX'))
{{html clean="false"}}
&lt;div class="notifications-macro loading"
&lt;div class="notifications-macro loading"
data-userId="$!escapetool.xml($services.model.serialize($xcontext.userReference, 'default'))"
data-count="$!escapetool.xml($xcontext.macro.params.count)"
data-count="$!escapetool.xml($xcontext.macro.params.count)"
data-useUserPreferences="$!escapetool.xml($xcontext.macro.params.useUserPreferences)"
data-displayOwnEvents="$!escapetool.xml($xcontext.macro.params.displayOwnEvents)"
data-displayMinorEvents="$!escapetool.xml($xcontext.macro.params.displayMinorEvents)"
......@@ -850,6 +851,7 @@
#set ($rssURL = "${rssURL}&amp;users=$!escapetool.url($xcontext.macro.params.users)")
#set ($rssURL = "${rssURL}&amp;displayReadStatus=$!escapetool.url($xcontext.macro.params.displayReadStatus)")
#set ($rssURL = "${rssURL}&amp;tags=$!escapetool.url($xcontext.macro.params.tags)")
#set ($rssURL = "${rssURL}&amp;currentWiki=$!escapetool.url($services.wiki.currentWikiId)")
&lt;p class="notifications-macro-rss-link"&gt;&lt;a href="$rssURL" target="_blank"&gt;$services.icon.renderHTML('rss') $escapetool.xml($services.localization.render('notifications.rss.feedLink'))&lt;/a&gt;&lt;/p&gt;
#end
&lt;/div&gt;
......
......@@ -233,7 +233,7 @@
rendering.macro.notifications.parameter.displayRSSLink.name=Display RSS link
rendering.macro.notifications.parameter.displayRSSLink.description=Display a link to the RSS view of the current macro.
rendering.macro.notifications.parameter.tags.name=Tags
rendering.macro.notifications.parameter.tags.description=List of tags to consider (comma-separated). Ignored if "useUserPreferences" is set to "true".
rendering.macro.notifications.parameter.tags.description=List of tags to consider (comma-separated). It only works on the current wiki. Ignored if "useUserPreferences" is set to "true".
## Notifications Macro
notifications.macro.noWatchedUsers=You are not following anybody.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment