/** * Copyright (C) 2011 JTalks.org Team * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jtalks.jcommune.service.nontransactional; import org.jtalks.jcommune.model.entity.Branch; import org.jtalks.jcommune.model.entity.JCUser; import org.jtalks.jcommune.model.entity.SubscriptionAwareEntity; import org.jtalks.jcommune.model.entity.Topic; import org.jtalks.jcommune.plugin.api.PluginLoader; import org.jtalks.jcommune.plugin.api.core.Plugin; import org.jtalks.jcommune.plugin.api.core.TopicPlugin; import org.jtalks.jcommune.plugin.api.filters.StateFilter; import org.jtalks.jcommune.plugin.api.filters.TypeFilter; import org.jtalks.jcommune.service.SubscriptionService; import org.jtalks.jcommune.service.UserService; import java.util.Collection; import java.util.List; /** * Send email notifications to the users subscribed. * If the update author is subscribed he won't get the notification message. * This service also assumes, that topic update as a enclosing branch update as well. * <p/> * Errors occurred while sending emails are suppressed (logged only) as updates * notifications are themselves a kind of a side effect, so they should not prevent * the whole operation from being completed. * * @author Evgeniy Naumenko * @author Vitaliy Kravchenko */ public class NotificationService { SubscriptionService subscriptionService; private UserService userService; private MailService mailService; private final PluginLoader pluginLoader; /** * @param userService to determine the update author * @param mailService to perform actual email notifications * @param subscriptionService to get the subscribers of the entity * @param pluginLoader to get different subscribers for plugable topics */ public NotificationService( UserService userService, MailService mailService, SubscriptionService subscriptionService, PluginLoader pluginLoader) { this.userService = userService; this.mailService = mailService; this.subscriptionService = subscriptionService; this.pluginLoader = pluginLoader; } /** * Notifies subscribers about subscribed entity updates by email. * If mailing failed this implementation simply continues * with other subscribers. * * @param entity changed subscribed entity. */ public void subscribedEntityChanged(SubscriptionAwareEntity entity) { Collection<JCUser> subscribers = subscriptionService.getAllowedSubscribers(entity); filterSubscribers(subscribers, entity); for (JCUser user : subscribers) { mailService.sendUpdatesOnSubscription(user, entity); } } /** * Notifies topic starter by email that his or her topic * was moved to another sections and also notifies all branch * subscribers * * @param topic topic moved */ public void sendNotificationAboutTopicMoved(Topic topic) { String curUser = userService.getCurrentUser().getUsername(); //send notification to topic subscribers Collection<JCUser> topicSubscribers = subscriptionService.getAllowedSubscribers(topic); this.filterSubscribers(topicSubscribers, topic); for (JCUser subscriber : topicSubscribers) { mailService.sendTopicMovedMail(subscriber, topic, curUser, Topic.class); } //send notification to branch subscribers Collection<JCUser> branchSubscribers = subscriptionService.getAllowedSubscribers(topic.getBranch()); branchSubscribers.removeAll(topicSubscribers); this.filterSubscribers(branchSubscribers, topic.getBranch()); for (JCUser subscriber : branchSubscribers) { if (!topicSubscribers.contains(subscriber)) { mailService.sendTopicMovedMail(subscriber, topic, curUser, Branch.class); } } } /** * Filter collection - remove current user from subscribers and performs plugin filtering * * @param subscribers collection of subscribers * @see org.jtalks.jcommune.plugin.api.core.SubscribersFilter */ private void filterSubscribers(Collection<JCUser> subscribers, SubscriptionAwareEntity entity) { List<Plugin> plugins = pluginLoader.getPlugins(new StateFilter(Plugin.State.ENABLED), new TypeFilter(TopicPlugin.class)); for (Plugin plugin : plugins) { TopicPlugin topicPlugin = (TopicPlugin)plugin; topicPlugin.getSubscribersFilter().filter(subscribers, entity); } // Current user should be removed after filtering by plugin because filter don't know anything // about current user subscribers.remove(userService.getCurrentUser()); } /** * Send notification to subscribers about removing topic or code review. * * @param topic Current topic */ public void sendNotificationAboutRemovingTopic(Topic topic) { subscribedEntityChanged(topic.getBranch()); Collection<JCUser> subscribers = subscriptionService.getAllowedSubscribers(topic); Collection<JCUser> branchSubscribers = subscriptionService.getAllowedSubscribers(topic.getBranch()); subscribers.removeAll(branchSubscribers); String curUser = userService.getCurrentUser().getUsername(); this.filterSubscribers(subscribers, topic); for (JCUser subscriber : subscribers) { mailService.sendRemovingTopicMail(subscriber, topic, curUser); } } /** * Notify about new topic creation in the subscribed branch. * * @param topic newly created topic */ public void sendNotificationAboutTopicCreated(Topic topic) { Collection<JCUser> branchSubscribers = subscriptionService.getAllowedSubscribers(topic.getBranch()); this.filterSubscribers(branchSubscribers, topic); for (JCUser subscriber : branchSubscribers) { mailService.sendTopicCreationMail(subscriber, topic); } } }