001 package org.shiftone.jrat.provider.tree.ui.trace.stack;
002
003
004 import org.shiftone.jrat.core.MethodKey;
005 import org.shiftone.jrat.desktop.util.Table;
006 import org.shiftone.jrat.provider.tree.ui.TraceTreeNode;
007 import org.shiftone.jrat.util.Percent;
008 import org.shiftone.jrat.util.log.Logger;
009
010 import javax.swing.table.AbstractTableModel;
011 import java.util.ArrayList;
012 import java.util.List;
013
014
015 /**
016 * Class StackTableModel
017 *
018 * @author jeff@shiftone.org (Jeff Drost)
019 */
020 public class StackTableModel extends AbstractTableModel {
021
022 private static final Logger LOG = Logger.getLogger(StackTableModel.class);
023 private List stack = new ArrayList();
024 private long rootTotalDuration;
025
026 private static final Table TABLE = new Table(); // enum please?
027 public static final Table.Column PACKAGE = TABLE.column("Package", false);
028 public static final Table.Column CLASS = TABLE.column("Class");
029 public static final Table.Column METHOD = TABLE.column("Method");
030 public static final Table.Column SIGNATURE = TABLE.column("Signature");
031 public static final Table.Column ENTERS = TABLE.column("Enters", false);
032 public static final Table.Column EXITS = TABLE.column("Exits");
033 public static final Table.Column ERRORS = TABLE.column("Errors", false);
034 public static final Table.Column THREADS = TABLE.column("Concurrent Threads", false);
035 public static final Table.Column TOTAL = TABLE.column("Total ms");
036 public static final Table.Column AVERAGE = TABLE.column("Average ms", false);
037 public static final Table.Column TOTAL_METHOD = TABLE.column("Total Method ms");
038 public static final Table.Column AVERAGE_METHOD = TABLE.column("Average Method ms");
039 public static final Table.Column STANDARD_DEVIATION = TABLE.column("Standard Deviation", false);
040 public static final Table.Column MIN = TABLE.column("Min ms", false);
041 public static final Table.Column MAX = TABLE.column("Max ms", false);
042 public static final Table.Column PERCENT_OF_PARENT = TABLE.column("% of Parent");
043 public static final Table.Column PERCENT_OF_ROOT = TABLE.column("% of Root");
044
045
046 public Object getValueAt(int rowIndex, int columnIndex) {
047
048 TraceTreeNode node = (TraceTreeNode) stack.get(rowIndex);
049 MethodKey methodKey = node.getMethodKey();
050
051 if (methodKey == null) {
052 return "?";
053 }
054
055 // yea, an enum would be nice
056
057 if (columnIndex == PACKAGE.getIndex()) {
058 return methodKey.getPackageName();
059 }
060 if (columnIndex == CLASS.getIndex()) {
061 return methodKey.getClassName();
062 }
063 if (columnIndex == METHOD.getIndex()) {
064 return methodKey.getMethodName();
065 }
066 if (columnIndex == SIGNATURE.getIndex()) {
067 return methodKey.getSig().getShortText();
068 }
069
070 if (columnIndex == ENTERS.getIndex()) {
071 return new Long(node.getTotalEnters());
072 }
073 if (columnIndex == EXITS.getIndex()) {
074 return new Long(node.getTotalExits());
075 }
076 if (columnIndex == ERRORS.getIndex()) {
077 return new Long(node.getTotalErrors());
078 }
079
080 if (columnIndex == THREADS.getIndex()) {
081 return new Integer(node.getMaxConcurrentThreads());
082 }
083 if (columnIndex == TOTAL.getIndex()) {
084 return new Long(node.getTotalDuration());
085 }
086 if (columnIndex == AVERAGE.getIndex()) {
087 return node.getAverageDuration();
088 }
089 if (columnIndex == TOTAL_METHOD.getIndex()) {
090 return new Long(node.getTotalMethodDuration());
091 }
092 if (columnIndex == AVERAGE_METHOD.getIndex()) {
093 return node.getAverageMethodDuration();
094 }
095
096 if (columnIndex == STANDARD_DEVIATION.getIndex()) {
097 return node.getStdDeviation();
098 }
099 if (columnIndex == MIN.getIndex()) {
100 return new Long(node.getMinDuration());
101 }
102 if (columnIndex == MAX.getIndex()) {
103 return new Long(node.getMaxDuration());
104 }
105 if (columnIndex == PERCENT_OF_PARENT.getIndex()) {
106 return new Percent(node.getPctOfAvgParentDuration());
107 }
108 if (columnIndex == PERCENT_OF_ROOT.getIndex()) {
109 return new Percent(getPctOfAvgRootDuration(node));
110 }
111
112 return null;
113 }
114
115 public synchronized void setStackTreeNode(TraceTreeNode root, TraceTreeNode node) {
116
117 List newStack = new ArrayList();
118 TraceTreeNode currNode = node;
119
120 while (currNode.getParent() != null) {
121 newStack.add(currNode);
122
123 if (currNode == root) {
124 break;
125 }
126
127 currNode = currNode.getParentNode();
128 }
129
130 // -------------------------------------
131 // I'm calcing the %of root on the fly - which allows any node to be
132 // set as the root node of the view. To do that, I need to know the
133 // total
134 // duration of the effective root. aka the last node on the stack.
135 // this is different from "root" because the that object may be the
136 // fake base node.
137 if (newStack.isEmpty()) {
138 rootTotalDuration = 0;
139 } else {
140 TraceTreeNode viewRoot = (TraceTreeNode) newStack.get(newStack.size() - 1);
141
142 rootTotalDuration = viewRoot.getTotalDuration();
143 }
144
145 stack = newStack;
146
147 fireTableDataChanged();
148 }
149
150
151 public int getRowCount() {
152 return stack.size();
153 }
154
155
156 public static List getColumns() {
157 return TABLE.getColumns();
158 }
159
160 public int getColumnCount() {
161 return TABLE.getColumnCount();
162 }
163
164
165 public String getColumnName(int columnIndex) {
166 return TABLE.getColumn(columnIndex).getName();
167 }
168
169
170 public Class getColumnClass(int columnIndex) {
171 return TABLE.getColumn(columnIndex).getType();
172 }
173
174
175 public boolean isCellEditable(int rowIndex, int columnIndex) {
176 return false;
177 }
178
179
180 public double getPctOfAvgRootDuration(TraceTreeNode node) {
181
182 return (rootTotalDuration > 0)
183 ? ((100.0 * node.getTotalDuration()) / rootTotalDuration)
184 : 0;
185 }
186 }