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.dependencyfinder.ant;
034:
035: import java.io.*;
036:
037: import javax.xml.parsers.*;
038:
039: import org.apache.tools.ant.*;
040:
041: import org.xml.sax.*;
042:
043: import com.jeantessier.dependency.*;
044:
045: public class DependencyMetrics extends GraphTask {
046: private String scopeIncludes = "//";
047: private String scopeExcludes = "";
048: private boolean packageScope;
049: private String packageScopeIncludes = "";
050: private String packageScopeExcludes = "";
051: private boolean classScope;
052: private String classScopeIncludes = "";
053: private String classScopeExcludes = "";
054: private boolean featureScope;
055: private String featureScopeIncludes = "";
056: private String featureScopeExcludes = "";
057: private String filterIncludes = "//";
058: private String filterExcludes = "";
059: private boolean packageFilter;
060: private String packageFilterIncludes = "";
061: private String packageFilterExcludes = "";
062: private boolean classFilter;
063: private String classFilterIncludes = "";
064: private String classFilterExcludes = "";
065: private boolean featureFilter;
066: private String featureFilterIncludes = "";
067: private String featureFilterExcludes = "";
068:
069: private boolean list = false;
070: private boolean chartClassesPerPackage = false;
071: private boolean chartFeaturesPerClass = false;
072: private boolean chartInboundsPerPackage = false;
073: private boolean chartOutboundsPerPackage = false;
074: private boolean chartInboundsPerClass = false;
075: private boolean chartOutboundsPerClass = false;
076: private boolean chartInboundsPerFeature = false;
077: private boolean chartOutboundsPerFeature = false;
078:
079: public String getScopeincludes() {
080: return scopeIncludes;
081: }
082:
083: public void setScopeincludes(String scopeIncludes) {
084: this .scopeIncludes = scopeIncludes;
085: }
086:
087: public String getScopeexcludes() {
088: return scopeExcludes;
089: }
090:
091: public void setScopeexcludes(String scopeExcludes) {
092: this .scopeExcludes = scopeExcludes;
093: }
094:
095: public boolean getPackagescope() {
096: return packageScope;
097: }
098:
099: public void setPackagescope(boolean packageScope) {
100: this .packageScope = packageScope;
101: }
102:
103: public String getPackagescopeincludes() {
104: return packageScopeIncludes;
105: }
106:
107: public void setPackagescopeincludes(String packageScopeIncludes) {
108: this .packageScopeIncludes = packageScopeIncludes;
109: }
110:
111: public String getPackagescopeexcludes() {
112: return packageScopeExcludes;
113: }
114:
115: public void setPackagescopeexcludes(String packageScopeExcludes) {
116: this .packageScopeExcludes = packageScopeExcludes;
117: }
118:
119: public boolean getClassscope() {
120: return classScope;
121: }
122:
123: public void setClassscope(boolean classScope) {
124: this .classScope = classScope;
125: }
126:
127: public String getClassscopeincludes() {
128: return classScopeIncludes;
129: }
130:
131: public void setClassscopeincludes(String classScopeIncludes) {
132: this .classScopeIncludes = classScopeIncludes;
133: }
134:
135: public String getClassscopeexcludes() {
136: return classScopeExcludes;
137: }
138:
139: public void setClassscopeexcludes(String classScopeExcludes) {
140: this .classScopeExcludes = classScopeExcludes;
141: }
142:
143: public boolean getFeaturescope() {
144: return featureScope;
145: }
146:
147: public void setFeaturescope(boolean featureScope) {
148: this .featureScope = featureScope;
149: }
150:
151: public String getFeaturescopeincludes() {
152: return featureScopeIncludes;
153: }
154:
155: public void setFeaturescopeincludes(String featureScopeIncludes) {
156: this .featureScopeIncludes = featureScopeIncludes;
157: }
158:
159: public String getFeaturescopeexcludes() {
160: return featureScopeExcludes;
161: }
162:
163: public void setFeaturescopeexcludes(String featureScopeExcludes) {
164: this .featureScopeExcludes = featureScopeExcludes;
165: }
166:
167: public String getFilterincludes() {
168: return filterIncludes;
169: }
170:
171: public void setFilterincludes(String filterIncludes) {
172: this .filterIncludes = filterIncludes;
173: }
174:
175: public String getFilterexcludes() {
176: return filterExcludes;
177: }
178:
179: public void setFilterexcludes(String filterExcludes) {
180: this .filterExcludes = filterExcludes;
181: }
182:
183: public boolean getPackagefilter() {
184: return packageFilter;
185: }
186:
187: public void setPackagefilter(boolean packageFilter) {
188: this .packageFilter = packageFilter;
189: }
190:
191: public String getPackagefilterincludes() {
192: return packageFilterIncludes;
193: }
194:
195: public void setPackagefilterincludes(String packageFilterIncludes) {
196: this .packageFilterIncludes = packageFilterIncludes;
197: }
198:
199: public String getPackagefilterexcludes() {
200: return packageFilterExcludes;
201: }
202:
203: public void setPackagefilterexcludes(String packageFilterExcludes) {
204: this .packageFilterExcludes = packageFilterExcludes;
205: }
206:
207: public boolean getClassfilter() {
208: return classFilter;
209: }
210:
211: public void setClassfilter(boolean classFilter) {
212: this .classFilter = classFilter;
213: }
214:
215: public String getClassfilterincludes() {
216: return classFilterIncludes;
217: }
218:
219: public void setClassfilterincludes(String classFilterIncludes) {
220: this .classFilterIncludes = classFilterIncludes;
221: }
222:
223: public String getClassfilterexcludes() {
224: return classFilterExcludes;
225: }
226:
227: public void setClassfilterexcludes(String classFilterExcludes) {
228: this .classFilterExcludes = classFilterExcludes;
229: }
230:
231: public boolean getFeaturefilter() {
232: return featureFilter;
233: }
234:
235: public void setFeaturefilter(boolean featureFilter) {
236: this .featureFilter = featureFilter;
237: }
238:
239: public String getFeaturefilterincludes() {
240: return featureFilterIncludes;
241: }
242:
243: public void setFeaturefilterincludes(String featureFilterIncludes) {
244: this .featureFilterIncludes = featureFilterIncludes;
245: }
246:
247: public String getFeaturefilterexcludes() {
248: return featureFilterExcludes;
249: }
250:
251: public void setFeaturefilterexcludes(String featureFilterExcludes) {
252: this .featureFilterExcludes = featureFilterExcludes;
253: }
254:
255: public void setP2p(boolean value) {
256: setPackagescope(value);
257: setPackagefilter(value);
258: }
259:
260: public void setC2p(boolean value) {
261: setClassscope(value);
262: setPackagefilter(value);
263: }
264:
265: public void setC2c(boolean value) {
266: setClassscope(value);
267: setClassfilter(value);
268: }
269:
270: public void setF2f(boolean value) {
271: setFeaturescope(value);
272: setFeaturefilter(value);
273: }
274:
275: public void setIncludes(String value) {
276: setScopeincludes(value);
277: setFilterincludes(value);
278: }
279:
280: public void setExcludes(String value) {
281: setScopeexcludes(value);
282: setFilterexcludes(value);
283: }
284:
285: public boolean getList() {
286: return list;
287: }
288:
289: public void setList(boolean list) {
290: this .list = list;
291: }
292:
293: public boolean getChartclassesperpackage() {
294: return chartClassesPerPackage;
295: }
296:
297: public void setChartclassesperpackage(boolean chartClassesPerPackage) {
298: this .chartClassesPerPackage = chartClassesPerPackage;
299: }
300:
301: public boolean getChartfeaturesperclass() {
302: return chartFeaturesPerClass;
303: }
304:
305: public void setChartfeaturesperclass(boolean chartFeaturesPerClass) {
306: this .chartFeaturesPerClass = chartFeaturesPerClass;
307: }
308:
309: public boolean getChartinboundsperpackage() {
310: return chartInboundsPerPackage;
311: }
312:
313: public void setChartinboundsperpackage(
314: boolean chartInboundsPerPackage) {
315: this .chartInboundsPerPackage = chartInboundsPerPackage;
316: }
317:
318: public boolean getChartoutboundsperpackage() {
319: return chartOutboundsPerPackage;
320: }
321:
322: public void setChartoutboundsperpackage(
323: boolean chartOutboundsPerPackage) {
324: this .chartOutboundsPerPackage = chartOutboundsPerPackage;
325: }
326:
327: public boolean getChartinboundsperclass() {
328: return chartInboundsPerClass;
329: }
330:
331: public void setChartinboundsperclass(boolean chartInboundsPerClass) {
332: this .chartInboundsPerClass = chartInboundsPerClass;
333: }
334:
335: public boolean getChartoutboundsperclass() {
336: return chartOutboundsPerClass;
337: }
338:
339: public void setChartoutboundsperclass(boolean chartOutboundsPerClass) {
340: this .chartOutboundsPerClass = chartOutboundsPerClass;
341: }
342:
343: public boolean getChartinboundsperfeature() {
344: return chartInboundsPerFeature;
345: }
346:
347: public void setChartinboundsperfeature(
348: boolean chartInboundsPerFeature) {
349: this .chartInboundsPerFeature = chartInboundsPerFeature;
350: }
351:
352: public boolean getChartoutboundsperfeature() {
353: return chartOutboundsPerFeature;
354: }
355:
356: public void setChartoutboundsperfeature(
357: boolean chartOutboundsPerFeature) {
358: this .chartOutboundsPerFeature = chartOutboundsPerFeature;
359: }
360:
361: public void setChartinbounds(boolean chartInbounds) {
362: setChartinboundsperpackage(chartInbounds);
363: setChartinboundsperclass(chartInbounds);
364: setChartinboundsperfeature(chartInbounds);
365: }
366:
367: public void setChartoutbounds(boolean chartOutbounds) {
368: setChartoutboundsperpackage(chartOutbounds);
369: setChartoutboundsperclass(chartOutbounds);
370: setChartoutboundsperfeature(chartOutbounds);
371: }
372:
373: public void setChartpackages(boolean chartPackages) {
374: setChartclassesperpackage(chartPackages);
375: setChartinboundsperpackage(chartPackages);
376: setChartoutboundsperpackage(chartPackages);
377: }
378:
379: public void setChartclasses(boolean chartClasses) {
380: setChartfeaturesperclass(chartClasses);
381: setChartinboundsperclass(chartClasses);
382: setChartoutboundsperclass(chartClasses);
383: }
384:
385: public void setChartfeatures(boolean chartFeatures) {
386: setChartinboundsperfeature(chartFeatures);
387: setChartoutboundsperfeature(chartFeatures);
388: }
389:
390: public void setChartall(boolean chartAll) {
391: setChartclassesperpackage(chartAll);
392: setChartfeaturesperclass(chartAll);
393: setChartinboundsperpackage(chartAll);
394: setChartoutboundsperpackage(chartAll);
395: setChartinboundsperclass(chartAll);
396: setChartoutboundsperclass(chartAll);
397: setChartinboundsperfeature(chartAll);
398: setChartoutboundsperfeature(chartAll);
399: }
400:
401: public void execute() throws BuildException {
402: // first off, make sure that we've got what we need
403: validateParameters();
404:
405: VerboseListener verboseListener = new VerboseListener(this );
406:
407: try {
408: NodeFactory factory = new NodeFactory();
409:
410: for (String filename : getSrc().list()) {
411: log("Reading graph from " + filename);
412:
413: if (filename.endsWith(".xml")) {
414: NodeLoader loader = new NodeLoader(factory,
415: getValidate());
416: loader.addDependencyListener(verboseListener);
417: loader.load(filename);
418: }
419: }
420:
421: log("Saving metrics report to "
422: + getDestfile().getAbsolutePath());
423:
424: PrintWriter out = new PrintWriter(new FileWriter(
425: getDestfile()));
426:
427: MetricsReport reporter = new MetricsReport(out);
428:
429: reporter.setListingElements(getList());
430: reporter
431: .setChartingClassesPerPackage(getChartclassesperpackage());
432: reporter
433: .setChartingFeaturesPerClass(getChartfeaturesperclass());
434: reporter
435: .setChartingInboundsPerPackage(getChartinboundsperpackage());
436: reporter
437: .setChartingOutboundsPerPackage(getChartoutboundsperpackage());
438: reporter
439: .setChartingInboundsPerClass(getChartinboundsperclass());
440: reporter
441: .setChartingOutboundsPerClass(getChartoutboundsperclass());
442: reporter
443: .setChartingInboundsPerFeature(getChartinboundsperfeature());
444: reporter
445: .setChartingOutboundsPerFeature(getChartoutboundsperfeature());
446:
447: MetricsGatherer metrics = new MetricsGatherer(getStrategy());
448: metrics.traverseNodes(factory.getPackages().values());
449: reporter.process(metrics);
450:
451: out.close();
452: } catch (SAXException ex) {
453: throw new BuildException(ex);
454: } catch (ParserConfigurationException ex) {
455: throw new BuildException(ex);
456: } catch (IOException ex) {
457: throw new BuildException(ex);
458: }
459: }
460:
461: private SelectionCriteria getScopeCriteria() throws BuildException {
462: RegularExpressionSelectionCriteria result = new RegularExpressionSelectionCriteria();
463:
464: if (getPackagescope() || getClassscope() || getFeaturescope()) {
465: result.setMatchingPackages(getPackagescope());
466: result.setMatchingClasses(getClassscope());
467: result.setMatchingFeatures(getFeaturescope());
468: }
469:
470: result.setGlobalIncludes(getScopeincludes());
471: result.setGlobalExcludes(getScopeexcludes());
472: result.setPackageIncludes(getPackagescopeincludes());
473: result.setPackageExcludes(getPackagescopeexcludes());
474: result.setClassIncludes(getClassscopeincludes());
475: result.setClassExcludes(getClassscopeexcludes());
476: result.setFeatureIncludes(getFeaturescopeincludes());
477: result.setFeatureExcludes(getFeaturescopeexcludes());
478:
479: return result;
480: }
481:
482: private SelectionCriteria getFilterCriteria() throws BuildException {
483: RegularExpressionSelectionCriteria result = new RegularExpressionSelectionCriteria();
484:
485: if (getPackagefilter() || getClassfilter()
486: || getFeaturefilter()) {
487: result.setMatchingPackages(getPackagefilter());
488: result.setMatchingClasses(getClassfilter());
489: result.setMatchingFeatures(getFeaturefilter());
490: }
491:
492: result.setGlobalIncludes(getFilterincludes());
493: result.setGlobalExcludes(getFilterexcludes());
494: result.setPackageIncludes(getPackagefilterincludes());
495: result.setPackageExcludes(getPackagefilterexcludes());
496: result.setClassIncludes(getClassfilterincludes());
497: result.setClassExcludes(getClassfilterexcludes());
498: result.setFeatureIncludes(getFeaturefilterincludes());
499: result.setFeatureExcludes(getFeaturefilterexcludes());
500:
501: return result;
502: }
503:
504: private TraversalStrategy getStrategy() throws BuildException {
505: return new SelectiveTraversalStrategy(getScopeCriteria(),
506: getFilterCriteria());
507: }
508: }
|