1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.kns.web.struts.action;
17  
18  import org.apache.commons.collections.MapUtils;
19  import org.apache.commons.lang.ArrayUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.apache.ojb.broker.OptimisticLockException;
22  import org.apache.struts.action.ActionForm;
23  import org.apache.struts.action.ActionForward;
24  import org.apache.struts.action.ActionMapping;
25  import org.apache.struts.upload.FormFile;
26  import org.kuali.rice.core.api.config.property.ConfigurationService;
27  import org.kuali.rice.core.api.util.ConcreteKeyValue;
28  import org.kuali.rice.core.api.util.KeyValue;
29  import org.kuali.rice.core.api.util.RiceConstants;
30  import org.kuali.rice.core.api.util.RiceKeyConstants;
31  import org.kuali.rice.coreservice.framework.parameter.ParameterConstants;
32  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
33  import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
34  import org.kuali.rice.kew.api.KewApiServiceLocator;
35  import org.kuali.rice.kew.api.WorkflowDocument;
36  import org.kuali.rice.kew.api.action.ActionRequest;
37  import org.kuali.rice.kew.api.action.ActionRequestType;
38  import org.kuali.rice.kew.api.action.DocumentActionParameters;
39  import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
40  import org.kuali.rice.kew.api.doctype.DocumentType;
41  import org.kuali.rice.kew.api.exception.WorkflowException;
42  import org.kuali.rice.kew.api.KewApiConstants;
43  import org.kuali.rice.kim.api.KimConstants;
44  import org.kuali.rice.kim.api.group.Group;
45  import org.kuali.rice.kim.api.group.GroupService;
46  import org.kuali.rice.kim.api.identity.Person;
47  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
48  import org.kuali.rice.kns.datadictionary.KNSDocumentEntry;
49  import org.kuali.rice.kns.document.MaintenanceDocument;
50  import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
51  import org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase;
52  import org.kuali.rice.kns.document.authorization.DocumentPresentationController;
53  import org.kuali.rice.kns.question.ConfirmationQuestion;
54  import org.kuali.rice.kns.question.RecallQuestion;
55  import org.kuali.rice.kns.rule.PromptBeforeValidation;
56  import org.kuali.rice.kns.rule.event.PromptBeforeValidationEvent;
57  import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
58  import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
59  import org.kuali.rice.kns.service.DataDictionaryService;
60  import org.kuali.rice.kns.service.DocumentHelperService;
61  import org.kuali.rice.kns.service.KNSServiceLocator;
62  import org.kuali.rice.kns.util.KNSGlobalVariables;
63  import org.kuali.rice.kns.util.WebUtils;
64  import org.kuali.rice.kns.web.struts.form.BlankFormFile;
65  import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
66  import org.kuali.rice.kns.web.struts.form.KualiForm;
67  import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
68  import org.kuali.rice.krad.UserSession;
69  import org.kuali.rice.krad.UserSessionUtils;
70  import org.kuali.rice.krad.bo.AdHocRoutePerson;
71  import org.kuali.rice.krad.bo.AdHocRouteRecipient;
72  import org.kuali.rice.krad.bo.AdHocRouteWorkgroup;
73  import org.kuali.rice.krad.bo.Attachment;
74  import org.kuali.rice.krad.bo.DocumentHeader;
75  import org.kuali.rice.krad.bo.Note;
76  import org.kuali.rice.krad.bo.PersistableBusinessObject;
77  import org.kuali.rice.krad.datadictionary.DataDictionary;
78  import org.kuali.rice.krad.document.Document;
79  import org.kuali.rice.krad.document.authorization.PessimisticLock;
80  import org.kuali.rice.krad.exception.AuthorizationException;
81  import org.kuali.rice.krad.exception.DocumentAuthorizationException;
82  import org.kuali.rice.krad.exception.UnknownDocumentIdException;
83  import org.kuali.rice.krad.rules.rule.event.AddAdHocRoutePersonEvent;
84  import org.kuali.rice.krad.rules.rule.event.AddAdHocRouteWorkgroupEvent;
85  import org.kuali.rice.krad.rules.rule.event.AddNoteEvent;
86  import org.kuali.rice.krad.rules.rule.event.RouteDocumentEvent;
87  import org.kuali.rice.krad.rules.rule.event.SendAdHocRequestsEvent;
88  import org.kuali.rice.krad.service.AttachmentService;
89  import org.kuali.rice.krad.service.BusinessObjectService;
90  import org.kuali.rice.krad.service.DocumentService;
91  import org.kuali.rice.krad.service.KRADServiceLocator;
92  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
93  import org.kuali.rice.krad.service.KualiRuleService;
94  import org.kuali.rice.krad.service.NoteService;
95  import org.kuali.rice.krad.service.PessimisticLockService;
96  import org.kuali.rice.krad.util.GlobalVariables;
97  import org.kuali.rice.krad.util.KRADConstants;
98  import org.kuali.rice.krad.util.KRADPropertyConstants;
99  import org.kuali.rice.krad.util.KRADUtils;
100 import org.kuali.rice.krad.util.NoteType;
101 import org.kuali.rice.krad.util.ObjectUtils;
102 import org.kuali.rice.krad.util.SessionTicket;
103 import org.kuali.rice.krad.util.UrlFactory;
104 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
105 import org.springmodules.orm.ojb.OjbOperationException;
106 
107 import javax.persistence.EntityManagerFactory;
108 import javax.servlet.http.HttpServletRequest;
109 import javax.servlet.http.HttpServletResponse;
110 import javax.xml.namespace.QName;
111 
112 import java.io.ByteArrayOutputStream;
113 import java.io.IOException;
114 import java.util.ArrayList;
115 import java.util.Enumeration;
116 import java.util.HashMap;
117 import java.util.Iterator;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Properties;
121 import java.util.Set;
122 
123 
124 
125 
126 
127 
128 public class KualiDocumentActionBase extends KualiAction {
129     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiDocumentActionBase.class);
130 
131     
132     protected static final String[] DOCUMENT_LOAD_COMMANDS = {
133             KewApiConstants.ACTIONLIST_COMMAND,
134             KewApiConstants.DOCSEARCH_COMMAND,
135             KewApiConstants.SUPERUSER_COMMAND,
136             KewApiConstants.HELPDESK_ACTIONLIST_COMMAND};
137 
138     private DataDictionaryService dataDictionaryService;
139     private DocumentHelperService documentHelperService;
140     private DocumentService documentService;
141     private ConfigurationService kualiConfigurationService;
142     private ParameterService parameterService;
143     private PessimisticLockService pessimisticLockService;
144     private KualiRuleService kualiRuleService;
145     private GroupService groupService;
146     private AttachmentService attachmentService;
147     private NoteService noteService;
148     private BusinessObjectAuthorizationService businessObjectAuthorizationService;
149     private BusinessObjectService businessObjectService;
150     private BusinessObjectMetaDataService businessObjectMetaDataService;
151     private EntityManagerFactory entityManagerFactory;
152 
153     @Override
154     protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
155         if (!(form instanceof KualiDocumentFormBase)) {
156             super.checkAuthorization(form, methodToCall);
157         }
158     }
159 
160     
161 
162 
163 
164 
165 
166 
167 
168 
169 
170     @Override
171     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
172         ActionForward returnForward = mapping.findForward(RiceConstants.MAPPING_BASIC);
173 
174         
175         try {
176             returnForward = super.execute(mapping, form, request, response);
177         } catch (OjbOperationException e) {
178             
179             OjbOperationException ooe = e;
180 
181             Throwable cause = ooe.getCause();
182             if (cause instanceof OptimisticLockException) {
183                 OptimisticLockException ole = (OptimisticLockException) cause;
184                 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_OPTIMISTIC_LOCK);
185                 logOjbOptimisticLockException(ole);
186             } else {
187                 
188                 throw e;
189             }
190         } finally {
191             if (form instanceof KualiDocumentFormBase) {
192                 ((KualiDocumentFormBase) form).setMessageMapFromPreviousRequest(GlobalVariables.getMessageMap());
193             }
194         }
195 
196         if (form instanceof KualiDocumentFormBase
197                 && ((KualiDocumentFormBase) form).isHasWorkflowDocument()) {
198             KualiDocumentFormBase formBase = (KualiDocumentFormBase) form;
199             Document document = formBase.getDocument();
200 
201             
202             WorkflowDocument workflowDocument = formBase.getDocument().getDocumentHeader().getWorkflowDocument();
203             formBase.populateHeaderFields(workflowDocument);
204             formBase.setDocId(document.getDocumentNumber());
205             
206 
207             
208             if (isFormRepresentingLockObject(formBase)) {
209                 
210                 if (LOG.isDebugEnabled()) {
211                     LOG.debug("Form " + formBase + " represents a PessimisticLock BO object");
212                 }
213             } else {
214                 
215                 
216                 
217                 
218                 populateAuthorizationFields(formBase);
219                 populateAdHocActionRequestCodes(formBase);
220 
221                 
222                 UserSession userSession = (UserSession) request.getSession().getAttribute(KRADConstants.USER_SESSION_KEY);
223 
224                 if (WebUtils.isDocumentSession(document, formBase)) {
225                     String formKey = formBase.getFormKey();
226                     if (StringUtils.isBlank(formBase.getFormKey()) || userSession.retrieveObject(formBase.getFormKey()) == null) {
227                         
228                         formKey = GlobalVariables.getUserSession().addObjectWithGeneratedKey(form);
229                         formBase.setFormKey(formKey);
230                     }
231                 }
232 
233 
234                 
235                 request.getSession().setAttribute(KRADConstants.DOCUMENT_HTTP_SESSION_KEY, document.getDocumentNumber());
236                 
237                 if ("displayActionListView".equals(formBase.getCommand())) {
238                     formBase.setReturnToActionList(true);
239                 }
240 
241                 String attachmentEnabled =
242                         getKualiConfigurationService().getPropertyValueAsString(KRADConstants.NOTE_ATTACHMENT_ENABLED);
243                 
244                 if (attachmentEnabled != null) {
245                     
246                     
247                     
248                     
249                     DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
250 
251                     org.kuali.rice.krad.datadictionary.DocumentEntry entry = (org.kuali.rice.krad.datadictionary.DocumentEntry) dataDictionary.getDocumentEntry(document.getClass().getName());
252                     entry.setAllowsNoteAttachments(Boolean.parseBoolean(attachmentEnabled));
253                 }
254                 
255                 if (exitingDocument()) {
256                     request.setAttribute(KRADConstants.EXITING_DOCUMENT, Boolean.TRUE);
257                 }
258 
259                 
260                 String methodCalledViaDispatch = (String) GlobalVariables.getUserSession().retrieveObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_OBJECT_KEY);
261                 if ((StringUtils.isNotBlank(methodCalledViaDispatch)) && (exitingDocument())) {
262                     GlobalVariables.getUserSession().removeObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_COMPLETE_OBJECT_KEY);
263                     attemptLockRelease(document, methodCalledViaDispatch);
264                 }
265                 setupPessimisticLockMessages(document, request);
266                 if (!document.getPessimisticLocks().isEmpty()) {
267                     String warningMinutes = getParameterService().getParameterValueAsString(KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.DOCUMENT_DETAIL_TYPE, KRADConstants.SESSION_TIMEOUT_WARNING_MESSAGE_TIME_PARM_NM);
268                     request.setAttribute(KRADConstants.SESSION_TIMEOUT_WARNING_MINUTES, warningMinutes);
269                     request.setAttribute(KRADConstants.SESSION_TIMEOUT_WARNING_MILLISECONDS, (request.getSession().getMaxInactiveInterval() - (Integer.valueOf(warningMinutes) * 60)) * 1000);
270                 }
271             }
272             
273             List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getPendingActionRequests(formBase.getDocId());
274             formBase.setActionRequests(actionRequests);
275         }
276 
277 
278         
279         return returnForward;
280     }
281 
282     protected boolean isFormRepresentingLockObject(KualiDocumentFormBase form) throws Exception {
283         if (form instanceof KualiMaintenanceForm) {
284             KualiMaintenanceForm maintForm = (KualiMaintenanceForm) form;
285             if (ObjectUtils.isNotNull(maintForm.getBusinessObjectClassName())) {
286                 return PessimisticLock.class.isAssignableFrom(Class.forName(((KualiMaintenanceForm) form).getBusinessObjectClassName()));
287             }
288         }
289         return false;
290     }
291 
292     protected void attemptLockRelease(Document document, String methodToCall) {
293         if ((document != null) && (!document.getPessimisticLocks().isEmpty())) {
294             releaseLocks(document, methodToCall);
295             
296             document.refreshPessimisticLocks();
297         }
298     }
299 
300     protected void releaseLocks(Document document, String methodToCall) {
301         
302         if (document.getLockClearningMethodNames().contains(methodToCall)) {
303             
304             getPessimisticLockService().releaseAllLocksForUser(document.getPessimisticLocks(), GlobalVariables.getUserSession().getPerson());
305         }
306     }
307 
308     protected void setupPessimisticLockMessages(Document document, HttpServletRequest request) {
309         List<String> lockMessages = new ArrayList<String>();
310         for (PessimisticLock lock : document.getPessimisticLocks()) {
311             
312             if (!lock.isOwnedByUser(GlobalVariables.getUserSession().getPerson())) {
313                 lockMessages.add(generatePessimisticLockMessage(lock));
314             }
315         }
316         request.setAttribute(KRADConstants.PESSIMISTIC_LOCK_MESSAGES, lockMessages);
317     }
318 
319     protected String generatePessimisticLockMessage(PessimisticLock lock) {
320         String descriptor = (lock.getLockDescriptor() != null) ? lock.getLockDescriptor() : "";
321         
322         return "This document currently has a " + descriptor + " lock owned by " + lock.getOwnedByUser().getName() + " as of " + RiceConstants.getDefaultTimeFormat().format(lock.getGeneratedTimestamp()) + " on " + RiceConstants.getDefaultDateFormat().format(lock.getGeneratedTimestamp());
323     }
324 
325 
326 
327 
328 
329 
330 
331     
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 
342 
343 
344     public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
345         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
346         String command = kualiDocumentFormBase.getCommand();
347 
348         if (kualiDocumentFormBase.getDocId()!= null && getDocumentService().getByDocumentHeaderId(kualiDocumentFormBase.getDocId()) == null) {
349             ConfigurationService kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService();
350             StringBuffer sb = new StringBuffer();
351             sb.append(kualiConfigurationService.getPropertyValueAsString(KRADConstants.KRAD_URL_KEY));
352             sb.append(kualiConfigurationService.getPropertyValueAsString(KRADConstants.KRAD_INITIATED_DOCUMENT_URL_KEY));
353             response.sendRedirect(sb.toString());
354             return new ActionForward(KRADConstants.KRAD_INITIATED_DOCUMENT_VIEW_NAME, sb.toString() ,true);
355         }
356         
357         if (ArrayUtils.contains(DOCUMENT_LOAD_COMMANDS, command) && kualiDocumentFormBase.getDocId() != null) {
358             loadDocument(kualiDocumentFormBase);
359         } else if (KewApiConstants.INITIATE_COMMAND.equals(command)) {
360             createDocument(kualiDocumentFormBase);
361         } else {
362             LOG.error("docHandler called with invalid parameters");
363             throw new IllegalArgumentException("docHandler called with invalid parameters");
364         }
365 
366         
367         if (LOG.isDebugEnabled()) {
368             LOG.debug("kualiDocumentFormBase.getAdditionalScriptFiles(): " + kualiDocumentFormBase.getAdditionalScriptFiles());
369         }
370         if (kualiDocumentFormBase.getAdditionalScriptFiles().isEmpty()) {
371             KNSDocumentEntry docEntry = (KNSDocumentEntry) getDataDictionaryService().getDataDictionary().getDocumentEntry(kualiDocumentFormBase.getDocument().getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
372             kualiDocumentFormBase.getAdditionalScriptFiles().addAll(docEntry.getWebScriptFiles());
373         }
374         if (KewApiConstants.SUPERUSER_COMMAND.equalsIgnoreCase(command)) {
375             kualiDocumentFormBase.setSuppressAllButtons(true);
376         }
377         return mapping.findForward(RiceConstants.MAPPING_BASIC);
378     }
379 
380     
381 
382 
383 
384 
385 
386 
387     protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
388         String docId = kualiDocumentFormBase.getDocId();
389         Document doc = null;
390         doc = getDocumentService().getByDocumentHeaderId(docId);
391         if (doc == null) {
392             throw new UnknownDocumentIdException("Document no longer exists.  It may have been cancelled before being saved.");
393         }
394         WorkflowDocument workflowDocument = doc.getDocumentHeader().getWorkflowDocument();
395         if (!getDocumentHelperService().getDocumentAuthorizer(doc).canOpen(doc, GlobalVariables.getUserSession().getPerson())) {
396             throw buildAuthorizationException("open", doc);
397         }
398         
399         if (workflowDocument != doc.getDocumentHeader().getWorkflowDocument()) {
400             LOG.warn("Workflow document changed via canOpen check");
401             doc.getDocumentHeader().setWorkflowDocument(workflowDocument);
402         }
403         kualiDocumentFormBase.setDocument(doc);
404         WorkflowDocument workflowDoc = doc.getDocumentHeader().getWorkflowDocument();
405         kualiDocumentFormBase.setDocTypeName(workflowDoc.getDocumentTypeName());
406 
407         
408         UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDoc);
409     }
410 
411 
412     
413 
414 
415 
416 
417 
418 
419     protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
420         Document doc = getDocumentService().getNewDocument(kualiDocumentFormBase.getDocTypeName());
421         UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(),
422                 doc.getDocumentHeader().getWorkflowDocument());
423 
424         kualiDocumentFormBase.setDocument(doc);
425         kualiDocumentFormBase.setDocTypeName(doc.getDocumentHeader().getWorkflowDocument().getDocumentTypeName());
426     }
427 
428     
429 
430 
431 
432 
433 
434 
435 
436 
437 
438 
439     public ActionForward insertAdHocRoutePerson(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
440         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
441         Document document = kualiDocumentFormBase.getDocument();
442 
443 
444         
445         DocumentAuthorizer documentAuthorizer = getDocumentHelperService().getDocumentAuthorizer(document);
446         if (!documentAuthorizer.canSendAdHocRequests(document, kualiDocumentFormBase.getNewAdHocRoutePerson().getActionRequested(), GlobalVariables.getUserSession().getPerson())) {
447             throw buildAuthorizationException("ad-hoc route", document);
448         }
449 
450         
451         boolean rulePassed = getKualiRuleService().applyRules(new AddAdHocRoutePersonEvent(document, kualiDocumentFormBase.getNewAdHocRoutePerson()));
452 
453         
454         if (rulePassed) {
455             
456 
457             kualiDocumentFormBase.getNewAdHocRoutePerson().setId(kualiDocumentFormBase.getNewAdHocRoutePerson().getId());
458             kualiDocumentFormBase.getAdHocRoutePersons().add(kualiDocumentFormBase.getNewAdHocRoutePerson());
459             AdHocRoutePerson person = new AdHocRoutePerson();
460             kualiDocumentFormBase.setNewAdHocRoutePerson(person);
461         }
462 
463         return mapping.findForward(RiceConstants.MAPPING_BASIC);
464     }
465 
466     
467 
468 
469 
470 
471 
472 
473 
474 
475 
476 
477     public ActionForward deleteAdHocRoutePerson(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
478         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
479 
480 
481         kualiDocumentFormBase.getAdHocRoutePersons().remove(this.getLineToDelete(request));
482         return mapping.findForward(RiceConstants.MAPPING_BASIC);
483     }
484 
485     
486 
487 
488 
489 
490 
491 
492 
493 
494 
495 
496     public ActionForward insertAdHocRouteWorkgroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
497         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
498         Document document = kualiDocumentFormBase.getDocument();
499 
500         
501         DocumentAuthorizer documentAuthorizer = getDocumentHelperService().getDocumentAuthorizer(document);
502         if (!documentAuthorizer.canSendAdHocRequests(document, kualiDocumentFormBase.getNewAdHocRouteWorkgroup().getActionRequested(), GlobalVariables.getUserSession().getPerson())) {
503             throw buildAuthorizationException("ad-hoc route", document);
504         }
505 
506         
507         boolean rulePassed = getKualiRuleService().applyRules(new AddAdHocRouteWorkgroupEvent(document, kualiDocumentFormBase.getNewAdHocRouteWorkgroup()));
508 
509         
510         if (rulePassed) {
511             
512             AdHocRouteWorkgroup newWorkgroup = kualiDocumentFormBase.getNewAdHocRouteWorkgroup();
513             if (newWorkgroup.getId() == null) {
514                 newWorkgroup.setId(KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(
515                         newWorkgroup.getRecipientNamespaceCode(), newWorkgroup.getRecipientName()).getId());
516             }
517             kualiDocumentFormBase.getAdHocRouteWorkgroups().add(newWorkgroup);
518             AdHocRouteWorkgroup workgroup = new AdHocRouteWorkgroup();
519             kualiDocumentFormBase.setNewAdHocRouteWorkgroup(workgroup);
520         }
521 
522         return mapping.findForward(RiceConstants.MAPPING_BASIC);
523     }
524 
525     
526 
527 
528 
529 
530 
531 
532 
533 
534 
535 
536     public ActionForward deleteAdHocRouteWorkgroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
537         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
538 
539         kualiDocumentFormBase.getAdHocRouteWorkgroups().remove(this.getLineToDelete(request));
540         return mapping.findForward(RiceConstants.MAPPING_BASIC);
541     }
542 
543     public ActionForward sendAdHocRequests(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
544         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
545         Document document = kualiDocumentFormBase.getDocument();
546 
547         boolean rulePassed = getKualiRuleService().applyRules(new SendAdHocRequestsEvent(document));
548 
549         if (rulePassed) {
550             getDocumentService().sendAdHocRequests(document, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
551             KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_SEND_AD_HOC_REQUESTS_SUCCESSFUL);
552         }
553 
554         return mapping.findForward(RiceConstants.MAPPING_BASIC);
555     }
556 
557     
558 
559 
560 
561 
562 
563 
564 
565 
566 
567     public ActionForward reload(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
568         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
569         Document document = kualiDocumentFormBase.getDocument();
570 
571         
572         kualiDocumentFormBase.setDocId(document.getDocumentNumber());
573         kualiDocumentFormBase.setCommand(DOCUMENT_LOAD_COMMANDS[1]);
574 
575         
576         ActionForward actionForward = docHandler(mapping, form, request, response);
577 
578         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_RELOADED);
579         
580 
581 
582 
583 
584 
585 
586 
587 
588         return actionForward;
589     }
590 
591     
592 
593 
594 
595 
596 
597 
598 
599 
600 
601     public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
602         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
603         doProcessingAfterPost(kualiDocumentFormBase, request);
604         
605         refreshAdHocRoutingWorkgroupLookups(request, kualiDocumentFormBase);
606         Document document = kualiDocumentFormBase.getDocument();
607 
608         ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "save", "");
609         if (forward != null) {
610             return forward;
611         }
612 
613         
614         getDocumentService().saveDocument(document);
615 
616         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_SAVED);
617         kualiDocumentFormBase.setAnnotation("");
618 
619         
620 
621 
622 
623 
624 
625 
626 
627 
628         return mapping.findForward(RiceConstants.MAPPING_BASIC);
629     }
630 
631     
632 
633 
634 
635 
636 
637 
638 
639 
640 
641 
642 
643 
644 
645 
646 
647     protected ActionForward checkAndWarnAboutSensitiveData(ActionMapping mapping, ActionForm form,
648                                                            HttpServletRequest request, HttpServletResponse response, String fieldName, String fieldValue, String caller, String context)
649             throws Exception {
650         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
651         Document document = kualiDocumentFormBase.getDocument();
652 
653         boolean containsSensitiveData = KRADUtils.containsSensitiveDataPatternMatch(fieldValue);
654 
655         
656         boolean warnForSensitiveData = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
657                 KRADConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
658                 KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS_WARNING_IND);
659 
660         
661         Map<String, String> ticketContext = new HashMap<String, String>();
662         ticketContext.put(KRADPropertyConstants.DOCUMENT_NUMBER, document.getDocumentNumber());
663         ticketContext.put(KRADConstants.CALLING_METHOD, caller);
664         ticketContext.put(KRADPropertyConstants.NAME, fieldName);
665 
666         boolean questionAsked = GlobalVariables.getUserSession().hasMatchingSessionTicket(
667                 KRADConstants.SENSITIVE_DATA_QUESTION_SESSION_TICKET, ticketContext);
668 
669         
670         if (containsSensitiveData && warnForSensitiveData && !questionAsked) {
671             Object question = request.getParameter(KRADConstants.QUESTION_INST_ATTRIBUTE_NAME);
672             if (question == null || !KRADConstants.DOCUMENT_SENSITIVE_DATA_QUESTION.equals(question)) {
673 
674                 
675                 return this.performQuestionWithoutInput(mapping, form, request, response,
676                         KRADConstants.DOCUMENT_SENSITIVE_DATA_QUESTION, getKualiConfigurationService()
677                         .getPropertyValueAsString(RiceKeyConstants.QUESTION_SENSITIVE_DATA_DOCUMENT),
678                         KRADConstants.CONFIRMATION_QUESTION, caller, context);
679             }
680 
681             Object buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON);
682             if (question != null && KRADConstants.DOCUMENT_SENSITIVE_DATA_QUESTION.equals(question)) {
683                 
684                 if (ConfirmationQuestion.NO.equals(buttonClicked)) {
685 
686                     return mapping.findForward(RiceConstants.MAPPING_BASIC);
687                 }
688 
689                 
690                 SessionTicket ticket = new SessionTicket(KRADConstants.SENSITIVE_DATA_QUESTION_SESSION_TICKET);
691                 ticket.setTicketContext(ticketContext);
692                 GlobalVariables.getUserSession().putSessionTicket(ticket);
693             }
694         }
695 
696         
697         return null;
698     }
699 
700     
701 
702 
703 
704 
705 
706 
707 
708 
709 
710     public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
711         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
712         if (isFormRepresentingLockObject(kualiDocumentFormBase)) {
713             String idValue = request.getParameter(KRADPropertyConstants.ID);
714             getPessimisticLockService().delete(idValue);
715             return returnToSender(request, mapping, kualiDocumentFormBase);
716         }
717         throw buildAuthorizationException(KRADConstants.DELETE_METHOD, kualiDocumentFormBase.getDocument());
718     }
719 
720     
721 
722 
723 
724 
725 
726 
727 
728 
729 
730     public ActionForward performRouteReport(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
731         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
732 
733         kualiDocumentFormBase.setDerivedValuesOnForm(request);
734         ActionForward preRulesForward = promptBeforeValidation(mapping, form, request, response);
735         if (preRulesForward != null) {
736             return preRulesForward;
737         }
738 
739         Document document = kualiDocumentFormBase.getDocument();
740         
741         
742         if (!kualiDocumentFormBase.getDocumentActions().containsKey(KRADConstants.KUALI_ACTION_PERFORM_ROUTE_REPORT)) {
743             throw buildAuthorizationException("perform route report", document);
744         }
745 
746         String backUrlBase = getReturnLocation(request, mapping);
747         String globalVariableFormKey = GlobalVariables.getUserSession().addObjectWithGeneratedKey(form);
748         
749         request.setAttribute("backUrlBase", backUrlBase);
750         List<KeyValue> backFormParameters = new ArrayList<KeyValue>();
751         backFormParameters.add(new ConcreteKeyValue(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL));
752         backFormParameters.add(new ConcreteKeyValue(KRADConstants.DOC_FORM_KEY, globalVariableFormKey));
753         request.setAttribute("backFormHiddenVariables", backFormParameters);
754 
755         
756         request.setAttribute("workflowRouteReportUrl", getKualiConfigurationService().getPropertyValueAsString(
757                 KRADConstants.WORKFLOW_URL_KEY) + "/" + KewApiConstants.DOCUMENT_ROUTING_REPORT_PAGE);
758         List<KeyValue> generalRouteReportFormParameters = new ArrayList<KeyValue>();
759         generalRouteReportFormParameters.add(new ConcreteKeyValue(KewApiConstants.INITIATOR_ID_ATTRIBUTE_NAME, document.getDocumentHeader().getWorkflowDocument().getDocument().getInitiatorPrincipalId()));
760         generalRouteReportFormParameters.add(new ConcreteKeyValue(KewApiConstants.DOCUMENT_TYPE_NAME_ATTRIBUTE_NAME, document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()));
761         
762         String xml = document.getXmlForRouteReport();
763         if (LOG.isDebugEnabled()) {
764             LOG.debug("XML being used for Routing Report is: " + xml);
765         }
766         generalRouteReportFormParameters.add(new ConcreteKeyValue(KewApiConstants.DOCUMENT_CONTENT_ATTRIBUTE_NAME, xml));
767 
768         
769         List<KeyValue> javaScriptFormParameters = new ArrayList<KeyValue>();
770         javaScriptFormParameters.addAll(generalRouteReportFormParameters);
771         javaScriptFormParameters.add(new ConcreteKeyValue(KewApiConstants.DISPLAY_CLOSE_BUTTON_ATTRIBUTE_NAME, KewApiConstants.DISPLAY_CLOSE_BUTTON_TRUE_VALUE));
772         request.setAttribute("javaScriptFormVariables", javaScriptFormParameters);
773 
774         
775         List<KeyValue> noJavaScriptFormParameters = new ArrayList<KeyValue>();
776         noJavaScriptFormParameters.addAll(generalRouteReportFormParameters);
777         Properties parameters = new Properties();
778         for (KeyValue pair : backFormParameters) {
779             parameters.put(pair.getKey(), pair.getValue());
780         }
781         noJavaScriptFormParameters.add(new ConcreteKeyValue(KewApiConstants.RETURN_URL_ATTRIBUTE_NAME, UrlFactory.parameterizeUrl(backUrlBase, parameters)));
782         request.setAttribute("noJavaScriptFormVariables", noJavaScriptFormParameters);
783 
784         return mapping.findForward(KRADConstants.MAPPING_ROUTE_REPORT);
785     }
786 
787     
788 
789 
790 
791 
792 
793 
794 
795 
796 
797     public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
798         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
799         doProcessingAfterPost(kualiDocumentFormBase, request);
800 
801         kualiDocumentFormBase.setDerivedValuesOnForm(request);
802         ActionForward preRulesForward = promptBeforeValidation(mapping, form, request, response);
803         if (preRulesForward != null) {
804             return preRulesForward;
805         }
806 
807         Document document = kualiDocumentFormBase.getDocument();
808 
809         ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "route", "");
810         if (forward != null) {
811             return forward;
812         }
813 
814         getDocumentService().routeDocument(document, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
815         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL);
816         kualiDocumentFormBase.setAnnotation("");
817 
818 
819         return mapping.findForward(RiceConstants.MAPPING_BASIC);
820     }
821 
822     
823 
824 
825 
826 
827 
828 
829 
830 
831 
832     public ActionForward blanketApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
833         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
834         doProcessingAfterPost(kualiDocumentFormBase, request);
835 
836         
837         boolean hasPendingAdhocForCompletion = this.hasPendingAdhocForCompletion(kualiDocumentFormBase);
838         if(hasPendingAdhocForCompletion){
839             GlobalVariables.getMessageMap().putError(KRADConstants.NEW_AD_HOC_ROUTE_WORKGROUP_PROPERTY_NAME, RiceKeyConstants.ERROR_ADHOC_COMPLETE_BLANKET_APPROVE_NOT_ALLOWED);
840             
841             return mapping.findForward(RiceConstants.MAPPING_BASIC);
842         }
843         
844         kualiDocumentFormBase.setDerivedValuesOnForm(request);
845         ActionForward preRulesForward = promptBeforeValidation(mapping, form, request, response);
846         if (preRulesForward != null) {
847             return preRulesForward;
848         }
849 
850         Document document = kualiDocumentFormBase.getDocument();
851 
852         ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "blanketApprove", "");
853         if (forward != null) {
854             return forward;
855         }
856 
857         getDocumentService().blanketApproveDocument(document, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
858         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_APPROVED);
859         kualiDocumentFormBase.setAnnotation("");
860         return returnToSender(request, mapping, kualiDocumentFormBase);
861     }
862 
863     
864 
865 
866 
867 
868 
869 
870 
871 
872 
873     public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
874         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
875         doProcessingAfterPost(kualiDocumentFormBase, request);
876 
877         kualiDocumentFormBase.setDerivedValuesOnForm(request);
878         ActionForward preRulesForward = promptBeforeValidation(mapping, form, request, response);
879         if (preRulesForward != null) {
880             return preRulesForward;
881         }
882 
883         Document document = kualiDocumentFormBase.getDocument();
884 
885         ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "approve", "");
886         if (forward != null) {
887             return forward;
888         }
889 
890         getDocumentService().approveDocument(document, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
891         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_APPROVED);
892         kualiDocumentFormBase.setAnnotation("");
893         return returnToSender(request, mapping, kualiDocumentFormBase);
894     }
895 
896     
897 
898 
899 
900 
901 
902 
903 
904 
905 
906     public ActionForward disapprove(ActionMapping mapping, ActionForm form, HttpServletRequest request,
907                                     HttpServletResponse response) throws Exception {
908 
909         ReasonPrompt prompt = new ReasonPrompt(KRADConstants.DOCUMENT_DISAPPROVE_QUESTION, RiceKeyConstants.QUESTION_DISAPPROVE_DOCUMENT, KRADConstants.CONFIRMATION_QUESTION, RiceKeyConstants.ERROR_DOCUMENT_DISAPPROVE_REASON_REQUIRED, KRADConstants.MAPPING_DISAPPROVE, ConfirmationQuestion.NO, RiceKeyConstants.MESSAGE_DISAPPROVAL_NOTE_TEXT_INTRO);
910         ReasonPrompt.Response resp = prompt.ask(mapping, form, request, response);
911 
912         if (resp.forward != null) {
913             return resp.forward;
914         }
915 
916         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
917         doProcessingAfterPost(kualiDocumentFormBase, request);
918         getDocumentService().disapproveDocument(kualiDocumentFormBase.getDocument(), resp.reason);
919         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_DISAPPROVED);
920         kualiDocumentFormBase.setAnnotation("");
921 
922         return returnToSender(request, mapping, kualiDocumentFormBase);
923     }
924 
925     
926 
927 
928 
929 
930 
931 
932 
933 
934 
935     public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
936         Object question = request.getParameter(KRADConstants.QUESTION_INST_ATTRIBUTE_NAME);
937         
938         
939         if (question == null) {
940             
941             return this.performQuestionWithoutInput(mapping, form, request, response, KRADConstants.DOCUMENT_CANCEL_QUESTION, getKualiConfigurationService().getPropertyValueAsString(
942                     "document.question.cancel.text"), KRADConstants.CONFIRMATION_QUESTION, KRADConstants.MAPPING_CANCEL, "");
943         } else {
944             Object buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON);
945             if ((KRADConstants.DOCUMENT_CANCEL_QUESTION.equals(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) {
946                 
947                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
948             }
949             
950         }
951 
952         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
953         doProcessingAfterPost(kualiDocumentFormBase, request);
954         
955         if (getDocumentService().documentExists(kualiDocumentFormBase.getDocId())) {
956             getDocumentService().cancelDocument(kualiDocumentFormBase.getDocument(), kualiDocumentFormBase.getAnnotation());
957         }
958 
959         return returnToSender(request, mapping, kualiDocumentFormBase);
960     }
961 
962     
963 
964 
965 
966 
967 
968 
969 
970 
971 
972     public ActionForward recall(ActionMapping mapping, ActionForm form, HttpServletRequest request,
973             HttpServletResponse response) throws Exception {
974         
975         ReasonPrompt prompt = new ReasonPrompt(KRADConstants.DOCUMENT_RECALL_QUESTION, RiceKeyConstants.QUESTION_RECALL_DOCUMENT, KRADConstants.RECALL_QUESTION, RiceKeyConstants.ERROR_DOCUMENT_RECALL_REASON_REQUIRED, KRADConstants.MAPPING_RECALL, null, RiceKeyConstants.MESSAGE_RECALL_NOTE_TEXT_INTRO);
976         ReasonPrompt.Response resp = prompt.ask(mapping, form, request, response);
977 
978         if (resp.forward != null) {
979             return resp.forward;
980         }
981         
982         boolean cancel = !((KRADConstants.DOCUMENT_RECALL_QUESTION.equals(resp.question)) && RecallQuestion.RECALL_TO_ACTIONLIST.equals(resp.button));
983 
984         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
985         doProcessingAfterPost(kualiDocumentFormBase, request);
986         getDocumentService().recallDocument(kualiDocumentFormBase.getDocument(), resp.reason, cancel);
987 
988         
989         return mapping.findForward(RiceConstants.MAPPING_BASIC);
990     }
991 
992     
993 
994 
995 
996 
997 
998 
999 
1000 
1001 
1002 
1003     public ActionForward close(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1004         KualiDocumentFormBase docForm = (KualiDocumentFormBase) form;
1005         doProcessingAfterPost(docForm, request);
1006         Document document = docForm.getDocument();
1007         
1008         if (canSave(docForm)) {
1009 
1010             Object question = getQuestion(request);
1011             
1012             if (question == null) {
1013                 
1014                 
1015                 saveUnconvertedValuesToSession(request, docForm);
1016 
1017                 
1018                 return this.performQuestionWithoutInput(mapping, form, request, response, KRADConstants.DOCUMENT_SAVE_BEFORE_CLOSE_QUESTION, getKualiConfigurationService().getPropertyValueAsString(
1019                         RiceKeyConstants.QUESTION_SAVE_BEFORE_CLOSE), KRADConstants.CONFIRMATION_QUESTION, KRADConstants.MAPPING_CLOSE, "");
1020             } else {
1021                 Object buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON);
1022 
1023                 
1024                 
1025                 Map<String, Object> unconvertedValues = restoreUnconvertedValuesFromSession(request, docForm);
1026 
1027                 if ((KRADConstants.DOCUMENT_SAVE_BEFORE_CLOSE_QUESTION.equals(question)) && ConfirmationQuestion.YES.equals(buttonClicked)) {
1028                     
1029 
1030                     
1031                     
1032                     
1033                     if (MapUtils.isNotEmpty(unconvertedValues)) for (Map.Entry<String, Object> entry : unconvertedValues.entrySet()) {
1034                         docForm.populateForProperty(entry.getKey(), entry.getValue(), unconvertedValues);
1035                     }
1036 
1037                     ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.DOCUMENT_EXPLANATION, document.getDocumentHeader().getExplanation(), "save", "");
1038                     if (forward != null) {
1039                         return forward;
1040                     }
1041 
1042                     getDocumentService().saveDocument(docForm.getDocument());
1043                 }
1044                 
1045             }
1046         }
1047 
1048         return returnToSender(request, mapping, docForm);
1049     }
1050 
1051     
1052     private void saveUnconvertedValuesToSession(HttpServletRequest request, KualiDocumentFormBase docForm) {
1053         if (MapUtils.isNotEmpty(docForm.getUnconvertedValues())) {
1054             request.getSession().setAttribute(getUnconvertedValuesSessionAttributeKey(docForm), new HashMap(docForm.getUnconvertedValues()));
1055         }
1056     }
1057 
1058     
1059     private Map<String, Object> restoreUnconvertedValuesFromSession(HttpServletRequest request,
1060             KualiDocumentFormBase docForm) {
1061         Map<String, Object> unconvertedValues =
1062                 (Map<String, Object>)request.getSession().getAttribute(getUnconvertedValuesSessionAttributeKey(docForm));
1063         if (MapUtils.isNotEmpty(unconvertedValues)) {
1064             request.getSession().removeAttribute(getUnconvertedValuesSessionAttributeKey(docForm));
1065             docForm.setUnconvertedValues(unconvertedValues); 
1066         }
1067         return unconvertedValues;
1068     }
1069 
1070     
1071     private String getUnconvertedValuesSessionAttributeKey(KualiDocumentFormBase docForm) {
1072         return "preCloseUnconvertedValues." + docForm.getDocId();
1073     }
1074 
1075     protected boolean canSave(ActionForm form) {
1076         KualiDocumentFormBase docForm = (KualiDocumentFormBase) form;
1077         return docForm.getDocumentActions().containsKey(KRADConstants.KUALI_ACTION_CAN_SAVE);
1078     }
1079 
1080     protected Object getQuestion(HttpServletRequest request) {
1081         return request.getParameter(KRADConstants.QUESTION_INST_ATTRIBUTE_NAME);
1082     }
1083 
1084     
1085 
1086 
1087 
1088 
1089 
1090 
1091 
1092 
1093 
1094     public ActionForward fyi(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1095         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1096         doProcessingAfterPost(kualiDocumentFormBase, request);
1097         getDocumentService().clearDocumentFyi(kualiDocumentFormBase.getDocument(), combineAdHocRecipients(kualiDocumentFormBase));
1098         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_FYIED);
1099         kualiDocumentFormBase.setAnnotation("");
1100         return returnToSender(request, mapping, kualiDocumentFormBase);
1101     }
1102 
1103     
1104 
1105 
1106 
1107 
1108 
1109 
1110 
1111 
1112 
1113     public ActionForward acknowledge(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1114         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1115         doProcessingAfterPost(kualiDocumentFormBase, request);
1116         getDocumentService().acknowledgeDocument(kualiDocumentFormBase.getDocument(), kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
1117         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_ACKNOWLEDGED);
1118         kualiDocumentFormBase.setAnnotation("");
1119         return returnToSender(request, mapping, kualiDocumentFormBase);
1120     }
1121 
1122     
1123 
1124 
1125 
1126 
1127 
1128 
1129 
1130 
1131 
1132     public ActionForward supervisorFunctions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1133         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1134 
1135 
1136         String workflowSuperUserUrl = getKualiConfigurationService().getPropertyValueAsString(
1137                 KRADConstants.WORKFLOW_URL_KEY) + "/SuperUser.do?methodToCall=displaySuperUserDocument&documentId=" + kualiDocumentFormBase.getDocument().getDocumentHeader().getDocumentNumber();
1138         response.sendRedirect(workflowSuperUserUrl);
1139 
1140         return null;
1141     }
1142 
1143     
1144 
1145 
1146 
1147 
1148 
1149 
1150     protected List<AdHocRouteRecipient> combineAdHocRecipients(KualiDocumentFormBase kualiDocumentFormBase) {
1151         List<AdHocRouteRecipient> adHocRecipients = new ArrayList<AdHocRouteRecipient>();
1152         adHocRecipients.addAll(kualiDocumentFormBase.getAdHocRoutePersons());
1153         adHocRecipients.addAll(kualiDocumentFormBase.getAdHocRouteWorkgroups());
1154         return adHocRecipients;
1155     }
1156 
1157     
1158 
1159 
1160 
1161 
1162 
1163     @Override
1164     public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1165         KualiDocumentFormBase kualiForm = (KualiDocumentFormBase) form;
1166         kualiForm.setDerivedValuesOnForm(request);
1167 
1168         super.refresh(mapping, form, request, response);
1169         refreshAdHocRoutingWorkgroupLookups(request, kualiForm);
1170 
1171         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1172     }
1173 
1174     
1175 
1176 
1177 
1178 
1179 
1180 
1181     @SuppressWarnings("unchecked")
1182     protected void refreshAdHocRoutingWorkgroupLookups(HttpServletRequest request, KualiDocumentFormBase kualiForm) throws WorkflowException {
1183         for (Enumeration<String> i = request.getParameterNames(); i.hasMoreElements();) {
1184             String parameterName = i.nextElement();
1185             if (parameterName.equals("newAdHocRouteWorkgroup.recipientName") && !"".equals(request.getParameter(parameterName))) {
1186                 
1187                 String namespace = KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE;
1188                 if (request.getParameter("newAdHocRouteWorkgroup.recipientNamespaceCode") != null && !"".equals(request.getParameter("newAdHocRouteWorkgroup.recipientNamespaceCode").trim())) {
1189                     namespace = request.getParameter("newAdHocRouteWorkgroup.recipientNamespaceCode").trim();
1190                 }
1191                 Group group = getGroupService().getGroupByNamespaceCodeAndName(namespace, request.getParameter(
1192                         parameterName));
1193                 if (group != null) {
1194                     kualiForm.getNewAdHocRouteWorkgroup().setId(group.getId());
1195                     kualiForm.getNewAdHocRouteWorkgroup().setRecipientName(group.getName());
1196                     kualiForm.getNewAdHocRouteWorkgroup().setRecipientNamespaceCode(group.getNamespaceCode());
1197                 } else {
1198                     GlobalVariables.getMessageMap().putError("newAdHocRouteWorkgroup.recipientNamespaceCode", RiceKeyConstants.ERROR_INVALID_ADHOC_WORKGROUP_NAMESPACECODE);
1199                     return;
1200                 }
1201             }
1202             if (parameterName.startsWith("adHocRouteWorkgroup[") && !"".equals(request.getParameter(parameterName))) {
1203                 if (parameterName.endsWith(".recipientName")) {
1204                     int lineNumber = Integer.parseInt(StringUtils.substringBetween(parameterName, "[", "]"));
1205                     
1206                     String namespaceParam = "adHocRouteWorkgroup[" + lineNumber + "].recipientNamespaceCode";
1207                     String namespace = KimConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE;
1208                     if (request.getParameter(namespaceParam) != null && !"".equals(request.getParameter(namespaceParam).trim())) {
1209                         namespace = request.getParameter(namespaceParam).trim();
1210                     }
1211                     Group group = getGroupService().getGroupByNamespaceCodeAndName(namespace, request.getParameter(
1212                             parameterName));
1213                     if (group != null) {
1214                         kualiForm.getAdHocRouteWorkgroup(lineNumber).setId(group.getId());
1215                         kualiForm.getAdHocRouteWorkgroup(lineNumber).setRecipientName(group.getName());
1216                         kualiForm.getAdHocRouteWorkgroup(lineNumber).setRecipientNamespaceCode(group.getNamespaceCode());
1217                     } else {
1218                         GlobalVariables.getMessageMap().putError(namespaceParam, RiceKeyConstants.ERROR_INVALID_ADHOC_WORKGROUP_NAMESPACECODE);
1219                         return;
1220                     }
1221                 }
1222             }
1223             
1224 
1225 
1226 
1227 
1228 
1229 
1230 
1231 
1232 
1233 
1234 
1235 
1236 
1237 
1238 
1239 
1240 
1241 
1242 
1243 
1244         }
1245     }
1246 
1247 
1248     
1249 
1250 
1251 
1252 
1253 
1254 
1255 
1256 
1257 
1258     public ActionForward cancelBOAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1259         KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form;
1260 
1261         
1262         documentForm.setAttachmentFile(new BlankFormFile());
1263 
1264         
1265         Note note = documentForm.getNewNote();
1266         note.removeAttachment();
1267         documentForm.setNewNote(note);
1268 
1269         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1270     }
1271 
1272     
1273 
1274 
1275 
1276 
1277 
1278 
1279 
1280 
1281     protected void streamToResponse(byte[] fileContents, String fileName, String fileContentType, HttpServletResponse response) throws Exception {
1282         ByteArrayOutputStream baos = null;
1283         try {
1284             baos = new ByteArrayOutputStream(fileContents.length);
1285             baos.write(fileContents);
1286             WebUtils.saveMimeOutputStreamAsFile(response, fileContentType, baos, fileName);
1287         } finally {
1288             try {
1289                 if (baos != null) {
1290                     baos.close();
1291                     baos = null;
1292                 }
1293             } catch (IOException ioEx) {
1294                 LOG.error("Error while downloading attachment");
1295                 throw new RuntimeException("IOException occurred while downloading attachment", ioEx);
1296             }
1297         }
1298     }
1299 
1300     
1301 
1302 
1303 
1304 
1305 
1306 
1307 
1308 
1309 
1310     public ActionForward downloadBOAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1311         KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form;
1312 
1313         int attachmentIndex = selectedAttachmentIndex(request);
1314         if (attachmentIndex >= 0) {
1315             Note note = documentForm.getDocument().getNote(attachmentIndex);
1316             Attachment attachment = note.getAttachment();
1317             
1318             attachment.setNote(note);
1319 
1320             
1321             documentForm.copyPopulateEditablePropertiesToActionEditableProperties();
1322 
1323             WebUtils.saveMimeInputStreamAsFile(response, attachment.getAttachmentMimeTypeCode(), attachment.getAttachmentContents(), attachment.getAttachmentFileName(), attachment.getAttachmentFileSize().intValue());
1324             return null;
1325         }
1326 
1327         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1328     }
1329 
1330 
1331     
1332 
1333 
1334 
1335     protected int selectedAttachmentIndex(HttpServletRequest request) {
1336         int attachmentIndex = -1;
1337 
1338         String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
1339         if (StringUtils.isNotBlank(parameterName)) {
1340             String attachmentIndexParam = StringUtils.substringBetween(parameterName, ".attachment[", "].");
1341 
1342             try {
1343                 attachmentIndex = Integer.parseInt(attachmentIndexParam);
1344             } catch (NumberFormatException ignored) {
1345             }
1346         }
1347 
1348         return attachmentIndex;
1349     }
1350 
1351 
1352     
1353 
1354 
1355 
1356 
1357 
1358 
1359 
1360 
1361 
1362     public ActionForward insertBONote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1363         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1364         Document document = kualiDocumentFormBase.getDocument();
1365         Note newNote = kualiDocumentFormBase.getNewNote();
1366         newNote.setNotePostedTimestampToCurrent();
1367 
1368         String attachmentTypeCode = null;
1369 
1370         FormFile attachmentFile = kualiDocumentFormBase.getAttachmentFile();
1371         if (attachmentFile == null) {
1372             GlobalVariables.getMessageMap().putError(
1373                     String.format("%s.%s",
1374                             KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME,
1375                             KRADConstants.NOTE_ATTACHMENT_FILE_PROPERTY_NAME),
1376                     RiceKeyConstants.ERROR_UPLOADFILE_NULL);
1377             
1378             
1379         }
1380 
1381         if (newNote.getAttachment() != null) {
1382             attachmentTypeCode = newNote.getAttachment().getAttachmentTypeCode();
1383         }
1384 
1385         
1386         DocumentAuthorizer documentAuthorizer = getDocumentHelperService().getDocumentAuthorizer(document);
1387         if (!documentAuthorizer.canAddNoteAttachment(document, attachmentTypeCode, GlobalVariables.getUserSession().getPerson())) {
1388             throw buildAuthorizationException("annotate", document);
1389         }
1390 
1391         
1392 
1393         Attachment attachment = null;
1394         if (attachmentFile != null && !StringUtils.isBlank(attachmentFile.getFileName())) {
1395             if (attachmentFile.getFileSize() == 0) {
1396                 GlobalVariables.getMessageMap().putError(
1397                         String.format("%s.%s",
1398                                 KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME,
1399                                 KRADConstants.NOTE_ATTACHMENT_FILE_PROPERTY_NAME),
1400                         RiceKeyConstants.ERROR_UPLOADFILE_EMPTY,
1401                         attachmentFile.getFileName());
1402                 
1403 
1404             } else {
1405                 String attachmentType = null;
1406                 Attachment newAttachment = kualiDocumentFormBase.getNewNote().getAttachment();
1407                 if (newAttachment != null) {
1408                     attachmentType = newAttachment.getAttachmentTypeCode();
1409                 }
1410                 attachment = getAttachmentService().createAttachment(document.getNoteTarget(), attachmentFile.getFileName(), attachmentFile.getContentType(), attachmentFile.getFileSize(), attachmentFile.getInputStream(), attachmentType);
1411             }
1412         }
1413 
1414         DataDictionary dataDictionary = getDataDictionaryService().getDataDictionary();
1415         org.kuali.rice.krad.datadictionary.DocumentEntry entry = dataDictionary.getDocumentEntry(document.getClass().getName());
1416 
1417         if (entry.getDisplayTopicFieldInNotes()) {
1418             String topicText = kualiDocumentFormBase.getNewNote().getNoteTopicText();
1419             if (StringUtils.isBlank(topicText)) {
1420                 GlobalVariables.getMessageMap().putError(
1421                         String.format("%s.%s",
1422                                 KRADConstants.NEW_DOCUMENT_NOTE_PROPERTY_NAME,
1423                                 KRADConstants.NOTE_TOPIC_TEXT_PROPERTY_NAME),
1424                         RiceKeyConstants.ERROR_REQUIRED,
1425                         "Note Topic (Note Topic)");
1426             }
1427         }
1428 
1429         
1430         
1431         Person kualiUser = GlobalVariables.getUserSession().getPerson();
1432         if (kualiUser == null) {
1433             throw new IllegalStateException("Current UserSession has a null Person.");
1434         }
1435         Note tmpNote = getNoteService().createNote(newNote, document.getNoteTarget(), kualiUser.getPrincipalId());
1436 
1437         ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response, KRADPropertyConstants.NOTE, tmpNote.getNoteText(), "insertBONote", "");
1438         if (forward != null) {
1439             return forward;
1440         }
1441 
1442         
1443         boolean rulePassed = getKualiRuleService().applyRules(new AddNoteEvent(document, tmpNote));
1444 
1445         
1446         if (rulePassed) {
1447             tmpNote.refresh();
1448 
1449 
1450             DocumentHeader documentHeader = document.getDocumentHeader();
1451 
1452             
1453             document.addNote(tmpNote);
1454 
1455             
1456             
1457             
1458             if (!documentHeader.getWorkflowDocument().isInitiated() && StringUtils.isNotEmpty(document.getNoteTarget().getObjectId())
1459                     && !(document instanceof MaintenanceDocument && NoteType.BUSINESS_OBJECT.getCode().equals(tmpNote.getNoteTypeCode()))
1460                     ) {
1461                 getNoteService().save(tmpNote);
1462             }
1463             
1464             
1465             
1466             if (attachment != null) {
1467                 tmpNote.addAttachment(attachment);
1468                 
1469                 
1470                 if (!documentHeader.getWorkflowDocument().isInitiated() && StringUtils.isNotEmpty(document.getNoteTarget().getObjectId())
1471                         && !(document instanceof MaintenanceDocument && NoteType.BUSINESS_OBJECT.getCode().equals(tmpNote.getNoteTypeCode()))
1472                         ) {
1473                     getNoteService().save(tmpNote);
1474                 }
1475             }
1476 
1477 
1478             
1479             kualiDocumentFormBase.setNewNote(new Note());
1480         }
1481 
1482 
1483         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1484     }
1485 
1486     
1487 
1488 
1489 
1490 
1491 
1492 
1493 
1494 
1495 
1496     public ActionForward deleteBONote(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1497         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1498         Document document = kualiDocumentFormBase.getDocument();
1499 
1500 
1501 
1502 
1503 
1504         
1505         
1506         
1507         
1508         
1509         
1510 
1511         
1512         
1513         Note newNote = kualiDocumentFormBase.getNewNote();
1514         Note note = document.getNote(getLineToDelete(request));
1515         Attachment attachment = note.getAttachment();
1516         String attachmentTypeCode = null;
1517         if (attachment != null) {
1518             attachmentTypeCode = attachment.getAttachmentTypeCode();
1519         }
1520         String authorUniversalIdentifier = note.getAuthorUniversalIdentifier();
1521         if (!WebUtils.canDeleteNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier)) {
1522             throw buildAuthorizationException("annotate", document);
1523         }
1524 
1525         if (attachment != null) { 
1526             
1527             
1528             
1529             if (note.getNoteIdentifier() != null) { 
1530                 attachment.refreshNonUpdateableReferences();
1531             }
1532             getAttachmentService().deleteAttachmentContents(attachment);
1533         }
1534         
1535         if (!document.getDocumentHeader().getWorkflowDocument().isInitiated()) {
1536             getNoteService().deleteNote(note);
1537         }
1538         document.removeNote(note);
1539 
1540         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1541     }
1542 
1543     
1544 
1545 
1546 
1547 
1548 
1549 
1550 
1551     protected String determineNoteWorkflowNotificationAction(HttpServletRequest request, KualiDocumentFormBase kualiDocumentFormBase, Note note) {
1552         return getParameterService().getParameterValueAsString(KRADConstants.KNS_NAMESPACE, KRADConstants.DetailTypes.DOCUMENT_DETAIL_TYPE, KRADConstants.SEND_NOTE_WORKFLOW_NOTIFICATION_ACTIONS_PARM_NM);
1553     }
1554 
1555     public ActionForward sendNoteWorkflowNotification(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1556         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1557         Document document = kualiDocumentFormBase.getDocument();
1558 
1559         Note note = document.getNote(getSelectedLine(request));
1560 
1561         
1562         if (StringUtils.isBlank(note.getAdHocRouteRecipient().getId())) {
1563             GlobalVariables.getMessageMap().putError(KRADPropertyConstants.NEW_DOCUMENT_NOTE, RiceKeyConstants.ERROR_SEND_NOTE_NOTIFICATION_RECIPIENT);
1564             return mapping.findForward(RiceConstants.MAPPING_BASIC);
1565         }
1566         
1567         else {
1568             note.getAdHocRouteRecipient().setActionRequested(determineNoteWorkflowNotificationAction(request, kualiDocumentFormBase, note));
1569 
1570             boolean rulePassed = getKualiRuleService().applyRules(new AddAdHocRoutePersonEvent(KRADPropertyConstants.NEW_DOCUMENT_NOTE, document, (AdHocRoutePerson) note.getAdHocRouteRecipient()));
1571             if (!rulePassed) {
1572                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
1573             }
1574         }
1575 
1576         
1577         if (!document.getDocumentHeader().getWorkflowDocument().isInitiated()) {
1578             getDocumentService().sendNoteRouteNotification(document, note, GlobalVariables.getUserSession().getPerson());
1579 
1580             
1581             KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_SEND_NOTE_NOTIFICATION_SUCCESSFUL);
1582         } else {
1583             GlobalVariables.getMessageMap().putError(KRADPropertyConstants.NEW_DOCUMENT_NOTE, RiceKeyConstants.ERROR_SEND_NOTE_NOTIFICATION_DOCSTATUS);
1584         }
1585 
1586         return mapping.findForward(RiceConstants.MAPPING_BASIC);
1587     }
1588 
1589 
1590     
1591 
1592 
1593 
1594 
1595     private final void logOjbOptimisticLockException(OptimisticLockException e) {
1596         if (LOG.isInfoEnabled()) {
1597             StringBuffer message = new StringBuffer("caught OptimisticLockException, caused by ");
1598             Object sourceObject = e.getSourceObject();
1599             String infix = null;
1600             try {
1601                 
1602                 infix = sourceObject.toString();
1603             } catch (Exception e2) {
1604                 
1605                 infix = sourceObject.getClass().getName();
1606             }
1607             message.append(infix);
1608 
1609             if (sourceObject instanceof PersistableBusinessObject) {
1610                 PersistableBusinessObject persistableObject = (PersistableBusinessObject) sourceObject;
1611                 message.append(" [versionNumber = ").append(persistableObject.getVersionNumber()).append("]");
1612             }
1613 
1614             LOG.info(message.toString(), e);
1615         }
1616     }
1617 
1618 
1619     
1620 
1621 
1622 
1623 
1624 
1625 
1626 
1627 
1628 
1629 
1630     public ActionForward promptBeforeValidation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1631         return promptBeforeValidation(mapping, form, request, response, "route");
1632     }
1633 
1634     
1635 
1636 
1637 
1638 
1639 
1640 
1641 
1642 
1643 
1644 
1645 
1646     public ActionForward promptBeforeValidation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String methodToCall) throws Exception {
1647         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
1648 
1649         
1650         Class<? extends PromptBeforeValidation> promptBeforeValidationClass = getDataDictionaryService().getPromptBeforeValidationClass(kualiDocumentFormBase.getDocTypeName());
1651         if (LOG.isDebugEnabled()) {
1652             LOG.debug("PromptBeforeValidationClass: " + promptBeforeValidationClass);
1653         }
1654         if (promptBeforeValidationClass != null) {
1655             PromptBeforeValidation promptBeforeValidation = promptBeforeValidationClass.newInstance();
1656             PromptBeforeValidationEvent event = new PromptBeforeValidationEvent("Pre Maint route Check", "", kualiDocumentFormBase.getDocument());
1657             boolean continueRoute = promptBeforeValidation.processPrompts(form, request, event);
1658             if (!continueRoute) {
1659                 if (event.isPerformQuestion()) {
1660                     return super.performQuestionWithoutInput(mapping, kualiDocumentFormBase, request, response, event.getQuestionId(), event.getQuestionText(), event.getQuestionType(), methodToCall, event.getQuestionContext());
1661                 } else {
1662                     
1663                     
1664                     
1665                     
1666                     
1667                     
1668                     
1669                     ActionForward actionForward = mapping.findForward(event.getActionForwardName());
1670                     if (actionForward == null) {
1671                         throw new RuntimeException("No ActionForwardName defined on this Event, no further actions will be processed.");
1672                     }
1673                     return actionForward;
1674                 }
1675             }
1676         }
1677 
1678         return null;
1679     }
1680 
1681 
1682     
1683 
1684 
1685 
1686 
1687 
1688     protected DocumentAuthorizationException buildAuthorizationException(String action, Document document) {
1689         return new DocumentAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(), action, document.getDocumentNumber());
1690     }
1691 
1692     protected boolean exitingDocument() {
1693     	String methodCalledViaDispatch = (String) GlobalVariables.getUserSession().retrieveObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_OBJECT_KEY);
1694         String methodCompleted = (String) GlobalVariables.getUserSession().retrieveObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_COMPLETE_OBJECT_KEY);
1695         return StringUtils.isNotEmpty(methodCompleted) && StringUtils.isNotEmpty(methodCalledViaDispatch) && methodCompleted.startsWith(methodCalledViaDispatch);
1696     }
1697 
1698     protected void setupDocumentExit() {
1699     	String methodCalledViaDispatch = (String) GlobalVariables.getUserSession().retrieveObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_OBJECT_KEY);
1700     	if(StringUtils.isNotEmpty(methodCalledViaDispatch)) {
1701     		GlobalVariables.getUserSession().addObject(DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_COMPLETE_OBJECT_KEY, (Object) (methodCalledViaDispatch + DocumentAuthorizerBase.USER_SESSION_METHOD_TO_CALL_COMPLETE_MARKER));
1702     	}
1703     }
1704 
1705     
1706 
1707 
1708 
1709 
1710 
1711 
1712     protected ActionForward returnToSender(HttpServletRequest request, ActionMapping mapping, KualiDocumentFormBase form) {
1713         final ActionForward dest;
1714         if (form.isReturnToActionList()) {
1715             String workflowBase = getKualiConfigurationService().getPropertyValueAsString(
1716                     KRADConstants.WORKFLOW_URL_KEY);
1717             String actionListUrl = workflowBase + "/ActionList.do";
1718 
1719             dest = new ActionForward(actionListUrl, true);
1720         } else if (StringUtils.isNotBlank(form.getBackLocation())) {
1721             dest = new ActionForward(form.getBackLocation(), true);
1722         } else {
1723             dest = mapping.findForward(KRADConstants.MAPPING_PORTAL);
1724         }
1725 
1726         setupDocumentExit();
1727         return dest;
1728     }
1729 
1730     @SuppressWarnings("unchecked")
1731     protected void populateAuthorizationFields(KualiDocumentFormBase formBase) {
1732         if (formBase.isFormDocumentInitialized()) {
1733             Document document = formBase.getDocument();
1734             Person user = GlobalVariables.getUserSession().getPerson();
1735             DocumentPresentationController documentPresentationController = KNSServiceLocator
1736                     .getDocumentHelperService().getDocumentPresentationController(document);
1737             DocumentAuthorizer documentAuthorizer = getDocumentHelperService().getDocumentAuthorizer(document);
1738             Set<String> documentActions = documentPresentationController.getDocumentActions(document);
1739             documentActions = documentAuthorizer.getDocumentActions(document, user, documentActions);
1740 
1741             if (getDataDictionaryService().getDataDictionary().getDocumentEntry(document.getClass().getName()).getUsePessimisticLocking()) {
1742                 documentActions = getPessimisticLockService().getDocumentActions(document, user, documentActions);
1743             }
1744 
1745             
1746             formBase.setDocumentActions(convertSetToMap(documentActions));
1747 
1748         }
1749     }
1750 
1751     protected void populateAdHocActionRequestCodes(KualiDocumentFormBase formBase) {
1752         Document document = formBase.getDocument();
1753         DocumentAuthorizer documentAuthorizer = getDocumentHelperService().getDocumentAuthorizer(document);
1754         Map<String, String> adHocActionRequestCodes = new HashMap<String, String>();
1755 
1756         if (documentAuthorizer.canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_FYI_REQ, GlobalVariables.getUserSession().getPerson())) {
1757             adHocActionRequestCodes.put(KewApiConstants.ACTION_REQUEST_FYI_REQ, KewApiConstants.ACTION_REQUEST_FYI_REQ_LABEL);
1758         }
1759         if (!document.getDocumentHeader().getWorkflowDocument().isFinal() && documentAuthorizer.canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, GlobalVariables.getUserSession().getPerson())) {
1760             adHocActionRequestCodes.put(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ_LABEL);
1761         }
1762         if (!(document.getDocumentHeader().getWorkflowDocument().isApproved() || document.getDocumentHeader().getWorkflowDocument().isProcessed() || document.getDocumentHeader().getWorkflowDocument().isFinal()) && documentAuthorizer.canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_APPROVE_REQ, GlobalVariables.getUserSession().getPerson())) {
1763             adHocActionRequestCodes.put(KewApiConstants.ACTION_REQUEST_APPROVE_REQ, KewApiConstants.ACTION_REQUEST_APPROVE_REQ_LABEL);
1764         }
1765 
1766         if ((document.getDocumentHeader().getWorkflowDocument().isInitiated() || document.getDocumentHeader().getWorkflowDocument().isSaved())
1767                 && documentAuthorizer.canSendAdHocRequests(document, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, GlobalVariables.getUserSession().getPerson())) {
1768             
1769             adHocActionRequestCodes.put(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ, KewApiConstants.ACTION_REQUEST_COMPLETE_REQ_LABEL);
1770         }
1771         formBase.setAdHocActionRequestCodes(adHocActionRequestCodes);
1772 
1773     }
1774 
1775 
1776     @SuppressWarnings("unchecked")
1777     protected Map convertSetToMap(Set s) {
1778         Map map = new HashMap();
1779         Iterator i = s.iterator();
1780         while (i.hasNext()) {
1781             Object key = i.next();
1782             map.put(key, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
1783         }
1784         return map;
1785     }
1786 
1787     
1788 
1789 
1790     protected DataDictionaryService getDataDictionaryService() {
1791         if (dataDictionaryService == null) {
1792             dataDictionaryService = KNSServiceLocator.getDataDictionaryService();
1793         }
1794         return dataDictionaryService;
1795     }
1796 
1797     protected DocumentHelperService getDocumentHelperService() {
1798         if (documentHelperService == null) {
1799             documentHelperService = KNSServiceLocator.getDocumentHelperService();
1800         }
1801         return this.documentHelperService;
1802     }
1803 
1804     protected DocumentService getDocumentService() {
1805         if (documentService == null) {
1806             documentService = KRADServiceLocatorWeb.getDocumentService();
1807         }
1808         return this.documentService;
1809     }
1810 
1811     protected ConfigurationService getKualiConfigurationService() {
1812         if (kualiConfigurationService == null) {
1813             kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService();
1814         }
1815         return this.kualiConfigurationService;
1816     }
1817 
1818     protected ParameterService getParameterService() {
1819         if (parameterService == null) {
1820             parameterService = CoreFrameworkServiceLocator.getParameterService();
1821         }
1822         return this.parameterService;
1823     }
1824 
1825     protected PessimisticLockService getPessimisticLockService() {
1826         if (pessimisticLockService == null) {
1827             pessimisticLockService = KRADServiceLocatorWeb.getPessimisticLockService();
1828         }
1829         return this.pessimisticLockService;
1830     }
1831 
1832     protected KualiRuleService getKualiRuleService() {
1833         if (kualiRuleService == null) {
1834             kualiRuleService = KRADServiceLocatorWeb.getKualiRuleService();
1835         }
1836         return this.kualiRuleService;
1837     }
1838 
1839     protected GroupService getGroupService() {
1840         if (groupService == null) {
1841             groupService = KimApiServiceLocator.getGroupService();
1842         }
1843         return this.groupService;
1844     }
1845 
1846     protected AttachmentService getAttachmentService() {
1847         if (attachmentService == null) {
1848             attachmentService = KRADServiceLocator.getAttachmentService();
1849         }
1850         return this.attachmentService;
1851     }
1852 
1853     protected NoteService getNoteService() {
1854         if (noteService == null) {
1855             noteService = KRADServiceLocator.getNoteService();
1856         }
1857         return this.noteService;
1858     }
1859 
1860     protected BusinessObjectService getBusinessObjectService() {
1861         if (businessObjectService == null) {
1862             businessObjectService = KRADServiceLocator.getBusinessObjectService();
1863         }
1864         return this.businessObjectService;
1865     }
1866 
1867     @Override
1868     protected BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
1869         if (businessObjectAuthorizationService == null) {
1870             businessObjectAuthorizationService = KNSServiceLocator.getBusinessObjectAuthorizationService();
1871         }
1872         return businessObjectAuthorizationService;
1873     }
1874 
1875     public BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
1876         if (businessObjectMetaDataService == null) {
1877             businessObjectMetaDataService = KNSServiceLocator.getBusinessObjectMetaDataService();
1878         }
1879         return this.businessObjectMetaDataService;
1880     }
1881 
1882     public EntityManagerFactory getEntityManagerFactory() {
1883         if (entityManagerFactory == null) {
1884             entityManagerFactory = KRADServiceLocator.getApplicationEntityManagerFactory();
1885         }
1886         return this.entityManagerFactory;
1887     }
1888 
1889     
1890 
1891 
1892     @Override
1893     public ActionForward hideAllTabs(ActionMapping mapping, ActionForm form,
1894                                      HttpServletRequest request, HttpServletResponse response)
1895             throws Exception {
1896         if (form instanceof KualiDocumentFormBase) {
1897             WebUtils.reuseErrorMapFromPreviousRequest((KualiDocumentFormBase) form);
1898         }
1899         return super.hideAllTabs(mapping, form, request, response);
1900     }
1901 
1902     
1903 
1904 
1905     @Override
1906     public ActionForward showAllTabs(ActionMapping mapping, ActionForm form,
1907                                      HttpServletRequest request, HttpServletResponse response)
1908             throws Exception {
1909         if (form instanceof KualiDocumentFormBase) {
1910             WebUtils.reuseErrorMapFromPreviousRequest((KualiDocumentFormBase) form);
1911         }
1912         return super.showAllTabs(mapping, form, request, response);
1913     }
1914 
1915     
1916 
1917 
1918     @Override
1919     public ActionForward toggleTab(ActionMapping mapping, ActionForm form,
1920                                    HttpServletRequest request, HttpServletResponse response)
1921             throws Exception {
1922         if (form instanceof KualiDocumentFormBase) {
1923             WebUtils.reuseErrorMapFromPreviousRequest((KualiDocumentFormBase) form);
1924         }
1925         return super.toggleTab(mapping, form, request, response);
1926     }
1927 
1928     @Override
1929     protected void doProcessingAfterPost(KualiForm form, HttpServletRequest request) {
1930         super.doProcessingAfterPost(form, request);
1931         if (form instanceof KualiDocumentFormBase) {
1932             Document document = ((KualiDocumentFormBase) form).getDocument();
1933 
1934             getBusinessObjectService().linkUserFields(document);
1935         }
1936     }
1937 
1938     
1939 
1940 
1941     private class ReasonPrompt {
1942         final String questionId;
1943         final String questionTextKey;
1944         final String questionType;
1945         final String missingReasonKey;
1946         final String questionCallerMapping;
1947         final String abortButton;
1948         final String noteIntroKey;
1949 
1950         private class Response {
1951             final String question;
1952             final ActionForward forward;
1953             final String reason;
1954             final String button;
1955             Response(String question, ActionForward forward) {
1956                 this(question, forward, null, null);
1957             }
1958             Response(String question, String reason, String button) {
1959                 this(question, null, reason, button);
1960             }
1961             private Response(String question, ActionForward forward, String reason, String button) {
1962                 this.question = question;
1963                 this.forward = forward;
1964                 this.reason = reason;
1965                 this.button = button;
1966             }
1967         }
1968 
1969         
1970 
1971 
1972 
1973 
1974 
1975 
1976 
1977         private ReasonPrompt(String questionId, String questionTextKey, String questionType, String missingReasonKey, String questionCallerMapping, String abortButton, String noteIntroKey) {
1978             this.questionId = questionId;
1979             this.questionTextKey = questionTextKey;
1980             this.questionType = questionType;
1981             this.questionCallerMapping = questionCallerMapping;
1982             this.abortButton = abortButton;
1983             this.noteIntroKey = noteIntroKey;
1984             this.missingReasonKey = missingReasonKey;
1985         }
1986 
1987         
1988 
1989 
1990 
1991 
1992 
1993 
1994 
1995 
1996 
1997         public Response ask(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
1998             String question = request.getParameter(KRADConstants.QUESTION_INST_ATTRIBUTE_NAME);
1999             String reason = request.getParameter(KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME);
2000 
2001             if (StringUtils.isBlank(reason)) {
2002                 String context = request.getParameter(KRADConstants.QUESTION_CONTEXT);
2003                 if (context != null && StringUtils.contains(context, KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME + "=")) {
2004                     reason = StringUtils.substringAfter(context, KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME + "=");
2005                 }
2006             }
2007 
2008             String disapprovalNoteText = "";
2009 
2010             
2011             if (question == null) {
2012                 
2013                 return new Response(question, performQuestionWithInput(mapping, form, request, response,
2014                         this.questionId,
2015                         getKualiConfigurationService().getPropertyValueAsString(this.questionTextKey),
2016                         this.questionType, this.questionCallerMapping, ""));
2017             }
2018 
2019             String buttonClicked = request.getParameter(KRADConstants.QUESTION_CLICKED_BUTTON);
2020             if (this.questionId.equals(question) && abortButton != null && abortButton.equals(buttonClicked)) {
2021                 
2022                 return new Response(question, mapping.findForward(RiceConstants.MAPPING_BASIC));
2023             }
2024 
2025             
2026             String introNoteMessage = "";
2027             if (noteIntroKey != null) {
2028                 introNoteMessage = getKualiConfigurationService().getPropertyValueAsString(this.noteIntroKey) + KRADConstants.BLANK_SPACE;
2029             }
2030 
2031             
2032             disapprovalNoteText = introNoteMessage + reason;
2033 
2034             
2035             boolean warnForSensitiveData = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsBoolean(
2036                     KRADConstants.KNS_NAMESPACE, ParameterConstants.ALL_COMPONENT,
2037                     KRADConstants.SystemGroupParameterNames.SENSITIVE_DATA_PATTERNS_WARNING_IND);
2038             if (warnForSensitiveData) {
2039                 String context = KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME + "=" + reason;
2040                 ActionForward forward = checkAndWarnAboutSensitiveData(mapping, form, request, response,
2041                         KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME, disapprovalNoteText, this.questionCallerMapping, context);
2042                 if (forward != null) {
2043                     return new Response(question, forward);
2044                 }
2045             } else {
2046                 if (KRADUtils.containsSensitiveDataPatternMatch(disapprovalNoteText)) {
2047                     return new Response(question, performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response,
2048                             this.questionId, getKualiConfigurationService().getPropertyValueAsString(this.questionTextKey),
2049                             this.questionType, this.questionCallerMapping, "", reason,
2050                             RiceKeyConstants.ERROR_DOCUMENT_FIELD_CONTAINS_POSSIBLE_SENSITIVE_DATA,
2051                             KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME, "reason"));
2052                 }
2053             }
2054 
2055             int disapprovalNoteTextLength = disapprovalNoteText.length();
2056 
2057             
2058             int noteTextMaxLength = getDataDictionaryService().getAttributeMaxLength(Note.class, KRADConstants.NOTE_TEXT_PROPERTY_NAME);
2059 
2060             if (StringUtils.isBlank(reason) || (disapprovalNoteTextLength > noteTextMaxLength)) {
2061 
2062                 if (reason == null) {
2063                     
2064                     reason = "";
2065                 }
2066                 return new Response(question, performQuestionWithInputAgainBecauseOfErrors(mapping, form, request, response,
2067                         this.questionId,
2068                         getKualiConfigurationService().getPropertyValueAsString(this.questionTextKey),
2069                         this.questionType, this.questionCallerMapping, "", reason,
2070                         this.missingReasonKey,
2071                         KRADConstants.QUESTION_REASON_ATTRIBUTE_NAME, Integer.toString(noteTextMaxLength)));
2072             }
2073 
2074             return new Response(question, disapprovalNoteText, buttonClicked);
2075         }
2076     }
2077 
2078     public ActionForward takeSuperUserActions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
2079         KualiDocumentFormBase documentForm = (KualiDocumentFormBase)form;
2080         if(StringUtils.isBlank(documentForm.getSuperUserAnnotation())) {
2081             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.takeactions.annotation.missing", "");
2082             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2083         } else if(documentForm.getSelectedActionRequests().isEmpty()) {
2084             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.takeactions.none.selected", "");
2085             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2086         }  else if (!documentForm.isStateAllowsApproveSingleActionRequest()) {
2087             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.takeactions.not.allowed", "");
2088             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2089         }
2090 
2091         for(String actionRequestId : documentForm.getSelectedActionRequests()) {
2092             ActionRequest actionRequest = null;
2093             for(ActionRequest pendingActionRequest : documentForm.getActionRequests()) {
2094                 if(StringUtils.equals(pendingActionRequest.getId(), actionRequestId)) {
2095                     actionRequest = pendingActionRequest;
2096                     break;
2097                 }
2098             }
2099             if(actionRequest == null) {
2100                 
2101                 continue;
2102             }
2103             if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.COMPLETE.getCode()) ||
2104                 StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.APPROVE.getCode())) {
2105                     getDocumentService().validateAndPersistDocument(documentForm.getDocument(), new RouteDocumentEvent(documentForm.getDocument()));
2106             }
2107 
2108             WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentForm.getWorkflowDocument().getDocumentTypeId());
2109             DocumentActionParameters parameters = DocumentActionParameters.create(documentForm.getDocId(), GlobalVariables.getUserSession().getPrincipalId(), documentForm.getSuperUserAnnotation());
2110             documentActions.superUserTakeRequestedAction(parameters, true, actionRequestId);
2111             String messageString;
2112             if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.ACKNOWLEDGE.getCode())) {
2113                 messageString = "general.routing.superuser.actionRequestAcknowledged";
2114             } else if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.FYI.getCode())) {
2115                 messageString = "general.routing.superuser.actionRequestFYI";
2116             } else if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.COMPLETE.getCode())) {
2117                 messageString = "general.routing.superuser.actionRequestCompleted";
2118             } else if (StringUtils.equals(actionRequest.getActionRequested().getCode(), ActionRequestType.APPROVE.getCode())) {
2119                 messageString = "general.routing.superuser.actionRequestApproved";
2120             } else {
2121                 messageString = "general.routing.superuser.actionRequestApproved";
2122             }
2123             GlobalVariables.getMessageMap().putInfo("document", messageString, documentForm.getDocId(), actionRequestId);
2124         }
2125         documentForm.setSuperUserAnnotation("");
2126         return mapping.findForward(RiceConstants.MAPPING_BASIC);
2127     }
2128 
2129     public ActionForward superUserDisapprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
2130     	KualiDocumentFormBase documentForm = (KualiDocumentFormBase)form;
2131     	if(StringUtils.isBlank(documentForm.getSuperUserAnnotation())) {
2132     		GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.disapprove.annotation.missing", "");
2133     		return mapping.findForward(RiceConstants.MAPPING_BASIC);
2134     	} else if (!documentForm.getSelectedActionRequests().isEmpty()) {
2135             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.disapprove.when.actions.checked", "");
2136             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2137         } else if (!documentForm.isStateAllowsApproveOrDisapprove()) {
2138             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.disapprove.not.allowed", "");
2139             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2140         }
2141 
2142         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentForm.getWorkflowDocument().getDocumentTypeId());
2143         DocumentActionParameters parameters = DocumentActionParameters.create(documentForm.getDocId(), GlobalVariables.getUserSession().getPrincipalId(), documentForm.getSuperUserAnnotation());
2144         documentActions.superUserDisapprove(parameters, true);
2145         GlobalVariables.getMessageMap().putInfo("document", "general.routing.superuser.disapproved", documentForm.getDocId());
2146         documentForm.setSuperUserAnnotation("");
2147         return mapping.findForward(RiceConstants.MAPPING_BASIC);
2148     }
2149 
2150     public ActionForward superUserApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
2151         KualiDocumentFormBase documentForm = (KualiDocumentFormBase)form;
2152         if(StringUtils.isBlank(documentForm.getSuperUserAnnotation())) {
2153             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.approve.annotation.missing", "");
2154             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2155         } else if (!documentForm.getSelectedActionRequests().isEmpty()) {
2156             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.approve.when.actions.checked", "");
2157             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2158         } else if (!documentForm.isStateAllowsApproveOrDisapprove()) {
2159             GlobalVariables.getMessageMap().putErrorForSectionId("superuser.errors", "superuser.approve.not.allowed", "");
2160             return mapping.findForward(RiceConstants.MAPPING_BASIC);
2161         }
2162 
2163         WorkflowDocumentActionsService documentActions = getWorkflowDocumentActionsService(documentForm.getWorkflowDocument().getDocumentTypeId());
2164         DocumentActionParameters parameters = DocumentActionParameters.create(documentForm.getDocId(), GlobalVariables.getUserSession().getPrincipalId(), documentForm.getSuperUserAnnotation());
2165         documentActions.superUserBlanketApprove(parameters, true);
2166         GlobalVariables.getMessageMap().putInfo("document", "general.routing.superuser.approved", documentForm.getDocId());
2167         documentForm.setSuperUserAnnotation("");
2168         return mapping.findForward(RiceConstants.MAPPING_BASIC);
2169     }
2170 
2171     private WorkflowDocumentActionsService getWorkflowDocumentActionsService(String documentTypeId) {
2172         DocumentType documentType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeById(documentTypeId);
2173         String applicationId = documentType.getApplicationId();
2174         QName serviceName = new QName(KewApiConstants.Namespaces.KEW_NAMESPACE_2_0,
2175                 KewApiConstants.ServiceNames.WORKFLOW_DOCUMENT_ACTIONS_SERVICE_SOAP);
2176         WorkflowDocumentActionsService service = (WorkflowDocumentActionsService) KsbApiServiceLocator.getServiceBus()
2177                 .getService(serviceName, applicationId);
2178         if (service == null) {
2179             service = KewApiServiceLocator.getWorkflowDocumentActionsService();
2180         }
2181         return service;
2182     }
2183     
2184     
2185 
2186 
2187 
2188 
2189 
2190 
2191 
2192 
2193 
2194     public ActionForward complete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
2195         KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form;
2196         doProcessingAfterPost(kualiDocumentFormBase, request);
2197 
2198         kualiDocumentFormBase.setDerivedValuesOnForm(request);
2199         ActionForward preRulesForward = promptBeforeValidation(mapping, form, request, response);
2200         if (preRulesForward != null) {
2201             return preRulesForward;
2202         }
2203 
2204         Document document = kualiDocumentFormBase.getDocument();
2205 
2206         getDocumentService().completeDocument(document, kualiDocumentFormBase.getAnnotation(), combineAdHocRecipients(kualiDocumentFormBase));
2207         KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_ROUTE_SUCCESSFUL);
2208         kualiDocumentFormBase.setAnnotation("");
2209 
2210         return mapping.findForward(RiceConstants.MAPPING_BASIC);
2211     }
2212     
2213     
2214 
2215 
2216 
2217 
2218     protected boolean hasPendingAdhocForCompletion(KualiDocumentFormBase kualiDocumentFormBase){
2219         List<AdHocRouteRecipient> adHocRecipients = this.combineAdHocRecipients(kualiDocumentFormBase);
2220         
2221         for(AdHocRouteRecipient receipients : adHocRecipients){
2222             String actionRequestedCode = receipients.getActionRequested();
2223             
2224             if(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(actionRequestedCode)){
2225                 return true;
2226             }
2227         }
2228         
2229         return false;
2230     }
2231     
2232 }
2233