/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xpn.xwiki.plugin.watchlist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.plugin.activitystream.api.ActivityEventType;
import com.xpn.xwiki.plugin.activitystream.api.ActivityStream;
import com.xpn.xwiki.plugin.activitystream.api.ActivityStreamException;
import com.xpn.xwiki.plugin.activitystream.api.ActivityEvent;
import com.xpn.xwiki.plugin.activitystream.plugin.ActivityStreamPlugin;
/**
* Matcher for WatchList events. This class store all the events fired during a given interval. It also allows to
* perform a match between events and elements watched by a user.
*
* @version $Id: 705f372eecb6c9491a18fe3fdfd01a0d9fc687cf $
*/
@Deprecated
@SuppressWarnings("serial")
public class WatchListEventMatcher
{
/**
* Logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WatchListEventMatcher.class);
/**
* Events to match.
*/
private static final List<String> MATCHING_EVENT_TYPES = new ArrayList<String>()
{
{
add(ActivityEventType.CREATE);
add(ActivityEventType.UPDATE);
add(ActivityEventType.DELETE);
}
};
/**
* List of events which have occurred between the start date and the current time.
*/
private final List<WatchListEvent> events = new ArrayList<WatchListEvent>();
/**
* Constructor. Gets all the events fired during the interval between the given date and the current date.
*
* @param context the XWiki context
* @param start start date to use for document matching
*/
public WatchListEventMatcher(Date start, XWikiContext context)
{
ActivityStream actStream =
((ActivityStreamPlugin)
context.getWiki().getPlugin(ActivityStreamPlugin.PLUGIN_NAME, context)).getActivityStream();
List<Object> parameters = new ArrayList<Object>();
List<ActivityEvent> rawEvents;
parameters.add(start);
try {
rawEvents =
actStream.searchEvents("act.date > ? and act.type in ('" + StringUtils.join(MATCHING_EVENT_TYPES, "','")
+ "')", false, true, 0, 0, parameters, context);
// If the page has been modified several times we want to display only one diff, if the page has been
// delete after update events we want to discard the update events since we won't be able to display
// diff from a deleted document. See WatchListEvent#addEvent(WatchListEvent) and
// WatchListEvent#equals(WatchListEvent).
for (ActivityEvent rawEvent : rawEvents) {
WatchListEvent event = new WatchListEvent(rawEvent, context);
if (!events.contains(event)) {
events.add(new WatchListEvent(rawEvent, context));
} else {
WatchListEvent existingCompositeEvent = events.get(events.indexOf(event));
existingCompositeEvent.addEvent(event);
}
}
} catch (ActivityStreamException e) {
LOGGER.error("Failed to retrieve updated documents from activity stream");
e.printStackTrace();
}
}
/**
* @return the number of events the matcher will work with.
*/
public int getEventNumber()
{
return events.size();
}
/**
* Get the events matching criteria.
*
* @param wikis a list of wikis from which events should match
* @param spaces a list of spaces from which events should match
* @param documents a list of documents from which events should match
* @param users a list of users from which events should match
* @param userName notification recipient
* @param context the XWiki context
* @return the list of events matching the given scopes
*/
public List<WatchListEvent> getMatchingEvents(List<String> wikis, List<String> spaces, List<String> documents,
List<String> users, String userName, XWikiContext context)
{
List<WatchListEvent> matchingEvents = new ArrayList<WatchListEvent>();
WatchListPlugin plugin = (WatchListPlugin) context.getWiki().getPlugin(WatchListPlugin.ID, context);
List<String> jobDocumentNames = plugin.getStore().getJobDocumentNames();
for (WatchListEvent event : events) {
if (wikis.contains(event.getWiki()) || spaces.contains(event.getPrefixedSpace())
|| documents.contains(event.getPrefixedFullName())
|| ListUtils.intersection(users, event.getAuthors()).size() > 0) {
try {
// We exclude watchlist jobs from notifications since they are modified each time they are fired,
// producing useless noise. We also ensure that users have the right to view documents we send
// notifications for.
if (!jobDocumentNames.contains(event.getFullName())
&& context.getWiki().getRightService().hasAccessLevel("view", userName,
event.getPrefixedFullName(), context)) {
matchingEvents.add(event);
}
} catch (XWikiException e) {
// We're in a job, we don't throw exceptions
e.printStackTrace();
}
}
}
Collections.sort(matchingEvents);
return matchingEvents;
}
}