View Javadoc

1   /**
2    * Copyright 2005-2013 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.kew.engine.node;
17  
18  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
19  
20  import java.util.Iterator;
21  import java.util.List;
22  
23  
24  /**
25   * Logs {@link RouteNodeInstance} graphs in a format which is indented and easy to read. 
26   *
27   * @author Kuali Rice Team (rice.collab@kuali.org)
28   */
29  public class NodeJotter {
30  
31      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NodeJotter.class);
32      private static final String INDENT = "   ";
33  
34      public static void jotNodeInstance(DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) {
35          try {
36              if (LOG.isDebugEnabled()) {
37                  List initialNodeInstances = document.getInitialRouteNodeInstances();
38                  for (Iterator iterator = initialNodeInstances.iterator(); iterator.hasNext();) {
39                      RouteNodeInstance initialNodeInstance = (RouteNodeInstance) iterator.next();
40                      NodeType nodeType = NodeType.fromNodeInstance(initialNodeInstance);
41                      LOG.debug(orchestrateOutput(initialNodeInstance, nodeType, null, 0));
42                  }
43              } else if (LOG.isInfoEnabled()) {
44                  NodeType nodeType = NodeType.fromNodeInstance(nodeInstance);
45                  LOG.info(outputNodeInstanceToLog(nodeInstance, nodeType, 0));
46              }
47          } catch (Throwable t) {
48              LOG.warn("Caught error attempting to jot node instance" + nodeInstance);
49          }
50      }
51  
52      private static String orchestrateOutput(RouteNodeInstance nodeInstance, NodeType nodeType, SplitJoinContext sjCtx, int indentDepth) throws Exception {
53          String output = "";
54          boolean isSplit = NodeType.SPLIT.equals(nodeType);
55          boolean isJoin = NodeType.JOIN.equals(nodeType);
56          if (isJoin && sjCtx != null) {
57              sjCtx.joinNodeInstance = nodeInstance;
58              return output;
59          }
60          SplitJoinContext newSplitJoinContext = null;
61          if (isSplit) {
62              newSplitJoinContext = new SplitJoinContext(nodeInstance);
63          }
64          output += outputNodeInstanceToLog(nodeInstance, nodeType, indentDepth);
65          for (Iterator iterator = nodeInstance.getNextNodeInstances().iterator(); iterator.hasNext();) {
66              RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iterator.next();
67              nodeType = NodeType.fromNodeInstance(nextNodeInstance);
68              if (newSplitJoinContext != null) {
69                  output += orchestrateOutput(nextNodeInstance, nodeType, newSplitJoinContext, indentDepth + 1);
70              } else {
71                  output += orchestrateOutput(nextNodeInstance, nodeType, sjCtx, indentDepth + 1);
72              }
73          }
74          if (isSplit) {
75              if (newSplitJoinContext != null && newSplitJoinContext.joinNodeInstance != null) {
76                  nodeType = NodeType.fromNodeInstance(newSplitJoinContext.joinNodeInstance);
77                  output += orchestrateOutput(newSplitJoinContext.joinNodeInstance, nodeType, sjCtx, indentDepth);
78              }
79          }
80          return output;
81      }
82  
83      private static String outputNodeInstanceToLog(RouteNodeInstance nodeInstance, NodeType nodeType, int indentDepth) throws Exception {
84          String memAddress = nodeInstance.toString().split("@")[1];
85          String dataIndent = getIndent(indentDepth + 1);
86          String output = getIndent(indentDepth) + "[NODE type=" + nodeType.getName() + "]\n" + dataIndent + "Name: " + nodeInstance.getName() + "(" + memAddress + ")\n";
87          output += dataIndent + "State: ";
88          for (Iterator iterator = nodeInstance.getState().iterator(); iterator.hasNext();) {
89              NodeState nodeState = (NodeState) iterator.next();
90              output += nodeState.getKey() + "=" + nodeState.getValue();
91              if (iterator.hasNext()) {
92                  output += ",";
93              }
94          }
95          output += "\n" + dataIndent + "Status Flags: initial=" + nodeInstance.isInitial() + ", active=" + nodeInstance.isActive() + ", complete=" + nodeInstance.isComplete();
96          output += (nodeInstance.getProcess() == null ? "" : "\n" + dataIndent + "ProcessDefinition Name: " + nodeInstance.getProcess().getName());
97          output += "\n";
98          return output;
99      }
100 
101     private static String getIndent(int indentDepth) {
102         StringBuffer buffer = new StringBuffer();
103         for (int depth = 0; depth < indentDepth; depth++) {
104             buffer.append(INDENT);
105         }
106         return buffer.toString();
107     }
108 
109     private static class SplitJoinContext {
110         public RouteNodeInstance splitNodeInstance;
111         public RouteNodeInstance joinNodeInstance;
112 
113         public SplitJoinContext(RouteNodeInstance splitNodeInstance) {
114             this.splitNodeInstance = splitNodeInstance;
115         }
116     }
117 
118 }