ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sbaill...@apache.org
Subject cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/sitraka XMLReport.java
Date Sun, 18 Nov 2001 00:45:51 GMT
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 <garrick.olson@aceva.com>
  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="sbailliez@imediation.com">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="sbailliez@imediation.com">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="sbailliez@imediation.com">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:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message