View Javadoc
1   /**
2    * Copyright 2005-2016 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.framework.workflow;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.jdom.Attribute;
20  import org.jdom.Element;
21  import org.kuali.rice.core.api.util.xml.XmlHelper;
22  import org.kuali.rice.core.api.util.xml.XmlJotter;
23  import org.kuali.rice.edl.framework.extract.DumpDTO;
24  import org.kuali.rice.edl.framework.extract.ExtractService;
25  import org.kuali.rice.edl.framework.extract.FieldDTO;
26  import org.kuali.rice.edl.framework.services.EdlFrameworkServiceLocator;
27  import org.kuali.rice.kew.api.KewApiConstants;
28  import org.kuali.rice.kew.api.KewApiServiceLocator;
29  import org.kuali.rice.kew.api.doctype.DocumentType;
30  import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
31  import org.kuali.rice.kew.framework.postprocessor.ActionTakenEvent;
32  import org.kuali.rice.kew.framework.postprocessor.DeleteEvent;
33  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
34  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
35  import org.kuali.rice.kew.framework.postprocessor.ProcessDocReport;
36  import org.w3c.dom.Document;
37  
38  import java.rmi.RemoteException;
39  import java.sql.Timestamp;
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.Iterator;
43  import java.util.List;
44  
45  public class EDocLiteDatabasePostProcessor extends EDocLitePostProcessor {
46  
47      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
48              .getLogger(EDocLiteDatabasePostProcessor.class);
49  
50      @Override
51      public ProcessDocReport doRouteStatusChange(DocumentRouteStatusChange event) throws RemoteException {
52          LOG.debug("doRouteStatusChange: " + event);
53          String documentId = event.getDocumentId();
54          super.postEvent(documentId, event, "statusChange");
55          Document doc = getEDLContent(documentId);
56          if (LOG.isDebugEnabled()) {
57              LOG.debug("Submitting doc: " + XmlJotter.jotNode(doc));
58          }
59          extractEDLData(documentId, getNodeNames(event.getDocumentId()), doc);
60          return super.doRouteStatusChange(event);
61      }
62  
63      @Override
64      public ProcessDocReport doActionTaken(ActionTakenEvent event) throws RemoteException {
65          LOG.debug("doActionTaken: " + event);
66          String documentId = event.getDocumentId();
67          super.postEvent(documentId, event, "actionTaken");
68  
69          // if the action requested is a save, go ahead and update the database with the most current information. -grpatter
70          if (KewApiConstants.ACTION_TAKEN_SAVED_CD.equals(event.getActionTaken().getActionTaken())) {
71              Document doc = getEDLContent(documentId);
72              extractEDLData(documentId, getNodeNames(event.getDocumentId()), doc);
73          }
74  
75          return super.doActionTaken(event);
76      }
77  
78      @Override
79      public ProcessDocReport doDeleteRouteHeader(DeleteEvent event) throws RemoteException {
80          LOG.debug("doDeleteRouteHeader: " + event);
81          super.postEvent(event.getDocumentId(), event, "deleteRouteHeader");
82          return super.doDeleteRouteHeader(event);
83      }
84  
85      @Override
86      public ProcessDocReport doRouteLevelChange(DocumentRouteLevelChange event) throws RemoteException {
87          LOG.debug("doRouteLevelChange: " + event);
88          String documentId = event.getDocumentId();
89          super.postEvent(documentId, event, "routeLevelChange");
90          Document doc = getEDLContent(documentId);
91          if (LOG.isDebugEnabled()) {
92              LOG.debug("Submitting doc: " + XmlJotter.jotNode(doc));
93          }
94          extractEDLData(documentId, new String[]{event.getNewNodeName()}, doc);
95          return super.doRouteLevelChange(event);
96      }
97  
98      //	    public static Document getEDLContent(DocumentRouteHeaderValue routeHeader) throws Exception {
99      //	        String content = routeHeader.getDocContent();
100     //	        Document doc =  DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(content)));
101     //	        return doc;
102     //	    }
103 
104     private String[] getNodeNames(String documentId) {
105         List<String> activeNodeInstances = KewApiServiceLocator.getWorkflowDocumentService().getActiveRouteNodeNames(documentId);
106         if (activeNodeInstances == null || activeNodeInstances.isEmpty()) {
107             activeNodeInstances = KewApiServiceLocator.getWorkflowDocumentService().getTerminalRouteNodeNames(documentId);
108         }
109 
110         return activeNodeInstances != null ? activeNodeInstances.toArray(new String[] {}) : new String[] {};
111     }
112 
113     private void extractEDLData(String documentId, String[] nodeNames, Document documentContent) {
114         try {
115             org.kuali.rice.kew.api.document.Document document = KewApiServiceLocator.getWorkflowDocumentService().getDocument(documentId);
116             DocumentType documentType = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeById(
117                     document.getDocumentTypeId());
118             DumpDTO dump = getExtractService().getDumpByDocumentId(documentId);
119             if (dump == null) {
120                 dump = new DumpDTO();
121             }
122             dump.setDocId(documentId);
123             dump.setDocCreationDate(new Timestamp(document.getDateCreated().getMillis()));
124             dump.setDocCurrentNodeName(StringUtils.join(nodeNames, ","));
125             dump.setDocDescription(documentType.getDescription());
126             if (document.getDateLastModified() != null) {
127                 dump.setDocModificationDate(new Timestamp(document.getDateLastModified().getMillis()));
128             }
129             dump.setDocInitiatorId(document.getInitiatorPrincipalId());
130             dump.setDocRouteStatusCode(document.getStatus().getCode());
131             dump.setDocTypeName(documentType.getName());
132 
133             List<FieldDTO> fields = dump.getFields();
134             fields.clear();
135 
136             List fieldElements = setExtractFields(documentContent);
137             for (Iterator iter = fieldElements.iterator(); iter.hasNext();) {
138                 FieldDTO field = new FieldDTO();
139                 field.setDocId(dump.getDocId());
140                 Element element = (Element) iter.next();
141                 Attribute attribute = element.getAttribute("name");
142                 field.setFieldName(attribute.getValue());
143                 field.setFieldValue(element.getChildText("value"));
144                 fields.add(field);
145             }
146             dump.setFields(fields);
147             getExtractService().saveDump(dump);
148         } catch (Exception e) {
149             if (e instanceof RuntimeException) {
150                 throw (RuntimeException) e;
151             }
152             throw new RuntimeException(e);
153         }
154     }
155 
156     private ExtractService getExtractService() {
157         return EdlFrameworkServiceLocator.getExtractService();
158     }
159 
160     private static Element getRootElement(Document docContent) {
161         return XmlHelper.buildJDocument(docContent).getRootElement();
162     }
163 
164     private List setExtractFields(Document documentContent) {
165         Element rootElement = getRootElement(documentContent);
166         List<Element> fields = new ArrayList<Element>();
167         Collection<Element> fieldElements = XmlHelper.findElements(rootElement, "field");
168         Iterator<Element> elementIter = fieldElements.iterator();
169         while (elementIter.hasNext()) {
170             Element field = elementIter.next();
171             Element version = field.getParentElement();
172             if (version.getAttribute("current").getValue().equals("true")) {
173                 if (field.getAttribute("name") != null) {
174                     fields.add(field);
175                 }
176             }
177         }
178         return fields;
179     }
180 
181 }