View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    * 
4    * 
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * 
9    * http://www.opensource.org/licenses/ecl2.php
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.engine.node;
18  
19  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
20  
21  import java.util.Iterator;
22  import java.util.List;
23  
24  
25  /**
26   * Logs {@link RouteNodeInstance} graphs in a format which is indented and easy to read. 
27   *
28   * @author Kuali Rice Team (rice.collab@kuali.org)
29   */
30  public class NodeJotter {
31  
32      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NodeJotter.class);
33      private static final String INDENT = "   ";
34  
35      public static void jotNodeInstance(DocumentRouteHeaderValue document, RouteNodeInstance nodeInstance) {
36          try {
37              if (LOG.isDebugEnabled()) {
38                  List initialNodeInstances = document.getInitialRouteNodeInstances();
39                  for (Iterator iterator = initialNodeInstances.iterator(); iterator.hasNext();) {
40                      RouteNodeInstance initialNodeInstance = (RouteNodeInstance) iterator.next();
41                      NodeType nodeType = NodeType.fromNodeInstance(initialNodeInstance);
42                      LOG.debug(orchestrateOutput(initialNodeInstance, nodeType, null, 0));
43                  }
44              } else if (LOG.isInfoEnabled()) {
45                  NodeType nodeType = NodeType.fromNodeInstance(nodeInstance);
46                  LOG.info(outputNodeInstanceToLog(nodeInstance, nodeType, 0));
47              }
48          } catch (Throwable t) {
49              LOG.warn("Caught error attempting to jot node instance" + nodeInstance);
50          }
51      }
52  
53      private static String orchestrateOutput(RouteNodeInstance nodeInstance, NodeType nodeType, SplitJoinContext sjCtx, int indentDepth) throws Exception {
54          String output = "";
55          boolean isSplit = NodeType.SPLIT.equals(nodeType);
56          boolean isJoin = NodeType.JOIN.equals(nodeType);
57          if (isJoin && sjCtx != null) {
58              sjCtx.joinNodeInstance = nodeInstance;
59              return output;
60          }
61          SplitJoinContext newSplitJoinContext = null;
62          if (isSplit) {
63              newSplitJoinContext = new SplitJoinContext(nodeInstance);
64          }
65          output += outputNodeInstanceToLog(nodeInstance, nodeType, indentDepth);
66          for (Iterator iterator = nodeInstance.getNextNodeInstances().iterator(); iterator.hasNext();) {
67              RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iterator.next();
68              nodeType = NodeType.fromNodeInstance(nextNodeInstance);
69              if (newSplitJoinContext != null) {
70                  output += orchestrateOutput(nextNodeInstance, nodeType, newSplitJoinContext, indentDepth + 1);
71              } else {
72                  output += orchestrateOutput(nextNodeInstance, nodeType, sjCtx, indentDepth + 1);
73              }
74          }
75          if (isSplit) {
76              if (newSplitJoinContext != null && newSplitJoinContext.joinNodeInstance != null) {
77                  nodeType = NodeType.fromNodeInstance(newSplitJoinContext.joinNodeInstance);
78                  output += orchestrateOutput(newSplitJoinContext.joinNodeInstance, nodeType, sjCtx, indentDepth);
79              }
80          }
81          return output;
82      }
83  
84      private static String outputNodeInstanceToLog(RouteNodeInstance nodeInstance, NodeType nodeType, int indentDepth) throws Exception {
85          String memAddress = nodeInstance.toString().split("@")[1];
86          String dataIndent = getIndent(indentDepth + 1);
87          String output = getIndent(indentDepth) + "[NODE type=" + nodeType.getName() + "]\n" + dataIndent + "Name: " + nodeInstance.getName() + "(" + memAddress + ")\n";
88          output += dataIndent + "State: ";
89          for (Iterator iterator = nodeInstance.getState().iterator(); iterator.hasNext();) {
90              NodeState nodeState = (NodeState) iterator.next();
91              output += nodeState.getKey() + "=" + nodeState.getValue();
92              if (iterator.hasNext()) {
93                  output += ",";
94              }
95          }
96          output += "\n" + dataIndent + "Status Flags: initial=" + nodeInstance.isInitial() + ", active=" + nodeInstance.isActive() + ", complete=" + nodeInstance.isComplete();
97          output += (nodeInstance.getProcess() == null ? "" : "\n" + dataIndent + "ProcessDefinition Name: " + nodeInstance.getProcess().getName());
98          output += "\n";
99          return output;
100     }
101 
102     private static String getIndent(int indentDepth) {
103         StringBuffer buffer = new StringBuffer();
104         for (int depth = 0; depth < indentDepth; depth++) {
105             buffer.append(INDENT);
106         }
107         return buffer.toString();
108     }
109 
110     private static class SplitJoinContext {
111         public RouteNodeInstance splitNodeInstance;
112         public RouteNodeInstance joinNodeInstance;
113 
114         public SplitJoinContext(RouteNodeInstance splitNodeInstance) {
115             this.splitNodeInstance = splitNodeInstance;
116         }
117     }
118 
119 }