Coverage Report - org.kuali.rice.ken.web.spring.SendNotificationMessageController
 
Classes in this File Line Coverage Branch Coverage Complexity
SendNotificationMessageController
0%
0/210
0%
0/98
5.833
 
 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.ken.web.spring;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.apache.log4j.Logger;
 21  
 import org.kuali.rice.core.framework.persistence.dao.GenericDao;
 22  
 import org.kuali.rice.ken.bo.Notification;
 23  
 import org.kuali.rice.ken.bo.NotificationChannel;
 24  
 import org.kuali.rice.ken.bo.NotificationChannelReviewer;
 25  
 import org.kuali.rice.ken.bo.NotificationContentType;
 26  
 import org.kuali.rice.ken.bo.NotificationPriority;
 27  
 import org.kuali.rice.ken.bo.NotificationProducer;
 28  
 import org.kuali.rice.ken.bo.NotificationRecipient;
 29  
 import org.kuali.rice.ken.bo.NotificationSender;
 30  
 import org.kuali.rice.ken.document.kew.NotificationWorkflowDocument;
 31  
 import org.kuali.rice.ken.exception.ErrorList;
 32  
 import org.kuali.rice.ken.service.NotificationChannelService;
 33  
 import org.kuali.rice.ken.service.NotificationMessageContentService;
 34  
 import org.kuali.rice.ken.service.NotificationRecipientService;
 35  
 import org.kuali.rice.ken.service.NotificationService;
 36  
 import org.kuali.rice.ken.service.NotificationWorkflowDocumentService;
 37  
 import org.kuali.rice.ken.util.NotificationConstants;
 38  
 import org.kuali.rice.ken.util.Util;
 39  
 import org.kuali.rice.kew.api.WorkflowDocument;
 40  
 import org.kuali.rice.kew.rule.GenericAttributeContent;
 41  
 import org.kuali.rice.kim.util.KimConstants.KimGroupMemberTypes;
 42  
 import org.springframework.web.servlet.ModelAndView;
 43  
 
 44  
 import javax.servlet.ServletException;
 45  
 import javax.servlet.http.HttpServletRequest;
 46  
 import javax.servlet.http.HttpServletResponse;
 47  
 import java.io.IOException;
 48  
 import java.sql.Timestamp;
 49  
 import java.text.ParseException;
 50  
 import java.util.Date;
 51  
 import java.util.HashMap;
 52  
 import java.util.List;
 53  
 import java.util.Map;
 54  
 
 55  
 /**
 56  
  * This class is the controller for sending Simple notification messages via an end user interface.
 57  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 58  
  */
 59  0
 public class SendNotificationMessageController extends BaseSendNotificationController {
 60  
     /** Logger for this class and subclasses */
 61  0
     private static final Logger LOG = Logger
 62  
             .getLogger(SendNotificationMessageController.class);
 63  
 
 64  
     private static final String NONE_CHANNEL = "___NONE___";
 65  
     private static final long REASONABLE_IMMEDIATE_TIME_THRESHOLD = 1000 * 60 * 5; // <= 5 minutes is "immediate"
 66  
 
 67  
     /**
 68  
      * Returns whether the specified time is considered "in the future", based on some reasonable
 69  
      * threshold
 70  
      * @param time the time to test
 71  
      * @return whether the specified time is considered "in the future", based on some reasonable
 72  
      *         threshold
 73  
      */
 74  
     private boolean timeIsInTheFuture(long time) {
 75  0
         boolean future = (time - System.currentTimeMillis()) > REASONABLE_IMMEDIATE_TIME_THRESHOLD;
 76  0
         LOG.info("Time: " + new Date(time) + " is in the future? " + future);
 77  0
         return future;
 78  
     }
 79  
 
 80  
     /**
 81  
      * Returns whether the specified Notification can be reasonably expected to have recipients.
 82  
      * This is determined on whether the channel has default recipients, is subscribably, and
 83  
      * whether the send date time is far enough in the future to expect that if there are no
 84  
      * subscribers, there may actually be some by the time the notification is sent.
 85  
      * @param notification the notification to test
 86  
      * @return whether the specified Notification can be reasonably expected to have recipients
 87  
      */
 88  
     private boolean hasPotentialRecipients(Notification notification) {
 89  0
         LOG.info("notification channel " + notification.getChannel() + " is subscribable: "
 90  
                 + notification.getChannel().isSubscribable());
 91  0
         return notification.getChannel().getRecipientLists().size() > 0
 92  
                 ||
 93  
                 notification.getChannel().getSubscriptions().size() > 0
 94  
                 ||
 95  
                 (notification.getChannel().isSubscribable() && timeIsInTheFuture(notification.getSendDateTime()
 96  
                         .getTime()));
 97  
     }
 98  
 
 99  
     protected NotificationService notificationService;
 100  
 
 101  
     protected NotificationWorkflowDocumentService notificationWorkflowDocService;
 102  
 
 103  
     protected NotificationChannelService notificationChannelService;
 104  
 
 105  
     protected NotificationRecipientService notificationRecipientService;
 106  
 
 107  
     protected NotificationMessageContentService messageContentService;
 108  
 
 109  
     protected GenericDao businessObjectDao;
 110  
 
 111  
     /**
 112  
      * Set the NotificationService
 113  
      * @param notificationService
 114  
      */
 115  
     public void setNotificationService(NotificationService notificationService) {
 116  0
         this.notificationService = notificationService;
 117  0
     }
 118  
 
 119  
     /**
 120  
      * This method sets the NotificationWorkflowDocumentService
 121  
      * @param s
 122  
      */
 123  
     public void setNotificationWorkflowDocumentService(
 124  
             NotificationWorkflowDocumentService s) {
 125  0
         this.notificationWorkflowDocService = s;
 126  0
     }
 127  
 
 128  
     /**
 129  
      * Sets the notificationChannelService attribute value.
 130  
      * @param notificationChannelService The notificationChannelService to set.
 131  
      */
 132  
     public void setNotificationChannelService(
 133  
             NotificationChannelService notificationChannelService) {
 134  0
         this.notificationChannelService = notificationChannelService;
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Sets the notificationRecipientService attribute value.
 139  
      * @param notificationRecipientService
 140  
      */
 141  
     public void setNotificationRecipientService(
 142  
             NotificationRecipientService notificationRecipientService) {
 143  0
         this.notificationRecipientService = notificationRecipientService;
 144  0
     }
 145  
 
 146  
     /**
 147  
      * Sets the messageContentService attribute value.
 148  
      * @param messageContentService
 149  
      */
 150  
     public void setMessageContentService(
 151  
             NotificationMessageContentService notificationMessageContentService) {
 152  0
         this.messageContentService = notificationMessageContentService;
 153  0
     }
 154  
 
 155  
     /**
 156  
      * Sets the businessObjectDao attribute value.
 157  
      * @param businessObjectDao The businessObjectDao to set.
 158  
      */
 159  
     public void setBusinessObjectDao(GenericDao businessObjectDao) {
 160  0
         this.businessObjectDao = businessObjectDao;
 161  0
     }
 162  
 
 163  
     /**
 164  
      * Handles the display of the form for sending a simple notification message
 165  
      * @param request : a servlet request
 166  
      * @param response : a servlet response
 167  
      * @throws ServletException : an exception
 168  
      * @throws IOException : an exception
 169  
      * @return a ModelAndView object
 170  
      */
 171  
     public ModelAndView sendSimpleNotificationMessage(
 172  
             HttpServletRequest request, HttpServletResponse response)
 173  
             throws ServletException, IOException {
 174  0
         String view = "SendSimpleNotificationMessage";
 175  
 
 176  0
         LOG.debug("remoteUser: " + request.getRemoteUser());
 177  
 
 178  0
         Map<String, Object> model = setupModelForSendSimpleNotification(request);
 179  0
         model.put("errors", new ErrorList()); // need an empty one so we don't have an NPE
 180  
 
 181  0
         return new ModelAndView(view, model);
 182  
     }
 183  
 
 184  
     /**
 185  
      * This method prepares the model used for the send simple notification message form.
 186  
      * @param request
 187  
      * @return Map<String, Object>
 188  
      */
 189  
     private Map<String, Object> setupModelForSendSimpleNotification(
 190  
             HttpServletRequest request) {
 191  0
         Map<String, Object> model = new HashMap<String, Object>();
 192  0
         model.put("defaultSender", request.getRemoteUser());
 193  0
         model.put("channels", notificationChannelService
 194  
                 .getAllNotificationChannels());
 195  0
         model.put("priorities", businessObjectDao
 196  
                 .findAll(NotificationPriority.class));
 197  
         // set sendDateTime to current datetime if not provided
 198  0
         String sendDateTime = request.getParameter("sendDateTime");
 199  0
         String currentDateTime = Util.getCurrentDateTime();
 200  0
         if (StringUtils.isEmpty(sendDateTime)) {
 201  0
             sendDateTime = currentDateTime;
 202  
         }
 203  0
         model.put("sendDateTime", sendDateTime);
 204  
 
 205  
         // retain the original date time or set to current if
 206  
         // it was not in the request
 207  0
         if (request.getParameter("originalDateTime") == null) {
 208  0
             model.put("originalDateTime", currentDateTime);
 209  
         } else {
 210  0
             model.put("originalDateTime", request.getParameter("originalDateTime"));
 211  
         }
 212  
 
 213  0
         model.put("userRecipients", request.getParameter("userRecipients"));
 214  0
         model.put("workgroupRecipients", request.getParameter("workgroupRecipients"));
 215  0
         model.put("workgroupNamespaceCodes", request.getParameter("workgroupNamespaceCodes"));
 216  
 
 217  0
         return model;
 218  
     }
 219  
 
 220  
     /**
 221  
      * This method handles submitting the actual simple notification message.
 222  
      * @param request
 223  
      * @param response
 224  
      * @return ModelAndView
 225  
      * @throws ServletException
 226  
      * @throws IOException
 227  
      */
 228  
     public ModelAndView submitSimpleNotificationMessage(
 229  
             HttpServletRequest request, HttpServletResponse response)
 230  
             throws ServletException, IOException {
 231  0
         LOG.debug("remoteUser: " + request.getRemoteUser());
 232  
 
 233  
         // obtain a workflow user object first
 234  
         //WorkflowIdDTO initiator = new WorkflowIdDTO(request.getRemoteUser());
 235  0
         String initiatorId = request.getRemoteUser();
 236  
 
 237  
         // now construct the workflow document, which will interact with workflow
 238  
         WorkflowDocument document;
 239  0
         Map<String, Object> model = new HashMap<String, Object>();
 240  
         String view;
 241  
         try {
 242  0
             document = NotificationWorkflowDocument.createNotificationDocument(
 243  
                     initiatorId,
 244  
                     NotificationConstants.KEW_CONSTANTS.SEND_NOTIFICATION_REQ_DOC_TYPE);
 245  
 
 246  
             //parse out the application content into a Notification BO
 247  0
             Notification notification = populateNotificationInstance(request,
 248  
                     model);
 249  
 
 250  
             // now get that content in an understandable XML format and pass into document
 251  0
             String notificationAsXml = messageContentService
 252  
                     .generateNotificationMessage(notification);
 253  
 
 254  0
             Map<String, String> attrFields = new HashMap<String, String>();
 255  0
             List<NotificationChannelReviewer> reviewers = notification.getChannel().getReviewers();
 256  0
             int ui = 0;
 257  0
             int gi = 0;
 258  0
             for (NotificationChannelReviewer reviewer : reviewers) {
 259  
                 String prefix;
 260  
                 int index;
 261  0
                 if (KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.equals(reviewer.getReviewerType())) {
 262  0
                     prefix = "user";
 263  0
                     index = ui;
 264  0
                     ui++;
 265  0
                 } else if (KimGroupMemberTypes.GROUP_MEMBER_TYPE.equals(reviewer.getReviewerType())) {
 266  0
                     prefix = "group";
 267  0
                     index = gi;
 268  0
                     gi++;
 269  
                 } else {
 270  0
                     LOG.error("Invalid type for reviewer " + reviewer.getReviewerId() + ": "
 271  
                             + reviewer.getReviewerType());
 272  0
                     continue;
 273  
                 }
 274  0
                 attrFields.put(prefix + index, reviewer.getReviewerId());
 275  0
             }
 276  0
             GenericAttributeContent gac = new GenericAttributeContent("channelReviewers");
 277  0
             document.setApplicationContent(notificationAsXml);
 278  0
             document.setAttributeContent("<attributeContent>" + gac.generateContent(attrFields) + "</attributeContent>");
 279  
 
 280  0
             document.setTitle(notification.getTitle());
 281  
 
 282  0
             document.route("This message was submitted via the simple notification message submission form by user "
 283  
                     + initiatorId);
 284  
 
 285  0
             view = "SendSimpleNotificationMessage";
 286  
 
 287  
             // This ain't pretty, but it gets the job done for now.
 288  0
             ErrorList el = new ErrorList();
 289  0
             el.addError("Notification(s) sent.");
 290  0
             model.put("errors", el);
 291  
 
 292  0
         } catch (ErrorList el) {
 293  
             // route back to the send form again
 294  0
             Map<String, Object> model2 = setupModelForSendSimpleNotification(request);
 295  0
             model.putAll(model2);
 296  0
             model.put("errors", el);
 297  
 
 298  0
             view = "SendSimpleNotificationMessage";
 299  0
         } catch (Exception e) {
 300  0
             throw new RuntimeException(e);
 301  0
         }
 302  
 
 303  0
         return new ModelAndView(view, model);
 304  
     }
 305  
 
 306  
     /**
 307  
      * This method creates a new Notification instance from the form values.
 308  
      * @param request
 309  
      * @param model
 310  
      * @return Notification
 311  
      * @throws IllegalArgumentException
 312  
      */
 313  
     private Notification populateNotificationInstance(
 314  
             HttpServletRequest request, Map<String, Object> model)
 315  
             throws IllegalArgumentException, ErrorList {
 316  0
         ErrorList errors = new ErrorList();
 317  
 
 318  0
         Notification notification = new Notification();
 319  
 
 320  
         // grab data from form
 321  
         // channel name
 322  0
         String channelName = request.getParameter("channelName");
 323  0
         if (StringUtils.isEmpty(channelName) || StringUtils.equals(channelName, NONE_CHANNEL)) {
 324  0
             errors.addError("You must choose a channel.");
 325  
         } else {
 326  0
             model.put("channelName", channelName);
 327  
         }
 328  
 
 329  
         // priority name
 330  0
         String priorityName = request.getParameter("priorityName");
 331  0
         if (StringUtils.isEmpty(priorityName)) {
 332  0
             errors.addError("You must choose a priority.");
 333  
         } else {
 334  0
             model.put("priorityName", priorityName);
 335  
         }
 336  
 
 337  
         // sender names
 338  0
         String senderNames = request.getParameter("senderNames");
 339  0
         String[] senders = null;
 340  0
         if (StringUtils.isEmpty(senderNames)) {
 341  0
             errors.addError("You must enter at least one sender.");
 342  
         } else {
 343  0
             senders = StringUtils.split(senderNames, ",");
 344  
 
 345  0
             model.put("senderNames", senderNames);
 346  
         }
 347  
 
 348  
         // delivery type
 349  0
         String deliveryType = request.getParameter("deliveryType");
 350  0
         if (StringUtils.isEmpty(deliveryType)) {
 351  0
             errors.addError("You must choose a type.");
 352  
         } else {
 353  0
             if (deliveryType
 354  
                     .equalsIgnoreCase(NotificationConstants.DELIVERY_TYPES.FYI)) {
 355  0
                 deliveryType = NotificationConstants.DELIVERY_TYPES.FYI;
 356  
             } else {
 357  0
                 deliveryType = NotificationConstants.DELIVERY_TYPES.ACK;
 358  
             }
 359  0
             model.put("deliveryType", deliveryType);
 360  
         }
 361  
 
 362  
         // get datetime when form was initially rendered
 363  0
         String originalDateTime = request.getParameter("originalDateTime");
 364  0
         Date origdate = null;
 365  0
         Date senddate = null;
 366  0
         Date removedate = null;
 367  
         try {
 368  0
             origdate = Util.parseUIDateTime(originalDateTime);
 369  0
         } catch (ParseException pe) {
 370  0
             errors.addError("Original date is invalid.");
 371  0
         }
 372  
         // send date time
 373  0
         String sendDateTime = request.getParameter("sendDateTime");
 374  0
         if (StringUtils.isBlank(sendDateTime)) {
 375  0
             sendDateTime = Util.getCurrentDateTime();
 376  
         }
 377  
 
 378  
         try {
 379  0
             senddate = Util.parseUIDateTime(sendDateTime);
 380  0
         } catch (ParseException pe) {
 381  0
             errors.addError("You specified an invalid Send Date/Time.  Please use the calendar picker.");
 382  0
         }
 383  
 
 384  0
         if (senddate != null && senddate.before(origdate)) {
 385  0
             errors.addError("Send Date/Time cannot be in the past.");
 386  
         }
 387  
 
 388  0
         model.put("sendDateTime", sendDateTime);
 389  
 
 390  
         // auto remove date time
 391  0
         String autoRemoveDateTime = request.getParameter("autoRemoveDateTime");
 392  0
         if (StringUtils.isNotBlank(autoRemoveDateTime)) {
 393  
             try {
 394  0
                 removedate = Util.parseUIDateTime(autoRemoveDateTime);
 395  0
             } catch (ParseException pe) {
 396  0
                 errors.addError("You specified an invalid Auto-Remove Date/Time.  Please use the calendar picker.");
 397  0
             }
 398  
 
 399  0
             if (removedate != null) {
 400  0
                 if (removedate.before(origdate)) {
 401  0
                     errors.addError("Auto-Remove Date/Time cannot be in the past.");
 402  0
                 } else if (senddate != null && removedate.before(senddate)) {
 403  0
                     errors.addError("Auto-Remove Date/Time cannot be before the Send Date/Time.");
 404  
                 }
 405  
             }
 406  
         }
 407  
 
 408  0
         model.put("autoRemoveDateTime", autoRemoveDateTime);
 409  
 
 410  
         // user recipient names
 411  0
         String[] userRecipients = parseUserRecipients(request);
 412  
 
 413  
         // workgroup recipient names
 414  0
         String[] workgroupRecipients = parseWorkgroupRecipients(request);
 415  
 
 416  
         // workgroup namespace codes
 417  0
         String[] workgroupNamespaceCodes = parseWorkgroupNamespaceCodes(request);
 418  
 
 419  
         // title
 420  0
         String title = request.getParameter("title");
 421  0
         if (!StringUtils.isEmpty(title)) {
 422  0
             model.put("title", title);
 423  
         } else {
 424  0
             errors.addError("You must fill in a title");
 425  
         }
 426  
 
 427  
         // message
 428  0
         String message = request.getParameter("message");
 429  0
         if (StringUtils.isEmpty(message)) {
 430  0
             errors.addError("You must fill in a message.");
 431  
         } else {
 432  0
             model.put("message", message);
 433  
         }
 434  
 
 435  
         // stop processing if there are errors
 436  0
         if (errors.getErrors().size() > 0) {
 437  0
             throw errors;
 438  
         }
 439  
 
 440  
         // now populate the notification BO instance
 441  0
         NotificationChannel channel = Util.retrieveFieldReference("channel",
 442  
                 "name", channelName, NotificationChannel.class,
 443  
                 businessObjectDao);
 444  0
         notification.setChannel(channel);
 445  
 
 446  0
         NotificationPriority priority = Util.retrieveFieldReference("priority",
 447  
                 "name", priorityName, NotificationPriority.class,
 448  
                 businessObjectDao);
 449  0
         notification.setPriority(priority);
 450  
 
 451  0
         NotificationContentType contentType = Util.retrieveFieldReference(
 452  
                 "contentType", "name",
 453  
                 NotificationConstants.CONTENT_TYPES.SIMPLE_CONTENT_TYPE,
 454  
                 NotificationContentType.class, businessObjectDao);
 455  0
         notification.setContentType(contentType);
 456  
 
 457  0
         NotificationProducer producer = Util
 458  
                 .retrieveFieldReference(
 459  
                         "producer",
 460  
                         "name",
 461  
                         NotificationConstants.KEW_CONSTANTS.NOTIFICATION_SYSTEM_USER_NAME,
 462  
                         NotificationProducer.class, businessObjectDao);
 463  0
         notification.setProducer(producer);
 464  
 
 465  0
         for (String senderName : senders) {
 466  0
             if (StringUtils.isEmpty(senderName)) {
 467  0
                 errors.addError("A sender's name cannot be blank.");
 468  
             } else {
 469  0
                 NotificationSender ns = new NotificationSender();
 470  0
                 ns.setSenderName(senderName.trim());
 471  0
                 notification.addSender(ns);
 472  
             }
 473  
         }
 474  
 
 475  0
         boolean recipientsExist = false;
 476  
 
 477  0
         if (userRecipients != null && userRecipients.length > 0) {
 478  0
             recipientsExist = true;
 479  0
             for (String userRecipientId : userRecipients) {
 480  0
                 if (isUserRecipientValid(userRecipientId, errors)) {
 481  0
                     NotificationRecipient recipient = new NotificationRecipient();
 482  0
                     recipient.setRecipientType(KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
 483  0
                     recipient.setRecipientId(userRecipientId);
 484  0
                     notification.addRecipient(recipient);
 485  
                 }
 486  
             }
 487  
         }
 488  
 
 489  0
         if (workgroupRecipients != null && workgroupRecipients.length > 0) {
 490  0
             recipientsExist = true;
 491  0
             if (workgroupNamespaceCodes != null && workgroupNamespaceCodes.length > 0) {
 492  0
                 if (workgroupNamespaceCodes.length == workgroupRecipients.length) {
 493  0
                     for (int i = 0; i < workgroupRecipients.length; i++) {
 494  0
                         if (isWorkgroupRecipientValid(workgroupRecipients[i], workgroupNamespaceCodes[i], errors)) {
 495  0
                             NotificationRecipient recipient = new NotificationRecipient();
 496  0
                             recipient.setRecipientType(KimGroupMemberTypes.GROUP_MEMBER_TYPE);
 497  0
                             recipient.setRecipientId(
 498  
                                     getGroupService().getGroupByName(workgroupNamespaceCodes[i],
 499  
                                             workgroupRecipients[i]).getId());
 500  0
                             notification.addRecipient(recipient);
 501  
                         }
 502  
                     }
 503  
                 } else {
 504  0
                     errors.addError("The number of groups must match the number of namespace codes");
 505  
                 }
 506  
             } else {
 507  0
                 errors.addError("You must specify a namespace code for every group name");
 508  
             }
 509  0
         } else if (workgroupNamespaceCodes != null && workgroupNamespaceCodes.length > 0) {
 510  0
             errors.addError("You must specify a group name for every namespace code");
 511  
         }
 512  
 
 513  
         // check to see if there were any errors
 514  0
         if (errors.getErrors().size() > 0) {
 515  0
             throw errors;
 516  
         }
 517  
 
 518  0
         notification.setTitle(title);
 519  
 
 520  0
         notification.setDeliveryType(deliveryType);
 521  
 
 522  
         // simpledateformat is not threadsafe, have to sync and validate
 523  0
         Date d = null;
 524  0
         if (StringUtils.isNotBlank(sendDateTime)) {
 525  
             try {
 526  0
                 d = Util.parseUIDateTime(sendDateTime);
 527  0
             } catch (ParseException pe) {
 528  0
                 errors.addError("You specified an invalid send date and time.  Please use the calendar picker.");
 529  0
             }
 530  0
             notification.setSendDateTime(new Timestamp(d.getTime()));
 531  
         }
 532  
 
 533  0
         Date d2 = null;
 534  0
         if (StringUtils.isNotBlank(autoRemoveDateTime)) {
 535  
             try {
 536  0
                 d2 = Util.parseUIDateTime(autoRemoveDateTime);
 537  0
                 if (d2.before(d)) {
 538  0
                     errors.addError("Auto Remove Date/Time cannot be before Send Date/Time.");
 539  
                 }
 540  0
             } catch (ParseException pe) {
 541  0
                 errors.addError("You specified an invalid auto remove date and time.  Please use the calendar picker.");
 542  0
             }
 543  0
             notification.setAutoRemoveDateTime(new Timestamp(d2.getTime()));
 544  
         }
 545  
 
 546  0
         if (!recipientsExist && !hasPotentialRecipients(notification)) {
 547  0
             errors.addError("You must specify at least one user or group recipient.");
 548  
         }
 549  
 
 550  
         // check to see if there were any errors
 551  0
         if (errors.getErrors().size() > 0) {
 552  0
             throw errors;
 553  
         }
 554  
 
 555  0
         notification
 556  
                 .setContent(NotificationConstants.XML_MESSAGE_CONSTANTS.CONTENT_SIMPLE_OPEN
 557  
                         + NotificationConstants.XML_MESSAGE_CONSTANTS.MESSAGE_OPEN
 558  
                         + message
 559  
                         + NotificationConstants.XML_MESSAGE_CONSTANTS.MESSAGE_CLOSE
 560  
                         + NotificationConstants.XML_MESSAGE_CONSTANTS.CONTENT_CLOSE);
 561  
 
 562  0
         return notification;
 563  
     }
 564  
 }