/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs.optional.ejb;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.BuildException;

/**
 * Task to compile EJB stubs and skeletons for the iPlanet Application Server.
 * The EJBs to be processed are specified by the EJB 1.1 standard XML
 * descriptor, and additional attributes are obtained from the iPlanet Application
 * Server-specific XML descriptor.  Since the XML descriptors can include
 * multiple EJBs, this is a convenient way of specifying many EJBs in a single
 * Ant task.  The following attributes are allowed:
 *   <ul>
 *     <li><i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
 *                                 titled "ejb-jar.xml").  This attribute is
 *                                 required.
 *     <li><i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
 *                                 Server (typically titled "ias-ejb-jar.xml).
 *                                 This attribute is required.
 *     <li><i>dest</i> -- The is the base directory where the RMI stubs and
 *                        skeletons are written.  In addition, the class files
 *                        for each bean (home interface, remote interface, and
 *                        EJB implementation) must be found in this directory.
 *                        This attribute is required.
 *     <li><i>classpath</i> -- The classpath used when generating EJB stubs and
 *                             skeletons.  This is an optional attribute (if
 *                             omitted, the classpath specified when Ant was
 *                             started will be used).  Nested "classpath"
 *                             elements may also be used.
 *     <li><i>keepgenerated</i> -- Indicates whether or not the Java source
 *                                 files which are generated by ejbc will be
 *                                 saved or automatically deleted.  If "yes",
 *                                 the source files will be retained.  This is
 *                                 an optional attribute (if omitted, it
 *                                 defaults to "no").
 *     <li><i>debug</i> -- Indicates whether or not the ejbc utility should
 *                         log additional debugging statements to the standard
 *                         output.  If "yes", the additional debugging statements
 *                         will be generated (if omitted, it defaults to "no").
 *     <li><i>iashome</i> -- May be used to specify the "home" directory for
 *                           this iPlanet Application Server installation.  This
 *                           is used to find the ejbc utility if it isn't
 *                           included in the user's system path.  This is an
 *                           optional attribute (if specified, it should refer
 *                           to the <code>[install-location]/iplanet/ias6/ias
 *                           </code> directory).  If omitted, the ejbc utility
 *                           must be on the user's system path.
 *   </ul>
 * <p>
 * For each EJB specified, this task will locate the three classes that comprise
 * the EJB.  If these class files cannot be located in the <code>dest</code>
 * directory, the task will fail.  The task will also attempt to locate the EJB
 * stubs and skeletons in this directory.  If found, the timestamps on the
 * stubs and skeletons will be checked to ensure they are up to date.  Only if
 * these files cannot be found or if they are out of date will ejbc be called
 * to generate new stubs and skeletons.
 *
 * @see    IPlanetEjbc
 * @author Greg Nelson <a href="mailto:greg@netscape.com">greg@netscape.com</a>
 *
 * @ant.task name="iplanet-ejbc" category="ejb"
 */
public class IPlanetEjbcTask extends Task {

    /* Attributes set by the Ant build file */
    private File    ejbdescriptor;
    private File    iasdescriptor;
    private File    dest;
    private Path    classpath;
    private boolean keepgenerated = false;
    private boolean debug         = false;
    private File    iashome;

    /**
     * Sets the location of the standard XML EJB descriptor.  Typically, this
     * file is named "ejb-jar.xml".
     *
     * @param ejbdescriptor The name and location of the EJB descriptor.
     */
    public void setEjbdescriptor(File ejbdescriptor) {
        this.ejbdescriptor = ejbdescriptor;
    }

    /**
     * Sets the location of the iAS-specific XML EJB descriptor.  Typically,
     * this file is named "ias-ejb-jar.xml".
     *
     * @param iasdescriptor The name and location of the iAS-specific EJB
     *                      descriptor.
     */
    public void setIasdescriptor (File iasdescriptor) {
        this.iasdescriptor = iasdescriptor;
    }

    /**
     * Sets the destination directory where the EJB "source" classes must exist
     * and where the stubs and skeletons will be written.  The destination
     * directory must exist before this task is executed.
     *
     * @param dest The directory where the compiled classes will be written.
     */
    public void setDest(File dest) {
        this.dest = dest;
    }

    /**
     * Sets the classpath to be used when compiling the EJB stubs and skeletons.
     *
     * @param classpath The classpath to be used.
     */
    public void setClasspath(Path classpath) {
        if (this.classpath == null) {
            this.classpath = classpath;
        } else {
            this.classpath.append(classpath);
        }
    }

    /**
     * Creates a nested classpath element.
     */
    public Path createClasspath() {
        if (classpath == null) {
            classpath = new Path(project);
        }
        return classpath.createPath();
    }

    /**
     * Sets whether or not the Java source files which are generated by the
     * ejbc process should be retained or automatically deleted.
     *
     * @param keepgenerated A boolean indicating if the Java source files for
     *                      the stubs and skeletons should be retained.
     */
    public void setKeepgenerated(boolean keepgenerated) {
        this.keepgenerated = keepgenerated;
    }

    /**
     * Sets whether or not debugging output will be generated when ejbc is
     * executed.
     *
     * @param debug A boolean indicating if debugging output should be generated
     */
    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    /**
     * Setter method used to store the "home" directory of the user's iAS
     * installation.  The directory specified should typically be
     * <code>[install-location]/iplanet/ias6/ias</code>.
     *
     * @param iashome The home directory for the user's iAS installation.
     */
    public void setIashome(File iashome) {
        this.iashome = iashome;
    }

    /**
     * Does the work.
     */
    public void execute() throws BuildException {
        checkConfiguration();

        executeEjbc(getParser());
    }

    /**
     * Verifies that the user selections are valid.
     *
     * @throws BuildException If the user selections are invalid.
     */
    private void checkConfiguration() throws BuildException {

        if (ejbdescriptor == null) {
            String msg = "The standard EJB descriptor must be specified using "
                            + "the \"ejbdescriptor\" attribute.";
            throw new BuildException(msg, location);
        }
        if ((!ejbdescriptor.exists()) || (!ejbdescriptor.isFile())) {
            String msg = "The standard EJB descriptor (" + ejbdescriptor
                            + ") was not found or isn't a file.";
            throw new BuildException(msg, location);
        }

        if (iasdescriptor == null) {
            String msg = "The iAS-speific XML descriptor must be specified using"
                            + " the \"iasdescriptor\" attribute.";
            throw new BuildException(msg, location);
        }
        if ((!iasdescriptor.exists()) || (!iasdescriptor.isFile())) {
            String msg = "The iAS-specific XML descriptor (" + iasdescriptor
                            + ") was not found or isn't a file.";
            throw new BuildException(msg, location);
        }

        if (dest == null) {
            String msg = "The destination directory must be specified using "
                            + "the \"dest\" attribute.";
            throw new BuildException(msg, location);
        }
        if ((!dest.exists()) || (!dest.isDirectory())) {
            String msg = "The destination directory (" + dest + ") was not "
                            + "found or isn't a directory.";
            throw new BuildException(msg, location);
        }

        if ((iashome != null) && (!iashome.isDirectory())) {
            String msg = "If \"iashome\" is specified, it must be a valid "
                            + "directory (it was set to " + iashome + ").";
            throw new BuildException(msg, getLocation());
        }
    }

    /**
     * Returns a SAXParser that may be used to process the XML descriptors.
     *
     * @return Parser which may be used to process the EJB descriptors.
     * @throws BuildException If the parser cannot be created or configured.
     */
    private SAXParser getParser() throws BuildException {

        SAXParser saxParser = null;
        try {
            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
            saxParserFactory.setValidating(true);
            saxParser = saxParserFactory.newSAXParser();
        } catch (SAXException e) {
            String msg = "Unable to create a SAXParser: " + e.getMessage();
            throw new BuildException(msg, e, location);
        } catch (ParserConfigurationException e) {
            String msg = "Unable to create a SAXParser: " + e.getMessage();
            throw new BuildException(msg, e, location);
        }

        return saxParser;
    }

    /**
     * Executes the EJBc utility using the SAXParser provided.
     *
     * @param saxParser SAXParser that may be used to process the EJB
     *                  descriptors
     * @throws BuildException If there is an error reading or parsing the XML
     *                        descriptors
     */
    private void executeEjbc(SAXParser saxParser) throws BuildException {
        IPlanetEjbc ejbc = new IPlanetEjbc(ejbdescriptor,
                                            iasdescriptor,
                                            dest,
                                            getClasspath().toString(),
                                            saxParser);
        ejbc.setRetainSource(keepgenerated);
        ejbc.setDebugOutput(debug);
        if (iashome != null) {
            ejbc.setIasHomeDir(iashome);
        }

        try {
            ejbc.execute();
        } catch (IOException e) {
            String msg = "An IOException occurred while trying to read the XML "
                            + "descriptor file: " + e.getMessage();
            throw new BuildException(msg, e, location);
        } catch (SAXException e) {
            String msg = "A SAXException occurred while trying to read the XML "
                            + "descriptor file: " + e.getMessage();
            throw new BuildException(msg, e, location);
        } catch (IPlanetEjbc.EjbcException e) {
            String msg = "An exception occurred while trying to run the ejbc "
                            + "utility: " + e.getMessage();
            throw new BuildException(msg, e, location);
        }
    }

    /**
     * Returns the CLASSPATH to be used when calling EJBc.  If no user CLASSPATH
     * is specified, the System classpath is returned instead.
     *
     * @return Path The classpath to be used for EJBc.
     */
    private Path getClasspath() {
        if (classpath == null) {
            classpath = Path.systemClasspath;
        }

        return classpath;
    }
}
