Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 285   Methods: 6
NCLOC: 133   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
EjbcHelper.java 0% 0% 0% 0%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-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   
 package org.apache.tools.ant.taskdefs.optional.ejb;
 55   
 
 56   
 import java.io.File;
 57   
 import java.io.FileInputStream;
 58   
 import java.io.FileWriter;
 59   
 import java.io.IOException;
 60   
 import java.io.ObjectInputStream;
 61   
 import java.io.PrintWriter;
 62   
 import java.util.Vector;
 63   
 import javax.ejb.deployment.DeploymentDescriptor;
 64   
 import javax.ejb.deployment.EntityDescriptor;
 65   
 
 66   
 
 67   
 /**
 68   
  * A helper class which performs the actual work of the ejbc task.
 69   
  *
 70   
  * This class is run with a classpath which includes the weblogic tools and the home and remote
 71   
  * interface class files referenced in the deployment descriptors being processed.
 72   
  *
 73   
  * @author Conor MacNeill, Cortex ebusiness Pty Limited
 74   
  */
 75   
 public class EjbcHelper {
 76   
     /**
 77   
      * The root directory of the tree containing the serialised deployment desciptors. 
 78   
      */
 79   
     private File descriptorDirectory;
 80   
     
 81   
     /**
 82   
      * The directory where generated files are placed.
 83   
      */
 84   
     private File generatedFilesDirectory;
 85   
     
 86   
     /**
 87   
      * The name of the manifest file generated for the EJB jar.
 88   
      */
 89   
     private File manifestFile;
 90   
     
 91   
     /**
 92   
      * The source directory for the home and remote interfaces. This is used to determine if
 93   
      * the generated deployment classes are out of date.
 94   
      */
 95   
     private File sourceDirectory;
 96   
    
 97   
     /**
 98   
      * The names of the serialised deployment descriptors
 99   
      */
 100   
     String[] descriptors;
 101   
 
 102   
     private boolean keepGenerated;
 103   
 
 104   
     /**
 105   
      * Command line interface for the ejbc helper task.
 106   
      */    
 107  0
     public static void main(String[] args) throws Exception {
 108  0
         EjbcHelper helper = new EjbcHelper(args);
 109  0
         helper.process();
 110   
     }
 111   
     
 112   
     /**
 113   
      * Initialise the EjbcHelper by reading the command arguments.
 114   
      */    
 115  0
     private EjbcHelper(String[] args) {
 116  0
         int index = 0;
 117  0
         descriptorDirectory = new File(args[index++]);
 118  0
         generatedFilesDirectory = new File(args[index++]);
 119  0
         sourceDirectory = new File(args[index++]);
 120  0
         manifestFile = new File(args[index++]);
 121  0
         keepGenerated = Boolean.valueOf(args[index++]).booleanValue();
 122   
         
 123  0
         descriptors = new String[args.length - index];
 124  0
         for (int i = 0; index < args.length; ++i) {
 125  0
             descriptors[i] = args[index++];
 126   
         }
 127   
     }
 128   
     
 129  0
     private String[] getCommandLine(boolean debug, File descriptorFile) {
 130  0
         Vector v = new Vector();
 131  0
         if (!debug) {
 132  0
             v.addElement("-noexit");
 133   
         }
 134  0
         if (keepGenerated) {
 135  0
             v.addElement("-keepgenerated");        
 136   
         }
 137  0
         v.addElement("-d");
 138  0
         v.addElement(generatedFilesDirectory.getPath());
 139  0
         v.addElement(descriptorFile.getPath());
 140   
     
 141  0
         String[] args = new String[v.size()];
 142  0
         v.copyInto(args);
 143  0
         return args;
 144   
     }
 145   
 
 146   
     /**
 147   
      * Determine if the weblogic EJB support classes need to be regenerated
 148   
      * for a given deployment descriptor.
 149   
      *
 150   
      * This process attempts to determine if the support classes need to be
 151   
      * rebuilt. It does this by examining only some of the support classes 
 152   
      * which are typically generated. If the ejbc task is interrupted generating
 153   
      * the support classes for a bean, all of the support classes should be removed
 154   
      * to force regeneration of the support classes.
 155   
      *
 156   
      * @param descriptorFile the serialised deployment descriptor
 157   
      *
 158   
      * @return true if the support classes need to be regenerated.
 159   
      *
 160   
      * @throws IOException if the descriptor file cannot be closed.
 161   
      */
 162  0
     private boolean isRegenRequired(File descriptorFile) throws IOException {
 163   
         // read in the descriptor. Under weblogic, the descriptor is a weblogic
 164   
         // specific subclass which has references to the implementation classes.
 165   
         // These classes must, therefore, be in the classpath when the deployment
 166   
         // descriptor is loaded from the .ser file
 167  0
         FileInputStream fis = null;
 168  0
         try {
 169  0
             fis = new FileInputStream(descriptorFile);
 170  0
             ObjectInputStream ois = new ObjectInputStream(fis);
 171  0
             DeploymentDescriptor dd = (DeploymentDescriptor) ois.readObject();
 172  0
             fis.close();
 173   
             
 174  0
             String homeInterfacePath = dd.getHomeInterfaceClassName().replace('.', '/') + ".java";
 175  0
             String remoteInterfacePath = dd.getRemoteInterfaceClassName().replace('.', '/') + ".java";
 176  0
             String primaryKeyClassPath = null;
 177  0
             if (dd instanceof EntityDescriptor) {
 178  0
                 primaryKeyClassPath = ((EntityDescriptor) dd).getPrimaryKeyClassName().replace('.', '/') + ".java";;
 179   
             }
 180   
         
 181  0
             File homeInterfaceSource = new File(sourceDirectory, homeInterfacePath);
 182  0
             File remoteInterfaceSource = new File(sourceDirectory, remoteInterfacePath);
 183  0
             File primaryKeyClassSource = null;
 184  0
             if (primaryKeyClassPath != null) {
 185  0
                 primaryKeyClassSource = new File(sourceDirectory, remoteInterfacePath);
 186   
             }
 187   
             
 188   
             // are any of the above out of date. 
 189   
             // we find the implementation classes and see if they are older than any
 190   
             // of the above or the .ser file itself.
 191  0
             String beanClassBase = dd.getEnterpriseBeanClassName().replace('.', '/');
 192  0
             File ejbImplentationClass 
 193   
                 = new File(generatedFilesDirectory, beanClassBase + "EOImpl.class");
 194  0
             File homeImplementationClass 
 195   
                 = new File(generatedFilesDirectory, beanClassBase + "HomeImpl.class");
 196  0
             File beanStubClass 
 197   
                 = new File(generatedFilesDirectory, beanClassBase + "EOImpl_WLStub.class");
 198   
                 
 199   
             // if the implementation classes don;t exist regenerate                
 200  0
             if (!ejbImplentationClass.exists() || !homeImplementationClass.exists() ||
 201   
                     !beanStubClass.exists()) {
 202  0
                 return true;
 203   
             }
 204   
                 
 205   
             // Is the ser file or any of the source files newer then the class files.
 206   
             // firstly find the oldest of the two class files.
 207  0
             long classModificationTime = ejbImplentationClass.lastModified();
 208  0
             if (homeImplementationClass.lastModified() < classModificationTime) {
 209  0
                 classModificationTime = homeImplementationClass.lastModified();
 210   
             }
 211  0
             if (beanStubClass.lastModified() < classModificationTime) {
 212  0
                 classModificationTime = beanStubClass.lastModified();
 213   
             }
 214   
             
 215  0
             if (descriptorFile.lastModified() > classModificationTime ||
 216   
                     homeInterfaceSource.lastModified() > classModificationTime ||
 217   
                     remoteInterfaceSource.lastModified() > classModificationTime) {
 218  0
                 return true;
 219   
             }
 220   
             
 221  0
             if (primaryKeyClassSource != null && 
 222   
                     primaryKeyClassSource.lastModified() > classModificationTime) {
 223  0
                 return true;
 224   
             }
 225   
         } catch (Throwable descriptorLoadException) {
 226  0
             System.out.println("Exception occurred reading " + descriptorFile.getName() + " - continuing");
 227   
             // any problems - just regenerate
 228  0
             return true;
 229   
         } finally {
 230  0
             if (fis != null) {
 231  0
                 fis.close();
 232   
             }
 233   
         }
 234   
         
 235  0
         return false;
 236   
     }
 237   
     
 238   
     /**
 239   
      * Process the descriptors in turn generating support classes for each and a manifest
 240   
      * file for all of the beans.
 241   
      */            
 242  0
     private void process() throws Exception {
 243  0
         String manifest = "Manifest-Version: 1.0\n\n";
 244  0
         for (int i = 0; i < descriptors.length; ++i) {
 245  0
             String descriptorName = descriptors[i];
 246  0
             File descriptorFile = new File(descriptorDirectory, descriptorName);
 247   
             
 248  0
             if (isRegenRequired(descriptorFile)) {
 249  0
                 System.out.println("Running ejbc for " + descriptorFile.getName());
 250  0
                 regenerateSupportClasses(descriptorFile);
 251   
             } else {
 252  0
                 System.out.println(descriptorFile.getName() + " is up to date");
 253   
             }
 254  0
             manifest += "Name: " + descriptorName.replace('\\', '/') + "\nEnterprise-Bean: True\n\n";
 255   
         }
 256   
         
 257  0
         FileWriter fw = new FileWriter(manifestFile);
 258  0
         PrintWriter pw = new PrintWriter(fw);
 259  0
         pw.print(manifest);
 260  0
         fw.flush();
 261  0
         fw.close();
 262   
     }
 263   
     
 264   
     /**
 265   
      * Perform the weblogic.ejbc call to regenerate the support classes.
 266   
      *
 267   
      * Note that this method relies on an undocumented -noexit option to the 
 268   
      * ejbc tool to stop the ejbc tool exiting the VM altogether.
 269   
      */
 270  0
     private void regenerateSupportClasses(File descriptorFile) throws Exception {
 271   
         // create a Java task to do the rebuild
 272   
 
 273   
         
 274  0
         String[] args = getCommandLine(false, descriptorFile);
 275   
         
 276  0
         try {
 277  0
             weblogic.ejbc.main(args);
 278   
         } catch (Exception e) {
 279   
             // run with no exit for better reporting
 280  0
             String[] newArgs = getCommandLine(true, descriptorFile);
 281  0
             weblogic.ejbc.main(newArgs);
 282   
         }
 283   
     }
 284   
 }
 285