Coverage Report - org.kuali.rice.kew.mail.service.impl.ActionListEmailServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionListEmailServiceImpl
0%
0/235
0%
0/82
2.485
 
 1  
 /*
 2  
  * Copyright 2006-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.kuali.rice.kew.mail.service.impl;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 21  
 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
 22  
 import org.kuali.rice.core.mail.EmailBody;
 23  
 import org.kuali.rice.core.mail.EmailFrom;
 24  
 import org.kuali.rice.core.mail.EmailSubject;
 25  
 import org.kuali.rice.core.mail.EmailTo;
 26  
 import org.kuali.rice.core.mail.Mailer;
 27  
 import org.kuali.rice.kew.actionitem.ActionItem;
 28  
 import org.kuali.rice.kew.actionlist.service.ActionListService;
 29  
 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
 30  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 31  
 import org.kuali.rice.kew.dto.ActionRequestDTO;
 32  
 import org.kuali.rice.kew.dto.DTOConverter;
 33  
 import org.kuali.rice.kew.dto.RouteHeaderDTO;
 34  
 import org.kuali.rice.kew.mail.CustomEmailAttribute;
 35  
 import org.kuali.rice.kew.mail.DailyEmailJob;
 36  
 import org.kuali.rice.kew.mail.WeeklyEmailJob;
 37  
 import org.kuali.rice.kew.mail.service.ActionListEmailService;
 38  
 import org.kuali.rice.kew.preferences.Preferences;
 39  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 40  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 41  
 import org.kuali.rice.kew.useroptions.UserOptions;
 42  
 import org.kuali.rice.kew.useroptions.UserOptionsService;
 43  
 import org.kuali.rice.kew.util.KEWConstants;
 44  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 45  
 import org.kuali.rice.kim.bo.Person;
 46  
 import org.kuali.rice.kns.util.KNSConstants;
 47  
 import org.kuali.rice.ksb.service.KSBServiceLocator;
 48  
 import org.quartz.CronTrigger;
 49  
 import org.quartz.JobDetail;
 50  
 import org.quartz.ObjectAlreadyExistsException;
 51  
 import org.quartz.Scheduler;
 52  
 import org.quartz.SchedulerException;
 53  
 import org.quartz.Trigger;
 54  
 
 55  
 import java.text.FieldPosition;
 56  
 import java.text.MessageFormat;
 57  
 import java.util.ArrayList;
 58  
 import java.util.Collection;
 59  
 import java.util.HashMap;
 60  
 import java.util.Iterator;
 61  
 import java.util.LinkedHashMap;
 62  
 import java.util.List;
 63  
 import java.util.Map;
 64  
 
 65  
 
 66  
 /**
 67  
  * ActionListeEmailService which generates messages whose body and subject can be customized via
 68  
  * KEW configuration parameters, 'immediate.reminder.email.message' and 'immediate.reminder.email.subject'.
 69  
  * The immediate reminder email message key should specify a MessageFormat string.  See code for the parameters
 70  
  * to this MessageFormat.
 71  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 72  
  */
 73  0
 public class ActionListEmailServiceImpl implements ActionListEmailService {
 74  0
         private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
 75  
                         .getLogger(ActionListEmailServiceImpl.class);
 76  
 
 77  
         private static final String DEFAULT_EMAIL_FROM_ADDRESS = "admin@localhost";
 78  
 
 79  
         private static final String ACTION_LIST_REMINDER = "Action List Reminder";
 80  
 
 81  
     private static final String IMMEDIATE_REMINDER_EMAIL_MESSAGE_KEY = "immediate.reminder.email.message";
 82  
 
 83  
     private static final String IMMEDIATE_REMINDER_EMAIL_SUBJECT_KEY = "immediate.reminder.email.subject";
 84  
 
 85  
     private static final String DAILY_TRIGGER_NAME = "Daily Email Trigger";
 86  
     private static final String DAILY_JOB_NAME = "Daily Email";
 87  
     private static final String WEEKLY_TRIGGER_NAME = "Weekly Email Trigger";
 88  
     private static final String WEEKLY_JOB_NAME = "Weekly Email";
 89  
 
 90  
         private String deploymentEnvironment;
 91  
         
 92  
         private Mailer mailer;
 93  
         
 94  
         public void setMailer(Mailer mailer){
 95  0
                 this.mailer = mailer;
 96  0
         }
 97  
 
 98  
         public String getDocumentTypeEmailAddress(DocumentType documentType) {
 99  0
                 String fromAddress = (documentType == null ? null : documentType
 100  
                                 .getNotificationFromAddress());
 101  0
                 if (org.apache.commons.lang.StringUtils.isEmpty(fromAddress)) {
 102  0
                         fromAddress = getApplicationEmailAddress();
 103  
                 }
 104  0
                 return fromAddress;
 105  
         }
 106  
 
 107  
         public String getApplicationEmailAddress() {
 108  
                 // first check the configured value
 109  0
                 String fromAddress = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.MAILER_DETAIL_TYPE, KEWConstants.EMAIL_REMINDER_FROM_ADDRESS);
 110  
                 // if there's no value configured, use the default
 111  0
                 if (org.apache.commons.lang.StringUtils.isEmpty(fromAddress)) {
 112  0
                         fromAddress = DEFAULT_EMAIL_FROM_ADDRESS;
 113  
                 }
 114  0
                 return fromAddress;
 115  
         }
 116  
 
 117  
         protected String getHelpLink() {
 118  0
                 return getHelpLink(null);
 119  
         }
 120  
 
 121  
         protected String getHelpLink(DocumentType documentType) {
 122  0
                 return "For additional help, email " + "<mailto:"
 123  
                                 + getDocumentTypeEmailAddress(documentType) + ">";
 124  
         }
 125  
 
 126  
         public EmailSubject getEmailSubject() {
 127  0
         String subject = ConfigContext.getCurrentContextConfig().getProperty(IMMEDIATE_REMINDER_EMAIL_SUBJECT_KEY);
 128  0
         if (subject == null) {
 129  0
             subject = ACTION_LIST_REMINDER;
 130  
         }
 131  0
                 return new EmailSubject(subject);
 132  
         }
 133  
 
 134  
         public EmailSubject getEmailSubject(String customSubject) {
 135  0
         String subject = ConfigContext.getCurrentContextConfig().getProperty(IMMEDIATE_REMINDER_EMAIL_SUBJECT_KEY);
 136  0
         if (subject == null) {
 137  0
             subject = ACTION_LIST_REMINDER;
 138  
         }
 139  0
                 return new EmailSubject(subject + " " + customSubject);
 140  
         }
 141  
 
 142  
         protected EmailFrom getEmailFrom(DocumentType documentType) {
 143  0
                 return new EmailFrom(getDocumentTypeEmailAddress(documentType));
 144  
         }
 145  
 
 146  
         protected void sendEmail(Person user, EmailSubject subject,
 147  
                         EmailBody body) {
 148  0
                 sendEmail(user, subject, body, null);
 149  0
         }
 150  
 
 151  
         protected void sendEmail(Person user, EmailSubject subject,
 152  
                         EmailBody body, DocumentType documentType) {
 153  
                 try {
 154  0
                         if (isProduction()) {
 155  0
                                 mailer.sendEmail(getEmailFrom(documentType),
 156  
                                                          new EmailTo(user.getEmailAddressUnmasked()), 
 157  
                                                          subject,
 158  
                                                          body,
 159  
                                                          false);
 160  
                         } else {
 161  0
                                 mailer.sendEmail(getEmailFrom(documentType),
 162  
                                                          new EmailTo(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.ACTION_LIST_DETAIL_TYPE, KEWConstants.ACTIONLIST_EMAIL_TEST_ADDRESS)),
 163  
                                                                  subject,
 164  
                                                                  body,
 165  
                                                                  false);
 166  
                         }
 167  0
                 } catch (Exception e) {
 168  0
                         LOG.error("Error sending Action List email.", e);
 169  0
                 }
 170  0
         }
 171  
 
 172  
         public void sendImmediateReminder(Person user, ActionItem actionItem) {
 173  0
         boolean shouldSendActionListEmailNotification = sendActionListEmailNotification();
 174  0
                 if (shouldSendActionListEmailNotification) {
 175  0
             LOG.debug("sending immediate reminder");
 176  0
                         DocumentRouteHeaderValue document = KEWServiceLocator
 177  
                                         .getRouteHeaderService().getRouteHeader(
 178  
                                                         actionItem.getDocumentId());
 179  0
                         StringBuffer emailBody = new StringBuffer(
 180  
                                         buildImmediateReminderBody(user, actionItem, document
 181  
                                                         .getDocumentType()));
 182  0
                         StringBuffer emailSubject = new StringBuffer();
 183  
                         try {
 184  0
                                 CustomEmailAttribute customEmailAttribute = document.getCustomEmailAttribute();
 185  0
                                 if (customEmailAttribute != null) {
 186  0
                                         RouteHeaderDTO routeHeaderVO = DTOConverter
 187  
                                                         .convertRouteHeader(document,
 188  
                                                                         user.getPrincipalId());
 189  0
                                         ActionRequestValue actionRequest = KEWServiceLocator
 190  
                                                         .getActionRequestService().findByActionRequestId(
 191  
                                                                         actionItem.getActionRequestId());
 192  0
                                         ActionRequestDTO actionRequestVO = DTOConverter
 193  
                                                         .convertActionRequest(actionRequest);
 194  0
                                         customEmailAttribute.setRouteHeaderVO(routeHeaderVO);
 195  0
                                         customEmailAttribute.setActionRequestVO(actionRequestVO);
 196  0
                                         String customBody = customEmailAttribute
 197  
                                                         .getCustomEmailBody();
 198  0
                                         if (!org.apache.commons.lang.StringUtils.isEmpty(customBody)) {
 199  0
                                                 emailBody.append(customBody);
 200  
                                         }
 201  0
                                         String customEmailSubject = customEmailAttribute
 202  
                                                         .getCustomEmailSubject();
 203  0
                                         if (!org.apache.commons.lang.StringUtils.isEmpty(customEmailSubject)) {
 204  0
                                                 emailSubject.append(customEmailSubject);
 205  
                                         }
 206  
                                 }
 207  0
                         } catch (Exception e) {
 208  0
                                 LOG
 209  
                                                 .error(
 210  
                                                                 "Error when checking for custom email body and subject.",
 211  
                                                                 e);
 212  0
                         }
 213  0
             LOG.debug("Sending email to " + user);
 214  0
                         sendEmail(user, getEmailSubject(emailSubject.toString()),
 215  
                                         new EmailBody(emailBody.toString()), document
 216  
                                                         .getDocumentType());
 217  
                 }
 218  
 
 219  0
         }
 220  
 
 221  
         protected boolean isProduction() {
 222  0
                 return ConfigContext.getCurrentContextConfig().getProperty(KEWConstants.PROD_DEPLOYMENT_CODE).equalsIgnoreCase(getDeploymentEnvironment());
 223  
         }
 224  
 
 225  
         public void sendDailyReminder() {
 226  0
                 if (sendActionListEmailNotification()) {
 227  0
                         Collection<Person> users = getUsersWithEmailSetting(KEWConstants.EMAIL_RMNDR_DAY_VAL);
 228  0
                         for (Iterator<Person> userIter = users.iterator(); userIter.hasNext();) {
 229  0
                                 Person user = userIter.next();
 230  
                                 try {
 231  0
                                         Collection actionItems = getActionListService().getActionList(user.getPrincipalId(), null);
 232  0
                                         if (actionItems != null && actionItems.size() > 0) {
 233  0
                                             sendPeriodicReminder(user, actionItems,
 234  
                                                                 KEWConstants.EMAIL_RMNDR_DAY_VAL);
 235  
                                         }
 236  0
                                 } catch (Exception e) {
 237  0
                                         LOG.error(
 238  
                                                         "Error sending daily action list reminder to user: "
 239  
                                                                         + user.getEmailAddressUnmasked(), e);
 240  0
                                 }
 241  0
                         }
 242  
                 }
 243  0
                 LOG.debug("Daily action list emails sent successful");
 244  0
         }
 245  
 
 246  
         public void sendWeeklyReminder() {
 247  0
                 if (sendActionListEmailNotification()) {
 248  0
                         List<Person> users = getUsersWithEmailSetting(KEWConstants.EMAIL_RMNDR_WEEK_VAL);
 249  0
                         for (Iterator<Person> userIter = users.iterator(); userIter.hasNext();) {
 250  0
                                 Person user = userIter.next();
 251  
                                 try {
 252  0
                                         Collection actionItems = getActionListService()
 253  
                                                         .getActionList(user.getPrincipalId(), null);
 254  0
                                         if (actionItems != null && actionItems.size() > 0) {
 255  0
                                             sendPeriodicReminder(user, actionItems,
 256  
                                                                 KEWConstants.EMAIL_RMNDR_WEEK_VAL);
 257  
                                         }
 258  0
                                 } catch (Exception e) {
 259  0
                                         LOG.error(
 260  
                                                         "Error sending weekly action list reminder to user: "
 261  
                                                                         + user.getEmailAddressUnmasked(), e);
 262  0
                                 }
 263  0
                         }
 264  
                 }
 265  0
                 LOG.debug("Weekly action list emails sent successful");
 266  0
         }
 267  
 
 268  
         protected void sendPeriodicReminder(Person user, Collection<ActionItem> actionItems, String emailSetting) {
 269  0
                 String emailBody = null;
 270  0
                 actionItems = filterActionItemsToNotify(user.getPrincipalId(), actionItems);
 271  
                 // if there are no action items after being filtered, there's no
 272  
                 // reason to send the email
 273  0
                 if (actionItems.isEmpty()) {
 274  0
                         return;
 275  
                 }
 276  0
                 if (KEWConstants.EMAIL_RMNDR_DAY_VAL.equals(emailSetting)) {
 277  0
                         emailBody = buildDailyReminderBody(user, actionItems);
 278  0
                 } else if (KEWConstants.EMAIL_RMNDR_WEEK_VAL.equals(emailSetting)) {
 279  0
                         emailBody = buildWeeklyReminderBody(user, actionItems);
 280  
                 }
 281  0
                 sendEmail(user, getEmailSubject(), new EmailBody(emailBody));
 282  0
         }
 283  
 
 284  
         /**
 285  
          * Returns a filtered Collection of {@link ActionItem}s which are
 286  
          * filtered according to the user's preferences.  If they have opted
 287  
          * not to recieve secondary or primary delegation emails then they
 288  
          * will not be included.
 289  
          */
 290  
         protected Collection filterActionItemsToNotify(String principalId, Collection actionItems) {
 291  0
                 List filteredItems = new ArrayList();
 292  0
                 Preferences preferences = KEWServiceLocator.getPreferencesService().getPreferences(principalId);
 293  0
                 for (Iterator iterator = actionItems.iterator(); iterator.hasNext();) {
 294  0
                         ActionItem actionItem = (ActionItem) iterator.next();
 295  0
                         if (!actionItem.getPrincipalId().equals(principalId)) {
 296  0
                                 LOG.warn("Encountered an ActionItem with an incorrect workflow ID.  Was " + actionItem.getPrincipalId() +
 297  
                                                 " but expected " + principalId);
 298  0
                                 continue;
 299  
                         }
 300  0
                         boolean includeItem = true;
 301  0
                         if (KEWConstants.DELEGATION_PRIMARY.equals(actionItem.getDelegationType())) {
 302  0
                                 includeItem = KEWConstants.PREFERENCES_YES_VAL.equals(preferences.getNotifyPrimaryDelegation());
 303  0
                         } else if (KEWConstants.DELEGATION_SECONDARY.equals(actionItem.getDelegationType())) {
 304  0
                                 includeItem = KEWConstants.PREFERENCES_YES_VAL.equals(preferences.getNotifySecondaryDelegation());
 305  
                         }
 306  0
                         if (includeItem) {
 307  0
                                 filteredItems.add(actionItem);
 308  
                         }
 309  0
                 }
 310  0
                 return filteredItems;
 311  
         }
 312  
 
 313  
         protected List<Person> getUsersWithEmailSetting(String setting) {
 314  0
                 List users = new ArrayList();
 315  0
                 Collection userOptions = getUserOptionsService().findByOptionValue(
 316  
                                 KEWConstants.EMAIL_RMNDR_KEY, setting);
 317  0
                 for (Iterator iter = userOptions.iterator(); iter.hasNext();) {
 318  0
                         String workflowId = ((UserOptions) iter.next()).getWorkflowId();
 319  
                         try {
 320  
 
 321  0
                                 users.add(KimApiServiceLocator.getPersonService().getPerson(workflowId));
 322  0
                         } catch (Exception e) {
 323  0
                                 LOG.error("error retrieving workflow user with ID: "
 324  
                                                 + workflowId);
 325  0
                         }
 326  0
                 }
 327  0
                 return users;
 328  
         }
 329  
 
 330  
     /**
 331  
      * 0 = actionItem.getDocumentId()
 332  
      * 1 = actionItem.getRouteHeader().getInitiatorUser().getDisplayName()
 333  
      * 2 = actionItem.getRouteHeader().getDocumentType().getName()
 334  
      * 3 = actionItem.getDocTitle()
 335  
      * 4 = docHandlerUrl
 336  
      * 5 = getActionListUrl()
 337  
      * 6 = getPreferencesUrl()
 338  
      * 7 = getHelpLink(documentType)
 339  
      */
 340  0
     private static final MessageFormat DEFAULT_IMMEDIATE_REMINDER = new MessageFormat(
 341  
         "Your Action List has an eDoc(electronic document) that needs your attention: \n\n" +
 342  
         "Document ID:\t{0,number,#}\n" +
 343  
         "Initiator:\t\t{1}\n" +
 344  
         "Type:\t\tAdd/Modify {2}\n" +
 345  
         "Title:\t\t{3}\n" +
 346  
         "\n\n" +
 347  
         "To respond to this eDoc: \n" +
 348  
         "\tGo to {4}\n\n" +
 349  
         "\tOr you may access the eDoc from your Action List: \n" +
 350  
         "\tGo to {5}, and then click on the numeric Document ID: {0,number,#} in the first column of the List. \n" +
 351  
         "\n\n\n" +
 352  
         "To change how these email notifications are sent(daily, weekly or none): \n" +
 353  
         "\tGo to {6}\n" +
 354  
         "\n\n\n" +
 355  
         "{7}\n\n\n"
 356  
     );
 357  
 
 358  
     /**
 359  
      * 0 = actionItem.getDocumentId()
 360  
      * 1 = actionItem.getRouteHeader().getInitiatorUser().getDisplayName()
 361  
      * 2 = actionItem.getRouteHeader().getDocumentType().getName()
 362  
      * 3 = actionItem.getDocTitle()
 363  
      * 4 = getActionListUrl()
 364  
      * 5 = getPreferencesUrl()
 365  
      * 6 = getHelpLink(documentType)
 366  
      */
 367  0
     private static final MessageFormat DEFAULT_IMMEDIATE_REMINDER_NO_DOC_HANDLER = new MessageFormat(
 368  
         "Your Action List has an eDoc(electronic document) that needs your attention: \n\n" +
 369  
         "Document ID:\t{0,number,#}\n" +
 370  
         "Initiator:\t\t{1}\n" +
 371  
         "Type:\t\tAdd/Modify {2}\n" +
 372  
         "Title:\t\t{3}\n" +
 373  
         "\n\n" +
 374  
         "To respond to this eDoc you may use your Action List: \n" +
 375  
         "\tGo to {4}, and then take actions related to Document ID: {0,number,#}. \n" +
 376  
         "\n\n\n" +
 377  
         "To change how these email notifications are sent(daily, weekly or none): \n" +
 378  
         "\tGo to {5}\n" +
 379  
         "\n\n\n" +
 380  
         "{6}\n\n\n"
 381  
     );
 382  
 
 383  
         public String buildImmediateReminderBody(Person person,
 384  
                         ActionItem actionItem, DocumentType documentType) {
 385  0
                 String docHandlerUrl = documentType.getDocHandlerUrl();
 386  0
                 if (StringUtils.isNotBlank(docHandlerUrl)) {
 387  0
                     if (!docHandlerUrl.contains("?")) {
 388  0
                             docHandlerUrl += "?";
 389  
                     } else {
 390  0
                             docHandlerUrl += "&";
 391  
                     }
 392  0
                     docHandlerUrl += KEWConstants.DOCUMENT_ID_PARAMETER + "="
 393  
                                     + actionItem.getDocumentId();
 394  0
                     docHandlerUrl += "&" + KEWConstants.COMMAND_PARAMETER + "="
 395  
                                     + KEWConstants.ACTIONLIST_COMMAND;
 396  
                 }
 397  0
                 StringBuffer sf = new StringBuffer();
 398  
 
 399  
                 /*sf
 400  
                                 .append("Your Action List has an eDoc(electronic document) that needs your attention: \n\n");
 401  
                 sf.append("Document ID:\t" + actionItem.getDocumentId() + "\n");
 402  
                 sf.append("Initiator:\t\t");
 403  
                 try {
 404  
                         sf.append(actionItem.getRouteHeader().getInitiatorUser()
 405  
                                         .getDisplayName()
 406  
                                         + "\n");
 407  
                 } catch (Exception e) {
 408  
                         LOG.error("Error retrieving initiator for action item "
 409  
                                         + actionItem.getDocumentId());
 410  
                         sf.append("\n");
 411  
                 }
 412  
                 sf.append("Type:\t\t" + "Add/Modify "
 413  
                                 + actionItem.getRouteHeader().getDocumentType().getName()
 414  
                                 + "\n");
 415  
                 sf.append("Title:\t\t" + actionItem.getDocTitle() + "\n");
 416  
                 sf.append("\n\n");
 417  
                 sf.append("To respond to this eDoc: \n");
 418  
                 sf.append("\tGo to " + docHandlerUrl + "\n\n");
 419  
                 sf.append("\tOr you may access the eDoc from your Action List: \n");
 420  
                 sf.append("\tGo to " + getActionListUrl()
 421  
                                 + ", and then click on the numeric Document ID: "
 422  
                                 + actionItem.getDocumentId()
 423  
                                 + " in the first column of the List. \n");
 424  
                 sf.append("\n\n\n");
 425  
                 sf
 426  
                                 .append("To change how these email notifications are sent(daily, weekly or none): \n");
 427  
                 sf.append("\tGo to " + getPreferencesUrl() + "\n");
 428  
                 sf.append("\n\n\n");
 429  
                 sf.append(getHelpLink(documentType) + "\n\n\n");*/
 430  
 
 431  0
         MessageFormat messageFormat = null;
 432  0
         String stringMessageFormat = ConfigContext.getCurrentContextConfig().getProperty(IMMEDIATE_REMINDER_EMAIL_MESSAGE_KEY);
 433  0
         LOG.debug("Immediate reminder email message from configuration (" + IMMEDIATE_REMINDER_EMAIL_MESSAGE_KEY + "): " + stringMessageFormat);
 434  0
         if (stringMessageFormat == null) {
 435  0
             messageFormat = DEFAULT_IMMEDIATE_REMINDER;
 436  
         } else {
 437  0
             messageFormat = new MessageFormat(stringMessageFormat);
 438  
         }
 439  0
         String initiatorUser = (person == null ? "" : person.getName());
 440  
 
 441  0
         if (StringUtils.isNotBlank(docHandlerUrl)) {
 442  0
             Object[] args = { actionItem.getDocumentId(), 
 443  
                     initiatorUser,
 444  
                     documentType.getName(),
 445  
                     actionItem.getDocTitle(), 
 446  
                     docHandlerUrl,
 447  
                     getActionListUrl(), 
 448  
                     getPreferencesUrl(),
 449  
                     getHelpLink(documentType) 
 450  
                     };
 451  
 
 452  0
             messageFormat.format(args, sf, new FieldPosition(0));
 453  
 
 454  0
             LOG.debug("default immediate reminder: " + DEFAULT_IMMEDIATE_REMINDER.format(args));
 455  0
         } else {
 456  0
             Object[] args = { actionItem.getDocumentId(), 
 457  
                     initiatorUser,
 458  
                     documentType.getName(),
 459  
                     actionItem.getDocTitle(), 
 460  
                     getActionListUrl(), 
 461  
                     getPreferencesUrl(),
 462  
                     getHelpLink(documentType) 
 463  
                     };
 464  
 
 465  0
             messageFormat.format(args, sf, new FieldPosition(0));
 466  
 
 467  0
             LOG.debug("default immediate reminder: " + DEFAULT_IMMEDIATE_REMINDER_NO_DOC_HANDLER.format(args));
 468  
         }
 469  0
         LOG.debug("immediate reminder: " + sf);
 470  
 
 471  
                 // for debugging purposes on the immediate reminder only
 472  0
                 if (!isProduction()) {
 473  
                         try {
 474  0
                                 sf.append("Action Item sent to " + actionItem.getPerson().getPrincipalName());
 475  0
                                 if (actionItem.getDelegationType() != null) {
 476  0
                                         sf.append(" for delegation type "
 477  
                                                         + actionItem.getDelegationType());
 478  
                                 }
 479  0
                         } catch (Exception e) {
 480  0
                                 throw new RuntimeException(e);
 481  0
                         }
 482  
                 }
 483  
 
 484  0
                 return sf.toString();
 485  
         }
 486  
 
 487  
         public String buildDailyReminderBody(Person user,
 488  
                         Collection actionItems) {
 489  0
                 StringBuffer sf = new StringBuffer();
 490  0
                 sf.append(getDailyWeeklyMessageBody(actionItems));
 491  0
                 sf
 492  
                                 .append("To change how these email notifications are sent (immediately, weekly or none): \n");
 493  0
                 sf.append("\tGo to " + getPreferencesUrl() + "\n");
 494  
                 // sf.append("\tSend as soon as you get an eDoc\n\t" +
 495  
                 // getPreferencesUrl() + "\n\n");
 496  
                 // sf.append("\tSend weekly\n\t" + getPreferencesUrl() + "\n\n");
 497  
                 // sf.append("\tDo not send\n\t" + getPreferencesUrl() + "\n");
 498  0
                 sf.append("\n\n\n");
 499  0
                 sf.append(getHelpLink() + "\n\n\n");
 500  0
                 return sf.toString();
 501  
         }
 502  
 
 503  
         public String buildWeeklyReminderBody(Person user,
 504  
                         Collection actionItems) {
 505  0
                 StringBuffer sf = new StringBuffer();
 506  0
                 sf.append(getDailyWeeklyMessageBody(actionItems));
 507  0
                 sf
 508  
                                 .append("To change how these email notifications are sent (immediately, daily or none): \n");
 509  0
                 sf.append("\tGo to " + getPreferencesUrl() + "\n");
 510  
                 // sf.append("\tSend as soon as you get an eDoc\n\t" +
 511  
                 // getPreferencesUrl() + "\n\n");
 512  
                 // sf.append("\tSend daily\n\t" + getPreferencesUrl() + "\n\n");
 513  
                 // sf.append("\tDo not send\n\t" + getPreferencesUrl() + "\n");
 514  0
                 sf.append("\n\n\n");
 515  0
                 sf.append(getHelpLink() + "\n\n\n");
 516  0
                 return sf.toString();
 517  
         }
 518  
 
 519  
         String getDailyWeeklyMessageBody(Collection actionItems) {
 520  0
                 StringBuffer sf = new StringBuffer();
 521  0
                 HashMap docTypes = getActionListItemsStat(actionItems);
 522  
 
 523  0
                 sf
 524  
                                 .append("Your Action List has "
 525  
                                                 + actionItems.size()
 526  
                                                 + " eDocs(electronic documents) that need your attention: \n\n");
 527  0
                 Iterator iter = docTypes.keySet().iterator();
 528  0
                 while (iter.hasNext()) {
 529  0
                         String docTypeName = (String) iter.next();
 530  0
                         sf.append("\t" + ((Integer) docTypes.get(docTypeName)).toString()
 531  
                                         + "\t" + docTypeName + "\n");
 532  0
                 }
 533  0
                 sf.append("\n\n");
 534  0
                 sf.append("To respond to each of these eDocs: \n");
 535  0
                 sf
 536  
                                 .append("\tGo to "
 537  
                                                 + getActionListUrl()
 538  
                                                 + ", and then click on its numeric Document ID in the first column of the List.\n");
 539  0
                 sf.append("\n\n\n");
 540  0
                 return sf.toString();
 541  
         }
 542  
 
 543  
         private HashMap<String,Integer> getActionListItemsStat(Collection<ActionItem> actionItems) {
 544  0
                 HashMap<String,Integer> docTypes = new LinkedHashMap<String,Integer>();
 545  0
                 Map<String,DocumentRouteHeaderValue> routeHeaders = KEWServiceLocator.getRouteHeaderService().getRouteHeadersForActionItems(actionItems);
 546  0
                 Iterator<ActionItem> iter = actionItems.iterator();
 547  
 
 548  0
                 while (iter.hasNext()) {
 549  0
                         String docTypeName = routeHeaders.get(iter.next().getDocumentId()).getDocumentType().getName();
 550  0
                         if (docTypes.containsKey(docTypeName)) {
 551  0
                                 docTypes.put(docTypeName, new Integer(docTypes.get(docTypeName).intValue() + 1));
 552  
                         } else {
 553  0
                                 docTypes.put(docTypeName, new Integer(1));
 554  
                         }
 555  0
                 }
 556  0
                 return docTypes;
 557  
         }
 558  
 
 559  
         protected boolean sendActionListEmailNotification() {
 560  0
         LOG.debug("actionlistsendconstant: " + CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.ACTION_LIST_DETAIL_TYPE, KEWConstants.ACTION_LIST_SEND_EMAIL_NOTIFICATION_IND));
 561  
 
 562  0
         return KEWConstants.ACTION_LIST_SEND_EMAIL_NOTIFICATION_VALUE
 563  
                         .equals(CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.ACTION_LIST_DETAIL_TYPE, KEWConstants.ACTION_LIST_SEND_EMAIL_NOTIFICATION_IND));
 564  
         }
 565  
 
 566  
         public void scheduleBatchEmailReminders() throws Exception {
 567  0
             String emailBatchGroup = "Email Batch";
 568  0
             String dailyCron = ConfigContext.getCurrentContextConfig().getProperty(KEWConstants.DAILY_EMAIL_CRON_EXPRESSION);
 569  0
             if (!StringUtils.isBlank(dailyCron)) {
 570  0
                 LOG.info("Scheduling Daily Email batch with cron expression: " + dailyCron);
 571  0
                 CronTrigger dailyTrigger = new CronTrigger(DAILY_TRIGGER_NAME, emailBatchGroup, dailyCron);
 572  0
                 JobDetail dailyJobDetail = new JobDetail(DAILY_JOB_NAME, emailBatchGroup, DailyEmailJob.class);
 573  0
                 dailyTrigger.setJobName(dailyJobDetail.getName());
 574  0
                 dailyTrigger.setJobGroup(dailyJobDetail.getGroup());
 575  0
                 addJobToScheduler(dailyJobDetail);
 576  0
                 addTriggerToScheduler(dailyTrigger);
 577  0
             } else {
 578  0
                 LOG.warn("No " + KEWConstants.DAILY_EMAIL_CRON_EXPRESSION + " parameter was configured.  Daily Email batch was not scheduled!");
 579  
             }
 580  
 
 581  0
             String weeklyCron = ConfigContext.getCurrentContextConfig().getProperty(KEWConstants.WEEKLY_EMAIL_CRON_EXPRESSION);
 582  0
             if (!StringUtils.isBlank(weeklyCron)) {
 583  0
                 LOG.info("Scheduling Weekly Email batch with cron expression: " + weeklyCron);
 584  0
                 CronTrigger weeklyTrigger = new CronTrigger(WEEKLY_TRIGGER_NAME, emailBatchGroup, weeklyCron);
 585  0
                 JobDetail weeklyJobDetail = new JobDetail(WEEKLY_JOB_NAME, emailBatchGroup, WeeklyEmailJob.class);
 586  0
                 weeklyTrigger.setJobName(weeklyJobDetail.getName());
 587  0
                 weeklyTrigger.setJobGroup(weeklyJobDetail.getGroup());
 588  0
                 addJobToScheduler(weeklyJobDetail);
 589  0
                 addTriggerToScheduler(weeklyTrigger);
 590  0
             } else {
 591  0
                 LOG.warn("No " + KEWConstants.WEEKLY_EMAIL_CRON_EXPRESSION + " parameter was configured.  Weekly Email batch was not scheduled!");
 592  
             }
 593  0
         }
 594  
 
 595  
         private void addJobToScheduler(JobDetail jobDetail) throws SchedulerException {
 596  0
                 getScheduler().addJob(jobDetail, true);
 597  0
         }
 598  
 
 599  
         private void addTriggerToScheduler(Trigger trigger) throws SchedulerException {
 600  0
                 boolean triggerExists = (getScheduler().getTrigger(trigger.getName(), trigger.getGroup()) != null);
 601  0
                 if (!triggerExists) {
 602  
                         try {
 603  0
                                 getScheduler().scheduleJob(trigger);
 604  0
                         } catch (ObjectAlreadyExistsException ex) {
 605  0
                                 getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
 606  0
                         }
 607  
                 } else {
 608  0
                     getScheduler().rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
 609  
                 }
 610  0
         }
 611  
 
 612  
         private Scheduler getScheduler() {
 613  0
                 return KSBServiceLocator.getScheduler();
 614  
         }
 615  
 
 616  
         private UserOptionsService getUserOptionsService() {
 617  0
                 return (UserOptionsService) KEWServiceLocator
 618  
                                 .getUserOptionsService();
 619  
         }
 620  
 
 621  
         protected ActionListService getActionListService() {
 622  0
                 return (ActionListService) KEWServiceLocator.getActionListService();
 623  
         }
 624  
 
 625  
         public String getDeploymentEnvironment() {
 626  0
                 return deploymentEnvironment;
 627  
         }
 628  
 
 629  
         public void setDeploymentEnvironment(String deploymentEnvironment) {
 630  0
                 this.deploymentEnvironment = deploymentEnvironment;
 631  0
         }
 632  
 
 633  
         protected String getActionListUrl() {
 634  0
                 return ConfigContext.getCurrentContextConfig().getProperty(KNSConstants.WORKFLOW_URL_KEY)
 635  
                                 + "/" + "ActionList.do";
 636  
         }
 637  
 
 638  
         protected String getPreferencesUrl() {
 639  0
                 return ConfigContext.getCurrentContextConfig().getProperty(KNSConstants.WORKFLOW_URL_KEY)
 640  
                                 + "/" + "Preferences.do";
 641  
         }
 642  
 }