blob: ec2006c318f16c167eeceaf0e1c1ab0dc0a8c198 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.taskdefs.optional.ejb;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import javax.xml.parsers.SAXParser;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.depend.DependencyAnalyzer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* A deployment tool which creates generic EJB jars. Generic jars contains
* only those classes and META-INF entries specified in the EJB 1.1 standard
*
* This class is also used as a framework for the creation of vendor specific
* deployment tools. A number of template methods are provided through which the
* vendor specific tool can hook into the EJB creation process.
*
*/
public class GenericDeploymentTool implements EJBDeploymentTool {
/** The default buffer byte size to use for IO */
public static final int DEFAULT_BUFFER_SIZE = 1024;
/** The level to use for compression */
public static final int JAR_COMPRESS_LEVEL = 9;
/** The standard META-INF directory in jar files */
protected static final String META_DIR = "META-INF/";
/** The standard MANIFEST file */
protected static final String MANIFEST = META_DIR + "MANIFEST.MF";
/** Name for EJB Deployment descriptor within EJB jars */
protected static final String EJB_DD = "ejb-jar.xml";
/** A dependency analyzer name to find ancestor classes */
public static final String ANALYZER_SUPER = "super";
/** A dependency analyzer name to find all related classes */
public static final String ANALYZER_FULL = "full";
/** A dependency analyzer name for no analyzer */
public static final String ANALYZER_NONE = "none";
/** The default analyzer */
public static final String DEFAULT_ANALYZER = ANALYZER_SUPER;
/** The analyzer class for the super analyzer */
public static final String ANALYZER_CLASS_SUPER
= "org.apache.tools.ant.util.depend.bcel.AncestorAnalyzer";
/** The analyzer class for the super analyzer */
public static final String ANALYZER_CLASS_FULL
= "org.apache.tools.ant.util.depend.bcel.FullAnalyzer";
/**
* The configuration from the containing task. This config combined
* with the settings of the individual attributes here constitues the
* complete config for this deployment tool.
*/
private EjbJar.Config config;
/** Stores a handle to the directory to put the Jar files in */
private File destDir;
/** The classpath to use with this deployment tool. This is appended to
any paths from the ejbjar task itself.*/
private Path classpath;
/** Instance variable that stores the suffix for the generated jarfile. */
private String genericJarSuffix = "-generic.jar";
/**
* The task to which this tool belongs. This is used to access services
* provided by the ant core, such as logging.
*/
private Task task;
/**
* The classloader generated from the given classpath to load
* the super classes and super interfaces.
*/
private ClassLoader classpathLoader = null;
/**
* Set of files have been loaded into the EJB jar
*/
private Set addedfiles;
/**
* Handler used to parse the EJB XML descriptor
*/
private DescriptorHandler handler;
/**
* Dependency analyzer used to collect class dependencies
*/
private DependencyAnalyzer dependencyAnalyzer;
/** No arg constructor */
public GenericDeploymentTool() {
}
/**
* Set the destination directory; required.
* @param inDir the destination directory.
*/
public void setDestdir(File inDir) {
this.destDir = inDir;
}
/**
* Get the destination directory.
*
* @return the destination directory into which EJB jars are to be written
*/
protected File getDestDir() {
return destDir;
}
/**
* Set the task which owns this tool
*
* @param task the Task to which this deployment tool is associated.
*/
public void setTask(Task task) {
this.task = task;
}
/**
* Get the task for this tool.
*
* @return the Task instance this tool is associated with.
*/
protected Task getTask() {
return task;
}
/**
* Get the basename terminator.
*
* @return an ejbjar task configuration
*/
protected EjbJar.Config getConfig() {
return config;
}
/**
* Indicate if this build is using the base jar name.
*
* @return true if the name of the generated jar is coming from the
* basejarname attribute
*/
protected boolean usingBaseJarName() {
return config.baseJarName != null;
}
/**
* Set the suffix for the generated jar file.
* @param inString the string to use as the suffix.
*/
public void setGenericJarSuffix(String inString) {
this.genericJarSuffix = inString;
}
/**
* Add the classpath for the user classes
*
* @return a Path instance to be configured by Ant.
*/
public Path createClasspath() {
if (classpath == null) {
classpath = new Path(task.getProject());
}
return classpath.createPath();
}
/**
* Set the classpath to be used for this compilation.
*
* @param classpath the classpath to be used for this build.
*/
public void setClasspath(Path classpath) {
this.classpath = classpath;
}
/**
* Get the classpath by combining the one from the surrounding task, if any
* and the one from this tool.
*
* @return the combined classpath
*/
protected Path getCombinedClasspath() {
Path combinedPath = classpath;
if (config.classpath != null) {
if (combinedPath == null) {
combinedPath = config.classpath;
} else {
combinedPath.append(config.classpath);
}
}
return combinedPath;
}
/**
* Log a message to the Ant output.
*
* @param message the message to be logged.
* @param level the severity of this message.
*/
protected void log(String message, int level) {
getTask().log(message, level);
}
/**
* Get the build file location associated with this element's task.
*
* @return the task's location instance.
*/
protected Location getLocation() {
return getTask().getLocation();
}
private void createAnalyzer() {
String analyzer = config.analyzer;
if (analyzer == null) {
analyzer = DEFAULT_ANALYZER;
}
if (analyzer.equals(ANALYZER_NONE)) {
return;
}
String analyzerClassName = null;
if (analyzer.equals(ANALYZER_SUPER)) {
analyzerClassName = ANALYZER_CLASS_SUPER;
} else if (analyzer.equals(ANALYZER_FULL)) {
analyzerClassName = ANALYZER_CLASS_FULL;
} else {
analyzerClassName = analyzer;
}
try {
Class analyzerClass = Class.forName(analyzerClassName);
dependencyAnalyzer
= (DependencyAnalyzer) analyzerClass.newInstance();
dependencyAnalyzer.addClassPath(new Path(task.getProject(),
config.srcDir.getPath()));
dependencyAnalyzer.addClassPath(config.classpath);
} catch (NoClassDefFoundError e) {
dependencyAnalyzer = null;
task.log("Unable to load dependency analyzer: " + analyzerClassName
+ " - dependent class not found: " + e.getMessage(),
Project.MSG_WARN);
} catch (Exception e) {
dependencyAnalyzer = null;
task.log("Unable to load dependency analyzer: " + analyzerClassName
+ " - exception: " + e.getMessage(),
Project.MSG_WARN);
}
}
/**
* Configure this tool for use in the ejbjar task.
*
* @param config the configuration from the surrounding ejbjar task.
*/
public void configure(EjbJar.Config config) {
this.config = config;
createAnalyzer();
classpathLoader = null;
}
/**
* 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 inputFile A File from which to read the
* contents the file being added.
* @param logicalFilename A String representing the name, including
* all relevant path information, that should be stored for the entry
* being added.
* @throws BuildException if there is a problem.
*/
protected void addFileToJar(JarOutputStream jStream,
File inputFile,
String logicalFilename)
throws BuildException {
FileInputStream iStream = null;
try {
if (!addedfiles.contains(logicalFilename)) {
iStream = new FileInputStream(inputFile);
// Create the zip entry and add it to the jar file
ZipEntry zipEntry = new ZipEntry(logicalFilename.replace('\\', '/'));
jStream.putNextEntry(zipEntry);
// Create the file input stream, and buffer everything over
// to the jar output stream
byte[] byteBuffer = new byte[2 * DEFAULT_BUFFER_SIZE];
int count = 0;
do {
jStream.write(byteBuffer, 0, count);
count = iStream.read(byteBuffer, 0, byteBuffer.length);
} while (count != -1);
//add it to list of files in jar
addedfiles.add(logicalFilename);
}
} catch (IOException ioe) {
log("WARNING: IOException while adding entry "
+ logicalFilename + " to jarfile from "
+ inputFile.getPath() + " " + ioe.getClass().getName()
+ "-" + ioe.getMessage(), Project.MSG_WARN);
} finally {
// Close up the file input stream for the class file
if (iStream != null) {
try {
iStream.close();
} catch (IOException closeException) {
// ignore
}
}
}
}
/**
* Get a descriptionHandler.
* @param srcDir the source directory.
* @return a handler.
*/
protected DescriptorHandler getDescriptorHandler(File srcDir) {
DescriptorHandler h = new DescriptorHandler(getTask(), srcDir);
registerKnownDTDs(h);
// register any DTDs supplied by the user
for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
h.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
}
return h;
}
/**
* Register the locations of all known DTDs.
*
* vendor-specific subclasses should override this method to define
* the vendor-specific locations of the EJB DTDs
* @param handler no used in this class.
*/
protected void registerKnownDTDs(DescriptorHandler handler) {
// none to register for generic
}
/** {@inheritDoc}. */
public void processDescriptor(String descriptorFileName, SAXParser saxParser) {
checkConfiguration(descriptorFileName, saxParser);
try {
handler = getDescriptorHandler(config.srcDir);
// Retrive the files to be added to JAR from EJB descriptor
Hashtable ejbFiles = parseEjbFiles(descriptorFileName, saxParser);
// Add any support classes specified in the build file
addSupportClasses(ejbFiles);
// Determine the JAR filename (without filename extension)
String baseName = getJarBaseName(descriptorFileName);
String ddPrefix = getVendorDDPrefix(baseName, descriptorFileName);
File manifestFile = getManifestFile(ddPrefix);
if (manifestFile != null) {
ejbFiles.put(MANIFEST, manifestFile);
}
// First the regular deployment descriptor
ejbFiles.put(META_DIR + EJB_DD,
new File(config.descriptorDir, descriptorFileName));
// now the vendor specific files, if any
addVendorFiles(ejbFiles, ddPrefix);
// add any dependent files
checkAndAddDependants(ejbFiles);
// Lastly create File object for the Jar files. If we are using
// a flat destination dir, then we need to redefine baseName!
if (config.flatDestDir && baseName.length() != 0) {
int startName = baseName.lastIndexOf(File.separator);
if (startName == -1) {
startName = 0;
}
int endName = baseName.length();
baseName = baseName.substring(startName, endName);
}
File jarFile = getVendorOutputJarFile(baseName);
// Check to see if we need a build and start doing the work!
if (needToRebuild(ejbFiles, jarFile)) {
// Log that we are going to build...
log("building "
+ jarFile.getName()
+ " with "
+ String.valueOf(ejbFiles.size())
+ " files",
Project.MSG_INFO);
// Use helper method to write the jarfile
String publicId = getPublicId();
writeJar(baseName, jarFile, ejbFiles, publicId);
} else {
// Log that the file is up to date...
log(jarFile.toString() + " is up to date.",
Project.MSG_VERBOSE);
}
} catch (SAXException se) {
String msg = "SAXException while parsing '"
+ descriptorFileName
+ "'. This probably indicates badly-formed XML."
+ " Details: "
+ se.getMessage();
throw new BuildException(msg, se);
} catch (IOException ioe) {
String msg = "IOException while parsing'"
+ descriptorFileName
+ "'. This probably indicates that the descriptor"
+ " doesn't exist. Details: "
+ ioe.getMessage();
throw new BuildException(msg, ioe);
}
}
/**
* This method is called as the first step in the processDescriptor method
* to allow vendor-specific subclasses to validate the task configuration
* prior to processing the descriptor. If the configuration is invalid,
* a BuildException should be thrown.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML
* descriptor
* @throws BuildException if there is a problem.
*/
protected void checkConfiguration(String descriptorFileName,
SAXParser saxParser) throws BuildException {
/*
* For the GenericDeploymentTool, do nothing. Vendor specific
* subclasses should throw a BuildException if the configuration is
* invalid for their server.
*/
}
/**
* This method returns a list of EJB files found when the specified EJB
* descriptor is parsed and processed.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @param saxParser SAXParser which may be used to parse the XML
* descriptor
* @return Hashtable of EJB class (and other) files to be
* added to the completed JAR file
* @throws SAXException Any SAX exception, possibly wrapping another
* exception
* @throws IOException An IOException from the parser, possibly from a
* the byte stream or character stream
*/
protected Hashtable parseEjbFiles(String descriptorFileName, SAXParser saxParser)
throws IOException, SAXException {
FileInputStream descriptorStream = null;
Hashtable ejbFiles = null;
try {
/* 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.
*/
descriptorStream
= new FileInputStream(new File(config.descriptorDir, descriptorFileName));
saxParser.parse(new InputSource(descriptorStream), handler);
ejbFiles = handler.getFiles();
} finally {
if (descriptorStream != null) {
try {
descriptorStream.close();
} catch (IOException closeException) {
// ignore
}
}
}
return ejbFiles;
}
/**
* Adds any classes the user specifies using <i>support</i> nested elements
* to the <code>ejbFiles</code> Hashtable.
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
*/
protected void addSupportClasses(Hashtable ejbFiles) {
// add in support classes if any
Project project = task.getProject();
for (Iterator i = config.supportFileSets.iterator(); i.hasNext();) {
FileSet supportFileSet = (FileSet) i.next();
File supportBaseDir = supportFileSet.getDir(project);
DirectoryScanner supportScanner = supportFileSet.getDirectoryScanner(project);
supportScanner.scan();
String[] supportFiles = supportScanner.getIncludedFiles();
for (int j = 0; j < supportFiles.length; ++j) {
ejbFiles.put(supportFiles[j], new File(supportBaseDir, supportFiles[j]));
}
}
}
/**
* Using the EJB descriptor file name passed from the <code>ejbjar</code>
* task, this method returns the "basename" which will be used to name the
* completed JAR file.
*
* @param descriptorFileName String representing the file name of an EJB
* descriptor to be processed
* @return The "basename" which will be used to name the
* completed JAR file
*/
protected String getJarBaseName(String descriptorFileName) {
String baseName = "";
// Work out what the base name is
if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.BASEJARNAME)) {
String canonicalDescriptor = descriptorFileName.replace('\\', '/');
int index = canonicalDescriptor.lastIndexOf('/');
if (index != -1) {
baseName = descriptorFileName.substring(0, index + 1);
}
baseName += config.baseJarName;
} else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
int lastSeparatorIndex = descriptorFileName.lastIndexOf(File.separator);
int endBaseName = -1;
if (lastSeparatorIndex != -1) {
endBaseName = descriptorFileName.indexOf(config.baseNameTerminator,
lastSeparatorIndex);
} else {
endBaseName = descriptorFileName.indexOf(config.baseNameTerminator);
}
if (endBaseName != -1) {
baseName = descriptorFileName.substring(0, endBaseName);
} else {
throw new BuildException("Unable to determine jar name "
+ "from descriptor \"" + descriptorFileName + "\"");
}
} else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) {
File descriptorFile = new File(config.descriptorDir, descriptorFileName);
String path = descriptorFile.getAbsolutePath();
int lastSeparatorIndex
= path.lastIndexOf(File.separator);
if (lastSeparatorIndex == -1) {
throw new BuildException("Unable to determine directory name holding descriptor");
}
String dirName = path.substring(0, lastSeparatorIndex);
int dirSeparatorIndex = dirName.lastIndexOf(File.separator);
if (dirSeparatorIndex != -1) {
dirName = dirName.substring(dirSeparatorIndex + 1);
}
baseName = dirName;
} else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.EJB_NAME)) {
baseName = handler.getEjbName();
}
return baseName;
}
/**
* Get the prefix for vendor deployment descriptors.
*
* This will contain the path and the start of the descriptor name,
* depending on the naming scheme
* @param baseName the base name to use.
* @param descriptorFileName the file name to use.
* @return the prefix.
*/
public String getVendorDDPrefix(String baseName, String descriptorFileName) {
String ddPrefix = null;
if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
ddPrefix = baseName + config.baseNameTerminator;
} else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.BASEJARNAME)
|| config.namingScheme.getValue().equals(EjbJar.NamingScheme.EJB_NAME)
|| config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) {
String canonicalDescriptor = descriptorFileName.replace('\\', '/');
int index = canonicalDescriptor.lastIndexOf('/');
if (index == -1) {
ddPrefix = "";
} else {
ddPrefix = descriptorFileName.substring(0, index + 1);
}
}
return ddPrefix;
}
/**
* Add any vendor specific files which should be included in the
* EJB Jar.
* @param ejbFiles a hashtable entryname -> file.
* @param ddPrefix a prefix to use.
*/
protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
// nothing to add for generic tool.
}
/**
* 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.
* @param baseName the basename to use.
*/
File getVendorOutputJarFile(String baseName) {
return new File(destDir, baseName + genericJarSuffix);
}
/**
* This method checks the timestamp on each file listed in the <code>
* ejbFiles</code> and compares them to the timestamp on the <code>jarFile
* </code>. If the <code>jarFile</code>'s timestamp is more recent than
* each EJB file, <code>true</code> is returned. Otherwise, <code>false
* </code> is returned.
* TODO: find a way to check the manifest-file, that is found by naming convention
*
* @param ejbFiles Hashtable of EJB classes (and other) files that will be
* added to the completed JAR file
* @param jarFile JAR file which will contain all of the EJB classes (and
* other) files
* @return boolean indicating whether or not the <code>jarFile</code>
* is up to date
*/
protected boolean needToRebuild(Hashtable ejbFiles, File jarFile) {
if (jarFile.exists()) {
long lastBuild = jarFile.lastModified();
Iterator fileIter = ejbFiles.values().iterator();
// Loop through the files seeing if any has been touched
// more recently than the destination jar.
while (fileIter.hasNext()) {
File currentFile = (File) fileIter.next();
if (lastBuild < currentFile.lastModified()) {
log("Build needed because " + currentFile.getPath() + " is out of date",
Project.MSG_VERBOSE);
return true;
}
}
return false;
}
return true;
}
/**
* Returns the Public ID of the DTD specified in the EJB descriptor. Not
* every vendor-specific <code>DeploymentTool</code> will need to reference
* this value or may want to determine this value in a vendor-specific way.
*
* @return Public ID of the DTD specified in the EJB descriptor.
*/
protected String getPublicId() {
return handler.getPublicId();
}
/**
* Get the manifets file to use for building the generic jar.
*
* If the file does not exist the global manifest from the config is used
* otherwise the default Ant manifest will be used.
*
* @param prefix the prefix where to llook for the manifest file based on
* the naming convention.
*
* @return the manifest file or null if the manifest file does not exist
*/
protected File getManifestFile(String prefix) {
File manifestFile
= new File(getConfig().descriptorDir, prefix + "manifest.mf");
if (manifestFile.exists()) {
return manifestFile;
}
if (config.manifest != null) {
return config.manifest;
}
return null;
}
/**
* 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.
* @param baseName the base name to use.
* @param jarfile the jar file to write to.
* @param files the files to write to the jar.
* @param publicId the id to use.
* @throws BuildException if there is a problem.
*/
protected void writeJar(String baseName, File jarfile, Hashtable files,
String publicId) throws BuildException {
JarOutputStream jarStream = null;
try {
// clean the addedfiles set
if (addedfiles == null) {
addedfiles = new HashSet();
} else {
addedfiles.clear();
}
/* 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();
InputStream in = null;
Manifest manifest = null;
try {
File manifestFile = (File) files.get(MANIFEST);
if (manifestFile != null && manifestFile.exists()) {
in = new FileInputStream(manifestFile);
} else {
String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
in = this.getClass().getResourceAsStream(defaultManifest);
if (in == null) {
throw new BuildException("Could not find "
+ "default manifest: " + defaultManifest);
}
}
manifest = new Manifest(in);
} catch (IOException e) {
throw new BuildException ("Unable to read manifest", e, getLocation());
} finally {
if (in != null) {
in.close();
}
}
// Create the streams necessary to write the jarfile
jarStream = new JarOutputStream(new FileOutputStream(jarfile), manifest);
jarStream.setMethod(JarOutputStream.DEFLATED);
// Loop through all the class files found and add them to the jar
for (Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext();) {
String entryName = (String) entryIterator.next();
if (entryName.equals(MANIFEST)) {
continue;
}
File entryFile = (File) files.get(entryName);
log("adding file '" + entryName + "'",
Project.MSG_VERBOSE);
addFileToJar(jarStream, entryFile, entryName);
// See if there are any inner classes for this class and add them in if there are
InnerClassFilenameFilter flt = new InnerClassFilenameFilter(entryFile.getName());
File entryDir = entryFile.getParentFile();
String[] innerfiles = entryDir.list(flt);
if (innerfiles != null) {
for (int i = 0, n = innerfiles.length; i < n; i++) {
//get and clean up innerclass name
int entryIndex = entryName.lastIndexOf(entryFile.getName()) - 1;
if (entryIndex < 0) {
entryName = innerfiles[i];
} else {
entryName = entryName.substring(0, entryIndex)
+ File.separatorChar + innerfiles[i];
}
// link the file
entryFile = new File(config.srcDir, entryName);
log("adding innerclass file '" + entryName + "'",
Project.MSG_VERBOSE);
addFileToJar(jarStream, entryFile, entryName);
}
}
}
} catch (IOException ioe) {
String msg = "IOException while processing ejb-jar file '"
+ jarfile.toString()
+ "'. Details: "
+ ioe.getMessage();
throw new BuildException(msg, ioe);
} finally {
if (jarStream != null) {
try {
jarStream.close();
} catch (IOException closeException) {
// ignore
}
}
}
} // end of writeJar
/**
* Add all available classes, that depend on Remote, Home, Bean, PK
* @param checkEntries files, that are extracted from the deployment descriptor
* @throws BuildException if there is a problem.
*/
protected void checkAndAddDependants(Hashtable checkEntries)
throws BuildException {
if (dependencyAnalyzer == null) {
return;
}
dependencyAnalyzer.reset();
Iterator i = checkEntries.keySet().iterator();
while (i.hasNext()) {
String entryName = (String) i.next();
if (entryName.endsWith(".class")) {
String className = entryName.substring(0,
entryName.length() - ".class".length());
className = className.replace(File.separatorChar, '/');
className = className.replace('/', '.');
dependencyAnalyzer.addRootClass(className);
}
}
Enumeration e = dependencyAnalyzer.getClassDependencies();
while (e.hasMoreElements()) {
String classname = (String) e.nextElement();
String location
= classname.replace('.', File.separatorChar) + ".class";
File classFile = new File(config.srcDir, location);
if (classFile.exists()) {
checkEntries.put(location, classFile);
log("dependent class: " + classname + " - " + classFile,
Project.MSG_VERBOSE);
}
}
}
/**
* Returns a Classloader object which parses the passed in generic EjbJar classpath.
* The loader is used to dynamically load classes from javax.ejb.* and the classes
* being added to the jar.
* @return a classloader.
*/
protected ClassLoader getClassLoaderForBuild() {
if (classpathLoader != null) {
return classpathLoader;
}
Path combinedClasspath = getCombinedClasspath();
// only generate a new ClassLoader if we have a classpath
if (combinedClasspath == null) {
classpathLoader = getClass().getClassLoader();
} else {
classpathLoader
= getTask().getProject().createClassLoader(combinedClasspath);
}
return classpathLoader;
}
/**
* Called to validate that the tool parameters have been configured.
*
* @throws BuildException If the Deployment Tool's configuration isn't
* valid
*/
public void validateConfigured() throws BuildException {
if ((destDir == null) || (!destDir.isDirectory())) {
String msg = "A valid destination directory must be specified "
+ "using the \"destdir\" attribute.";
throw new BuildException(msg, getLocation());
}
}
}