001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.ken.service.impl; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.ken.bo.NotificationMessageDelivery; 020import org.kuali.rice.ken.document.kew.NotificationWorkflowDocument; 021import org.kuali.rice.ken.service.NotificationMessageContentService; 022import org.kuali.rice.ken.service.NotificationWorkflowDocumentService; 023import org.kuali.rice.ken.util.NotificationConstants; 024import org.kuali.rice.kew.api.WorkflowDocument; 025import org.kuali.rice.kew.api.WorkflowRuntimeException; 026import org.kuali.rice.kew.api.action.ActionRequest; 027import org.kuali.rice.kew.api.action.ActionRequestType; 028import org.kuali.rice.kim.api.identity.principal.Principal; 029import org.kuali.rice.kim.api.services.KimApiServiceLocator; 030 031import java.util.List; 032 033/** 034 * This class is responsible for interacting with KEW - this is the default implementation that 035 * leverages the KEW client API. 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038public class NotificationWorkflowDocumentServiceImpl implements NotificationWorkflowDocumentService { 039 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger 040 .getLogger(NotificationWorkflowDocumentServiceImpl.class); 041 042 private NotificationMessageContentService messageContentService; 043 044 /** 045 * Constructs a NotificationWorkflowDocumentServiceImpl instance. 046 * @param messageContentService 047 */ 048 public NotificationWorkflowDocumentServiceImpl(NotificationMessageContentService messageContentService) { 049 this.messageContentService = messageContentService; 050 } 051 052 /** 053 * Implements by instantiating a NotificationWorkflowDocument, which in turn interacts with 054 * Workflow to set it up with an initiator of the passed in user id. 055 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#createAndAdHocRouteNotificationWorkflowDocument(org.kuali.rice.ken.bo.NotificationMessageDelivery, 056 * java.lang.String, java.lang.String, java.lang.String) 057 */ 058 public String createAndAdHocRouteNotificationWorkflowDocument(NotificationMessageDelivery messageDelivery, 059 String initiatorUserId, 060 String recipientUserId, String annotation) { 061 // obtain a workflow user object first 062 //WorkflowIdDTO initiator = new WorkflowIdDTO(initiatorUserId); 063 064 // now construct the workflow document, which will interact with workflow 065 WorkflowDocument document = NotificationWorkflowDocument.createNotificationDocument(initiatorUserId); 066 067 // this is our loose foreign key to our message delivery record in notification 068 document.setApplicationDocumentId(messageDelivery.getId().toString()); 069 //document.setAppDocId(messageDelivery.getId().toString()); 070 071 // now add the content of the notification as XML to the document 072 document.setApplicationContent(messageContentService.generateNotificationMessage( 073 messageDelivery.getNotification(), messageDelivery.getUserRecipientId())); 074 075 if (!StringUtils.isBlank(messageDelivery.getNotification().getTitle())) { 076 document.setTitle(messageDelivery.getNotification().getTitle()); 077 } else { 078 LOG.error("Encountered notification with no title set: Message Delivery #" + messageDelivery.getId() 079 + ", Notification #" + messageDelivery.getNotification().getId()); 080 } 081 082 // now set up the ad hoc route 083 String actionRequested; 084 if (NotificationConstants.DELIVERY_TYPES.ACK.equals(messageDelivery.getNotification().getDeliveryType())) { 085 actionRequested = NotificationConstants.KEW_CONSTANTS.ACK_AD_HOC_ROUTE; 086 } else { 087 actionRequested = NotificationConstants.KEW_CONSTANTS.FYI_AD_HOC_ROUTE; 088 } 089 090 // Clarification of ad hoc route call 091 // param 1 - actionRequested will be either ACK or FYI 092 // param 2 - annotation is whatever text we pass in to describe the transaction - this will be system generated 093 // param 3 - recipient is the person who will receive this request 094 // param 4 - this is the responsibilityParty (a.k.a the system that produced this request), so we'll put the producer name in there 095 // param 5 - this is the "force action" requests - if set to true, this will be delivered to the recipients list regardless of 096 // whether the recipient has already taken action on this request; in our case, this doesn't really apply at this point in time, 097 // so we'll set to true just to be safe 098 099 // recipientUserId will always be a principal ID due to code changes in NotificationMessageDeliveryResolverServiceImpl.buildCompleteRecipientList() 100 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(recipientUserId); 101 102 document.adHocToPrincipal(ActionRequestType.fromCode(actionRequested), annotation, principal.getPrincipalId(), 103 messageDelivery.getNotification().getProducer().getName(), true); 104 105 // now actually route it along its way 106 document.route(annotation); 107 108 return document.getDocumentId(); 109 } 110 111 /** 112 * This service method is implemented by constructing a NotificationWorkflowDocument using the 113 * pre-existing document Id that is passed in. 114 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#findNotificationWorkflowDocumentByDocumentId(java.lang.String, 115 * java.lang.String) 116 */ 117 public WorkflowDocument getNotificationWorkflowDocumentByDocumentId(String initiatorUserId, 118 String workflowDocumentId) { 119 // construct the workflow id value object 120 //WorkflowIdDTO initiator = new WorkflowIdDTO(initiatorUserId); 121 122 // now return the actual document instance 123 // this handles going out and getting the workflow document 124 return NotificationWorkflowDocument.loadNotificationDocument(initiatorUserId, workflowDocumentId); 125 } 126 127 /** 128 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#clearAllFyisAndAcknowledgeNotificationWorkflowDocument(java.lang.String, 129 * org.kuali.rice.ken.document.kew.NotificationWorkflowDocument, java.lang.String) 130 */ 131 public void clearAllFyisAndAcknowledgeNotificationWorkflowDocument(String initiatorUserId, 132 WorkflowDocument workflowDocument, String annotation) { 133 List<ActionRequest> reqs = workflowDocument.getRootActionRequests(); 134 for (int i = 0; i < reqs.size(); i++) { 135 LOG.info("Action Request[" + i + "] = " + reqs.get(i).getActionRequested()); 136 if (reqs.get(i).getActionRequested().equals(ActionRequestType.ACKNOWLEDGE)) { 137 workflowDocument.acknowledge(annotation); 138 } else if (reqs.get(i).getActionRequested().equals(ActionRequestType.FYI)) { 139 workflowDocument.logAnnotation(annotation); 140 workflowDocument.fyi(); 141 } else { 142 throw new WorkflowRuntimeException("Invalid notification action request in workflow document (" 143 + workflowDocument.getDocumentId() 144 + ") was encountered. Should be either an acknowledge or fyi and was not."); 145 } 146 } 147 } 148 149 /** 150 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#terminateWorkflowDocument(org.kuali.rice.kew.api.WorkflowDocument) 151 */ 152 public void terminateWorkflowDocument(WorkflowDocument document) { 153 document.superUserCancel("terminating document: documentId=" + document.getDocumentId() + ", appDocId=" 154 + document.getApplicationDocumentId()); 155 } 156}