diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java new file mode 100644 index 000000000..0c21cabf2 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java @@ -0,0 +1,431 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.ejb; + +import java.io.*; +import java.io.FileReader; +import java.io.LineNumberReader; +import java.io.StringReader; +import java.net.*; +import java.util.*; +import java.util.Iterator; +import java.util.jar.*; +import javax.xml.parsers.*; + +import org.apache.tools.ant.*; +import org.apache.tools.ant.taskdefs.ExecTask; +import org.apache.tools.ant.taskdefs.Java; +import org.apache.tools.ant.types.*; +import org.apache.tools.ant.types.Commandline.Argument; +import org.xml.sax.*; + +/** + * BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 + * This task generates and compilesthe stubs and skeletons for all ejb described into the + * Deployement Descriptor, builds the jar file including the support files and verify + * whether the produced jar is valid or not. + * The supported options are: + * + * + *
+ *
+ *      <ejbjar srcdir="${build.classes}"  basejarname="vsmp"  descriptordir="${rsc.dir}/hrmanager">
+ *        <borland destdir="tstlib">
+ *          <classpath refid="classpath" />
+ *        </borland>      
+ *        <include name="**\ejb-jar.xml"/>
+ *        <support dir="${build.classes}">
+ *          <include name="demo\smp\*.class"/>
+ *          <include name="demo\helper\*.class"/>
+ *         </support>
+ *     </ejbjar>
+ *
+ * + */ +public class BorlandDeploymentTool extends GenericDeploymentTool +{ + public static final String PUBLICID_EJB11 + = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"; + public static final String PUBLICID_EJB20 + = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"; + + public static final String PUBLICID_BORLAND_EJB + = "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN"; + + protected static final String DEFAULT_BAS45_EJB11_DTD_LOCATION + = "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd"; + + protected static final String DEFAULT_BAS_DTD_LOCATION + = "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd"; + + protected static final String BAS_DD = "ejb-inprise.xml"; + + /** Java2iiop executable **/ + protected static final String JAVA2IIOP = "java2iiop.exe"; + + /** Verify class */ + protected static final String VERIFY = "com.inprise.ejb.util.Verify"; + + /** Instance variable that stores the suffix for the borland jarfile. */ + private String jarSuffix = ".jar"; + + /** Instance variable that stores the location of the borland DTD file. */ + private String borlandDTD; + + /** Instance variable that stores the location of the ejb 1.1 DTD file. */ + private String ejb11DTD; + + + /** Instance variable that determines whether the debug mode is on */ + private boolean java2iiopdebug = false; + + /** Instance variable that determines whether it is necessary to verify the produced jar */ + private boolean verify = true; + private String verifyArgs = ""; + + /** + * set the debug mode for java2iiop + **/ + public void setDebug(boolean debug) { + this.java2iiopdebug = debug; + } + + /** + * set the verify mode for the produced jar + **/ + public void setVerify(boolean verify) { + this.verify = verify; + } + + + + /** + * Setter used to store the suffix for the generated borland jar file. + * @param inString the string to use as the suffix. + */ + public void setSuffix(String inString) { + this.jarSuffix = inString; + } + + + /** + * sets some additional args to send to verify command + */ + public void setVerifyArgs(String args) + { + this.verifyArgs = args; + } + + + /** + * Setter used to store the location of the borland DTD. This can be a file on the system + * or a resource on the classpath. + * @param inString the string to use as the DTD location. + */ + public void setBASdtd(String inString) { + this.borlandDTD = inString; + } + + /** + * Setter used to store the location of the Sun's Generic EJB DTD. + * This can be a file on the system or a resource on the classpath. + * @param inString the string to use as the DTD location. + */ + public void setEJBdtd(String inString) { + this.ejb11DTD = inString; + } + + + protected void registerKnownDTDs(DescriptorHandler handler) { + handler.registerDTD(PUBLICID_EJB11, DEFAULT_BAS45_EJB11_DTD_LOCATION); + } + + protected DescriptorHandler getBorlandDescriptorHandler(final File srcDir) { + DescriptorHandler handler = + new DescriptorHandler(getTask(), srcDir) { + protected void processElement() { + if (currentElement.equals("type-storage")) { + // Get the filename of vendor specific descriptor + String fileNameWithMETA = currentText; + //trim the META_INF\ off of the file name + String fileName = fileNameWithMETA.substring(META_DIR.length(), + fileNameWithMETA.length() ); + File descriptorFile = new File(srcDir, fileName); + + ejbFiles.put(fileNameWithMETA, descriptorFile); + } + } + }; + + handler.registerDTD(PUBLICID_BORLAND_EJB, + borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD); + + for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) { + EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next(); + handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation()); + } + return handler; + } + + /** + * Add any vendor specific files which should be included in the + * EJB Jar. + */ + protected void addVendorFiles(Hashtable ejbFiles, String baseName) { + + File borlandDD = new File(getConfig().descriptorDir,META_DIR+BAS_DD); + if (borlandDD.exists()) + { + log("Borland specific file found "+ borlandDD, Project.MSG_VERBOSE); + ejbFiles.put(META_DIR + BAS_DD, borlandDD); + } + else + { + log("Unable to locate borland deployment descriptor. It was expected to be in " + + borlandDD.getPath(), Project.MSG_WARN); + return; + } + + } + + /** + * Get the vendor specific name of the Jar that will be output. The modification date + * of this jar will be checked against the dependent bean classes. + */ + File getVendorOutputJarFile(String baseName) + { + return new File(getDestDir(), baseName + jarSuffix); + } + + /** + * Verify the produced jar file by invoking the Borland verify tool + * @param sourceJar java.io.File representing the produced jar file + */ + private void verifyBorlandJar(File sourceJar) + { + org.apache.tools.ant.taskdefs.Java javaTask = null; + log("verify "+sourceJar,Project.MSG_INFO); + try { + + String args = verifyArgs; + args += " "+sourceJar.getPath(); + + javaTask = (Java) getTask().getProject().createTask("java"); + javaTask.setTaskName("verify"); + javaTask.setClassname(VERIFY); + Commandline.Argument arguments = javaTask.createArg(); + arguments.setLine(args); + Path classpath = getCombinedClasspath(); + if (classpath != null) + { + javaTask.setClasspath(classpath); + javaTask.setFork(true); + } + + log("Calling "+VERIFY+" for " + sourceJar.toString(), Project.MSG_VERBOSE); + javaTask.execute(); + } + catch (Exception e) + { + //TO DO : delete the file if it is not a valid file. + String msg = "Exception while calling "+VERIFY+" Details: " + e.toString(); + throw new BuildException(msg, e); + } + + + } + + /** + * Generate stubs & sketelton for each home found into the DD + * Add all the generate class file into the ejb files + * @param ithomes : iterator on home class + * @param files : file list , updated by the adding generated files + */ + private void buildBorlandStubs(Iterator ithomes,Hashtable files ) + { + org.apache.tools.ant.taskdefs.ExecTask execTask = null; + File java2iiopOut = new File("java2iiop.log"); + try + { + execTask = (ExecTask) getTask().getProject().createTask("exec"); + execTask.setOutput(java2iiopOut); + if ( java2iiopdebug ) + { + execTask.createArg().setValue("-VBJdebug"); + } // end of if () + + execTask.setDir(getConfig().srcDir); + execTask.setExecutable(JAVA2IIOP); + //set the classpath + execTask.createArg().setValue("-VBJclasspath"); + execTask.createArg().setPath(getCombinedClasspath()); + //list file + execTask.createArg().setValue("-list_files"); + //root dir + execTask.createArg().setValue("-root_dir"); + execTask.createArg().setValue(getConfig().srcDir.getAbsolutePath()); + //compiling order + execTask.createArg().setValue("-compile"); + //add the home class + while ( ithomes.hasNext()) + { + execTask.createArg().setValue(ithomes.next().toString()); + } // end of while () + log("Calling java2iiop",Project.MSG_VERBOSE); + execTask.execute(); + } + catch (Exception e) { + // Have to catch this because of the semantics of calling main() + String msg = "Exception while calling java2iiop. Details: " + e.toString(); + throw new BuildException(msg, e); + } + + try + { + FileReader fr = new FileReader(java2iiopOut); + LineNumberReader lnr = new LineNumberReader(fr); + String javafile; + while ( ( javafile = lnr.readLine()) != null) + { + if ( javafile.endsWith(".java") ) + { + String classfile = toClassFile(javafile); + + String key = classfile.substring(getConfig().srcDir.getAbsolutePath().length()+1); + log(" generated : "+ classfile ,Project.MSG_DEBUG); + log(" key : "+ key ,Project.MSG_DEBUG); + files.put(key, new File(classfile)); + } // end of if () + } // end of while () + lnr.close(); + } + catch(Exception e) + { + String msg = "Exception while parsing java2iiop output. Details: " + e.toString(); + throw new BuildException(msg, e); + } + } + + /** + * Method used to encapsulate the writing of the JAR file. Iterates over the + * filenames/java.io.Files in the Hashtable stored on the instance variable + * ejbFiles. + */ + protected void writeJar(String baseName, File jarFile, Hashtable files, + String publicId) throws BuildException { + //build the home classes list. + Vector homes = new Vector(); + Iterator it = files.keySet().iterator(); + while ( it.hasNext()) + { + String clazz = (String) it.next(); + if ( clazz.endsWith("Home.class") ) + { + //remove .class extension + String home = toClass(clazz); + homes.add(home); + log(" Home "+home,Project.MSG_VERBOSE); + } // end of if () + } // end of while () + + buildBorlandStubs(homes.iterator(),files); + + super.writeJar(baseName, jarFile, files, publicId); + + if ( verify ) + { + verifyBorlandJar(jarFile); + } // end of if () + + } + + /** + * convert a class file name : A/B/C/toto.class + * into a class name: A.B.C.toto + */ + protected String toClass(String filename) + { + //remove the .class + String classname = filename.substring(0,filename.lastIndexOf(".class")); + classname = classname.replace('\\','.'); + return classname; + } + + /** + * convert a file name : A/B/C/toto.java + * into a class name: A/B/C/toto.class + */ + protected String toClassFile(String filename) + { + //remove the .class + String classfile = filename.substring(0,filename.lastIndexOf(".java")); + classfile = classfile+".class"; + return classfile; + } + + /** + * Called to validate that the tool parameters have been configured. + * + */ + public void validateConfigured() throws BuildException { + super.validateConfigured(); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java index 5b30c347f..923ea398d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2000 The Apache Software Foundation. All rights + * Copyright (c) 2000, 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -193,6 +193,21 @@ public class EjbJar extends MatchingTask { return tool; } + /** + * Create a Borland nested element used to configure a + * deployment tool for Borland server. + * + * @return the deployment tool instance to be configured. + */ + public BorlandDeploymentTool createBorland() { + log("Borland deployment tools", Project.MSG_VERBOSE); + + BorlandDeploymentTool tool = new BorlandDeploymentTool(); + tool.setTask(this); + deploymentTools.add(tool); + return tool; + } + /** * Create a nested element for weblogic when using the Toplink * Object- Relational mapping.