buildframework/helium/sf/java/quality/src/com/nokia/helium/quality/ant/taskdefs/CMTToolTask.java
/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.helium.quality.ant.taskdefs;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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.ExecTask;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.FileSet;
/**
* CMTTool is the task used to execute the Complexity Measures Tool for C/C++.
*
* <pre>
* Usage:
*
* <hlm:cmt output="${cmt.output.dir}\logs\${build.id}_${ido.name}_${componentbase}_${cmt.id}.txt>
* <fileset id="input" dir="${test.data.src}">
* <include name="**/*.h"/>
* <include name="**/*.cpp"/>
* </fileset>
* </hlm:cmt>
*
* output : Name of the file to contain the results of Complexity Measures Tool.
* fileset: Location of the source files whose complexity is to be measured.
* </pre>
*
* @ant.task name="cmt" category="Quality".
*/
public class CMTToolTask extends Task {
private List<FileSet> cmtFileSetList = new ArrayList<FileSet>();
private File input;
private File output;
private File htmlOutputDir;
private boolean failOnError = true;
/**
* Set the fileset.
*
* @param fileSet
* is the fileset which points to the location of source files to
* be measured.
* @ant.required
*/
public void addFileset(FileSet fileSet) {
cmtFileSetList.add(fileSet);
}
/**
* Set the name and location of the output file to contain the result of CMT
* tool.
*
* @param output
* is the name of the result file to be generated.
* @ant.required
*/
public void setOutput(File output) {
this.output = output;
}
/**
* @param failOnError the failOnError to set
*/
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}
/**
* @param htmlOutputDir the htmlOutputDir to set
*/
public void setHtmlOutputDir(File htmlOutputDir) {
this.htmlOutputDir = htmlOutputDir;
}
/**
* Run the CMT task.
*/
public void execute() {
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
throw new BuildException("CMT supported only on windows platforms.");
}
validate();
try {
input = File.createTempFile("Files", ".list");
generateFileList();
runCmtCommand();
if (this.htmlOutputDir != null) {
runCmt2HtmlCommand();
}
} catch (IOException ioe) {
throw new BuildException("Not able to generate file list for 'cmt'. ", ioe);
} catch (BuildException be) {
if (failOnError) {
throw new BuildException("Exception occured while running 'cmt' tool. ", be);
}
log("Exception occured while running 'cmt' tool. ", Project.MSG_ERR);
} finally {
if (input != null) {
input.delete();
}
}
}
/**
* Execute the cmt.exe command.
*/
private void runCmtCommand() {
String command = null;
if (!this.output.getParentFile().exists()) {
this.output.getParentFile().mkdirs();
}
ExecTask task = getExecTask("cmttool", "cmt", new File("."));
command = "cmt";
task.createArg().setValue("-f");
command += " " + "-f";
task.createArg().setValue(input.toString());
command += " " + input.toString();
task.createArg().setValue("-o");
command += " " + "-o";
task.createArg().setValue(output.toString());
command += " " + output;
task.setProject(getProject());
log("run command: " + command);
task.execute();
}
/**
* Execute the cmt2html.bat command.
*/
private void runCmt2HtmlCommand() {
String command = null;
if (!this.htmlOutputDir.exists()) {
this.htmlOutputDir.mkdirs();
}
ExecTask task = getExecTask("cmt2html", "cmt2html.bat", this.htmlOutputDir);
command = "cmt2html.bat";
task.createArg().setValue("-i");
command += " " + "-i";
task.createArg().setValue(output.toString());
command += " " + output;
task.createArg().setValue("-nsb");
command += " " + "-nsb";
task.setProject(getProject());
log("run command: " + command);
task.execute();
}
/**
* Return an execute task with the given inputs.
*
* @param taskName
* is the name of the execute task.
* @param cmd
* is the command to be executed by the task.
* @param outDir
* is the working directory for the task.
* @return an instance of execute task.
*/
private ExecTask getExecTask(String taskName, String cmd, File outDir) {
ExecTask task = new ExecTask();
task.bindToOwner(this);
task.setDir(outDir);
task.setExecutable(cmd);
return task;
}
/**
* Method validates the required parameters and elements are set.
*/
private void validate() {
if (cmtFileSetList.size() == 0) {
throw new BuildException("Nested Element 'fileset' missing for task 'cmt'.");
}
if (output == null) {
throw new BuildException("Parameter 'output' missing for task 'cmt'.");
}
}
/**
* Generates a file containing a list of files.
*/
private void generateFileList() {
for (FileSet fileSet : cmtFileSetList) {
DirectoryScanner dirScanner = fileSet.getDirectoryScanner();
dirScanner.scan();
String[] filelist = dirScanner.getIncludedFiles();
String lineSeparator = System.getProperty("line.separator");
String fileSeparator = System.getProperty("file.separator");
BufferedWriter outputFile = null;
try {
outputFile = new BufferedWriter(new FileWriter(input));
for (String file : filelist) {
outputFile.write(dirScanner.getBasedir().toString() + fileSeparator + file
+ lineSeparator);
}
} catch (IOException e) {
throw new BuildException("Not able to generate file list for 'cmt'. ", e);
} finally {
try {
if (outputFile != null) {
outputFile.close();
}
} catch (IOException ex) {
// ignore exception
ex = null;
}
}
}
}
}