Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 229 |  | Methods: | 10
| NCLOC: | 161 |  | Classes: | 2
Source file | Conditionals | Statements | Methods | TOTAL
ReportTree.java | 56.2% | 51.1% | 40% | 52% |

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