Return-Path: Delivered-To: apmail-jakarta-ant-dev-archive@jakarta.apache.org Received: (qmail 15142 invoked by uid 500); 14 Oct 2001 13:56:34 -0000 Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk Reply-To: ant-dev@jakarta.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 15132 invoked from network); 14 Oct 2001 13:56:29 -0000 X-Apparently-From: From: "Rob Oxspring" To: Subject: [PATCH] XML output from JDepend Date: Sun, 14 Oct 2001 15:00:56 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0001_01C154C1.0710B000" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 Importance: Normal X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. ------=_NextPart_000_0001_01C154C1.0710B000 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi all, I've just put together a patch for the JDepend task to use xml output. A new attribute "format" has been added that can take either "xml" or "text" defaulting to the latter. Appropriate changes have been made to the documentation, and additionally a .xsl file is attached to produce html with a similar style to that of junitreport. Testing: I haven't produced a testcase xml file as I couldn't think of a decent test to perform. Instead I have manually tested it using Ant 1.5a, Win2000, JDepend 2.1, and the Xalan 2.2.D11 for the xsl. Hope people find this useful, Rob ------=_NextPart_000_0001_01C154C1.0710B000 Content-Type: application/octet-stream; name="jdepend.html.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="jdepend.html.diff" Index: jdepend.html =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: = /home/cvspublic/jakarta-ant/docs/manual/OptionalTasks/jdepend.html,v retrieving revision 1.3 diff -u -r1.3 jdepend.html --- jdepend.html 2001/09/08 01:05:18 1.3 +++ jdepend.html 2001/10/14 13:22:00 @@ -16,14 +16,14 @@

Invokes the JDepend = parser.

=20

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=20 +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."

=20

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

=20

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

=20 -

The task requires at least the JDepend 1.2 version.

=09 +

The task requires at least the JDepend 1.2 version.

=20

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.

=20 @@ -41,6 +41,11 @@ 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. No, default is "off" @@ -74,8 +79,8 @@ =20

Nested Elements

=20 -

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

=20 +

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

=20

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

=20 @@ -96,7 +101,7 @@ =20
-<jdepend outputfile=3D"docs/jdepend.txt" fork=3D"yes">
+<jdepend outputfile=3D"docs/jdepend.xml" fork=3D"yes" =
format=3D"xml">
     <sourcespath>
         <pathelement location=3D"src" =
/>
     </sourcespath>
@@ -106,10 +111,10 @@
     </classpath>
 </jdepend>
 
-
=20 + =20 -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.=20 +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. =20
------=_NextPart_000_0001_01C154C1.0710B000 Content-Type: application/octet-stream; name="JDependTask.java.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="JDependTask.java.diff" Index: JDependTask.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: = /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/option= al/jdepend/JDependTask.java,v retrieving revision 1.1 diff -u -r1.1 JDependTask.java --- JDependTask.java 2001/06/01 04:43:03 1.1 +++ JDependTask.java 2001/10/14 13:30:17 @@ -71,6 +71,7 @@ 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; =20 /** * Ant task to run JDepend tests. @@ -82,10 +83,11 @@ * The current implementation spawn a new Java VM. * * @author Jerome = Lacoste + * @author Rob Oxspring */ public class JDependTask extends Task { - private CommandlineJava commandline =3D new CommandlineJava(); = =20 - =20 + //private CommandlineJava commandline =3D new CommandlineJava(); + // required attributes private Path _sourcesPath; =20 @@ -94,23 +96,26 @@ private File _dir; private Path _compileClasspath; private boolean _haltonerror =3D false; - private boolean _fork =3D false; =20 + private boolean _fork =3D false; //private Integer _timeout =3D null; - =20 + + private String _jvm =3D null; + private String format =3D "text"; + public JDependTask() { - commandline.setClassname("jdepend.textui.JDepend"); + } =20 /* public void setTimeout(Integer value) { _timeout =3D value; } - =20 + public Integer getTimeout() { return _timeout; } */ - =20 + public void setOutputFile(File outputFile) { _outputFile =3D outputFile; } @@ -134,9 +139,9 @@ * 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) { =20 - _fork =3D value; =20 - } =20 + public void setFork(boolean value) { + _fork =3D value; + } =20 public boolean getFork() { return _fork; @@ -148,9 +153,10 @@ * @see #setFork(boolean) */ public void setJvm(String value) { - commandline.setVm(value); + _jvm =3D value; + } - =20 + /** * Maybe creates a nested classpath element. */ @@ -165,7 +171,7 @@ public Path getSourcespath() { return _sourcesPath; } -=20 + /** * 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 @@ * @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(); } =20 @@ -221,27 +227,56 @@ createClasspath().setRefid(r); } =20 + + public void setFormat(FormatAttribute ea) + { + format =3D ea.getValue(); + } + + public static class FormatAttribute extends EnumeratedAttribute + { + private String [] formats =3D new String[]{"xml","text"}; + + public String[] getValues() + { + return formats; + } + } + + /** * No problems with this test. */ - private static final int SUCCESS =3D 0; =20 + private static final int SUCCESS =3D 0; /** * An error occured. - */ =20 + */ private static final int ERRORS =3D 1; - =20 + public void execute() throws BuildException { + + CommandlineJava commandline =3D new CommandlineJava(); + + if("text".equals(format)) + commandline.setClassname("jdepend.textui.JDepend"); + else + if("xml".equals(format)) + commandline.setClassname("jdepend.xmlui.JDepend"); + + if(_jvm!=3Dnull) + commandline.setVm(_jvm); + if (getSourcespath() =3D=3D null) throw new BuildException("Missing Sourcepath required = argument"); - =20 + // execute the test and get the return code int exitValue =3D JDependTask.ERRORS; boolean wasKilled =3D false; if (! getFork()) { - exitValue =3D executeInVM(); + exitValue =3D executeInVM(commandline); } else { - ExecuteWatchdog watchdog =3D createWatchdog(); = =20 - exitValue =3D executeAsForked(watchdog); + ExecuteWatchdog watchdog =3D createWatchdog(); + exitValue =3D executeAsForked(commandline,watchdog); // null watchdog means no timeout, you'd better not check = with null if (watchdog !=3D null) { //info will be used in later version do nothing for now @@ -260,21 +295,21 @@ else log("JDepend FAILED", Project.MSG_ERR); } - } =20 + } + =20 =20 - =20 // 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)" =20 - =20 + // to remove it in future versions. TBD. (SBa)" + /** * Execute inside VM. */ - public int executeInVM() throws BuildException { + public int executeInVM(CommandlineJava commandline) throws = BuildException { jdepend.textui.JDepend jdepend =3D new = jdepend.textui.JDepend(); - =20 + if (getOutputFile() !=3D null) { FileWriter fw; try { @@ -292,15 +327,15 @@ PathTokenizer sourcesPath =3D new = PathTokenizer(getSourcespath().toString()); while (sourcesPath.hasMoreTokens()) { File f =3D new File(sourcesPath.nextToken()); - =20 - // not necessary as JDepend would fail, but why loose some = time? =20 + + // not necessary as JDepend would fail, but why loose some = time? if (! f.exists() || !f.isDirectory()) { String msg =3D "\""+ f.getPath() + "\" does not = represent a valid directory. JDepend would fail."; log(msg); throw new BuildException(msg); } - try { =20 - jdepend.addDirectory(f.getPath()); =20 + try { + jdepend.addDirectory(f.getPath()); } catch (IOException e) { String msg =3D "JDepend Failed when adding a source = directory: " + e.getMessage(); @@ -311,7 +346,7 @@ jdepend.analyze(); return SUCCESS; } - =20 + =20 /** * Execute the task by forking a new JVM. The command will block = until @@ -322,15 +357,15 @@ * the test could probably hang forever. */ // JL: comment extracted from JUnitTask (and slightly modified) - public int executeAsForked(ExecuteWatchdog watchdog) throws = BuildException { =20 + public int executeAsForked(CommandlineJava = commandline,ExecuteWatchdog watchdog) throws BuildException { // if not set, auto-create the ClassPath from the project createClasspath(); =20 // 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()); } =20 if (getOutputFile() !=3D null) { @@ -344,22 +379,22 @@ PathTokenizer sourcesPath =3D new = PathTokenizer(getSourcespath().toString()); while (sourcesPath.hasMoreTokens()) { File f =3D new File(sourcesPath.nextToken()); - =20 + // 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()); } - =20 - Execute execute =3D new Execute(new LogStreamHandler(this, = Project.MSG_INFO, Project.MSG_WARN), watchdog); =20 + + Execute execute =3D new Execute(new LogStreamHandler(this, = Project.MSG_INFO, Project.MSG_WARN), watchdog); execute.setCommandline(commandline.getCommandline()); if (getDir() !=3D null) { execute.setWorkingDirectory(getDir()); execute.setAntRun(project); } =20 - if (getOutputFile() !=3D null)=20 - log("Ouptut to be stored in " + getOutputFile().getPath()); + if (getOutputFile() !=3D null) + log("Output to be stored in " + getOutputFile().getPath()); log("Executing: "+commandline.toString(), Project.MSG_VERBOSE); try { return execute.execute(); ------=_NextPart_000_0001_01C154C1.0710B000 Content-Type: text/xml; name="jdepend.xsl" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="jdepend.xsl" JDepend Analysis =09 =09 =09 =09

JDepend Analysis

Designed for use with JDepend and = Ant.


=09

Summary

[summary] [packages] [cycles] [explanations]
=09 =09 =09
Package Total Classes Abstract Classes Concrete Classes Afferent Couplings Efferent Couplings Abstractness Instability Distance
#PK
=09

Packages

[summary] [packages] [cycles] [explanations]
=09

PK

=09
Afferent Couplings: Efferent Couplings: Abstractness: Instability: Distance:
=09
Abstract Classes Concrete Classes Used by Packages Uses Packages
None
None
None #PK
None #PK
=09

Cycles

[summary] [packages] [cycles] [explanations]
=09

There are no cyclic dependancies.


=09

Explanations

[summary] [packages] [cycles] [explanations]
=09

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

=09

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

=20

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=3D0 indicating a = completely concrete package and A=3D1 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=3D0 indicating a = completely stable package and I=3D1 indicating a completely instable = package.

Distance

The perpendicular distance of a package from the idealized line A + = I =3D 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=3D0, y=3D1) or completely concrete and = instable (x=3D1, y=3D0).

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

=09
------=_NextPart_000_0001_01C154C1.0710B000-- _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com