View Javadoc

1   /**
2    * Copyright 2005-2011 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_APPROVE.equals(action)) {
129             document.approve(annotation);
130         } else if (UserAction.ACTION_DISAPPROVE.equals(action)) {
131             document.disapprove(annotation);
132         } else if (UserAction.ACTION_CANCEL.equals(action)) {
133             document.cancel(annotation);
134         } else if (UserAction.ACTION_BLANKETAPPROVE.equals(action)) {
135             document.blanketApprove(annotation);
136         } else if (UserAction.ACTION_FYI.equals(action)) {
137             document.fyi();
138         } else if (UserAction.ACTION_ACKNOWLEDGE.equals(action)) {
139             document.acknowledge(annotation);
140         } else if (UserAction.ACTION_SAVE.equals(action)) {
141             if (document.getStatus().equals(DocumentStatus.INITIATED)) {
142                 document.saveDocument(annotation);
143             } else {
144                 document.saveDocumentData();
145             }
146         } else if (UserAction.ACTION_COMPLETE.equals(action)) {
147             document.complete(annotation);
148         } else if (UserAction.ACTION_DELETE.equals(action)) {
149             document.delete();
150         } else if (UserAction.ACTION_RETURN_TO_PREVIOUS.equals(action)) {
151             document.returnToPreviousNode(annotation, previousNodeName);
152         } else {
153             actionTaken = false;
154         }
155 
156         if (actionTaken) {
157             Element actionTakenElement = EDLXmlUtils.getOrCreateChildElement(dom.getDocumentElement(), ACTION_TAKEN,
158                     true);
159             actionTakenElement.appendChild(dom.createTextNode(action));
160         }
161     }
162 
163 }