diff --git a/docs/manual/OptionalTasks/jdepend.html b/docs/manual/OptionalTasks/jdepend.html index 5bbe5c75e..2d2734ff9 100644 --- a/docs/manual/OptionalTasks/jdepend.html +++ b/docs/manual/OptionalTasks/jdepend.html @@ -16,14 +16,14 @@

Invokes the JDepend parser.

This parser "traverses a set of Java source file directories and generates design quality metrics for each Java package". -It allows to "automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to +It allows to "automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to effectively manage and control package dependencies."

Source file directories are defined by nested <sourcespath>, see nested elements.

Optionally, you can also set the outputfile name where the output is stored. By default the task writes its report to the standard output.

-

The task requires at least the JDepend 1.2 version.

+

The task requires at least the JDepend 1.2 version.

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.

@@ -40,6 +40,11 @@ effectively manage and control package dependencies."

The output file name. If not set, the output is printed on the standard output. No + + format + The fomat to write the output in. The default is "text", the alternative is "xml" + No + fork Run the tests in a separate VM. @@ -74,8 +79,8 @@ effectively manage and control package dependencies."

Nested Elements

-

jdepend supports two nested elements <classpath> and <sourcespath>, -that represent PATH like structures.

+

jdepend supports two nested elements <classpath> and <sourcespath>, +that represent PATH like structures.

<sourcespath> is used to define the paths of the source code to analyze.

@@ -96,7 +101,7 @@ The classpath is defined using a classpath reference.
-<jdepend outputfile="docs/jdepend.txt" fork="yes">
+<jdepend outputfile="docs/jdepend.xml" fork="yes" format="xml">
     <sourcespath>
         <pathelement location="src" />
     </sourcespath>
@@ -106,10 +111,10 @@ The classpath is defined using a classpath reference.
     </classpath>
 </jdepend>
 
-
+ -This invokes JDepend in a separate VM on the src and testsrc directories, writing the output in the <docs/jdepend.txt> file. -The classpath is defined using nested elements. +This invokes JDepend in a separate VM on the src and testsrc directories, writing the output to the <docs/jdepend.xml> file in xml format. +The classpath is defined using nested elements.
diff --git a/src/etc/jdepend.xsl b/src/etc/jdepend.xsl new file mode 100644 index 000000000..97dd0f9f9 --- /dev/null +++ b/src/etc/jdepend.xsl @@ -0,0 +1,258 @@ + + + + + + + + JDepend Analysis + + + + + + + + +

JDepend Analysis

+

Designed for use with JDepend and Ant.

+
+ +
+

Summary

+
+ [summary] + [packages] + [cycles] + [explanations] +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PackageTotal ClassesAbstract ClassesConcrete ClassesAfferent CouplingsEfferent CouplingsAbstractnessInstabilityDistance
+ + #PK + + + +
+ +
+ +
+

Packages

+
+ [summary] + [packages] + [cycles] + [explanations] +
+ + + +

PK +

+ + + + + + + +
Afferent Couplings: Efferent Couplings: Abstractness: Instability: Distance:
+ + + + + + + + + + + + + + +
Abstract ClassesConcrete ClassesUsed by PackagesUses Packages
+ + None + + +
+
+
+ + None + + +
+
+
+ + None + + + + #PK + +
+
+
+ + None + + + + #PK + +
+
+
+
+
+ +
+

Cycles

+
+ [summary] + [packages] + [cycles] + [explanations] +
+ + +

There are no cyclic dependancies.

+
+ +

+ +
+

+
+ +
+

Explanations

+
+ [summary] + [packages] + [cycles] + [explanations] +
+ +

The following explanations are for quick reference and are lifted directly from the original JDepend documentation.

+ +

Number of Classes

+

The number of concrete and abstract classes (and interfaces) in the package is an indicator of the extensibility of the package.

+

Afferent Couplings

+

The number of other packages that depend upon classes within the package is an indicator of the package's responsibility.

+

Efferent Couplings

+

The number of other packages that the classes in the package depend upon is an indicator of the package's independence.

+

Abstractness

+

The ratio of the number of abstract classes (and interfaces) in the analyzed package to the total number of classes in the analyzed package.

+

The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package.

+

Instability

+

The ratio of efferent coupling (Ce) to total coupling (Ce / (Ce + Ca)). This metric is an indicator of the package's resilience to change.

+

The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package.

+

Distance

+

The perpendicular distance of a package from the idealized line A + I = 1. This metric is an indicator of the package's balance between abstractness and stability.

+

A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0).

+

The range for this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence and D=1 indicating a package that is as far from the main sequence as possible.

+ + + +
+ +
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java index a32e39659..63d507c95 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java @@ -71,6 +71,7 @@ import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.types.CommandlineJava; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.types.EnumeratedAttribute; /** * Ant task to run JDepend tests. @@ -82,10 +83,11 @@ import org.apache.tools.ant.types.Reference; * The current implementation spawn a new Java VM. * * @author Jerome Lacoste + * @author Rob Oxspring */ public class JDependTask extends Task { - private CommandlineJava commandline = new CommandlineJava(); - + //private CommandlineJava commandline = new CommandlineJava(); + // required attributes private Path _sourcesPath; @@ -94,23 +96,26 @@ public class JDependTask extends Task { private File _dir; private Path _compileClasspath; private boolean _haltonerror = false; - private boolean _fork = false; + private boolean _fork = false; //private Integer _timeout = null; - + + private String _jvm = null; + private String format = "text"; + public JDependTask() { - commandline.setClassname("jdepend.textui.JDepend"); + } /* public void setTimeout(Integer value) { _timeout = value; } - + public Integer getTimeout() { return _timeout; } */ - + public void setOutputFile(File outputFile) { _outputFile = outputFile; } @@ -134,9 +139,9 @@ public class JDependTask extends Task { * Tells whether a JVM should be forked for the task. Default: false. * @param value true if a JVM should be forked, otherwise false */ - public void setFork(boolean value) { - _fork = value; - } + public void setFork(boolean value) { + _fork = value; + } public boolean getFork() { return _fork; @@ -148,9 +153,10 @@ public class JDependTask extends Task { * @see #setFork(boolean) */ public void setJvm(String value) { - commandline.setVm(value); + _jvm = value; + } - + /** * Maybe creates a nested classpath element. */ @@ -165,7 +171,7 @@ public class JDependTask extends Task { public Path getSourcespath() { return _sourcesPath; } - + /** * The directory to invoke the VM in. Ignored if no JVM is forked. * @param dir the directory to invoke the JVM from. @@ -210,7 +216,7 @@ public class JDependTask extends Task { * @return create a new JVM argument so that any argument can be passed to the JVM. * @see #setFork(boolean) */ - public Commandline.Argument createJvmarg() { + public Commandline.Argument createJvmarg(CommandlineJava commandline ) { return commandline.createVmArgument(); } @@ -221,27 +227,56 @@ public class JDependTask extends Task { createClasspath().setRefid(r); } + + public void setFormat(FormatAttribute ea) + { + format = ea.getValue(); + } + + public static class FormatAttribute extends EnumeratedAttribute + { + private String [] formats = new String[]{"xml","text"}; + + public String[] getValues() + { + return formats; + } + } + + /** * No problems with this test. */ - private static final int SUCCESS = 0; + private static final int SUCCESS = 0; /** * An error occured. - */ + */ private static final int ERRORS = 1; - + public void execute() throws BuildException { + + CommandlineJava commandline = new CommandlineJava(); + + if("text".equals(format)) + commandline.setClassname("jdepend.textui.JDepend"); + else + if("xml".equals(format)) + commandline.setClassname("jdepend.xmlui.JDepend"); + + if(_jvm!=null) + commandline.setVm(_jvm); + if (getSourcespath() == null) throw new BuildException("Missing Sourcepath required argument"); - + // execute the test and get the return code int exitValue = JDependTask.ERRORS; boolean wasKilled = false; if (! getFork()) { - exitValue = executeInVM(); + exitValue = executeInVM(commandline); } else { - ExecuteWatchdog watchdog = createWatchdog(); - exitValue = executeAsForked(watchdog); + ExecuteWatchdog watchdog = createWatchdog(); + exitValue = executeAsForked(commandline,watchdog); // null watchdog means no timeout, you'd better not check with null if (watchdog != null) { //info will be used in later version do nothing for now @@ -260,21 +295,26 @@ public class JDependTask extends Task { else log("JDepend FAILED", Project.MSG_ERR); } - } + } + - // 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 - // to remove it in future versions. TBD. (SBa)" - + // to remove it in future versions. TBD. (SBa)" + /** * Execute inside VM. */ - public int executeInVM() throws BuildException { - jdepend.textui.JDepend jdepend = new jdepend.textui.JDepend(); - + public int executeInVM(CommandlineJava commandline) throws BuildException { + jdepend.textui.JDepend jdepend; + + if("xml".equals(format)) + jdepend = new jdepend.xmlui.JDepend(); + else + jdepend = new jdepend.textui.JDepend(); + if (getOutputFile() != null) { FileWriter fw; try { @@ -286,21 +326,21 @@ public class JDependTask extends Task { throw new BuildException(msg); } jdepend.setWriter(new PrintWriter(fw)); - log("Ouptut to be stored in " + getOutputFile().getPath()); + log("Output to be stored in " + getOutputFile().getPath()); } PathTokenizer sourcesPath = new PathTokenizer(getSourcespath().toString()); while (sourcesPath.hasMoreTokens()) { File f = new File(sourcesPath.nextToken()); - - // not necessary as JDepend would fail, but why loose some time? + + // 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()); + try { + jdepend.addDirectory(f.getPath()); } catch (IOException e) { String msg = "JDepend Failed when adding a source directory: " + e.getMessage(); @@ -311,7 +351,7 @@ public class JDependTask extends Task { jdepend.analyze(); return SUCCESS; } - + /** * Execute the task by forking a new JVM. The command will block until @@ -322,15 +362,15 @@ public class JDependTask extends Task { * the test could probably hang forever. */ // JL: comment extracted from JUnitTask (and slightly modified) - public int executeAsForked(ExecuteWatchdog watchdog) throws BuildException { + public int executeAsForked(CommandlineJava commandline,ExecuteWatchdog watchdog) throws BuildException { // if not set, auto-create the ClassPath from the project createClasspath(); // not sure whether this test is needed but cost nothing to put. // hope it will be reviewed by anybody competent if (getClasspath().toString().length() > 0) { - createJvmarg().setValue("-classpath"); - createJvmarg().setValue(getClasspath().toString()); + createJvmarg(commandline).setValue("-classpath"); + createJvmarg(commandline).setValue(getClasspath().toString()); } if (getOutputFile() != null) { @@ -344,22 +384,22 @@ public class JDependTask extends Task { PathTokenizer sourcesPath = new PathTokenizer(getSourcespath().toString()); while (sourcesPath.hasMoreTokens()) { File f = new File(sourcesPath.nextToken()); - + // 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 execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), watchdog); execute.setCommandline(commandline.getCommandline()); if (getDir() != null) { execute.setWorkingDirectory(getDir()); execute.setAntRun(project); } - if (getOutputFile() != null) - log("Ouptut to be stored in " + getOutputFile().getPath()); + if (getOutputFile() != null) + log("Output to be stored in " + getOutputFile().getPath()); log("Executing: "+commandline.toString(), Project.MSG_VERBOSE); try { return execute.execute();