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}