Format CSV avec JDepend

Cette page a été rédigée il y a fort fort longtemps, et n'a pas tellement été mise à jour.

 

Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise page. Moi, si je devais résumer mon wiki aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-être à un moment où je ne pouvais pas, où j'étais seul chez moi. Et c'est assez curieux de se dire que les hasards, les rencontres forgent une destinée... Parce que quand on a le goût de la chose, quand on a le goût de la chose bien faite, le beau geste, parfois on ne trouve pas l'interlocuteur en face je dirais, le miroir qui vous aide à avancer. Alors ça n'est pas mon cas, comme je disais là, puisque moi au contraire, j'ai pu ; et je dis merci au wiki, je lui dis merci, je chante le wiki, je danse le wiki... je ne suis qu'amour ! Et finalement, quand des gens me disent « Mais comment fais-tu pour avoir cette humanité ? », je leur réponds très simplement que c'est ce goût de l'amour, ce goût donc qui m'a poussé aujourd'hui à entreprendre une construction logicielle... mais demain qui sait ? Peut-être simplement à me mettre au service de la communauté, à faire le don, le don de soi.

L’outil JDepend permet de calculer des métriques de qualité pour les packages d’une application. Il évalue les dépendances amont et aval de chaque package, identifie les dépendances circulaires et fait ressortir le niveau d’abstraction et d’instabilité de chaque package. JDepend est très facile à mettre en oeuvre ; par contre, l’analyse des métriques demande un bon niveau d’expérience en conception objet.

Les résultats de JDepend peuvent être sortis dans un écran dédié (version swingui), dans un fichier xml (version xmlui) ou dans un fichier texte (version textui). C’est cette dernière possibilité qui m’a intéressée car le fichier résultat contient une synthèse des métriques sous forme CSV. Le défaut, c’est que le séparateur de colonnes utilisé est la virgule, qui est aussi le séparateur décimal puisque mon poste est en français.

Pour contourner ce problème, j’ai redéveloppé une classe de lancement pour JDepend, dans laquelle, j’ai modifié le séparateur de colonnes. J’en ai profité pour retirer toutes les autres informations et utiliser le suffixe .csv.

Classe JDepend

L’outil JDepend propose une classe JDepend centrale (package framework), plus 1 classe par type de sortie. Etant plutôt fainéant, j’ai estimé qu’en héritant de la classe textui.JDepend, j’aurais un minimum de travail à fournir. J’ai donc développé une classe qui hérite de jdepend.textui.JDepend, qui a sa méthode main, et qui redéfinit quelques méthodes…​

 package fr.sewatech.design.dependency;

 public class CsvJDepend extends jdepend.textui.JDepend {

   public static void main(String args[]) {
     new CsvJDepend().instanceMain(args);
   }
   public CsvJDepend() {
     super();
   }

   public CsvJDepend(PrintWriter writer) {
     super(writer);
   }

   // ...
 }

Formatage des sorties

La classe jdepend.textui.JDepend implémente plusieurs méthodes préfixées par print, qui écrivent les différentes parties du fichier texte. Seule la partie summary m’intéresse, j’ai donc redéfinit toutes les autres méthodes print avec des méthodes vides. Je sais que ce n’est pas très design, mais je suis dans un contexte où je ne domine pas le contenu de la sur-classe, et surtout, c’est pratique !

   @Override
   protected void printHeader() {
   }

   @Override
   protected void printPackages(Collection packages) {
   }

   @Override
   protected void printCycles(Collection packages) {
   }

   @Override
   protected void printFooter() {
   }

Ecriture du CSV

Enfin, pour la partie summary, je me suis inspriré de la sur-classe, en modifiant le séparateur de colonnes.

   @Override
   protected void printSummary(Collection packages) {
     final String separator = ";";

     getWriter().println(
       "Name"+separator+" CC"+separator+" CA"+separator+" Ca"+separator+" Ce"+separator+" A"+separator+" I"+separator+" D"+separator+" V");

     Iterator i = packages.iterator();
     while (i.hasNext()) {
       JavaPackage jPackage = (JavaPackage) i.next();
       getWriter().print(jPackage.getName() + separator);
       getWriter().print(jPackage.getClassCount() + separator);
       getWriter().print(jPackage.getAbstractClassCount() + separator);
       getWriter().print(jPackage.afferentCoupling() + separator);
       getWriter().print(jPackage.efferentCoupling() + separator);
       getWriter().print(toFormattedString(jPackage.abstractness()) + separator);
       getWriter().print(toFormattedString(jPackage.instability()) + separator);
       getWriter().print(toFormattedString(jPackage.distance()) + separator);
       getWriter().println(jPackage.getVolatility());
     }
   }

Lancement de la classe

Les options de lancement sont les mêmes que pour l’outil jDepend standard, de même que le même fichier jdepend.properties est pris en compte. Le lancement du nouvel outil se fait de la façon suivant :

 java fr.sewatech.design.dependency.CsvJDepend -file jdepend-report.csv D:\Projets\leader\workspace\novanet\novanet\WEB-INF\classes