- /*
- * Copyright 2001-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
- package org.apache.tools.ant.taskdefs.optional.sitraka;
-
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.util.Vector;
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.Project;
- import org.apache.tools.ant.Task;
- import org.apache.tools.ant.taskdefs.Execute;
- import org.apache.tools.ant.taskdefs.LogStreamHandler;
- import org.apache.tools.ant.types.Commandline;
- import org.apache.tools.ant.types.CommandlineJava;
- import org.apache.tools.ant.types.EnumeratedAttribute;
- import org.apache.tools.ant.types.FileSet;
- import org.apache.tools.ant.types.Path;
- import org.apache.tools.ant.util.JavaEnvUtils;
-
- /**
- * Runs Sitraka JProbe Coverage.
- *
- * Options are pretty numerous, you'd better check the manual for a full
- * descriptions of options. (not that simple since they differ from the online
- * help, from the usage command line and from the examples...)
- * <p>
- * For additional information, visit <a href="http://www.sitraka.com">www.sitraka.com</a>
- *
- *
- * @ant.task name="jpcoverage" category="metrics"
- */
- public class Coverage extends CovBase {
-
- protected Commandline cmdl = new Commandline();
-
- protected CommandlineJava cmdlJava = new CommandlineJava();
-
- protected String function = "coverage";
-
- protected String seedName;
-
- protected File inputFile;
-
- protected File javaExe;
-
- protected String vm;
-
- protected boolean applet = false;
-
- /** this is a somewhat annoying thing, set it to never */
- protected String exitPrompt = "never";
-
- protected Filters filters = new Filters();
-
- protected Triggers triggers;
-
- protected String finalSnapshot = "coverage";
-
- protected String recordFromStart = "coverage";
-
- protected File snapshotDir;
-
- protected File workingDir;
-
- protected boolean trackNatives = false;
-
- protected Socket socket;
-
- protected int warnLevel = 0;
-
- protected Vector filesets = new Vector();
-
- //--------- setters used via reflection --
-
- /** seed name for snapshot file. Can be null, default to snap */
- public void setSeedname(String value) {
- seedName = value;
- }
-
- /**
- * @ant.attribute ignore="true"
- */
- public void setInputfile(File value) {
- inputFile = value;
- }
-
- /**
- * Path to the java executable.
- */
- public void setJavaexe(File value) {
- javaExe = value;
- }
-
- public static class Javavm extends EnumeratedAttribute {
- public String[] getValues() {
- return new String[]{"java2", "jdk118", "jdk117"};
- }
- }
-
- /**
- * Indicates which virtual machine to run: "jdk117", "jdk118" or "java2".
- * Can be null, default to "java2". */
- public void setVm(Javavm value) {
- vm = value.getValue();
- }
-
- /**
- * If true, run an applet.
- */
- public void setApplet(boolean value) {
- applet = value;
- }
-
- /**
- * Toggles display of the console prompt: always, error, never
- */
- public void setExitprompt(String value) {
- exitPrompt = value;
- }
-
- /**
- * Defines class/method filters based on pattern matching.
- * The syntax is filters is similar to a fileset.
- */
- public Filters createFilters() {
- return filters;
- }
-
- /**
- * Defines events to use for interacting with the
- * collection of data performed during coverage.
- *
- * For example you may run a whole application but only decide
- * to collect data once it reaches a certain method and once it
- * exits another one.
- */
- public Triggers createTriggers() {
- if (triggers == null) {
- triggers = new Triggers();
- }
- return triggers;
- }
-
- /**
- * Define a host and port to connect to if you want to do
- * remote viewing.
- */
- public Socket createSocket() {
- if (socket == null) {
- socket = new Socket();
- }
- return socket;
- }
-
- public static class Finalsnapshot extends EnumeratedAttribute {
- public String[] getValues() {
- return new String[]{"coverage", "none", "all"};
- }
- }
-
- /**
- * Type of snapshot to send at program termination: none, coverage, all.
- * Can be null, default to none
- */
- public void setFinalsnapshot(String value) {
- finalSnapshot = value;
- }
-
- public static class Recordfromstart extends EnumeratedAttribute {
- public String[] getValues() {
- return new String[]{"coverage", "none", "all"};
- }
- }
-
- /**
- * "all", "coverage", or "none".
- */
- public void setRecordfromstart(Recordfromstart value) {
- recordFromStart = value.getValue();
- }
-
- /**
- * Set warning level (0-3, where 0 is the least amount of warnings).
- */
- public void setWarnlevel(Integer value) {
- warnLevel = value.intValue();
- }
-
- /**
- * The path to the directory where snapshot files are stored.
- * Choose a directory that is reachable by both the remote
- * and local computers, and enter the same path on the command-line
- * and in the viewer.
- */
- public void setSnapshotdir(File value) {
- snapshotDir = value;
- }
-
- /**
- * The physical path to the working directory for the VM.
- */
- public void setWorkingdir(File value) {
- workingDir = value;
- }
-
- /**
- * If true, track native methods.
- */
- public void setTracknatives(boolean value) {
- trackNatives = value;
- }
-
- //
-
- /**
- * Adds a JVM argument.
- */
- public Commandline.Argument createJvmarg() {
- return cmdlJava.createVmArgument();
- }
-
- /**
- * Adds a command argument.
- */
- public Commandline.Argument createArg() {
- return cmdlJava.createArgument();
- }
-
- /**
- * classpath to run the files.
- */
- public Path createClasspath() {
- return cmdlJava.createClasspath(getProject()).createPath();
- }
-
- /**
- * classname to run as standalone or runner for filesets.
- */
- public void setClassname(String value) {
- cmdlJava.setClassname(value);
- }
-
- /**
- * the classnames to execute.
- */
- public void addFileset(FileSet fs) {
- filesets.addElement(fs);
- }
-
-
- //---------------- the tedious job begins here
-
- public Coverage() {
- }
-
- /** execute the jplauncher by providing a parameter file */
- public void execute() throws BuildException {
- File paramfile = null;
- // if an input file is used, all other options are ignored...
- if (inputFile == null) {
- checkOptions();
- paramfile = createParamFile();
- } else {
- paramfile = inputFile;
- }
- try {
- // we need to run Coverage from his directory due to dll/jar issues
- cmdl.setExecutable(findExecutable("jplauncher"));
- cmdl.createArgument().setValue("-jp_input=" + paramfile.getAbsolutePath());
-
- // use the custom handler for stdin issues
- LogStreamHandler handler = new CoverageStreamHandler(this);
- Execute exec = new Execute(handler);
- log(cmdl.describeCommand(), Project.MSG_VERBOSE);
- exec.setCommandline(cmdl.getCommandline());
- int exitValue = exec.execute();
- if (Execute.isFailure(exitValue)) {
- throw new BuildException("JProbe Coverage failed (" + exitValue + ")");
- }
- } catch (IOException e) {
- throw new BuildException("Failed to execute JProbe Coverage.", e);
- } finally {
- //@todo should be removed once switched to JDK1.2
- if (inputFile == null && paramfile != null) {
- paramfile.delete();
- }
- }
- }
-
- /** wheck what is necessary to check, Coverage will do the job for us */
- protected void checkOptions() throws BuildException {
- // check coverage home
- if (getHome() == null || !getHome().isDirectory()) {
- throw new BuildException("Invalid home directory. Must point to JProbe home directory");
- }
- File jar = findCoverageJar();
- if (!jar.exists()) {
- throw new BuildException("Cannot find Coverage directory: " + getHome());
- }
-
- // make sure snapshot dir exists and is resolved
- if (snapshotDir == null) {
- snapshotDir = new File(".");
- }
- snapshotDir = getProject().resolveFile(snapshotDir.getPath());
- if (!snapshotDir.isDirectory() || !snapshotDir.exists()) {
- throw new BuildException("Snapshot directory does not exists :" + snapshotDir);
- }
- if (workingDir == null) {
- workingDir = new File(".");
- }
- workingDir = getProject().resolveFile(workingDir.getPath());
-
- // check for info, do your best to select the java executable.
- // JProbe 3.0 fails if there is no javaexe option. So
- if (javaExe == null && (vm == null || "java2".equals(vm))) {
- if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
- if (vm == null) {
- vm = "java2";
- }
- javaExe = new File(JavaEnvUtils.getJreExecutable("java"));
- }
- }
- }
-
- /**
- * return the command line parameters. Parameters can either be passed
- * to the command line and stored to a file (then use the -jp_input=<filename>)
- * if they are too numerous.
- */
- protected String[] getParameters() {
- Vector params = new Vector();
- params.addElement("-jp_function=" + function);
- if (vm != null) {
- params.addElement("-jp_vm=" + vm);
- }
- if (javaExe != null) {
- params.addElement("-jp_java_exe=" + getProject().resolveFile(javaExe.getPath()));
- }
- params.addElement("-jp_working_dir=" + workingDir.getPath());
- params.addElement("-jp_snapshot_dir=" + snapshotDir.getPath());
- params.addElement("-jp_record_from_start=" + recordFromStart);
- params.addElement("-jp_warn=" + warnLevel);
- if (seedName != null) {
- params.addElement("-jp_output_file=" + seedName);
- }
- params.addElement("-jp_filter=" + filters.toString());
- if (triggers != null) {
- params.addElement("-jp_trigger=" + triggers.toString());
- }
- if (finalSnapshot != null) {
- params.addElement("-jp_final_snapshot=" + finalSnapshot);
- }
- params.addElement("-jp_exit_prompt=" + exitPrompt);
- //params.addElement("-jp_append=" + append);
- params.addElement("-jp_track_natives=" + trackNatives);
- //.... now the jvm
- // arguments
- String[] vmargs = cmdlJava.getVmCommand().getArguments();
- for (int i = 0; i < vmargs.length; i++) {
- params.addElement(vmargs[i]);
- }
- // classpath
- Path classpath = cmdlJava.getClasspath();
- if (classpath != null && classpath.size() > 0) {
- params.addElement("-classpath " + classpath.toString());
- }
- // classname (runner or standalone)
- if (cmdlJava.getClassname() != null) {
- params.addElement(cmdlJava.getClassname());
- }
- // arguments for classname
- String[] args = cmdlJava.getJavaCommand().getArguments();
- for (int i = 0; i < args.length; i++) {
- params.addElement(args[i]);
- }
-
- String[] array = new String[params.size()];
- params.copyInto(array);
- return array;
- }
-
-
- /**
- * create the parameter file from the given options. The file is
- * created with a random name in the current directory.
- * @return the file object where are written the configuration to run
- * JProbe Coverage
- * @throws BuildException thrown if something bad happens while writing
- * the arguments to the file.
- */
- protected File createParamFile() throws BuildException {
- //@todo change this when switching to JDK 1.2 and use File.createTmpFile()
- File file = createTempFile("jpcov");
- file.deleteOnExit();
- log("Creating parameter file: " + file, Project.MSG_VERBOSE);
-
- // options need to be one per line in the parameter file
- // so write them all in a single string
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- String[] params = getParameters();
- for (int i = 0; i < params.length; i++) {
- pw.println(params[i]);
- }
- pw.flush();
- log("JProbe Coverage parameters:\n" + sw.toString(), Project.MSG_VERBOSE);
-
- // now write them to the file
- FileWriter fw = null;
- try {
- fw = new FileWriter(file);
- fw.write(sw.toString());
- fw.flush();
- } catch (IOException e) {
- throw new BuildException("Could not write parameter file " + file, e);
- } finally {
- if (fw != null) {
- try {
- fw.close();
- } catch (IOException ignored) {
- }
- }
- }
- return file;
- }
-
- /** specific pumper to avoid those nasty stdin issues */
- static class CoverageStreamHandler extends LogStreamHandler {
- CoverageStreamHandler(Task task) {
- super(task, Project.MSG_INFO, Project.MSG_WARN);
- }
-
- /**
- * there are some issues concerning all JProbe executable
- * In our case a 'Press ENTER to close this window..." will
- * be displayed in the current window waiting for enter.
- * So I'm closing the stream right away to avoid problems.
- */
- public void setProcessInputStream(OutputStream os) {
- try {
- os.close();
- } catch (IOException ignored) {
- }
- }
- }
-
- }