Date | 2007/07/27 |
---|---|
Codebase | 7949 |
Reviews | 14931 |
DPMO | 271 |
Sigma | 4.958 |
Name | Number | Min | Avg | Max | Total |
---|---|---|---|---|---|
Class complexity | 1 | 102.00 | 102.00 | 102.00 | 102.00 |
Code length | 31 | 1.00 | 13.06 | 48.00 | 405.00 |
File length | 1 | 593.00 | 593.00 | 593.00 | 593.00 |
Operation complexity | 30 | 1.00 | 3.70 | 12.00 | 111.00 |
Work order | 1 | 8.62 | 8.62 | 8.62 | 8.62 |
# | Line | Column | Name | Severity | Description |
---|---|---|---|---|---|
1 | 24 | 1 | ER-023 | 3 | Packages should begin with [] |
2 | 108 | 89 | ER-036 | 3 | Line is too long |
3 | 110 | 91 | ER-036 | 3 | Line is too long |
4 | 152 | 94 | ER-036 | 3 | Line is too long |
5 | 154 | 103 | ER-036 | 3 | Line is too long |
6 | 158 | 87 | ER-036 | 3 | Line is too long |
7 | 165 | 84 | ER-036 | 3 | Line is too long |
8 | 170 | 80 | ER-036 | 3 | Line is too long |
9 | 176 | 80 | ER-036 | 3 | Line is too long |
10 | 186 | 102 | ER-036 | 3 | Line is too long |
11 | 191 | 84 | ER-036 | 3 | Line is too long |
12 | 206 | 101 | ER-036 | 3 | Line is too long |
13 | 214 | 118 | ER-036 | 3 | Line is too long |
14 | 219 | 106 | ER-036 | 3 | Line is too long |
15 | 221 | 161 | ER-036 | 3 | Line is too long |
16 | 222 | 90 | ER-036 | 3 | Line is too long |
17 | 227 | 81 | ER-036 | 3 | Line is too long |
18 | 228 | 85 | ER-036 | 3 | Line is too long |
19 | 232 | 80 | ER-036 | 3 | Line is too long |
20 | 240 | 95 | ER-036 | 3 | Line is too long |
21 | 241 | 123 | ER-036 | 3 | Line is too long |
22 | 256 | 86 | ER-036 | 3 | Line is too long |
23 | 262 | 100 | ER-036 | 3 | Line is too long |
24 | 263 | 99 | ER-036 | 3 | Line is too long |
25 | 307 | 100 | ER-036 | 3 | Line is too long |
26 | 308 | 99 | ER-036 | 3 | Line is too long |
27 | 348 | 85 | ER-036 | 3 | Line is too long |
28 | 351 | 84 | ER-036 | 3 | Line is too long |
29 | 354 | 92 | ER-036 | 3 | Line is too long |
30 | 363 | 94 | ER-036 | 3 | Line is too long |
31 | 369 | 85 | ER-036 | 3 | Line is too long |
32 | 374 | 105 | ER-036 | 3 | Line is too long |
33 | 380 | 109 | ER-036 | 3 | Line is too long |
34 | 382 | 125 | ER-036 | 3 | Line is too long |
35 | 388 | 94 | ER-036 | 3 | Line is too long |
36 | 396 | 102 | ER-036 | 3 | Line is too long |
37 | 402 | 83 | ER-036 | 3 | Line is too long |
38 | 417 | 99 | ER-036 | 3 | Line is too long |
39 | 427 | 142 | ER-036 | 3 | Line is too long |
40 | 428 | 89 | ER-036 | 3 | Line is too long |
41 | 429 | 133 | ER-036 | 3 | Line is too long |
42 | 432 | 106 | ER-036 | 3 | Line is too long |
43 | 437 | 94 | ER-036 | 3 | Line is too long |
44 | 439 | 103 | ER-036 | 3 | Line is too long |
45 | 443 | 87 | ER-036 | 3 | Line is too long |
46 | 446 | 84 | ER-036 | 3 | Line is too long |
47 | 449 | 121 | ER-036 | 3 | Line is too long |
48 | 450 | 106 | ER-036 | 3 | Line is too long |
49 | 451 | 154 | ER-036 | 3 | Line is too long |
50 | 452 | 175 | ER-036 | 3 | Line is too long |
51 | 453 | 145 | ER-036 | 3 | Line is too long |
52 | 457 | 88 | ER-036 | 3 | Line is too long |
53 | 458 | 191 | ER-036 | 3 | Line is too long |
54 | 471 | 183 | ER-036 | 3 | Line is too long |
55 | 480 | 186 | ER-036 | 3 | Line is too long |
56 | 488 | 90 | ER-036 | 3 | Line is too long |
57 | 491 | 91 | ER-036 | 3 | Line is too long |
58 | 504 | 86 | ER-036 | 3 | Line is too long |
59 | 509 | 94 | ER-036 | 3 | Line is too long |
60 | 511 | 103 | ER-036 | 3 | Line is too long |
61 | 515 | 87 | ER-036 | 3 | Line is too long |
62 | 518 | 92 | ER-036 | 3 | Line is too long |
63 | 534 | 196 | ER-036 | 3 | Line is too long |
64 | 542 | 214 | ER-036 | 3 | Line is too long |
65 | 551 | 225 | ER-036 | 3 | Line is too long |
66 | 563 | 82 | ER-036 | 3 | Line is too long |
67 | 580 | 82 | ER-036 | 3 | Line is too long |
68 | 581 | 94 | ER-036 | 3 | Line is too long |
69 | 584 | 110 | ER-036 | 3 | Line is too long |
70 | 589 | 87 | ER-036 | 3 | Line is too long |
71 | 71 | 1 | ER-011 | 1 | Cyclomatic complexity (102) exceeds 100 |
72 | 71 | 1 | ER-049 | 2 | Unify logging strategy - define individual logger for class |
73 | 74 | 30 | ER-030 | 3 | Avoid hardwired string literals |
74 | 77 | 5 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
75 | 77 | 5 | ER-109 | 3 | It is good practice to call in any case super() in a constructor. (see also: UnnecessaryConstructorRule ) |
76 | 85 | 24 | ER-082 | 3 | Avoid using method parameter names that conflict with class member names |
77 | 92 | 25 | ER-030 | 3 | Avoid hardwired string literals |
78 | 93 | 25 | ER-030 | 3 | Avoid hardwired string literals |
79 | 94 | 25 | ER-030 | 3 | Avoid hardwired string literals |
80 | 95 | 25 | ER-030 | 3 | Avoid hardwired string literals |
81 | 96 | 25 | ER-030 | 3 | Avoid hardwired string literals |
82 | 97 | 25 | ER-030 | 3 | Avoid hardwired string literals |
83 | 98 | 25 | ER-030 | 3 | Avoid hardwired string literals |
84 | 99 | 25 | ER-030 | 3 | Avoid hardwired string literals |
85 | 100 | 25 | ER-030 | 3 | Avoid hardwired string literals |
86 | 103 | 5 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
87 | 105 | 42 | ER-030 | 3 | Avoid hardwired string literals |
88 | 110 | 42 | ER-030 | 3 | Avoid hardwired string literals |
89 | 129 | 34 | ER-082 | 3 | Avoid using method parameter names that conflict with class member names |
90 | 137 | 30 | ER-082 | 3 | Avoid using method parameter names that conflict with class member names |
91 | 147 | 31 | ER-082 | 3 | Avoid using method parameter names that conflict with class member names |
92 | 154 | 42 | ER-030 | 3 | Avoid hardwired string literals |
93 | 158 | 42 | ER-030 | 3 | Avoid hardwired string literals |
94 | 167 | 59 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
95 | 167 | 55 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
96 | 167 | 16 | ER-030 | 3 | Avoid hardwired string literals |
97 | 167 | 46 | ER-028 | 3 | Avoid hardwired character literals |
98 | 167 | 51 | ER-028 | 3 | Avoid hardwired character literals |
99 | 167 | 56 | ER-028 | 3 | Avoid hardwired character literals |
100 | 174 | 5 | ER-005 | 3 | Classes, interfaces, methods, and variables should be named according to Sun's naming conventions. |
101 | 176 | 5 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
102 | 178 | 42 | ER-030 | 3 | Avoid hardwired string literals |
103 | 186 | 54 | ER-030 | 3 | Avoid hardwired string literals |
104 | 194 | 17 | ER-028 | 3 | Avoid hardwired character literals |
105 | 199 | 54 | ER-030 | 3 | Avoid hardwired string literals |
106 | 201 | 35 | ER-030 | 3 | Avoid hardwired string literals |
107 | 219 | 62 | ER-082 | 3 | Avoid using method parameter names that conflict with class member names |
108 | 219 | 33 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
109 | 221 | 105 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
110 | 221 | 102 | ER-030 | 3 | Avoid hardwired string literals |
111 | 223 | 57 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
112 | 227 | 57 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
113 | 231 | 43 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
114 | 236 | 33 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
115 | 240 | 80 | ER-047 | 2 | Operation (method or constructor) declares subclasses of RuntimeException in throws clause |
116 | 240 | 33 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
117 | 249 | 33 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
118 | 262 | 33 | ER-210 | 3 | StringTokenizer is deprecated, use String.split() instead. |
119 | 263 | 33 | ER-210 | 3 | StringTokenizer is deprecated, use String.split() instead. |
120 | 264 | 50 | ER-030 | 3 | Avoid hardwired string literals |
121 | 270 | 35 | ER-030 | 3 | Avoid hardwired string literals |
122 | 272 | 37 | ER-030 | 3 | Avoid hardwired string literals |
123 | 278 | 31 | ER-030 | 3 | Avoid hardwired string literals |
124 | 284 | 33 | ER-030 | 3 | Avoid hardwired string literals |
125 | 287 | 33 | ER-210 | 3 | StringTokenizer is deprecated, use String.split() instead. |
126 | 287 | 66 | ER-030 | 3 | Avoid hardwired string literals |
127 | 289 | 31 | ER-030 | 3 | Avoid hardwired string literals |
128 | 291 | 33 | ER-030 | 3 | Avoid hardwired string literals |
129 | 296 | 11 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
130 | 307 | 33 | ER-210 | 3 | StringTokenizer is deprecated, use String.split() instead. |
131 | 308 | 33 | ER-210 | 3 | StringTokenizer is deprecated, use String.split() instead. |
132 | 315 | 35 | ER-030 | 3 | Avoid hardwired string literals |
133 | 317 | 37 | ER-030 | 3 | Avoid hardwired string literals |
134 | 323 | 31 | ER-030 | 3 | Avoid hardwired string literals |
135 | 329 | 33 | ER-030 | 3 | Avoid hardwired string literals |
136 | 334 | 11 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
137 | 348 | 50 | ER-030 | 3 | Avoid hardwired string literals |
138 | 354 | 88 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
139 | 354 | 58 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
140 | 354 | 55 | ER-028 | 3 | Avoid hardwired character literals |
141 | 354 | 79 | ER-028 | 3 | Avoid hardwired character literals |
142 | 354 | 84 | ER-028 | 3 | Avoid hardwired character literals |
143 | 354 | 89 | ER-030 | 3 | Avoid hardwired string literals |
144 | 369 | 50 | ER-030 | 3 | Avoid hardwired string literals |
145 | 374 | 101 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
146 | 374 | 58 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
147 | 374 | 55 | ER-028 | 3 | Avoid hardwired character literals |
148 | 374 | 92 | ER-028 | 3 | Avoid hardwired character literals |
149 | 374 | 97 | ER-028 | 3 | Avoid hardwired character literals |
150 | 374 | 102 | ER-028 | 3 | Avoid hardwired character literals |
151 | 377 | 29 | ER-030 | 3 | Avoid hardwired string literals |
152 | 388 | 46 | ER-030 | 3 | Avoid hardwired string literals |
153 | 396 | 87 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
154 | 396 | 46 | ER-030 | 3 | Avoid hardwired string literals |
155 | 396 | 88 | ER-030 | 3 | Avoid hardwired string literals |
156 | 401 | 19 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
157 | 402 | 54 | ER-030 | 3 | Avoid hardwired string literals |
158 | 406 | 35 | ER-030 | 3 | Avoid hardwired string literals |
159 | 410 | 35 | ER-030 | 3 | Avoid hardwired string literals |
160 | 419 | 11 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
161 | 421 | 11 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
162 | 424 | 25 | ER-030 | 3 | Avoid hardwired string literals |
163 | 428 | 31 | ER-030 | 3 | Avoid hardwired string literals |
164 | 429 | 76 | ER-030 | 3 | Avoid hardwired string literals |
165 | 432 | 5 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
166 | 434 | 42 | ER-030 | 3 | Avoid hardwired string literals |
167 | 439 | 42 | ER-030 | 3 | Avoid hardwired string literals |
168 | 443 | 42 | ER-030 | 3 | Avoid hardwired string literals |
169 | 446 | 72 | ER-030 | 3 | Avoid hardwired string literals |
170 | 447 | 45 | ER-030 | 3 | Avoid hardwired string literals |
171 | 450 | 64 | ER-030 | 3 | Avoid hardwired string literals |
172 | 451 | 67 | ER-030 | 3 | Avoid hardwired string literals |
173 | 451 | 81 | ER-030 | 3 | Avoid hardwired string literals |
174 | 451 | 131 | ER-030 | 3 | Avoid hardwired string literals |
175 | 452 | 67 | ER-030 | 3 | Avoid hardwired string literals |
176 | 452 | 88 | ER-030 | 3 | Avoid hardwired string literals |
177 | 452 | 145 | ER-030 | 3 | Avoid hardwired string literals |
178 | 453 | 75 | ER-030 | 3 | Avoid hardwired string literals |
179 | 453 | 121 | ER-030 | 3 | Avoid hardwired string literals |
180 | 458 | 87 | ER-030 | 3 | Avoid hardwired string literals |
181 | 458 | 178 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
182 | 458 | 140 | ER-030 | 3 | Avoid hardwired string literals |
183 | 461 | 13 | ER-030 | 3 | Avoid hardwired string literals |
184 | 471 | 93 | ER-030 | 3 | Avoid hardwired string literals |
185 | 471 | 114 | ER-030 | 3 | Avoid hardwired string literals |
186 | 471 | 171 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
187 | 471 | 148 | ER-030 | 3 | Avoid hardwired string literals |
188 | 480 | 88 | ER-030 | 3 | Avoid hardwired string literals |
189 | 480 | 106 | ER-030 | 3 | Avoid hardwired string literals |
190 | 480 | 174 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
191 | 480 | 140 | ER-030 | 3 | Avoid hardwired string literals |
192 | 487 | 33 | ER-029 | 3 | Avoid hardwired numeric literals |
193 | 488 | 75 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
194 | 488 | 33 | ER-030 | 3 | Avoid hardwired string literals |
195 | 488 | 66 | ER-028 | 3 | Avoid hardwired character literals |
196 | 488 | 71 | ER-028 | 3 | Avoid hardwired character literals |
197 | 488 | 76 | ER-030 | 3 | Avoid hardwired string literals |
198 | 491 | 76 | ER-030 | 3 | Avoid hardwired string literals |
199 | 499 | 11 | ER-103 | 2 | Catch-blocks should log the exeption with Log4J.error("Context String" , exception ) |
200 | 500 | 42 | ER-030 | 3 | Avoid hardwired string literals |
201 | 504 | 5 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
202 | 506 | 42 | ER-030 | 3 | Avoid hardwired string literals |
203 | 511 | 42 | ER-030 | 3 | Avoid hardwired string literals |
204 | 515 | 42 | ER-030 | 3 | Avoid hardwired string literals |
205 | 518 | 80 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
206 | 518 | 28 | ER-030 | 3 | Avoid hardwired string literals |
207 | 518 | 71 | ER-028 | 3 | Avoid hardwired character literals |
208 | 518 | 76 | ER-028 | 3 | Avoid hardwired character literals |
209 | 518 | 81 | ER-030 | 3 | Avoid hardwired string literals |
210 | 522 | 17 | ER-028 | 3 | Avoid hardwired character literals |
211 | 529 | 35 | ER-030 | 3 | Avoid hardwired string literals |
212 | 534 | 88 | ER-030 | 3 | Avoid hardwired string literals |
213 | 534 | 107 | ER-030 | 3 | Avoid hardwired string literals |
214 | 542 | 93 | ER-030 | 3 | Avoid hardwired string literals |
215 | 542 | 140 | ER-030 | 3 | Avoid hardwired string literals |
216 | 542 | 202 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
217 | 542 | 189 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
218 | 542 | 186 | ER-030 | 3 | Avoid hardwired string literals |
219 | 551 | 88 | ER-030 | 3 | Avoid hardwired string literals |
220 | 551 | 132 | ER-030 | 3 | Avoid hardwired string literals |
221 | 551 | 213 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
222 | 551 | 196 | ER-116 | 3 | Use StringBuffer for excessive String concatenation |
223 | 551 | 178 | ER-030 | 3 | Avoid hardwired string literals |
224 | 580 | 9 | ER-105 | 3 | Document all Interfaces and public methods. Use a Class header. Provide Javadoc |
225 | 584 | 46 | ER-030 | 3 | Avoid hardwired string literals |
226 | 589 | 42 | ER-030 | 3 | Avoid hardwired string literals |
1/*
2 * Hammurapi
3 * Automated Java code review system.
4 * Copyright (C) 2004 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.org
21 * e-Mail: support@hammurapi.biz
22 */
23
24package org.hammurapi;
25
26import java.io.File;
27import java.io.FileInputStream;
28import java.io.FileNotFoundException;
29import java.io.FileOutputStream;
30import java.io.IOException;
31import java.io.InputStream;
32import java.util.HashMap;
33import java.util.Iterator;
34import java.util.Map;
35import java.util.StringTokenizer;
36
37import org.apache.tools.ant.BuildException;
38import org.apache.tools.ant.Project;
39import org.apache.tools.ant.util.FileUtils;
40import org.hammurapi.render.dom.CompositeResultsRenderer;
41import org.hammurapi.render.dom.HammurapiMetricRenderer;
42import org.hammurapi.render.dom.InspectorDescriptorRenderer;
43import org.hammurapi.render.dom.InspectorSetRenderer;
44import org.hammurapi.render.dom.InspectorSummaryRenderer;
45import org.hammurapi.render.dom.ReportRenderer;
46import org.hammurapi.render.dom.ReviewResultsRenderer;
47import org.hammurapi.results.AggregatedResults;
48import org.hammurapi.results.Annotation;
49import org.hammurapi.results.AnnotationConfig;
50import org.hammurapi.results.AnnotationContext;
51import org.hammurapi.results.CompositeResults;
52import org.hammurapi.results.InspectorSummary;
53import org.hammurapi.results.ReportMixer;
54import org.hammurapi.results.ReviewResults;
55
56import com.pavelvlasov.config.ConfigurationException;
57import com.pavelvlasov.metrics.MeasurementCategoryFactory;
58import com.pavelvlasov.metrics.Metric;
59import com.pavelvlasov.metrics.TimeIntervalCategory;
60import com.pavelvlasov.render.RenderRequest;
61import com.pavelvlasov.render.RenderingException;
62import com.pavelvlasov.render.dom.AbstractRenderer;
63
64/**
65 * Outputs review results to XML or HTML.
66 * @ant.element parent="hammurapi" name="output" display-name="Output subelement"
67 * @ant.non-required
68 * @author Pavel Vlasov
69 * @version $Revision: 1.12 $
70 */
71public class Output implements Listener /*, ReviewUnitFilter*/ {
72 private String dir;
73 private boolean embeddedStyle=true;
74 private String extension=".html";
75 private TaskBase task;
76
77 public Output(TaskBase task) {
78 this.task=task;
79 }
80
81 /**
82 * Output directory
83 * @ant.required
84 */
85 public void setDir(String dir) {
86 this.dir=dir;
87 }
88
89 private Map styleSheets=new HashMap();
90
91 {
92 styleSheets.put("compilation-unit", new StyleSheetEntry());
93 styleSheets.put("summary", new StyleSheetEntry());
94 styleSheets.put("left-panel", new StyleSheetEntry());
95 styleSheets.put("waived-violations", new StyleSheetEntry());
96 styleSheets.put("package", new StyleSheetEntry());
97 styleSheets.put("inspector-set", new StyleSheetEntry());
98 styleSheets.put("inspector-descriptor", new StyleSheetEntry());
99 styleSheets.put("inspector-summary", new StyleSheetEntry());
100 styleSheets.put("metric-details", new StyleSheetEntry());
101 }
102
103 public void addConfiguredStyleSheet(StyleSheetEntry styleSheet) {
104 if (styleSheet.getName()==null) {
105 throw new BuildException("Unnamed stylesheet");
106 }
107
108 StyleSheetEntry existing=(StyleSheetEntry) styleSheets.get(styleSheet.getName());
109 if (existing==null) {
110 throw new BuildException("Invalid stylesheet name: "+styleSheet.getName());
111 }
112
113 if (styleSheet.getFile()!=null) {
114 existing.setFile(styleSheet.getFile());
115 }
116
117 if (styleSheet.getUrl()!=null) {
118 existing.setUrl(styleSheet.getUrl());
119 }
120
121 existing.setParameters(styleSheet.getParameters());
122 }
123
124 /**
125 * Use embedded stylesheets if no stylesheets has been set explicitly.
126 * Default is true.
127 * @ant.non-required
128 */
129 public void setEmbeddedStyle(boolean embeddedStyle) {
130 this.embeddedStyle=embeddedStyle;
131 }
132
133 /**
134 * Extension for output files. Defaults to ".html"
135 * @ant.non-required
136 */
137 public void setExtension(String extension) {
138 this.extension=extension;
139 }
140
141 private File javaDocDir;
142
143 /**
144 * JavaDoc directory to generate links.
145 * @ant.non-required
146 */
147 public void setJavaDocDir(File javaDocDir) {
148 this.javaDocDir=javaDocDir;
149 }
150
151 private File getOutDir() throws HammurapiException {
152 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
153 if (!outDir.exists()) {
154 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
155 }
156
157 if (!outDir.isDirectory()) {
158 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
159 }
160
161 return outDir;
162 }
163
164 private String getFileName(ReviewResults reviewResult) {
165 String packageName=reviewResult.getCompilationUnit().getPackage().getName();
166 String unitName=reviewResult.getName();
167 return "source/"+packageName.replace('.', '/')+'/'+unitName;
168 }
169
170 private File getFile(ReviewResults reviewResult) throws HammurapiException {
171 return new File(getOutDir(), getFileName(reviewResult)+extension);
172 }
173
174 private static final Object mkDirSynchronizationMonitor=new Object();
175
176 public void onReview(ReviewResults reviewResult) throws HammurapiException {
177 if (dir==null) {
178 throw new HammurapiException("dir attribute is mandatory");
179 }
180
181 final File outFile=getFile(reviewResult);
182 final File outFileParent=outFile.getParentFile();
183 synchronized (mkDirSynchronizationMonitor) {
184 if (!outFileParent.exists()) {
185 if (!outFileParent.mkdirs()) {
186 throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath());
187 }
188 }
189 }
190
191 String packageName=reviewResult.getCompilationUnit().getPackage().getName();
192 int count=0;
193 for (int i=0; i<packageName.length(); i++) {
194 if ('.'==packageName.charAt(i)) {
195 count++;
196 }
197 }
198
199 StringBuffer inspectorsPath=new StringBuffer("../");
200 while (count-->=0) {
201 inspectorsPath.append("../");
202 }
203
204 renderAnnotations(reviewResult, outFile);
205
206 writeUnitDoc(reviewResult, outFile, inspectorsPath.toString(), getJavaDocPath(reviewResult));
207 }
208
209 /**
210 * @param reviewResult
211 * @param outFile
212 * @throws HammurapiException
213 */
214 private void renderAnnotations(AggregatedResults reviewResult, final File outFile) throws HammurapiException {
215 Iterator ait=reviewResult.getAnnotations().iterator();
216 while (ait.hasNext()) {
217 final Annotation annotation=(Annotation) ait.next();
218 annotation.render(new AnnotationContext() {
219 public FileEntry getNextFile(String extension) throws HammurapiException {
220 try {
221 final File ret=File.createTempFile(outFile.getName()+"_"+annotation.getName(),extension,outFile.getParentFile());
222 return new AnnotationContext.FileEntry() {
223 public File getFile() {
224 return ret;
225 }
226
227 public String getPath() {
228 return ret.getName();
229 }
230 };
231 } catch (IOException e) {
232 throw new HammurapiException(e);
233 }
234 }
235
236 public String getExtension() {
237 return Output.this.getExtension();
238 }
239
240 public Object getParameter(String name) throws BuildException {
241 AnnotationConfig ac=(AnnotationConfig) annotationConfigs.get(annotation.getName());
242 if (ac==null) {
243 return null;
244 }
245
246 return ac.getParameter(name);
247 }
248
249 public boolean isEmbeddedStyle() {
250 return Output.this.isEmbeddedStyle();
251 }
252 });
253 }
254 }
255
256 private String getRelativePath(String packageName) throws HammurapiException {
257 if (javaDocDir==null) {
258 return null;
259 }
260
261 try {
262 StringTokenizer ost=new StringTokenizer(getOutDir().getCanonicalPath(), File.separator);
263 StringTokenizer jst=new StringTokenizer(javaDocDir.getCanonicalPath(), File.separator);
264 StringBuffer upPath=new StringBuffer("../");
265 StringBuffer downPath=new StringBuffer();
266 while (ost.hasMoreTokens() && jst.hasMoreTokens()) {
267 String ot=ost.nextToken();
268 String jt=jst.nextToken();
269 if (!ot.equals(jt)) {
270 upPath.append("../");
271 downPath.append(jt);
272 downPath.append("/");
273 break;
274 }
275 }
276
277 while (ost.hasMoreTokens()) {
278 upPath.append("../");
279 ost.nextToken();
280 }
281
282 while (jst.hasMoreTokens()) {
283 downPath.append(jst.nextToken());
284 downPath.append("/");
285 }
286
287 StringTokenizer pst=new StringTokenizer(packageName, ".");
288 while (pst.hasMoreTokens()) {
289 upPath.append("../");
290 downPath.append(pst.nextToken());
291 downPath.append("/");
292 }
293
294 upPath.append(downPath);
295 return upPath.toString();
296 } catch (IOException e) {
297 return null;
298 }
299 }
300
301 private String getRelativePath() throws HammurapiException {
302 if (javaDocDir==null) {
303 return null;
304 }
305
306 try {
307 StringTokenizer ost=new StringTokenizer(getOutDir().getCanonicalPath(), File.separator);
308 StringTokenizer jst=new StringTokenizer(javaDocDir.getCanonicalPath(), File.separator);
309 StringBuffer upPath=new StringBuffer();
310 StringBuffer downPath=new StringBuffer();
311 while (ost.hasMoreTokens() && jst.hasMoreTokens()) {
312 String ot=ost.nextToken();
313 String jt=jst.nextToken();
314 if (!ot.equals(jt)) {
315 upPath.append("../");
316 downPath.append(jt);
317 downPath.append("/");
318 break;
319 }
320 }
321
322 while (ost.hasMoreTokens()) {
323 upPath.append("../");
324 ost.nextToken();
325 }
326
327 while (jst.hasMoreTokens()) {
328 downPath.append(jst.nextToken());
329 downPath.append("/");
330 }
331
332 upPath.append(downPath);
333 return upPath.toString();
334 } catch (IOException e) {
335 return null;
336 }
337 }
338
339 /**
340 * @pag:todo Should calculate relative path to JavaDoc dir.
341 */
342 private String getJavaDocPath(ReviewResults ru) throws HammurapiException {
343 if (javaDocDir==null) {
344 return null;
345 }
346
347 if (!javaDocDir.exists()) {
348 throw new HammurapiException("JavaDoc directory does not exist");
349 }
350
351 String packageName = ru.getCompilationUnit().getPackage().getName();
352 String path=getRelativePath(packageName);
353 if (path==null) {
354 path=javaDocDir.getAbsolutePath()+'/'+packageName.replace('.', '/')+"/";
355 }
356
357 return path;
358 }
359
360 /**
361 * @pag:todo Should calculate relative path to JavaDoc dir.
362 */
363 private String getJavaDocPath(CompositeResults packageResults) throws HammurapiException {
364 if (javaDocDir==null) {
365 return null;
366 }
367
368 if (!javaDocDir.exists()) {
369 throw new HammurapiException("JavaDoc directory does not exist");
370 }
371
372 String path=getRelativePath(packageResults.getName());
373 if (path==null) {
374 path=javaDocDir.getAbsolutePath()+'/'+packageResults.getName().replace('.', '/')+'/';
375 }
376
377 return path+"package-summary.html";
378 }
379
380 private static TimeIntervalCategory tic=MeasurementCategoryFactory.getTimeIntervalCategory(Output.class);
381
382 private void render(AbstractRenderer renderer, String styleName, String inspectorsPath, String javaDocPath, File outFile)
383 throws HammurapiException {
384 long start=tic.getTime();
385 File outFileParent=outFile.getParentFile();
386 if (!outFileParent.exists()) {
387 if (!outFileParent.mkdirs()) {
388 throw new HammurapiException("Can't create "+outFileParent.getAbsolutePath());
389 }
390 }
391
392 renderer.setEmbeddedStyle(embeddedStyle);
393
394 StyleSheetEntry sse=(StyleSheetEntry) styleSheets.get(styleName);
395 if (sse==null) {
396 throw new HammurapiException("Stylesheet entry with name '"+styleName +"' not found");
397 }
398
399 try {
400 sse.setParameters(task.getProject(), renderer);
401 } catch (ConfigurationException ce) {
402 throw new HammurapiException("setParameters() failed", ce);
403 }
404
405 if (inspectorsPath!=null) {
406 renderer.setParameter("inspectorsPath", inspectorsPath);
407 }
408
409 if (javaDocPath!=null) {
410 renderer.setParameter("javaDocPath", javaDocPath);
411 }
412
413 try {
414 if (sse.getFile()==null) {
415 renderer.render(new FileOutputStream(outFile));
416 } else {
417 renderer.render(new FileInputStream(sse.getFile()), new FileOutputStream(outFile));
418 }
419 } catch (FileNotFoundException e) {
420 throw new HammurapiException(e.toString(), e);
421 } catch (RenderingException e) {
422 throw new HammurapiException(e.toString(), e);
423 }
424 tic.addInterval("render", start);
425 }
426
427 private void writeUnitDoc(ReviewResults reviewResult, File outFile, String inspectorsPath, String javaDocPath) throws HammurapiException {
428 task.getProject().log("Writing "+outFile.getAbsolutePath(), Project.MSG_VERBOSE);
429 render(new ReviewResultsRenderer(new RenderRequest(reviewResult)), "compilation-unit", inspectorsPath, javaDocPath, outFile);
430 }
431
432 public void onSummary(CompositeResults summary, InspectorSet inspectorSet) throws HammurapiException {
433 if (dir==null) {
434 throw new HammurapiException("dir attribute is mandatory");
435 }
436
437 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
438 if (!outDir.exists()) {
439 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
440 }
441
442 if (!outDir.isDirectory()) {
443 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
444 }
445
446 String javaDocPath=javaDocDir==null ? null : getRelativePath()+"index.html";
447 File summaryFile = new File(outDir, "summary"+extension);
448 renderAnnotations(summary, summaryFile);
449 RenderRequest summaryRenderRequest = new RenderRequest(ReportMixer.mix(summary, task.reviewDescription));
450 render(new ReportRenderer(summaryRenderRequest, null), "summary", null, javaDocPath, summaryFile);
451 render(new CompositeResultsRenderer(summaryRenderRequest, "leftPanel"), "left-panel", null, javaDocPath, new File(outDir, "leftPanel"+extension));
452 render(new CompositeResultsRenderer(summaryRenderRequest, "waivedViolations"), "waived-violations", null, javaDocPath, new File(outDir, "waivedViolations"+extension));
453 render(new InspectorSetRenderer(new RenderRequest(inspectorSet)), "inspector-set", null, null, new File(outDir, "inspectors"+extension));
454
455 Iterator descriptors=inspectorSet.getDescriptors().iterator();
456 while (descriptors.hasNext()) {
457 InspectorDescriptor d =(InspectorDescriptor) descriptors.next();
458 render(new InspectorDescriptorRenderer(new RenderRequest(d)), "inspector-descriptor", null, null, new File(outDir, "inspectors/inspector_" + d.getName() + extension));
459 }
460
461 if (".HTML".equalsIgnoreCase(extension)) {
462 writeFrame(outDir);
463 }
464
465 Iterator it=summary.getSeveritySummary().values().iterator();
466 while (it.hasNext()) {
467 Iterator iit=((Map) it.next()).values().iterator();
468 while (iit.hasNext()) {
469 InspectorSummary is=(InspectorSummary) iit.next();
470 if (is.getLocations()!=null) {
471 render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", "source/", null, new File(outDir, "summary_"+is.getName()+extension));
472 }
473 }
474 }
475
476 it=summary.getMetrics().values().iterator();
477 while (it.hasNext()) {
478 Metric metric = (Metric) it.next();
479 if (metric.getMeasurements()!=null) {
480 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", "source/", null, new File(outDir, "metric_details_"+metric.getName()+extension));
481 }
482 }
483 }
484
485 private void writeFrame(File outDir) throws HammurapiException {
486 try {
487 byte[] buf=new byte[4096];
488 String resourceName="/"+getClass().getName().replace('.', '/')+"!report.html";
489 InputStream in=getClass().getResourceAsStream(resourceName);
490 if (in!=null) {
491 FileOutputStream out=new FileOutputStream(new File(outDir, "report.html"));
492 int l;
493 while ((l=in.read(buf))!=-1) {
494 out.write(buf,0,l);
495 }
496 out.close();
497 in.close();
498 }
499 } catch (IOException e) {
500 throw new HammurapiException("Can't write report.html: "+e);
501 }
502 }
503
504 public void onPackage(CompositeResults packageResults) throws HammurapiException {
505 if (dir==null) {
506 throw new HammurapiException("dir attribute is mandatory");
507 }
508
509 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
510 if (!outDir.exists()) {
511 throw new HammurapiException("Output directory does not exist: "+outDir.getAbsolutePath());
512 }
513
514 if (!outDir.isDirectory()) {
515 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
516 }
517
518 String summaryPath="source/"+packageResults.getName().replace('.', '/')+"/.summary";
519
520 int count=0;
521 for (int i=0; i<summaryPath.length(); i++) {
522 if ('/'==summaryPath.charAt(i)) {
523 count++;
524 }
525 }
526
527 StringBuffer inspectorsPath=new StringBuffer();
528 while (count-- > 0) {
529 inspectorsPath.append("../");
530 }
531
532 File packageSummaryFile = new File(outDir, summaryPath+extension);
533 renderAnnotations(packageResults, packageSummaryFile);
534 render(new CompositeResultsRenderer(new RenderRequest(packageResults), "packageSummary"), "package", inspectorsPath.toString(), getJavaDocPath(packageResults), packageSummaryFile);
535
536 Iterator it=packageResults.getSeveritySummary().values().iterator();
537 while (it.hasNext()) {
538 Iterator iit=((Map) it.next()).values().iterator();
539 while (iit.hasNext()) {
540 InspectorSummary is=(InspectorSummary) iit.next();
541 if (is.getLocations()!=null) {
542 render(new InspectorSummaryRenderer(new RenderRequest(is)), "inspector-summary", inspectorsPath.toString()+"source/", null, new File(outDir, summaryPath+"_"+is.getName()+extension));
543 }
544 }
545 }
546
547 it=packageResults.getMetrics().values().iterator();
548 while (it.hasNext()) {
549 Metric metric = (Metric) it.next();
550 if (metric.getMeasurements()!=null) {
551 render(new HammurapiMetricRenderer(new RenderRequest(metric)), "metric-details", inspectorsPath.toString()+"source/", null, new File(outDir, summaryPath+"_metric_details_"+metric.getName()+extension));
552 }
553 }
554 }
555
556 private final Map annotationConfigs=new HashMap();
557
558 /**
559 * Annotation configuration
560 * @ant.non-required
561 * @param annotationConfig
562 */
563 public void addConfiguredAnnotationConfig(AnnotationConfig annotationConfig) {
564 annotationConfigs.put(annotationConfig.getName(), annotationConfig);
565 }
566 /**
567 * @return Returns the extension.
568 */
569 private String getExtension() {
570 return extension;
571 }
572
573 /**
574 * @return Returns the embeddedStyle.
575 */
576 private boolean isEmbeddedStyle() {
577 return embeddedStyle;
578 }
579
580 public void onBegin(InspectorSet inspectorSet) throws HammurapiException {
581 File outDir=FileUtils.newFileUtils().resolveFile(task.getProject().getBaseDir(), dir);
582 if (!outDir.exists()) {
583 if (!outDir.mkdirs()) {
584 throw new HammurapiException("Output directory cannot be created: "+outDir.getAbsolutePath());
585 }
586 }
587
588 if (!outDir.isDirectory()) {
589 throw new HammurapiException("Not a directory: "+outDir.getAbsolutePath());
590 }
591 }
592}
593
594