diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java
index 667fda3f0..cd6ba582a 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/AbstractMetamataTask.java
@@ -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 @@ import java.util.Random;
* For more information, visit the website at
* www.metamata.com
*
- * @author Stephane Bailliez
+ * @author Stephane Bailliez
*/
-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 @@ public abstract class AbstractMetamataTask extends Task{
// 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 @@ public abstract class AbstractMetamataTask extends Task{
}
/** 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 @@ public abstract class AbstractMetamataTask extends Task{
}
/** 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 @@ public abstract class AbstractMetamataTask extends Task{
}
/** -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 @@ public abstract class AbstractMetamataTask extends Task{
}
}
- //--------------------- PRIVATE/PROTECTED METHODS --------------------------
-
/** check the options and build the command line */
protected void setUp() throws BuildException {
checkOptions();
@@ -190,10 +190,12 @@ public abstract class AbstractMetamataTask extends Task{
// 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 @@ public abstract class AbstractMetamataTask extends Task{
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 @@ public abstract class AbstractMetamataTask extends Task{
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;
+ }
+
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java
index bacb00005..1e2caac38 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAudit.java
@@ -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 @@ import java.util.Vector;
* For more information, visit the website at
* www.metamata.com
*
- * @author Stephane Bailliez
+ * @author Stephane Bailliez
*/
public class MAudit extends AbstractMetamataTask {
@@ -119,15 +117,24 @@ public class MAudit extends AbstractMetamataTask {
// (?: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 @@ public class MAudit extends AbstractMetamataTask {
}
/** 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 @@ public class MAudit extends AbstractMetamataTask {
// 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 @@ public class MAudit extends AbstractMetamataTask {
/** 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;
- }
-
}
-
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java
index 0bdf4481e..f6fdc367c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MAuditStreamHandler.java
@@ -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 @@ import javax.xml.parsers.DocumentBuilderFactory;
*
it does not report error that goes to stderr.
*
*
- * @author Stephane Bailliez
+ * @author Stephane Bailliez
*/
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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
}
/** 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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
/** 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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
* 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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
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("\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("\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 @@ class MAuditStreamHandler implements ExecuteStreamHandler {
}
/** 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);
}
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java
index d5f6bdb11..e739d7ccb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetrics.java
@@ -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 @@ Format Options
*/
/** 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 -------------------------------
@@ -131,20 +129,29 @@ Format Options
super("com.metamata.sc.MMetrics");
}
+ /**
+ * 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 @@ Format Options
* 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 @@ Format Options
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 @@ Format Options
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 @@ Format Options
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 @@ Format Options
* 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;
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java
index da9a8315f..0aeab1b0f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/metamata/MMetricsStreamHandler.java
@@ -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 @@ import org.apache.tools.ant.Project;
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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
/** 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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
* @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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
// 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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
* @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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
/**
* 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 @@ public class MMetricsStreamHandler implements ExecuteStreamHandler {
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 @@ class MetricsElement {
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 @@ class MetricsElement {
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 @@ class MetricsElement {
// 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
}