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