Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 312   Methods: 15
NCLOC: 172   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
MParse.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.metamata;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.FileWriter;
 59   
 import java.io.IOException;
 60   
 import java.io.PrintWriter;
 61   
 import java.util.Vector;
 62   
 import org.apache.tools.ant.BuildException;
 63   
 import org.apache.tools.ant.Project;
 64   
 import org.apache.tools.ant.taskdefs.Execute;
 65   
 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
 66   
 import org.apache.tools.ant.taskdefs.LogStreamHandler;
 67   
 import org.apache.tools.ant.types.Commandline;
 68   
 import org.apache.tools.ant.types.Path;
 69   
 import org.apache.tools.ant.util.JavaEnvUtils;
 70   
 
 71   
 /**
 72   
  * Simple Metamata MParse task.
 73   
  * Based on the original written by
 74   
  * <a href="mailto:thomas.haas@softwired-inc.com">Thomas Haas</a>.
 75   
  *
 76   
  * This version was written for Metamata 2.0 available at
 77   
  * <a href="http://www.metamata.com">http://www.metamata.com</a>
 78   
  *
 79   
  * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
 80   
  * @todo make a subclass of AbstractMetaMataTask
 81   
  */
 82   
 public class MParse extends AbstractMetamataTask {
 83   
 
 84   
     private File target = null;
 85   
     private boolean verbose = false;
 86   
     private boolean debugparser = false;
 87   
     private boolean debugscanner = false;
 88   
     private boolean cleanup = false;
 89   
 
 90   
     /** The .jj file to process; required. */
 91  0
     public void setTarget(File target) {
 92  0
         this.target = target;
 93   
     }
 94   
 
 95   
     /** set verbose mode */
 96  0
     public void setVerbose(boolean flag){
 97  0
         verbose = flag;
 98   
     }
 99   
 
 100   
     /** set scanner debug mode; optional, default false */
 101  0
     public void setDebugscanner(boolean flag){
 102  0
         debugscanner = flag;
 103   
     }
 104   
 
 105   
     /** set parser debug mode; optional, default false */
 106  0
     public void setDebugparser(boolean flag){
 107  0
         debugparser = flag;
 108   
     }
 109   
 
 110   
     /** Remove the intermediate Sun JavaCC file
 111   
      * ; optional, default false.
 112   
      */
 113  0
     public void setCleanup(boolean value) {
 114  0
         cleanup = value;
 115   
     }
 116   
 
 117  0
     public MParse() {
 118  0
         cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
 119  0
         cmdl.setClassname("com.metamata.jj.MParse");
 120   
     }
 121   
 
 122   
 
 123   
     /** execute the command line */
 124  0
     public void execute() throws BuildException {
 125  0
         try {
 126  0
             setUp();
 127  0
             ExecuteStreamHandler handler = createStreamHandler();
 128  0
             _execute(handler);
 129   
         } finally {
 130  0
             cleanUp();
 131   
         }
 132   
     }
 133   
 
 134   
     /** return the default stream handler for this task */
 135  0
     protected ExecuteStreamHandler createStreamHandler(){
 136  0
         return new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_INFO);
 137   
     }
 138   
 
 139   
     /**
 140   
      * check the options and build the command line
 141   
      */
 142  0
     protected void setUp() throws BuildException {
 143  0
         checkOptions();
 144   
 
 145   
         // set the classpath as the jar files
 146  0
         File[] jars = getMetamataLibs();
 147  0
         final Path classPath = cmdl.createClasspath(getProject());
 148  0
         for (int i = 0; i < jars.length; i++){
 149  0
             classPath.createPathElement().setLocation(jars[i]);
 150   
         }
 151   
 
 152   
         // set the metamata.home property
 153  0
         final Commandline.Argument vmArgs = cmdl.createVmArgument();
 154  0
         vmArgs.setValue("-Dmetamata.home=" + metamataHome.getAbsolutePath());
 155   
 
 156   
 
 157   
         // write all the options to a temp file and use it ro run the process
 158  0
         Vector opts = getOptions();
 159  0
         String[] options = new String[ opts.size() ];
 160  0
         opts.copyInto(options);
 161   
 
 162  0
         optionsFile = createTmpFile();
 163  0
         generateOptionsFile(optionsFile, options);
 164  0
         Commandline.Argument args = cmdl.createArgument();
 165  0
         args.setLine("-arguments " + optionsFile.getAbsolutePath());
 166   
     }
 167   
 
 168   
 
 169   
     /** execute the process with a specific handler */
 170  0
     protected void _execute(ExecuteStreamHandler handler) throws BuildException {
 171   
         // target has been checked as a .jj, see if there is a matching
 172   
         // java file and if it is needed to run to process the grammar
 173  0
         String pathname = target.getAbsolutePath();
 174  0
         int pos = pathname.length() - ".jj".length();
 175  0
         pathname = pathname.substring(0, pos) + ".java";
 176  0
         File javaFile = new File(pathname);
 177  0
         if (javaFile.exists() && target.lastModified() < javaFile.lastModified()) {
 178  0
             getProject().log("Target is already build - skipping (" + target + ")");
 179  0
             return;
 180   
         }
 181   
 
 182  0
         final Execute process = new Execute(handler);
 183  0
         log(cmdl.describeCommand(), Project.MSG_VERBOSE);
 184  0
         process.setCommandline(cmdl.getCommandline());
 185  0
         try {
 186  0
             if (process.execute() != 0) {
 187  0
                 throw new BuildException("Metamata task failed.");
 188   
             }
 189   
         } catch (IOException e){
 190  0
             throw new BuildException("Failed to launch Metamata task: ", e);
 191   
         }
 192   
     }
 193   
 
 194   
     /** clean up all the mess that we did with temporary objects */
 195  0
     protected void cleanUp(){
 196  0
         if (optionsFile != null){
 197  0
             optionsFile.delete();
 198  0
             optionsFile = null;
 199   
         }
 200  0
         if (cleanup) {
 201  0
             String name = target.getName();
 202  0
             int pos = name.length() - ".jj".length();
 203  0
             name = "__jj" + name.substring(0, pos) + ".sunjj";
 204  0
             final File sunjj = new File(target.getParent(), name);
 205  0
             if (sunjj.exists()) {
 206  0
                 getProject().log("Removing stale file: " + sunjj.getName());
 207  0
                 sunjj.delete();
 208   
             }
 209   
         }
 210   
     }
 211   
 
 212   
     /**
 213   
      * return an array of files containing the path to the needed
 214   
      * libraries to run metamata. The file are not checked for
 215   
      * existence. You should do this yourself if needed or simply let the
 216   
      * forked process do it for you.
 217   
      * @return array of jars/zips needed to run metamata.
 218   
      */
 219  0
     protected File[] getMetamataLibs(){
 220  0
         Vector files = new Vector();
 221  0
         files.addElement(new File(metamataHome, "lib/metamata.jar"));
 222  0
         files.addElement(new File(metamataHome, "bin/lib/JavaCC.zip"));
 223   
 
 224  0
         File[] array = new File[ files.size() ];
 225  0
         files.copyInto(array);
 226  0
         return array;
 227   
     }
 228   
 
 229   
 
 230   
     /**
 231   
      * validate options set and resolve files and paths
 232   
      * @throws BuildException thrown if an option has an incorrect state.
 233   
      */
 234  0
     protected void checkOptions() throws BuildException {
 235   
         // check that the home is ok.
 236  0
         if (metamataHome == null || !metamataHome.exists()){
 237  0
             throw new BuildException("'metamatahome' must point to Metamata home directory.");
 238   
         }
 239  0
         metamataHome = getProject().resolveFile(metamataHome.getPath());
 240   
 
 241   
         // check that the needed jar exists.
 242  0
         File[] jars = getMetamataLibs();
 243  0
         for (int i = 0; i < jars.length; i++){
 244  0
             if (!jars[i].exists()){
 245  0
                 throw new BuildException(jars[i]
 246   
                     + " does not exist. Check your metamata installation.");
 247   
             }
 248   
         }
 249   
 
 250   
         // check that the target is ok and resolve it.
 251  0
         if (target == null || !target.isFile()
 252   
             || !target.getName().endsWith(".jj")) {
 253  0
             throw new BuildException("Invalid target: " + target);
 254   
         }
 255  0
         target = getProject().resolveFile(target.getPath());
 256   
     }
 257   
 
 258   
     /**
 259   
      * return all options of the command line as string elements
 260   
      * @return an array of options corresponding to the setted options.
 261   
      */
 262  0
     protected Vector getOptions() {
 263  0
         Vector options = new Vector();
 264  0
         if (verbose){
 265  0
             options.addElement("-verbose");
 266   
         }
 267  0
         if (debugscanner){
 268  0
             options.addElement("-ds");
 269   
         }
 270  0
         if (debugparser){
 271  0
             options.addElement("-dp");
 272   
         }
 273  0
         if (classPath != null){
 274  0
             options.addElement("-classpath");
 275  0
             options.addElement(classPath.toString());
 276   
         }
 277  0
         if (sourcePath != null){
 278  0
             options.addElement("-sourcepath");
 279  0
             options.addElement(sourcePath.toString());
 280   
         }
 281  0
         options.addElement(target.getAbsolutePath());
 282  0
         return options;
 283   
     }
 284   
 
 285   
     /**
 286   
      * write all options to a file with one option / line
 287   
      * @param tofile the file to write the options to.
 288   
      * @param options the array of options element to write to the file.
 289   
      * @throws BuildException thrown if there is a problem while writing
 290   
      * to the file.
 291   
      */
 292  0
     protected void generateOptionsFile(File tofile, String[] options) throws BuildException {
 293  0
         FileWriter fw = null;
 294  0
         try {
 295  0
             fw = new FileWriter(tofile);
 296  0
             PrintWriter pw = new PrintWriter(fw);
 297  0
             for (int i = 0; i < options.length; i++){
 298  0
                 pw.println(options[i]);
 299   
             }
 300  0
             pw.flush();
 301   
         } catch (IOException e){
 302  0
             throw new BuildException("Error while writing options file " + tofile, e);
 303   
         } finally {
 304  0
             if (fw != null){
 305  0
                 try {
 306  0
                     fw.close();
 307   
                 } catch (IOException ignored){}
 308   
             }
 309   
         }
 310   
     }
 311   
 }
 312