001/** 002 * Copyright 2005-2015 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.notification.service.impl; 017 018import java.util.Collections; 019import java.util.Comparator; 020import java.util.HashSet; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Set; 024 025import org.apache.commons.collections.ComparatorUtils; 026import org.kuali.rice.core.api.delegation.DelegationType; 027import org.kuali.rice.kew.actionitem.ActionItemComparator; 028import org.kuali.rice.kew.api.KewApiServiceLocator; 029import org.kuali.rice.kew.api.WorkflowRuntimeException; 030import org.kuali.rice.kew.api.action.ActionItem; 031import org.kuali.rice.kew.api.mail.ImmediateEmailReminderQueue; 032import org.kuali.rice.kew.doctype.bo.DocumentType; 033import org.kuali.rice.kew.engine.RouteContext; 034import org.kuali.rice.kew.notification.service.NotificationService; 035import org.kuali.rice.kew.api.preferences.Preferences; 036import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; 037import org.kuali.rice.kew.service.KEWServiceLocator; 038import org.kuali.rice.kew.api.KewApiConstants; 039 040 041/** 042 * The default implementation of the NotificationService. 043 * 044 * @author Kuali Rice Team (rice.collab@kuali.org) 045 */ 046public class DefaultNotificationService implements NotificationService { 047 048 protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass()); 049 050 private static final Comparator notificationPriorityComparator = ComparatorUtils.reversedComparator(new ActionItemComparator()); 051 052 /** 053 * Queues up immediate email processors for ActionItem notification. Prioritizes the list of 054 * Action Items passed in and attempts to not send out multiple emails to the same user. 055 */ 056 public void notify(List<ActionItem> actionItems) { 057 // sort the list of action items using the same comparator as the Action List 058 Collections.sort(actionItems, notificationPriorityComparator); 059 Set sentNotifications = new HashSet(); 060 for (Iterator iterator = actionItems.iterator(); iterator.hasNext();) { 061 ActionItem actionItem = (ActionItem) iterator.next(); 062 if (!sentNotifications.contains(actionItem.getPrincipalId()) && shouldNotify(actionItem)) { 063 sentNotifications.add(actionItem.getPrincipalId()); 064 sendNotification(actionItem); 065 } 066 } 067 } 068 069 /** 070 * Sends a notification 071 * @param actionItem the action item 072 */ 073 protected void sendNotification(ActionItem actionItem) { 074 ImmediateEmailReminderQueue immediateEmailQueue = KewApiServiceLocator.getImmediateEmailReminderQueue(); 075 immediateEmailQueue.sendReminder(actionItem, RouteContext.getCurrentRouteContext().isDoNotSendApproveNotificationEmails()); 076 // TODO: JLR - replace with direct call to ActionListEmailService 077 } 078 079 protected boolean shouldNotify(ActionItem actionItem) { 080 try { 081 boolean sendEmail = true; 082 // Removed preferences items since they will be checked before it sends 083 // the email in the action list email service 084 085 // don't send notification if this action item came from a SAVE action and the NOTIFY_ON_SAVE policy is not set 086 if (sendEmail && isItemOriginatingFromSave(actionItem) && !shouldNotifyOnSave(actionItem)) { 087 sendEmail = false; 088 } 089 return sendEmail; 090 } catch (Exception e) { 091 throw new WorkflowRuntimeException("Error loading user with workflow id " + actionItem.getPrincipalId() + " for notification.", e); 092 } 093 } 094 095 /** 096 * Returns true if the ActionItem doesn't represent a request generated from a "SAVE" action or, if it does, 097 * returns true if the document type policy 098 */ 099 protected boolean isItemOriginatingFromSave(ActionItem actionItem) { 100 return actionItem.getResponsibilityId() != null && actionItem.getResponsibilityId().equals(KewApiConstants.SAVED_REQUEST_RESPONSIBILITY_ID); 101 } 102 103 protected boolean shouldNotifyOnSave(ActionItem actionItem) { 104 DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(actionItem.getDocumentId()); 105 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findById(document.getDocumentTypeId()); 106 return documentType.getNotifyOnSavePolicy().getPolicyValue().booleanValue(); 107 } 108 109 public void removeNotification(List<ActionItem> actionItems) { 110 // nothing 111 } 112}