diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java new file mode 100644 index 000000000..a524e76d2 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java @@ -0,0 +1,239 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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.util.*; +import java.io.*; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.AttributeList; + +/** + * Inner class used by EjbJar to facilitate the parsing of deployment + * descriptors and the capture of appropriate information. Extends + * HandlerBase so it only implements the methods needed. During parsing + * creates a hashtable consisting of entries mapping the name it should be + * inserted into an EJB jar as to a File representing the file on disk. This + * list can then be accessed through the getFiles() method. + */ +public class DescriptorHandler extends org.xml.sax.HandlerBase { + /** + * Bunch of constants used for storing entries in a hashtable, and for + * constructing the filenames of various parts of the ejb jar. + */ + private static final String HOME_INTERFACE = "home"; + private static final String REMOTE_INTERFACE = "remote"; + private static final String BEAN_CLASS = "ejb-class"; + private static final String PK_CLASS = "prim-key-class"; + + /** + * Instance variable used to store the name of the current element being + * processed by the SAX parser. Accessed by the SAX parser call-back methods + * startElement() and endElement(). + */ + private String currentElement = null; + + /** + * The text of the current element + */ + private String currentText = null; + + /** + * Instance variable that stores the names of the files as they will be + * put into the jar file, mapped to File objects Accessed by the SAX + * parser call-back method characters(). + */ + private Hashtable ejbFiles = null; + + private Hashtable fileDTDs = new Hashtable(); + + private Hashtable resourceDTDs = new Hashtable(); + + /** + * The directory containing the bean classes and interfaces. This is + * used for performing dependency file lookups. + */ + private File srcDir; + + public DescriptorHandler(File srcDir) { + this.srcDir = srcDir; + } + + + public void registerFileDTD(String publicId, File dtdFile) { + fileDTDs.put(publicId, dtdFile); + } + + public void registerResourceDTD(String publicId, String resourceName) { + resourceDTDs.put(publicId, resourceName); + } + + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException + { + + File dtdFile = (File) fileDTDs.get(publicId); + if (dtdFile != null && dtdFile.exists()) { + try { + return new InputSource(new FileInputStream(dtdFile)); + } catch( FileNotFoundException ex ) { + // ignore + } + } + + String dtdResourceName = (String)resourceDTDs.get(publicId); + if (dtdResourceName != null) { + InputStream is = this.getClass().getResourceAsStream(dtdResourceName); + if( is != null ) { + return new InputSource(is); + } + } + + return null; + } + + /** + * Getter method that returns the set of files to include in the EJB jar. + */ + public Hashtable getFiles() { + return (ejbFiles == null) ? new Hashtable() : ejbFiles; + } + + + /** + * SAX parser call-back method that is used to initialize the values of some + * instance variables to ensure safe operation. + */ + public void startDocument() throws SAXException { + this.ejbFiles = new Hashtable(10, 1); + this.currentElement = null; + } + + + /** + * SAX parser call-back method that is invoked when a new element is entered + * into. Used to store the context (attribute name) in the currentAttribute + * instance variable. + * @param name The name of the element being entered. + * @param attrs Attributes associated to the element. + */ + public void startElement(String name, AttributeList attrs) + throws SAXException { + this.currentElement = name; + currentText = ""; + } + + + /** + * SAX parser call-back method that is invoked when an element is exited. + * Used to blank out (set to the empty string, not nullify) the name of + * the currentAttribute. A better method would be to use a stack as an + * instance variable, however since we are only interested in leaf-node + * data this is a simpler and workable solution. + * @param name The name of the attribute being exited. Ignored + * in this implementation. + */ + public void endElement(String name) throws SAXException { + processElement(); + currentText = ""; + this.currentElement = ""; + } + + /** + * SAX parser call-back method invoked whenever characters are located within + * an element. currentAttribute (modified by startElement and endElement) + * tells us whether we are in an interesting element (one of the up to four + * classes of an EJB). If so then converts the classname from the format + * org.apache.tools.ant.Parser to the convention for storing such a class, + * org/apache/tools/ant/Parser.class. This is then resolved into a file + * object under the srcdir which is stored in a Hashtable. + * @param ch A character array containing all the characters in + * the element, and maybe others that should be ignored. + * @param start An integer marking the position in the char + * array to start reading from. + * @param length An integer representing an offset into the + * char array where the current data terminates. + */ + public void characters(char[] ch, int start, int length) + throws SAXException { + + currentText += new String(ch, start, length); + } + + + private void processElement() { + if (currentElement.equals(HOME_INTERFACE) || + currentElement.equals(REMOTE_INTERFACE) || + currentElement.equals(BEAN_CLASS) || + currentElement.equals(PK_CLASS)) { + + // Get the filename into a String object + File classFile = null; + String className = currentText; + + // If it's a primitive wrapper then we shouldn't try and put + // it into the jar, so ignore it. + if (!className.startsWith("java.lang")) { + // Translate periods into path separators, add .class to the + // name, create the File object and add it to the Hashtable. + className = className.replace('.', File.separatorChar); + className += ".class"; + classFile = new File(srcDir, className); + ejbFiles.put(className, classFile); + } + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java new file mode 100644 index 000000000..4b8314673 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java @@ -0,0 +1,90 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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 javax.xml.parsers.SAXParser; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public interface EJBDeploymentTool { + /** + * Process a deployment descriptor, generating the necessary vendor specifi + * deployment files. + * + * @param descriptorFilename the name of the deployment descriptor + * @param saxParser a SAX parser which can be used to parse the deployment descriptor. + */ + public void processDescriptor(File srcDir, String descriptorFilename, SAXParser saxParser) + throws BuildException; + + /** + * Called to validate that the tool parameters have been configured. + * + */ + public void validateConfigured() throws BuildException; + + /** + * Set the task which owns this tool + */ + public void setTask(Task task); + + /** + * Configure this tool for use in the ejbjar task. + */ + public void configure(String basenameTerminator, boolean flatDestDir); +} \ No newline at end of file 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 9e89177c1..73098a2e7 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) 1999 The Apache Software Foundation. All rights + * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,37 +55,20 @@ package org.apache.tools.ant.taskdefs.optional.ejb; // Standard java imports -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.io.File; -import java.io.IOException; -import java.util.jar.*; -import java.util.zip.*; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Iterator; +import java.io.*; +import java.util.*; // XML imports import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.ParserConfigurationException; -import org.xml.sax.Parser; -import org.xml.sax.Locator; -import org.xml.sax.InputSource; -import org.xml.sax.AttributeList; -import org.xml.sax.DocumentHandler; import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.ParserFactory; // Apache/Ant imports import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Task; import org.apache.tools.ant.Project; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.taskdefs.Java; /** *

Provides automated ejb jar file creation for ant. Extends the MatchingTask @@ -104,146 +87,21 @@ import org.apache.tools.ant.taskdefs.Java; * 5.1 jars. The weblogic deployment descriptors, used in constructing the * Weblogic jar, are located based on a simple naming convention. The name of the * standard deployment descriptor is taken upto the first instance of a String, - * specified by the attribute basenameterminator, and then the regular Weblogic - * descriptor name is appended. For example if basenameterminator is set to '-', + * specified by the attribute basenameTerminator, and then the regular Weblogic + * descriptor name is appended. For example if basenameTerminator is set to '-', * its default value, and a standard descriptor is called Foo-ejb-jar.xml then * the files Foo-weblogic-ejb-jar.xml and Foo-weblogic-cmp-rdbms-jar.xml will be * looked for, and if found, included in the jarfile.

* *

Attributes and setter methods are provided to support optional generation * of Weblogic5.1 jars, optional deletion of generic jar files, setting alternate - * values for basenameterminator, and setting the strings to append to the names + * values for basenameTerminator, and setting the strings to append to the names * of the generated jarfiles.

* * @author Tim Fennell */ public class EjbJar extends MatchingTask { - /** - * Inner class used by EjbJar to facilitate the parsing of deployment - * descriptors and the capture of appropriate information. Extends - * HandlerBase so it only implements the methods needed. During parsing - * creates a hashtable consisting of entries mapping the name it should be - * inserted into an EJB jar as to a File representing the file on disk. This - * list can then be accessed through the getFiles() method. - */ - protected class DescriptorHandler extends org.xml.sax.HandlerBase { - /** - * Bunch of constants used for storing entries in a hashtable, and for - * constructing the filenames of various parts of the ejb jar. - */ - private static final String HOME_INTERFACE = "home"; - private static final String REMOTE_INTERFACE = "remote"; - private static final String BEAN_CLASS = "ejb-class"; - private static final String PK_CLASS = "prim-key-class"; - - /** - * Instance variable used to store the name of the current attribute being - * processed by the SAX parser. Accessed by the SAX parser call-back methods - * startElement() and endElement(). - */ - private String currentAttribute = null; - - /** - * Instance variable that stores the names of the files as they will be - * put into the jar file, mapped to File objects Accessed by the SAX - * parser call-back method characters(). - */ - private Hashtable ejbFiles = null; - - /** Instance variable to store the source directory of the task */ - - - /** - * Getter method that returns the set of files to include in the EJB jar. - */ - public Hashtable getFiles() { - return (ejbFiles == null) ? new Hashtable() : ejbFiles; - } - - - /** - * SAX parser call-back method that is used to initialize the values of some - * instance variables to ensure safe operation. - */ - public void startDocument() throws SAXException { - this.ejbFiles = new Hashtable(10, 1); - this.currentAttribute = null; - } - - - /** - * SAX parser call-back method that is invoked when a new element is entered - * into. Used to store the context (attribute name) in the currentAttribute - * instance variable. - * @param name The name of the element being entered. - * @param attrs Attributes associated to the element. - */ - public void startElement(String name, AttributeList attrs) - throws SAXException { - this.currentAttribute = name; - } - - - /** - * SAX parser call-back method that is invoked when an element is exited. - * Used to blank out (set to the empty string, not nullify) the name of - * the currentAttribute. A better method would be to use a stack as an - * instance variable, however since we are only interested in leaf-node - * data this is a simpler and workable solution. - * @param name The name of the attribute being exited. Ignored - * in this implementation. - */ - public void endElement(String name) throws SAXException { - this.currentAttribute = ""; - } - - /** - * SAX parser call-back method invoked whenever characters are located within - * an element. currentAttribute (modified by startElement and endElement) - * tells us whether we are in an interesting element (one of the up to four - * classes of an EJB). If so then converts the classname from the format - * org.apache.tools.ant.Parser to the convention for storing such a class, - * org/apache/tools/ant/Parser.class. This is then resolved into a file - * object under the srcdir which is stored in a Hashtable. - * @param ch A character array containing all the characters in - * the element, and maybe others that should be ignored. - * @param start An integer marking the position in the char - * array to start reading from. - * @param length An integer representing an offset into the - * char array where the current data terminates. - */ - public void characters(char[] ch, int start, int length) - throws SAXException { - if (currentAttribute.equals(DescriptorHandler.HOME_INTERFACE) || - currentAttribute.equals(DescriptorHandler.REMOTE_INTERFACE) || - currentAttribute.equals(DescriptorHandler.BEAN_CLASS) || - currentAttribute.equals(DescriptorHandler.PK_CLASS)) { - - // Get the filename into a String object - File classFile = null; - String className = new String(ch, start, length); - - // If it's a primitive wrapper then we shouldn't try and put - // it into the jar, so ignore it. - if (!className.startsWith("java.lang")) { - // Translate periods into path separators, add .class to the - // name, create the File object and add it to the Hashtable. - className = className.replace('.', File.separatorChar); - className += ".class"; - classFile = new File(srcdir, className); - ejbFiles.put(className, classFile); - } - } - } - } // End of DescriptorHandler - - /** Private constants that are used when constructing the standard jarfile */ - private static final String META_DIR = "META-INF/"; - private static final String EJB_DD = "ejb-jar.xml"; - private static final String WL_DD = "weblogic-ejb-jar.xml"; - private static final String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml"; - /** Stores a handle to the directory under which to search for files */ private File srcdir = null; @@ -255,47 +113,50 @@ public class EjbJar extends MatchingTask { * of a flat directory as the destination for the jar files. */ private boolean flatdestdir = false; - - /** Instance variable that determines whether to generate weblogic jars. */ - private boolean generateweblogic = false; - - /** Instance variable that determines whether generic ejb jars are kept. */ - private boolean keepgeneric = true; /** Instance variable that marks the end of the 'basename' */ - private String basenameterminator = "-"; + private String basenameTerminator = "-"; /** Instance variable that stores the suffix for the generated jarfile. */ private String genericjarsuffix = "-generic.jar"; - /** Instance variable that stores the suffix for the weblogic jarfile. */ - private String weblogicjarsuffix = "-wl.jar"; + /** + * The list of deployment tools we are going to run. + */ + private ArrayList deploymentTools = new ArrayList(); + + public EJBDeploymentTool createWeblogic() { + EJBDeploymentTool tool = new WeblogicDeploymentTool(); + tool.setTask(this); + deploymentTools.add(tool); + return tool; + } /** * Setter used to store the value of srcdir prior to execute() being called. - * @param inDir The string indicating the source directory. + * @param inDir the source directory. */ - public void setSrcdir(String inDir) { - this.srcdir = this.project.resolveFile(inDir); + public void setSrcdir(File inDir) { + this.srcdir = inDir; } /** * Setter used to store the value of destination directory prior to execute() * being called. - * @param inFile The string indicating the source directory. + * @param inFile the destination directory. */ - public void setDestdir(String inDir) { - this.destdir = this.project.resolveFile(inDir); + public void setDestdir(File inDir) { + this.destdir = inDir; } /** * Setter used to store the value of flatdestdir. * @param inValue a string, either 'true' or 'false'. */ - public void setFlatdestdir(String inValue) { - this.flatdestdir = Boolean.valueOf(inValue).booleanValue(); + public void setFlatdestdir(boolean inValue) { + this.flatdestdir = inValue; } - + /** * Setter used to store the suffix for the generated jar file. * @param inString the string to use as the suffix. @@ -305,164 +166,13 @@ public class EjbJar extends MatchingTask { } /** - * Setter used to store the suffix for the generated weblogic jar file. - * @param inString the string to use as the suffix. - */ - public void setWeblogicjarsuffix(String inString) { - this.weblogicjarsuffix = inString; - } - - /** - * Setter used to store the value of generateweblogic. - * @param inValue a string, either 'true' or 'false'. - */ - public void setGenerateweblogic(String inValue) { - this.generateweblogic = Boolean.valueOf(inValue).booleanValue(); - } - - /** - * Setter used to store the value of keepgeneric - * @param inValue a string, either 'true' or 'false'. - */ - public void setKeepgeneric(String inValue) { - this.keepgeneric = Boolean.valueOf(inValue).booleanValue(); - } - - /** - * Setter used to store the value of basenameterminator + * Setter used to store the value of basenameTerminator * @param inValue a string which marks the end of the basename. */ - public void setBasenameterminator(String inValue) { - if (inValue != null) this.basenameterminator = inValue; - } - - /** - * Utility method that encapsulates the logic of adding a file entry to - * a .jar file. Used by execute() to add entries to the jar file as it is - * constructed. - * @param jStream A JarOutputStream into which to write the - * jar entry. - * @param iStream A FileInputStream from which to read the - * contents the file being added. - * @param filename A String representing the name, including - * all relevant path information, that should be stored for the entry - * being added. - */ - protected void addFileToJar(JarOutputStream jStream, - FileInputStream iStream, - String filename) - throws BuildException { - try { - // Create the zip entry and add it to the jar file - ZipEntry zipEntry = new ZipEntry(filename); - jStream.putNextEntry(zipEntry); - - // Create the file input stream, and buffer everything over - // to the jar output stream - byte[] byteBuffer = new byte[2 * 1024]; - int count = 0; - do { - jStream.write(byteBuffer, 0, count); - count = iStream.read(byteBuffer, 0, byteBuffer.length); - } while (count != -1); - - // Close up the file input stream for the class file - iStream.close(); - } - catch (IOException ioe) { - String msg = "IOException while adding entry " - + filename + "to jarfile." - + ioe.getMessage(); - throw new BuildException(msg, ioe); - } - } - - /** - * 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. - */ - public void writeJar(File jarfile, Hashtable files) throws BuildException{ - JarOutputStream jarStream = null; - Iterator entryIterator = null; - String entryName = null; - File entryFile = null; - - try { - /* If the jarfile already exists then whack it and recreate it. - * Should probably think of a more elegant way to handle this - * so that in case of errors we don't leave people worse off - * than when we started =) - */ - if (jarfile.exists()) jarfile.delete(); - jarfile.getParentFile().mkdirs(); - jarfile.createNewFile(); - - // Create the streams necessary to write the jarfile - jarStream = new JarOutputStream(new FileOutputStream(jarfile)); - jarStream.setMethod(JarOutputStream.DEFLATED); - - // Loop through all the class files found and add them to the jar - entryIterator = files.keySet().iterator(); - while (entryIterator.hasNext()) { - entryName = (String) entryIterator.next(); - entryFile = (File) files.get(entryName); - - this.log("adding file '" + entryName + "'", - Project.MSG_VERBOSE); - - addFileToJar(jarStream, - new FileInputStream(entryFile), - entryName); - } - // All done. Close the jar stream. - jarStream.close(); - } - catch(IOException ioe) { - String msg = "IOException while processing ejb-jar file '" - + jarfile.toString() - + "'. Details: " - + ioe.getMessage(); - throw new BuildException(msg, ioe); - } - } // end of writeJar - - - /** - * Helper method invoked by execute() for each WebLogic jar to be built. - * Encapsulates the logic of constructing a java task for calling - * weblogic.ejbc and executing it. - * @param sourceJar java.io.File representing the source (EJB1.1) jarfile. - * @param destJar java.io.File representing the destination, WebLogic - * jarfile. - */ - public void buildWeblogicJar(File sourceJar, File destJar) { - org.apache.tools.ant.taskdefs.Java javaTask = null; - - try { - // Unfortunately, because weblogic.ejbc calls system.exit(), we - // cannot do it 'in-process'. If they ever fix this, we should - // change this code - it would be much quicker! - String args = "-noexit " + sourceJar + " " + destJar; - - javaTask = (Java) this.project.createTask("java"); - javaTask.setClassname("weblogic.ejbc"); - javaTask.setArgs(args); - javaTask.setFork(false); - - this.log("Calling weblogic.ejbc for " + sourceJar.toString(), - Project.MSG_INFO); - - javaTask.execute(); - } - catch (Exception e) { - // Have to catch this because of the semantics of calling main() - String msg = "Exception while calling ejbc. Details: " + e.toString(); - throw new BuildException(msg, e); - } + public void setBasenameTerminator(String inValue) { + if (inValue != null) this.basenameTerminator = inValue; } - /** * Invoked by Ant after the task is prepared, when it is ready to execute * this task. Parses the XML deployment descriptor to acquire the list of @@ -475,173 +185,51 @@ public class EjbJar extends MatchingTask { * that a major problem occurred within this task. */ public void execute() throws BuildException { - boolean needBuild = true; - DirectoryScanner ds = null; - String[] files = null; - int index = 0; - File weblogicDD = null; - File jarfile = null; - File wlJarfile = null; - File jarToCheck = null; - DescriptorHandler handler = null; - Hashtable ejbFiles = null; - String baseName = null; - - // Lets do a little asserting to make sure we have all the - // required attributes from the task processor - StringBuffer sb = new StringBuffer(); - boolean die = false; - sb.append("Processing ejbjar - the following attributes "); - sb.append("must be specified: "); - if (this.srcdir == null) { sb.append("srcdir "); die = true; } - if (this.destdir == null) { sb.append("destdir"); die = true; } - if ( die ) throw new BuildException(sb.toString()); + if (srcdir == null) { + throw new BuildException("The srcdir attribute must be specified"); + } + + if (deploymentTools.size() == 0) { + GenericDeploymentTool genericTool = new GenericDeploymentTool(); + genericTool.setDestdir(destdir); + genericTool.setTask(this); + genericTool.setGenericjarsuffix(genericjarsuffix); + deploymentTools.add(genericTool); + } + + for (Iterator i = deploymentTools.iterator(); i.hasNext(); ) { + EJBDeploymentTool tool = (EJBDeploymentTool)i.next(); + tool.configure(basenameTerminator, flatdestdir); + tool.validateConfigured(); + } + try { // Create the parser using whatever parser the system dictates SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - saxParserFactory.setValidating(false); + saxParserFactory.setValidating(true); SAXParser saxParser = saxParserFactory.newSAXParser(); - - ds = this.getDirectoryScanner(this.srcdir); + + DirectoryScanner ds = getDirectoryScanner(srcdir); ds.scan(); - files = ds.getIncludedFiles(); - - this.log(files.length + " deployment descriptors located.", - Project.MSG_VERBOSE); - + String[] files = ds.getIncludedFiles(); + + log(files.length + " deployment descriptors located.", + Project.MSG_VERBOSE); + + // Loop through the files. Each file represents one deployment // descriptor, and hence one bean in our model. - for (index=0; index < files.length; ++index) { - - // By default we assume we need to build. - needBuild = true; - - // Work out what the base name is - int endBaseName = - files[index].indexOf(basenameterminator, - files[index].lastIndexOf(File.separator)); - baseName = files[index].substring(0, endBaseName); - - /* Parse the ejb deployment descriptor. While it may not - * look like much, we use a SAXParser and an inner class to - * get hold of all the classfile names for the descriptor. - */ - handler = new DescriptorHandler(); - saxParser.parse(new InputSource - (new FileInputStream - (new File(this.srcdir, files[index]))), - handler); - - ejbFiles = handler.getFiles(); - - /* Now try to locate all of the deployment descriptors for the - * jar, and if they exist, add them to the list of files. - */ - - // First the regular deployment descriptor - ejbFiles.put(EjbJar.META_DIR + EjbJar.EJB_DD, - new File(this.srcdir, files[index])); - - // Then the weblogic deployment descriptor - weblogicDD = new File(this.srcdir, - baseName - + this.basenameterminator - + EjbJar.WL_DD); - - if (weblogicDD.exists()) { - ejbFiles.put(EjbJar.META_DIR + EjbJar.WL_DD, - weblogicDD); + for (int index = 0; index < files.length; ++index) { + // process the deployment descriptor in each tool + for (Iterator i = deploymentTools.iterator(); i.hasNext(); ) { + EJBDeploymentTool tool = (EJBDeploymentTool)i.next(); + processDescriptor(files[index], saxParser, tool); } - - // The the weblogic cmp deployment descriptor - weblogicDD = new File(this.srcdir, - baseName - + this.basenameterminator - + EjbJar.WL_CMP_DD); - - if (weblogicDD.exists()) { - ejbFiles.put(EjbJar.META_DIR + EjbJar.WL_CMP_DD, - weblogicDD); - } - - // Lastly create File object for the Jar files. If we are using - // a flat destination dir, then we need to redefine baseName! - if (this.flatdestdir) { - int startName = baseName.lastIndexOf(File.separator); - int endName = baseName.length(); - baseName = baseName.substring(startName, endName); - } - - jarfile = new File(this.destdir, - baseName - + this.genericjarsuffix); - - wlJarfile = new File(this.destdir, - baseName - + this.weblogicjarsuffix); - - /* Check to see if the jar file is already up to date. - * Unfortunately we have to parse the descriptor just to do - * that, but it's still a saving over re-constructing the jar - * file each time. Tertiary is used to determine which jarfile - * we should check times against...think about it. - */ - jarToCheck = this.generateweblogic ? wlJarfile : jarfile; - - if (jarToCheck.exists()) { - long lastBuild = jarToCheck.lastModified(); - Iterator fileIter = ejbFiles.values().iterator(); - File currentFile = null; - - // Set the need build to false until we find out otherwise. - needBuild = false; - - // Loop through the files seeing if any has been touched - // more recently than the destination jar. - while( (needBuild == false) && (fileIter.hasNext()) ) { - currentFile = (File) fileIter.next(); - needBuild = ( lastBuild < currentFile.lastModified() ); - } - } - - // Check to see if we need a build and start - // doing the work! - if (needBuild) { - // Log that we are going to build... - this.log( "building " - + jarfile.getName() - + " with " - + String.valueOf(ejbFiles.size()) - + " total files", - Project.MSG_INFO); - - // Use helper method to write the jarfile - this.writeJar(jarfile, ejbFiles); - - // Generate weblogic jar if requested - if (this.generateweblogic) { - this.buildWeblogicJar(jarfile, wlJarfile); - } - - // Delete the original jar if we weren't asked to keep it. - if (!this.keepgeneric) { - this.log("deleting jar " + jarfile.toString(), - Project.MSG_INFO); - jarfile.delete(); - } - } - else { - // Log that the file is up to date... - this.log(jarfile.toString() + " is up to date.", - Project.MSG_INFO); - } - } + } } catch (SAXException se) { - String msg = "SAXException while parsing '" - + files[index].toString() - + "'. This probably indicates badly-formed XML." + String msg = "SAXException while creating parser." + " Details: " + se.getMessage(); throw new BuildException(msg, se); @@ -651,15 +239,14 @@ public class EjbJar extends MatchingTask { + "Details: " + pce.getMessage(); throw new BuildException(msg, pce); } - catch (IOException ioe) { - String msg = "IOException while parsing'" - + files[index].toString() - + "'. This probably indicates that the descriptor" - + " doesn't exist. Details:" - + ioe.getMessage(); - throw new BuildException(msg, ioe); - } } // end of execute() + + + private void processDescriptor(String descriptorFilename, SAXParser saxParser, + EJBDeploymentTool tool) { + + tool.processDescriptor(srcdir, descriptorFilename, saxParser); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java new file mode 100644 index 000000000..88b5062ee --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java @@ -0,0 +1,377 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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.util.*; +import java.util.jar.*; +import java.util.zip.*; + +import javax.xml.parsers.SAXParser; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; + +public class GenericDeploymentTool implements EJBDeploymentTool { + /** Private constants that are used when constructing the standard jarfile */ + protected static final String META_DIR = "META-INF/"; + protected static final String EJB_DD = "ejb-jar.xml"; + + /** Stores a handle to the directory to put the Jar files in */ + private File destDir = null; + + /** + * Instance variable that determines whether to use a package structure + * of a flat directory as the destination for the jar files. + */ + private boolean flatDestDir = false; + + /** Instance variable that marks the end of the 'basename' */ + private String basenameTerminator = "-"; + + /** Instance variable that stores the suffix for the generated jarfile. */ + private String genericjarsuffix = "-generic.jar"; + + /** + * The task to which this tool belongs. + */ + private Task task; + + /** + * Setter used to store the value of destination directory prior to execute() + * being called. + * @param inDir the destination directory. + */ + public void setDestdir(File inDir) { + this.destDir = inDir; + } + + /** + * Get the desitination directory. + */ + protected File getDestDir() { + return destDir; + } + + + /** + * Set the task which owns this tool + */ + public void setTask(Task task) { + this.task = task; + } + + /** + * Get the task for this tool. + */ + protected Task getTask() { + return task; + } + + /** + * Get the basename terminator. + */ + protected String getBasenameTerminator() { + return basenameTerminator; + } + + /** + * Setter used to store the suffix for the generated jar file. + * @param inString the string to use as the suffix. + */ + public void setGenericjarsuffix(String inString) { + this.genericjarsuffix = inString; + } + + /** + * Configure this tool for use in the ejbjar task. + */ + public void configure(String basenameTerminator, boolean flatDestDir) { + this.basenameTerminator = basenameTerminator; + this.flatDestDir = flatDestDir; + } + + /** + * Utility method that encapsulates the logic of adding a file entry to + * a .jar file. Used by execute() to add entries to the jar file as it is + * constructed. + * @param jStream A JarOutputStream into which to write the + * jar entry. + * @param iStream A FileInputStream from which to read the + * contents the file being added. + * @param filename A String representing the name, including + * all relevant path information, that should be stored for the entry + * being added. + */ + protected void addFileToJar(JarOutputStream jStream, + FileInputStream iStream, + String filename) + throws BuildException { + try { + // Create the zip entry and add it to the jar file + ZipEntry zipEntry = new ZipEntry(filename); + jStream.putNextEntry(zipEntry); + + // Create the file input stream, and buffer everything over + // to the jar output stream + byte[] byteBuffer = new byte[2 * 1024]; + int count = 0; + do { + jStream.write(byteBuffer, 0, count); + count = iStream.read(byteBuffer, 0, byteBuffer.length); + } while (count != -1); + + // Close up the file input stream for the class file + iStream.close(); + } + catch (IOException ioe) { + String msg = "IOException while adding entry " + + filename + "to jarfile." + + ioe.getMessage(); + throw new BuildException(msg, ioe); + } + } + + protected DescriptorHandler getDescriptorHandler(File srcDir) { + return new DescriptorHandler(srcDir); + } + + public void processDescriptor(File srcDir, String descriptorFilename, SAXParser saxParser) { + try { + DescriptorHandler handler = getDescriptorHandler(srcDir); + + /* Parse the ejb deployment descriptor. While it may not + * look like much, we use a SAXParser and an inner class to + * get hold of all the classfile names for the descriptor. + */ + saxParser.parse(new InputSource + (new FileInputStream + (new File(srcDir, descriptorFilename))), + handler); + + Hashtable ejbFiles = handler.getFiles(); + + String baseName = ""; + + // Work out what the base name is + int lastSeparatorIndex = descriptorFilename.lastIndexOf(File.separator); + int endBaseName = -1; + if (lastSeparatorIndex != -1) { + endBaseName = descriptorFilename.indexOf(basenameTerminator, + lastSeparatorIndex); + } + else { + endBaseName = descriptorFilename.indexOf(basenameTerminator); + } + + if (endBaseName != -1) { + baseName = descriptorFilename.substring(0, endBaseName); + } + + // First the regular deployment descriptor + ejbFiles.put(META_DIR + EJB_DD, + new File(srcDir, descriptorFilename)); + + addVendorFiles(ejbFiles, srcDir, baseName); + + // Lastly create File object for the Jar files. If we are using + // a flat destination dir, then we need to redefine baseName! + if (flatDestDir && baseName.length() != 0) { + int startName = baseName.lastIndexOf(File.separator); + int endName = baseName.length(); + baseName = baseName.substring(startName, endName); + } + + File jarFile = getVendorOutputJarFile(baseName); + + // By default we assume we need to build. + boolean needBuild = true; + + if (jarFile.exists()) { + long lastBuild = jarFile.lastModified(); + Iterator fileIter = ejbFiles.values().iterator(); + // Set the need build to false until we find out otherwise. + needBuild = false; + + // Loop through the files seeing if any has been touched + // more recently than the destination jar. + while( (needBuild == false) && (fileIter.hasNext()) ) { + File currentFile = (File) fileIter.next(); + needBuild = ( lastBuild < currentFile.lastModified() ); + } + } + + // Check to see if we need a build and start + // doing the work! + if (needBuild) { + // Log that we are going to build... + getTask().log( "building " + + jarFile.getName() + + " with " + + String.valueOf(ejbFiles.size()) + + " files", + Project.MSG_INFO); + + // Use helper method to write the jarfile + writeJar(baseName, jarFile, ejbFiles); + + } + else { + // Log that the file is up to date... + getTask().log(jarFile.toString() + " is up to date.", + Project.MSG_INFO); + } + + } + catch (SAXException se) { + String msg = "SAXException while parsing '" + + descriptorFilename.toString() + + "'. This probably indicates badly-formed XML." + + " Details: " + + se.getMessage(); + throw new BuildException(msg, se); + } + catch (IOException ioe) { + String msg = "IOException while parsing'" + + descriptorFilename.toString() + + "'. This probably indicates that the descriptor" + + " doesn't exist. Details:" + + ioe.getMessage(); + throw new BuildException(msg, ioe); + } + } + + /** + * Add any vendor specific files which should be included in the + * EJB Jar. + */ + protected void addVendorFiles(Hashtable ejbFiles, File srcDir, String baseName) { + } + + + /** + * 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(destDir, baseName + genericjarsuffix); + } + + /** + * 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) throws BuildException{ + JarOutputStream jarStream = null; + Iterator entryIterator = null; + String entryName = null; + File entryFile = null; + + try { + /* If the jarfile already exists then whack it and recreate it. + * Should probably think of a more elegant way to handle this + * so that in case of errors we don't leave people worse off + * than when we started =) + */ + if (jarfile.exists()) { + jarfile.delete(); + } + jarfile.getParentFile().mkdirs(); + jarfile.createNewFile(); + + // Create the streams necessary to write the jarfile + jarStream = new JarOutputStream(new FileOutputStream(jarfile)); + jarStream.setMethod(JarOutputStream.DEFLATED); + + // Loop through all the class files found and add them to the jar + entryIterator = files.keySet().iterator(); + while (entryIterator.hasNext()) { + entryName = (String) entryIterator.next(); + entryFile = (File) files.get(entryName); + + getTask().log("adding file '" + entryName + "'", + Project.MSG_VERBOSE); + + addFileToJar(jarStream, + new FileInputStream(entryFile), + entryName); + } + // All done. Close the jar stream. + jarStream.close(); + } + catch(IOException ioe) { + String msg = "IOException while processing ejb-jar file '" + + jarfile.toString() + + "'. Details: " + + ioe.getMessage(); + throw new BuildException(msg, ioe); + } + } // end of writeJar + + + /** + * Called to validate that the tool parameters have been configured. + * + */ + public void validateConfigured() throws BuildException { + if (destDir == null) { + throw new BuildException("The destdir attribute must be specified"); + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java new file mode 100644 index 000000000..e310b1ad4 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java @@ -0,0 +1,203 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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.util.*; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.taskdefs.Java; + +public class WeblogicDeploymentTool extends GenericDeploymentTool { + protected static final String WL_DD = "weblogic-ejb-jar.xml"; + protected static final String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml"; + + /** Instance variable that stores the suffix for the weblogic jarfile. */ + private String jarSuffix = "-wl.jar"; + + private Path classpath; + + /** Instance variable that determines whether generic ejb jars are kept. */ + private boolean keepgeneric = true; + + /** + * Set the classpath to be used for this compilation. + */ + public void setClasspath(Path classpath) { + this.classpath = classpath; + } + + /** + * Setter used to store the suffix for the generated weblogic jar file. + * @param inString the string to use as the suffix. + */ + public void setSuffix(String inString) { + this.jarSuffix = inString; + } + + /** + * Setter used to store the value of keepgeneric + * @param inValue a string, either 'true' or 'false'. + */ + public void setKeepgeneric(String inValue) { + this.keepgeneric = Boolean.valueOf(inValue).booleanValue(); + } + + protected DescriptorHandler getDescriptorHandler(File srcDir) { + DescriptorHandler handler = new DescriptorHandler(srcDir); + handler.registerResourceDTD("-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN", + "/weblogic/ejb/deployment/xml/ejb-jar.dtd"); + return handler; + } + + /** + * Add any vendor specific files which should be included in the + * EJB Jar. + */ + protected void addVendorFiles(Hashtable ejbFiles, File srcdir, String baseName) { + // Then the weblogic deployment descriptor + File weblogicDD = new File(srcdir, + baseName + getBasenameTerminator() + WL_DD); + + if (weblogicDD.exists()) { + ejbFiles.put(META_DIR + WL_DD, + weblogicDD); + } + + // The the weblogic cmp deployment descriptor + File weblogicCMPDD = new File(srcdir, + baseName + getBasenameTerminator() + WL_CMP_DD); + + if (weblogicCMPDD.exists()) { + ejbFiles.put(META_DIR + WL_CMP_DD, + weblogicCMPDD); + } + } + + /** + * 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); + } + + /** + * Helper method invoked by execute() for each WebLogic jar to be built. + * Encapsulates the logic of constructing a java task for calling + * weblogic.ejbc and executing it. + * @param sourceJar java.io.File representing the source (EJB1.1) jarfile. + * @param destJar java.io.File representing the destination, WebLogic + * jarfile. + */ + private void buildWeblogicJar(File sourceJar, File destJar) { + org.apache.tools.ant.taskdefs.Java javaTask = null; + + try { + String args = "-noexit " + sourceJar.getPath().replace('\\', '/') + " " + destJar.getPath().replace('\\', '/'); + + javaTask = (Java) getTask().getProject().createTask("java"); + javaTask.setClassname("weblogic.ejbc"); + javaTask.setArgs(args); + if (classpath != null) { + javaTask.setClasspath(classpath); + javaTask.setFork(true); + } + else { + javaTask.setFork(false); + } + + + getTask().log("Calling weblogic.ejbc for " + sourceJar.toString(), + Project.MSG_VERBOSE); + + javaTask.execute(); + } + catch (Exception e) { + // Have to catch this because of the semantics of calling main() + String msg = "Exception while calling ejbc. 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) throws BuildException { + // need to create a generic jar first. + File genericJarFile = super.getVendorOutputJarFile(baseName); + super.writeJar(baseName, genericJarFile, files); + + buildWeblogicJar(genericJarFile, jarFile); + if (!keepgeneric) { + getTask().log("deleting generic jar " + genericJarFile.toString(), + Project.MSG_VERBOSE); + genericJarFile.delete(); + } + } + + /** + * Called to validate that the tool parameters have been configured. + * + */ + public void validateConfigured() throws BuildException { + super.validateConfigured(); + } +}