1 package net.sourceforge.pmd.lang.dfa.report;
2
3 import java.util.Iterator;
4
5 import net.sourceforge.pmd.RuleViolation;
6
7 public class ReportTree {
8
9 private PackageNode rootNode = new PackageNode("");
10 private AbstractReportNode level;
11
12 private class TreeIterator implements Iterator<RuleViolation> {
13
14 private AbstractReportNode iterNode = rootNode;
15 private boolean hasNextFlag;
16
17 public void remove() {
18 throw new UnsupportedOperationException();
19 }
20
21 public boolean hasNext() {
22 hasNextFlag = true;
23 return getNext() != null;
24 }
25
26 public RuleViolation next() {
27 if (!hasNextFlag) {
28 getNext();
29 } else {
30 hasNextFlag = false;
31 }
32
33 if (iterNode instanceof ViolationNode) {
34 return ((ViolationNode) iterNode).getRuleViolation();
35 }
36 return null;
37 }
38
39
40
41
42
43
44
45
46
47
48
49
50 private AbstractReportNode getNext() {
51 AbstractReportNode node;
52
53 while (true) {
54 if (iterNode.isLeaf()) {
55
56 while ((node = iterNode.getNextSibling()) == null) {
57
58 node = iterNode.getParent();
59 if (node == null) {
60 return null;
61 } else {
62 iterNode = node;
63 }
64 }
65
66 iterNode = node;
67 if (iterNode.isLeaf()) {
68 return iterNode;
69 } else {
70 continue;
71 }
72 } else {
73 iterNode = iterNode.getFirstChild();
74 if (iterNode.isLeaf()) {
75 return iterNode;
76 } else {
77 continue;
78 }
79 }
80 }
81 }
82 }
83
84 public Iterator<RuleViolation> iterator() {
85 return new TreeIterator();
86 }
87
88 public int size() {
89 int count = 0;
90 for (Iterator<RuleViolation> i = iterator(); i.hasNext();) {
91 i.next();
92 count++;
93 }
94 return count;
95 }
96
97 public AbstractReportNode getRootNode() {
98 return rootNode;
99 }
100
101
102
103
104
105 public void addRuleViolation(RuleViolation violation) {
106 String packageName = violation.getPackageName();
107 if (packageName == null) {
108 packageName = "";
109 }
110
111 level = rootNode;
112
113 int endIndex = packageName.indexOf('.');
114 while (true) {
115 String parentPackage;
116 if (endIndex < 0) {
117 parentPackage = packageName;
118 } else {
119 parentPackage = packageName.substring(0, endIndex);
120 }
121
122 if (!isStringInLevel(parentPackage)) {
123 PackageNode node = new PackageNode(parentPackage);
124 level.addFirst(node);
125
126 level = node;
127 }
128
129 if (endIndex < 0) {
130 break;
131 }
132 endIndex = packageName.indexOf('.', endIndex + 1);
133 }
134
135 String cl = violation.getClassName();
136
137 if (!isStringInLevel(cl)) {
138 ClassNode node = new ClassNode(cl);
139 level.addFirst(node);
140
141 level = node;
142 }
143
144
145
146
147
148 ViolationNode tmp = new ViolationNode(violation);
149 if (!equalsNodeInLevel(level, tmp)) {
150 level.add(tmp);
151 }
152 }
153
154
155
156
157 private boolean equalsNodeInLevel(AbstractReportNode level,
158 AbstractReportNode node) {
159 for (int i = 0; i < level.getChildCount(); i++) {
160 if (level.getChildAt(i).equalsNode(node)) {
161 return true;
162 }
163 }
164 return false;
165 }
166
167
168
169
170
171
172 private boolean isStringInLevel(String str) {
173
174 for (int i = 0; i < level.getChildCount(); i++) {
175 final AbstractReportNode child = level.getChildAt(i);
176 final String tmp;
177 if (child instanceof PackageNode) {
178 tmp = ((PackageNode) child).getPackageName();
179 } else if (child instanceof ClassNode) {
180 tmp = ((ClassNode) child).getClassName();
181 } else {
182 return false;
183 }
184
185 if (tmp != null && tmp.equals(str)) {
186
187 level = child;
188 return true;
189 }
190 }
191 return false;
192 }
193
194 }