View Javadoc
1   /**
2    * Copyright 2005-2014 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  package org.kuali.rice.ken.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.ken.bo.NotificationMessageDelivery;
20  import org.kuali.rice.ken.document.kew.NotificationWorkflowDocument;
21  import org.kuali.rice.ken.service.NotificationMessageContentService;
22  import org.kuali.rice.ken.service.NotificationWorkflowDocumentService;
23  import org.kuali.rice.ken.util.NotificationConstants;
24  import org.kuali.rice.kew.api.WorkflowDocument;
25  import org.kuali.rice.kew.api.WorkflowRuntimeException;
26  import org.kuali.rice.kew.api.action.ActionRequest;
27  import org.kuali.rice.kew.api.action.ActionRequestType;
28  import org.kuali.rice.kim.api.identity.principal.Principal;
29  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
30  
31  import java.util.List;
32  
33  /**
34   * This class is responsible for interacting with KEW - this is the default implementation that
35   * leverages the KEW client API.
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class NotificationWorkflowDocumentServiceImpl implements NotificationWorkflowDocumentService {
39      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
40              .getLogger(NotificationWorkflowDocumentServiceImpl.class);
41  
42      private NotificationMessageContentService messageContentService;
43  
44      /**
45       * Constructs a NotificationWorkflowDocumentServiceImpl instance.
46       * @param messageContentService
47       */
48      public NotificationWorkflowDocumentServiceImpl(NotificationMessageContentService messageContentService) {
49          this.messageContentService = messageContentService;
50      }
51  
52      /**
53       * Implements by instantiating a NotificationWorkflowDocument, which in turn interacts with
54       * Workflow to set it up with an initiator of the passed in user id.
55       * @see org.kuali.rice.ken.service.NotificationWorkflowDocumentService#createAndAdHocRouteNotificationWorkflowDocument(org.kuali.rice.ken.bo.NotificationMessageDelivery,
56       *      java.lang.String, java.lang.String, java.lang.String)
57       */
58      public String createAndAdHocRouteNotificationWorkflowDocument(NotificationMessageDelivery messageDelivery,
59              String initiatorUserId,
60              String recipientUserId, String annotation) {
61          // obtain a workflow user object first
62          //WorkflowIdDTO initiator = new WorkflowIdDTO(initiatorUserId);
63  
64          // now construct the workflow document, which will interact with workflow
65          WorkflowDocument document;
66          if (StringUtils.isNotBlank(messageDelivery.getNotification().getDocTypeName())) {
67              document = NotificationWorkflowDocument.createNotificationDocument(initiatorUserId,
68                      messageDelivery.getNotification().getDocTypeName());
69          } else {
70              document = NotificationWorkflowDocument.createNotificationDocument(initiatorUserId);
71          }
72  
73          // this is our loose foreign key to our message delivery record in notification
74          document.setApplicationDocumentId(messageDelivery.getId().toString());
75          //document.setAppDocId(messageDelivery.getId().toString());
76  
77          // now add the content of the notification as XML to the document
78          document.setApplicationContent(messageContentService.generateNotificationMessage(
79                  messageDelivery.getNotification(), messageDelivery.getUserRecipientId()));
80  
81          if (!StringUtils.isBlank(messageDelivery.getNotification().getTitle())) {
82              document.setTitle(messageDelivery.getNotification().getTitle());
83          } else {
84              LOG.error("Encountered notification with no title set: Message Delivery #" + messageDelivery.getId()
85                      + ", Notification #" + messageDelivery.getNotification().getId());
86          }
87  
88          // now set up the ad hoc route
89          String actionRequested;
90          if (NotificationConstants.DELIVERY_TYPES.ACK.equals(messageDelivery.getNotification().getDeliveryType())) {
91              actionRequested = NotificationConstants.KEW_CONSTANTS.ACK_AD_HOC_ROUTE;
92          } else {
93              actionRequested = NotificationConstants.KEW_CONSTANTS.FYI_AD_HOC_ROUTE;
94          }
95  
96          // Clarification of ad hoc route call
97          // param 1 - actionRequested will be either ACK or FYI
98          // param 2 - annotation is whatever text we pass in to describe the transaction - this will be system generated
99          // 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 }