001 /**
002 * Copyright 2005-2012 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 */
016 package org.kuali.rice.edl.impl.components;
017
018 import org.apache.log4j.Logger;
019 import org.kuali.rice.core.api.util.xml.XmlJotter;
020 import org.kuali.rice.edl.impl.EDLContext;
021 import org.kuali.rice.edl.impl.EDLModelComponent;
022 import org.kuali.rice.edl.impl.EDLXmlUtils;
023 import org.kuali.rice.edl.impl.RequestParser;
024 import org.kuali.rice.edl.impl.UserAction;
025 import org.kuali.rice.kew.api.WorkflowDocument;
026 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
027 import org.kuali.rice.kew.api.WorkflowRuntimeException;
028 import org.kuali.rice.kew.api.document.DocumentStatus;
029 import org.kuali.rice.kew.api.exception.WorkflowException;
030 import org.w3c.dom.Document;
031 import 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 */
041 public 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 }