/*
 * FindBugs - Find bugs in Java programs
 * Copyright (C) 2003, Mike Fagan <mfagan@tde.com>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs.detect;

import edu.umd.cs.findbugs.*;
import edu.umd.cs.pugh.visitclass.PreorderVisitor;
import edu.umd.cs.daveho.ba.ClassContext;

import java.util.*;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.io.*;

import org.apache.bcel.Repository;
import org.apache.bcel.classfile.*;

import org.dom4j.Element;
import org.dom4j.Branch;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.io.OutputFormat;


public class FindBugsSummaryStats extends PreorderVisitor 
                                  implements Detector, BugReporterObserver, SummaryReport {
  private HashMap<String, PackageStats> packageStatsMap = new HashMap<String, PackageStats>();
  private BugReporter bugReporter;
  int totalErrors;
  int totalClasses;


  public FindBugsSummaryStats(BugReporter bugReporter) {
	this.bugReporter = bugReporter;
    bugReporter.addObserver( this );
    this.totalErrors = 0;
    this.totalClasses = 0;
  }

  public void visitClassContext(ClassContext classContext) {
	classContext.getJavaClass().accept(this);
  }

  public void report() { }

  public void reportSummary( OutputStream out ) {
     Document document = DocumentHelper.createDocument();
     Element root = document.addElement("FindBugsSummary");
     DateFormat df = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z" );
     root.addAttribute("timestamp", df.format(new Date() ));
     root.addAttribute( "total_classes", String.valueOf( totalClasses ) );
     root.addAttribute( "total_bugs", String.valueOf( totalErrors ) );
     root.addAttribute( "num_packages", String.valueOf( packageStatsMap.size() ) );
	 Iterator<PackageStats> i = packageStatsMap.values().iterator();
     while( i.hasNext() ) {
       PackageStats stats = i.next();
       stats.toElement( root );
     } 

     try {
       XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
       writer.write(document);
     }
     catch ( Exception e ) {
       e.printStackTrace();
     }
  }

  public void visit(JavaClass obj)     {
	super.visit(obj);
    PackageStats stat = getPackageStats( packageName );
    stat.addClass( betterClassName, obj.isInterface() );
    totalClasses++;
  }

  public void reportBug( BugInstance bug ) {
    PackageStats stat = getPackageStats( bug.getPrimaryClass().getPackageName() );
    stat.addError( bug );
    totalErrors++;
  }

  private PackageStats getPackageStats( String packageName ) {
    PackageStats stat = packageStatsMap.get( packageName );
    if ( stat == null ) {
      stat = new PackageStats( packageName );
      packageStatsMap.put( packageName, stat );
    }
    return stat;
  }

}

@@ -1020,72 +1020,8 @@
 .*;%0A
-import java.text.SimpleDateFormat;%0Aimport java.text.DateFormat;%0A
 impo
@@ -1517,169 +1517,64 @@
 ate 
-HashMap%3CString, PackageStats%3E packageStatsMap = new HashMap%3CString, PackageStats%3E();%0A  private BugReporter bugReporter;%0A  int totalErrors;%0A  int totalClasse
+BugReporter bugReporter;%0A  private ProjectStats stat
 s;%0A%0A
-%0A
   pu
@@ -1626,17 +1626,20 @@
 rter) %7B%0A
-%09
+    
 this.bug
@@ -1670,92 +1670,76 @@
     
-bugReporter.addObserver( this );%0A    this.totalErrors = 0;%0A    this.totalClasses = 0
+this.stats = new ProjectStats();%0A    bugReporter.addObserver( this )
 ;%0A  
@@ -1802,17 +1802,20 @@
 text) %7B%0A
-%09
+    
 classCon
@@ -1993,188 +1993,27 @@
 ();%0A
-     Element root = document.addElement(%22FindBugsSummary%22);%0A     DateFormat df = new SimpleDateFormat( %22EEE, d MMM yyyy HH:mm:ss Z%22 );%0A     root.addAttribute(%22timestamp%22, df.form
+%0A     stats.setD
 at
+e
 (new
@@ -2023,18 +2023,16 @@
 te()
- )
 );%0A     
 root
@@ -2031,404 +2031,34 @@
     
-root.addAttribute( %22total_classes%22, String.valueOf( totalClasses ) );%0A     root.addAttribute( %22total_bugs%22, String.valueOf( totalErrors ) );%0A     root.addAttribute( %22num_packages%22, String.valueOf( packageStatsMap.size() ) );%0A%09 Iterator%3CPackageStats%3E i = packageStatsMap.values().iterator();%0A     while( i.hasNext() ) %7B%0A       PackageStats stats = i.next();%0A       stats.toElement( root );%0A     %7D 
+stats.toElement(document);
 %0A%0A  
@@ -2298,9 +2298,12 @@
   %7B%0A
-%09
+    
 supe
@@ -2324,68 +2324,13 @@
     
-PackageStats stat = getPackageStats( packageName );%0A    
 stat
+s
 .add
@@ -2378,28 +2378,8 @@
  );%0A
-    totalClasses++;%0A
   %7D%0A
@@ -2432,401 +2432,25 @@
     
-PackageStats stat = getPackageStats( bug.getPrimaryClass().getPackageName() );%0A    stat.addError( bug );%0A    totalErrors++;%0A  %7D%0A%0A  private PackageStats getPackageStats( String packageName ) %7B%0A    PackageStats stat = packageStatsMap.get( packageName );%0A    if ( stat == null ) %7B%0A      stat = new PackageStats( packageName );%0A      packageStatsMap.put( packageName, stat );%0A    %7D%0A    return stat
+stats.addBug(bug)
 ;%0A  

Use a ProjectStats object to store all of the stats.