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