001 /**
002 * Copyright 2005-2012 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 */
016 package org.kuali.rice.ken.deliverer.impl;
017
018 import java.io.ByteArrayOutputStream;
019 import java.io.IOException;
020 import java.util.Properties;
021
022 import org.kuali.rice.ken.bo.NotificationMessageDelivery;
023 import org.kuali.rice.ken.core.GlobalNotificationServiceLocator;
024 import org.kuali.rice.ken.deliverer.NotificationMessageDeliverer;
025 import org.kuali.rice.ken.exception.NotificationAutoRemoveException;
026 import org.kuali.rice.ken.exception.NotificationMessageDeliveryException;
027 import org.kuali.rice.ken.service.NotificationWorkflowDocumentService;
028 import org.kuali.rice.ken.util.NotificationConstants;
029 import org.kuali.rice.ken.util.Util;
030 import org.kuali.rice.kew.api.WorkflowDocument;
031
032 /**
033 * This class is responsible for describing the default delivery mechanism for the system - the KEW
034 * Action List.
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037 public class KEWActionListMessageDeliverer implements NotificationMessageDeliverer {
038 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KEWActionListMessageDeliverer.class);
039
040 /**
041 * Property set in the attribute content that indicates the action received by workflow was
042 * initiated by the Notification System itself (and not an end user)
043 */
044 public static final String INTERNAL_COMMAND_FLAG = "internal_command";
045
046 private NotificationWorkflowDocumentService notificationWorkflowDocumentService;
047
048 /**
049 * Constructs a KEWActionListMessageDeliverer.java.
050 */
051 public KEWActionListMessageDeliverer() {
052 this.notificationWorkflowDocumentService = GlobalNotificationServiceLocator.getInstance()
053 .getNotificationWorkflowDocumentService();
054 }
055
056 /**
057 * This implementation leverages the workflow integration services to push this notification
058 * into the KEW action list.
059 * @see org.kuali.rice.ken.deliverer.NotificationMessageDeliverer#deliverMessage(org.kuali.rice.ken.bo.NotificationMessageDelivery)
060 */
061 public void deliverMessage(NotificationMessageDelivery messageDelivery) throws NotificationMessageDeliveryException {
062 // make the call to actually generate and ad-hoc route a workflow document
063 String documentId = notificationWorkflowDocumentService.createAndAdHocRouteNotificationWorkflowDocument(
064 messageDelivery,
065 Util.getNotificationSystemUser(),
066 messageDelivery.getUserRecipientId(),
067 NotificationConstants.KEW_CONSTANTS.GENERIC_DELIVERY_ANNOTATION);
068
069 // now set the workflow doc id into the message delivery's delivery system id
070 messageDelivery.setDeliverySystemId(documentId);
071 LOG.debug("Message Delivery: " + messageDelivery.toString());
072 }
073
074 /**
075 * This implementation does an auto-remove by "canceling" the workflow document associated with
076 * the message delivery record. This prevents the user from seeing the item in their list
077 * anymore.
078 * @see org.kuali.rice.ken.deliverer.NotificationMessageDeliverer#autoRemoveMessageDelivery(org.kuali.rice.ken.bo.NotificationMessageDelivery)
079 */
080 public void autoRemoveMessageDelivery(NotificationMessageDelivery messageDelivery)
081 throws NotificationAutoRemoveException {
082 // first retrieve the appropriate notification workflow document to "auto-remove" and proxy as the recipient
083 WorkflowDocument workflowDoc = null;
084 String sysId = messageDelivery.getDeliverySystemId();
085 if (sysId == null) {
086 LOG.error("NotificationMessageDelivery " + messageDelivery.getId()
087 + " is missing delivery system id (workflow document id");
088 // there is no possibility for recovery, so since there is no id, we'll just log an error and return successfully instead
089 // of throwing an exception
090 return;
091 }
092
093 workflowDoc = notificationWorkflowDocumentService.getNotificationWorkflowDocumentByDocumentId(
094 messageDelivery.getUserRecipientId(), sysId);
095
096 flagWorkflowDocument(workflowDoc);
097
098 notificationWorkflowDocumentService.clearAllFyisAndAcknowledgeNotificationWorkflowDocument(
099 messageDelivery.getUserRecipientId(), workflowDoc,
100 NotificationConstants.KEW_CONSTANTS.GENERIC_AUTO_REMOVE_ANNOTATION);
101 }
102
103 /**
104 * @see org.kuali.rice.ken.deliverer.NotificationMessageDeliverer#dismissMessageDelivery(org.kuali.rice.ken.bo.NotificationMessageDelivery,
105 * java.lang.String, java.lang.String)
106 */
107 public void dismissMessageDelivery(NotificationMessageDelivery messageDelivery, String user, String cause) {
108 // TODO: move hardcoded web controller actions here...
109 LOG.info("Dismissing as user '" + user + "' workflow document '" + messageDelivery.getDeliverySystemId()
110 + "' corresponding to message delivery #" + messageDelivery.getId() + " due to cause: " + cause);
111 if (NotificationConstants.AUTO_REMOVE_CAUSE.equals(cause)) {
112 // perform an auto-remove
113 // XXX: currently auto-removes are going through autoremove method
114 } else {
115 WorkflowDocument nwd;
116 nwd = notificationWorkflowDocumentService.getNotificationWorkflowDocumentByDocumentId(user,
117 messageDelivery.getDeliverySystemId());
118
119 flagWorkflowDocument(nwd);
120
121 if (NotificationConstants.ACK_CAUSE.equals(cause)) {
122 // moved from NotificationController, ack command
123 /*
124 * acknowledge using workflow docId
125 */
126 if (nwd.isAcknowledgeRequested()) {
127 nwd.acknowledge("This notification has been acknowledged.");
128 LOG.debug("acknowledged " + nwd.getTitle());
129 LOG.debug("status display value: " + nwd.getStatus().getLabel());
130 } else {
131 LOG.debug("Acknowledgement was not needed for document " + nwd.getDocumentId());
132 }
133 } else if (NotificationConstants.FYI_CAUSE.equals(cause)) {
134 // moved from NotificationController, fyi command
135 /*
136 * FYI using workflow docId
137 */
138 if (nwd.isFYIRequested()) {
139 nwd.fyi();
140 LOG.debug("fyi " + nwd.getTitle());
141 LOG.debug("status display value: " + nwd.getStatus().getLabel());
142 } else {
143 LOG.debug("FYI was not needed for document " + nwd.getDocumentId());
144 }
145 }
146 }
147 }
148
149 /**
150 * Marks the workflow document as originating from the Notification System, so that the
151 * Notification post-processor does not route the action back through the Notification System.
152 * @param doc the doc to monogram
153 */
154 protected void flagWorkflowDocument(WorkflowDocument doc) {
155 Properties p = new Properties();
156 p.setProperty(INTERNAL_COMMAND_FLAG, "true");
157 ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
158 try {
159 p.store(baos, null);
160 } catch (IOException ioe) {
161 throw new RuntimeException("Could not store properties", ioe);
162 }
163 doc.setAttributeContent("<whatever>" + new String(baos.toByteArray()) + "</whatever>");
164 }
165 }