Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 506   Methods: 30
NCLOC: 262   Classes: 5
 
 Source file Conditionals Statements Methods TOTAL
Coverage.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant.taskdefs.optional.sitraka;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.FileWriter;
 59   
 import java.io.IOException;
 60   
 import java.io.OutputStream;
 61   
 import java.io.PrintWriter;
 62   
 import java.io.StringWriter;
 63   
 import java.util.Random;
 64   
 import java.util.Vector;
 65   
 import org.apache.tools.ant.BuildException;
 66   
 import org.apache.tools.ant.Project;
 67   
 import org.apache.tools.ant.Task;
 68   
 import org.apache.tools.ant.taskdefs.Execute;
 69   
 import org.apache.tools.ant.taskdefs.LogStreamHandler;
 70   
 import org.apache.tools.ant.types.Commandline;
 71   
 import org.apache.tools.ant.types.CommandlineJava;
 72   
 import org.apache.tools.ant.types.EnumeratedAttribute;
 73   
 import org.apache.tools.ant.types.FileSet;
 74   
 import org.apache.tools.ant.types.Path;
 75   
 import org.apache.tools.ant.util.JavaEnvUtils;
 76   
 
 77   
 /**
 78   
  * Runs Sitraka JProbe Coverage.
 79   
  *
 80   
  * Options are pretty numerous, you'd better check the manual for a full
 81   
  * descriptions of options. (not that simple since they differ from the online
 82   
  * help, from the usage command line and from the examples...)
 83   
  * <p>
 84   
  * For additional information, visit <a href="http://www.sitraka.com">www.sitraka.com</a>
 85   
  *
 86   
  * @author <a href="sbailliez@imediation.com">Stephane Bailliez</a>
 87   
  *
 88   
  * @ant.task name="jpcoverage" category="metrics"
 89   
  */
 90   
 public class Coverage extends CovBase {
 91   
 
 92   
     protected Commandline cmdl = new Commandline();
 93   
 
 94   
     protected CommandlineJava cmdlJava = new CommandlineJava();
 95   
 
 96   
     protected String function = "coverage";
 97   
 
 98   
     protected String seedName;
 99   
 
 100   
     protected File inputFile;
 101   
 
 102   
     protected File javaExe;
 103   
 
 104   
     protected String vm;
 105   
 
 106   
     protected boolean applet = false;
 107   
 
 108   
     /** this is a somewhat annoying thing, set it to never */
 109   
     protected String exitPrompt = "never";
 110   
 
 111   
     protected Filters filters = new Filters();
 112   
 
 113   
     protected Triggers triggers;
 114   
 
 115   
     protected String finalSnapshot = "coverage";
 116   
 
 117   
     protected String recordFromStart = "coverage";
 118   
 
 119   
     protected File snapshotDir;
 120   
 
 121   
     protected File workingDir;
 122   
 
 123   
     protected boolean trackNatives = false;
 124   
 
 125   
     protected Socket socket;
 126   
 
 127   
     protected int warnLevel = 0;
 128   
 
 129   
     protected Vector filesets = new Vector();
 130   
 
 131   
     //--------- setters used via reflection --
 132   
 
 133   
     /** seed name for snapshot file. Can be null, default to snap */
 134  0
     public void setSeedname(String value) {
 135  0
         seedName = value;
 136   
     }
 137   
 
 138   
     /**
 139   
      * @ant.attribute ignore="true"
 140   
      */
 141  0
     public void setInputfile(File value) {
 142  0
         inputFile = value;
 143   
     }
 144   
 
 145   
     /**
 146   
      * Path to the java executable.
 147   
      */
 148  0
     public void setJavaexe(File value) {
 149  0
         javaExe = value;
 150   
     }
 151   
 
 152   
     public static class Javavm extends EnumeratedAttribute {
 153  0
         public String[] getValues() {
 154  0
             return new String[]{"java2", "jdk118", "jdk117"};
 155   
         }
 156   
     }
 157   
 
 158   
     /**
 159   
      * Indicates which virtual machine to run: "jdk117", "jdk118" or "java2".
 160   
      * Can be null, default to "java2". */
 161  0
     public void setVm(Javavm value) {
 162  0
         vm = value.getValue();
 163   
     }
 164   
 
 165   
     /**
 166   
      * If true, run an applet.
 167   
      */
 168  0
     public void setApplet(boolean value) {
 169  0
         applet = value;
 170   
     }
 171   
 
 172   
     /**
 173   
      * Toggles display of the console prompt: always, error, never
 174   
      */
 175  0
     public void setExitprompt(String value) {
 176  0
         exitPrompt = value;
 177   
     }
 178   
 
 179   
     /**
 180   
      * Defines class/method filters based on pattern matching.
 181   
      * The syntax is filters is similar to a fileset.
 182   
      */
 183  0
     public Filters createFilters() {
 184  0
         return filters;
 185   
     }
 186   
 
 187   
     /**
 188   
      * Defines events to use for interacting with the
 189   
      * collection of data performed during coverage.
 190   
      *
 191   
      * For example you may run a whole application but only decide
 192   
      * to collect data once it reaches a certain method and once it
 193   
      * exits another one.
 194   
      */
 195  0
     public Triggers createTriggers() {
 196  0
         if (triggers == null) {
 197  0
             triggers = new Triggers();
 198   
         }
 199  0
         return triggers;
 200   
     }
 201   
 
 202   
     /**
 203   
      * Define a host and port to connect to if you want to do
 204   
      * remote viewing.
 205   
      */
 206  0
     public Socket createSocket() {
 207  0
         if (socket == null) {
 208  0
             socket = new Socket();
 209   
         }
 210  0
         return socket;
 211   
     }
 212   
 
 213   
     public static class Finalsnapshot extends EnumeratedAttribute {
 214  0
         public String[] getValues() {
 215  0
             return new String[]{"coverage", "none", "all"};
 216   
         }
 217   
     }
 218   
 
 219   
     /**
 220   
      * Type of snapshot to send at program termination: none, coverage, all.
 221   
      * Can be null, default to none
 222   
      */
 223  0
     public void setFinalsnapshot(String value) {
 224  0
         finalSnapshot = value;
 225   
     }
 226   
 
 227   
     public static class Recordfromstart extends EnumeratedAttribute {
 228  0
         public String[] getValues() {
 229  0
             return new String[]{"coverage", "none", "all"};
 230   
         }
 231   
     }
 232   
 
 233   
     /**
 234   
      * "all", "coverage",  or "none".
 235   
      */
 236  0
     public void setRecordfromstart(Recordfromstart value) {
 237  0
         recordFromStart = value.getValue();
 238   
     }
 239   
 
 240   
     /**
 241   
      * Set warning level (0-3, where 0 is the least amount of warnings).
 242   
      */
 243  0
     public void setWarnlevel(Integer value) {
 244  0
         warnLevel = value.intValue();
 245   
     }
 246   
 
 247   
     /**
 248   
      * The path to the directory where snapshot files are stored.
 249   
      * Choose a directory that is reachable by both the remote
 250   
      * and local computers, and enter the same path on the command-line
 251   
      * and in the viewer.
 252   
      */
 253  0
     public void setSnapshotdir(File value) {
 254  0
         snapshotDir = value;
 255   
     }
 256   
 
 257   
     /**
 258   
      * The physical path to the working directory for the VM.
 259   
      */
 260  0
     public void setWorkingdir(File value) {
 261  0
         workingDir = value;
 262   
     }
 263   
 
 264   
     /**
 265   
      * If true, track native methods.
 266   
      */
 267  0
     public void setTracknatives(boolean value) {
 268  0
         trackNatives = value;
 269   
     }
 270   
 
 271   
     //
 272   
 
 273   
     /**
 274   
      * Adds a JVM argument.
 275   
      */
 276  0
     public Commandline.Argument createJvmarg() {
 277  0
         return cmdlJava.createVmArgument();
 278   
     }
 279   
 
 280   
     /**
 281   
      * Adds a command argument.
 282   
      */
 283  0
     public Commandline.Argument createArg() {
 284  0
         return cmdlJava.createArgument();
 285   
     }
 286   
 
 287   
     /**
 288   
      * classpath to run the files.
 289   
      */
 290  0
     public Path createClasspath() {
 291  0
         return cmdlJava.createClasspath(getProject()).createPath();
 292   
     }
 293   
 
 294   
     /**
 295   
      * classname to run as standalone or runner for filesets.
 296   
      */
 297  0
     public void setClassname(String value) {
 298  0
         cmdlJava.setClassname(value);
 299   
     }
 300   
 
 301   
     /**
 302   
      * the classnames to execute.
 303   
      */
 304  0
     public void addFileset(FileSet fs) {
 305  0
         filesets.addElement(fs);
 306   
     }
 307   
 
 308   
 
 309   
     //---------------- the tedious job begins here
 310   
 
 311  0
     public Coverage() {
 312   
     }
 313   
 
 314   
     /** execute the jplauncher by providing a parameter file */
 315  0
     public void execute() throws BuildException {
 316  0
         File paramfile = null;
 317   
         // if an input file is used, all other options are ignored...
 318  0
         if (inputFile == null) {
 319  0
             checkOptions();
 320  0
             paramfile = createParamFile();
 321   
         } else {
 322  0
             paramfile = inputFile;
 323   
         }
 324  0
         try {
 325   
             // we need to run Coverage from his directory due to dll/jar issues
 326  0
             cmdl.setExecutable(findExecutable("jplauncher"));
 327  0
             cmdl.createArgument().setValue("-jp_input=" + paramfile.getAbsolutePath());
 328   
 
 329   
             // use the custom handler for stdin issues
 330  0
             LogStreamHandler handler = new CoverageStreamHandler(this);
 331  0
             Execute exec = new Execute(handler);
 332  0
             log(cmdl.describeCommand(), Project.MSG_VERBOSE);
 333  0
             exec.setCommandline(cmdl.getCommandline());
 334  0
             int exitValue = exec.execute();
 335  0
             if (exitValue != 0) {
 336  0
                 throw new BuildException("JProbe Coverage failed (" + exitValue + ")");
 337   
             }
 338   
         } catch (IOException e) {
 339  0
             throw new BuildException("Failed to execute JProbe Coverage.", e);
 340   
         } finally {
 341   
             //@todo should be removed once switched to JDK1.2
 342  0
             if (inputFile == null && paramfile != null) {
 343  0
                 paramfile.delete();
 344   
             }
 345   
         }
 346   
     }
 347   
 
 348   
     /** wheck what is necessary to check, Coverage will do the job for us */
 349  0
     protected void checkOptions() throws BuildException {
 350   
         // check coverage home
 351  0
         if (getHome() == null || !getHome().isDirectory()) {
 352  0
             throw new BuildException("Invalid home directory. Must point to JProbe home directory");
 353   
         }
 354  0
         File jar = findCoverageJar();
 355  0
         if (!jar.exists()) {
 356  0
             throw new BuildException("Cannot find Coverage directory: " + getHome());
 357   
         }
 358   
 
 359   
         // make sure snapshot dir exists and is resolved
 360  0
         if (snapshotDir == null) {
 361  0
             snapshotDir = new File(".");
 362   
         }
 363  0
         snapshotDir = getProject().resolveFile(snapshotDir.getPath());
 364  0
         if (!snapshotDir.isDirectory() || !snapshotDir.exists()) {
 365  0
             throw new BuildException("Snapshot directory does not exists :" + snapshotDir);
 366   
         }
 367  0
         if (workingDir == null) {
 368  0
             workingDir = new File(".");
 369   
         }
 370  0
         workingDir = getProject().resolveFile(workingDir.getPath());
 371   
 
 372   
         // check for info, do your best to select the java executable.
 373   
         // JProbe 3.0 fails if there is no javaexe option. So
 374  0
         if (javaExe == null && (vm == null || "java2".equals(vm))) {
 375  0
             if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
 376  0
                 if (vm == null) {
 377  0
                     vm = "java2";
 378   
                 }
 379  0
                 javaExe = new File(JavaEnvUtils.getJreExecutable("java"));
 380   
             }
 381   
         }
 382   
     }
 383   
 
 384   
     /**
 385   
      * return the command line parameters. Parameters can either be passed
 386   
      * to the command line and stored to a file (then use the -jp_input=&lt;filename&gt;)
 387   
      * if they are too numerous.
 388   
      */
 389  0
     protected String[] getParameters() {
 390  0
         Vector params = new Vector();
 391  0
         params.addElement("-jp_function=" + function);
 392  0
         if (vm != null) {
 393  0
             params.addElement("-jp_vm=" + vm);
 394   
         }
 395  0
         if (javaExe != null) {
 396  0
             params.addElement("-jp_java_exe=" + getProject().resolveFile(javaExe.getPath()));
 397   
         }
 398  0
         params.addElement("-jp_working_dir=" + workingDir.getPath());
 399  0
         params.addElement("-jp_snapshot_dir=" + snapshotDir.getPath());
 400  0
         params.addElement("-jp_record_from_start=" + recordFromStart);
 401  0
         params.addElement("-jp_warn=" + warnLevel);
 402  0
         if (seedName != null) {
 403  0
             params.addElement("-jp_output_file=" + seedName);
 404   
         }
 405  0
         params.addElement("-jp_filter=" + filters.toString());
 406  0
         if (triggers != null) {
 407  0
             params.addElement("-jp_trigger=" + triggers.toString());
 408   
         }
 409  0
         if (finalSnapshot != null) {
 410  0
             params.addElement("-jp_final_snapshot=" + finalSnapshot);
 411   
         }
 412  0
         params.addElement("-jp_exit_prompt=" + exitPrompt);
 413   
         //params.addElement("-jp_append=" + append);
 414  0
         params.addElement("-jp_track_natives=" + trackNatives);
 415   
         //.... now the jvm
 416   
         // arguments
 417  0
         String[] vmargs = cmdlJava.getVmCommand().getArguments();
 418  0
         for (int i = 0; i < vmargs.length; i++) {
 419  0
             params.addElement(vmargs[i]);
 420   
         }
 421   
         // classpath
 422  0
         Path classpath = cmdlJava.getClasspath();
 423  0
         if (classpath != null && classpath.size() > 0) {
 424  0
             params.addElement("-classpath " + classpath.toString());
 425   
         }
 426   
         // classname (runner or standalone)
 427  0
         if (cmdlJava.getClassname() != null) {
 428  0
             params.addElement(cmdlJava.getClassname());
 429   
         }
 430   
         // arguments for classname
 431  0
         String[] args = cmdlJava.getJavaCommand().getArguments();
 432  0
         for (int i = 0; i < args.length; i++) {
 433  0
             params.addElement(args[i]);
 434   
         }
 435   
 
 436  0
         String[] array = new String[params.size()];
 437  0
         params.copyInto(array);
 438  0
         return array;
 439   
     }
 440   
 
 441   
 
 442   
     /**
 443   
      * create the parameter file from the given options. The file is
 444   
      * created with a random name in the current directory.
 445   
      * @return the file object where are written the configuration to run
 446   
      * JProbe Coverage
 447   
      * @throws BuildException thrown if something bad happens while writing
 448   
      * the arguments to the file.
 449   
      */
 450  0
     protected File createParamFile() throws BuildException {
 451   
         //@todo change this when switching to JDK 1.2 and use File.createTmpFile()
 452  0
         File file = createTempFile("jpcov");
 453  0
         log("Creating parameter file: " + file, Project.MSG_VERBOSE);
 454   
 
 455   
         // options need to be one per line in the parameter file
 456   
         // so write them all in a single string
 457  0
         StringWriter sw = new StringWriter();
 458  0
         PrintWriter pw = new PrintWriter(sw);
 459  0
         String[] params = getParameters();
 460  0
         for (int i = 0; i < params.length; i++) {
 461  0
             pw.println(params[i]);
 462   
         }
 463  0
         pw.flush();
 464  0
         log("JProbe Coverage parameters:\n" + sw.toString(), Project.MSG_VERBOSE);
 465   
 
 466   
         // now write them to the file
 467  0
         FileWriter fw = null;
 468  0
         try {
 469  0
             fw = new FileWriter(file);
 470  0
             fw.write(sw.toString());
 471  0
             fw.flush();
 472   
         } catch (IOException e) {
 473  0
             throw new BuildException("Could not write parameter file " + file, e);
 474   
         } finally {
 475  0
             if (fw != null) {
 476  0
                 try {
 477  0
                     fw.close();
 478   
                 } catch (IOException ignored) {
 479   
                 }
 480   
             }
 481   
         }
 482  0
         return file;
 483   
     }
 484   
 
 485   
     /** specific pumper to avoid those nasty stdin issues */
 486   
     static class CoverageStreamHandler extends LogStreamHandler {
 487  0
         CoverageStreamHandler(Task task) {
 488  0
             super(task, Project.MSG_INFO, Project.MSG_WARN);
 489   
         }
 490   
 
 491   
         /**
 492   
          * there are some issues concerning all JProbe executable
 493   
          * In our case a 'Press ENTER to close this window..." will
 494   
          * be displayed in the current window waiting for enter.
 495   
          * So I'm closing the stream right away to avoid problems.
 496   
          */
 497  0
         public void setProcessInputStream(OutputStream os) {
 498  0
             try {
 499  0
                 os.close();
 500   
             } catch (IOException ignored) {
 501   
             }
 502   
         }
 503   
     }
 504   
 
 505   
 }
 506