DependencyMetrics.java
/*
* Copyright (c) 2001-2024, Jean Tessier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Jean Tessier nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jeantessier.dependencyfinder.ant;
import java.io.*;
import javax.xml.parsers.*;
import org.apache.tools.ant.*;
import org.xml.sax.*;
import com.jeantessier.dependency.*;
public class DependencyMetrics extends GraphTask {
private String scopeIncludes = "//";
private String scopeExcludes = "";
private boolean packageScope;
private String packageScopeIncludes = "";
private String packageScopeExcludes = "";
private boolean classScope;
private String classScopeIncludes = "";
private String classScopeExcludes = "";
private boolean featureScope;
private String featureScopeIncludes = "";
private String featureScopeExcludes = "";
private String filterIncludes = "//";
private String filterExcludes = "";
private boolean packageFilter;
private String packageFilterIncludes = "";
private String packageFilterExcludes = "";
private boolean classFilter;
private String classFilterIncludes = "";
private String classFilterExcludes = "";
private boolean featureFilter;
private String featureFilterIncludes = "";
private String featureFilterExcludes = "";
private boolean list = false;
private boolean chartClassesPerPackage = false;
private boolean chartFeaturesPerClass = false;
private boolean chartInboundsPerPackage = false;
private boolean chartOutboundsPerPackage = false;
private boolean chartInboundsPerClass = false;
private boolean chartOutboundsPerClass = false;
private boolean chartInboundsPerFeature = false;
private boolean chartOutboundsPerFeature = false;
private boolean histogramClassesPerPackage = false;
private boolean histogramFeaturesPerClass = false;
private boolean histogramInboundsPerPackage = false;
private boolean histogramOutboundsPerPackage = false;
private boolean histogramInboundsPerClass = false;
private boolean histogramOutboundsPerClass = false;
private boolean histogramInboundsPerFeature = false;
private boolean histogramOutboundsPerFeature = false;
private boolean json = false;
public String getScopeincludes() {
return scopeIncludes;
}
public void setScopeincludes(String scopeIncludes) {
this.scopeIncludes = scopeIncludes;
}
public String getScopeexcludes() {
return scopeExcludes;
}
public void setScopeexcludes(String scopeExcludes) {
this.scopeExcludes = scopeExcludes;
}
public boolean getPackagescope() {
return packageScope;
}
public void setPackagescope(boolean packageScope) {
this.packageScope = packageScope;
}
public String getPackagescopeincludes() {
return packageScopeIncludes;
}
public void setPackagescopeincludes(String packageScopeIncludes) {
this.packageScopeIncludes = packageScopeIncludes;
}
public String getPackagescopeexcludes() {
return packageScopeExcludes;
}
public void setPackagescopeexcludes(String packageScopeExcludes) {
this.packageScopeExcludes = packageScopeExcludes;
}
public boolean getClassscope() {
return classScope;
}
public void setClassscope(boolean classScope) {
this.classScope = classScope;
}
public String getClassscopeincludes() {
return classScopeIncludes;
}
public void setClassscopeincludes(String classScopeIncludes) {
this.classScopeIncludes = classScopeIncludes;
}
public String getClassscopeexcludes() {
return classScopeExcludes;
}
public void setClassscopeexcludes(String classScopeExcludes) {
this.classScopeExcludes = classScopeExcludes;
}
public boolean getFeaturescope() {
return featureScope;
}
public void setFeaturescope(boolean featureScope) {
this.featureScope = featureScope;
}
public String getFeaturescopeincludes() {
return featureScopeIncludes;
}
public void setFeaturescopeincludes(String featureScopeIncludes) {
this.featureScopeIncludes = featureScopeIncludes;
}
public String getFeaturescopeexcludes() {
return featureScopeExcludes;
}
public void setFeaturescopeexcludes(String featureScopeExcludes) {
this.featureScopeExcludes = featureScopeExcludes;
}
public String getFilterincludes() {
return filterIncludes;
}
public void setFilterincludes(String filterIncludes) {
this.filterIncludes = filterIncludes;
}
public String getFilterexcludes() {
return filterExcludes;
}
public void setFilterexcludes(String filterExcludes) {
this.filterExcludes = filterExcludes;
}
public boolean getPackagefilter() {
return packageFilter;
}
public void setPackagefilter(boolean packageFilter) {
this.packageFilter = packageFilter;
}
public String getPackagefilterincludes() {
return packageFilterIncludes;
}
public void setPackagefilterincludes(String packageFilterIncludes) {
this.packageFilterIncludes = packageFilterIncludes;
}
public String getPackagefilterexcludes() {
return packageFilterExcludes;
}
public void setPackagefilterexcludes(String packageFilterExcludes) {
this.packageFilterExcludes = packageFilterExcludes;
}
public boolean getClassfilter() {
return classFilter;
}
public void setClassfilter(boolean classFilter) {
this.classFilter = classFilter;
}
public String getClassfilterincludes() {
return classFilterIncludes;
}
public void setClassfilterincludes(String classFilterIncludes) {
this.classFilterIncludes = classFilterIncludes;
}
public String getClassfilterexcludes() {
return classFilterExcludes;
}
public void setClassfilterexcludes(String classFilterExcludes) {
this.classFilterExcludes = classFilterExcludes;
}
public boolean getFeaturefilter() {
return featureFilter;
}
public void setFeaturefilter(boolean featureFilter) {
this.featureFilter = featureFilter;
}
public String getFeaturefilterincludes() {
return featureFilterIncludes;
}
public void setFeaturefilterincludes(String featureFilterIncludes) {
this.featureFilterIncludes = featureFilterIncludes;
}
public String getFeaturefilterexcludes() {
return featureFilterExcludes;
}
public void setFeaturefilterexcludes(String featureFilterExcludes) {
this.featureFilterExcludes = featureFilterExcludes;
}
public void setP2p(boolean value) {
setPackagescope(value);
setPackagefilter(value);
}
public void setC2p(boolean value) {
setClassscope(value);
setPackagefilter(value);
}
public void setC2c(boolean value) {
setClassscope(value);
setClassfilter(value);
}
public void setF2f(boolean value) {
setFeaturescope(value);
setFeaturefilter(value);
}
public void setIncludes(String value) {
setScopeincludes(value);
setFilterincludes(value);
}
public void setExcludes(String value) {
setScopeexcludes(value);
setFilterexcludes(value);
}
public boolean getList() {
return list;
}
public void setList(boolean list) {
this.list = list;
}
public boolean getChartclassesperpackage() {
return chartClassesPerPackage;
}
public void setChartclassesperpackage(boolean chartClassesPerPackage) {
this.chartClassesPerPackage = chartClassesPerPackage;
}
public boolean getChartfeaturesperclass() {
return chartFeaturesPerClass;
}
public void setChartfeaturesperclass(boolean chartFeaturesPerClass) {
this.chartFeaturesPerClass = chartFeaturesPerClass;
}
public boolean getChartinboundsperpackage() {
return chartInboundsPerPackage;
}
public void setChartinboundsperpackage(boolean chartInboundsPerPackage) {
this.chartInboundsPerPackage = chartInboundsPerPackage;
}
public boolean getChartoutboundsperpackage() {
return chartOutboundsPerPackage;
}
public void setChartoutboundsperpackage(boolean chartOutboundsPerPackage) {
this.chartOutboundsPerPackage = chartOutboundsPerPackage;
}
public boolean getChartinboundsperclass() {
return chartInboundsPerClass;
}
public void setChartinboundsperclass(boolean chartInboundsPerClass) {
this.chartInboundsPerClass = chartInboundsPerClass;
}
public boolean getChartoutboundsperclass() {
return chartOutboundsPerClass;
}
public void setChartoutboundsperclass(boolean chartOutboundsPerClass) {
this.chartOutboundsPerClass = chartOutboundsPerClass;
}
public boolean getChartinboundsperfeature() {
return chartInboundsPerFeature;
}
public void setChartinboundsperfeature(boolean chartInboundsPerFeature) {
this.chartInboundsPerFeature = chartInboundsPerFeature;
}
public boolean getChartoutboundsperfeature() {
return chartOutboundsPerFeature;
}
public void setChartoutboundsperfeature(boolean chartOutboundsPerFeature) {
this.chartOutboundsPerFeature = chartOutboundsPerFeature;
}
public void setChartinbounds(boolean chartInbounds) {
setChartinboundsperpackage(chartInbounds);
setChartinboundsperclass(chartInbounds);
setChartinboundsperfeature(chartInbounds);
}
public void setChartoutbounds(boolean chartOutbounds) {
setChartoutboundsperpackage(chartOutbounds);
setChartoutboundsperclass(chartOutbounds);
setChartoutboundsperfeature(chartOutbounds);
}
public void setChartpackages(boolean chartPackages) {
setChartclassesperpackage(chartPackages);
setChartinboundsperpackage(chartPackages);
setChartoutboundsperpackage(chartPackages);
}
public void setChartclasses(boolean chartClasses) {
setChartfeaturesperclass(chartClasses);
setChartinboundsperclass(chartClasses);
setChartoutboundsperclass(chartClasses);
}
public void setChartfeatures(boolean chartFeatures) {
setChartinboundsperfeature(chartFeatures);
setChartoutboundsperfeature(chartFeatures);
}
public void setChartall(boolean chartAll) {
setChartclassesperpackage(chartAll);
setChartfeaturesperclass(chartAll);
setChartinboundsperpackage(chartAll);
setChartoutboundsperpackage(chartAll);
setChartinboundsperclass(chartAll);
setChartoutboundsperclass(chartAll);
setChartinboundsperfeature(chartAll);
setChartoutboundsperfeature(chartAll);
}
public boolean getHistogramclassesperpackage() {
return histogramClassesPerPackage;
}
public void setHistogramclassesperpackage(boolean histogramClassesPerPackage) {
this.histogramClassesPerPackage = histogramClassesPerPackage;
}
public boolean getHistogramfeaturesperclass() {
return histogramFeaturesPerClass;
}
public void setHistogramfeaturesperclass(boolean histogramFeaturesPerClass) {
this.histogramFeaturesPerClass = histogramFeaturesPerClass;
}
public boolean getHistograminboundsperpackage() {
return histogramInboundsPerPackage;
}
public void setHistograminboundsperpackage(boolean histogramInboundsPerPackage) {
this.histogramInboundsPerPackage = histogramInboundsPerPackage;
}
public boolean getHistogramoutboundsperpackage() {
return histogramOutboundsPerPackage;
}
public void setHistogramoutboundsperpackage(boolean histogramOutboundsPerPackage) {
this.histogramOutboundsPerPackage = histogramOutboundsPerPackage;
}
public boolean getHistograminboundsperclass() {
return histogramInboundsPerClass;
}
public void setHistograminboundsperclass(boolean histogramInboundsPerClass) {
this.histogramInboundsPerClass = histogramInboundsPerClass;
}
public boolean getHistogramoutboundsperclass() {
return histogramOutboundsPerClass;
}
public void setHistogramoutboundsperclass(boolean histogramOutboundsPerClass) {
this.histogramOutboundsPerClass = histogramOutboundsPerClass;
}
public boolean getHistograminboundsperfeature() {
return histogramInboundsPerFeature;
}
public void setHistograminboundsperfeature(boolean histogramInboundsPerFeature) {
this.histogramInboundsPerFeature = histogramInboundsPerFeature;
}
public boolean getHistogramoutboundsperfeature() {
return histogramOutboundsPerFeature;
}
public void setHistogramoutboundsperfeature(boolean histogramOutboundsPerFeature) {
this.histogramOutboundsPerFeature = histogramOutboundsPerFeature;
}
public void setHistograminbounds(boolean histogramInbounds) {
setHistograminboundsperpackage(histogramInbounds);
setHistograminboundsperclass(histogramInbounds);
setHistograminboundsperfeature(histogramInbounds);
}
public void setHistogramoutbounds(boolean histogramOutbounds) {
setHistogramoutboundsperpackage(histogramOutbounds);
setHistogramoutboundsperclass(histogramOutbounds);
setHistogramoutboundsperfeature(histogramOutbounds);
}
public void setHistogrampackages(boolean histogramPackages) {
setHistogramclassesperpackage(histogramPackages);
setHistograminboundsperpackage(histogramPackages);
setHistogramoutboundsperpackage(histogramPackages);
}
public void setHistogramclasses(boolean histogramClasses) {
setHistogramfeaturesperclass(histogramClasses);
setHistograminboundsperclass(histogramClasses);
setHistogramoutboundsperclass(histogramClasses);
}
public void setHistogramfeatures(boolean histogramFeatures) {
setHistograminboundsperfeature(histogramFeatures);
setHistogramoutboundsperfeature(histogramFeatures);
}
public void setHistogramall(boolean histogramAll) {
setHistogramclassesperpackage(histogramAll);
setHistogramfeaturesperclass(histogramAll);
setHistograminboundsperpackage(histogramAll);
setHistogramoutboundsperpackage(histogramAll);
setHistograminboundsperclass(histogramAll);
setHistogramoutboundsperclass(histogramAll);
setHistograminboundsperfeature(histogramAll);
setHistogramoutboundsperfeature(histogramAll);
}
public boolean getJson() {
return json;
}
public void setJson(boolean json) {
this.json = json;
}
public void execute() throws BuildException {
// first off, make sure that we've got what we need
validateParameters();
VerboseListener verboseListener = new VerboseListener(this);
try {
NodeFactory factory = new NodeFactory();
for (String filename : getSrc().list()) {
log("Reading graph from " + filename);
if (filename.endsWith(".xml")) {
NodeLoader loader = new NodeLoader(factory, getValidate());
loader.addDependencyListener(verboseListener);
loader.load(filename);
}
}
log("Saving metrics report to " + getDestfile().getAbsolutePath());
PrintWriter out = new PrintWriter(new FileWriter(getDestfile()));
MetricsReport reporter;
if (getJson()) {
reporter = new JSONMetricsReport(out);
} else {
reporter = new TextMetricsReport(out);
}
reporter.setListingElements(getList());
reporter.setShowingClassesPerPackageChart(getChartclassesperpackage());
reporter.setShowingFeaturesPerClassChart(getChartfeaturesperclass());
reporter.setShowingInboundsPerPackageChart(getChartinboundsperpackage());
reporter.setShowingOutboundsPerPackageChart(getChartoutboundsperpackage());
reporter.setShowingInboundsPerClassChart(getChartinboundsperclass());
reporter.setShowingOutboundsPerClassChart(getChartoutboundsperclass());
reporter.setShowingInboundsPerFeatureChart(getChartinboundsperfeature());
reporter.setShowingOutboundsPerFeatureChart(getChartoutboundsperfeature());
reporter.setShowingClassesPerPackageHistogram(getHistogramclassesperpackage());
reporter.setShowingFeaturesPerClassHistogram(getHistogramfeaturesperclass());
reporter.setShowingInboundsPerPackageHistogram(getHistograminboundsperpackage());
reporter.setShowingOutboundsPerPackageHistogram(getHistogramoutboundsperpackage());
reporter.setShowingInboundsPerClassHistogram(getHistograminboundsperclass());
reporter.setShowingOutboundsPerClassHistogram(getHistogramoutboundsperclass());
reporter.setShowingInboundsPerFeatureHistogram(getHistograminboundsperfeature());
reporter.setShowingOutboundsPerFeatureHistogram(getHistogramoutboundsperfeature());
MetricsGatherer metrics = new MetricsGatherer(getStrategy());
metrics.traverseNodes(factory.getPackages().values());
reporter.process(metrics);
out.close();
} catch (SAXException | ParserConfigurationException | IOException ex) {
throw new BuildException(ex);
}
}
private SelectionCriteria getScopeCriteria() throws BuildException {
RegularExpressionSelectionCriteria result = new RegularExpressionSelectionCriteria();
if (getPackagescope() || getClassscope() || getFeaturescope()) {
result.setMatchingPackages(getPackagescope());
result.setMatchingClasses(getClassscope());
result.setMatchingFeatures(getFeaturescope());
}
result.setGlobalIncludes(getScopeincludes());
result.setGlobalExcludes(getScopeexcludes());
result.setPackageIncludes(getPackagescopeincludes());
result.setPackageExcludes(getPackagescopeexcludes());
result.setClassIncludes(getClassscopeincludes());
result.setClassExcludes(getClassscopeexcludes());
result.setFeatureIncludes(getFeaturescopeincludes());
result.setFeatureExcludes(getFeaturescopeexcludes());
return result;
}
private SelectionCriteria getFilterCriteria() throws BuildException {
RegularExpressionSelectionCriteria result = new RegularExpressionSelectionCriteria();
if (getPackagefilter() || getClassfilter() || getFeaturefilter()) {
result.setMatchingPackages(getPackagefilter());
result.setMatchingClasses(getClassfilter());
result.setMatchingFeatures(getFeaturefilter());
}
result.setGlobalIncludes(getFilterincludes());
result.setGlobalExcludes(getFilterexcludes());
result.setPackageIncludes(getPackagefilterincludes());
result.setPackageExcludes(getPackagefilterexcludes());
result.setClassIncludes(getClassfilterincludes());
result.setClassExcludes(getClassfilterexcludes());
result.setFeatureIncludes(getFeaturefilterincludes());
result.setFeatureExcludes(getFeaturefilterexcludes());
return result;
}
private TraversalStrategy getStrategy() throws BuildException {
return new SelectiveTraversalStrategy(getScopeCriteria(), getFilterCriteria());
}
}