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.log4j.Logger; 019import org.kuali.rice.core.api.util.xml.XmlJotter; 020import org.kuali.rice.edl.impl.EDLContext; 021import org.kuali.rice.edl.impl.EDLModelComponent; 022import org.kuali.rice.edl.impl.EDLXmlUtils; 023import org.kuali.rice.edl.impl.RequestParser; 024import org.kuali.rice.edl.impl.UserAction; 025import org.kuali.rice.kew.api.WorkflowDocument; 026import org.kuali.rice.kew.api.WorkflowDocumentFactory; 027import org.kuali.rice.kew.api.WorkflowRuntimeException; 028import org.kuali.rice.kew.api.document.DocumentStatus; 029import org.kuali.rice.kew.api.exception.WorkflowException; 030import org.w3c.dom.Document; 031import org.w3c.dom.Element; 032 033/** 034 * Used as a pre processor and post processor. As a pre processor this creates/fetches the workflow 035 * document and sets it on request. As a post processor this takes appropriate user action on the 036 * document if the document is not in error. 037 * 038 * @author Kuali Rice Team (rice.collab@kuali.org) 039 * 040 */ 041public class WorkflowDocumentActions implements EDLModelComponent { 042 043 private static final Logger LOG = Logger.getLogger(WorkflowDocumentActions.class); 044 045 public static final String ACTION_TAKEN = "actionTaken"; 046 047 boolean isPreProcessor; 048 049 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) { 050 051 try { 052 isPreProcessor = configElement.getTagName().equals("preProcessor"); 053 if (isPreProcessor) { 054 doPreProcessWork(edlContext); 055 } else { 056 doPostProcessWork(dom, edlContext); 057 } 058 } catch (Exception e) { 059 throw new WorkflowRuntimeException(e); 060 } 061 062 } 063 064 private void doPreProcessWork(EDLContext edlContext) throws Exception { 065 RequestParser requestParser = edlContext.getRequestParser(); 066 067 UserAction userAction = edlContext.getUserAction(); 068 WorkflowDocument document = null; 069 if (UserAction.ACTION_CREATE.equals(userAction.getAction())) { 070 document = WorkflowDocumentFactory.createDocument(edlContext.getUserSession().getPrincipalId(), edlContext 071 .getEdocLiteAssociation().getEdlName()); 072 document.setTitle("Routing Document Type '" + document.getDocumentTypeName() + "'"); 073 document.getDocumentId(); 074 LOG.info("Created document " + document.getDocumentId()); 075 } else { 076 document = (WorkflowDocument) requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); 077 if (document == null) { 078 String docId = (String) requestParser.getAttribute("docId"); 079 if (docId == null) { 080 LOG.info("no document found for edl " + edlContext.getEdocLiteAssociation().getEdlName()); 081 return; 082 } else { 083 document = WorkflowDocumentFactory 084 .loadDocument(edlContext.getUserSession().getPrincipalId(), docId); 085 } 086 } 087 } 088 089 requestParser.setAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY, document); 090 } 091 092 private void doPostProcessWork(Document dom, EDLContext edlContext) throws Exception { 093 RequestParser requestParser = edlContext.getRequestParser(); 094 // if the document is in error then we don't want to execute the action! 095 if (edlContext.isInError()) { 096 return; 097 } 098 WorkflowDocument document = (WorkflowDocument) edlContext.getRequestParser().getAttribute( 099 RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); 100 if (document == null) { 101 return; 102 } 103 //strip out the data element 104 Element dataElement = (Element) dom.getElementsByTagName(EDLXmlUtils.DATA_E).item(0); 105 String docContent = XmlJotter.jotNode(dataElement);//use the transformer on edlcontext 106 document.setApplicationContent(docContent); 107 takeAction(document, dom, edlContext); 108 } 109 110 public static void takeAction(WorkflowDocument document, Document dom, EDLContext edlContext) 111 throws WorkflowException { 112 RequestParser requestParser = edlContext.getRequestParser(); 113 UserAction userAction = edlContext.getUserAction(); 114 String annotation = requestParser.getParameterValue("annotation"); 115 String action = userAction.getAction(); 116 String previousNodeName = requestParser.getParameterValue("previousNode"); 117 118 if (!userAction.isValidatableAction()) { 119 // if the action's not validatable, clear the attribute definitions because we don't want to end up executing validateClientRoutingData() 120 // 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 121 document.clearAttributeDefinitions(); 122 } 123 124 boolean actionTaken = true; 125 126 if (UserAction.ACTION_ROUTE.equals(action)) { 127 document.route(annotation); 128 }else if(UserAction.ACTION_CREATE.equals(action)){ 129 document.saveDocumentData(); 130 } 131 else if (UserAction.ACTION_APPROVE.equals(action)) { 132 document.approve(annotation); 133 } else if (UserAction.ACTION_DISAPPROVE.equals(action)) { 134 document.disapprove(annotation); 135 } else if (UserAction.ACTION_CANCEL.equals(action)) { 136 document.cancel(annotation); 137 } else if (UserAction.ACTION_BLANKETAPPROVE.equals(action)) { 138 document.blanketApprove(annotation); 139 } else if (UserAction.ACTION_FYI.equals(action)) { 140 document.fyi(); 141 } else if (UserAction.ACTION_ACKNOWLEDGE.equals(action)) { 142 document.acknowledge(annotation); 143 } else if (UserAction.ACTION_SAVE.equals(action)) { 144 if (document.getStatus().equals(DocumentStatus.INITIATED)) { 145 document.saveDocument(annotation); 146 } else { 147 document.saveDocumentData(); 148 } 149 } else if (UserAction.ACTION_COMPLETE.equals(action)) { 150 document.complete(annotation); 151 } else if (UserAction.ACTION_DELETE.equals(action)) { 152 document.delete(); 153 } else if (UserAction.ACTION_RETURN_TO_PREVIOUS.equals(action)) { 154 document.returnToPreviousNode(annotation, previousNodeName); 155 } else { 156 actionTaken = false; 157 } 158 159 if (actionTaken) { 160 Element actionTakenElement = EDLXmlUtils.getOrCreateChildElement(dom.getDocumentElement(), ACTION_TAKEN, 161 true); 162 actionTakenElement.appendChild(dom.createTextNode(action)); 163 } 164 } 165 166}