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.util.*;
036:
037: public class MetricsGatherer extends VisitorBase {
038: private Collection<PackageNode> packages = new LinkedList<PackageNode>();
039: private Collection<ClassNode> classes = new LinkedList<ClassNode>();
040: private Collection<FeatureNode> features = new LinkedList<FeatureNode>();
041:
042: private long nbOutbound = 0;
043: private long nbInbound = 0;
044: private long nbOutboundPackages = 0;
045: private long nbInboundPackages = 0;
046: private long nbOutboundClasses = 0;
047: private long nbInboundClasses = 0;
048: private long nbOutboundFeatures = 0;
049: private long nbInboundFeatures = 0;
050:
051: private Map<Integer, long[]> chartData = new TreeMap<Integer, long[]>();
052: private int chartMaximum = 0;
053: public static final int CHART_INDEX = 0;
054: public static final int CLASSES_PER_PACKAGE = 1;
055: public static final int FEATURES_PER_CLASS = 2;
056: public static final int INBOUNDS_PER_PACKAGE = 3;
057: public static final int OUTBOUNDS_PER_PACKAGE = 4;
058: public static final int INBOUNDS_PER_CLASS = 5;
059: public static final int OUTBOUNDS_PER_CLASS = 6;
060: public static final int INBOUNDS_PER_FEATURE = 7;
061: public static final int OUTBOUNDS_PER_FEATURE = 8;
062: public static final int NB_CHARTS = 9;
063:
064: private static final String[] CHART_NAMES = { "n",
065: "Classes per Package", "Feafures per Class",
066: "Inbounds per Package", "Outbounds per Package",
067: "Inbounds per Class", "Outbounds per Class",
068: "Inbounds per Feature", "Outbounds per Feature" };
069:
070: public static int getNbCharts() {
071: return NB_CHARTS;
072: }
073:
074: public static String getChartName(int i) {
075: return CHART_NAMES[i];
076: }
077:
078: public MetricsGatherer() {
079: super ();
080: }
081:
082: public MetricsGatherer(TraversalStrategy strategy) {
083: super (strategy);
084: }
085:
086: public long[] getChartData(int i) {
087: long[] result = chartData.get(i);
088:
089: if (result == null) {
090: result = new long[NB_CHARTS];
091: result[CHART_INDEX] = i;
092: chartData.put(i, result);
093:
094: if (chartMaximum < i) {
095: chartMaximum = i;
096: }
097: }
098:
099: return result;
100: }
101:
102: public int getChartMaximum() {
103: return chartMaximum;
104: }
105:
106: public Collection<PackageNode> getPackages() {
107: return packages;
108: }
109:
110: public Collection<ClassNode> getClasses() {
111: return classes;
112: }
113:
114: public Collection<FeatureNode> getFeatures() {
115: return features;
116: }
117:
118: public long getNbOutbound() {
119: return nbOutbound;
120: }
121:
122: public long getNbInbound() {
123: return nbInbound;
124: }
125:
126: public long getNbOutboundPackages() {
127: return nbOutboundPackages;
128: }
129:
130: public long getNbInboundPackages() {
131: return nbInboundPackages;
132: }
133:
134: public long getNbOutboundClasses() {
135: return nbOutboundClasses;
136: }
137:
138: public long getNbInboundClasses() {
139: return nbInboundClasses;
140: }
141:
142: public long getNbOutboundFeatures() {
143: return nbOutboundFeatures;
144: }
145:
146: public long getNbInboundFeatures() {
147: return nbInboundFeatures;
148: }
149:
150: public void preprocessPackageNode(PackageNode node) {
151: super .preprocessPackageNode(node);
152:
153: packages.add(node);
154:
155: getChartData(node.getClasses().size())[CLASSES_PER_PACKAGE]++;
156: getChartData(node.getInboundDependencies().size())[INBOUNDS_PER_PACKAGE]++;
157: getChartData(node.getOutboundDependencies().size())[OUTBOUNDS_PER_PACKAGE]++;
158: }
159:
160: /**
161: * PackageNode --> CurrentNode()
162: */
163: public void visitInboundPackageNode(PackageNode node) {
164: if (getStrategy().isInFilter(node)) {
165: nbInbound++;
166: nbOutboundPackages++;
167: }
168: }
169:
170: /**
171: * CurrentNode() --> PackageNode
172: */
173: public void visitOutboundPackageNode(PackageNode node) {
174: if (getStrategy().isInFilter(node)) {
175: nbOutbound++;
176: nbInboundPackages++;
177: }
178: }
179:
180: public void preprocessClassNode(ClassNode node) {
181: super .preprocessClassNode(node);
182:
183: classes.add(node);
184:
185: getChartData(node.getFeatures().size())[FEATURES_PER_CLASS]++;
186: getChartData(node.getInboundDependencies().size())[INBOUNDS_PER_CLASS]++;
187: getChartData(node.getOutboundDependencies().size())[OUTBOUNDS_PER_CLASS]++;
188: }
189:
190: /**
191: * ClassNode --> CurrentNode()
192: */
193: public void visitInboundClassNode(ClassNode node) {
194: if (getStrategy().isInFilter(node)) {
195: nbInbound++;
196: nbOutboundClasses++;
197: }
198: }
199:
200: /**
201: * CurrentNode() --> ClassNode
202: */
203: public void visitOutboundClassNode(ClassNode node) {
204: if (getStrategy().isInFilter(node)) {
205: nbOutbound++;
206: nbInboundClasses++;
207: }
208: }
209:
210: public void preprocessFeatureNode(FeatureNode node) {
211: super .preprocessFeatureNode(node);
212:
213: features.add(node);
214:
215: getChartData(node.getInboundDependencies().size())[INBOUNDS_PER_FEATURE]++;
216: getChartData(node.getOutboundDependencies().size())[OUTBOUNDS_PER_FEATURE]++;
217: }
218:
219: /**
220: * FeatureNode --> CurrentNode()
221: */
222: public void visitInboundFeatureNode(FeatureNode node) {
223: if (getStrategy().isInFilter(node)) {
224: nbInbound++;
225: nbOutboundFeatures++;
226: }
227: }
228:
229: /**
230: * CurrentNode() --> FeatureNode
231: */
232: public void visitOutboundFeatureNode(FeatureNode node) {
233: if (getStrategy().isInFilter(node)) {
234: nbOutbound++;
235: nbInboundFeatures++;
236: }
237: }
238: }
|