/*
 *  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.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.xml.sax.SAXException;

/**
 * Compiles 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
 *
 * @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);
        }
    }

    /**
     * Adds to the classpath used when compiling the EJB stubs and skeletons.
     * @return the class path.
     */
    public Path createClasspath() {
        if (classpath == null) {
            classpath = new Path(getProject());
        }
        return classpath.createPath();
    }

    /**
     * If true, the Java source files which are generated by ejbc will be saved .
     *
     * @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;
    }

    /**
     * If true, 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;
    }

    /**
     * May be used to specify the "home" directory for this 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.
     * @throws BuildException if there is a problem.
     */
    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, getLocation());
        }
        if ((!ejbdescriptor.exists()) || (!ejbdescriptor.isFile())) {
            String msg = "The standard EJB descriptor (" + ejbdescriptor
                            + ") was not found or isn't a file.";
            throw new BuildException(msg, getLocation());
        }

        if (iasdescriptor == null) {
            String msg = "The iAS-speific XML descriptor must be specified using"
                            + " the \"iasdescriptor\" attribute.";
            throw new BuildException(msg, getLocation());
        }
        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, getLocation());
        }

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

        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, getLocation());
        } catch (ParserConfigurationException e) {
            String msg = "Unable to create a SAXParser: " + e.getMessage();
            throw new BuildException(msg, e, getLocation());
        }

        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, getLocation());
        } catch (SAXException e) {
            String msg = "A SAXException occurred while trying to read the XML "
                            + "descriptor file: " + e.getMessage();
            throw new BuildException(msg, e, getLocation());
        } catch (IPlanetEjbc.EjbcException e) {
            String msg = "An exception occurred while trying to run the ejbc "
                            + "utility: " + e.getMessage();
            throw new BuildException(msg, e, getLocation());
        }
    }

    /**
     * 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() {
        Path cp = null;
        if (classpath == null) {
            cp = (new Path(getProject())).concatSystemClasspath("last");
        } else {
            cp = classpath.concatSystemClasspath("ignore");
        }

        return cp;
    }
}
