Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 339   Methods: 8
NCLOC: 152   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
WLJspc.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000,2002-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   
 package org.apache.tools.ant.taskdefs.optional.jsp;
 55   
 
 56   
 //apache/ant imports
 57   
 import java.io.File;
 58   
 import java.util.Date;
 59   
 import java.util.StringTokenizer;
 60   
 import java.util.Vector;
 61   
 import org.apache.tools.ant.BuildException;
 62   
 import org.apache.tools.ant.DirectoryScanner;
 63   
 import org.apache.tools.ant.Project;
 64   
 import org.apache.tools.ant.taskdefs.Java;
 65   
 import org.apache.tools.ant.taskdefs.MatchingTask;
 66   
 import org.apache.tools.ant.types.Path;
 67   
 
 68   
 /**
 69   
  * Precompiles JSP's using WebLogic's JSP compiler (weblogic.jspc).
 70   
  * 
 71   
  * @author <a href="mailto:avik@aviksengupta.com">Avik Sengupta</a> http://www.webteksoftware.com
 72   
  * 
 73   
  * Tested only on Weblogic 4.5.1 - NT4.0 and Solaris 5.7
 74   
  * 
 75   
  * required attributes
 76   
  *      src : root of source tree for JSP, ie, the document root for your weblogic server
 77   
  *      dest : root of destination directory, what you have set as WorkingDir in the weblogic properties
 78   
  *      package : start package name under which your JSP's would be compiled
 79   
  * 
 80   
  * other attributes
 81   
  *     classpath
 82   
  * 
 83   
  * A classpath should be set which contains the weblogic classes as well as all application classes
 84   
  * referenced by the JSP. The system classpath is also appended when the jspc is called, so you may 
 85   
  * choose to put everything in the classpath while calling Ant. However, since presumably the JSP's will reference
 86   
  * classes being build by Ant, it would be better to explicitly add the classpath in the task
 87   
  * 
 88   
  * The task checks timestamps on the JSP's and the generated classes, and compiles
 89   
  * only those files that have changed. 
 90   
  * 
 91   
  * It follows the weblogic naming convention of putting classes in 
 92   
  *  <b> _dirName/_fileName.class for dirname/fileName.jsp   </b>
 93   
  * 
 94   
  * Limitation: It compiles the files thru the Classic compiler only. 
 95   
  * Limitation: Since it is my experience that weblogic jspc throws out of memory error on being given too
 96   
  *             many files at one go, it is called multiple times with one jsp file each. 
 97   
  * 
 98   
  * <pre>
 99   
  * example
 100   
  * &lt;target name="jspcompile" depends="compile"&gt;
 101   
  *   &lt;wljspc src="c:\\weblogic\\myserver\\public_html" dest="c:\\weblogic\\myserver\\serverclasses" package="myapp.jsp"&gt;
 102   
  *   &lt;classpath&gt;
 103   
  *          &lt;pathelement location="${weblogic.classpath}" /&gt;
 104   
  *           &lt;pathelement path="${compile.dest}" /&gt;
 105   
  *      &lt;/classpath&gt;
 106   
  * 
 107   
  *   &lt;/wljspc&gt;
 108   
  * &lt;/target&gt;
 109   
  * </pre>
 110   
  * 
 111   
  */
 112   
 
 113   
 public class WLJspc extends MatchingTask {
 114   
     //TODO Test on other versions of weblogic
 115   
     //TODO add more attributes to the task, to take care of all jspc options
 116   
     //TODO Test on Unix
 117   
     
 118   
     private File destinationDirectory; //root of compiled files tree
 119   
     private File sourceDirectory; // root of source files tree
 120   
     private String destinationPackage; //package under which resultant classes will reside
 121   
     private Path compileClasspath; //classpath used to compile the jsp files. 
 122   
     //private String compilerPath; //fully qualified name for the compiler executable
 123   
     
 124   
     private String pathToPackage = "";
 125   
     private Vector filesToDo = new Vector();
 126   
     
 127  0
     public void execute() throws BuildException {
 128  0
         if (!destinationDirectory.isDirectory()) {
 129  0
             throw new BuildException("destination directory " + destinationDirectory.getPath() + 
 130   
                                      " is not valid");
 131   
         }
 132   
                                
 133  0
         if (!sourceDirectory.isDirectory()) {
 134  0
             throw new BuildException("src directory " + sourceDirectory.getPath() + 
 135   
                                      " is not valid");
 136   
         }
 137   
 
 138  0
         if (destinationPackage == null) {
 139  0
             throw new BuildException("package attribute must be present.", getLocation());
 140   
         }
 141   
         
 142   
         
 143  0
         pathToPackage
 144   
             = this.destinationPackage.replace('.', File.separatorChar);
 145   
         // get all the files in the sourceDirectory
 146  0
         DirectoryScanner ds = super.getDirectoryScanner(sourceDirectory);
 147   
 
 148   
         //use the systemclasspath as well, to include the ant jar
 149  0
         if (compileClasspath == null) {
 150  0
             compileClasspath = new Path(getProject());
 151   
         }
 152   
         
 153  0
         compileClasspath = compileClasspath.concatSystemClasspath();
 154  0
         String[] files = ds.getIncludedFiles();
 155   
         
 156   
         //Weblogic.jspc calls System.exit() ... have to fork
 157   
         // Therefore, takes loads of time 
 158   
         // Can pass directories at a time (*.jsp) but easily runs out of memory on hefty dirs 
 159   
         // (even on  a Sun)
 160  0
         Java helperTask = (Java) getProject().createTask("java");
 161  0
         helperTask.setFork(true);
 162  0
         helperTask.setClassname("weblogic.jspc");
 163  0
         helperTask.setTaskName(getTaskName());
 164  0
         String[] args = new String[12];
 165   
         
 166  0
         File jspFile = null;
 167  0
         String parents = "";
 168  0
         int j = 0;
 169   
         //XXX  this array stuff is a remnant of prev trials.. gotta remove. 
 170  0
         args[j++] = "-d";
 171  0
         args[j++] = destinationDirectory.getAbsolutePath().trim(); 
 172  0
         args[j++] = "-docroot";
 173  0
         args[j++] = sourceDirectory.getAbsolutePath().trim();
 174  0
         args[j++] = "-keepgenerated";  //TODO: Parameterise ??
 175   
         //Call compiler as class... dont want to fork again 
 176   
         //Use classic compiler -- can be parameterised?
 177  0
         args[j++] =  "-compilerclass";
 178  0
         args[j++] = "sun.tools.javac.Main";
 179   
         //Weblogic jspc does not seem to work unless u explicitly set this...
 180   
         // Does not take the classpath from the env....
 181   
         // Am i missing something about the Java task??
 182  0
         args[j++] = "-classpath";
 183  0
         args[j++] = compileClasspath.toString();
 184   
             
 185  0
         this.scanDir(files);
 186  0
         log("Compiling " + filesToDo.size() + " JSP files");
 187   
             
 188  0
         for (int i = 0; i < filesToDo.size(); i++) {
 189   
             //XXX
 190   
             // All this to get package according to weblogic standards
 191   
             // Can be written better... this is too hacky! 
 192   
             // Careful.. similar code in scanDir , but slightly different!!
 193  0
             String filename = (String) filesToDo.elementAt(i);
 194  0
             jspFile = new File(filename);
 195  0
             args[j] = "-package";
 196  0
             parents = jspFile.getParent();
 197  0
             if ((parents != null)  && (!("").equals(parents))) {
 198  0
                 parents =  this.replaceString(parents, File.separator, "_.");
 199  0
                 args[j + 1] = destinationPackage + "." + "_" + parents;
 200   
             } else {
 201  0
                 args[j + 1] = destinationPackage;
 202   
             }
 203   
             
 204   
             
 205  0
             args[j + 2] =  sourceDirectory + File.separator + filename;
 206  0
             helperTask.clearArgs();
 207   
             
 208  0
             for (int x = 0; x < j + 3; x++) {
 209  0
                 helperTask.createArg().setValue(args[x]);
 210   
             }
 211   
             
 212  0
             helperTask.setClasspath(compileClasspath);
 213  0
             if (helperTask.executeJava() != 0) {                         
 214  0
                 log(filename + " failed to compile", Project.MSG_WARN);
 215   
             }
 216   
         }
 217   
     }
 218   
 
 219   
     
 220   
     
 221   
     /**
 222   
      * Set the classpath to be used for this compilation.
 223   
      * 
 224   
      */
 225  0
     public void setClasspath(Path classpath) {
 226  0
         if (compileClasspath == null) {
 227  0
             compileClasspath = classpath;
 228   
         } else {
 229  0
             compileClasspath.append(classpath);
 230   
         }
 231   
     }
 232   
 
 233   
     /**
 234   
      * Maybe creates a nested classpath element.
 235   
      */
 236  0
     public Path createClasspath() {
 237  0
         if (compileClasspath == null) {
 238  0
             compileClasspath = new Path(getProject());
 239   
         }
 240  0
         return compileClasspath;
 241   
     }
 242   
 
 243   
     /**
 244   
      * Set the directory containing the source jsp's
 245   
      * 
 246   
      *
 247   
      * @param dirName the directory containg the source jsp's
 248   
      */
 249  0
     public void setSrc(File dirName) {
 250   
         
 251  0
         sourceDirectory = dirName;
 252   
     }
 253   
     
 254   
      /**
 255   
      * Set the directory containing the source jsp's
 256   
      * 
 257   
      *
 258   
      * @param dirName the directory containg the source jsp's
 259   
      */
 260  0
     public void setDest(File dirName) {
 261   
         
 262  0
         destinationDirectory = dirName;
 263   
     }
 264   
     
 265   
     /**
 266   
      * Set the package under which the compiled classes go
 267   
      * 
 268   
      * @param packageName the package name for the clases
 269   
      */
 270  0
     public void setPackage(String packageName) {
 271   
         
 272  0
         destinationPackage = packageName; 
 273   
     }
 274   
     
 275   
     
 276   
     
 277  0
     protected void scanDir(String files[]) {
 278   
 
 279  0
         long now = (new Date()).getTime();
 280  0
         File jspFile = null;
 281  0
         String parents = null;
 282  0
         String pack = "";
 283  0
         for (int i = 0; i < files.length; i++) {
 284  0
             File srcFile = new File(this.sourceDirectory, files[i]);
 285   
             //XXX
 286   
             // All this to convert source to destination directory according to weblogic standards
 287   
             // Can be written better... this is too hacky!
 288  0
             jspFile = new File(files[i]);
 289  0
             parents = jspFile.getParent();
 290   
 
 291  0
             if ((parents != null)  && (!("").equals(parents))) {
 292  0
                 parents =  this.replaceString(parents, File.separator, "_/");
 293  0
                 pack = pathToPackage + File.separator + "_" + parents;
 294   
             } else {
 295  0
                 pack = pathToPackage;
 296   
             }
 297   
             
 298  0
             String filePath = pack + File.separator + "_";
 299  0
             int startingIndex 
 300   
                 = files[i].lastIndexOf(File.separator) != -1 ? files[i].lastIndexOf(File.separator) + 1 : 0;
 301  0
             int endingIndex = files[i].indexOf(".jsp");
 302  0
             if (endingIndex == -1) {
 303  0
                 log("Skipping " + files[i] + ". Not a JSP", 
 304   
                     Project.MSG_VERBOSE);
 305  0
                 continue;
 306   
             }
 307   
             
 308  0
             filePath += files[i].substring(startingIndex, endingIndex);
 309  0
             filePath += ".class";
 310  0
             File classFile = new File(this.destinationDirectory, filePath);
 311   
 
 312  0
             if (srcFile.lastModified() > now) {
 313  0
                 log("Warning: file modified in the future: " +
 314   
                     files[i], Project.MSG_WARN);
 315   
             }
 316  0
             if (srcFile.lastModified() > classFile.lastModified()) {
 317   
                //log("Files are" + srcFile.getAbsolutePath()+" " +classFile.getAbsolutePath());
 318  0
                 filesToDo.addElement(files[i]);
 319  0
                 log("Recompiling File " + files[i], Project.MSG_VERBOSE);
 320   
             }
 321   
         }
 322   
     }
 323   
     
 324   
     
 325  0
     protected String replaceString(String inpString, String escapeChars,
 326   
                                    String replaceChars) {
 327  0
         String localString = "";
 328  0
         int numTokens = 0;
 329  0
         StringTokenizer st = new StringTokenizer(inpString, escapeChars, true);
 330  0
         numTokens = st.countTokens();
 331  0
         for (int i = 0; i < numTokens; i++) {
 332  0
             String test = st.nextToken();
 333  0
             test = (test.equals(escapeChars) ? replaceChars : test);
 334  0
             localString += test;
 335   
         }
 336  0
         return localString;
 337   
     }
 338   
 }
 339