blob: 929390c71fa0b6fd739e4ed095c7e2c7e8abd823 [file] [log] [blame]
/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
*
* This program and the accompanying materials are made available under
* the terms of the Common Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/cpl-v10.html
*
* $Id: emmajavaTask.java,v 1.1.1.1.2.2 2004/07/16 23:32:04 vlad_r Exp $
*/
package com.vladium.emma;
import java.io.File;
import com.vladium.util.IProperties;
import com.vladium.util.Strings;
import com.vladium.emma.ant.*;
import com.vladium.emma.instr.FilterCfg;
import com.vladium.emma.instr.FilterCfg.filterElement;
import com.vladium.emma.report.ReportCfg;
import com.vladium.emma.report.IReportEnums.DepthAttribute;
import com.vladium.emma.report.IReportEnums.UnitsTypeAttribute;
import com.vladium.emma.report.ReportCfg.Element_HTML;
import com.vladium.emma.report.ReportCfg.Element_LCOV;
import com.vladium.emma.report.ReportCfg.Element_TXT;
import com.vladium.emma.report.ReportCfg.Element_XML;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
// ----------------------------------------------------------------------------
/**
* @author Vlad Roubtsov, (C) 2003
*/
public
class emmajavaTask extends Java
{
// public: ................................................................
public void init () throws BuildException
{
super.init ();
m_verbosityCfg = new VerbosityCfg ();
m_genericCfg = new GenericCfg (this);
m_filterCfg = new FilterCfg (this);
m_reportCfg = new ReportCfg (project, this);
setEnabled (true);
}
public void execute () throws BuildException
{
log (IAppConstants.APP_VERBOSE_BUILD_ID, Project.MSG_VERBOSE);
if (getClasspath () == null)
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ ": this task requires 'classpath' attribute to be set", location).fillInStackTrace ();
if (isEnabled ())
{
// fork:
if (m_forkUserOverride && ! m_fork)
log (getTaskName () + ": 'fork=\"false\"' attribute setting ignored (this task always forks)", Project.MSG_WARN);
super.setFork (true); // always fork
// add emma libs to the parent task's classpath [to support non-extdir deployment]:
final Path libClasspath = m_libClasspath;
if ((libClasspath != null) && (libClasspath.size () > 0))
{
super.createClasspath ().append (libClasspath);
}
// classname|jar (1/2):
super.setClassname ("emmarun");
// <emmajava> extensions:
{
// report types:
{
String reportTypes = Strings.toListForm (m_reportCfg.getReportTypes (), ',');
if ((reportTypes == null) || (reportTypes.length () == 0)) reportTypes = "txt";
super.createArg ().setValue ("-r");
super.createArg ().setValue (reportTypes);
}
// full classpath scan flag:
{
if (m_scanCoveragePath)
{
super.createArg ().setValue ("-f");
}
}
// dump raw data flag and options:
{
if (m_dumpSessionData)
{
super.createArg ().setValue ("-raw");
if (m_outFile != null)
{
super.createArg ().setValue ("-out");
super.createArg ().setValue (m_outFile.getAbsolutePath ());
}
if (m_outFileMerge != null)
{
super.createArg ().setValue ("-merge");
super.createArg ().setValue (m_outFileMerge.booleanValue () ? "y" : "n");
}
}
else
{
if (m_outFile != null)
log (getTaskName () + ": output file attribute ignored ('fullmetadata=\"true\"' not specified)", Project.MSG_WARN);
if (m_outFileMerge != null)
log (getTaskName () + ": merge attribute setting ignored ('fullmetadata=\"true\"' not specified)", Project.MSG_WARN);
}
}
// instr filter:
{
final String [] specs = m_filterCfg.getFilterSpecs ();
if ((specs != null) && (specs.length > 0))
{
super.createArg ().setValue ("-ix");
super.createArg ().setValue (Strings.toListForm (specs, ','));
}
}
// sourcepath:
{
final Path srcpath = m_reportCfg.getSourcepath ();
if (srcpath != null)
{
super.createArg ().setValue ("-sp");
super.createArg ().setValue (Strings.toListForm (srcpath.list (), ','));
}
}
// all other generic settings:
{
final IProperties reportSettings = m_reportCfg.getReportSettings ();
final IProperties genericSettings = m_genericCfg.getGenericSettings ();
// TODO: another options is to read this file in the forked JVM [use '-props' pass-through]
// the best option depends on how ANT resolves relative file names
final IProperties fileSettings = m_genericCfg.getFileSettings ();
// verbosity settings use dedicated attributes and hence are more specific
// than anything generic:
final IProperties verbositySettings = m_verbosityCfg.getSettings ();
// (1) file settings have lower priority than any explicitly named overrides
// (2) named report settings override generic named settings
// (3) verbosity settings use dedicated attributes (not overlapping with report
// cfg) and hence are more specific than anything generic
final IProperties settings = IProperties.Factory.combine (reportSettings,
IProperties.Factory.combine (verbositySettings,
IProperties.Factory.combine (genericSettings,
fileSettings)));
final String [] argForm = settings.toAppArgsForm ("-D");
if (argForm.length > 0)
{
for (int a = 0; a < argForm.length; ++ a)
super.createArg ().setValue (argForm [a]);
}
}
}
// [assertion: getClasspath() is not null]
// classpath:
super.createArg ().setValue ("-cp");
super.createArg ().setPath (getClasspath ());
// classname|jar (2/2):
if (getClassname () != null)
super.createArg ().setValue (getClassname ());
else if (getJar () != null)
{
super.createArg ().setValue ("-jar");
super.createArg ().setValue (getJar ().getAbsolutePath ());
}
else
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ "either 'jar' or 'classname' attribute must be set", location).fillInStackTrace ();
// main class args:
if (m_appArgs != null)
{
final String [] args = m_appArgs.getArguments ();
for (int a = 0; a < args.length; ++ a)
{
super.createArg ().setValue (args [a]); // note: spaces etc are escaped correctly by ANT libs
}
}
}
else
{
// fork:
super.setFork (m_fork);
// [assertion: getClasspath() is not null]
// classpath:
super.createClasspath ().append (getClasspath ()); // can't use setClasspath() for obvious reasons
// classname|jar:
if (getClassname () != null)
super.setClassname (getClassname ());
else if (getJar () != null)
super.setJar (getJar ());
else
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ "either 'jar' or 'classname' attribute must be set", location).fillInStackTrace ();
// main class args:
if (m_appArgs != null)
{
final String [] args = m_appArgs.getArguments ();
for (int a = 0; a < args.length; ++ a)
{
super.createArg ().setValue (args [a]); // note: spaces etc are escaped correctly by ANT libs
}
}
}
super.execute ();
}
// <java> overrides [ANT 1.4]:
public void setClassname (final String classname)
{
if (getJar () != null)
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ "'jar' and 'classname' attributes cannot be set at the same time", location).fillInStackTrace ();
m_classname = classname;
}
public void setJar (final File file)
{
if (getClassname () != null)
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ "'jar' and 'classname' attributes cannot be set at the same time", location).fillInStackTrace ();
m_jar = file;
}
public void setClasspath (final Path path)
{
if (m_classpath == null)
m_classpath = path;
else
m_classpath.append (path);
}
public void setClasspathRef (final Reference ref)
{
createClasspath ().setRefid (ref);
}
public Path createClasspath ()
{
if (m_classpath == null)
m_classpath = new Path (project);
return m_classpath.createPath ();
}
/**
* This is already deprecated in ANT v1.4. However, it is still supported by
* the parent task so I do likewise.
*/
public void setArgs (final String args)
{
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ ": disallows using <java>'s deprecated 'args' attribute", location).fillInStackTrace ();
}
/**
* Not overridable.
*/
public final void setFork (final boolean fork)
{
m_fork = fork;
m_forkUserOverride = true;
}
/**
* Not overridable [due to limitations in ANT's Commandline].
*/
public final Commandline.Argument createArg ()
{
if (m_appArgs == null)
m_appArgs = new Commandline ();
return m_appArgs.createArgument ();
}
// <java> overrides [ANT 1.5]:
// [nothing at this point]
// <emmajava> extensions:
public void setEnabled (final boolean enabled)
{
m_enabled = enabled;
}
// .properties file attribute:
public final void setProperties (final File file)
{
m_genericCfg.setProperties (file);
}
// generic property element:
public final PropertyElement createProperty ()
{
return m_genericCfg.createProperty ();
}
// verbosity attribute:
public void setVerbosity (final VerbosityCfg.VerbosityAttribute verbosity)
{
m_verbosityCfg.setVerbosity (verbosity);
}
// verbosity class filter attribute:
public void setVerbosityfilter (final String filter)
{
m_verbosityCfg.setVerbosityfilter (filter);
}
// lib classpath attribute [to support non-extdir deployment]:
public final void setLibclasspath (final Path classpath)
{
if (m_libClasspath == null)
m_libClasspath = classpath;
else
m_libClasspath.append (classpath);
}
public final void setLibclasspathRef (final Reference ref)
{
if (m_libClasspath == null)
m_libClasspath = new Path (project);
m_libClasspath.createPath ().setRefid (ref);
}
// -f flag:
public void setFullmetadata (final boolean full)
{
m_scanCoveragePath = full; // defaults to false TODO: maintain the default in a central location
}
// -raw flag:
public void setDumpsessiondata (final boolean dump)
{
m_dumpSessionData = dump;
}
// -out option:
// sessiondatafile|outfile attribute:
public void setSessiondatafile (final File file)
{
if (m_outFile != null)
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ ": session data file attribute already set", location).fillInStackTrace ();
m_outFile = file;
}
public void setOutfile (final File file)
{
if (m_outFile != null)
throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
+ ": session data file attribute already set", location).fillInStackTrace ();
m_outFile = file;
}
// public void setTofile (final File file)
// {
// if (m_outFile != null)
// throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
// + ": session data file attribute already set", location).fillInStackTrace ();
//
// m_outFile = file;
// }
//
// public void setFile (final File file)
// {
// if (m_outFile != null)
// throw (BuildException) SuppressableTask.newBuildException (getTaskName ()
// + ": session data file attribute already set", location).fillInStackTrace ();
//
// m_outFile = file;
// }
// merge attribute:
public void setMerge (final boolean merge)
{
m_outFileMerge = merge ? Boolean.TRUE : Boolean.FALSE;
}
// instr filter attribute/element:
public final void setFilter (final String filter)
{
m_filterCfg.setFilter (filter);
}
public final filterElement createFilter ()
{
return m_filterCfg.createFilter ();
}
// TODO: should what's below go inside <report></report> ?
// sourcepath attribute/element:
public final void setSourcepath (final Path path)
{
m_reportCfg.setSourcepath (path);
}
public final void setSourcepathRef (final Reference ref)
{
m_reportCfg.setSourcepathRef (ref);
}
public final Path createSourcepath ()
{
return m_reportCfg.createSourcepath ();
}
// generator elements:
public final Element_TXT createTxt ()
{
return m_reportCfg.createTxt ();
}
public final Element_LCOV createLcov ()
{
return m_reportCfg.createLcov ();
}
public final Element_HTML createHtml ()
{
return m_reportCfg.createHtml ();
}
public final Element_XML createXml ()
{
return m_reportCfg.createXml ();
}
// report properties [defaults for all report types]:
public final void setUnits (final UnitsTypeAttribute units)
{
m_reportCfg.setUnits (units);
}
public final void setDepth (final DepthAttribute depth)
{
m_reportCfg.setDepth (depth);
}
public final void setColumns (final String columns)
{
m_reportCfg.setColumns (columns);
}
public final void setSort (final String sort)
{
m_reportCfg.setSort (sort);
}
public final void setMetrics (final String metrics)
{
m_reportCfg.setMetrics (metrics);
}
// these are not supported anymore
// public final void setOutdir (final File dir)
// {
// m_reportCfg.setOutdir (dir);
// }
//
// public final void setDestdir (final File dir)
// {
// m_reportCfg.setDestdir (dir);
// }
// should be set at this level [and conflicts with raw data opts]:
// public void setOutfile (final String fileName)
// {
// m_reportCfg.setOutfile (fileName);
// }
public void setEncoding (final String encoding)
{
m_reportCfg.setEncoding (encoding);
}
// protected: .............................................................
protected String getClassname ()
{
return m_classname;
}
protected File getJar ()
{
return m_jar;
}
protected Path getClasspath ()
{
return m_classpath;
}
// extended functionality:
protected boolean isEnabled ()
{
return m_enabled;
}
// package: ...............................................................
// private: ...............................................................
// <java> overrides:
private Path m_classpath;
private String m_classname;
private File m_jar;
private Commandline m_appArgs;
private boolean m_fork, m_forkUserOverride;
// <emmajava> extensions:
private boolean m_enabled;
private Path m_libClasspath;
private /*final*/ VerbosityCfg m_verbosityCfg;
private /*final*/ GenericCfg m_genericCfg;
private /*final*/ FilterCfg m_filterCfg;
private /*final*/ ReportCfg m_reportCfg;
private boolean m_scanCoveragePath; // defaults to false
private boolean m_dumpSessionData; //defaults to false
private File m_outFile;
private Boolean m_outFileMerge;
} // end of class
// ----------------------------------------------------------------------------