001/** 002 * Copyright 2005-2015 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; 066 if (StringUtils.isNotBlank(messageDelivery.getNotification().getDocTypeName())) { 067 document = NotificationWorkflowDocument.createNotificationDocument(initiatorUserId, 068 messageDelivery.getNotification().getDocTypeName()); 069 } else { 070 document = NotificationWorkflowDocument.createNotificationDocument(initiatorUserId); 071 } 072 073 // this is our loose foreign key to our message delivery record in notification 074 document.setApplicationDocumentId(messageDelivery.getId().toString()); 075 //document.setAppDocId(messageDelivery.getId().toString()); 076 077 // now add the content of the notification as XML to the document 078 document.setApplicationContent(messageContentService.generateNotificationMessage( 079 messageDelivery.getNotification(), messageDelivery.getUserRecipientId())); 080 081 if (!StringUtils.isBlank(messageDelivery.getNotification().getTitle())) { 082 document.setTitle(messageDelivery.getNotification().getTitle()); 083 } else { 084 LOG.error("Encountered notification with no title set: Message Delivery #" + messageDelivery.getId() 085 + ", Notification #" + messageDelivery.getNotification().getId()); 086 } 087 088 // now set up the ad hoc route 089 String actionRequested; 090 if (NotificationConstants.DELIVERY_TYPES.ACK.equals(messageDelivery.getNotification().getDeliveryType())) { 091 actionRequested = NotificationConstants.KEW_CONSTANTS.ACK_AD_HOC_ROUTE; 092 } else { 093 actionRequested = NotificationConstants.KEW_CONSTANTS.FYI_AD_HOC_ROUTE; 094 } 095 096 // Clarification of ad hoc route call 097 // param 1 - actionRequested will be either ACK or FYI 098 // param 2 - annotation is whatever text we pass in to describe the transaction - this will be system generated 099 // param 3 - recipient is the person who will receive this request 100 // param 4 - this is the responsibilityParty (a.k.a the system that produced this request), so we'll put the producer name in there 101 // param 5 - this is the "force action" requests - if set to true, this will be delivered to the recipients list regardless of 102 // whether the recipient has already taken action on this request; in our case, this doesn't really apply at this point in time, 103 // so we'll set to true just to be safe 104 105 // recipientUserId will always be a principal ID due to code changes in NotificationMessageDeliveryResolverServiceImpl.buildCompleteRecipientList() 106 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(recipientUserId); 107 108 document.adHocToPrincipal(ActionRequestType.fromCode(actionRequested), annotation, principal.getPrincipalId(), 109 messageDelivery.getNotification().getProducer().getName(), true); 110 111 // now actually route it along its way 112 document.route(annotation); 113 114 return document.getDocumentId(); 115 } 116 117 /** 118 * This service method is implemented by constructing a NotificationWorkflowDocument using the 119 * pre-existing document Id that is passed in. 120 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#findNotificationWorkflowDocumentByDocumentId(java.lang.String, 121 * java.lang.String) 122 */ 123 public WorkflowDocument getNotificationWorkflowDocumentByDocumentId(String initiatorUserId, 124 String workflowDocumentId) { 125 // construct the workflow id value object 126 //WorkflowIdDTO initiator = new WorkflowIdDTO(initiatorUserId); 127 128 // now return the actual document instance 129 // this handles going out and getting the workflow document 130 return NotificationWorkflowDocument.loadNotificationDocument(initiatorUserId, workflowDocumentId); 131 } 132 133 /** 134 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#clearAllFyisAndAcknowledgeNotificationWorkflowDocument(java.lang.String, 135 * org.kuali.rice.ken.document.kew.NotificationWorkflowDocument, java.lang.String) 136 */ 137 public void clearAllFyisAndAcknowledgeNotificationWorkflowDocument(String initiatorUserId, 138 WorkflowDocument workflowDocument, String annotation) { 139 List<ActionRequest> reqs = workflowDocument.getRootActionRequests(); 140 for (int i = 0; i < reqs.size(); i++) { 141 LOG.info("Action Request[" + i + "] = " + reqs.get(i).getActionRequested()); 142 if (reqs.get(i).getActionRequested().equals(ActionRequestType.ACKNOWLEDGE)) { 143 workflowDocument.acknowledge(annotation); 144 } else if (reqs.get(i).getActionRequested().equals(ActionRequestType.FYI)) { 145 workflowDocument.logAnnotation(annotation); 146 workflowDocument.fyi(); 147 } else { 148 throw new WorkflowRuntimeException("Invalid notification action request in workflow document (" 149 + workflowDocument.getDocumentId() 150 + ") was encountered. Should be either an acknowledge or fyi and was not."); 151 } 152 } 153 } 154 155 /** 156 * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#terminateWorkflowDocument(org.kuali.rice.kew.api.WorkflowDocument) 157 */ 158 public void terminateWorkflowDocument(WorkflowDocument document) { 159 document.superUserCancel("terminating document: documentId=" + document.getDocumentId() + ", appDocId=" 160 + document.getApplicationDocumentId()); 161 } 162}