001/** 002 * Copyright 2005-2015 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.edl.impl.components; 017 018import org.apache.logging.log4j.Logger; 019import org.apache.logging.log4j.LogManager; 020import org.kuali.rice.core.api.util.xml.XmlJotter; 021import org.kuali.rice.edl.impl.EDLContext; 022import org.kuali.rice.edl.impl.EDLModelComponent; 023import org.kuali.rice.edl.impl.EDLXmlUtils; 024import org.kuali.rice.edl.impl.RequestParser; 025import org.kuali.rice.edl.impl.UserAction; 026import org.kuali.rice.kew.api.WorkflowDocument; 027import org.kuali.rice.kew.api.WorkflowDocumentFactory; 028import org.kuali.rice.kew.api.WorkflowRuntimeException; 029import org.kuali.rice.kew.api.document.DocumentStatus; 030import org.kuali.rice.kew.api.exception.WorkflowException; 031import org.w3c.dom.Document; 032import org.w3c.dom.Element; 033 034/** 035 * Used as a pre processor and post processor. As a pre processor this creates/fetches the workflow 036 * document and sets it on request. As a post processor this takes appropriate user action on the 037 * document if the document is not in error. 038 * 039 * @author Kuali Rice Team (rice.collab@kuali.org) 040 * 041 */ 042public class WorkflowDocumentActions implements EDLModelComponent { 043 044 private static final Logger LOG = LogManager.getLogger(WorkflowDocumentActions.class); 045 046 public static final String ACTION_TAKEN = "actionTaken"; 047 048 boolean isPreProcessor; 049 050 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) { 051 052 try { 053 isPreProcessor = configElement.getTagName().equals("preProcessor"); 054 if (isPreProcessor) { 055 doPreProcessWork(edlContext); 056 } else { 057 doPostProcessWork(dom, edlContext); 058 } 059 } catch (Exception e) { 060 throw new WorkflowRuntimeException(e); 061 } 062 063 } 064 065 private void doPreProcessWork(EDLContext edlContext) throws Exception { 066 RequestParser requestParser = edlContext.getRequestParser(); 067 068 UserAction userAction = edlContext.getUserAction(); 069 WorkflowDocument document = null; 070 if (UserAction.ACTION_CREATE.equals(userAction.getAction())) { 071 document = WorkflowDocumentFactory.createDocument(edlContext.getUserSession().getPrincipalId(), edlContext 072 .getEdocLiteAssociation().getEdlName()); 073 document.setTitle("Routing Document Type '" + document.getDocumentTypeName() + "'"); 074 document.getDocumentId(); 075 LOG.info("Created document " + document.getDocumentId()); 076 } else { 077 document = (WorkflowDocument) requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); 078 if (document == null) { 079 String docId = (String) requestParser.getAttribute("docId"); 080 if (docId == null) { 081 LOG.info("no document found for edl " + edlContext.getEdocLiteAssociation().getEdlName()); 082 return; 083 } else { 084 document = WorkflowDocumentFactory 085 .loadDocument(edlContext.getUserSession().getPrincipalId(), docId); 086 } 087 } 088 } 089 090 requestParser.setAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY, document); 091 } 092 093 private void doPostProcessWork(Document dom, EDLContext edlContext) throws Exception { 094 RequestParser requestParser = edlContext.getRequestParser(); 095 // if the document is in error then we don't want to execute the action! 096 if (edlContext.isInError()) { 097 return; 098 } 099 WorkflowDocument document = (WorkflowDocument) edlContext.getRequestParser().getAttribute( 100 RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); 101 if (document == null) { 102 return; 103 } 104 //strip out the data element 105 Element dataElement = (Element) dom.getElementsByTagName(EDLXmlUtils.DATA_E).item(0); 106 String docContent = XmlJotter.jotNode(dataElement);//use the transformer on edlcontext 107 document.setApplicationContent(docContent); 108 takeAction(document, dom, edlContext); 109 } 110 111 public static void takeAction(WorkflowDocument document, Document dom, EDLContext edlContext) 112 throws WorkflowException { 113 RequestParser requestParser = edlContext.getRequestParser(); 114 UserAction userAction = edlContext.getUserAction(); 115 String annotation = requestParser.getParameterValue("annotation"); 116 String action = userAction.getAction(); 117 String previousNodeName = requestParser.getParameterValue("previousNode"); 118 119 if (!userAction.isValidatableAction()) { 120 // if the action's not validatable, clear the attribute definitions because we don't want to end up executing validateClientRoutingData() 121 // TODO the problem here is that the XML is still updated on a cancel so we end up without any attribute content in the document content 122 document.clearAttributeDefinitions(); 123 } 124 125 boolean actionTaken = true; 126 127 if (UserAction.ACTION_ROUTE.equals(action)) { 128 document.route(annotation); 129 }else if(UserAction.ACTION_CREATE.equals(action)){ 130 document.saveDocumentData(); 131 } 132 else if (UserAction.ACTION_APPROVE.equals(action)) { 133 document.approve(annotation); 134 } else if (UserAction.ACTION_DISAPPROVE.equals(action)) { 135 document.disapprove(annotation); 136 } else if (UserAction.ACTION_CANCEL.equals(action)) { 137 document.cancel(annotation); 138 } else if (UserAction.ACTION_BLANKETAPPROVE.equals(action)) { 139 document.blanketApprove(annotation); 140 } else if (UserAction.ACTION_FYI.equals(action)) { 141 document.fyi(); 142 } else if (UserAction.ACTION_ACKNOWLEDGE.equals(action)) { 143 document.acknowledge(annotation); 144 } else if (UserAction.ACTION_SAVE.equals(action)) { 145 if (document.getStatus().equals(DocumentStatus.INITIATED)) { 146 document.saveDocument(annotation); 147 } else { 148 document.saveDocumentData(); 149 } 150 } else if (UserAction.ACTION_COMPLETE.equals(action)) { 151 document.complete(annotation); 152 } else if (UserAction.ACTION_DELETE.equals(action)) { 153 document.delete(); 154 } else if (UserAction.ACTION_RETURN_TO_PREVIOUS.equals(action)) { 155 document.returnToPreviousNode(annotation, previousNodeName); 156 } else { 157 actionTaken = false; 158 } 159 160 if (actionTaken) { 161 Element actionTakenElement = EDLXmlUtils.getOrCreateChildElement(dom.getDocumentElement(), ACTION_TAKEN, 162 true); 163 actionTakenElement.appendChild(dom.createTextNode(action)); 164 } 165 } 166 167}