Browse Source

Add <classespath> nested element to mirror <sourcespath> but point to

compiled classes.

Add <exclude> nested element to conditionally exclude packages from
being parsed.

PR: 17134
Submitted by:	Bob Hays <electricbob at alephnaught dot com>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274371 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 22 years ago
parent
commit
9c51b355f7
3 changed files with 180 additions and 45 deletions
  1. +6
    -0
      WHATSNEW
  2. +44
    -15
      docs/manual/OptionalTasks/jdepend.html
  3. +130
    -30
      src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java

+ 6
- 0
WHATSNEW View File

@@ -202,6 +202,12 @@ Other changes:
* <junit> has a new attribute tempdir that controls the placement of
temporary files. Bugzilla Report 15454.

* <jdepend> now supports a new nested element <classespath> which is
the same as <sourcespath> but point to compiled classes (the
prefered mode of operation for JDepend > 2.5). Additionally, nested
<exclude> elements can be used to exclude certain packages from
being parsed. Bugzilla Report 17134.

Changes from Ant 1.5.2 to Ant 1.5.3
===================================



+ 44
- 15
docs/manual/OptionalTasks/jdepend.html View File

@@ -19,14 +19,15 @@
It allows to &quot;automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to
effectively manage and control package dependencies.&quot;</P>

<p>Source file directories are defined by nested <code>&lt;sourcespath&gt;</code>, see <a href="#nested">nested elements</a>.</p>
<p>Source file directories are defined by nested
<code>&lt;sourcespath&gt;</code>; Class file directories are defined
by nested <code>&lt;classesespath&gt;</code>, see <a
href="#nested">nested elements</a>.</p>

<p>Optionally, you can also set the <code>outputfile</code> name where the output is stored. By default the task writes its report to the standard output.</P>

<p> The task requires at least the JDepend 1.2 version. </p>

<P>Note: whereas the JDepend tool can be customized to exclude some packages, the current jdepend And Task does not have parameters to allow these exclusions. Read JDepend specific documentation for that purpose.</P>

<h3>Parameters</h3>

<table BORDER=1 CELLSPACING=0 CELLPADDING=2 >
@@ -79,26 +80,37 @@ effectively manage and control package dependencies.&quot;</P>

<h3><a name="nested">Nested Elements</a></h3>

<p><code>jdepend</code> supports two nested elements <code>&lt;classpath&gt;</code> and <code>&lt;sourcespath&gt;</code>,
that represent <a href="../using.html#path">PATH like structures</a>.</p>

<p><code>&lt;sourcespath&gt;</code> is used to define the paths of the source code to analyze.</p>
<p><code>jdepend</code> supports four nested elements:
<code>&lt;classpath&gt;, &lt;classespath&gt; </code> and
<code>&lt;sourcespath&gt;</code>, that represent <a
href="../using.html#path">PATH like structures</a>, and
<code>&lt;exclude&gt;</code>.</p>

<p><code>&lt;sourcespath&gt;</code> is used to define the paths of the
source code to analyze, but it is deprecated. With version 2.5 of
JDepend, only class files are analyzed. The nested element
&lt;classespath&gt; replaces &lt;sourcespath&gt; and is used to define
the paths of compiled class code to analyze; the &lt;sourcespath&gt;
variable is still available in case you are using an earlier version
of JDepend. The &lt;exclude&gt; element can be used to set packages
to ignore.</p>

<h3>Examples</h3>

<blockquote>
<pre>
&lt;jdepend classpathref="base.path"&gt;
&nbsp;&nbsp;&nbsp; &lt;sourcespath&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="src"/&gt;
&nbsp;&nbsp;&nbsp; &lt;/sourcespath&gt;
&nbsp;&nbsp;&nbsp; &lt;classespath&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="build"/&gt;
&nbsp;&nbsp;&nbsp; &lt;/classespath&gt;
&lt;/jdepend&gt;

</pre>
</blockquote>

This invokes JDepend on the <code>src</code> directory, writing the output on the standard output.
The classpath is defined using a classpath reference.
<p>This invokes JDepend on the <code>build</code> directory, writing
the output on the standard output. The classpath is defined using a
classpath reference.</p>

<blockquote>
<pre>
@@ -111,15 +123,32 @@ The classpath is defined using a classpath reference.
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="lib/jdepend.jar"/&gt;
&nbsp;&nbsp;&nbsp; &lt;/classpath&gt;
&lt;/jdepend&gt;
</pre>
</blockquote>

<p>This invokes JDepend in a separate VM on the <code>src</code> and
<code>testsrc</code> directories, writing the output to the
<code>&lt;docs/jdepend.xml&gt;</code> file in xml format. The
classpath is defined using nested elements. </p>

<blockquote>
<pre>
&lt;jdepend classpathref="base.path"&gt;
&nbsp;&nbsp;&nbsp; &lt;exclude name="java.*&gt;
&nbsp;&nbsp;&nbsp; &lt;exclude name="javax.*&gt;
&nbsp;&nbsp;&nbsp; &lt;classespath&gt;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="build"/&gt;
&nbsp;&nbsp;&nbsp; &lt;/classespath&gt;
&lt;/jdepend&gt;
</pre>
</blockquote>

This invokes JDepend in a separate VM on the <code>src</code> and <code>testsrc</code> directories, writing the output to the <code>&lt;docs/jdepend.xml&gt;</code> file in xml format.
The classpath is defined using nested elements.
<p>This invokes JDepend with the build directory as the base for class
files to analyze, and will ignore all classes in the java.* and
javax.* packages.</p>

<hr>
<p align="center">Copyright &copy; 2001-2002 Apache Software Foundation. All rights
<p align="center">Copyright &copy; 2001-2003 Apache Software Foundation. All rights
Reserved.</p>
</body>
</html>


+ 130
- 30
src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java View File

@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2002 The Apache Software Foundation. All rights
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.PathTokenizer;
import org.apache.tools.ant.Project;
@@ -69,6 +70,7 @@ import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.CommandlineJava;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.Reference;

/**
@@ -87,7 +89,8 @@ public class JDependTask extends Task {
//private CommandlineJava commandline = new CommandlineJava();

// required attributes
private Path _sourcesPath;
private Path _sourcesPath; // Deprecated!
private Path _classesPath; // Use this going forward

// optional attributes
private File _outputFile;
@@ -99,6 +102,7 @@ public class JDependTask extends Task {

private String _jvm = null;
private String format = "text";
private PatternSet defaultPatterns = new PatternSet();

public JDependTask() {

@@ -165,6 +169,7 @@ public class JDependTask extends Task {

/**
* Adds a path to source code to analyze.
* @deprecated
*/
public Path createSourcespath() {
if (_sourcesPath == null) {
@@ -173,11 +178,34 @@ public class JDependTask extends Task {
return _sourcesPath.createPath();
}

/** Gets the sourcepath. */
/**
* Gets the sourcepath.
*
* @deprecated
*
*/
public Path getSourcespath() {
return _sourcesPath;
}

/**
* Adds a path to class code to analyze.
*/
public Path createClassespath() {
if (_classesPath == null) {
_classesPath = new Path(getProject());
}
return _classesPath.createPath();
}

/**
* Gets the classespath.
*
*/
public Path getClassespath() {
return _classesPath;
}

/**
* The directory to invoke the VM in. Ignored if no JVM is forked.
* @param dir the directory to invoke the JVM from.
@@ -233,6 +261,16 @@ public class JDependTask extends Task {
createClasspath().setRefid(r);
}

/**
* add a name entry on the exclude list
*/
public PatternSet.NameEntry createExclude() {
return defaultPatterns.createExclude();
}

public PatternSet getExcludes() {
return defaultPatterns;
}

/**
* The format to write the output in, "xml" or "text".
@@ -251,7 +289,6 @@ public class JDependTask extends Task {
}
}


/**
* No problems with this test.
*/
@@ -275,13 +312,18 @@ public class JDependTask extends Task {
if (_jvm != null) {
commandline.setVm(_jvm);
}

if (getSourcespath() == null) {
throw new BuildException("Missing Sourcepath required argument");
if (getSourcespath() == null && getClassespath() == null) {
throw new BuildException("Missing classespath required argument");
} else if (getClassespath() == null) {
String msg =
"sourcespath is deprecated in JDepend >= 2.5 "
+ "- please convert to classespath";
log(msg);
}

// execute the test and get the return code
int exitValue = JDependTask.ERRORS;
//boolean wasKilled = false;
if (!getFork()) {
exitValue = executeInVM(commandline);
} else {
@@ -308,8 +350,6 @@ public class JDependTask extends Task {
}
}



// this comment extract from JUnit Task may also apply here
// "in VM is not very nice since it could probably hang the
// whole build. IMHO this method should be avoided and it would be best
@@ -341,27 +381,75 @@ public class JDependTask extends Task {
log("Output to be stored in " + getOutputFile().getPath());
}

PathTokenizer sourcesPath
= new PathTokenizer(getSourcespath().toString());
while (sourcesPath.hasMoreTokens()) {
File f = new File(sourcesPath.nextToken());
if (getClassespath() != null) {
// This is the new, better way - use classespath instead
// of sourcespath. The code is currently the same - you
// need class files in a directory to use this - jar files
// coming soon....
String[] classesPath = getClassespath().list();
for (int i = 0; i < classesPath.length; i++) {
File f = new File(classesPath[i]);
// not necessary as JDepend would fail, but why loose
// some time?
if (!f.exists() || !f.isDirectory()) {
String msg = "\""
+ f.getPath()
+ "\" does not represent a valid"
+ " directory. JDepend would fail.";
log(msg);
throw new BuildException(msg);
}
try {
jdepend.addDirectory(f.getPath());
} catch (IOException e) {
String msg =
"JDepend Failed when adding a class directory: "
+ e.getMessage();
log(msg);
throw new BuildException(msg);
}
}

// not necessary as JDepend would fail, but why loose some time?
if (!f.exists() || !f.isDirectory()) {
String msg = "\"" + f.getPath() + "\" does not represent a valid"
+ " directory. JDepend would fail.";
log(msg);
throw new BuildException(msg);
} else if (getSourcespath() != null) {

// This is the old way and is deprecated - classespath is
// the right way to do this and is above
String[] sourcesPath = getSourcespath().list();
for (int i = 0; i < sourcesPath.length; i++) {
File f = new File(sourcesPath[i]);

// not necessary as JDepend would fail, but why loose
// some time?
if (!f.exists() || !f.isDirectory()) {
String msg = "\""
+ f.getPath()
+ "\" does not represent a valid"
+ " directory. JDepend would fail.";
log(msg);
throw new BuildException(msg);
}
try {
jdepend.addDirectory(f.getPath());
} catch (IOException e) {
String msg =
"JDepend Failed when adding a source directory: "
+ e.getMessage();
log(msg);
throw new BuildException(msg);
}
}
try {
jdepend.addDirectory(f.getPath());
} catch (IOException e) {
String msg = "JDepend Failed when adding a source directory: "
+ e.getMessage();
log(msg);
throw new BuildException(msg);
}

// This bit turns <exclude> child tags into patters to ignore
String[] patterns = defaultPatterns.getExcludePatterns(getProject());
if (patterns != null && patterns.length > 0) {
Vector v = new Vector();
for (int i = 0; i < patterns.length; i++) {
v.addElement(patterns[i]);
}
jdepend.setFilter(new jdepend.framework.PackageFilter(v));
}

jdepend.analyze();
return SUCCESS;
}
@@ -397,10 +485,10 @@ public class JDependTask extends Task {
// we have to find a cleaner way to put this output
}

PathTokenizer sourcesPath
= new PathTokenizer(getSourcespath().toString());
while (sourcesPath.hasMoreTokens()) {
File f = new File(sourcesPath.nextToken());
// This is deprecated - use classespath in the future
String[] sourcesPath = getSourcespath().list();
for (int i = 0; i < sourcesPath.length; i++) {
File f = new File(sourcesPath[i]);

// not necessary as JDepend would fail, but why loose some time?
if (!f.exists() || !f.isDirectory()) {
@@ -410,6 +498,18 @@ public class JDependTask extends Task {
commandline.createArgument().setValue(f.getPath());
}

// This is the new way - use classespath - code is the same for now
String[] classesPath = getClassespath().list();
for (int i = 0; i < classesPath.length; i++) {
File f = new File(classesPath[i]);
// not necessary as JDepend would fail, but why loose some time?
if (!f.exists() || !f.isDirectory()) {
throw new BuildException("\"" + f.getPath() + "\" does not "
+ "represent a valid directory. JDepend would fail.");
}
commandline.createArgument().setValue(f.getPath());
}

Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), watchdog);
execute.setCommandline(commandline.getCommandline());
if (getDir() != null) {


Loading…
Cancel
Save