Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 207 |  | Methods: | 11
| NCLOC: | 174 |  | Classes: | 3
Source file | Conditionals | Statements | Methods | TOTAL
DFAPanel.java | 0% | 0% | 0% | 0% |

1 |  | package net.sourceforge.pmd.util.designer;
2 |  |
3 |  | import net.sourceforge.pmd.ast.ASTMethodDeclaration;
4 |  | import net.sourceforge.pmd.ast.SimpleNode;
5 |  | import net.sourceforge.pmd.dfa.IDataFlowNode;
6 |  | import net.sourceforge.pmd.dfa.variableaccess.VariableAccess;
7 |  | import net.sourceforge.pmd.util.HasLines;
8 |  |
9 |  | import javax.swing.*;
10 |  | import javax.swing.event.ListSelectionEvent;
11 |  | import javax.swing.event.ListSelectionListener;
12 |  | import java.awt.BorderLayout;
13 |  | import java.awt.Canvas;
14 |  | import java.awt.Color;
15 |  | import java.awt.Dimension;
16 |  | import java.awt.Graphics;
17 |  | import java.util.Iterator;
18 |  | import java.util.List;
19 |  |
20 |  | public class DFAPanel extends JComponent implements ListSelectionListener {
21 |  |
22 |  | public static class DFACanvas extends Canvas {
23 |  |
24 |  | private static final int NODE_RADIUS = 10;
25 |  | private static final int NODE_DIAMETER = 2 * NODE_RADIUS;
26 |  |
27 |  | private SimpleNode node;
28 |  |
29 |  | private int x = 150;
30 |  | private int y = 50;
31 |  | private HasLines lines;
32 |  |
33 | 0 | public void paint(Graphics g) {
34 | 0 | super.paint(g);
35 | 0 | if (node == null) {
36 | 0 | return;
37 |  | }
38 | 0 | List flow = node.getDataFlowNode().getFlow();
39 | 0 | for (int i = 0; i < flow.size(); i++) {
40 | 0 | IDataFlowNode inode = (IDataFlowNode) flow.get(i);
41 |  |
42 | 0 | y = computeDrawPos(inode.getIndex());
43 |  |
44 | 0 | g.drawArc(x, y, NODE_DIAMETER, NODE_DIAMETER, 0, 360);
45 | 0 | g.drawString(lines.getLine(inode.getLine()), x + 200, y + 15);
46 |  |
47 |  | // draw index number centered inside of node
48 | 0 | String idx = String.valueOf(inode.getIndex());
49 | 0 | int hack = 4 * (idx.length() / 2); // eo - hack to get one and two digit numbers centered
50 | 0 | g.drawString(idx, x + NODE_RADIUS - 2 - hack, y + NODE_RADIUS + 4);
51 |  |
52 | 0 | List access = inode.getVariableAccess();
53 | 0 | if (access != null) {
54 | 0 | StringBuffer exp = new StringBuffer();
55 | 0 | for (int k = 0; k < access.size(); k++) {
56 | 0 | VariableAccess va = (VariableAccess) access.get(k);
57 | 0 | if (va.isDefinition()) {
58 | 0 | exp.append("d(");
59 | 0 | } else if (va.isReference()) {
60 | 0 | exp.append("r(");
61 | 0 | } else if (va.isUndefinition()) {
62 | 0 | exp.append("u(");
63 |  | //continue; // eo - the u() entries add a lot of clutter to the report
64 |  | } else {
65 | 0 | exp.append("?(");
66 |  | }
67 | 0 | exp.append(va.getVariableName() + "), ");
68 |  | }
69 | 0 | g.drawString(exp.toString(), x + 70, y + 15);
70 |  | }
71 |  |
72 | 0 | for (int j = 0; j < inode.getChildren().size(); j++) {
73 | 0 | IDataFlowNode n = (IDataFlowNode) inode.getChildren().get(j);
74 | 0 | this.drawMyLine(inode.getIndex(), n.getIndex(), g);
75 | 0 | String output = (j == 0 ? "" : ",") + String.valueOf(n.getIndex());
76 | 0 | g.drawString(output, x - 3 * NODE_DIAMETER + (j * 20), y + NODE_RADIUS - 2);
77 |  | }
78 |  | }
79 |  | }
80 |  |
81 | 0 | public void setCode(HasLines h) {
82 | 0 | this.lines = h;
83 |  | }
84 |  |
85 | 0 | public void setMethod(SimpleNode node) {
86 | 0 | this.node = node;
87 |  | }
88 |  |
89 | 0 | private int computeDrawPos(int index) {
90 | 0 | int z = NODE_RADIUS * 4;
91 | 0 | return z + index * z;
92 |  | }
93 |  |
94 | 0 | private void drawMyLine(int index1, int index2, Graphics g) {
95 | 0 | int y1 = this.computeDrawPos(index1);
96 | 0 | int y2 = this.computeDrawPos(index2);
97 |  |
98 | 0 | int arrow = 3;
99 |  |
100 | 0 | if (index1 < index2) {
101 | 0 | if (index2 - index1 == 1) {
102 | 0 | x += NODE_RADIUS;
103 | 0 | g.drawLine(x, y1 + NODE_DIAMETER, x, y2);
104 | 0 | g.fillRect(x - arrow, y2 - arrow, arrow * 2, arrow * 2);
105 | 0 | x -= NODE_RADIUS;
106 | 0 | } else if (index2 - index1 > 1) {
107 | 0 | y1 = y1 + NODE_RADIUS;
108 | 0 | y2 = y2 + NODE_RADIUS;
109 | 0 | int n = ((index2 - index1 - 2) * 10) + 10;
110 | 0 | g.drawLine(x, y1, x - n, y1);
111 | 0 | g.drawLine(x - n, y1, x - n, y2);
112 | 0 | g.drawLine(x - n, y2, x, y2);
113 | 0 | g.fillRect(x - arrow, y2 - arrow, arrow * 2, arrow * 2);
114 |  | }
115 |  |
116 |  | } else {
117 | 0 | if (index1 - index2 > 1) {
118 | 0 | y1 = y1 + NODE_RADIUS;
119 | 0 | y2 = y2 + NODE_RADIUS;
120 | 0 | x = x + NODE_DIAMETER;
121 | 0 | int n = ((index1 - index2 - 2) * 10) + 10;
122 | 0 | g.drawLine(x, y1, x + n, y1);
123 | 0 | g.drawLine(x + n, y1, x + n, y2);
124 | 0 | g.drawLine(x + n, y2, x, y2);
125 | 0 | g.fillRect(x - arrow, y2 - arrow, arrow * 2, arrow * 2);
126 | 0 | x = x - NODE_DIAMETER;
127 | 0 | } else if (index1 - index2 == 1) {
128 | 0 | y2 = y2 + NODE_DIAMETER;
129 | 0 | g.drawLine(x + NODE_RADIUS, y2, x + NODE_RADIUS, y1);
130 | 0 | g.fillRect(x + NODE_RADIUS - arrow, y2 - arrow, arrow * 2, arrow * 2);
131 |  | }
132 |  | }
133 |  | }
134 |  | }
135 |  |
136 |  | private static class ElementWrapper {
137 |  | private ASTMethodDeclaration node;
138 |  |
139 | 0 | public ElementWrapper(ASTMethodDeclaration node) {
140 | 0 | this.node = node;
141 |  | }
142 |  |
143 | 0 | public ASTMethodDeclaration getNode() {
144 | 0 | return node;
145 |  | }
146 |  |
147 | 0 | public String toString() {
148 | 0 | return node.getMethodName();
149 |  | }
150 |  | }
151 |  |
152 |  | private DFACanvas dfaCanvas;
153 |  | private JList nodeList;
154 |  | private DefaultListModel nodes = new DefaultListModel();
155 |  | private JPanel wrapperPanel;
156 |  |
157 | 0 | public DFAPanel() {
158 | 0 | super();
159 |  |
160 | 0 | setLayout(new BorderLayout());
161 | 0 | JPanel leftPanel = new JPanel();
162 | 0 | nodeList = new JList(nodes);
163 | 0 | nodeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
164 | 0 | nodeList.setFixedCellWidth(150);
165 | 0 | nodeList.setBorder(BorderFactory.createLineBorder(Color.black));
166 | 0 | nodeList.addListSelectionListener(this);
167 | 0 | leftPanel.add(nodeList);
168 | 0 | add(leftPanel, BorderLayout.WEST);
169 |  |
170 | 0 | dfaCanvas = new DFACanvas();
171 | 0 | JScrollPane scrollPane = new JScrollPane();
172 | 0 | scrollPane.setPreferredSize(new Dimension(800, 450)); // eo - it would be better to calculate the size based on the containing object's size
173 | 0 | dfaCanvas.setSize(2000, 4000); // eo - these seem to give a big enough canvas
174 | 0 | scrollPane.add(dfaCanvas);
175 | 0 | wrapperPanel = new JPanel();
176 | 0 | wrapperPanel.add(scrollPane);
177 | 0 | wrapperPanel.setBorder(BorderFactory.createLineBorder(Color.black));
178 | 0 | add(wrapperPanel, BorderLayout.EAST);
179 |  | }
180 |  |
181 | 0 | public void valueChanged(ListSelectionEvent event) {
182 | 0 | ElementWrapper wrapper = null;
183 | 0 | if (nodes.size() == 1) {
184 | 0 | wrapper = (ElementWrapper) nodes.get(0);
185 | 0 | } else if (nodes.isEmpty()) {
186 | 0 | return;
187 | 0 | } else if (nodeList.getSelectedValue() == null) {
188 | 0 | wrapper = (ElementWrapper) nodes.get(0);
189 |  | } else {
190 | 0 | wrapper = (ElementWrapper) nodeList.getSelectedValue();
191 |  | }
192 | 0 | dfaCanvas.setMethod(wrapper.getNode());
193 | 0 | dfaCanvas.repaint();
194 |  | }
195 |  |
196 | 0 | public void resetTo(List newNodes, HasLines lines) {
197 | 0 | dfaCanvas.setCode(lines);
198 | 0 | nodes.clear();
199 | 0 | for (Iterator i = newNodes.iterator(); i.hasNext();) {
200 | 0 | nodes.addElement(new ElementWrapper((ASTMethodDeclaration) i.next()));
201 |  | }
202 | 0 | nodeList.setSelectedIndex(0);
203 | 0 | dfaCanvas.setMethod((SimpleNode) newNodes.get(0));
204 | 0 | repaint();
205 |  | }
206 |  | }
207 |  |