FileDocCategorySizeDatePackage
IPlanetEjbc.javaAPI DocApache Ant 1.7058195Wed Dec 13 06:16:18 GMT 2006org.apache.tools.ant.taskdefs.optional.ejb

IPlanetEjbc

public class IPlanetEjbc extends Object
Compiles EJB stubs and skeletons for the iPlanet Application Server (iAS). The class will read a standard EJB descriptor (as well as an EJB descriptor specific to iPlanet Application Server) to identify one or more EJBs to process. It will search for EJB "source" classes (the remote ; * interface, home interface, and EJB implementation class) and the EJB stubs and skeletons in the specified destination directory. Only if the stubs and skeletons cannot be found or if they're out of date will the iPlanet Application Server ejbc utility be run.

Because this class (and it's assorted inner classes) may be bundled into the iPlanet Application Server distribution at some point (and removed from the Ant distribution), the class has been written to be independent of all Ant-specific classes. It is also for this reason (and to avoid cluttering the Apache Ant source files) that this utility has been packaged into a single source file.

For more information on Ant Tasks for iPlanet Application Server, see the IPlanetDeploymentTool and IPlanetEjbcTask classes.

see
IPlanetDeploymentTool
see
IPlanetEjbcTask
ant.task
ignore="true"

Fields Summary
private static final int
MIN_NUM_ARGS
private static final int
MAX_NUM_ARGS
private static final int
NUM_CLASSES_WITH_IIOP
private static final int
NUM_CLASSES_WITHOUT_IIOP
private static final String
ENTITY_BEAN
private static final String
STATELESS_SESSION
private static final String
STATEFUL_SESSION
private File
stdDescriptor
private File
iasDescriptor
private File
destDirectory
private String
classpath
private String[]
classpathElements
private boolean
retainSource
private boolean
debugOutput
private File
iasHomeDir
private SAXParser
parser
private EjbcHandler
handler
private Hashtable
ejbFiles
private String
displayName
Constructors Summary
public IPlanetEjbc(File stdDescriptor, File iasDescriptor, File destDirectory, String classpath, SAXParser parser)
Constructs an instance which may be used to process EJB descriptors and generate EJB stubs and skeletons, if needed.

param
stdDescriptor File referencing a standard EJB descriptor.
param
iasDescriptor File referencing an iAS-specific EJB descriptor.
param
destDirectory File referencing the base directory where both EJB "source" files are found and where stubs and skeletons will be written.
param
classpath String representation of the classpath to be used by the iAS ejbc utility.
param
parser SAXParser to be used to process both of the EJB descriptors.
todo
classpathElements is not needed here, its never used (at least IDEA tells me so! :)


                                                                                                                                                                                                                   
      
                        
                        
                        
                         
        this.stdDescriptor = stdDescriptor;
        this.iasDescriptor      = iasDescriptor;
        this.destDirectory      = destDirectory;
        this.classpath          = classpath;
        this.parser             = parser;

        /*
         * Parse the classpath into it's individual elements and store the
         * results in the "classpathElements" instance variable.
         */
        List elements = new ArrayList();
        if (classpath != null) {
            StringTokenizer st = new StringTokenizer(classpath,
                                                        File.pathSeparator);
            while (st.hasMoreTokens()) {
                elements.add(st.nextToken());
            }
            classpathElements
                    = (String[]) elements.toArray(new String[elements.size()]);
        }
    
Methods Summary
private java.lang.String[]buildArgumentList(org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc$EjbInfo ejb)
Based on this object's instance variables as well as the EJB to be processed, the correct flags and parameters are set for the ejbc command-line utility.

param
ejb The EJB for which stubs and skeletons will be compiled.
return
An array of Strings which are the command-line parameters for for the ejbc utility.


        List arguments = new ArrayList();

        /* OPTIONAL COMMAND LINE PARAMETERS */

        if (debugOutput) {
            arguments.add("-debug");
        }

        /* No beantype flag is needed for an entity bean */
        if (ejb.getBeantype().equals(STATELESS_SESSION)) {
            arguments.add("-sl");
        } else if (ejb.getBeantype().equals(STATEFUL_SESSION)) {
            arguments.add("-sf");
        }

        if (ejb.getIiop()) {
            arguments.add("-iiop");
        }

        if (ejb.getCmp()) {
            arguments.add("-cmp");
        }

        if (retainSource) {
            arguments.add("-gs");
        }

        if (ejb.getHasession()) {
            arguments.add("-fo");
        }

        /* REQUIRED COMMAND LINE PARAMETERS */

        arguments.add("-classpath");
        arguments.add(classpath);

        arguments.add("-d");
        arguments.add(destDirectory.toString());

        arguments.add(ejb.getHome().getQualifiedClassName());
        arguments.add(ejb.getRemote().getQualifiedClassName());
        arguments.add(ejb.getImplementation().getQualifiedClassName());

        /* Convert the List into an Array and return it */
        return (String[]) arguments.toArray(new String[arguments.size()]);
    
private voidcallEjbc(java.lang.String[] arguments)
Executes the iPlanet Application Server ejbc command-line utility.

param
arguments Command line arguments to be passed to the ejbc utility.


        /* Concatenate all of the command line arguments into a single String */
        StringBuffer args = new StringBuffer();
        for (int i = 0; i < arguments.length; i++) {
            args.append(arguments[i]).append(" ");
        }

        /* If an iAS home directory is specified, prepend it to the commmand */
        String command;
        if (iasHomeDir == null) {
            command = "";
        } else {
            command = iasHomeDir.toString() + File.separator + "bin"
                                                        + File.separator;
        }
        command += "ejbc ";

        log(command + args);

        /*
         * Use the Runtime object to execute an external command.  Use the
         * RedirectOutput inner class to direct the standard and error output
         * from the command to the JRE's standard output
         */
        try {
            Process p = Runtime.getRuntime().exec(command + args);
            RedirectOutput output = new RedirectOutput(p.getInputStream());
            RedirectOutput error  = new RedirectOutput(p.getErrorStream());
            output.start();
            error.start();
            p.waitFor();
            p.destroy();
        } catch (IOException e) {
            log("An IOException has occurred while trying to execute ejbc.");
            e.printStackTrace();
        } catch (InterruptedException e) {
            // Do nothing
        }
    
protected voidcheckConfiguration()
Verifies that the user selections are valid.

throws
EjbcException If the user selections are invalid.


        String msg = "";

        if (stdDescriptor == null) {
            msg += "A standard XML descriptor file must be specified.  ";
        }
        if (iasDescriptor == null) {
            msg += "An iAS-specific XML descriptor file must be specified.  ";
        }
        if (classpath == null) {
            msg += "A classpath must be specified.    ";
        }
        if (parser == null) {
            msg += "An XML parser must be specified.    ";
        }

        if (destDirectory == null) {
            msg += "A destination directory must be specified.  ";
        } else if (!destDirectory.exists()) {
            msg += "The destination directory specified does not exist.  ";
        } else if (!destDirectory.isDirectory()) {
            msg += "The destination specified is not a directory.  ";
        }

        if (msg.length() > 0) {
            throw new EjbcException(msg);
        }
    
public voidexecute()
Compiles the stub and skeletons for the specified EJBs, if they need to be updated.

throws
EjbcException If the ejbc utility cannot be correctly configured or if one or more of the EJB "source" classes cannot be found in the destination directory
throws
IOException If the parser encounters a problem reading the XML file
throws
SAXException If the parser encounters a problem processing the XML descriptor (it may wrap another exception)


        checkConfiguration();   // Throws EjbcException if unsuccessful

        EjbInfo[] ejbs = getEjbs(); // Returns list of EJBs for processing

        for (int i = 0; i < ejbs.length; i++) {
            log("EJBInfo...");
            log(ejbs[i].toString());
        }

        for (int i = 0; i < ejbs.length; i++) {
            EjbInfo ejb = ejbs[i];

            ejb.checkConfiguration(destDirectory);  // Throws EjbcException

            if (ejb.mustBeRecompiled(destDirectory)) {
                log(ejb.getName() + " must be recompiled using ejbc.");

                String[] arguments = buildArgumentList(ejb);
                callEjbc(arguments);

            } else {
                log(ejb.getName() + " is up to date.");
            }
        }
    
public java.lang.String[]getCmpDescriptors()
Returns the list of CMP descriptors referenced in the EJB descriptors.

return
An array of CMP descriptors.

        List returnList = new ArrayList();

        EjbInfo[] ejbs = handler.getEjbs();

        for (int i = 0; i < ejbs.length; i++) {
            List descriptors = (List) ejbs[i].getCmpDescriptors();
            returnList.addAll(descriptors);
        }

        return (String[]) returnList.toArray(new String[returnList.size()]);
    
public java.lang.StringgetDisplayName()
Returns the display-name element read from the standard EJB descriptor.

return
The EJB-JAR display name.

        return displayName;
    
public java.util.HashtablegetEjbFiles()
Returns a Hashtable which contains a list of EJB class files processed by the ejbc utility (both "source" class files as well as stubs and skeletons). The key for the Hashtable is a String representing the path to the class file (relative to the destination directory). The value for the Hashtable is a File object which reference the actual class file.

return
The list of EJB files processed by the ejbc utility.

        return ejbFiles;
    
private org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc$EjbInfo[]getEjbs()
Parses the EJB descriptors and returns a list of EJBs which may need to be compiled.

return
An array of objects which describe the EJBs to be processed.
throws
IOException If the parser encounters a problem reading the XML files
throws
SAXException If the parser encounters a problem processing the XML descriptor (it may wrap another exception)

        EjbInfo[] ejbs = null;

        /*
         * The EJB information is gathered from the standard XML EJB descriptor
         * and the iAS-specific XML EJB descriptor using a SAX parser.
         */

        parser.parse(stdDescriptor, handler);
        parser.parse(iasDescriptor, handler);
        ejbs = handler.getEjbs();

        return ejbs;
    
private voidlog(java.lang.String msg)
Convenience method used to print messages to the user if debugging messages are enabled.

param
msg The String to print to standard output.

        if (debugOutput) {
            System.out.println(msg);
        }
    
public static voidmain(java.lang.String[] args)
Main application method for the iPlanet Application Server ejbc utility. If the application is run with no commandline arguments, a usage statement is printed for the user.

param
args The commandline arguments passed to the application.

        File        stdDescriptor;
        File        iasDescriptor;
        File        destDirectory = null;
        String      classpath     = null;
        SAXParser   parser        = null;
        boolean     debug         = false;
        boolean     retainSource  = false;
        IPlanetEjbc ejbc;

        if ((args.length < MIN_NUM_ARGS) || (args.length > MAX_NUM_ARGS)) {
            usage();
            return;
        }

        stdDescriptor = new File(args[args.length - 2]);
        iasDescriptor = new File(args[args.length - 1]);

        for (int i = 0; i < args.length - 2; i++) {
            if (args[i].equals("-classpath")) {
                classpath = args[++i];
            } else if (args[i].equals("-d")) {
                destDirectory = new File(args[++i]);
            } else if (args[i].equals("-debug")) {
                debug = true;
            } else if (args[i].equals("-keepsource")) {
                retainSource = true;
            } else {
                usage();
                return;
            }
        }

        /* If the -classpath flag isn't specified, use the system classpath */
        if (classpath == null) {
            Properties props = System.getProperties();
            classpath = props.getProperty("java.class.path");
        }

        /*
         * If the -d flag isn't specified, use the working directory as the
         * destination directory
         */
        if (destDirectory == null) {
            Properties props = System.getProperties();
            destDirectory = new File(props.getProperty("user.dir"));
        }

        /* Construct a SAXParser used to process the descriptors */
        SAXParserFactory parserFactory = SAXParserFactory.newInstance();
        parserFactory.setValidating(true);
        try {
            parser = parserFactory.newSAXParser();
        } catch (Exception e) {
            // SAXException or ParserConfigurationException may be thrown
            System.out.println("An exception was generated while trying to ");
            System.out.println("create a new SAXParser.");
            e.printStackTrace();
            return;
        }

        /* Build and populate an instance of the ejbc utility */
        ejbc = new IPlanetEjbc(stdDescriptor, iasDescriptor, destDirectory,
                                classpath, parser);
        ejbc.setDebugOutput(debug);
        ejbc.setRetainSource(retainSource);

        /* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed */
        try {
            ejbc.execute();
        } catch (IOException e) {
            System.out.println("An IOException has occurred while reading the "
                    + "XML descriptors (" + e.getMessage() + ").");
            return;
        } catch (SAXException e) {
            System.out.println("A SAXException has occurred while reading the "
                    + "XML descriptors (" + e.getMessage() + ").");
            return;
        } catch (IPlanetEjbc.EjbcException e) {
            System.out.println("An error has occurred while executing the ejbc "
                    + "utility (" + e.getMessage() + ").");
            return;
        }
    
public voidregisterDTD(java.lang.String publicID, java.lang.String location)
Registers the location of a local DTD file or resource. By registering a local DTD, EJB descriptors can be parsed even when the remote servers which contain the "public" DTDs cannot be accessed.

param
publicID The public DTD identifier found in an XML document.
param
location The file or resource name for the appropriate DTD stored on the local machine.

        handler.registerDTD(publicID, location);
    
public voidsetDebugOutput(boolean debugOutput)
If true, enables debugging output when ejbc is executed.

param
debugOutput A boolean indicating if debugging output should be generated

        this.debugOutput = debugOutput;
    
public voidsetIasHomeDir(java.io.File iasHomeDir)
May be used to specify the "home" directory for this iAS installation. The directory specified should typically be [install-location]/iplanet/ias6/ias.

param
iasHomeDir The home directory for the user's iAS installation.

        this.iasHomeDir = iasHomeDir;
    
public voidsetRetainSource(boolean retainSource)
If true, the Java source files which are generated by the ejbc process are retained.

param
retainSource A boolean indicating if the Java source files for the stubs and skeletons should be retained.
todo
This is not documented in the HTML. On purpose?

        this.retainSource = retainSource;
    
private static voidusage()
Print a usage statement.

        System.out.println("java org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc \\");
        System.out.println("  [OPTIONS] [EJB 1.1 descriptor] [iAS EJB descriptor]");
        System.out.println("");
        System.out.println("Where OPTIONS are:");
        System.out.println("  -debug -- for additional debugging output");
        System.out.println("  -keepsource -- to retain Java source files generated");
        System.out.println("  -classpath [classpath] -- classpath used for compilation");
        System.out.println("  -d [destination directory] -- directory for compiled classes");
        System.out.println("");
        System.out.println("If a classpath is not specified, the system classpath");
        System.out.println("will be used.  If a destination directory is not specified,");
        System.out.println("the current working directory will be used (classes will");
        System.out.println("still be placed in subfolders which correspond to their");
        System.out.println("package name).");
        System.out.println("");
        System.out.println("The EJB home interface, remote interface, and implementation");
        System.out.println("class must be found in the destination directory.  In");
        System.out.println("addition, the destination will look for the stubs and skeletons");
        System.out.println("in the destination directory to ensure they are up to date.");