Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 422   Methods: 12
NCLOC: 152   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
IPlanetDeploymentTool.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2001-2002 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.ejb;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.IOException;
 59   
 import java.util.Hashtable;
 60   
 import javax.xml.parsers.SAXParser;
 61   
 import org.apache.tools.ant.BuildException;
 62   
 import org.apache.tools.ant.Project;
 63   
 import org.xml.sax.SAXException;
 64   
 
 65   
 /**
 66   
  * This class is used to generate iPlanet Application Server (iAS) 6.0 stubs and
 67   
  * skeletons and build an EJB Jar file.  It is designed to be used with the Ant
 68   
  * <code>ejbjar</code> task.  If only stubs and skeletons need to be generated
 69   
  * (in other words, if no JAR file needs to be created), refer to the
 70   
  * <code>iplanet-ejbc</code> task and the <code>IPlanetEjbcTask</code> class.
 71   
  * <p>
 72   
  * The following attributes may be specified by the user:
 73   
  *   <ul>
 74   
  *     <li><i>destdir</i> -- The base directory into which the generated JAR
 75   
  *                           files will be written.  Each JAR file is written
 76   
  *                           in directories which correspond to their location
 77   
  *                           within the "descriptordir" namespace.  This is a
 78   
  *                           required attribute.
 79   
  *     <li><i>classpath</i> -- The classpath used when generating EJB stubs and
 80   
  *                             skeletons.  This is an optional attribute (if
 81   
  *                             omitted, the classpath specified in the "ejbjar"
 82   
  *                             parent task will be used).  If specified, the
 83   
  *                             classpath elements will be prepended to the
 84   
  *                             classpath specified in the parent "ejbjar" task.
 85   
  *                             Note that nested "classpath" elements may also be
 86   
  *                             used.
 87   
  *     <li><i>keepgenerated</i> -- Indicates whether or not the Java source
 88   
  *                                 files which are generated by ejbc will be
 89   
  *                                 saved or automatically deleted.  If "yes",
 90   
  *                                 the source files will be retained.  This is
 91   
  *                                 an optional attribute (if omitted, it
 92   
  *                                 defaults to "no").
 93   
  *     <li><i>debug</i> -- Indicates whether or not the ejbc utility should
 94   
  *                         log additional debugging statements to the standard
 95   
  *                         output.  If "yes", the additional debugging statements
 96   
  *                         will be generated (if omitted, it defaults to "no").
 97   
  *     <li><i>iashome</i> -- May be used to specify the "home" directory for
 98   
  *                           this iPlanet Application server installation.  This
 99   
  *                           is used to find the ejbc utility if it isn't
 100   
  *                           included in the user's system path.  This is an
 101   
  *                           optional attribute (if specified, it should refer
 102   
  *                           to the <code>[install-location]/iplanet/ias6/ias
 103   
  *                           </code> directory).  If omitted, the ejbc utility
 104   
  *                           must be on the user's system path.
 105   
  *     <li><i>suffix</i> -- String value appended to the JAR filename when
 106   
  *                          creating each JAR.  This attribute is not required
 107   
  *                          (if omitted, it defaults to ".jar").
 108   
  *   </ul>
 109   
  * <p>
 110   
  * For each EJB descriptor found in the "ejbjar" parent task, this deployment
 111   
  * tool will locate the three classes that comprise the EJB.  If these class
 112   
  * files cannot be located in the specified <code>srcdir</code> directory, the
 113   
  * task will fail.  The task will also attempt to locate the EJB stubs and
 114   
  * skeletons in this directory.  If found, the timestamps on the stubs and
 115   
  * skeletons will be checked to ensure they are up to date.  Only if these files
 116   
  * cannot be found or if they are out of date will ejbc be called.
 117   
  *
 118   
  * @see    IPlanetEjbc
 119   
  * @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
 120   
  */
 121   
 public class IPlanetDeploymentTool extends GenericDeploymentTool {
 122   
 
 123   
     /* Attributes set by the Ant build file */
 124   
     private File    iashome;
 125   
     private String  jarSuffix     = ".jar";
 126   
     private boolean keepgenerated = false;
 127   
     private boolean debug         = false;
 128   
 
 129   
     /*
 130   
      * Filenames of the standard EJB descriptor (which is passed to this class
 131   
      * from the parent "ejbjar" task) and the iAS-specific EJB descriptor
 132   
      * (whose name is determined by this class).  Both filenames are relative
 133   
      * to the directory specified by the "srcdir" attribute in the ejbjar task.
 134   
      */
 135   
     private String  descriptorName;
 136   
     private String  iasDescriptorName;
 137   
 
 138   
     /*
 139   
      * The displayName variable stores the value of the "display-name" element
 140   
      * from the standard EJB descriptor.  As a future enhancement to this task,
 141   
      * we may determine the name of the EJB JAR file using this display-name,
 142   
      * but this has not be implemented yet.
 143   
      */
 144   
     private String  displayName;
 145   
 
 146   
     /*
 147   
      * Regardless of the name of the iAS-specific EJB descriptor file, it will
 148   
      * written in the completed JAR file as "ias-ejb-jar.xml".  This is the
 149   
      * naming convention implemented by iAS.
 150   
      */
 151   
     private static final String IAS_DD = "ias-ejb-jar.xml";
 152   
 
 153   
     /**
 154   
      * Setter method used to store the "home" directory of the user's iAS
 155   
      * installation.  The directory specified should typically be
 156   
      * <code>[install-location]/iplanet/ias6/ias</code>.
 157   
      *
 158   
      * @param iashome The home directory for the user's iAS installation.
 159   
      */
 160  0
     public void setIashome(File iashome) {
 161  0
         this.iashome = iashome;
 162   
     }
 163   
 
 164   
     /**
 165   
      * Setter method used to specify whether the Java source files generated by
 166   
      * the ejbc utility should be saved or automatically deleted.
 167   
      *
 168   
      * @param keepgenerated boolean which, if <code>true</code>, indicates that
 169   
      *                      Java source files generated by ejbc for the stubs
 170   
      *                      and skeletons should be kept.
 171   
      */
 172  0
     public void setKeepgenerated(boolean keepgenerated) {
 173  0
         this.keepgenerated = keepgenerated;
 174   
     }
 175   
 
 176   
     /**
 177   
      * Sets whether or not debugging output will be generated when ejbc is
 178   
      * executed.
 179   
      *
 180   
      * @param debug A boolean indicating if debugging output should be generated
 181   
      */
 182  0
     public void setDebug(boolean debug) {
 183  0
         this.debug = debug;
 184   
     }
 185   
 
 186   
     /**
 187   
      * Setter method used to specify the filename suffix (for example, ".jar")
 188   
      * for the JAR files to be created.
 189   
      *
 190   
      * @param jarSuffix The string to use as the JAR filename suffix.
 191   
      */
 192  0
     public void setSuffix(String jarSuffix) {
 193  0
         this.jarSuffix = jarSuffix;
 194   
     }
 195   
 
 196   
     /**
 197   
      * Since iAS doesn't generate a "generic" JAR as part of its processing,
 198   
      * this attribute is ignored and a warning message is displayed to the user.
 199   
      *
 200   
      * @param inString the string to use as the suffix.  This parameter is
 201   
      *                 ignored.
 202   
      */
 203  0
     public void setGenericJarSuffix(String inString) {
 204  0
         log("Since a generic JAR file is not created during processing, the "
 205   
                 + "iPlanet Deployment Tool does not support the "
 206   
                 + "\"genericjarsuffix\" attribute.  It will be ignored.",
 207   
             Project.MSG_WARN);
 208   
     }
 209   
 
 210  0
     public void processDescriptor(String descriptorName, SAXParser saxParser) {
 211  0
         this.descriptorName = descriptorName;
 212  0
         this.iasDescriptorName = null;
 213   
 
 214  0
         log("iPlanet Deployment Tool processing: " + descriptorName + " (and "
 215   
                 + getIasDescriptorName() + ")", Project.MSG_VERBOSE);
 216   
 
 217  0
         super.processDescriptor(descriptorName, saxParser);
 218   
     }
 219   
 
 220   
     /**
 221   
      * Verifies that the user selections are valid.
 222   
      *
 223   
      * @param descriptorFileName String representing the file name of an EJB
 224   
      *                           descriptor to be processed
 225   
      * @param saxParser          SAXParser which may be used to parse the XML
 226   
      *                           descriptor
 227   
      * @throws BuildException If the user selections are invalid.
 228   
      */
 229  0
     protected void checkConfiguration(String descriptorFileName,
 230   
                                     SAXParser saxParser) throws BuildException {
 231   
 
 232  0
         int startOfName = descriptorFileName.lastIndexOf(File.separatorChar) + 1;
 233  0
         String stdXml = descriptorFileName.substring(startOfName);
 234  0
         if (stdXml.equals(EJB_DD) && (getConfig().baseJarName == null)) {
 235  0
             String msg = "No name specified for the completed JAR file.  The EJB"
 236   
                             + " descriptor should be prepended with the JAR "
 237   
                             + "name or it should be specified using the "
 238   
                             + "attribute \"basejarname\" in the \"ejbjar\" task.";
 239  0
             throw new BuildException(msg, getLocation());
 240   
         }
 241   
 
 242  0
         File iasDescriptor = new File(getConfig().descriptorDir,
 243   
                                         getIasDescriptorName());
 244  0
         if ((!iasDescriptor.exists()) || (!iasDescriptor.isFile())) {
 245  0
             String msg = "The iAS-specific EJB descriptor ("
 246   
                             + iasDescriptor + ") was not found.";
 247  0
             throw new BuildException(msg, getLocation());
 248   
         }
 249   
 
 250  0
         if ((iashome != null) && (!iashome.isDirectory())) {
 251  0
             String msg = "If \"iashome\" is specified, it must be a valid "
 252   
                             + "directory (it was set to " + iashome + ").";
 253  0
             throw new BuildException(msg, getLocation());
 254   
         }
 255   
     }
 256   
 
 257   
     /**
 258   
      * This method returns a list of EJB files found when the specified EJB
 259   
      * descriptor is parsed and processed.
 260   
      *
 261   
      * @param descriptorFileName String representing the file name of an EJB
 262   
      *                           descriptor to be processed
 263   
      * @param saxParser          SAXParser which may be used to parse the XML
 264   
      *                           descriptor
 265   
      * @return                   Hashtable of EJB class (and other) files to be
 266   
      *                           added to the completed JAR file
 267   
      * @throws IOException       An IOException from the parser, possibly from
 268   
      *                           the byte stream or character stream
 269   
      * @throws SAXException      Any SAX exception, possibly wrapping another
 270   
      *                           exception
 271   
      */
 272  0
     protected Hashtable parseEjbFiles(String descriptorFileName,
 273   
                          SAXParser saxParser) throws IOException, SAXException {
 274   
 
 275  0
         Hashtable files;
 276   
 
 277   
         /* Build and populate an instance of the ejbc utility */
 278  0
         IPlanetEjbc ejbc = new IPlanetEjbc(
 279   
                                     new File(getConfig().descriptorDir,
 280   
                                                 descriptorFileName),
 281   
                                     new File(getConfig().descriptorDir,
 282   
                                                 getIasDescriptorName()),
 283   
                                     getConfig().srcDir,
 284   
                                     getCombinedClasspath().toString(),
 285   
                                     saxParser);
 286  0
         ejbc.setRetainSource(keepgenerated);
 287  0
         ejbc.setDebugOutput(debug);
 288  0
         if (iashome != null) {
 289  0
             ejbc.setIasHomeDir(iashome);
 290   
         }
 291   
 
 292   
         /* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed */
 293  0
         try {
 294  0
             ejbc.execute();
 295   
         } catch (IPlanetEjbc.EjbcException e) {
 296  0
             throw new BuildException("An error has occurred while trying to "
 297   
                         + "execute the iAS ejbc utility", e, getLocation());
 298   
         }
 299   
 
 300  0
         displayName    = ejbc.getDisplayName();
 301  0
         files          = ejbc.getEjbFiles();
 302   
 
 303   
         /* Add CMP descriptors to the list of EJB files */
 304  0
         String[] cmpDescriptors = ejbc.getCmpDescriptors();
 305  0
         if (cmpDescriptors.length > 0) {
 306  0
             File baseDir = getConfig().descriptorDir;
 307   
 
 308  0
             int endOfPath = descriptorFileName.lastIndexOf(File.separator);
 309  0
             String relativePath = descriptorFileName.substring(0, endOfPath + 1);
 310   
 
 311  0
             for (int i = 0; i < cmpDescriptors.length; i++) {
 312  0
                 int endOfCmp = cmpDescriptors[i].lastIndexOf('/');
 313  0
                 String cmpDescriptor = cmpDescriptors[i].substring(endOfCmp + 1);
 314   
 
 315  0
                 File   cmpFile = new File(baseDir, relativePath + cmpDescriptor);
 316  0
                 if (!cmpFile.exists()) {
 317  0
                     throw new BuildException("The CMP descriptor file ("
 318   
                             + cmpFile + ") could not be found.", getLocation());
 319   
                 }
 320  0
                 files.put(cmpDescriptors[i], cmpFile);
 321   
             }
 322   
         }
 323   
 
 324  0
         return files;
 325   
     }
 326   
 
 327   
     /**
 328   
      * Add the iAS-specific EJB descriptor to the list of files which will be
 329   
      * written to the JAR file.
 330   
      *
 331   
      * @param ejbFiles Hashtable of EJB class (and other) files to be added to
 332   
      *                 the completed JAR file.
 333   
      * @param baseName String name of the EJB JAR file to be written (without
 334   
      *                 a filename extension).
 335   
      */
 336  0
     protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
 337  0
         ejbFiles.put(META_DIR + IAS_DD, new File(getConfig().descriptorDir,
 338   
                      getIasDescriptorName()));
 339   
     }
 340   
 
 341   
     /**
 342   
      * Get the name of the Jar that will be written. The modification date
 343   
      * of this jar will be checked against the dependent bean classes.
 344   
      *
 345   
      * @param baseName String name of the EJB JAR file to be written (without
 346   
      *                 a filename extension).
 347   
      *
 348   
      * @return File representing the JAR file which will be written.
 349   
      */
 350  0
     File getVendorOutputJarFile(String baseName) {
 351  0
         File jarFile = new File(getDestDir(), baseName + jarSuffix);
 352  0
         log("JAR file name: " + jarFile.toString(), Project.MSG_VERBOSE);
 353  0
         return jarFile;
 354   
     }
 355   
 
 356   
     /**
 357   
      * The iAS ejbc utility doesn't require the Public ID of the descriptor's
 358   
      * DTD for it to process correctly--this method always returns <code>null
 359   
      * </code>.
 360   
      *
 361   
      * @return <code>null</code>.
 362   
      */
 363  0
     protected String getPublicId() {
 364  0
         return null;
 365   
     }
 366   
 
 367   
     /**
 368   
      * Determines the name of the iAS-specific EJB descriptor using the
 369   
      * specified standard EJB descriptor name.  In general, the standard
 370   
      * descriptor will be named "[basename]-ejb-jar.xml", and this method will
 371   
      * return "[basename]-ias-ejb-jar.xml".
 372   
      *
 373   
      * @return The name of the iAS-specific EJB descriptor file.
 374   
      */
 375  0
     private String getIasDescriptorName() {
 376   
 
 377   
         /* Only calculate the descriptor name once */
 378  0
         if (iasDescriptorName != null) {
 379  0
             return iasDescriptorName;
 380   
         }
 381   
 
 382  0
         String path = "";   // Directory path of the EJB descriptor
 383  0
         String basename;    // Filename appearing before name terminator
 384  0
         String remainder;   // Filename appearing after the name terminator
 385   
 
 386   
         /* Find the end of the standard descriptor's relative path */
 387  0
         int startOfFileName = descriptorName.lastIndexOf(File.separatorChar);
 388  0
         if (startOfFileName != -1) {
 389  0
             path = descriptorName.substring(0, startOfFileName + 1);
 390   
         }
 391   
 
 392   
         /* Check to see if the standard name is used (there's no basename) */
 393  0
         if (descriptorName.substring(startOfFileName + 1).equals(EJB_DD)) {
 394  0
             basename = "";
 395  0
             remainder = EJB_DD;
 396   
 
 397   
         } else {
 398  0
             int endOfBaseName = descriptorName.indexOf(
 399   
                                                 getConfig().baseNameTerminator,
 400   
                                                 startOfFileName);
 401   
             /*
 402   
              * Check for the odd case where the terminator and/or filename
 403   
              * extension aren't found.  These will ensure "ias-" appears at the
 404   
              * end of the name and before the '.' (if present).
 405   
              */
 406  0
             if (endOfBaseName < 0) {
 407  0
                 endOfBaseName = descriptorName.lastIndexOf('.') - 1;
 408  0
                 if (endOfBaseName < 0) {
 409  0
                     endOfBaseName = descriptorName.length() - 1;
 410   
                 }
 411   
             }
 412   
 
 413  0
             basename = descriptorName.substring(startOfFileName + 1,
 414   
                                                 endOfBaseName + 1);
 415  0
             remainder = descriptorName.substring(endOfBaseName + 1);
 416   
         }
 417   
 
 418  0
         iasDescriptorName = path + basename + "ias-" + remainder;
 419  0
         return iasDescriptorName;
 420   
     }
 421   
 }
 422