1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.document;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.ArrayUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.kuali.rice.core.api.CoreApiServiceLocator;
22 import org.kuali.rice.core.api.config.property.ConfigContext;
23 import org.kuali.rice.core.api.config.property.ConfigurationService;
24 import org.kuali.rice.core.api.exception.RiceRuntimeException;
25 import org.kuali.rice.core.api.util.RiceKeyConstants;
26 import org.kuali.rice.coreservice.framework.parameter.ParameterConstants;
27 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
28 import org.kuali.rice.kew.api.KewApiConstants;
29 import org.kuali.rice.kew.api.KewApiServiceLocator;
30 import org.kuali.rice.kew.api.WorkflowDocument;
31 import org.kuali.rice.kew.api.action.ActionRequest;
32 import org.kuali.rice.kew.api.action.ActionRequestType;
33 import org.kuali.rice.kew.api.action.DocumentActionParameters;
34 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
35 import org.kuali.rice.kew.api.doctype.DocumentType;
36 import org.kuali.rice.kew.api.exception.WorkflowException;
37 import org.kuali.rice.kim.api.identity.Person;
38 import org.kuali.rice.krad.UserSessionUtils;
39 import org.kuali.rice.krad.bo.AdHocRouteRecipient;
40 import org.kuali.rice.krad.bo.Attachment;
41 import org.kuali.rice.krad.bo.DocumentHeader;
42 import org.kuali.rice.krad.bo.Note;
43 import org.kuali.rice.krad.exception.DocumentAuthorizationException;
44 import org.kuali.rice.krad.exception.UnknownDocumentIdException;
45 import org.kuali.rice.krad.exception.ValidationException;
46 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
47 import org.kuali.rice.krad.rules.rule.event.AddNoteEvent;
48 import org.kuali.rice.krad.rules.rule.event.DocumentEvent;
49 import org.kuali.rice.krad.rules.rule.event.RouteDocumentEvent;
50 import org.kuali.rice.krad.rules.rule.event.SaveDocumentEvent;
51 import org.kuali.rice.krad.service.AttachmentService;
52 import org.kuali.rice.krad.service.DataDictionaryService;
53 import org.kuali.rice.krad.service.DocumentDictionaryService;
54 import org.kuali.rice.krad.service.DocumentService;
55 import org.kuali.rice.krad.service.KRADServiceLocator;
56 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
57 import org.kuali.rice.krad.service.LegacyDataAdapter;
58 import org.kuali.rice.krad.service.NoteService;
59 import org.kuali.rice.krad.uif.UifConstants;
60 import org.kuali.rice.krad.uif.UifParameters;
61 import org.kuali.rice.krad.uif.UifPropertyPaths;
62 import org.kuali.rice.krad.uif.component.BindingInfo;
63 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
64 import org.kuali.rice.krad.uif.view.DocumentView;
65 import org.kuali.rice.krad.util.GlobalVariables;
66 import org.kuali.rice.krad.util.KRADConstants;
67 import org.kuali.rice.krad.util.KRADUtils;
68 import org.kuali.rice.krad.util.NoteType;
69 import org.kuali.rice.krad.web.form.DialogResponse;
70 import org.kuali.rice.krad.web.form.DocumentFormBase;
71 import org.kuali.rice.krad.web.form.UifFormBase;
72 import org.kuali.rice.krad.web.service.CollectionControllerService;
73 import org.kuali.rice.krad.web.service.ModelAndViewService;
74 import org.kuali.rice.krad.web.service.NavigationControllerService;
75 import org.kuali.rice.krad.web.service.impl.ControllerServiceImpl;
76 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
77 import org.springframework.web.multipart.MultipartFile;
78 import org.springframework.web.servlet.ModelAndView;
79
80 import javax.servlet.http.HttpServletResponse;
81 import javax.xml.namespace.QName;
82 import java.io.IOException;
83 import java.util.ArrayList;
84 import java.util.List;
85 import java.util.Properties;
86 import java.util.Set;
87
88
89
90
91
92
93 public class DocumentControllerServiceImpl extends ControllerServiceImpl implements DocumentControllerService {
94 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
95 DocumentControllerServiceImpl.class);
96
97
98 protected static final String[] DOCUMENT_LOAD_COMMANDS =
99 {KewApiConstants.ACTIONLIST_COMMAND, KewApiConstants.DOCSEARCH_COMMAND, KewApiConstants.SUPERUSER_COMMAND,
100 KewApiConstants.HELPDESK_ACTIONLIST_COMMAND};
101 protected static final String SENSITIVE_DATA_DIALOG = "DialogGroup-SensitiveData";
102 protected static final String EXPLANATION_DIALOG = "DisapproveExplanationDialog";
103
104 private LegacyDataAdapter legacyDataAdapter;
105 private DataDictionaryService dataDictionaryService;
106 private DocumentService documentService;
107 private DocumentDictionaryService documentDictionaryService;
108 private AttachmentService attachmentService;
109 private NoteService noteService;
110 private ModelAndViewService modelAndViewService;
111 private NavigationControllerService navigationControllerService;
112 private ConfigurationService configurationService;
113 private CollectionControllerService collectionControllerService;
114 private ParameterService parameterService;
115
116
117
118
119
120
121
122
123 @Override
124 public ModelAndView docHandler(DocumentFormBase form) throws WorkflowException {
125 String command = form.getCommand();
126 DocumentView view = (DocumentView) form.getView();
127
128 if (ArrayUtils.contains(DOCUMENT_LOAD_COMMANDS, command) && (form.getDocId() != null)) {
129 checkReturnLocationForDocSearch(command, form);
130
131 loadDocument(form);
132
133 if (KewApiConstants.SUPERUSER_COMMAND.equals(command)) {
134 view.setSuperUserView(true);
135 }
136 } else if (KewApiConstants.INITIATE_COMMAND.equals(command)) {
137 if (view != null) {
138 form.setApplyDefaultValues(true);
139 }
140
141 createDocument(form);
142 } else {
143 LOG.error("docHandler called with invalid parameters");
144 throw new IllegalArgumentException("docHandler called with invalid parameters");
145 }
146
147 return getModelAndViewService().getModelAndView(form);
148 }
149
150
151
152
153
154
155
156
157 private void checkReturnLocationForDocSearch(String command, DocumentFormBase form) {
158 if (KewApiConstants.DOCSEARCH_COMMAND.equals(command)) {
159 form.setReturnLocation(ConfigContext.getCurrentContextConfig().getProperty(KRADConstants.APPLICATION_URL_KEY));
160 }
161 }
162
163
164
165
166
167
168
169
170
171 protected void loadDocument(DocumentFormBase form) throws WorkflowException {
172 String docId = form.getDocId();
173
174 if (LOG.isDebugEnabled()) {
175 LOG.debug("Loading document" + docId);
176 }
177
178 Document document = getDocumentService().getByDocumentHeaderId(docId);
179 if (document == null) {
180 throw new UnknownDocumentIdException(
181 "Document no longer exists. It may have been cancelled before being saved.");
182 }
183
184 WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
185 if (!getDocumentDictionaryService().getDocumentAuthorizer(document).canOpen(document,
186 GlobalVariables.getUserSession().getPerson())) {
187 throw buildAuthorizationException("open", document);
188 }
189
190
191
192 if (workflowDocument != document.getDocumentHeader().getWorkflowDocument()) {
193 LOG.warn("Workflow document changed via canOpen check");
194 document.getDocumentHeader().setWorkflowDocument(workflowDocument);
195 }
196
197 form.setDocument(document);
198 form.setDocTypeName(workflowDocument.getDocumentTypeName());
199
200 UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDocument);
201 }
202
203
204
205
206
207
208
209
210
211 protected void createDocument(DocumentFormBase form) throws WorkflowException {
212 if (LOG.isDebugEnabled()) {
213 LOG.debug("Creating new document instance for doc type: " + form.getDocTypeName());
214 }
215
216 Document doc = getDocumentService().getNewDocument(form.getDocTypeName());
217
218 form.setDocument(doc);
219 form.setDocTypeName(doc.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
220 }
221
222
223
224
225 @Override
226 public ModelAndView cancel(UifFormBase form) {
227 performWorkflowAction((DocumentFormBase) form, UifConstants.WorkflowAction.CANCEL);
228
229 return getNavigationControllerService().returnToPrevious(form);
230 }
231
232
233
234
235 @Override
236 public ModelAndView reload(DocumentFormBase form) throws WorkflowException {
237 Document document = form.getDocument();
238
239
240 form.setDocId(document.getDocumentNumber());
241 form.setCommand(DOCUMENT_LOAD_COMMANDS[1]);
242
243 form.setEvaluateFlagsAndModes(true);
244 form.setCanEditView(null);
245
246 GlobalVariables.getMessageMap().putInfo(KRADConstants.GLOBAL_MESSAGES, RiceKeyConstants.MESSAGE_RELOADED);
247
248 return docHandler(form);
249 }
250
251
252
253
254 @Override
255 public ModelAndView recall(DocumentFormBase form) {
256 performWorkflowAction(form, UifConstants.WorkflowAction.RECALL);
257
258 return getModelAndViewService().getModelAndView(form);
259 }
260
261
262
263
264 @Override
265 public ModelAndView save(DocumentFormBase form) {
266 return save(form, null);
267 }
268
269
270
271
272 @Override
273 public ModelAndView save(DocumentFormBase form, SaveDocumentEvent saveDocumentEvent) {
274 Document document = form.getDocument();
275
276
277 String explanation = document.getDocumentHeader().getExplanation();
278 ModelAndView sensitiveDataDialogModelAndView = checkSensitiveDataAndWarningDialog(explanation, form);
279
280
281 if (sensitiveDataDialogModelAndView != null) {
282 return sensitiveDataDialogModelAndView;
283 }
284
285 performWorkflowAction(form, UifConstants.WorkflowAction.SAVE, saveDocumentEvent);
286
287 return getModelAndViewService().getModelAndView(form);
288 }
289
290
291
292
293 @Override
294 public ModelAndView complete(DocumentFormBase form) {
295 performWorkflowAction(form, UifConstants.WorkflowAction.COMPLETE);
296
297 return getModelAndViewService().getModelAndView(form);
298 }
299
300
301
302
303 @Override
304 public ModelAndView route(DocumentFormBase form) {
305 performWorkflowAction(form, UifConstants.WorkflowAction.ROUTE);
306
307 return getModelAndViewService().getModelAndView(form);
308 }
309
310
311
312
313 @Override
314 public ModelAndView blanketApprove(DocumentFormBase form) {
315 Document document = form.getDocument();
316 WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
317
318
319 List<AdHocRouteRecipient> adHocRecipients = new ArrayList<AdHocRouteRecipient>();
320 adHocRecipients.addAll(document.getAdHocRoutePersons());
321 adHocRecipients.addAll(document.getAdHocRouteWorkgroups());
322
323
324 for (AdHocRouteRecipient adHocRouteRecipient : adHocRecipients) {
325 String actionRequestedCode = adHocRouteRecipient.getActionRequested();
326
327
328 if (KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(actionRequestedCode)) {
329 GlobalVariables.getMessageMap().putError(KRADConstants.NEW_AD_HOC_ROUTE_WORKGROUP_PROPERTY_NAME,
330 RiceKeyConstants.ERROR_ADHOC_COMPLETE_BLANKET_APPROVE_NOT_ALLOWED);
331
332 return getModelAndViewService().getModelAndView(form);
333 }
334 }
335
336 performWorkflowAction(form, UifConstants.WorkflowAction.BLANKETAPPROVE);
337
338 if (GlobalVariables.getMessageMap().hasErrors()) {
339 return getModelAndViewService().getModelAndView(form);
340 }
341
342 return getNavigationControllerService().returnToPrevious(form);
343 }
344
345
346
347
348 @Override
349 public ModelAndView approve(DocumentFormBase form) {
350 performWorkflowAction(form, UifConstants.WorkflowAction.APPROVE);
351
352 return getNavigationControllerService().returnToPrevious(form);
353 }
354
355
356
357
358 @Override
359 public ModelAndView disapprove(DocumentFormBase form) {
360
361 String explanationData = generateDisapprovalNote(form);
362 ModelAndView sensitiveDataDialogModelAndView = checkSensitiveDataAndWarningDialog(explanationData, form);
363
364
365 if (sensitiveDataDialogModelAndView != null) {
366 return sensitiveDataDialogModelAndView;
367 }
368
369 performWorkflowAction(form, UifConstants.WorkflowAction.DISAPPROVE);
370
371 return getNavigationControllerService().returnToPrevious(form);
372 }
373
374
375
376
377
378
379
380 protected String generateDisapprovalNote(DocumentFormBase form) {
381 String explanationData = form.getDialogExplanations().get(EXPLANATION_DIALOG);
382 if(explanationData == null) {
383 return "";
384 }
385
386
387 String introNoteMessage = getConfigurationService().getPropertyValueAsString(
388 RiceKeyConstants.MESSAGE_DISAPPROVAL_NOTE_TEXT_INTRO) + KRADConstants.BLANK_SPACE;
389
390 return introNoteMessage + explanationData;
391 }
392
393
394
395
396 @Override
397 public ModelAndView fyi(DocumentFormBase form) {
398 performWorkflowAction(form, UifConstants.WorkflowAction.FYI);
399
400 return getNavigationControllerService().returnToPrevious(form);
401 }
402
403
404
405
406 @Override
407 public ModelAndView acknowledge(DocumentFormBase form) {
408 performWorkflowAction(form, UifConstants.WorkflowAction.ACKNOWLEDGE);
409
410 return getNavigationControllerService().returnToPrevious(form);
411 }
412
413
414
415
416 @Override
417 public ModelAndView sendAdHocRequests(DocumentFormBase form) {
418 performWorkflowAction(form, UifConstants.WorkflowAction.SENDADHOCREQUESTS);
419
420 return getModelAndViewService().getModelAndView(form);
421 }
422
423
424
425
426 @Override
427 public ModelAndView supervisorFunctions(DocumentFormBase form) {
428 String workflowSuperUserUrl = getConfigurationService().getPropertyValueAsString(KRADConstants.WORKFLOW_URL_KEY)
429 + "/"
430 + KRADConstants.SUPERUSER_ACTION;
431
432 Properties props = new Properties();
433 props.setProperty(UifParameters.METHOD_TO_CALL, UifConstants.MethodToCallNames.DISPLAY_SUPER_USER_DOCUMENT);
434 props.setProperty(UifPropertyPaths.DOCUMENT_ID, form.getDocument().getDocumentNumber());
435
436 return getModelAndViewService().performRedirect(form, workflowSuperUserUrl, props);
437 }
438
439
440
441
442 @Override
443 public ModelAndView close(DocumentFormBase form) {
444 return getNavigationControllerService().returnToPrevious(form);
445 }
446
447
448
449
450
451
452
453 @Override
454 public ModelAndView insertNote(DocumentFormBase form) {
455 Document document = form.getDocument();
456
457 Note newNote = getAddLineNoteInstance(form);
458 setNewNoteProperties(form, document, newNote);
459
460 Attachment attachment = getNewNoteAttachment(form, document, newNote);
461
462
463 boolean rulesPassed = KRADServiceLocatorWeb.getKualiRuleService().applyRules(new AddNoteEvent(document,
464 newNote));
465 if (!rulesPassed) {
466 return getModelAndViewService().getModelAndView(form);
467 }
468
469
470
471
472 if (attachment != null) {
473 newNote.addAttachment(attachment);
474 }
475
476
477 ModelAndView sensitiveDataDialogModelAndView = checkSensitiveDataAndWarningDialog(newNote.getNoteText(), form);
478 if (sensitiveDataDialogModelAndView != null) {
479 return sensitiveDataDialogModelAndView;
480 }
481
482 saveNewNote(form, document, newNote);
483
484 return getCollectionControllerService().addLine(form);
485 }
486
487
488
489
490
491
492
493 protected Note getAddLineNoteInstance(DocumentFormBase form) {
494 String selectedCollectionId = form.getActionParamaterValue(UifParameters.SELECTED_COLLECTION_ID);
495
496 BindingInfo addLineBindingInfo = (BindingInfo) form.getViewPostMetadata().getComponentPostData(
497 selectedCollectionId, UifConstants.PostMetadata.ADD_LINE_BINDING_INFO);
498
499 String addLinePath = addLineBindingInfo.getBindingPath();
500 Object addLine = ObjectPropertyUtils.getPropertyValue(form, addLinePath);
501
502 return (Note) addLine;
503 }
504
505
506
507
508
509
510
511
512 protected void setNewNoteProperties(DocumentFormBase form, Document document, Note newNote) {
513 newNote.setNotePostedTimestampToCurrent();
514 newNote.setRemoteObjectIdentifier(document.getNoteTarget().getObjectId());
515
516 Person kualiUser = GlobalVariables.getUserSession().getPerson();
517 if (kualiUser == null) {
518 throw new IllegalStateException("Current UserSession has a null Person.");
519 }
520
521 newNote.setAuthorUniversalIdentifier(kualiUser.getPrincipalId());
522 }
523
524
525
526
527
528
529
530
531
532 protected Attachment getNewNoteAttachment(DocumentFormBase form, Document document, Note newNote) {
533 MultipartFile attachmentFile = form.getAttachmentFile();
534
535 if ((attachmentFile == null) || StringUtils.isBlank(attachmentFile.getOriginalFilename())) {
536 return null;
537 }
538
539 if (attachmentFile.getSize() == 0) {
540 GlobalVariables.getMessageMap().putError(String.format("%s.%s",
541 KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME, KRADConstants.NOTE_ATTACHMENT_FILE_PROPERTY_NAME),
542 RiceKeyConstants.ERROR_UPLOADFILE_EMPTY, attachmentFile.getOriginalFilename());
543
544 return null;
545 }
546
547 String attachmentTypeCode = null;
548 if (newNote.getAttachment() != null) {
549 attachmentTypeCode = newNote.getAttachment().getAttachmentTypeCode();
550 }
551
552 DocumentAuthorizer documentAuthorizer = getDocumentDictionaryService().getDocumentAuthorizer(document);
553 if (!documentAuthorizer.canAddNoteAttachment(document, attachmentTypeCode,
554 GlobalVariables.getUserSession().getPerson())) {
555 throw buildAuthorizationException("annotate", document);
556 }
557
558 Attachment attachment;
559 try {
560 attachment = getAttachmentService().createAttachment(document.getNoteTarget(),
561 attachmentFile.getOriginalFilename(), attachmentFile.getContentType(),
562 (int) attachmentFile.getSize(), attachmentFile.getInputStream(), attachmentTypeCode);
563 } catch (IOException e) {
564 throw new RiceRuntimeException("Unable to store attachment", e);
565 }
566
567 return attachment;
568 }
569
570
571
572
573
574
575
576
577 protected void saveNewNote(DocumentFormBase form, Document document, Note newNote) {
578 DocumentHeader documentHeader = document.getDocumentHeader();
579
580 if (!documentHeader.getWorkflowDocument().isInitiated() && StringUtils.isNotEmpty(
581 document.getNoteTarget().getObjectId()) && !(document instanceof MaintenanceDocument && NoteType
582 .BUSINESS_OBJECT.getCode().equals(newNote.getNoteTypeCode()))) {
583
584 getNoteService().save(newNote);
585 }
586 }
587
588
589
590
591 @Override
592 public ModelAndView deleteNote(DocumentFormBase form) {
593 String selectedLineIndex = form.getActionParamaterValue(UifParameters.SELECTED_LINE_INDEX);
594
595 Document document = form.getDocument();
596
597 Note note = document.getNote(Integer.parseInt(selectedLineIndex));
598 Attachment attachment = note.getAttachment();
599
600 String attachmentTypeCode = null;
601 if (attachment != null) {
602 attachmentTypeCode = attachment.getAttachmentTypeCode();
603 }
604
605
606 Person user = GlobalVariables.getUserSession().getPerson();
607 if (!getDocumentDictionaryService().getDocumentAuthorizer(document).canDeleteNoteAttachment(document,
608 attachmentTypeCode, note.getAuthorUniversalIdentifier(), user)) {
609 throw buildAuthorizationException("annotate", document);
610 }
611
612 if (attachment != null && attachment.isComplete()) {
613 getAttachmentService().deleteAttachmentContents(attachment);
614 }
615
616
617 if (!document.getDocumentHeader().getWorkflowDocument().isInitiated()) {
618 getNoteService().deleteNote(note);
619 }
620
621 return getCollectionControllerService().deleteLine(form);
622 }
623
624
625
626
627
628
629
630 @Override
631 public ModelAndView downloadAttachment(DocumentFormBase form, HttpServletResponse response) {
632 Attachment attachment = null;
633
634 String selectedLineIndex = form.getActionParamaterValue(UifParameters.SELECTED_LINE_INDEX);
635 if (StringUtils.isNotBlank(selectedLineIndex)) {
636 Note note = form.getDocument().getNote(Integer.parseInt(selectedLineIndex));
637 attachment = note.getAttachment();
638 } else {
639 Long noteIdentifier = Long.valueOf(form.getActionParamaterValue(KRADConstants.NOTE_IDENTIFIER));
640 Note note = getNoteService().getNoteByNoteId(noteIdentifier);
641 if ((note != null) && (note.getAttachment() != null)) {
642 attachment = note.getAttachment();
643
644
645 attachment.setNote(note);
646 }
647 }
648
649 if (attachment == null) {
650 throw new RuntimeException("Unable to find attachment for action parameters passed.");
651 }
652
653 try {
654 KRADUtils.addAttachmentToResponse(response, getAttachmentService().retrieveAttachmentContents(attachment),
655 attachment.getAttachmentMimeTypeCode(), attachment.getAttachmentFileName(),
656 attachment.getAttachmentFileSize().longValue());
657 } catch (IOException e) {
658 throw new RuntimeException("Unable to download note attachment", e);
659 }
660
661 return null;
662 }
663
664
665
666
667 @Override
668 public ModelAndView cancelAttachment(DocumentFormBase form) {
669 form.setAttachmentFile(null);
670
671 return getModelAndViewService().getModelAndView(form);
672 }
673
674
675
676
677 @Override
678 public ModelAndView superUserTakeActions(DocumentFormBase form) {
679 Document document = form.getDocument();
680
681 if (StringUtils.isBlank(document.getSuperUserAnnotation())) {
682 GlobalVariables.getMessageMap().putErrorForSectionId(
683 "Uif-SuperUserAnnotation", RiceKeyConstants.ERROR_SUPER_USER_TAKE_ACTIONS_MISSING);
684 }
685
686 Set<String> selectedActionRequests = form.getSelectedCollectionLines().get(UifPropertyPaths.ACTION_REQUESTS);
687
688 if (CollectionUtils.isEmpty(selectedActionRequests)) {
689 GlobalVariables.getMessageMap().putErrorForSectionId(
690 "Uif-SuperUserActionRequests", RiceKeyConstants.ERROR_SUPER_USER_TAKE_ACTIONS_NONE_SELECTED);
691 }
692
693 if (GlobalVariables.getMessageMap().hasErrors()) {
694 return getModelAndViewService().getModelAndView(form);
695 }
696
697 List<ActionRequest> actionRequests = new ArrayList<ActionRequest>();
698 for (String selectedActionRequest : selectedActionRequests) {
699 ActionRequest actionRequest = ObjectPropertyUtils.getPropertyValue(document, selectedActionRequest);
700 actionRequests.add(actionRequest);
701 }
702
703 for (ActionRequest actionRequest : actionRequests) {
704 if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.COMPLETE.getCode()) ||
705 StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.APPROVE.getCode())) {
706 document = getDocumentService().validateAndPersistDocument(document, new RouteDocumentEvent(document));
707 form.setDocument(document);
708 }
709
710 performSuperUserWorkflowAction(form, UifConstants.SuperUserWorkflowAction.TAKEACTION, actionRequest);
711 }
712
713 document.setSuperUserAnnotation("");
714 form.getSelectedCollectionLines().remove(UifPropertyPaths.ACTION_REQUESTS);
715
716 return getModelAndViewService().getModelAndView(form);
717 }
718
719
720
721
722 @Override
723 public ModelAndView superUserApprove(DocumentFormBase form) {
724 Document document = form.getDocument();
725
726 if (StringUtils.isBlank(document.getSuperUserAnnotation())) {
727 GlobalVariables.getMessageMap().putErrorForSectionId(
728 "Uif-SuperUserAnnotation", RiceKeyConstants.ERROR_SUPER_USER_APPROVE_MISSING);
729 }
730
731 Set<String> selectedCollectionLines = form.getSelectedCollectionLines().get(UifPropertyPaths.ACTION_REQUESTS);
732
733 if (!CollectionUtils.isEmpty(selectedCollectionLines)) {
734 GlobalVariables.getMessageMap().putErrorForSectionId(
735 "Uif-SuperUserActionRequests", RiceKeyConstants.ERROR_SUPER_USER_APPROVE_ACTIONS_CHECKED);
736 }
737
738 if (GlobalVariables.getMessageMap().hasErrors()) {
739 return getModelAndViewService().getModelAndView(form);
740 }
741
742 performSuperUserWorkflowAction(form, UifConstants.SuperUserWorkflowAction.APPROVE);
743
744 return getModelAndViewService().getModelAndView(form);
745 }
746
747
748
749
750 @Override
751 public ModelAndView superUserDisapprove(DocumentFormBase form) {
752 Document document = form.getDocument();
753
754 if (StringUtils.isBlank(document.getSuperUserAnnotation())) {
755 GlobalVariables.getMessageMap().putErrorForSectionId(
756 "Uif-SuperUserAnnotation", RiceKeyConstants.ERROR_SUPER_USER_DISAPPROVE_MISSING);
757 }
758
759 Set<String> selectedCollectionLines = form.getSelectedCollectionLines().get(UifPropertyPaths.ACTION_REQUESTS);
760
761 if (!CollectionUtils.isEmpty(selectedCollectionLines)) {
762 GlobalVariables.getMessageMap().putErrorForSectionId(
763 "Uif-SuperUserActionRequests", RiceKeyConstants.ERROR_SUPER_USER_DISAPPROVE_ACTIONS_CHECKED);
764 }
765
766 if (GlobalVariables.getMessageMap().hasErrors()) {
767 return getModelAndViewService().getModelAndView(form);
768 }
769
770 performSuperUserWorkflowAction(form, UifConstants.SuperUserWorkflowAction.DISAPPROVE);
771
772 return getModelAndViewService().getModelAndView(form);
773 }
774
775
776
777
778 @Override
779 public void performWorkflowAction(DocumentFormBase form, UifConstants.WorkflowAction action) {
780 performWorkflowAction(form, action, null);
781 }
782
783
784
785
786 @Override
787 public void performWorkflowAction(DocumentFormBase form, UifConstants.WorkflowAction action,
788 DocumentEvent documentEvent) {
789 Document document = form.getDocument();
790
791 if (LOG.isDebugEnabled()) {
792 LOG.debug("Performing workflow action " + action.name() + "for document: " + document.getDocumentNumber());
793 }
794
795
796 if (!UifConstants.WorkflowAction.SAVE.equals(action) || document.getDocumentHeader().getWorkflowDocument()
797 .isInitiated()) {
798 form.setEvaluateFlagsAndModes(true);
799 form.setCanEditView(null);
800 }
801
802 try {
803 String successMessageKey = null;
804 switch (action) {
805 case SAVE:
806 if (documentEvent == null) {
807 document = getDocumentService().saveDocument(document);
808 } else {
809 document = getDocumentService().saveDocument(document, documentEvent);
810 }
811
812 successMessageKey = RiceKeyConstants.MESSAGE_SAVED;
813 break;
814 case ROUTE:
815 document = getDocumentService().routeDocument(document, form.getAnnotation(),
816 combineAdHocRecipients(form));
817 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL;
818 break;
819 case BLANKETAPPROVE:
820 document = getDocumentService().blanketApproveDocument(document, form.getAnnotation(),
821 combineAdHocRecipients(form));
822 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_APPROVED;
823 break;
824 case APPROVE:
825 document = getDocumentService().approveDocument(document, form.getAnnotation(),
826 combineAdHocRecipients(form));
827 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_APPROVED;
828 break;
829 case DISAPPROVE:
830 String disapprovalNoteText = generateDisapprovalNote(form);
831 document = getDocumentService().disapproveDocument(document, disapprovalNoteText);
832 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_DISAPPROVED;
833 break;
834 case FYI:
835 document = getDocumentService().clearDocumentFyi(document, combineAdHocRecipients(form));
836 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_FYIED;
837 break;
838 case ACKNOWLEDGE:
839 document = getDocumentService().acknowledgeDocument(document, form.getAnnotation(),
840 combineAdHocRecipients(form));
841 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_ACKNOWLEDGED;
842 break;
843 case CANCEL:
844 if (getDocumentService().documentExists(document.getDocumentNumber())) {
845 document = getDocumentService().cancelDocument(document, form.getAnnotation());
846 successMessageKey = RiceKeyConstants.MESSAGE_CANCELLED;
847 }
848 break;
849 case COMPLETE:
850 if (getDocumentService().documentExists(document.getDocumentNumber())) {
851 document = getDocumentService().completeDocument(document, form.getAnnotation(),
852 combineAdHocRecipients(form));
853 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL;
854 }
855 break;
856 case SENDADHOCREQUESTS:
857 getDocumentService().sendAdHocRequests(document, form.getAnnotation(), combineAdHocRecipients(
858 form));
859 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL;
860 break;
861 case RECALL:
862 if (getDocumentService().documentExists(document.getDocumentNumber())) {
863 String recallExplanation = form.getDialogExplanations().get(
864 KRADConstants.QUESTION_ACTION_RECALL_REASON);
865 document = getDocumentService().recallDocument(document, recallExplanation, true);
866 successMessageKey = RiceKeyConstants.MESSAGE_ROUTE_RECALLED;
867 }
868 break;
869 }
870
871
872 form.setDocument(document);
873
874 if (successMessageKey != null) {
875 GlobalVariables.getMessageMap().putInfo(KRADConstants.GLOBAL_MESSAGES, successMessageKey);
876 }
877 } catch (ValidationException e) {
878
879
880
881 KRADUtils.logErrors();
882 LOG.error("Validation Exception occured for document :" + document.getDocumentNumber(), e);
883
884
885 if (GlobalVariables.getMessageMap().hasNoErrors()) {
886 throw new RiceRuntimeException("Validation Exception with no error message.", e);
887 }
888 } catch (Exception e) {
889 throw new RiceRuntimeException(
890 "Exception trying to invoke action " + action.name() + " for document: " + document
891 .getDocumentNumber(), e);
892 }
893
894 form.setAnnotation("");
895 }
896
897
898
899
900
901
902
903
904 protected List<AdHocRouteRecipient> combineAdHocRecipients(DocumentFormBase form) {
905 Document document = form.getDocument();
906
907 List<AdHocRouteRecipient> adHocRecipients = new ArrayList<AdHocRouteRecipient>();
908 adHocRecipients.addAll(document.getAdHocRoutePersons());
909 adHocRecipients.addAll(document.getAdHocRouteWorkgroups());
910
911 return adHocRecipients;
912 }
913
914
915
916
917 @Override
918 public void performSuperUserWorkflowAction(DocumentFormBase form, UifConstants.SuperUserWorkflowAction action) {
919 performSuperUserWorkflowAction(form, action, null);
920 }
921
922
923
924
925 @Override
926 public void performSuperUserWorkflowAction(DocumentFormBase form, UifConstants.SuperUserWorkflowAction action,
927 ActionRequest actionRequest) {
928 Document document = form.getDocument();
929
930 if (LOG.isDebugEnabled()) {
931 LOG.debug("Performing super user workflow action " + action.name() + "for document: " + document.getDocumentNumber());
932 }
933
934 try {
935 String documentTypeId = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeId();
936 String documentNumber = document.getDocumentNumber();
937 String principalId = GlobalVariables.getUserSession().getPrincipalId();
938 String superUserAnnotation = document.getSuperUserAnnotation();
939
940 WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentTypeId);
941 DocumentActionParameters parameters = DocumentActionParameters.create(documentNumber, principalId, superUserAnnotation);
942
943 String successMessageKey = null;
944 switch (action) {
945 case TAKEACTION:
946 if (actionRequest != null) {
947 documentActions.superUserTakeRequestedAction(parameters, true, actionRequest.getId());
948
949 String actionRequestedCode = actionRequest.getActionRequested().getCode();
950 if (StringUtils.equals(actionRequestedCode, ActionRequestType.ACKNOWLEDGE.getCode())) {
951 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_ACTION_REQUEST_ACKNOWLEDGED;
952 } else if (StringUtils.equals(actionRequestedCode, ActionRequestType.FYI.getCode())) {
953 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_ACTION_REQUEST_FYIED;
954 } else if (StringUtils.equals(actionRequestedCode, ActionRequestType.COMPLETE.getCode())) {
955 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_ACTION_REQUEST_COMPLETED;
956 } else if (StringUtils.equals(actionRequestedCode, ActionRequestType.APPROVE.getCode())) {
957 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_ACTION_REQUEST_APPROVED;
958 } else {
959 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_ACTION_REQUEST_APPROVED;
960 }
961 }
962 break;
963 case APPROVE:
964 documentActions.superUserBlanketApprove(parameters, true);
965
966 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_APPROVED;
967 break;
968 case DISAPPROVE:
969 documentActions.superUserDisapprove(parameters, true);
970
971 successMessageKey = RiceKeyConstants.MESSAGE_SUPER_USER_DISAPPROVED;
972 break;
973 }
974
975 form.setEvaluateFlagsAndModes(true);
976 form.setCanEditView(null);
977
978 if (successMessageKey != null) {
979 if (actionRequest != null) {
980 GlobalVariables.getMessageMap().putInfo(KRADConstants.GLOBAL_MESSAGES, successMessageKey,
981 document.getDocumentNumber(), actionRequest.getId());
982 } else {
983 GlobalVariables.getMessageMap().putInfo(KRADConstants.GLOBAL_MESSAGES, successMessageKey,
984 document.getDocumentNumber());
985 }
986 }
987 } catch (ValidationException e) {
988
989
990
991 KRADUtils.logErrors();
992 LOG.error("Validation Exception occured for document :" + document.getDocumentNumber(), e);
993
994
995 if (GlobalVariables.getMessageMap().hasNoErrors()) {
996 throw new RiceRuntimeException("Validation Exception with no error message.", e);
997 }
998 } catch (Exception e) {
999 throw new RiceRuntimeException(
1000 "Exception trying to invoke action " + action.name() + " for document: " + document
1001 .getDocumentNumber(), e);
1002 }
1003
1004 document.setSuperUserAnnotation("");
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 protected WorkflowDocumentActionsService getWorkflowDocumentActionsService(String documentTypeId) {
1016 DocumentType documentType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeById(documentTypeId);
1017 String applicationId = documentType.getApplicationId();
1018 QName serviceName = new QName(KewApiConstants.Namespaces.KEW_NAMESPACE_2_0,
1019 KewApiConstants.ServiceNames.WORKFLOW_DOCUMENT_ACTIONS_SERVICE_SOAP);
1020
1021 WorkflowDocumentActionsService service = (WorkflowDocumentActionsService) KsbApiServiceLocator.getServiceBus()
1022 .getService(serviceName, applicationId);
1023
1024 if (service == null) {
1025 service = KewApiServiceLocator.getWorkflowDocumentActionsService();
1026 }
1027
1028 return service;
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 protected ModelAndView checkSensitiveDataAndWarningDialog(String field, UifFormBase form) {
1042 boolean hasSensitiveData = KRADUtils.containsSensitiveDataPatternMatch(field);
1043 Boolean warnForSensitiveData = getParameterService().getParameterValueAsBoolean(KRADConstants.KNS_NAMESPACE,
1044 ParameterConstants.ALL_COMPONENT,
1045 KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS_WARNING_IND);
1046
1047
1048
1049 if (hasSensitiveData && warnForSensitiveData.booleanValue()) {
1050 DialogResponse sensitiveDataDialogResponse = form.getDialogResponse(SENSITIVE_DATA_DIALOG);
1051
1052 if (sensitiveDataDialogResponse == null) {
1053
1054 return getModelAndViewService().showDialog(SENSITIVE_DATA_DIALOG, true, form);
1055 }
1056 }
1057
1058 return null;
1059 }
1060
1061
1062
1063
1064
1065
1066
1067 protected DocumentAuthorizationException buildAuthorizationException(String action, Document document) {
1068 return new DocumentAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(),
1069 action, document.getDocumentNumber());
1070 }
1071
1072 protected LegacyDataAdapter getLegacyDataAdapter() {
1073 if (this.legacyDataAdapter == null) {
1074 this.legacyDataAdapter = KRADServiceLocatorWeb.getLegacyDataAdapter();
1075 }
1076 return this.legacyDataAdapter;
1077 }
1078
1079 public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
1080 this.legacyDataAdapter = legacyDataAdapter;
1081 }
1082
1083 protected DataDictionaryService getDataDictionaryService() {
1084 if (this.dataDictionaryService == null) {
1085 this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
1086 }
1087 return this.dataDictionaryService;
1088 }
1089
1090 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
1091 this.dataDictionaryService = dataDictionaryService;
1092 }
1093
1094 protected DocumentService getDocumentService() {
1095 if (this.documentService == null) {
1096 this.documentService = KRADServiceLocatorWeb.getDocumentService();
1097 }
1098 return this.documentService;
1099 }
1100
1101 public void setDocumentService(DocumentService documentService) {
1102 this.documentService = documentService;
1103 }
1104
1105 protected DocumentDictionaryService getDocumentDictionaryService() {
1106 if (this.documentDictionaryService == null) {
1107 this.documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService();
1108 }
1109 return this.documentDictionaryService;
1110 }
1111
1112 public void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) {
1113 this.documentDictionaryService = documentDictionaryService;
1114 }
1115
1116 protected AttachmentService getAttachmentService() {
1117 if (attachmentService == null) {
1118 attachmentService = KRADServiceLocator.getAttachmentService();
1119 }
1120 return this.attachmentService;
1121 }
1122
1123 public void setAttachmentService(AttachmentService attachmentService) {
1124 this.attachmentService = attachmentService;
1125 }
1126
1127 protected NoteService getNoteService() {
1128 if (noteService == null) {
1129 noteService = KRADServiceLocator.getNoteService();
1130 }
1131
1132 return this.noteService;
1133 }
1134
1135 public void setNoteService(NoteService noteService) {
1136 this.noteService = noteService;
1137 }
1138
1139 protected ModelAndViewService getModelAndViewService() {
1140 return modelAndViewService;
1141 }
1142
1143 public void setModelAndViewService(ModelAndViewService modelAndViewService) {
1144 this.modelAndViewService = modelAndViewService;
1145 }
1146
1147 protected NavigationControllerService getNavigationControllerService() {
1148 return navigationControllerService;
1149 }
1150
1151 public void setNavigationControllerService(NavigationControllerService navigationControllerService) {
1152 this.navigationControllerService = navigationControllerService;
1153 }
1154
1155 protected ConfigurationService getConfigurationService() {
1156 return configurationService;
1157 }
1158
1159 public void setConfigurationService(ConfigurationService configurationService) {
1160 this.configurationService = configurationService;
1161 }
1162
1163 protected CollectionControllerService getCollectionControllerService() {
1164 return collectionControllerService;
1165 }
1166
1167 public void setCollectionControllerService(CollectionControllerService collectionControllerService) {
1168 this.collectionControllerService = collectionControllerService;
1169 }
1170
1171 protected ParameterService getParameterService() {
1172 return parameterService;
1173 }
1174
1175 public void setParameterService(ParameterService parameterService) {
1176 this.parameterService = parameterService;
1177 }
1178 }