1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.ken.web.spring;
17
18 import java.io.IOException;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.servlet.ServletException;
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.log4j.Logger;
29 import org.kuali.rice.ken.api.KenApiConstants;
30 import org.kuali.rice.ken.bo.NotificationBo;
31 import org.kuali.rice.ken.bo.NotificationMessageDelivery;
32 import org.kuali.rice.ken.bo.NotificationRecipientBo;
33 import org.kuali.rice.ken.bo.NotificationSenderBo;
34 import org.kuali.rice.ken.service.NotificationMessageDeliveryService;
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.api.KewApiConstants;
40 import org.kuali.rice.kew.api.KewApiServiceLocator;
41 import org.kuali.rice.kim.api.identity.principal.Principal;
42 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
43 import org.kuali.rice.krad.UserSession;
44 import org.kuali.rice.krad.util.KRADUtils;
45 import org.springframework.web.servlet.ModelAndView;
46 import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
47
48
49
50
51
52
53 public class NotificationController extends MultiActionController {
54
55 private static final Logger LOG = Logger.getLogger(NotificationController.class);
56
57 protected NotificationService notificationService;
58 protected NotificationWorkflowDocumentService notificationWorkflowDocService;
59 protected NotificationMessageDeliveryService messageDeliveryService;
60
61
62
63
64
65 public void setNotificationService(NotificationService notificationService) {
66 this.notificationService = notificationService;
67 }
68
69
70
71
72
73 public void setNotificationWorkflowDocumentService(NotificationWorkflowDocumentService s) {
74 this.notificationWorkflowDocService = s;
75 }
76
77
78
79
80
81 public void setMessageDeliveryService(NotificationMessageDeliveryService messageDeliveryService) {
82 this.messageDeliveryService = messageDeliveryService;
83 }
84
85
86
87
88
89
90
91
92
93 public ModelAndView displayHome(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
94 String view = "HomePage";
95 LOG.debug("remoteUser: "+request.getRemoteUser());
96 Map<String, Object> model = new HashMap<String, Object>();
97 return new ModelAndView(view, model);
98 }
99
100
101
102
103
104
105
106
107
108 public ModelAndView displayNotificationsSent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
109 String view = "NotificationsSent";
110 LOG.debug("remoteUser: "+request.getRemoteUser());
111 Map<String, Object> model = new HashMap<String, Object>();
112 model.put("userId", request.getRemoteUser());
113 return new ModelAndView(view, model);
114 }
115
116
117
118
119
120
121
122
123
124 public ModelAndView displaySearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
125 String view = "Search";
126 LOG.debug("remoteUser: "+request.getRemoteUser());
127 Map<String, Object> model = new HashMap<String, Object>();
128 return new ModelAndView(view, model);
129 }
130
131
132
133
134
135
136
137
138
139 public ModelAndView displayLookupUsers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
140 String view = "LookupUsers";
141 LOG.debug("remoteUser: "+request.getRemoteUser());
142 Map<String, Object> model = new HashMap<String, Object>();
143 return new ModelAndView(view, model);
144 }
145
146
147
148
149
150
151
152
153
154 public ModelAndView displayLookupWorkgroups(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
155 String view = "LookupWorkgroups";
156 LOG.debug("remoteUser: "+request.getRemoteUser());
157 Map<String, Object> model = new HashMap<String, Object>();
158 return new ModelAndView(view, model);
159 }
160
161
162
163
164
165
166
167
168
169 protected NotificationMessageDelivery determineMessageFromRequest(HttpServletRequest request) {
170
171
172
173
174
175 String messageDeliveryId = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.MSG_DELIVERY_ID);
176 String delivererId = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.DELIVERER_ID);
177 if (delivererId == null) {
178 delivererId = request.getParameter(KewApiConstants.DOCUMENT_ID_PARAMETER);
179 }
180
181 NotificationMessageDelivery messageDelivery;
182 if (messageDeliveryId != null) {
183 LOG.debug("Looking up notification with messageDeliveryId: "+messageDeliveryId);
184 try {
185 messageDelivery = messageDeliveryService.getNotificationMessageDelivery(new Long(messageDeliveryId));
186 } catch (Exception e) {
187 throw new RuntimeException("Error getting message with id: " + messageDeliveryId, e);
188 }
189 } else if (delivererId != null) {
190 LOG.debug("Looking up notification with workflowId: "+delivererId);
191 try {
192 messageDelivery = messageDeliveryService.getNotificationMessageDeliveryByDelivererId(delivererId);
193 } catch (Exception e) {
194 LOG.error("Error getting message with from deliverer id: " + delivererId, e);
195 throw new RuntimeException("Error getting message with deliverer id: " + delivererId, e);
196 }
197 } else {
198 throw new RuntimeException("Neither message ('" + NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.MSG_DELIVERY_ID
199 + "') nor deliverer id ('" + NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.DELIVERER_ID + "') were specified in the request");
200 }
201
202 return messageDelivery;
203 }
204
205
206
207
208
209 protected boolean requestIsFromKEW(HttpServletRequest req) {
210 return req.getParameter(KewApiConstants.DOCUMENT_ID_PARAMETER) != null;
211 }
212
213
214
215
216
217
218
219
220
221 public ModelAndView displayNotificationDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
222 String view = "NotificationDetail";
223
224 UserSession userSession = KRADUtils.getUserSessionFromRequest(request);
225 String principalId = "";
226 if(userSession != null) {
227 principalId = userSession.getPrincipalId();
228 if(StringUtils.isBlank(principalId)) {
229 String principalName = request.getRemoteUser();
230 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName);
231 if(principal != null) {
232 principalId = principal.getPrincipalId();
233 } else {
234 throw new RuntimeException("There is no principal for principalName " + principalName);
235 }
236 }
237 }
238
239 String command = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.COMMAND);
240 String standaloneWindow = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.STANDALONE_WINDOW);
241
242 NotificationMessageDelivery messageDelivery = determineMessageFromRequest(request);
243
244 NotificationBo notification = messageDelivery.getNotification();
245 boolean actionable = false;
246
247 if (requestIsFromKEW(request)) {
248
249 if(command != null &&
250 (command.equals(NotificationConstants.NOTIFICATION_DETAIL_VIEWS.NORMAL_VIEW) ||
251 command.equals(NotificationConstants.NOTIFICATION_DETAIL_VIEWS.DOC_SEARCH_VIEW))) {
252 standaloneWindow = "true";
253 }
254
255
256 command = NotificationConstants.NOTIFICATION_DETAIL_VIEWS.INLINE;
257 }
258
259 actionable = (principalId).equals(messageDelivery.getUserRecipientId()) && NotificationConstants.MESSAGE_DELIVERY_STATUS.DELIVERED.equals(messageDelivery.getMessageDeliveryStatus());
260
261 String documentId = request.getParameter(KewApiConstants.DOCUMENT_ID_PARAMETER);
262 if(StringUtils.isNotBlank(documentId)) {
263 boolean authorized = KewApiServiceLocator.getWorkflowDocumentActionsService().isUserInRouteLog(documentId, principalId, false);
264 LOG.debug("User in route log = " + authorized);
265 if(!authorized) {
266 Map<String, String> permissionDetails = new HashMap<String, String>();
267 permissionDetails.put(KenApiConstants.KIMTypes.Channel.CHANNEL_ID, notification.getChannel().getId().toString());
268 Map<String, String> qualification = new HashMap<String, String>();
269 authorized = KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(principalId, KenApiConstants.Namespaces.CODE, KenApiConstants.Permissions.VIEW_NOTIFICATION, permissionDetails, qualification);
270 LOG.debug("User has 'View Notification' permission = " + authorized);
271 if(!authorized) {
272 return new ModelAndView("NotAuthorized");
273 }
274 }
275 }
276
277 List<NotificationSenderBo> senders = notification.getSenders();
278 List<NotificationRecipientBo> recipients = notification.getRecipients();
279
280 String contenthtml = Util.transformContent(notification);
281
282
283 if (command != null && command.equals(NotificationConstants.NOTIFICATION_DETAIL_VIEWS.INLINE)) {
284 view = "NotificationDetailInline";
285 }
286
287 Map<String, Object> model = new HashMap<String, Object>();
288 model.put("notification", notification);
289 model.put("senders", senders);
290 model.put("recipients", recipients);
291 model.put("contenthtml", contenthtml);
292 model.put("messageDeliveryId", messageDelivery.getId());
293 model.put("command", command);
294 model.put("actionable", actionable);
295 model.put(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.STANDALONE_WINDOW, standaloneWindow);
296 return new ModelAndView(view, model);
297 }
298
299
300
301
302
303
304
305 public ModelAndView dismissMessage(HttpServletRequest request, HttpServletResponse response) {
306 String command = request.getParameter("action");
307 if (command == null) throw new RuntimeException("Dismissal command not specified");
308
309 if (NotificationConstants.ACK_CAUSE.equals(command)) {
310 return dismissMessage(command, "Notificaton acknowledged. Please refresh your action list.", request, response);
311 } else if (NotificationConstants.FYI_CAUSE.equals(command)) {
312 return dismissMessage(command, "Action Taken. Please refresh your action list.", request, response);
313 } else {
314 throw new RuntimeException("Unknown dismissal command: " + command);
315 }
316 }
317
318
319
320
321
322
323
324
325
326
327 private ModelAndView dismissMessage(String action, String message, HttpServletRequest request, HttpServletResponse response) {
328 String view = "NotificationDetail";
329
330 String principalNm = request.getRemoteUser();
331 String messageDeliveryId = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.MSG_DELIVERY_ID);
332 String command = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.COMMAND);
333 String standaloneWindow = request.getParameter(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.STANDALONE_WINDOW);
334
335 if (messageDeliveryId == null) {
336 throw new RuntimeException("A null messageDeliveryId was provided.");
337 }
338
339 LOG.debug("messageDeliveryId: "+messageDeliveryId);
340 LOG.debug("command: "+command);
341
342
343
344
345
346
347 NotificationMessageDelivery delivery = messageDeliveryService.getNotificationMessageDelivery(Long.decode(messageDeliveryId));
348 if (delivery == null) {
349 throw new RuntimeException("Could not find message delivery with id " + messageDeliveryId);
350 }
351 NotificationBo notification = delivery.getNotification();
352
353
354
355
356
357 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalNm);
358 notificationService.dismissNotificationMessageDelivery(delivery.getId(), principal.getPrincipalId(), action);
359
360 List<NotificationSenderBo> senders = notification.getSenders();
361 List<NotificationRecipientBo> recipients = notification.getRecipients();
362
363 String contenthtml = Util.transformContent(notification);
364
365
366 if(standaloneWindow != null && standaloneWindow.equals("true")) {
367 view = "NotificationActionTakenCloseWindow";
368 } else {
369 if (command != null && command.equals(NotificationConstants.NOTIFICATION_DETAIL_VIEWS.INLINE)) {
370 view = "NotificationDetailInline";
371 }
372 }
373
374 Map<String, Object> model = new HashMap<String, Object>();
375 model.put("notification", notification);
376 model.put("message", message);
377 model.put("senders", senders);
378 model.put("recipients", recipients);
379 model.put("contenthtml", contenthtml);
380 model.put("messageDeliveryId", messageDeliveryId);
381 model.put("command", command);
382 model.put(NotificationConstants.NOTIFICATION_CONTROLLER_CONSTANTS.STANDALONE_WINDOW, standaloneWindow);
383 return new ModelAndView(view, model);
384 }
385 }