Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 230 |  | Methods: | 10
| NCLOC: | 162 |  | Classes: | 2
Source file | Conditionals | Statements | Methods | TOTAL
ReportTree.java | 56.2% | 50% | 30% | 50.7% |

1 |  | package net.sourceforge.pmd.dfa.report;
2 |  |
3 |  | import net.sourceforge.pmd.RuleViolation;
4 |  | import net.sourceforge.pmd.IRuleViolation;
5 |  |
6 |  | import java.lang.reflect.InvocationTargetException;
7 |  | import java.lang.reflect.Method;
8 |  | import java.util.ArrayList;
9 |  | import java.util.Iterator;
10 |  | import java.util.List;
11 |  | import java.util.StringTokenizer;
12 |  |
13 |  | public class ReportTree {
14 |  |
15 |  | private PackageNode rootNode = new PackageNode("");
16 |  | private AbstractReportNode level;
17 |  |
18 |  | private class TreeIterator implements Iterator {
19 |  |
20 |  | private AbstractReportNode iterNode = rootNode;
21 |  | private boolean hasNextFlag;
22 |  |
23 | 0 | public void remove() {
24 | 0 | throw new UnsupportedOperationException();
25 |  | }
26 |  |
27 | 0 | public boolean hasNext() {
28 | 0 | this.hasNextFlag = true;
29 | 0 | return this.getNext() != null;
30 |  | }
31 |  |
32 | 0 | public Object next() {
33 |  |
34 | 0 | if (!this.hasNextFlag) {
35 | 0 | this.getNext();
36 |  | } else {
37 | 0 | this.hasNextFlag = false;
38 |  | }
39 |  |
40 | 0 | if (this.iterNode instanceof ViolationNode) {
41 | 0 | return ((ViolationNode) this.iterNode).getRuleViolation();
42 |  | }
43 | 0 | return null;
44 |  | }
45 |  |
46 |  | /**
47 |  | * It's some kind of left-right-middle search (postorder).
48 |  | * It always returns only
49 |  | * leafs. The first node he returns is the most left handed leaf he can
50 |  | * found. Now he's looking for siblings and if there are any, he starts
51 |  | * searching for the next most left handed leaf. If there are no
52 |  | * siblings he goes up to his parent and starts looking for siblings.
53 |  | * If there are any he starts searching for the next most left handed
54 |  | * leaf again. And so on ... until he wants to get the parent of the
55 |  | * root node. Because there is no one, the search stops.
56 |  | */
57 |  |
58 | 0 | private Object getNext() {
59 | 0 | AbstractReportNode node;
60 |  |
61 | 0 | while (true) {
62 | 0 | if (this.iterNode.isLeaf()) {
63 |  |
64 | 0 | while ((node = (this.iterNode).getNextSibling()) == null) {
65 |  |
66 | 0 | node = this.iterNode.getParent();
67 | 0 | if (node == null) {
68 | 0 | return null;
69 |  | } else {
70 | 0 | this.iterNode = node;
71 |  | }
72 |  | }
73 |  |
74 | 0 | this.iterNode = node;
75 | 0 | if (this.iterNode.isLeaf()) {
76 | 0 | return this.iterNode;
77 |  | } else {
78 | 0 | continue;
79 |  | }
80 |  | } else {
81 | 0 | this.iterNode = this.iterNode.getFirstChild();
82 | 0 | if (this.iterNode.isLeaf()) {
83 | 0 | return this.iterNode;
84 |  | } else {
85 | 0 | continue;
86 |  | }
87 |  | }
88 |  | }
89 |  | }
90 |  | }
91 |  |
92 |  |
93 | 0 | public Iterator iterator() {
94 | 0 | return new TreeIterator();
95 |  | }
96 |  |
97 | 0 | public int size() {
98 | 0 | int count = 0;
99 | 0 | for (Iterator i = iterator(); i.hasNext();) {
100 | 0 | i.next();
101 | 0 | count++;
102 |  | }
103 | 0 | return count;
104 |  | }
105 |  |
106 | 0 | public AbstractReportNode getRootNode() {
107 | 0 | return rootNode;
108 |  | }
109 |  |
110 |  | /**
111 |  | * Adds the RuleViolation to the tree. Splits the package name. Each
112 |  | * package, class and violation gets there own tree node.
113 |  | */
114 | 2660 | public void addRuleViolation(IRuleViolation violation) {
115 | 2660 | String pack = violation.getPackageName();
116 | 2660 | String[] a = {};
117 | 2660 | if (pack == null) {
118 | 0 | a = new String[]{""};
119 | 2660 | } else if (pack.indexOf(".") != -1) {
120 |  | // TODO Remove when minimal runtime support is >= JDK 1.4
121 | 2 | try {
122 | 2 | Method split = String.class.getMethod("split", new Class[]{String.class});
123 | 2 | if (split != null) {
124 |  | // // Compatible with >= JDK 1.4
125 | 2 | Object[] tmp = (Object[]) split.invoke(pack, new Object[]{"\\."});
126 | 2 | a = new String[tmp.length];
127 | 2 | for (int i = 0; i < tmp.length; i++) {
128 | 4 | a[i] = (String) tmp[i];
129 |  | }
130 |  | }
131 |  | } catch (IllegalAccessException e) {
132 | 0 | e.printStackTrace();
133 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
134 |  | } catch (IllegalArgumentException e) {
135 | 0 | e.printStackTrace();
136 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
137 |  | } catch (InvocationTargetException e) {
138 | 0 | e.printStackTrace();
139 | 0 | throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
140 |  | } catch (NoSuchMethodException nsme) {
141 |  | // Compatible with < JDK 1.4
142 | 0 | StringTokenizer toker = new StringTokenizer(pack, ".");
143 | 0 | List parts = new ArrayList();
144 | 0 | while (toker.hasMoreTokens()) {
145 | 0 | parts.add(toker.nextToken());
146 |  | }
147 | 0 | a = (String[]) parts.toArray(new String[parts.size()]);
148 |  | }
149 |  | } else {
150 | 2658 | a = new String[]{pack};
151 |  | }
152 |  |
153 | 2660 | this.level = this.rootNode;
154 | 2660 | String plugedPackageName = "";
155 |  |
156 | 2660 | for (int i = 0; i < a.length; i++) {
157 | 2662 | String packageName = a[i];
158 | 2662 | plugedPackageName += packageName + ".";
159 |  |
160 | 2662 | if (!this.isStringInLevel(plugedPackageName)) {
161 | 543 | PackageNode node = new PackageNode(plugedPackageName);
162 | 543 | this.level.addFirst(node);
163 |  | // gotoLevel
164 | 543 | this.level = node;
165 |  | }
166 |  | }
167 |  |
168 | 2660 | String cl = violation.getClassName();
169 |  |
170 | 2660 | if (!this.isStringInLevel(cl)) {
171 | 549 | ClassNode node = new ClassNode(cl);
172 | 549 | this.level.addFirst(node);
173 |  | // gotoLevel
174 | 549 | this.level = node;
175 |  | }
176 |  |
177 |  | /*
178 |  | * Filters dublicated rule violations. Like the comparator in
179 |  | * RuleViolation if he already exists.
180 |  | */
181 | 2660 | ViolationNode tmp = new ViolationNode(violation);
182 | 2660 | if (!this.equalsNodeInLevel(this.level, tmp)) {
183 | 2651 | this.level.add(tmp);
184 |  | }
185 |  | }
186 |  |
187 |  | /**
188 |  | * Checks if node is a child of the level node.
189 |  | */
190 | 2660 | private boolean equalsNodeInLevel(AbstractReportNode level, AbstractReportNode node) {
191 | 2660 | for (int i = 0; i < level.getChildCount(); i++) {
192 | 41840 | if ((level.getChildAt(i)).equalsNode(node)) {
193 | 9 | return true;
194 |  | }
195 |  | }
196 | 2651 | return false;
197 |  | }
198 |  |
199 |  | /**
200 |  | * Checks if the packageName or the className is a child of the current
201 |  | * (this.level) node. If it's true, the current node changes to the
202 |  | * child node.
203 |  | */
204 | 5322 | private boolean isStringInLevel(String str) {
205 |  |
206 | 5322 | for (int i = 0; i < this.level.getChildCount(); i++) {
207 | 4238 | AbstractReportNode child = this.level.getChildAt(i);
208 | 4238 | String tmp = null;
209 |  |
210 | 4238 | if (child instanceof PackageNode) {
211 | 2119 | tmp = ((PackageNode) child).getPackageName();
212 |  | }
213 | 4238 | if (child instanceof ClassNode) {
214 | 2119 | tmp = ((ClassNode) child).getClassName();
215 |  | }
216 |  |
217 | 4238 | if (tmp == null) {
218 | 0 | return false;
219 |  | }
220 |  |
221 | 4238 | if (tmp.equals(str)) {
222 |  | // goto level
223 | 4230 | this.level = child;
224 | 4230 | return true;
225 |  | }
226 |  | }
227 | 1092 | return false;
228 |  | }
229 |  |
230 |  | }