1 23 24 package net.sourceforge.cobertura.reporting.xml; 25 26 import java.io.File ; 27 import java.io.FileWriter ; 28 import java.io.IOException ; 29 import java.io.PrintWriter ; 30 import java.util.Collection ; 31 import java.util.Date ; 32 import java.util.Iterator ; 33 import java.util.SortedSet ; 34 import java.util.TreeSet ; 35 36 import net.sourceforge.cobertura.coveragedata.ClassData; 37 import net.sourceforge.cobertura.coveragedata.LineData; 38 import net.sourceforge.cobertura.coveragedata.PackageData; 39 import net.sourceforge.cobertura.coveragedata.ProjectData; 40 import net.sourceforge.cobertura.coveragedata.SourceFileData; 41 import net.sourceforge.cobertura.reporting.ComplexityCalculator; 42 import net.sourceforge.cobertura.util.FileFinder; 43 import net.sourceforge.cobertura.util.Header; 44 import net.sourceforge.cobertura.util.StringUtil; 45 46 import org.apache.log4j.Logger; 47 48 public class XMLReport 49 { 50 51 private static final Logger logger = Logger.getLogger(XMLReport.class); 52 53 protected final static String coverageDTD = "coverage-02.dtd"; 54 55 private final PrintWriter pw; 56 private final FileFinder finder; 57 private final ComplexityCalculator complexity; 58 private int indent = 0; 59 60 public XMLReport(ProjectData projectData, File destinationDir, 61 FileFinder finder, ComplexityCalculator complexity) throws IOException 62 { 63 this.complexity = complexity; 64 this.finder = finder; 65 66 pw = new PrintWriter (new FileWriter (new File (destinationDir, 67 "coverage.xml"))); 68 69 try 70 { 71 println("<?xml version=\"1.0\"?>"); 72 println("<!DOCTYPE coverage SYSTEM \"http://cobertura.sourceforge.net/xml/" 73 + coverageDTD + "\">"); 74 println(""); 75 76 println("<coverage line-rate=\"" 79 + projectData.getLineCoverageRate() + "\" branch-rate=\"" 80 + projectData.getBranchCoverageRate() + "\" version=\"" 81 + Header.version() + "\" timestamp=\"" 82 + new Date ().getTime() + "\">"); 83 84 increaseIndentation(); 85 dumpSources(); 86 dumpPackages(projectData); 87 decreaseIndentation(); 88 println("</coverage>"); 89 } 90 finally 91 { 92 pw.close(); 93 } 94 } 95 96 void increaseIndentation() 97 { 98 indent++; 99 } 100 101 void decreaseIndentation() 102 { 103 if (indent > 0) 104 indent--; 105 } 106 107 void indent() 108 { 109 for (int i = 0; i < indent; i++) 110 { 111 pw.print("\t"); 112 } 113 } 114 115 void println(String ln) 116 { 117 indent(); 118 pw.println(ln); 119 } 120 121 private void dumpSources() 122 { 123 println("<sources>"); 124 increaseIndentation(); 125 for (Iterator it = finder.getSourceDirectoryList().iterator(); it.hasNext(); ) { 126 String dir = (String ) it.next(); 127 dumpSource(dir); 128 } 129 decreaseIndentation(); 130 println("</sources>"); 131 } 132 133 private void dumpSource(String sourceDirectory) 134 { 135 println("<source>" + sourceDirectory + "</source>"); 136 } 137 138 private void dumpPackages(ProjectData projectData) 139 { 140 println("<packages>"); 141 increaseIndentation(); 142 143 Iterator it = projectData.getPackages().iterator(); 144 while (it.hasNext()) 145 { 146 dumpPackage((PackageData)it.next()); 147 } 148 149 decreaseIndentation(); 150 println("</packages>"); 151 } 152 153 private void dumpPackage(PackageData packageData) 154 { 155 logger.debug("Dumping package " + packageData.getName()); 156 157 println("<package name=\"" + packageData.getName() 158 + "\" line-rate=\"" + packageData.getLineCoverageRate() 159 + "\" branch-rate=\"" + packageData.getBranchCoverageRate() 160 + "\" complexity=\"" + complexity.getCCNForPackage(packageData) + "\"" + ">"); 161 increaseIndentation(); 162 dumpSourceFiles(packageData); 163 decreaseIndentation(); 164 println("</package>"); 165 } 166 167 private void dumpSourceFiles(PackageData packageData) 168 { 169 println("<classes>"); 170 increaseIndentation(); 171 172 Iterator it = packageData.getSourceFiles().iterator(); 173 while (it.hasNext()) 174 { 175 dumpClasses((SourceFileData)it.next()); 176 } 177 178 decreaseIndentation(); 179 println("</classes>"); 180 } 181 182 private void dumpClasses(SourceFileData sourceFileData) 183 { 184 Iterator it = sourceFileData.getClasses().iterator(); 185 while (it.hasNext()) 186 { 187 dumpClass((ClassData)it.next()); 188 } 189 } 190 191 private void dumpClass(ClassData classData) 192 { 193 logger.debug("Dumping class " + classData.getName()); 194 195 println("<class name=\"" + classData.getName() + "\" filename=\"" 196 + classData.getSourceFileName() + "\" line-rate=\"" 197 + classData.getLineCoverageRate() + "\" branch-rate=\"" 198 + classData.getBranchCoverageRate() + "\" complexity=\"" 199 + complexity.getCCNForClass(classData) + "\"" + ">"); 200 increaseIndentation(); 201 202 dumpMethods(classData); 203 dumpLines(classData); 204 205 decreaseIndentation(); 206 println("</class>"); 207 } 208 209 private void dumpMethods(ClassData classData) 210 { 211 println("<methods>"); 212 increaseIndentation(); 213 214 SortedSet sortedMethods = new TreeSet (); 215 sortedMethods.addAll(classData.getMethodNamesAndDescriptors()); 216 Iterator iter = sortedMethods.iterator(); 217 while (iter.hasNext()) 218 { 219 dumpMethod(classData, (String )iter.next()); 220 } 221 222 decreaseIndentation(); 223 println("</methods>"); 224 } 225 226 private void dumpMethod(ClassData classData, String nameAndSig) 227 { 228 String name = nameAndSig.substring(0, nameAndSig.indexOf('(')); 229 String signature = nameAndSig.substring(nameAndSig.indexOf('(')); 230 double lineRate = classData.getLineCoverageRate(nameAndSig); 231 double branchRate = classData.getBranchCoverageRate(nameAndSig); 232 233 println("<method name=\"" + xmlEscape(name) + "\" signature=\"" 234 + xmlEscape(signature) + "\" line-rate=\"" + lineRate 235 + "\" branch-rate=\"" + branchRate + "\">"); 236 increaseIndentation(); 237 dumpLines(classData, nameAndSig); 238 decreaseIndentation(); 239 println("</method>"); 240 } 241 242 private static String xmlEscape(String str) 243 { 244 str = StringUtil.replaceAll(str, "<", "<"); 245 str = StringUtil.replaceAll(str, ">", ">"); 246 return str; 247 } 248 249 private void dumpLines(ClassData classData) 250 { 251 dumpLines(classData.getLines()); 252 } 253 254 private void dumpLines(ClassData classData, String methodNameAndSig) 255 { 256 dumpLines(classData.getLines(methodNameAndSig)); 257 } 258 259 private void dumpLines(Collection lines) 260 { 261 println("<lines>"); 262 increaseIndentation(); 263 264 SortedSet sortedLines = new TreeSet (); 265 sortedLines.addAll(lines); 266 Iterator iter = sortedLines.iterator(); 267 while (iter.hasNext()) 268 { 269 dumpLine((LineData)iter.next()); 270 } 271 272 decreaseIndentation(); 273 println("</lines>"); 274 } 275 276 private void dumpLine(LineData lineData) 277 { 278 int lineNumber = lineData.getLineNumber(); 279 long hitCount = lineData.getHits(); 280 boolean isBranch = lineData.isBranch(); 281 282 println("<line number=\"" + lineNumber + "\" hits=\"" + hitCount 283 + "\" branch=\"" + isBranch + "\"/>"); 284 } 285 286 } 287 | Popular Tags |