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