View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.edl.impl.components;
17  
18  import org.apache.log4j.Logger;
19  import org.kuali.rice.core.api.util.xml.XmlJotter;
20  import org.kuali.rice.edl.impl.EDLContext;
21  import org.kuali.rice.edl.impl.EDLModelComponent;
22  import org.kuali.rice.edl.impl.EDLXmlUtils;
23  import org.kuali.rice.edl.impl.RequestParser;
24  import org.kuali.rice.edl.impl.UserAction;
25  import org.kuali.rice.kew.api.WorkflowDocument;
26  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
27  import org.kuali.rice.kew.api.WorkflowRuntimeException;
28  import org.kuali.rice.kew.api.document.DocumentStatus;
29  import org.kuali.rice.kew.api.exception.WorkflowException;
30  import org.w3c.dom.Document;
31  import org.w3c.dom.Element;
32  
33  /**
34   * Used as a pre processor and post processor. As a pre processor this creates/fetches the workflow
35   * document and sets it on request. As a post processor this takes appropriate user action on the
36   * document if the document is not in error.
37   * 
38   * @author Kuali Rice Team (rice.collab@kuali.org)
39   * 
40   */
41  public class WorkflowDocumentActions implements EDLModelComponent {
42  
43      private static final Logger LOG = Logger.getLogger(WorkflowDocumentActions.class);
44  
45      public static final String ACTION_TAKEN = "actionTaken";
46  
47      boolean isPreProcessor;
48  
49      public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
50  
51          try {
52              isPreProcessor = configElement.getTagName().equals("preProcessor");
53              if (isPreProcessor) {
54                  doPreProcessWork(edlContext);
55              } else {
56                  doPostProcessWork(dom, edlContext);
57              }
58          } catch (Exception e) {
59              throw new WorkflowRuntimeException(e);
60          }
61  
62      }
63  
64      private void doPreProcessWork(EDLContext edlContext) throws Exception {
65          RequestParser requestParser = edlContext.getRequestParser();
66  
67          UserAction userAction = edlContext.getUserAction();
68          WorkflowDocument document = null;
69          if (UserAction.ACTION_CREATE.equals(userAction.getAction())) {
70              document = WorkflowDocumentFactory.createDocument(edlContext.getUserSession().getPrincipalId(), edlContext
71                      .getEdocLiteAssociation().getEdlName());
72              document.setTitle("Routing Document Type '" + document.getDocumentTypeName() + "'");
73              document.getDocumentId();
74              LOG.info("Created document " + document.getDocumentId());
75          } else {
76              document = (WorkflowDocument) requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY);
77              if (document == null) {
78                  String docId = (String) requestParser.getAttribute("docId");
79                  if (docId == null) {
80                      LOG.info("no document found for edl " + edlContext.getEdocLiteAssociation().getEdlName());
81                      return;
82                  } else {
83                      document = WorkflowDocumentFactory
84                              .loadDocument(edlContext.getUserSession().getPrincipalId(), docId);
85                  }
86              }
87          }
88  
89          requestParser.setAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY, document);
90      }
91  
92      private void doPostProcessWork(Document dom, EDLContext edlContext) throws Exception {
93          RequestParser requestParser = edlContext.getRequestParser();
94          // if the document is in error then we don't want to execute the action!
95          if (edlContext.isInError()) {
96              return;
97          }
98          WorkflowDocument document = (WorkflowDocument) edlContext.getRequestParser().getAttribute(
99                  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 }