sbailliez    01/11/17 16:45:51

  Modified:    src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode
                        ClassFile.java MethodInfo.java
               src/main/org/apache/tools/ant/taskdefs/optional/sitraka
                        XMLReport.java
  Log:
  Applied patch from Garrick Olson <[EMAIL PROTECTED]>
  I refactored the bytecode reading to avoid keeping unnecessary data and 
wasting memory.
  I will do a second pass to remove all useless classes.
  
  Revision  Changes    Path
  1.3       +111 -133  
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java
  
  Index: ClassFile.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClassFile.java    2001/10/28 21:30:23     1.2
  +++ ClassFile.java    2001/11/18 00:45:51     1.3
  @@ -53,154 +53,132 @@
    */
   package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode;
   
  +import java.io.DataInputStream;
   import java.io.IOException;
   import java.io.InputStream;
  -import java.io.DataInputStream;
   
  -import 
org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
   import 
org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.AttributeInfoList;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.SourceFile;
  +import 
org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
  +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo;
   import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.AttributeInfo;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.SourceDir;
   import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.LineNumberTable;
   
   
   /**
    * Object representing a class.
    *
  + * Information are kept to the strict minimum for JProbe reports so
  + * that not too many objects are created for a class, otherwise the
  + * JVM can quickly run out of memory when analyzing a great deal of
  + * classes and keeping them in memory for global analysis.
  + *
    * @author <a href="[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
  -public class ClassFile {
  -     
  -     protected ConstantPool constantPool;
  -     
  -     protected InterfaceList interfaces;
  -     
  -     protected FieldInfoList fields;
  -     
  -     protected MethodInfoList methods;
  -             
  -     protected String sourceDir;
  -     
  -     protected String sourceFile;
  -     
  -     protected int access_flags;
  -     
  -     protected int this_class;
  -     
  -     protected int super_class;
  -     
  -     protected boolean isSynthetic;
  -     
  -     protected boolean isDeprecated;
  -     
  -     public ClassFile(InputStream is) throws IOException {
  -             DataInputStream dis = new DataInputStream(is);
  -             constantPool = new ConstantPool();
  -                     
  -             int magic = dis.readInt(); // 0xCAFEBABE
  -             int minor = dis.readShort();
  -             int major = dis.readShort();
  -                             
  -             constantPool.read(dis);
  -             constantPool.resolve();
  -             
  -             access_flags = dis.readShort();
  -             this_class = dis.readShort();
  -             super_class = dis.readShort();
  -             
  -             interfaces = new InterfaceList(constantPool);
  -             interfaces.read(dis);
  -             //System.out.println(interfaces.toString());
  -             
  -             fields = new FieldInfoList(constantPool);
  -             fields.read(dis);
  -             //System.out.println(fields.toString());
  -             
  -             methods = new MethodInfoList(constantPool);
  -             methods.read(dis);
  -             //System.out.println(methods.toString());
  -             
  -             AttributeInfoList attributes = new 
AttributeInfoList(constantPool);
  -             attributes.read(dis);
  -             SourceFile srcFile = 
(SourceFile)attributes.getAttribute(AttributeInfo.SOURCE_FILE);
  -             if (srcFile != null){
  -                     sourceFile = srcFile.getValue();
  -             }
  -             SourceDir srcDir = 
(SourceDir)attributes.getAttribute(AttributeInfo.SOURCE_DIR);
  -             if (srcDir != null){
  -                     sourceDir = srcDir.getValue();
  -             }
  -             isSynthetic = attributes.getAttribute(AttributeInfo.SYNTHETIC) 
!= null;
  -             isDeprecated = 
attributes.getAttribute(AttributeInfo.DEPRECATED) != null;
  -     }
  -     
  -     public int getAccess(){
  -             return access_flags;
  -     }
  -     public InterfaceList getInterfaces(){
  -             return interfaces;
  -     }
  -     public String getSourceFile(){
  -             return sourceFile;
  -     }
  -     public String getSourceDir(){
  -             return sourceDir;
  -     }
  -     public boolean isSynthetic() {
  -             return isSynthetic;
  -     }
  -     public boolean isDeprecated() {
  -             return isDeprecated;
  -     }
  -     public MethodInfoList getMethods(){
  -             return methods;
  -     }
  -     public FieldInfoList getFields(){
  -             return fields;
  -     }
  -     public String getSuperName(){
  -             return Utils.getUTF8Value(constantPool, super_class);
  -     }
  -     public String getFullName(){
  -             return 
((ClassCPInfo)constantPool.getEntry(this_class)).getClassName().replace('/','.');
  -     }
  -     public String getName(){
  -             String name = getFullName();
  -             int pos = name.lastIndexOf('.');
  -             if (pos == -1){
  -                     return "";
  -             }
  -             return name.substring(pos + 1);
  -     }
  -     public String getPackage(){
  -             String name = getFullName();
  -             int pos = name.lastIndexOf('.');
  -             if (pos == -1){
  -                     return "";
  -             }
  -             return name.substring(0, pos);
  -     }
  -     
  -     /** dirty test method, move it into a testcase */
  -     public static void main(String[] args) throws Exception {
  -             System.out.println("loading classfile...");
  -             InputStream is = 
ClassLoader.getSystemResourceAsStream("java/util/Vector.class");
  -             ClassFile clazzfile = new ClassFile(is);
  -             System.out.println("Class name: " + clazzfile.getName());
  -             MethodInfoList methods = clazzfile.getMethods();
  -             for (int i = 0; i < methods.length(); i++){
  -                     MethodInfo method = methods.getMethod(i);
  -                     System.out.println("Method: " + 
method.getFullSignature());
  -                     System.out.println("line: " +  
method.getNumberOfLines());
  -                     LineNumberTable lnt = 
method.getCode().getLineNumberTable();
  -             }
  -     }
  -     
  +public final class ClassFile {
  +
  +    private MethodInfo[] methods;
  +
  +    private String sourceFile;
  +
  +    private String fullname;
  +
  +    private int access_flags;
  +
  +    public ClassFile(InputStream is) throws IOException {
  +        DataInputStream dis = new DataInputStream(is);
  +        ConstantPool constantPool = new ConstantPool();
  +
  +        int magic = dis.readInt(); // 0xCAFEBABE
  +        int minor = dis.readShort();
  +        int major = dis.readShort();
  +
  +        constantPool.read(dis);
  +        constantPool.resolve();
  +
  +        // class information
  +        access_flags = dis.readShort();
  +        int this_class = dis.readShort();
  +        fullname = ((ClassCPInfo) 
constantPool.getEntry(this_class)).getClassName().replace('/', '.');
  +        int super_class = dis.readShort();
  +
  +        // skip interfaces...
  +        int count = dis.readShort();
  +        dis.skipBytes(count * 2); // short
  +
  +        // skip fields...
  +        int numFields = dis.readShort();
  +        for (int i = 0; i < numFields; i++) {
  +            // 3 short: access flags, name index, descriptor index
  +            dis.skip(2 * 3);
  +            // attribute list...
  +            int attributes_count = dis.readUnsignedShort();
  +            for (int j = 0; j < attributes_count; j++) {
  +                dis.skipBytes(2); // skip attr_id (short)
  +                int len = dis.readInt();
  +                dis.skipBytes(len);
  +            }
  +        }
  +
  +        // read methods
  +        int method_count = dis.readShort();
  +        methods = new MethodInfo[method_count];
  +        for (int i = 0; i < method_count; i++) {
  +            methods[i] = new MethodInfo();
  +            methods[i].read(constantPool, dis);
  +        }
  +
  +        // get interesting attributes.
  +        int attributes_count = dis.readUnsignedShort();
  +        for (int j = 0; j < attributes_count; j++) {
  +            int attr_id = dis.readShort();
  +            int len = dis.readInt();
  +            String attr_name = Utils.getUTF8Value(constantPool, attr_id);
  +            if (AttributeInfo.SOURCE_FILE.equals(attr_name)) {
  +                int name_index = dis.readShort();
  +                sourceFile = ((Utf8CPInfo) 
constantPool.getEntry(name_index)).getValue();
  +            } else {
  +                dis.skipBytes(len);
  +            }
  +        }
  +    }
  +
  +    public int getAccess() {
  +        return access_flags;
  +    }
  +
  +    public String getSourceFile() {
  +        return sourceFile;
  +    }
  +
  +    public MethodInfo[] getMethods() {
  +        return methods;
  +    }
  +
  +    public String getFullName() {
  +        return fullname;
  +    }
  +
  +    public String getName() {
  +        String name = getFullName();
  +        int pos = name.lastIndexOf('.');
  +        if (pos == -1) {
  +            return "";
  +        }
  +        return name.substring(pos + 1);
  +    }
  +
  +    public String getPackage() {
  +        String name = getFullName();
  +        int pos = name.lastIndexOf('.');
  +        if (pos == -1) {
  +            return "";
  +        }
  +        return name.substring(0, pos);
  +    }
  +
   }
   
  +
   
  - 
   
   
  
  
  
  1.3       +114 -103  
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java
  
  Index: MethodInfo.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MethodInfo.java   2001/10/28 21:30:23     1.2
  +++ MethodInfo.java   2001/11/18 00:45:51     1.3
  @@ -53,15 +53,11 @@
    */
   package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode;
   
  -import java.io.IOException;
   import java.io.DataInputStream;
  +import java.io.IOException;
   
   import 
org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.Code;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.Exceptions;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.AttributeInfoList;
   import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.AttributeInfo;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.LineNumberTable;
   
   /**
    * Method info structure.
  @@ -69,104 +65,119 @@
    *
    * @author <a href="[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
  -public class MethodInfo {
  -     protected ConstantPool constantPool;
  -     protected int access_flags;
  -     protected int name_index;
  -     protected int descriptor_index;
  -     protected Code code;
  -     protected boolean deprecated;
  -     protected boolean synthetic;
  -     protected Exceptions exceptions;
  -     public MethodInfo(ConstantPool pool){
  -             constantPool = pool;
  -     }
  -     
  -     public void read(DataInputStream dis) throws IOException {
  -             access_flags = dis.readShort();
  -             name_index = dis.readShort();
  -             descriptor_index = dis.readShort();
  -             AttributeInfoList attrlist = new 
AttributeInfoList(constantPool);
  -             attrlist.read(dis);
  -             code = (Code)attrlist.getAttribute(AttributeInfo.CODE);
  -             synthetic = attrlist.getAttribute(AttributeInfo.SYNTHETIC) != 
null;
  -             deprecated = attrlist.getAttribute(AttributeInfo.DEPRECATED) != 
null;
  -             exceptions = 
(Exceptions)attrlist.getAttribute(AttributeInfo.EXCEPTIONS);
  -     }
  -     
  -     public int getAccessFlags(){
  -             return access_flags;
  -     }
  -     
  -     public String getName(){
  -             return Utils.getUTF8Value(constantPool, name_index);
  -     }
  -     
  -     public String getDescriptor(){
  -             return Utils.getUTF8Value(constantPool, descriptor_index);
  -     }
  -     
  -     public String getFullSignature(){
  -             return getReturnType() + " " + getShortSignature();
  -     }
  -     
  -     public String getShortSignature(){
  -             StringBuffer buf = new StringBuffer(getName());
  -             buf.append("(");
  -             String[] params = getParametersType();
  -             for (int i = 0; i < params.length; i++){
  -                     buf.append(params[i]);
  -                     if (i != params.length - 1){
  -                             buf.append(", ");
  -                     }
  -             }
  -             buf.append(")");
  -             return buf.toString();
  -     }
  -     
  -     public String getReturnType(){
  -             return Utils.getMethodReturnType(getDescriptor());
  -     }
  -     
  -     public String[] getParametersType(){
  -             return Utils.getMethodParams(getDescriptor());
  -     }
  -     
  -     public Code getCode(){
  -             return code;
  -     }
  -     
  -     public int getNumberOfLines(){
  -             int len = -1;
  -             if (code != null){
  -                     LineNumberTable lnt = code.getLineNumberTable();
  -                     if (lnt != null){
  -                             len = lnt.length();
  -                     }
  -             }
  -             return len;
  -     }
  -     
  -     public boolean isDeprecated(){
  -             return deprecated;
  -     }
  -     
  -     public boolean isSynthetic(){
  -             return synthetic;
  -     }
  -    
  -     public String getAccess(){
  -             return Utils.getMethodAccess(access_flags);
  -     }
  -     
  -     public String toString(){
  -             StringBuffer sb = new StringBuffer();
  -             sb.append("Method: ").append(getAccess()).append(" ");
  -             sb.append(getFullSignature());
  -             sb.append(" synthetic:").append(synthetic);
  -             sb.append(" deprecated:").append(deprecated);
  -             return sb.toString();
  -     }
  +public final class MethodInfo {
  +    private int access_flags;
  +    private int loc = -1;
  +    private String name;
  +    private String descriptor;
  +
  +    public MethodInfo() {
  +    }
  +
  +    public void read(ConstantPool constantPool, DataInputStream dis) throws 
IOException {
  +        access_flags = dis.readShort();
  +
  +        int name_index = dis.readShort();
  +        name =  Utils.getUTF8Value(constantPool, name_index);
  +
  +        int descriptor_index = dis.readShort();
  +        descriptor = Utils.getUTF8Value(constantPool, descriptor_index);
  +
  +        int attributes_count = dis.readUnsignedShort();
  +        for (int i = 0; i < attributes_count; i++) {
  +            int attr_id = dis.readShort();
  +            String attr_name = Utils.getUTF8Value(constantPool, attr_id);
  +            int len = dis.readInt();
  +            if (AttributeInfo.CODE.equals(attr_name)) {
  +                readCode(constantPool, dis);
  +            } else {
  +                dis.skipBytes(len);
  +            }
  +        }
  +
  +    }
  +
  +    protected void readCode(ConstantPool constantPool, DataInputStream dis) 
throws IOException {
  +        // skip max_stack (short), max_local (short)
  +        dis.skipBytes(2*2);
  +
  +        // skip bytecode...
  +        int bytecode_len = dis.readInt();
  +        dis.skip(bytecode_len);
  +
  +        // skip exceptions... 1 exception = 4 short.
  +        int exception_count = dis.readShort();
  +        dis.skipBytes(exception_count * 4 * 2);
  +
  +        // read attributes...
  +        int attributes_count = dis.readUnsignedShort();
  +        for (int i = 0; i < attributes_count; i++) {
  +            int attr_id = dis.readShort();
  +            String attr_name = Utils.getUTF8Value(constantPool, attr_id);
  +            int len = dis.readInt();
  +            if (AttributeInfo.LINE_NUMBER_TABLE.equals(attr_name)) {
  +                // we're only interested in lines of code...
  +                loc = dis.readShort();
  +                // skip the table which is 2*loc*short
  +                dis.skip(loc * 2 * 2);
  +            } else {
  +                dis.skipBytes(len);
  +            }
  +        }
  +    }
  +
  +    public int getAccessFlags() {
  +        return access_flags;
  +    }
  +
  +    public String getName() {
  +        return name;
  +    }
  +
  +    public String getDescriptor() {
  +        return descriptor;
  +    }
  +
  +    public String getFullSignature() {
  +        return getReturnType() + " " + getShortSignature();
  +    }
  +
  +    public String getShortSignature() {
  +        StringBuffer buf = new StringBuffer(getName());
  +        buf.append("(");
  +        String[] params = getParametersType();
  +        for (int i = 0; i < params.length; i++) {
  +            buf.append(params[i]);
  +            if (i != params.length - 1) {
  +                buf.append(", ");
  +            }
  +        }
  +        buf.append(")");
  +        return buf.toString();
  +    }
  +
  +    public String getReturnType() {
  +        return Utils.getMethodReturnType(getDescriptor());
  +    }
  +
  +    public String[] getParametersType() {
  +        return Utils.getMethodParams(getDescriptor());
  +    }
  +
  +    public int getNumberOfLines() {
  +        return loc;
  +    }
  +
  +    public String getAccess() {
  +        return Utils.getMethodAccess(access_flags);
  +    }
  +
  +    public String toString() {
  +        StringBuffer sb = new StringBuffer();
  +        sb.append("Method: ").append(getAccess()).append(" ");
  +        sb.append(getFullSignature());
  +        return sb.toString();
  +    }
   }
   
   
  
  
  
  1.3       +494 -505  
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java
  
  Index: XMLReport.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLReport.java    2001/10/28 21:30:23     1.2
  +++ XMLReport.java    2001/11/18 00:45:51     1.3
  @@ -53,33 +53,32 @@
    */
   package org.apache.tools.ant.taskdefs.optional.sitraka;
   
  +import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.Task;
  +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;
  +
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  -import javax.xml.transform.TransformerFactory;
  -import javax.xml.transform.Transformer;
   import javax.xml.transform.OutputKeys;
  +import javax.xml.transform.Transformer;
  +import javax.xml.transform.TransformerFactory;
   import javax.xml.transform.dom.DOMSource;
   import javax.xml.transform.stream.StreamResult;
  -
  -import org.w3c.dom.Document;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.Node;
  -import org.xml.sax.InputSource;
   import java.io.File;
   import java.io.FileInputStream;
   import java.io.FileOutputStream;
  -import java.util.Hashtable;
   import java.util.Enumeration;
  -import java.util.Vector;
  +import java.util.Hashtable;
   import java.util.NoSuchElementException;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.ClassPathLoader;
  -import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.ClassFile;
  -import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.MethodInfo;
  -import 
org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.MethodInfoList;
  -import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.Utils;
  -import org.apache.tools.ant.Task;
  -import org.apache.tools.ant.Project;
  +import java.util.Vector;
   
   /**
    * Little hack to process XML report from JProbe. It will fix
  @@ -90,498 +89,488 @@
    * @author <a href="[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
   public class XMLReport {
  -     /** task caller, can be null, used for logging purpose */
  -     protected Task task;
  +    /** task caller, can be null, used for logging purpose */
  +    protected Task task;
   
  -     /** the XML file to process just from CovReport */
  -     protected File file;
  +    /** the XML file to process just from CovReport */
  +    protected File file;
   
  -     /** jprobe home path. It is used to get the DTD */
  -     protected File jprobeHome;
  +    /** jprobe home path. It is used to get the DTD */
  +    protected File jprobeHome;
   
  -     /** parsed document */
  -     protected Document report;
  -
  -     /** mapping package name / package node for faster access */
  -     protected Hashtable pkgMap;
  -
  -     /** mapping classname / class node for faster access */
  -     protected Hashtable classMap;
  -
  -     /** method filters */
  -     protected ReportFilters filters;
  -
  -     /** create a new XML report, logging will be on stdout */
  -     public XMLReport(File file){
  -             this(null, file);
  -     }
  -
  -     /** create a new XML report, logging done on the task */
  -     public XMLReport(Task task, File file){
  -             this.file = file;
  -             this.task = task;
  -     }
  -
  -     /** set the JProbe home path. Used to get the DTD */
  -     public void setJProbehome(File home){
  -             jprobeHome = home;
  -     }
  -
  -     /** set the  */
  -     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("keeped method:" + 
signature);
  -                                             nbmethods++;
  -                                     }
  -                                     else {
  -                                             clazz.removeChild(meth);
  -                                     }
  -                             }
  -                             // if we don't keep any method, we don't keep 
the class
  -                             if (nbmethods != 0){
  -                                     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 */
  -     public Document createDocument(String[] classPath) throws Exception {
  -
  -             DocumentBuilder dbuilder = newBuilder();
  -             InputSource is = new InputSource( new FileInputStream(file) );
  -             if (jprobeHome != null){
  -                     File dtdDir = new File(jprobeHome, "Dtd/snapshot.dtd");
  -                     is.setSystemId( "file:///" + dtdDir.getAbsolutePath() );
  -             }
  -             report = dbuilder.parse( is );
  -             report.normalize();
  -
  -             // create maps for faster node access
  -             createNodeMaps();
  -
  -             // iterate over the classpath...
  -             ClassPathLoader cpl = new ClassPathLoader(classPath);
  -             Enumeration enum = cpl.loaders();
  -             while ( enum.hasMoreElements() ){
  -                     ClassPathLoader.FileLoader fl = 
(ClassPathLoader.FileLoader)enum.nextElement();
  -                     ClassFile[] classes = fl.getClasses();
  -                     log("Processing " + classes.length + " classes in " + 
fl.getFile());
  -                     // process all classes
  -                     for (int i = 0; i < classes.length; i++){
  -                             serializeClass(classes[i]);
  -                     }
  -             }
  -             // 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
  -      */
  -     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 ie, <classname>.<method>()
  -      */
  -     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
  -      */
  -     protected void removeAbstractMethods(ClassFile classFile, Element 
classNode){
  -             MethodInfoList 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.getMethod(i);
  -                     String methodSig = getMethodSignature(method);
  -                     Element methodNode = 
(Element)methodNodeList.get(methodSig);
  -                     if ( methodNode != null &&
  -                             Utils.isAbstract(method.getAccessFlags())) {
  -                             log("\tRemoving method " + methodSig);
  -                             classNode.removeChild(methodNode);
  -                     }
  -             }
  -     }
  -
  -     /** create an empty method element with its cov.data values */
  -     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) */
  -     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) */
  -     protected Element createClassElement(ClassFile classFile){
  -             // create the class element
  -             Element classElem = report.createElement("class");
  -             classElem.setAttribute("name", classFile.getName());
  -             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 */
  -     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;
  -             for (int i = 0; i < methods.size(); 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);
  -     }
  -
  -     protected Vector getFilteredMethods(ClassFile classFile){
  -             Vector methods = new Vector();
  -             MethodInfoList methodlist = classFile.getMethods();
  -             for (int i = 0; i < methodlist.length(); i++){
  -                     MethodInfo method = methodlist.getMethod(i);
  -                     String signature = getMethodSignature(classFile, 
method);
  -                     if (filters.accept(signature)){
  -                             methods.addElement(method);
  -                             log("keeping " + signature);
  -                     } else {
  +    /** parsed document */
  +    protected Document report;
  +
  +    /** mapping of class names to <code>ClassFile</code>s from the reference 
classpath.  It is used to filter the JProbe report. */
  +    protected Hashtable classFiles;
  +
  +    /** mapping package name / package node for faster access */
  +    protected Hashtable pkgMap;
  +
  +    /** mapping classname / class node for faster access */
  +    protected Hashtable classMap;
  +
  +    /** method filters */
  +    protected ReportFilters filters;
  +
  +    /** create a new XML report, logging will be on stdout */
  +    public XMLReport(File file) {
  +        this(null, file);
  +    }
  +
  +    /** create a new XML report, logging done on the task */
  +    public XMLReport(Task task, File file) {
  +        this.file = file;
  +        this.task = task;
  +    }
  +
  +    /** set the JProbe home path. Used to get the DTD */
  +    public void setJProbehome(File home) {
  +        jprobeHome = home;
  +    }
  +
  +    /** set the  */
  +    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 */
  +    public Document createDocument(String[] classPath) throws Exception {
  +
  +        // Iterate over the classpath to identify reference classes
  +        classFiles = new Hashtable();
  +        ClassPathLoader cpl = new ClassPathLoader(classPath);
  +        Enumeration enum = cpl.loaders();
  +        while (enum.hasMoreElements()) {
  +            ClassPathLoader.FileLoader fl = (ClassPathLoader.FileLoader) 
enum.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("file:///" + dtdDir.getAbsolutePath() + "/");
  +        }
  +        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
  +     */
  +    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 ie, <classname>.<method>()
  +     */
  +    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
  +     */
  +    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 method " + methodSig);
  +                classNode.removeChild(methodNode);
  +            }
  +        }
  +    }
  +
  +    /** create an empty method element with its cov.data values */
  +    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) */
  +    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) */
  +    protected Element createClassElement(ClassFile classFile) {
  +        // create the class element
  +        Element classElem = report.createElement("class");
  +        classElem.setAttribute("name", classFile.getName());
  +        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 */
  +    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;
  +        for (int i = 0; i < methods.size(); 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);
  +    }
  +
  +    protected Vector getFilteredMethods(ClassFile classFile) {
  +        Vector methods = new Vector();
  +        MethodInfo[] methodlist = classFile.getMethods();
  +        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 enum = pkgMap.elements();
  -             while ( enum.hasMoreElements() ){
  -                     Element pkgElem = (Element)enum.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 e){
  -                                     System.err.println("Error parsing '" + 
classname + "' (" + j + "/" + classes.length + ") in package '" + pkgname + 
"'");
  -                                     throw e;
  -                             }
  -                     }
  -                     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));
  -     }
  -
  -     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() + "'");
  -     }
  -
  -     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;
  -     }
  -
  -     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;
  -
  -     }
  -
  -     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);
  -             }
  -     }
  -
  -     public void log(String message){
  -             if (task == null){
  -                     //System.out.println(message);
  -             } else {
  -                     task.log(message, Project.MSG_DEBUG);
  -             }
  -     }
  -
  -     public static void main(String[] args) throws Exception {
  -             File reportFile = new File( 
XMLReport.class.getResource("covreport-test.xml").getFile() );
  -             XMLReport report = new XMLReport( reportFile );
  -             report.setJProbehome(new File("d:/Program Files/JProbe"));
  -             ReportFilters filters = new ReportFilters();
  -             ReportFilters.Include incl = new ReportFilters.Include();
  -             incl.setClass("*");
  -             incl.setMethod("set*");
  -             filters.addInclude(incl);
  -             report.setReportFilters(filters);
  -             Document doc = report.createDocument( new 
String[]{"Z:/imediation/ichannel/sources/toolkit/lib/imtoolkit.jar"} );
  -             TransformerFactory tfactory = TransformerFactory.newInstance();
  -             Transformer transformer = tfactory.newTransformer();
  -             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  -             transformer.setOutputProperty(OutputKeys.METHOD, "xml");
  -             transformer.transform(new DOMSource(doc), new StreamResult( new 
FileOutputStream( "d:/tmp/snapshot_merge.xml")));
  -     }
  +            }
  +        }
  +        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 enum = pkgMap.elements();
  +        while (enum.hasMoreElements()) {
  +            Element pkgElem = (Element) enum.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 e) {
  +                    System.err.println("Error parsing '" + classname + "' (" 
+ j + "/" + classes.length + ") in package '" + pkgname + "'");
  +                    throw e;
  +                }
  +            }
  +            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));
  +    }
  +
  +    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() + "'");
  +    }
  +
  +    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;
  +    }
  +
  +    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;
  +
  +    }
  +
  +    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);
  +        }
  +    }
  +
  +    public void log(String message) {
  +        if (task == null) {
  +            //System.out.println(message);
  +        } else {
  +            task.log(message, Project.MSG_DEBUG);
  +        }
  +    }
   
   }
   
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to