sbailliez    02/02/08 14:06:56

  Modified:    src/main/org/apache/tools/ant/taskdefs/optional/metamata
                        MAudit.java MMetricsStreamHandler.java
                        MMetrics.java MAuditStreamHandler.java
                        AbstractMetamataTask.java
  Log:
  - Added rulespath to Audit to use customized rules.
  - Fix Audit messages to remove fullpath in it. It
  won't work on references though.
  - Fix MAudit handler to print stderr as well so
  that a missing agent or invalid options return
  a message.
  - Enhance options to reflect those available also
  in Webgain QA 2.1.2+
  
  Revision  Changes    Path
  1.4       +108 -56   
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java
  
  Index: MAudit.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MAudit.java       10 Jan 2002 13:59:37 -0000      1.3
  +++ MAudit.java       8 Feb 2002 22:06:56 -0000       1.4
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2001 The Apache Software Foundation.  All rights
  + * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -53,21 +53,19 @@
    */
   package org.apache.tools.ant.taskdefs.optional.metamata;
   
  +import java.io.File;
  +import java.io.FileOutputStream;
  +import java.io.IOException;
  +import java.io.OutputStream;
  +import java.util.Vector;
  +
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
  -
   import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
   import org.apache.tools.ant.taskdefs.LogStreamHandler;
  +import org.apache.tools.ant.types.FileSet;
   import org.apache.tools.ant.types.Path;
   
  -
  -
  -import java.io.File;
  -import java.io.OutputStream;
  -import java.io.FileOutputStream;
  -import java.io.IOException;
  -import java.util.Vector;
  -
   /**
    * Metamata Audit evaluates Java code for programming errors, weaknesses, and
    * style violation.
  @@ -81,7 +79,7 @@
    * For more information, visit the website at
    * <a href="http://www.metamata.com";>www.metamata.com</a>
    *
  - * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
   public class MAudit extends AbstractMetamataTask {
   
  @@ -119,15 +117,24 @@
       // (?:file:)?((?#filepath).+):((?#line)\\d+)\\s*:\\s+((?#message).*)
       final static String AUDIT_PATTERN = "(?:file:)?(.+):(\\d+)\\s*:\\s+(.*)";
   
  -    protected File outFile = null;
  -    
  -    protected Path searchPath = null;
  -    
  -    protected boolean fix = false;
  -    
  -    protected boolean list = false;
  -    
  -    protected boolean unused = false;
  +    private File outFile = null;
  +
  +    private Path searchPath = null;
  +
  +    private Path rulesPath = null;
  +
  +    private boolean fix = false;
  +
  +    private boolean list = false;
  +
  +    private boolean unused = false;
  +
  +//  add a bunch of undocumented options for the task
  +    private boolean quiet = false;
  +    private boolean exit = false;
  +    private boolean offsets = false;
  +    private boolean verbose = false;
  +    private boolean fullsemanticize = false;
   
       /** default constructor */
       public MAudit() {
  @@ -135,49 +142,101 @@
       }
   
       /** set the destination file which should be an xml file */
  -    public void setTofile(File outFile){
  +    public void setTofile(File outFile) {
           this.outFile = outFile;
       }
   
  -    public void setFix(boolean flag){
  +    public void setFix(boolean flag) {
           this.fix = flag;
       }
   
  -    public void setList(boolean flag){
  +    public void setList(boolean flag) {
           this.list = flag;
       }
   
  -    public void setUnused(boolean flag){
  +    public void setUnused(boolean flag) {
           this.unused = flag;
       }
   
  -    public Path createSearchpath(){
  -        if (searchPath == null){
  -            searchPath = new Path(project);
  +    public void setQuiet(boolean flag) {
  +        this.quiet = flag;
  +    }
  +
  +    public void setExit(boolean flag) {
  +        this.exit = flag;
  +    }
  +
  +    public void setOffsets(boolean flag) {
  +        this.offsets = flag;
  +    }
  +
  +    public void setVerbose(boolean flag) {
  +        this.verbose = flag;
  +    }
  +
  +    public void setFullsemanticize(boolean flag) {
  +        this.fullsemanticize = flag;
  +    }
  +
  +    /** one or more path for rules that must be placed before metamata.jar 
!! */
  +    public Path createRulespath() {
  +        if (rulesPath == null) {
  +            rulesPath = new Path(getProject());
  +        }
  +        return rulesPath;
  +    }
  +
  +    /** search path to use for unused global declarations */
  +    public Path createSearchpath() {
  +        if (searchPath == null) {
  +            searchPath = new Path(getProject());
           }
           return searchPath;
       }
   
  -    protected Vector getOptions(){
  +    protected Vector getOptions() {
           Vector options = new Vector(512);
  +        // add the source path automatically from the fileset.
  +        // to avoid redundancy...
  +        for (int i = 0; i < fileSets.size(); i++) {
  +            FileSet fs = (FileSet) fileSets.elementAt(i);
  +            Path path = createSourcepath();
  +            File dir = fs.getDir(getProject());
  +            path.setLocation(dir);
  +        }
  +
           // there is a bug in Metamata 2.0 build 37. The sourcepath argument 
does
           // not work. So we will use the sourcepath prepended to classpath. 
(order
           // is important since Metamata looks at .class and .java)
  -        if (sourcePath != null){
  +        if (sourcePath != null) {
               sourcePath.append(classPath); // srcpath is prepended
               classPath = sourcePath;
               sourcePath = null; // prevent from using -sourcepath
  -        }        
  -        
  +        }
  +
           // don't forget to modify the pattern if you change the options 
reporting
  -        if (classPath != null){
  +        if (classPath != null) {
               options.addElement("-classpath");
               options.addElement(classPath.toString());
           }
           // suppress copyright msg when running, we will let it so that this
           // will be the only output to the console if in xml mode
  -//      options.addElement("-quiet");
  -        if (fix){
  +        if (quiet) {
  +            options.addElement("-quiet");
  +        }
  +        if (fullsemanticize) {
  +            options.addElement("-full-semanticize");
  +        }
  +        if (verbose) {
  +            options.addElement("-verbose");
  +        }
  +        if (offsets) {
  +            options.addElement("-offsets");
  +        }
  +        if (exit) {
  +            options.addElement("-exit");
  +        }
  +        if (fix) {
               options.addElement("-fix");
           }
           options.addElement("-fullpath");
  @@ -185,43 +244,45 @@
           // generate .maudit files much more detailed than the report
           // I don't like it very much, I think it could be interesting
           // to get all .maudit files and include them in the XML.
  -        if (list){
  +        if (list) {
               options.addElement("-list");
           }
  -        if (sourcePath != null){
  +        if (sourcePath != null) {
               options.addElement("-sourcepath");
               options.addElement(sourcePath.toString());
           }
  -        
  -        if (unused){
  +        addAllVector(options, includedFiles.keys());
  +        if (unused) {
               options.addElement("-unused");
               options.addElement(searchPath.toString());
           }
  -        addAllVector(options, includedFiles.keys());
           return options;
       }
   
       protected void checkOptions() throws BuildException {
           super.checkOptions();
  -        if (unused && searchPath == null){
  +        if (unused && searchPath == null) {
               throw new BuildException("'searchpath' element must be set when 
looking for 'unused' declarations.");
           }
  -        if (!unused && searchPath != null){
  +        if (!unused && searchPath != null) {
               log("'searchpath' element ignored. 'unused' attribute is 
disabled.", Project.MSG_WARN);
           }
  +        if (rulesPath != null) {
  +            cmdl.createClasspath(getProject()).addExisting(rulesPath);
  +        }
       }
  -    
  +
       protected ExecuteStreamHandler createStreamHandler() throws 
BuildException {
           ExecuteStreamHandler handler = null;
           // if we didn't specify a file, then use a screen report
  -        if (outFile == null){
  -           handler = new LogStreamHandler(this, Project.MSG_INFO, 
Project.MSG_INFO);
  +        if (outFile == null) {
  +            handler = new LogStreamHandler(this, Project.MSG_INFO, 
Project.MSG_INFO);
           } else {
               try {
                   //XXX
  -                OutputStream out = new FileOutputStream( outFile );
  +                OutputStream out = new FileOutputStream(outFile);
                   handler = new MAuditStreamHandler(this, out);
  -            } catch (IOException e){
  +            } catch (IOException e) {
                   throw new BuildException(e);
               }
           }
  @@ -242,18 +303,9 @@
   
       /** the inner class used to report violation information */
       final static class Violation {
  -        int line;
  +        String line;
           String error;
       }
   
  -    /** handy factory to create a violation */
  -    static final Violation createViolation(int line, String msg){
  -        Violation violation = new Violation();
  -        violation.line = line;
  -        violation.error = msg;
  -        return violation;
  -    }
  -
   }
  -
   
  
  
  
  1.6       +95 -82    
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java
  
  Index: MMetricsStreamHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- MMetricsStreamHandler.java        10 Jan 2002 13:59:37 -0000      1.5
  +++ MMetricsStreamHandler.java        8 Feb 2002 22:06:56 -0000       1.6
  @@ -54,32 +54,36 @@
   package org.apache.tools.ant.taskdefs.optional.metamata;
   
   
  -import org.xml.sax.SAXException;
  -import org.xml.sax.Attributes;
  -import org.xml.sax.helpers.AttributesImpl;
  -import javax.xml.transform.TransformerFactory;
  -import javax.xml.transform.Transformer;
  -import javax.xml.transform.OutputKeys;
  -import javax.xml.transform.stream.StreamResult;
  -import javax.xml.transform.sax.TransformerHandler;
  -import javax.xml.transform.sax.SAXTransformerFactory;
  -import java.util.Stack;
  -import java.util.EmptyStackException;
  -import java.util.Enumeration;
  -import java.util.Vector;
  +import java.io.BufferedReader;
  +import java.io.IOException;
   import java.io.InputStream;
  +import java.io.InputStreamReader;
   import java.io.OutputStream;
  -import java.io.IOException;
   import java.io.OutputStreamWriter;
  -import java.io.BufferedReader;
  -import java.io.InputStreamReader;
  -import java.text.ParseException;
  -import java.text.NumberFormat;
   import java.text.DecimalFormat;
  +import java.text.NumberFormat;
  +import java.text.ParseException;
  +import java.util.Date;
  +import java.util.EmptyStackException;
  +import java.util.Enumeration;
  +import java.util.Stack;
  +import java.util.Vector;
  +import javax.xml.transform.OutputKeys;
  +import javax.xml.transform.Transformer;
  +import javax.xml.transform.TransformerFactory;
  +import javax.xml.transform.sax.SAXTransformerFactory;
  +import javax.xml.transform.sax.TransformerHandler;
  +import javax.xml.transform.stream.StreamResult;
   
  -import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
  -import org.apache.tools.ant.Task;
  +import org.xml.sax.Attributes;
  +import org.xml.sax.SAXException;
  +import org.xml.sax.helpers.AttributesImpl;
  +
  +import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.Task;
  +import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
  +import org.apache.tools.ant.util.DateUtils;
   
   /**
    * A handy metrics handler. Most of this code was done only with the
  @@ -95,44 +99,44 @@
   public class MMetricsStreamHandler implements ExecuteStreamHandler {
   
       /** CLASS construct, it should be named something like 'MyClass' */
  -    protected final static String CLASS = "class";
  +    private final static String CLASS = "class";
   
       /** package construct, it should be look like 'com.mycompany.something' 
*/
  -    protected final static String PACKAGE = "package";
  +    private final static String PACKAGE = "package";
   
       /** FILE construct, it should look like something 'MyClass.java' or 
'MyClass.class' */
  -    protected final static String FILE = "file";
  +    private final static String FILE = "file";
   
       /** METHOD construct, it should looke like something 'doSomething(...)' 
or 'doSomething()' */
  -    protected final static String METHOD = "method";
  +    private final static String METHOD = "method";
   
  -    protected final static String[] ATTRIBUTES = { "name", "vg", "loc",
  -    "dit", "noa", "nrm", "nlm", "wmc", "rfc", "dac", "fanout", "cbo", 
"lcom", "nocl"
  -    };
  +    private final static String[] ATTRIBUTES = {
  +        "name", "vg", "loc", "dit", "noa", "nrm", "nlm", "wmc",
  +        "rfc", "dac", "fanout", "cbo", "lcom", "nocl"};
   
       /** reader for stdout */
  -    protected InputStream metricsOutput;
  +    private InputStream metricsOutput;
   
       /**
        * this is where the XML output will go, should mostly be a file
        * the caller is responsible for flushing and closing this stream
        */
  -    protected OutputStream xmlOutputStream;
  +    private OutputStream xmlOutputStream;
   
       /** metrics handler */
  -    protected TransformerHandler metricsHandler;
  +    private TransformerHandler metricsHandler;
   
       /** the task */
  -    protected Task task;
  +    private Task task;
   
       /**
        * the stack where are stored the metrics element so that they we can
        * know if we have to close an element or not.
        */
  -    protected Stack stack = new Stack();
  +    private Stack stack = new Stack();
   
       /** initialize this handler */
  -    MMetricsStreamHandler(Task task, OutputStream xmlOut){
  +    MMetricsStreamHandler(Task task, OutputStream xmlOut) {
           this.task = task;
           this.xmlOutputStream = xmlOut;
       }
  @@ -147,34 +151,39 @@
   
       /** Set the inputstream */
       public void setProcessOutputStream(InputStream is) throws IOException {
  -            metricsOutput = is;
  +        metricsOutput = is;
       }
   
       public void start() throws IOException {
           // create the transformer handler that will be used to serialize
           // the output.
           TransformerFactory factory = TransformerFactory.newInstance();
  -        if ( !factory.getFeature(SAXTransformerFactory.FEATURE) ){
  +        if (!factory.getFeature(SAXTransformerFactory.FEATURE)) {
               throw new IllegalStateException("Invalid Transformer factory 
feature");
           }
           try {
  -            metricsHandler = 
((SAXTransformerFactory)factory).newTransformerHandler();
  -            metricsHandler.setResult( new StreamResult( new 
OutputStreamWriter(xmlOutputStream, "UTF-8")) );
  +            metricsHandler = ((SAXTransformerFactory) 
factory).newTransformerHandler();
  +            metricsHandler.setResult(new StreamResult(new 
OutputStreamWriter(xmlOutputStream, "UTF-8")));
               Transformer transformer = metricsHandler.getTransformer();
               transformer.setOutputProperty(OutputKeys.INDENT, "yes");
   
               // start the document with a 'metrics' root
  +            final Date now = new Date();
               metricsHandler.startDocument();
               AttributesImpl attr = new AttributesImpl();
               attr.addAttribute("", "company", "company", "CDATA", "metamata");
  +            attr.addAttribute("", "snapshot_created", "snapshot_created", 
"CDATA",
  +                    DateUtils.format(now, 
DateUtils.ISO8601_DATETIME_PATTERN));
  +//            attr.addAttribute("", "elapsed_time", "elapsed_time", "CDATA", 
String.valueOf(now.getTime() - program_start.getTime()));
  +            attr.addAttribute("", "program_start", "program_start", "CDATA",
  +                    DateUtils.format(new Date(), 
DateUtils.ISO8601_DATETIME_PATTERN));
               metricsHandler.startElement("", "metrics", "metrics", attr);
   
               // now parse the whole thing
               parseOutput();
   
  -        } catch (Exception e){
  -            e.printStackTrace();
  -            throw new IOException(e.getMessage());
  +        } catch (Exception e) {
  +            throw new BuildException(e);
           }
       }
   
  @@ -185,15 +194,15 @@
           try {
               // we need to pop everything and close elements that have not 
been
               // closed yet.
  -            while ( stack.size() > 0){
  -                ElementEntry elem = (ElementEntry)stack.pop();
  +            while (stack.size() > 0) {
  +                ElementEntry elem = (ElementEntry) stack.pop();
                   metricsHandler.endElement("", elem.getType(), 
elem.getType());
               }
               // close the root
               metricsHandler.endElement("", "metrics", "metrics");
               // document is finished for good
               metricsHandler.endDocument();
  -        } catch (SAXException e){
  +        } catch (SAXException e) {
               e.printStackTrace();
               throw new IllegalStateException(e.getMessage());
           }
  @@ -203,7 +212,7 @@
       protected void parseOutput() throws IOException, SAXException {
           BufferedReader br = new BufferedReader(new 
InputStreamReader(metricsOutput));
           String line = null;
  -        while ( (line = br.readLine()) != null ){
  +        while ((line = br.readLine()) != null) {
               processLine(line);
           }
       }
  @@ -214,16 +223,16 @@
        * @param line the line to process, it is normally a line full of 
metrics.
        */
       protected void processLine(String line) throws SAXException {
  -        if ( 
line.startsWith("Construct\tV(G)\tLOC\tDIT\tNOA\tNRM\tNLM\tWMC\tRFC\tDAC\tFANOUT\tCBO\tLCOM\tNOCL")
 ){
  +        if 
(line.startsWith("Construct\tV(G)\tLOC\tDIT\tNOA\tNRM\tNLM\tWMC\tRFC\tDAC\tFANOUT\tCBO\tLCOM\tNOCL"))
 {
               return;
           }
           try {
               MetricsElement elem = MetricsElement.parse(line);
               startElement(elem);
           } catch (ParseException e) {
  -            e.printStackTrace();
  +            //e.printStackTrace();
               // invalid lines are sent to the output as information, it might 
be anything,
  -           task.log(line, Project.MSG_INFO);
  +            task.log(line, Project.MSG_INFO);
           }
       }
   
  @@ -238,16 +247,17 @@
           // if there are elements in the stack we possibly need to close one 
or
           // more elements previous to this one until we got its parent
           int indent = elem.getIndent();
  -        if ( stack.size() > 0 ){
  -            ElementEntry previous = (ElementEntry)stack.peek();
  +        if (stack.size() > 0) {
  +            ElementEntry previous = (ElementEntry) stack.peek();
               // close nodes until you got the parent.
               try {
  -                while ( indent <= previous.getIndent() && stack.size() > 0){
  +                while (indent <= previous.getIndent() && stack.size() > 0) {
                       stack.pop();
                       metricsHandler.endElement("", previous.getType(), 
previous.getType());
  -                        previous = (ElementEntry)stack.peek();
  +                    previous = (ElementEntry) stack.peek();
                   }
  -            } catch (EmptyStackException ignored){}
  +            } catch (EmptyStackException ignored) {
  +            }
           }
   
           // ok, now start the new construct
  @@ -256,7 +266,7 @@
           metricsHandler.startElement("", type, type, attrs);
   
           // make sure we keep track of what we did, that's history
  -        stack.push( new ElementEntry(type, indent) );
  +        stack.push(new ElementEntry(type, indent));
       }
   
       /**
  @@ -267,36 +277,36 @@
        * @return the type of the metrics element, either PACKAGE, FILE, CLASS 
or
        * METHOD.
        */
  -    protected String getConstructType(MetricsElement elem){
  +    protected String getConstructType(MetricsElement elem) {
           // ok no doubt, it's a file
  -        if ( elem.isCompilationUnit() ){
  +        if (elem.isCompilationUnit()) {
               return FILE;
           }
   
           // same, we're sure it's a method
  -        if ( elem.isMethod() ){
  +        if (elem.isMethod()) {
               return METHOD;
           }
   
           // if it's empty, and none of the above it should be a package
  -        if ( stack.size() == 0 ){
  +        if (stack.size() == 0) {
               return PACKAGE;
           }
   
           // ok, this is now black magic time, we will guess the type based on
           // the previous type and its indent...
  -        final ElementEntry previous = (ElementEntry)stack.peek();
  +        final ElementEntry previous = (ElementEntry) stack.peek();
           final String prevType = previous.getType();
           final int prevIndent = previous.getIndent();
           final int indent = elem.getIndent();
           // we're just under a file with a bigger indent so it's a class
  -        if ( prevType.equals(FILE) && indent > prevIndent ){
  +        if (prevType.equals(FILE) && indent > prevIndent) {
               return CLASS;
           }
   
           // we're just under a class with a greater or equals indent, it's a 
class
           // (there might be several classes in a compilation unit and inner 
classes as well)
  -        if ( prevType.equals(CLASS) && indent >= prevIndent ){
  +        if (prevType.equals(CLASS) && indent >= prevIndent) {
               return CLASS;
           }
   
  @@ -308,17 +318,16 @@
       /**
        * Create all attributes of a MetricsElement skipping those who have an
        * empty string
  -     * @param   elem
        */
  -    protected Attributes createAttributes(MetricsElement elem){
  +    protected Attributes createAttributes(MetricsElement elem) {
           AttributesImpl impl = new AttributesImpl();
           int i = 0;
           String name = ATTRIBUTES[i++];
           impl.addAttribute("", name, name, "CDATA", elem.getName());
           Enumeration metrics = elem.getMetrics();
  -        for (; metrics.hasMoreElements(); i++){
  -            String value = (String)metrics.nextElement();
  -            if ( value.length() > 0 ){
  +        for (; metrics.hasMoreElements(); i++) {
  +            String value = (String) metrics.nextElement();
  +            if (value.length() > 0) {
                   name = ATTRIBUTES[i];
                   impl.addAttribute("", name, name, "CDATA", value);
               }
  @@ -333,13 +342,16 @@
       private final static class ElementEntry {
           private String type;
           private int indent;
  -        ElementEntry(String type, int indent){
  +
  +        ElementEntry(String type, int indent) {
               this.type = type;
               this.indent = indent;
           }
  -        public String getType(){
  +
  +        public String getType() {
               return type;
           }
  +
           public int getIndent() {
               return indent;
           }
  @@ -351,6 +363,7 @@
       private final static NumberFormat METAMATA_NF;
   
       private final static NumberFormat NEUTRAL_NF;
  +
       static {
           METAMATA_NF = NumberFormat.getInstance();
           METAMATA_NF.setMaximumFractionDigits(1);
  @@ -367,30 +380,30 @@
   
       private Vector metrics;
   
  -    MetricsElement(int indent, String construct, Vector metrics){
  +    MetricsElement(int indent, String construct, Vector metrics) {
           this.indent = indent;
           this.construct = construct;
           this.metrics = metrics;
       }
   
  -    public int getIndent(){
  +    public int getIndent() {
           return indent;
       }
   
  -    public String getName(){
  +    public String getName() {
           return construct;
       }
   
  -    public Enumeration getMetrics(){
  +    public Enumeration getMetrics() {
           return metrics.elements();
       }
   
  -    public boolean isCompilationUnit(){
  -        return ( construct.endsWith(".java") || construct.endsWith(".class") 
);
  +    public boolean isCompilationUnit() {
  +        return (construct.endsWith(".java") || construct.endsWith(".class"));
       }
   
  -    public boolean isMethod(){
  -        return ( construct.endsWith("(...)") || construct.endsWith("()") );
  +    public boolean isMethod() {
  +        return (construct.endsWith("(...)") || construct.endsWith("()"));
       }
   
       public static MetricsElement parse(String line) throws ParseException {
  @@ -399,32 +412,32 @@
   
           // i'm using indexOf since I need to know if there are empty strings
           // between tabs and I find it easier than with StringTokenizer
  -        while ( (pos = line.indexOf('\t')) != -1 ){
  +        while ((pos = line.indexOf('\t')) != -1) {
               String token = line.substring(0, pos);
               // only parse what coudl be a valid number. ie not constructs 
nor no value
               /*if (metrics.size() != 0 || token.length() != 0){
                   Number num = METAMATA_NF.parse(token); // parse with 
Metamata NF
                   token = NEUTRAL_NF.format(num.doubleValue()); // and format 
with a neutral NF
               }*/
  -            metrics.addElement( token );
  +            metrics.addElement(token);
               line = line.substring(pos + 1);
           }
  -        metrics.addElement( line );
  +        metrics.addElement(line);
   
           // there should be exactly 14 tokens (1 name + 13 metrics), if not, 
there is a problem !
  -        if ( metrics.size() != 14 ){
  -            throw new ParseException("Could not parse the following line as 
a metrics: -->" + line +"<--", -1);
  +        if (metrics.size() != 14) {
  +            throw new ParseException("Could not parse the following line as 
a metrics: -->" + line + "<--", -1);
           }
   
           // remove the first token it's made of the indentation string and the
           // construct name, we'll need all this to figure out what type of
           // construct it is since we lost all semantics :(
           // (#indent[/]*)(#construct.*)
  -        String name = (String)metrics.elementAt(0);
  +        String name = (String) metrics.elementAt(0);
           metrics.removeElementAt(0);
           int indent = 0;
           pos = name.lastIndexOf('/');
  -        if (pos != -1){
  +        if (pos != -1) {
               name = name.substring(pos + 1);
               indent = pos + 1; // indentation is last position of token + 1
           }
  
  
  
  1.4       +62 -56    
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java
  
  Index: MMetrics.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MMetrics.java     10 Jan 2002 13:59:37 -0000      1.3
  +++ MMetrics.java     8 Feb 2002 22:06:56 -0000       1.4
  @@ -53,21 +53,19 @@
    */
   package org.apache.tools.ant.taskdefs.optional.metamata;
   
  +import java.io.File;
  +import java.io.FileInputStream;
  +import java.io.FileOutputStream;
  +import java.io.IOException;
  +import java.util.Vector;
  +
   import org.apache.tools.ant.BuildException;
   import org.apache.tools.ant.Project;
  -
   import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
   import org.apache.tools.ant.taskdefs.LogStreamHandler;
  +import org.apache.tools.ant.types.EnumeratedAttribute;
   import org.apache.tools.ant.types.Path;
   
  -
  -
  -import java.io.File;
  -import java.io.FileInputStream;
  -import java.io.IOException;
  -import java.io.FileOutputStream;
  -import java.util.Vector;
  -
   /**
    * Calculates global complexity and quality metrics on Java source code.
    *
  @@ -114,15 +112,15 @@
   */
   
       /** the granularity mode. Should be one of 'files', 'methods' and 
'types'. */
  -    protected String granularity = null;
  +    private String granularity = null;
   
       /** the XML output file */
  -    protected File outFile = null;
  -    
  +    private File outFile = null;
  +
       /** the location of the temporary txt report */
  -    protected File tmpFile = createTmpFile();
  +    private File tmpFile;
   
  -    protected Path path = null;
  +    private Path path = null;
   
       //--------------------------- PUBLIC METHODS 
-------------------------------
   
  @@ -132,19 +130,28 @@
       }
   
       /**
  +     * Attributes for granularity.
  +     */
  +    public static class GranularityAttribute extends EnumeratedAttribute {
  +        public String[] getValues() {
  +            return new String[]{"compilation-units", "files", "methods", 
"types", "packages"};
  +        }
  +    }
  +
  +    /**
        * set the granularity of the audit. Should be one of 'files', 'methods'
        * or 'types'.
        * @param granularity   the audit reporting mode.
        */
  -    public void setGranularity(String granularity){
  -        this.granularity = granularity;
  +    public void setGranularity(GranularityAttribute granularity) {
  +        this.granularity = granularity.getValue();
       }
   
       /**
        * Set the output XML file
        * @param file the xml file to write the XML report to.
        */
  -    public void setTofile(File file){
  +    public void setTofile(File file) {
           this.outFile = file;
       }
   
  @@ -152,7 +159,7 @@
        * Set a new path (directory) to measure metrics from.
        * @return the path instance to use.
        */
  -    public Path createPath(){
  +    public Path createPath() {
           if (path == null) {
               path = new Path(project);
           }
  @@ -167,27 +174,24 @@
       protected void checkOptions() throws BuildException {
           super.checkOptions();
   
  -        if ( !"files".equals(granularity) && !"methods".equals(granularity)
  -           && !"types".equals(granularity) ){
  -            throw new BuildException("Metrics reporting granularity is 
invalid. Must be one of 'files', 'methods', 'types'");
  -        }
  -        if (outFile == null){
  +        if (outFile == null) {
               throw new BuildException("Output XML file must be set via 
'tofile' attribute.");
           }
  -        if (path == null && fileSets.size() == 0){
  +        if (path == null && fileSets.size() == 0) {
               throw new BuildException("Must set either paths (path element) 
or files (fileset element)");
           }
           // I don't accept dirs and files at the same time, I cannot 
recognize the semantic in the result
  -        if (path != null && fileSets.size() > 0){
  +        if (path != null && fileSets.size() > 0) {
               throw new BuildException("Cannot set paths (path element) and 
files (fileset element) at the same time");
           }
  +        tmpFile = createTmpFile();
       }
   
       protected void execute0(ExecuteStreamHandler handler) throws 
BuildException {
           super.execute0(handler);
           transformFile();
       }
  -    
  +
       /**
        * transform the generated file via the handler
        * This function can either be called if the result is written to the 
output
  @@ -197,8 +201,8 @@
       protected void transformFile() throws BuildException {
           FileInputStream tmpStream = null;
           try {
  -            tmpStream = new FileInputStream( tmpFile );
  -        } catch (IOException e){
  +            tmpStream = new FileInputStream(tmpFile);
  +        } catch (IOException e) {
               throw new BuildException("Error reading temporary file: " + 
tmpFile, e);
           }
           FileOutputStream xmlStream = null;
  @@ -208,29 +212,31 @@
               xmlHandler.setProcessOutputStream(tmpStream);
               xmlHandler.start();
               xmlHandler.stop();
  -        } catch (IOException e){
  +        } catch (IOException e) {
               throw new BuildException("Error creating output file: " + 
outFile, e);
           } finally {
  -            if (xmlStream != null){
  +            if (xmlStream != null) {
                   try {
                       xmlStream.close();
  -                } catch (IOException ignored){}
  +                } catch (IOException ignored) {
  +                }
               }
  -            if (tmpStream != null){
  +            if (tmpStream != null) {
                   try {
                       tmpStream.close();
  -                } catch (IOException ignored){}
  +                } catch (IOException ignored) {
  +                }
               }
           }
       }
  -    
  +
   
       /** cleanup the temporary txt report */
       protected void cleanUp() throws BuildException {
           try {
               super.cleanUp();
           } finally {
  -            if (tmpFile != null){
  +            if (tmpFile != null) {
                   tmpFile.delete();
                   tmpFile = null;
               }
  @@ -242,52 +248,52 @@
        * a normal logger here, otherwise we could use the metrics handler
        * directly to capture and transform the output on stdout to XML.
        */
  -    protected ExecuteStreamHandler createStreamHandler(){
  +    protected ExecuteStreamHandler createStreamHandler() {
           // write the report directtly to an XML stream
           // return new MMetricsStreamHandler(this, xmlStream);
           return new LogStreamHandler(this, Project.MSG_INFO, 
Project.MSG_INFO);
       }
   
   
  -    protected Vector getOptions(){
  +    protected Vector getOptions() {
           Vector options = new Vector(512);
           // there is a bug in Metamata 2.0 build 37. The sourcepath argument 
does
           // not work. So we will use the sourcepath prepended to classpath. 
(order
           // is important since Metamata looks at .class and .java)
  -        if (sourcePath != null){
  +        if (sourcePath != null) {
               sourcePath.append(classPath); // srcpath is prepended
               classPath = sourcePath;
               sourcePath = null; // prevent from using -sourcepath
           }
  -                
  +
           // don't forget to modify the pattern if you change the options 
reporting
  -        if (classPath != null){
  +        if (classPath != null) {
               options.addElement("-classpath");
  -            options.addElement(classPath);
  +            options.addElement(classPath.toString());
           }
  -        options.addElement( "-output" );
  -        options.addElement( tmpFile.toString() );
  -        
  -        options.addElement( "-" + granularity);
  -        
  +        options.addElement("-output");
  +        options.addElement(tmpFile.toString());
  +
  +        options.addElement("-" + granularity);
  +
           // display the metamata copyright
           // options.addElement( "-quiet");
  -        options.addElement( "-format");
  -        
  +        options.addElement("-format");
  +
           // need this because that's what the handler is using, it's
           // way easier to process than any other separator
  -        options.addElement( "tab");
  -        
  +        options.addElement("tab");
  +
           // specify a / as the indent character, used by the handler.
  -        options.addElement( "-i");
  -        options.addElement( "/");
  -        
  +        options.addElement("-i");
  +        options.addElement("/");
  +
           // directories
           String[] dirs = path.list();
  -        for (int i = 0; i < dirs.length; i++){
  -            options.addElement( dirs[i] );
  +        for (int i = 0; i < dirs.length; i++) {
  +            options.addElement(dirs[i]);
           }
  -        // files next. 
  +        // files next.
           addAllVector(options, includedFiles.keys());
           return options;
       }
  
  
  
  1.4       +115 -69   
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java
  
  Index: MAuditStreamHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MAuditStreamHandler.java  10 Jan 2002 13:59:37 -0000      1.3
  +++ MAuditStreamHandler.java  8 Feb 2002 22:06:56 -0000       1.4
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2001 The Apache Software Foundation.  All rights
  + * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -53,31 +53,34 @@
    */
   package org.apache.tools.ant.taskdefs.optional.metamata;
   
  -import org.apache.tools.ant.Project;
  -
  -import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
  -
  -import org.apache.tools.ant.util.regexp.RegexpMatcher;
  -import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
  -
  -import org.apache.tools.ant.util.DOMElementWriter;
  -
  -import org.w3c.dom.Document;
  -import org.w3c.dom.Element;
  -
   import java.io.BufferedReader;
  -import java.io.OutputStream;
  -import java.io.InputStream;
  +import java.io.File;
   import java.io.IOException;
  +import java.io.InputStream;
   import java.io.InputStreamReader;
  -import java.io.Writer;
  +import java.io.OutputStream;
   import java.io.OutputStreamWriter;
  -import java.util.Hashtable;
  +import java.io.Writer;
  +import java.util.Date;
   import java.util.Enumeration;
  +import java.util.Hashtable;
   import java.util.Vector;
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
   
  +import org.w3c.dom.Document;
  +import org.w3c.dom.Element;
  +
  +import org.apache.tools.ant.Project;
  +import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
  +import org.apache.tools.ant.taskdefs.LogOutputStream;
  +import org.apache.tools.ant.taskdefs.StreamPumper;
  +import org.apache.tools.ant.util.DOMElementWriter;
  +import org.apache.tools.ant.util.DateUtils;
  +import org.apache.tools.ant.util.StringUtils;
  +import org.apache.tools.ant.util.regexp.RegexpMatcher;
  +import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
  +
   
   /**
    * This is a very bad stream handler for the MAudit task.
  @@ -93,31 +96,41 @@
    * <li>it does not report error that goes to stderr.
    * </ul>
    *
  - * @author <a href="[EMAIL PROTECTED]">Stephane Bailliez</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
   class MAuditStreamHandler implements ExecuteStreamHandler {
   
  -    protected MAudit task;
  +    /** parent task */
  +    private MAudit task;
   
       /** reader for stdout */
  -    protected BufferedReader br;
  +    private BufferedReader br;
   
       /** matcher that will be used to extract the info from the line */
  -    protected RegexpMatcher matcher;
  +    private RegexpMatcher matcher;
   
       /**
        * this is where the XML output will go, should mostly be a file
        * the caller is responsible for flushing and closing this stream
        */
  -    protected OutputStream xmlOut = null;
  +    private OutputStream xmlOut = null;
  +
  +    /** error stream, might be useful to spit out error messages */
  +    private OutputStream errStream;
  +
  +    /** thread pumping out error stream */
  +    private Thread errThread;
   
       /**
        * the multimap. The key in the map is the filepath that caused the audit
        * error and the value is a vector of MAudit.Violation entries.
        */
  -    protected Hashtable auditedFiles = new Hashtable();
  +    private Hashtable auditedFiles = new Hashtable();
   
  -    MAuditStreamHandler(MAudit task, OutputStream xmlOut){
  +    /** program start timestamp for reporting purpose */
  +    private Date program_start;
  +
  +    MAuditStreamHandler(MAudit task, OutputStream xmlOut) {
           this.task = task;
           this.xmlOut = xmlOut;
           /** the matcher should be the Oro one. I don't know about the other 
one */
  @@ -126,10 +139,14 @@
       }
   
       /** Ignore. */
  -    public void setProcessInputStream(OutputStream os) {}
  +    public void setProcessInputStream(OutputStream os) {
  +    }
   
       /** Ignore. */
  -    public void setProcessErrorStream(InputStream is) {}
  +    public void setProcessErrorStream(InputStream is) {
  +        errStream = new LogOutputStream(task, Project.MSG_ERR);
  +        errThread = createPump(is, errStream);
  +    }
   
       /** Set the inputstream */
       public void setProcessOutputStream(InputStream is) throws IOException {
  @@ -138,6 +155,8 @@
   
       /** Invokes parseOutput. This will block until the end :-(*/
       public void start() throws IOException {
  +        program_start = new Date();
  +        errThread.start();
           parseOutput(br);
       }
   
  @@ -146,19 +165,32 @@
        * the MAudit output and write it to the output.
        */
       public void stop() {
  +        // make sure to flush err stream
  +        try {
  +            errThread.join();
  +        } catch (InterruptedException e) {
  +        }
  +        try {
  +            errStream.flush();
  +        } catch (IOException e) {
  +        }
           // serialize the content as XML, move this to another method
  -        // this is the only code that could be needed to be overrided
  +        // this is the only code that could be needed to be overriden
           Document doc = getDocumentBuilder().newDocument();
           Element rootElement = doc.createElement("classes");
           Enumeration keys = auditedFiles.keys();
           Hashtable filemapping = task.getFileMapping();
  +        final Date now = new Date();
  +        rootElement.setAttribute("snapshot_created", DateUtils.format(now, 
DateUtils.ISO8601_DATETIME_PATTERN));
  +        rootElement.setAttribute("elapsed_time", 
String.valueOf(now.getTime() - program_start.getTime()));
  +        rootElement.setAttribute("program_start", DateUtils.format(now, 
DateUtils.ISO8601_DATETIME_PATTERN));
           rootElement.setAttribute("audited", 
String.valueOf(filemapping.size()));
           rootElement.setAttribute("reported", 
String.valueOf(auditedFiles.size()));
           int errors = 0;
  -        while (keys.hasMoreElements()){
  -            String filepath = (String)keys.nextElement();
  -            Vector v = (Vector)auditedFiles.get(filepath);
  -            String fullclassname = (String)filemapping.get(filepath);
  +        while (keys.hasMoreElements()) {
  +            String filepath = (String) keys.nextElement();
  +            Vector v = (Vector) auditedFiles.get(filepath);
  +            String fullclassname = (String) filemapping.get(filepath);
               if (fullclassname == null) {
                   task.getProject().log("Could not find class mapping for " + 
filepath, Project.MSG_WARN);
                   continue;
  @@ -169,12 +201,13 @@
               Element clazz = doc.createElement("class");
               clazz.setAttribute("package", pkg);
               clazz.setAttribute("name", clazzname);
  -            clazz.setAttribute("violations", String.valueOf(v.size()));
  -            errors += v.size();
  -            for (int i = 0; i < v.size(); i++){
  -                MAudit.Violation violation = 
(MAudit.Violation)v.elementAt(i);
  +            final int violationCount = v.size();
  +            clazz.setAttribute("violations", String.valueOf(violationCount));
  +            errors += violationCount;
  +            for (int i = 0; i < violationCount; i++) {
  +                MAudit.Violation violation = (MAudit.Violation) 
v.elementAt(i);
                   Element error = doc.createElement("violation");
  -                error.setAttribute("line", String.valueOf(violation.line));
  +                error.setAttribute("line", violation.line);
                   error.setAttribute("message", violation.error);
                   clazz.appendChild(error);
               }
  @@ -183,54 +216,67 @@
           rootElement.setAttribute("violations", String.valueOf(errors));
   
           // now write it to the outputstream, not very nice code
  -        if (xmlOut != null) {
  -            Writer wri = null;
  -            try {
  -                wri = new OutputStreamWriter(xmlOut, "UTF-8");
  -                wri.write("<?xml version=\"1.0\"?>\n");
  -                (new DOMElementWriter()).write(rootElement, wri, 0, "  ");
  -                wri.flush();
  -            } catch(IOException exc) {
  -                task.log("Unable to write log file", Project.MSG_ERR);
  -            } finally {
  -                if (xmlOut != System.out && xmlOut != System.err) {
  -                    if (wri != null) {
  -                        try {
  -                            wri.close();
  -                        } catch (IOException e) {}
  -                    }
  +        Writer wri = null;
  +        try {
  +            wri = new OutputStreamWriter(xmlOut, "UTF-8");
  +            wri.write("<?xml version=\"1.0\"?>\n");
  +            (new DOMElementWriter()).write(rootElement, wri, 0, "  ");
  +            wri.flush();
  +        } catch (IOException exc) {
  +            task.log("Unable to write log file", Project.MSG_ERR);
  +        } finally {
  +            if (wri != null) {
  +                try {
  +                    wri.close();
  +                } catch (IOException e) {
                   }
               }
           }
  -
       }
   
       protected static DocumentBuilder getDocumentBuilder() {
           try {
               return DocumentBuilderFactory.newInstance().newDocumentBuilder();
  -        }
  -        catch(Exception exc) {
  +        } catch (Exception exc) {
               throw new ExceptionInInitializerError(exc);
           }
       }
   
  +    /**
  +     * Creates a stream pumper to copy the given input stream to the given 
output stream.
  +     */
  +    protected Thread createPump(InputStream is, OutputStream os) {
  +        final Thread result = new Thread(new StreamPumper(is, os));
  +        result.setDaemon(true);
  +        return result;
  +    }
  +
  +
       /** read each line and process it */
       protected void parseOutput(BufferedReader br) throws IOException {
           String line = null;
  -        while ( (line = br.readLine()) != null ){
  +        while ((line = br.readLine()) != null) {
               processLine(line);
           }
       }
   
       // we suppose here that there is only one report / line.
       // There will obviouslly be a problem if the message is on several 
lines...
  -    protected void processLine(String line){
  +    protected void processLine(String line) {
           Vector matches = matcher.getGroups(line);
           if (matches != null) {
  -            String file = (String)matches.elementAt(1);
  -            int lineNum = Integer.parseInt((String)matches.elementAt(2));
  -            String msg = (String)matches.elementAt(3);
  -            addViolationEntry(file, MAudit.createViolation(lineNum, msg) );
  +            String file = (String) matches.elementAt(1);
  +            MAudit.Violation violation = new MAudit.Violation();
  +            violation.line = (String) matches.elementAt(2);
  +            violation.error = (String) matches.elementAt(3);
  +            // remove the pathname from any messages and let the classname 
only.
  +            final int pos = file.lastIndexOf(File.separatorChar);
  +            if ((pos != -1) && (pos != file.length() - 1)) {
  +                String filename = file.substring(pos + 1);
  +                violation.error = StringUtils.replace(violation.error,
  +                        "file:" + file, filename);
  +            }
  +            addViolationEntry(file, violation);
           } else {
               // this doesn't match..report it as info, it could be
               // either the copyright, summary or a multiline message (damn !)
  @@ -239,14 +285,14 @@
       }
   
       /** add a violation entry for the file */
  -    protected void addViolationEntry(String file, MAudit.Violation entry){
  -            Vector violations = (Vector)auditedFiles.get(file);
  -            // if there is no decl for this file yet, create it.
  -            if (violations == null){
  -                violations = new Vector();
  -                auditedFiles.put(file, violations);
  -            }
  -            violations.add( entry );
  +    protected void addViolationEntry(String file, MAudit.Violation entry) {
  +        Vector violations = (Vector) auditedFiles.get(file);
  +        // if there is no decl for this file yet, create it.
  +        if (violations == null) {
  +            violations = new Vector();
  +            auditedFiles.put(file, violations);
  +        }
  +        violations.addElement(entry);
       }
   
   }
  
  
  
  1.5       +90 -60    
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java
  
  Index: AbstractMetamataTask.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractMetamataTask.java 10 Jan 2002 13:59:37 -0000      1.4
  +++ AbstractMetamataTask.java 8 Feb 2002 22:06:56 -0000       1.5
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2001 The Apache Software Foundation.  All rights
  + * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -53,25 +53,25 @@
    */
   package org.apache.tools.ant.taskdefs.optional.metamata;
   
  +import java.io.File;
  +import java.io.FileWriter;
  +import java.io.IOException;
  +import java.io.PrintWriter;
  +import java.util.Enumeration;
  +import java.util.Hashtable;
  +import java.util.Vector;
  +
   import org.apache.tools.ant.BuildException;
  +import org.apache.tools.ant.DirectoryScanner;
   import org.apache.tools.ant.Project;
   import org.apache.tools.ant.Task;
  -import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
   import org.apache.tools.ant.taskdefs.Execute;
  -import org.apache.tools.ant.types.Path;
  -import org.apache.tools.ant.types.CommandlineJava;
  +import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
   import org.apache.tools.ant.types.Commandline;
  +import org.apache.tools.ant.types.CommandlineJava;
   import org.apache.tools.ant.types.FileSet;
  -import org.apache.tools.ant.DirectoryScanner;
  -
  -import java.io.File;
  -import java.io.IOException;
  -import java.io.FileWriter;
  -import java.io.PrintWriter;
  -import java.util.Hashtable;
  -import java.util.Vector;
  -import java.util.Enumeration;
  -import java.util.Random;
  +import org.apache.tools.ant.types.Path;
  +import org.apache.tools.ant.util.FileUtils;
   
   /**
    * Somewhat abstract framework to be used for other metama 2.0 tasks.
  @@ -80,11 +80,9 @@
    * For more information, visit the website at
    * <a href="http://www.metamata.com";>www.metamata.com</a>
    *
  - * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Bailliez</a>
    */
  -public abstract class AbstractMetamataTask extends Task{
  -
  -    //--------------------------- ATTRIBUTES 
-----------------------------------
  +public abstract class AbstractMetamataTask extends Task {
   
       /**
        * The user classpath to be provided. It matches the -classpath of the
  @@ -116,7 +114,7 @@
       // be set when calling scanFileSets();
       protected Hashtable includedFiles = null;
   
  -    public AbstractMetamataTask(){
  +    public AbstractMetamataTask() {
       }
   
       /** initialize the task with the classname of the task to run */
  @@ -126,8 +124,12 @@
       }
   
       /** the metamata.home property to run all tasks. */
  -    public void setMetamatahome(final File metamataHome){
  -        this.metamataHome = metamataHome;
  +    public void setHome(final File value) {
  +        this.metamataHome = value;
  +    }
  +
  +    public void setMetamatahome(final File value) {
  +        setHome(value);
       }
   
       /** user classpath */
  @@ -139,8 +141,8 @@
       }
   
       /** create the source path for this task */
  -    public Path createSourcepath(){
  -        if (sourcePath == null){
  +    public Path createSourcepath() {
  +        if (sourcePath == null) {
               sourcePath = new Path(project);
           }
           return sourcePath;
  @@ -152,7 +154,7 @@
       }
   
       /**  -mx or -Xmx depending on VM version */
  -    public void setMaxmemory(String max){
  +    public void setMaxmemory(String max) {
           if (Project.getJavaVersion().startsWith("1.1")) {
               createJvmarg().setValue("-mx" + max);
           } else {
  @@ -177,8 +179,6 @@
           }
       }
   
  -    //--------------------- PRIVATE/PROTECTED METHODS 
--------------------------
  -
       /** check the options and build the command line */
       protected void setUp() throws BuildException {
           checkOptions();
  @@ -190,10 +190,12 @@
   
           // set the metamata.home property
           final Commandline.Argument vmArgs = cmdl.createVmArgument();
  -        vmArgs.setValue("-Dmetamata.home=" + metamataHome.getAbsolutePath() 
);
  +        vmArgs.setValue("-Dmetamata.home=" + metamataHome.getAbsolutePath());
   
           // retrieve all the files we want to scan
  -        includedFiles = scanFileSets();
  +        includedFiles = scanSources(new Hashtable());
  +        //String[] entries = sourcePath.list();
  +        //includedFiles = scanSources(new Hashtable(), entries);
           log(includedFiles.size() + " files added for audit", 
Project.MSG_VERBOSE);
   
           // write all the options to a temp file and use it ro run the process
  @@ -220,34 +222,33 @@
               if (process.execute() != 0) {
                   throw new BuildException("Metamata task failed.");
               }
  -        } catch (IOException e){
  -            throw new BuildException("Failed to launch Metamata task: " + e);
  +        } catch (IOException e) {
  +            throw new BuildException("Failed to launch Metamata task", e);
           }
       }
   
       /** clean up all the mess that we did with temporary objects */
  -    protected void cleanUp(){
  -        if (optionsFile != null){
  +    protected void cleanUp() {
  +        if (optionsFile != null) {
               optionsFile.delete();
               optionsFile = null;
           }
       }
   
       /** return the location of the jar file used to run */
  -    protected final File getMetamataJar(File home){
  -        return new File(new File(home.getAbsolutePath()), 
"lib/metamata.jar");
  +    protected final File getMetamataJar(File home) {
  +        return new File(home, "lib/metamata.jar");
       }
   
       /** validate options set */
       protected void checkOptions() throws BuildException {
           // do some validation first
  -        if (metamataHome == null || !metamataHome.exists()){
  -            throw new BuildException("'metamatahome' must point to Metamata 
home directory.");
  +        if (metamataHome == null || !metamataHome.exists()) {
  +            throw new BuildException("'home' must point to Metamata home 
directory.");
           }
  -        metamataHome = project.resolveFile(metamataHome.getPath());
           File jar = getMetamataJar(metamataHome);
  -        if (!jar.exists()){
  -            throw new BuildException( jar + " does not exist. Check your 
metamata installation.");
  +        if (!jar.exists()) {
  +            throw new BuildException(jar + " does not exist. Check your 
metamata installation.");
           }
       }
   
  @@ -261,65 +262,94 @@
               fw = new FileWriter(tofile);
               PrintWriter pw = new PrintWriter(fw);
               final int size = options.size();
  -            for (int i = 0; i < size; i++){
  -                pw.println( options.elementAt(i) );
  +            for (int i = 0; i < size; i++) {
  +                pw.println(options.elementAt(i));
               }
               pw.flush();
  -        } catch (IOException e){
  +        } catch (IOException e) {
               throw new BuildException("Error while writing options file " + 
tofile, e);
           } finally {
  -            if (fw != null){
  +            if (fw != null) {
                   try {
                       fw.close();
  -                } catch (IOException ignored){}
  +                } catch (IOException ignored) {
  +                }
               }
           }
       }
   
   
  -    protected Hashtable getFileMapping(){
  +    protected Hashtable getFileMapping() {
           return includedFiles;
       }
  +
       /**
        * convenient method for JDK 1.1. Will copy all elements from src to dest
        */
  -    protected static final void addAllVector(Vector dest, Enumeration files){
  +    protected static final void addAllVector(Vector dest, Enumeration files) 
{
           while (files.hasMoreElements()) {
  -            dest.addElement( files.nextElement() );
  +            dest.addElement(files.nextElement());
           }
       }
  -    
  -    protected static final File createTmpFile(){
  -        // must be compatible with JDK 1.1 !!!!
  -        final long rand = (new 
Random(System.currentTimeMillis())).nextLong();
  -        File file = new File("metamata" + rand + ".tmp");
  -        return file;
  +
  +    protected final File createTmpFile() {
  +        return FileUtils.newFileUtils().createTempFile("metamata", ".tmp", 
getProject().getBaseDir());
       }
   
       /**
        * @return the list of .java files (as their absolute path) that should
        *         be audited.
        */
  -    protected Hashtable scanFileSets(){
  +
  +    protected Hashtable scanSources(Hashtable map) {
           Hashtable files = new Hashtable();
  -        for (int i = 0; i < fileSets.size(); i++){
  +        for (int i = 0; i < fileSets.size(); i++) {
               FileSet fs = (FileSet) fileSets.elementAt(i);
               DirectoryScanner ds = fs.getDirectoryScanner(project);
               ds.scan();
               String[] f = ds.getIncludedFiles();
               log(i + ") Adding " + f.length + " files from directory " + 
ds.getBasedir(), Project.MSG_VERBOSE);
  -            for (int j = 0; j < f.length; j++){
  +            for (int j = 0; j < f.length; j++) {
                   String pathname = f[j];
  -                if ( pathname.endsWith(".java") ){
  -                    File file = new File( ds.getBasedir(), pathname);
  +                if (pathname.endsWith(".java")) {
  +                    File file = new File(ds.getBasedir(), pathname);
   //                  file = project.resolveFile(file.getAbsolutePath());
  -                    String classname = pathname.substring(0, 
pathname.length()-".java".length());
  +                    String classname = pathname.substring(0, 
pathname.length() - ".java".length());
                       classname = classname.replace(File.separatorChar, '.');
  -                   files.put( file.getAbsolutePath(), classname ); // it's a 
java file, add it.
  +                    files.put(file.getAbsolutePath(), classname); // it's a 
java file, add it.
                   }
               }
           }
           return files;
  +    }
  +
  +    protected Hashtable scanSources(final Hashtable mapping, final String[] 
entries) {
  +        final Vector javaFiles = new Vector(512);
  +        for (int i = 0; i < entries.length; i++) {
  +            final File f = new File(entries[i]);
  +            if (f.isDirectory()) {
  +                DirectoryScanner ds = new DirectoryScanner();
  +                ds.setBasedir(f);
  +                ds.setIncludes(new String[]{"**/*.java"});
  +                ds.scan();
  +                String[] included = ds.getIncludedFiles();
  +                for (int j = 0; j < included.length; j++) {
  +                    javaFiles.addElement(new File(f, included[j]));
  +                }
  +            } else if (entries[i].endsWith(".java")) {
  +                javaFiles.addElement(f);
  +            }
  +        }
  +        // do the mapping paths/classname
  +        final int count = javaFiles.size();
  +        for (int i = 0; i < count; i++) {
  +            File file = (File) javaFiles.elementAt(i);
  +            String pathname = Path.translateFile(file.getAbsolutePath());
  +            String classname = pathname.substring(0, pathname.length() - 
".java".length());
  +            classname = classname.replace(File.separatorChar, '.');
  +            mapping.put(pathname, classname);
  +        }
  +        return mapping;
       }
   
   }
  
  
  

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

Reply via email to