001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.dependency;
034:
035: import java.io.*;
036: import java.util.*;
037:
038: public class MetricsReport {
039: private PrintWriter out;
040:
041: boolean listingElements = false;
042: boolean chartingClassesPerPackage = false;
043: boolean chartingFeaturesPerClass = false;
044: boolean chartingInboundsPerPackage = false;
045: boolean chartingOutboundsPerPackage = false;
046: boolean chartingInboundsPerClass = false;
047: boolean chartingOutboundsPerClass = false;
048: boolean chartingInboundsPerFeature = false;
049: boolean chartingOutboundsPerFeature = false;
050:
051: public MetricsReport(PrintWriter out) {
052: this .out = out;
053: }
054:
055: public boolean isListingElements() {
056: return listingElements;
057: }
058:
059: public void setListingElements(boolean listingElements) {
060: this .listingElements = listingElements;
061: }
062:
063: public boolean isChartingClassesPerPackage() {
064: return chartingClassesPerPackage;
065: }
066:
067: public void setChartingClassesPerPackage(
068: boolean chartingClassesPerPackage) {
069: this .chartingClassesPerPackage = chartingClassesPerPackage;
070: }
071:
072: public boolean isChartingFeaturesPerClass() {
073: return chartingFeaturesPerClass;
074: }
075:
076: public void setChartingFeaturesPerClass(
077: boolean chartingFeaturesPerClass) {
078: this .chartingFeaturesPerClass = chartingFeaturesPerClass;
079: }
080:
081: public boolean isChartingInboundsPerPackage() {
082: return chartingInboundsPerPackage;
083: }
084:
085: public void setChartingInboundsPerPackage(
086: boolean chartingInboundsPerPackage) {
087: this .chartingInboundsPerPackage = chartingInboundsPerPackage;
088: }
089:
090: public boolean isChartingOutboundsPerPackage() {
091: return chartingOutboundsPerPackage;
092: }
093:
094: public void setChartingOutboundsPerPackage(
095: boolean chartingOutboundsPerPackage) {
096: this .chartingOutboundsPerPackage = chartingOutboundsPerPackage;
097: }
098:
099: public boolean isChartingInboundsPerClass() {
100: return chartingInboundsPerClass;
101: }
102:
103: public void setChartingInboundsPerClass(
104: boolean chartingInboundsPerClass) {
105: this .chartingInboundsPerClass = chartingInboundsPerClass;
106: }
107:
108: public boolean isChartingOutboundsPerClass() {
109: return chartingOutboundsPerClass;
110: }
111:
112: public void setChartingOutboundsPerClass(
113: boolean chartingOutboundsPerClass) {
114: this .chartingOutboundsPerClass = chartingOutboundsPerClass;
115: }
116:
117: public boolean isChartingInboundsPerFeature() {
118: return chartingInboundsPerFeature;
119: }
120:
121: public void setChartingInboundsPerFeature(
122: boolean chartingInboundsPerFeature) {
123: this .chartingInboundsPerFeature = chartingInboundsPerFeature;
124: }
125:
126: public boolean isChartingOutboundsPerFeature() {
127: return chartingOutboundsPerFeature;
128: }
129:
130: public void setChartingOutboundsPerFeature(
131: boolean chartingOutboundsPerFeature) {
132: this .chartingOutboundsPerFeature = chartingOutboundsPerFeature;
133: }
134:
135: public void process(MetricsGatherer metrics) {
136: int nbPackages = metrics.getPackages().size();
137: out.print(nbPackages + " package(s)");
138: if (nbPackages > 0) {
139: int nbConfirmedPackages = countConfirmedNodes(metrics
140: .getPackages());
141: out
142: .print(" ("
143: + nbConfirmedPackages
144: + " confirmed, "
145: + (nbConfirmedPackages / (double) nbPackages)
146: + ")");
147: }
148: out.println();
149: if (isListingElements()) {
150: for (PackageNode packageNode : metrics.getPackages()) {
151: out.println(" " + packageNode);
152: }
153: }
154:
155: int nbClasses = metrics.getClasses().size();
156: out.print(nbClasses + " class(es)");
157: if (nbClasses > 0) {
158: int nbConfirmedClasses = countConfirmedNodes(metrics
159: .getClasses());
160: out.print(" (" + nbConfirmedClasses + " confirmed, "
161: + (nbConfirmedClasses / (double) nbClasses) + ")");
162: }
163: out.println();
164: if (isListingElements()) {
165: for (ClassNode classNode : metrics.getClasses()) {
166: out.println(" " + classNode);
167: }
168: }
169:
170: int nbFeatures = metrics.getFeatures().size();
171: out.print(nbFeatures + " feature(s)");
172: if (nbFeatures > 0) {
173: int nbConfirmedFeatures = countConfirmedNodes(metrics
174: .getFeatures());
175: out
176: .print(" ("
177: + nbConfirmedFeatures
178: + " confirmed, "
179: + (nbConfirmedFeatures / (double) nbFeatures)
180: + ")");
181: }
182: out.println();
183: if (isListingElements()) {
184: for (FeatureNode featureNode : metrics.getFeatures()) {
185: out.println(" " + featureNode);
186: }
187: }
188:
189: out.println();
190:
191: out.println(metrics.getNbOutbound() + " outbound link(s)");
192:
193: long nbOutboundPackages = metrics.getNbOutboundPackages();
194: out.print(" " + nbOutboundPackages + " from package(s)");
195: if (nbOutboundPackages > 0 && nbPackages > 0) {
196: out.print(" (on average "
197: + (nbOutboundPackages / (double) nbPackages)
198: + " per package)");
199: }
200: out.println();
201:
202: long nbOutboundClasses = metrics.getNbOutboundClasses();
203: out.print(" " + nbOutboundClasses + " from class(es)");
204: if (nbOutboundClasses > 0 && nbClasses > 0) {
205: out.print(" (on average "
206: + (nbOutboundClasses / (double) nbClasses)
207: + " per class)");
208: }
209: out.println();
210:
211: long nbOutboundFeatures = metrics.getNbOutboundFeatures();
212: out.print(" " + nbOutboundFeatures + " from feature(s)");
213: if (nbOutboundFeatures > 0 && nbFeatures > 0) {
214: out.print(" (on average "
215: + (nbOutboundFeatures / (double) nbFeatures)
216: + " per feature)");
217: }
218: out.println();
219:
220: out.println(metrics.getNbInbound() + " inbound link(s)");
221:
222: long nbInboundPackages = metrics.getNbInboundPackages();
223: out.print(" " + nbInboundPackages + " to package(s)");
224: if (nbInboundPackages > 0 && nbPackages > 0) {
225: out.print(" (on average "
226: + (nbInboundPackages / (double) nbPackages)
227: + " per package)");
228: }
229: out.println();
230:
231: long nbInboundClasses = metrics.getNbInboundClasses();
232: out.print(" " + nbInboundClasses + " to class(es)");
233: if (nbInboundClasses > 0 && nbClasses > 0) {
234: out.print(" (on average "
235: + (nbInboundClasses / (double) nbClasses)
236: + " per class)");
237: }
238: out.println();
239:
240: long nbInboundFeatures = metrics.getNbInboundFeatures();
241: out.print(" " + nbInboundFeatures + " to feature(s)");
242: if (nbInboundFeatures > 0 && nbFeatures > 0) {
243: out.print(" (on average "
244: + (nbInboundFeatures / (double) nbFeatures)
245: + " per feature)");
246: }
247: out.println();
248:
249: if (isChartingClassesPerPackage()
250: || isChartingFeaturesPerClass()
251: || isChartingInboundsPerPackage()
252: || isChartingOutboundsPerPackage()
253: || isChartingInboundsPerClass()
254: || isChartingOutboundsPerClass()
255: || isChartingInboundsPerFeature()
256: || isChartingOutboundsPerFeature()) {
257:
258: out.println();
259:
260: out.print("n");
261: if (isChartingClassesPerPackage()) {
262: out.print(", \"classes per package\"");
263: }
264: if (isChartingFeaturesPerClass()) {
265: out.print(", \"features per class\"");
266: }
267: if (isChartingInboundsPerPackage()) {
268: out.print(", \"inbounds per package\"");
269: }
270: if (isChartingOutboundsPerPackage()) {
271: out.print(", \"outbounds per package\"");
272: }
273: if (isChartingInboundsPerClass()) {
274: out.print(", \"inbounds per class\"");
275: }
276: if (isChartingOutboundsPerClass()) {
277: out.print(", \"outbounds per class\"");
278: }
279: if (isChartingInboundsPerFeature()) {
280: out.print(", \"inbounds per feature\"");
281: }
282: if (isChartingOutboundsPerFeature()) {
283: out.print(", \"outbounds per feature\"");
284: }
285: out.println();
286:
287: for (int k = 0; k <= metrics.getChartMaximum(); k++) {
288: long[] dataPoint = metrics.getChartData(k);
289:
290: out.print(k);
291: if (isChartingClassesPerPackage()) {
292: out
293: .print(", "
294: + dataPoint[MetricsGatherer.CLASSES_PER_PACKAGE]);
295: }
296: if (isChartingFeaturesPerClass()) {
297: out
298: .print(", "
299: + dataPoint[MetricsGatherer.FEATURES_PER_CLASS]);
300: }
301: if (isChartingInboundsPerPackage()) {
302: out
303: .print(", "
304: + dataPoint[MetricsGatherer.INBOUNDS_PER_PACKAGE]);
305: }
306: if (isChartingOutboundsPerPackage()) {
307: out
308: .print(", "
309: + dataPoint[MetricsGatherer.OUTBOUNDS_PER_PACKAGE]);
310: }
311: if (isChartingInboundsPerClass()) {
312: out
313: .print(", "
314: + dataPoint[MetricsGatherer.INBOUNDS_PER_CLASS]);
315: }
316: if (isChartingOutboundsPerClass()) {
317: out
318: .print(", "
319: + dataPoint[MetricsGatherer.OUTBOUNDS_PER_CLASS]);
320: }
321: if (isChartingInboundsPerFeature()) {
322: out
323: .print(", "
324: + dataPoint[MetricsGatherer.INBOUNDS_PER_FEATURE]);
325: }
326: if (isChartingOutboundsPerFeature()) {
327: out
328: .print(", "
329: + dataPoint[MetricsGatherer.OUTBOUNDS_PER_FEATURE]);
330: }
331: out.println();
332: }
333: }
334: }
335:
336: private int countConfirmedNodes(Collection<? extends Node> nodes) {
337: int result = 0;
338:
339: for (Node node : nodes) {
340: if (node.isConfirmed()) {
341: result++;
342: }
343: }
344:
345: return result;
346: }
347: }
|