|
|
@@ -1,615 +0,0 @@ |
|
|
|
/* |
|
|
|
* Copyright 2001-2005 The Apache Software Foundation |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* You may obtain a copy of the License at |
|
|
|
* |
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
* |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* limitations under the License. |
|
|
|
* |
|
|
|
*/ |
|
|
|
package org.apache.tools.ant.taskdefs.optional.sitraka; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.FileInputStream; |
|
|
|
import java.util.Enumeration; |
|
|
|
import java.util.Hashtable; |
|
|
|
import java.util.NoSuchElementException; |
|
|
|
import java.util.Vector; |
|
|
|
import javax.xml.parsers.DocumentBuilder; |
|
|
|
import javax.xml.parsers.DocumentBuilderFactory; |
|
|
|
import org.apache.tools.ant.Project; |
|
|
|
import org.apache.tools.ant.Task; |
|
|
|
import org.apache.tools.ant.util.JAXPUtils; |
|
|
|
import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.ClassFile; |
|
|
|
import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.ClassPathLoader; |
|
|
|
import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.MethodInfo; |
|
|
|
import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.Utils; |
|
|
|
import org.w3c.dom.Document; |
|
|
|
import org.w3c.dom.Element; |
|
|
|
import org.w3c.dom.Node; |
|
|
|
import org.w3c.dom.NodeList; |
|
|
|
import org.xml.sax.InputSource; |
|
|
|
|
|
|
|
/** |
|
|
|
* Little hack to process XML report from JProbe. It will fix |
|
|
|
* some reporting errors from JProbe 3.0 and makes use of a reference |
|
|
|
* classpath to add classes/methods that were not reported by JProbe |
|
|
|
* as being used (ie loaded) |
|
|
|
* |
|
|
|
*/ |
|
|
|
public class XMLReport { |
|
|
|
/** task caller, can be null, used for logging purpose */ |
|
|
|
private Task task; |
|
|
|
|
|
|
|
/** the XML file to process just from CovReport */ |
|
|
|
private File file; |
|
|
|
|
|
|
|
/** jprobe home path. It is used to get the DTD */ |
|
|
|
private File jprobeHome; |
|
|
|
|
|
|
|
/** parsed document */ |
|
|
|
private Document report; |
|
|
|
|
|
|
|
/** |
|
|
|
* mapping of class names to <code>ClassFile</code>s from the reference |
|
|
|
* classpath. It is used to filter the JProbe report. |
|
|
|
*/ |
|
|
|
private Hashtable classFiles; |
|
|
|
|
|
|
|
/** mapping package name / package node for faster access */ |
|
|
|
private Hashtable pkgMap; |
|
|
|
|
|
|
|
/** mapping classname / class node for faster access */ |
|
|
|
private Hashtable classMap; |
|
|
|
|
|
|
|
/** method filters */ |
|
|
|
private ReportFilters filters; |
|
|
|
|
|
|
|
/** |
|
|
|
* Create a new XML report, logging will be on stdout. |
|
|
|
* @param file the file to place the report in |
|
|
|
*/ |
|
|
|
public XMLReport(File file) { |
|
|
|
this(null, file); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create a new XML report, logging done on the task. |
|
|
|
* @param task the task to use for logging |
|
|
|
* @param file the file to place the report in |
|
|
|
*/ |
|
|
|
public XMLReport(Task task, File file) { |
|
|
|
this.file = file; |
|
|
|
this.task = task; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Set the JProbe home path. Used to get the DTD. |
|
|
|
* @param home the JProbe directory |
|
|
|
*/ |
|
|
|
public void setJProbehome(File home) { |
|
|
|
jprobeHome = home; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* set the filters attribute. |
|
|
|
* @param filters a filtersreport value |
|
|
|
*/ |
|
|
|
public void setReportFilters(ReportFilters filters) { |
|
|
|
this.filters = filters; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** create node maps so that we can access node faster by their name */ |
|
|
|
protected void createNodeMaps() { |
|
|
|
pkgMap = new Hashtable(); |
|
|
|
classMap = new Hashtable(); |
|
|
|
// create a map index of all packages by their name |
|
|
|
// @todo can be done faster by direct access. |
|
|
|
NodeList packages = report.getElementsByTagName("package"); |
|
|
|
final int pkglen = packages.getLength(); |
|
|
|
log("Indexing " + pkglen + " packages"); |
|
|
|
for (int i = pkglen - 1; i > -1; i--) { |
|
|
|
Element pkg = (Element) packages.item(i); |
|
|
|
String pkgname = pkg.getAttribute("name"); |
|
|
|
|
|
|
|
int nbclasses = 0; |
|
|
|
// create a map index of all classes by their fully |
|
|
|
// qualified name. |
|
|
|
NodeList classes = pkg.getElementsByTagName("class"); |
|
|
|
final int classlen = classes.getLength(); |
|
|
|
log("Indexing " + classlen + " classes in package " + pkgname); |
|
|
|
for (int j = classlen - 1; j > -1; j--) { |
|
|
|
Element clazz = (Element) classes.item(j); |
|
|
|
String classname = clazz.getAttribute("name"); |
|
|
|
if (pkgname != null && pkgname.length() != 0) { |
|
|
|
classname = pkgname + "." + classname; |
|
|
|
} |
|
|
|
|
|
|
|
int nbmethods = 0; |
|
|
|
NodeList methods = clazz.getElementsByTagName("method"); |
|
|
|
final int methodlen = methods.getLength(); |
|
|
|
for (int k = methodlen - 1; k > -1; k--) { |
|
|
|
Element meth = (Element) methods.item(k); |
|
|
|
StringBuffer methodname = new StringBuffer(meth.getAttribute("name")); |
|
|
|
methodname.delete(methodname.toString().indexOf("("), |
|
|
|
methodname.toString().length()); |
|
|
|
String signature = classname + "." + methodname + "()"; |
|
|
|
if (filters.accept(signature)) { |
|
|
|
log("kept method:" + signature); |
|
|
|
nbmethods++; |
|
|
|
} else { |
|
|
|
clazz.removeChild(meth); |
|
|
|
} |
|
|
|
} |
|
|
|
// if we don't keep any method, we don't keep the class |
|
|
|
if (nbmethods != 0 && classFiles.containsKey(classname)) { |
|
|
|
log("Adding class '" + classname + "'"); |
|
|
|
classMap.put(classname, clazz); |
|
|
|
nbclasses++; |
|
|
|
} else { |
|
|
|
pkg.removeChild(clazz); |
|
|
|
} |
|
|
|
} |
|
|
|
if (nbclasses != 0) { |
|
|
|
log("Adding package '" + pkgname + "'"); |
|
|
|
pkgMap.put(pkgname, pkg); |
|
|
|
} else { |
|
|
|
pkg.getParentNode().removeChild(pkg); |
|
|
|
} |
|
|
|
} |
|
|
|
log("Indexed " + classMap.size() + " classes in " + pkgMap.size() + " packages"); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create the whole new document. |
|
|
|
* @param classPath the classpath |
|
|
|
* @return a dom document |
|
|
|
* @throws Exception on error |
|
|
|
*/ |
|
|
|
public Document createDocument(String[] classPath) throws Exception { |
|
|
|
|
|
|
|
// Iterate over the classpath to identify reference classes |
|
|
|
classFiles = new Hashtable(); |
|
|
|
ClassPathLoader cpl = new ClassPathLoader(classPath); |
|
|
|
Enumeration e = cpl.loaders(); |
|
|
|
while (e.hasMoreElements()) { |
|
|
|
ClassPathLoader.FileLoader fl = (ClassPathLoader.FileLoader) e.nextElement(); |
|
|
|
ClassFile[] classes = fl.getClasses(); |
|
|
|
log("Processing " + classes.length + " classes in " + fl.getFile()); |
|
|
|
// process all classes |
|
|
|
for (int i = 0; i < classes.length; i++) { |
|
|
|
classFiles.put(classes[i].getFullName(), classes[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Load the JProbe coverage XML report |
|
|
|
DocumentBuilder dbuilder = newBuilder(); |
|
|
|
InputSource is = new InputSource(new FileInputStream(file)); |
|
|
|
if (jprobeHome != null) { |
|
|
|
File dtdDir = new File(jprobeHome, "dtd"); |
|
|
|
is.setSystemId(JAXPUtils.getSystemId(dtdDir)); |
|
|
|
} |
|
|
|
report = dbuilder.parse(is); |
|
|
|
report.normalize(); |
|
|
|
|
|
|
|
// create maps for faster node access (also filters out unwanted nodes) |
|
|
|
createNodeMaps(); |
|
|
|
|
|
|
|
// Make sure each class from the reference path ends up in the report |
|
|
|
Enumeration classes = classFiles.elements(); |
|
|
|
while (classes.hasMoreElements()) { |
|
|
|
ClassFile cf = (ClassFile) classes.nextElement(); |
|
|
|
serializeClass(cf); |
|
|
|
} |
|
|
|
// update the document with the stats |
|
|
|
update(); |
|
|
|
return report; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* JProbe does not put the java.lang prefix for classes |
|
|
|
* in this package, so used this nice method so that |
|
|
|
* I have the same signature for methods |
|
|
|
* @param method info on a method |
|
|
|
* @return a method signature with the "java.lang" prefixes removed from |
|
|
|
* the method arguments |
|
|
|
*/ |
|
|
|
protected String getMethodSignature(MethodInfo method) { |
|
|
|
StringBuffer buf = new StringBuffer(method.getName()); |
|
|
|
buf.append("("); |
|
|
|
String[] params = method.getParametersType(); |
|
|
|
for (int i = 0; i < params.length; i++) { |
|
|
|
String type = params[i]; |
|
|
|
int pos = type.lastIndexOf('.'); |
|
|
|
if (pos != -1) { |
|
|
|
String pkg = type.substring(0, pos); |
|
|
|
if ("java.lang".equals(pkg)) { |
|
|
|
params[i] = type.substring(pos + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
buf.append(params[i]); |
|
|
|
if (i != params.length - 1) { |
|
|
|
buf.append(", "); |
|
|
|
} |
|
|
|
} |
|
|
|
buf.append(")"); |
|
|
|
return buf.toString(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Convert to a CovReport-like signature - <classname>.<method>(). |
|
|
|
* @param clazz the class to use |
|
|
|
* @param method the method to use |
|
|
|
* @return the CovReport-like signature |
|
|
|
*/ |
|
|
|
protected String getMethodSignature(ClassFile clazz, MethodInfo method) { |
|
|
|
StringBuffer buf = new StringBuffer(clazz.getFullName()); |
|
|
|
buf.append("."); |
|
|
|
buf.append(method.getName()); |
|
|
|
buf.append("()"); |
|
|
|
return buf.toString(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Do additional work on an element to remove abstract methods that |
|
|
|
* are reported by JProbe 3.0 |
|
|
|
* @param classFile the class to use |
|
|
|
* @param classNode information on the class |
|
|
|
*/ |
|
|
|
protected void removeAbstractMethods(ClassFile classFile, Element classNode) { |
|
|
|
MethodInfo[] methods = classFile.getMethods(); |
|
|
|
Hashtable methodNodeList = getMethods(classNode); |
|
|
|
// assert xmlMethods.size() == methods.length() |
|
|
|
final int size = methods.length; |
|
|
|
for (int i = 0; i < size; i++) { |
|
|
|
MethodInfo method = methods[i]; |
|
|
|
String methodSig = getMethodSignature(method); |
|
|
|
Element methodNode = (Element) methodNodeList.get(methodSig); |
|
|
|
if (methodNode != null |
|
|
|
&& Utils.isAbstract(method.getAccessFlags())) { |
|
|
|
log("\tRemoving abstract method " + methodSig); |
|
|
|
classNode.removeChild(methodNode); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create an empty method element with its cov.data values. |
|
|
|
* @param method jprobe info on a method |
|
|
|
* @return the method element |
|
|
|
*/ |
|
|
|
protected Element createMethodElement(MethodInfo method) { |
|
|
|
String methodsig = getMethodSignature(method); |
|
|
|
Element methodElem = report.createElement("method"); |
|
|
|
methodElem.setAttribute("name", methodsig); |
|
|
|
// create the method cov.data element |
|
|
|
Element methodData = report.createElement("cov.data"); |
|
|
|
methodElem.appendChild(methodData); |
|
|
|
methodData.setAttribute("calls", "0"); |
|
|
|
methodData.setAttribute("hit_lines", "0"); |
|
|
|
methodData.setAttribute("total_lines", String.valueOf(method.getNumberOfLines())); |
|
|
|
return methodElem; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create an empty package element with its default cov.data (0). |
|
|
|
* @param pkgname the packet name |
|
|
|
* @return the package element |
|
|
|
*/ |
|
|
|
protected Element createPackageElement(String pkgname) { |
|
|
|
Element pkgElem = report.createElement("package"); |
|
|
|
pkgElem.setAttribute("name", pkgname); |
|
|
|
// create the package cov.data element / default |
|
|
|
// must be updated at the end of the whole process |
|
|
|
Element pkgData = report.createElement("cov.data"); |
|
|
|
pkgElem.appendChild(pkgData); |
|
|
|
pkgData.setAttribute("calls", "0"); |
|
|
|
pkgData.setAttribute("hit_methods", "0"); |
|
|
|
pkgData.setAttribute("total_methods", "0"); |
|
|
|
pkgData.setAttribute("hit_lines", "0"); |
|
|
|
pkgData.setAttribute("total_lines", "0"); |
|
|
|
return pkgElem; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create an empty class element with its default cov.data (0). |
|
|
|
* @param classFile jprobe class info |
|
|
|
* @return an class element |
|
|
|
*/ |
|
|
|
protected Element createClassElement(ClassFile classFile) { |
|
|
|
// create the class element |
|
|
|
Element classElem = report.createElement("class"); |
|
|
|
classElem.setAttribute("name", classFile.getName()); |
|
|
|
// source file possibly does not exist in the bytecode |
|
|
|
if (null != classFile.getSourceFile()) { |
|
|
|
classElem.setAttribute("source", classFile.getSourceFile()); |
|
|
|
} |
|
|
|
// create the cov.data elem |
|
|
|
Element classData = report.createElement("cov.data"); |
|
|
|
classElem.appendChild(classData); |
|
|
|
// create the class cov.data element |
|
|
|
classData.setAttribute("calls", "0"); |
|
|
|
classData.setAttribute("hit_methods", "0"); |
|
|
|
classData.setAttribute("total_methods", "0"); |
|
|
|
classData.setAttribute("hit_lines", "0"); |
|
|
|
classData.setAttribute("total_lines", "0"); |
|
|
|
return classElem; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* serialize a classfile into XML. |
|
|
|
* @param classFile the class file to serialize |
|
|
|
*/ |
|
|
|
protected void serializeClass(ClassFile classFile) { |
|
|
|
// the class already is reported so ignore it |
|
|
|
String fullclassname = classFile.getFullName(); |
|
|
|
log("Looking for '" + fullclassname + "'"); |
|
|
|
Element clazz = (Element) classMap.get(fullclassname); |
|
|
|
|
|
|
|
// ignore classes that are already reported, all the information is |
|
|
|
// already there. |
|
|
|
if (clazz != null) { |
|
|
|
log("Ignoring " + fullclassname); |
|
|
|
removeAbstractMethods(classFile, clazz); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// ignore interfaces files, there is no code in there to cover. |
|
|
|
if (Utils.isInterface(classFile.getAccess())) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Vector methods = getFilteredMethods(classFile); |
|
|
|
// no need to process, there are no methods to add for this class. |
|
|
|
if (methods.size() == 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
String pkgname = classFile.getPackage(); |
|
|
|
// System.out.println("Looking for package " + pkgname); |
|
|
|
Element pkgElem = (Element) pkgMap.get(pkgname); |
|
|
|
if (pkgElem == null) { |
|
|
|
pkgElem = createPackageElement(pkgname); |
|
|
|
report.getDocumentElement().appendChild(pkgElem); |
|
|
|
pkgMap.put(pkgname, pkgElem); // add the pkg to the map |
|
|
|
} |
|
|
|
// this is a brand new class, so we have to create a new node |
|
|
|
|
|
|
|
// create the class element |
|
|
|
Element classElem = createClassElement(classFile); |
|
|
|
pkgElem.appendChild(classElem); |
|
|
|
|
|
|
|
int total_lines = 0; |
|
|
|
int total_methods = 0; |
|
|
|
final int count = methods.size(); |
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
// create the method element |
|
|
|
MethodInfo method = (MethodInfo) methods.elementAt(i); |
|
|
|
if (Utils.isAbstract(method.getAccessFlags())) { |
|
|
|
continue; // no need to report abstract methods |
|
|
|
} |
|
|
|
Element methodElem = createMethodElement(method); |
|
|
|
classElem.appendChild(methodElem); |
|
|
|
total_lines += method.getNumberOfLines(); |
|
|
|
total_methods++; |
|
|
|
} |
|
|
|
// create the class cov.data element |
|
|
|
Element classData = getCovDataChild(classElem); |
|
|
|
classData.setAttribute("total_methods", String.valueOf(total_methods)); |
|
|
|
classData.setAttribute("total_lines", String.valueOf(total_lines)); |
|
|
|
|
|
|
|
// add itself to the node map |
|
|
|
classMap.put(fullclassname, classElem); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the methods from a classFile that pass the filters. |
|
|
|
* @param classFile the class file to get the methods from |
|
|
|
* @return the list of methods |
|
|
|
*/ |
|
|
|
protected Vector getFilteredMethods(ClassFile classFile) { |
|
|
|
MethodInfo[] methodlist = classFile.getMethods(); |
|
|
|
Vector methods = new Vector(methodlist.length); |
|
|
|
for (int i = 0; i < methodlist.length; i++) { |
|
|
|
MethodInfo method = methodlist[i]; |
|
|
|
String signature = getMethodSignature(classFile, method); |
|
|
|
if (filters.accept(signature)) { |
|
|
|
methods.addElement(method); |
|
|
|
log("keeping " + signature); |
|
|
|
} else { |
|
|
|
// log("discarding " + signature); |
|
|
|
} |
|
|
|
} |
|
|
|
return methods; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** update the count of the XML, that is accumulate the stats on |
|
|
|
* methods, classes and package so that the numbers are valid |
|
|
|
* according to the info that was appended to the XML. |
|
|
|
*/ |
|
|
|
protected void update() { |
|
|
|
int calls = 0; |
|
|
|
int hit_methods = 0; |
|
|
|
int total_methods = 0; |
|
|
|
int hit_lines = 0; |
|
|
|
int total_lines = 0; |
|
|
|
|
|
|
|
// use the map for access, all nodes should be there |
|
|
|
Enumeration e = pkgMap.elements(); |
|
|
|
while (e.hasMoreElements()) { |
|
|
|
Element pkgElem = (Element) e.nextElement(); |
|
|
|
String pkgname = pkgElem.getAttribute("name"); |
|
|
|
Element[] classes = getClasses(pkgElem); |
|
|
|
int pkg_calls = 0; |
|
|
|
int pkg_hit_methods = 0; |
|
|
|
int pkg_total_methods = 0; |
|
|
|
int pkg_hit_lines = 0; |
|
|
|
int pkg_total_lines = 0; |
|
|
|
//System.out.println("Processing package '" + pkgname + "': " |
|
|
|
// + classes.length + " classes"); |
|
|
|
for (int j = 0; j < classes.length; j++) { |
|
|
|
Element clazz = classes[j]; |
|
|
|
String classname = clazz.getAttribute("name"); |
|
|
|
if (pkgname != null && pkgname.length() != 0) { |
|
|
|
classname = pkgname + "." + classname; |
|
|
|
} |
|
|
|
// there's only cov.data as a child so bet on it |
|
|
|
Element covdata = getCovDataChild(clazz); |
|
|
|
try { |
|
|
|
pkg_calls += Integer.parseInt(covdata.getAttribute("calls")); |
|
|
|
pkg_hit_methods += Integer.parseInt(covdata.getAttribute("hit_methods")); |
|
|
|
pkg_total_methods += Integer.parseInt(covdata.getAttribute("total_methods")); |
|
|
|
pkg_hit_lines += Integer.parseInt(covdata.getAttribute("hit_lines")); |
|
|
|
pkg_total_lines += Integer.parseInt(covdata.getAttribute("total_lines")); |
|
|
|
} catch (NumberFormatException ex) { |
|
|
|
log("Error parsing '" + classname + "' (" + j + "/" |
|
|
|
+ classes.length + ") in package '" + pkgname + "'"); |
|
|
|
throw ex; |
|
|
|
} |
|
|
|
} |
|
|
|
Element covdata = getCovDataChild(pkgElem); |
|
|
|
covdata.setAttribute("calls", String.valueOf(pkg_calls)); |
|
|
|
covdata.setAttribute("hit_methods", String.valueOf(pkg_hit_methods)); |
|
|
|
covdata.setAttribute("total_methods", String.valueOf(pkg_total_methods)); |
|
|
|
covdata.setAttribute("hit_lines", String.valueOf(pkg_hit_lines)); |
|
|
|
covdata.setAttribute("total_lines", String.valueOf(pkg_total_lines)); |
|
|
|
calls += pkg_calls; |
|
|
|
hit_methods += pkg_hit_methods; |
|
|
|
total_methods += pkg_total_methods; |
|
|
|
hit_lines += pkg_hit_lines; |
|
|
|
total_lines += pkg_total_lines; |
|
|
|
} |
|
|
|
Element covdata = getCovDataChild(report.getDocumentElement()); |
|
|
|
covdata.setAttribute("calls", String.valueOf(calls)); |
|
|
|
covdata.setAttribute("hit_methods", String.valueOf(hit_methods)); |
|
|
|
covdata.setAttribute("total_methods", String.valueOf(total_methods)); |
|
|
|
covdata.setAttribute("hit_lines", String.valueOf(hit_lines)); |
|
|
|
covdata.setAttribute("total_lines", String.valueOf(total_lines)); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Search for an element with the tag "cov.data" in the children |
|
|
|
* of the parent element and return it. |
|
|
|
* @param parent the parent element to search in |
|
|
|
* @return the "cov.data" element |
|
|
|
* @throws NoSuchElementException if unable to find a cov.data element |
|
|
|
*/ |
|
|
|
protected Element getCovDataChild(Element parent) { |
|
|
|
NodeList children = parent.getChildNodes(); |
|
|
|
int len = children.getLength(); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
Node child = children.item(i); |
|
|
|
if (child.getNodeType() == Node.ELEMENT_NODE) { |
|
|
|
Element elem = (Element) child; |
|
|
|
if ("cov.data".equals(elem.getNodeName())) { |
|
|
|
return elem; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
throw new NoSuchElementException("Could not find 'cov.data' " |
|
|
|
+ "element in parent '" + parent.getNodeName() + "'"); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the method elements of an class element. |
|
|
|
* @param clazz the element to search it |
|
|
|
* @return a name to element map of methods |
|
|
|
*/ |
|
|
|
protected Hashtable getMethods(Element clazz) { |
|
|
|
Hashtable map = new Hashtable(); |
|
|
|
NodeList children = clazz.getChildNodes(); |
|
|
|
int len = children.getLength(); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
Node child = children.item(i); |
|
|
|
if (child.getNodeType() == Node.ELEMENT_NODE) { |
|
|
|
Element elem = (Element) child; |
|
|
|
if ("method".equals(elem.getNodeName())) { |
|
|
|
String name = elem.getAttribute("name"); |
|
|
|
map.put(name, elem); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return map; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the class elements of an package element. |
|
|
|
* @param pkg the element to search it |
|
|
|
* @return an array of class elements |
|
|
|
*/ |
|
|
|
protected Element[] getClasses(Element pkg) { |
|
|
|
Vector v = new Vector(); |
|
|
|
NodeList children = pkg.getChildNodes(); |
|
|
|
int len = children.getLength(); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
Node child = children.item(i); |
|
|
|
if (child.getNodeType() == Node.ELEMENT_NODE) { |
|
|
|
Element elem = (Element) child; |
|
|
|
if ("class".equals(elem.getNodeName())) { |
|
|
|
v.addElement(elem); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Element[] elems = new Element[v.size()]; |
|
|
|
v.copyInto(elems); |
|
|
|
return elems; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the package elements of an snapshot element. |
|
|
|
* @param snapshot the element to search it |
|
|
|
* @return an array of package elements |
|
|
|
*/ |
|
|
|
protected Element[] getPackages(Element snapshot) { |
|
|
|
Vector v = new Vector(); |
|
|
|
NodeList children = snapshot.getChildNodes(); |
|
|
|
int len = children.getLength(); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
Node child = children.item(i); |
|
|
|
if (child.getNodeType() == Node.ELEMENT_NODE) { |
|
|
|
Element elem = (Element) child; |
|
|
|
if ("package".equals(elem.getNodeName())) { |
|
|
|
v.addElement(elem); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Element[] elems = new Element[v.size()]; |
|
|
|
v.copyInto(elems); |
|
|
|
return elems; |
|
|
|
} |
|
|
|
|
|
|
|
private static DocumentBuilder newBuilder() { |
|
|
|
try { |
|
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
|
|
|
factory.setIgnoringComments(true); |
|
|
|
factory.setValidating(false); |
|
|
|
return factory.newDocumentBuilder(); |
|
|
|
} catch (Exception e) { |
|
|
|
throw new ExceptionInInitializerError(e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Log a message to the associated task. |
|
|
|
* @param message a <code>String</code> attribute |
|
|
|
*/ |
|
|
|
public void log(String message) { |
|
|
|
if (task == null) { |
|
|
|
//System.out.println(message); |
|
|
|
} else { |
|
|
|
task.log(message, Project.MSG_DEBUG); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|