KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > dfa > report > ReportTree


1 package net.sourceforge.pmd.dfa.report;
2
3 import net.sourceforge.pmd.IRuleViolation;
4
5 import java.lang.reflect.InvocationTargetException JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.util.ArrayList JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.StringTokenizer JavaDoc;
11
12 public class ReportTree {
13
14     private PackageNode rootNode = new PackageNode("");
15     private AbstractReportNode level;
16
17     private class TreeIterator implements Iterator JavaDoc {
18
19         private AbstractReportNode iterNode = rootNode;
20         private boolean hasNextFlag;
21
22         public void remove() {
23             throw new UnsupportedOperationException JavaDoc();
24         }
25
26         public boolean hasNext() {
27             this.hasNextFlag = true;
28             return this.getNext() != null;
29         }
30
31         public Object JavaDoc next() {
32
33             if (!this.hasNextFlag) {
34                 this.getNext();
35             } else {
36                 this.hasNextFlag = false;
37             }
38
39             if (this.iterNode instanceof ViolationNode) {
40                 return ((ViolationNode) this.iterNode).getRuleViolation();
41             }
42             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         private Object JavaDoc getNext() {
58             AbstractReportNode node;
59
60             while (true) {
61                 if (this.iterNode.isLeaf()) {
62
63                     while ((node = (this.iterNode).getNextSibling()) == null) {
64
65                         node = this.iterNode.getParent();
66                         if (node == null) {
67                             return null;
68                         } else {
69                             this.iterNode = node;
70                         }
71                     }
72
73                     this.iterNode = node;
74                     if (this.iterNode.isLeaf()) {
75                         return this.iterNode;
76                     } else {
77                         continue;
78                     }
79                 } else {
80                     this.iterNode = this.iterNode.getFirstChild();
81                     if (this.iterNode.isLeaf()) {
82                         return this.iterNode;
83                     } else {
84                         continue;
85                     }
86                 }
87             }
88         }
89     }
90
91
92     public Iterator JavaDoc iterator() {
93         return new TreeIterator();
94     }
95
96     public int size() {
97         int count = 0;
98         for (Iterator JavaDoc i = iterator(); i.hasNext();) {
99             i.next();
100             count++;
101         }
102         return count;
103     }
104
105     public AbstractReportNode getRootNode() {
106         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     public void addRuleViolation(IRuleViolation violation) {
114         String JavaDoc pack = violation.getPackageName();
115         String JavaDoc[] a = {};
116         if (pack == null) {
117             a = new String JavaDoc[]{""};
118         } else if (pack.indexOf('.') != -1) {
119             // TODO Remove when minimal runtime support is >= JDK 1.4
120
try {
121                 Method JavaDoc split = String JavaDoc.class.getMethod("split", new Class JavaDoc[]{String JavaDoc.class});
122                 if (split != null) {
123                     // // Compatible with >= JDK 1.4
124
Object JavaDoc[] tmp = (Object JavaDoc[]) split.invoke(pack, new Object JavaDoc[]{"\\."});
125                     a = new String JavaDoc[tmp.length];
126                     for (int i = 0; i < tmp.length; i++) {
127                         a[i] = (String JavaDoc) tmp[i];
128                     }
129                 }
130             } catch (IllegalAccessException JavaDoc e) {
131                 e.printStackTrace();
132                 throw new InternalError JavaDoc("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
133             } catch (IllegalArgumentException JavaDoc e) {
134                 e.printStackTrace();
135                 throw new InternalError JavaDoc("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
136             } catch (InvocationTargetException JavaDoc e) {
137                 e.printStackTrace();
138                 throw new InternalError JavaDoc("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
139             } catch (NoSuchMethodException JavaDoc nsme) {
140                 // Compatible with < JDK 1.4
141
StringTokenizer JavaDoc toker = new StringTokenizer JavaDoc(pack, ".");
142                 List JavaDoc parts = new ArrayList JavaDoc();
143                 while (toker.hasMoreTokens()) {
144                     parts.add(toker.nextToken());
145                 }
146                 a = (String JavaDoc[]) parts.toArray(new String JavaDoc[parts.size()]);
147             }
148         } else {
149             a = new String JavaDoc[]{pack};
150         }
151
152         this.level = this.rootNode;
153         String JavaDoc plugedPackageName = "";
154
155         for (int i = 0; i < a.length; i++) {
156             String JavaDoc packageName = a[i];
157             plugedPackageName += packageName + '.';
158
159             if (!this.isStringInLevel(plugedPackageName)) {
160                 PackageNode node = new PackageNode(plugedPackageName);
161                 this.level.addFirst(node);
162                 // gotoLevel
163
this.level = node;
164             }
165         }
166
167         String JavaDoc cl = violation.getClassName();
168
169         if (!this.isStringInLevel(cl)) {
170             ClassNode node = new ClassNode(cl);
171             this.level.addFirst(node);
172             // gotoLevel
173
this.level = node;
174         }
175
176         /*
177          * Filters dublicated rule violations. Like the comparator in
178          * RuleViolation if he already exists.
179          */

180         ViolationNode tmp = new ViolationNode(violation);
181         if (!this.equalsNodeInLevel(this.level, tmp)) {
182             this.level.add(tmp);
183         }
184     }
185
186     /**
187      * Checks if node is a child of the level node.
188      */

189     private boolean equalsNodeInLevel(AbstractReportNode level, AbstractReportNode node) {
190         for (int i = 0; i < level.getChildCount(); i++) {
191             if ((level.getChildAt(i)).equalsNode(node)) {
192                 return true;
193             }
194         }
195         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     private boolean isStringInLevel(String JavaDoc str) {
204
205         for (int i = 0; i < this.level.getChildCount(); i++) {
206             AbstractReportNode child = this.level.getChildAt(i);
207             String JavaDoc tmp = null;
208
209             if (child instanceof PackageNode) {
210                 tmp = ((PackageNode) child).getPackageName();
211             }
212             if (child instanceof ClassNode) {
213                 tmp = ((ClassNode) child).getClassName();
214             }
215
216             if (tmp == null) {
217                 return false;
218             }
219
220             if (tmp.equals(str)) {
221                 // goto level
222
this.level = child;
223                 return true;
224             }
225         }
226         return false;
227     }
228
229 }
230
Popular Tags