/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 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.*;
import java.net.*;
import java.util.*;
import java.util.jar.*;
import javax.xml.parsers.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.types.*;
import org.xml.sax.*;

/**
 * BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 and 4.5.1
 * This task generates and compiles the stubs and skeletons for all ejb described into the
 * Deployement Descriptor, builds the jar file including the support files and verify
 * whether the produced jar is valid or not.
 * The supported options are:
 * <ul>
 * <li>debug  (boolean)    : turn on the debug mode for generation of stubs and skeletons (default:false)</li>
 * <li>verify (boolean)    : turn on the verification at the end of the jar production    (default:true) </li>
 * <li>verifyargs (String) : add optional argument to verify command (see vbj com.inprise.ejb.util.Verify)</li>
 * <li>basdtd (String)     : location of the BAS DTD </li>
 * <li>generateclient (boolean) : turn on the client jar file generation </li>
 * </ul>
 *
 *<PRE>
 *
 *      &lt;ejbjar srcdir=&quot;${build.classes}&quot;  basejarname=&quot;vsmp&quot;  descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
 *        &lt;borland destdir=&quot;tstlib&quot;&gt;
 *          &lt;classpath refid=&quot;classpath&quot; /&gt;
 *        &lt;/borland&gt;      
 *        &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
 *        &lt;support dir=&quot;${build.classes}&quot;&gt;
 *          &lt;include name=&quot;demo\smp\*.class&quot;/&gt;
 *          &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
 *         &lt;/support&gt;
 *     &lt;/ejbjar&gt;
 *</PRE>
 * @author     <a href="mailto:benoit.moussaud@criltelecom.com">Benoit Moussaud</a>
 *
 */
public class BorlandDeploymentTool extends GenericDeploymentTool  implements ExecuteStreamHandler 
{
    public static final String PUBLICID_BORLAND_EJB
    = "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";

    protected static final String DEFAULT_BAS45_EJB11_DTD_LOCATION 
    = "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";
    
    protected static final String DEFAULT_BAS_DTD_LOCATION 
    = "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";       
    
    protected static final String BAS_DD = "ejb-inprise.xml";    

    /** Java2iiop executable **/
    protected static final String JAVA2IIOP = "java2iiop";

    /** Verify class */
    protected static final String VERIFY = "com.inprise.ejb.util.Verify";

    /** Instance variable that stores the suffix for the borland jarfile. */
    private String jarSuffix = "-ejb.jar";

    /** Instance variable that stores the location of the borland DTD file. */
    private String borlandDTD;
        
    /** Instance variable that determines whether the debug mode is on */
    private boolean java2iiopdebug = false;

    /** Instance variable that determines whetger the client jar file is generated */
    private boolean generateclient = false;
    /** Instance variable that determines whether it is necessary to verify the produced jar */
    private boolean verify     = true;
    private String  verifyArgs = "";

    private Hashtable _genfiles = new Hashtable();

    /** 
     * set the debug mode for java2iiop (default false)
     **/
    public void setDebug(boolean debug) {
        this.java2iiopdebug = debug;
    }

    /** 
     * set the verify  mode for the produced jar (default true)
     **/
    public void setVerify(boolean verify) {
        this.verify = verify;
    }

   
    /**
     * Setter used to store the suffix for the generated borland jar file.
     * @param inString the string to use as the suffix.
     */
    public void setSuffix(String inString) {
        this.jarSuffix = inString;
    }


    /**
     * sets some additional args to send to verify command
     * @param args addtions command line parameters
     */
    public void setVerifyArgs(String args) {
        this.verifyArgs = args;
    }
        
    /**
     * Setter used to store the location of the borland DTD. This can be a file on the system 
     * or a resource on the classpath. 
     * @param inString the string to use as the DTD location.
     */
    public void setBASdtd(String inString) {
        this.borlandDTD = inString;
    }

        
    /**
     * setter used to store whether the task will include the generate client task.
     * (see : BorlandGenerateClient task)
     */
    public void setGenerateclient(boolean b) {
        this.generateclient = b;
    }


    protected DescriptorHandler getBorlandDescriptorHandler(final File srcDir) {
        DescriptorHandler handler =
            new DescriptorHandler(getTask(), srcDir) {
                    protected void processElement() {
                        if (currentElement.equals("type-storage")) {
                            // Get the filename of vendor specific descriptor
                            String fileNameWithMETA = currentText;
                            //trim the META_INF\ off of the file name
                            String fileName = fileNameWithMETA.substring(META_DIR.length(), 
                                                                         fileNameWithMETA.length() );
                            File descriptorFile = new File(srcDir, fileName);
                       
                            ejbFiles.put(fileNameWithMETA, descriptorFile);
                        }
                    }
                };
        handler.registerDTD(PUBLICID_BORLAND_EJB, 
                            borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD);
                            
        for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
            EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation)i.next();
            handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
        }
        return handler;                                    
    }

    /**
     * Add any vendor specific files which should be included in the 
     * EJB Jar.
     */
    protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {

        File borlandDD = new File(getConfig().descriptorDir,BAS_DD);
        if (borlandDD.exists()) {
            log("Borland specific file found "+ borlandDD,  Project.MSG_VERBOSE);
            ejbFiles.put(META_DIR + BAS_DD, ddPrefix + borlandDD);
        }
        else {
            log("Unable to locate borland deployment descriptor. It was expected to be in " + 
                borlandDD.getPath(), Project.MSG_WARN);
            return;
        }
    }
    
    /**
     * 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);
    }

    /**
     * Verify the produced jar file by invoking the Borland verify tool
     * @param sourceJar java.io.File representing the produced jar file
     */
    private void verifyBorlandJar(File sourceJar) {
        org.apache.tools.ant.taskdefs.Java javaTask = null;
        log("verify "+sourceJar,Project.MSG_INFO);
        try {

            String args = verifyArgs;            
            args += " "+sourceJar.getPath();
            
            javaTask = (Java) getTask().getProject().createTask("java");
            javaTask.setTaskName("verify");
            javaTask.setClassname(VERIFY);
            Commandline.Argument arguments = javaTask.createArg();
            arguments.setLine(args);
            Path classpath = getCombinedClasspath();             
            if (classpath != null) 
            {
                javaTask.setClasspath(classpath);
                javaTask.setFork(true);
            }
            
            log("Calling "+VERIFY+" for " + sourceJar.toString(), Project.MSG_VERBOSE);
            javaTask.execute();
        }
        catch (Exception e) {
            //TO DO : delete the file if it is not a valid file.
            String msg = "Exception while calling "+VERIFY+" Details: " + e.toString();
            throw new BuildException(msg, e);
        }
    }

    /**
     * Generate the client jar corresponding to the jar file passed as paremeter
     * the method uses the BorlandGenerateClient task.
     * @param sourceJar java.io.File representing the produced jar file
     */
    private void generateClient(File sourceJar) {
        getTask().getProject().addTaskDefinition("internal_bas_generateclient",
                                                 org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class);

        org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
        log("generate client for "+sourceJar,Project.MSG_INFO);
        try {
            String args = verifyArgs;            
            args += " "+sourceJar.getPath();
            
            gentask = (BorlandGenerateClient) getTask().getProject().createTask("internal_bas_generateclient");
            gentask.setEjbjar(sourceJar);
            gentask.setDebug(java2iiopdebug);            
            Path classpath = getCombinedClasspath();             
            if (classpath != null) {
                gentask.setClasspath(classpath);
            }
            gentask.setTaskName("generate client");
            gentask.execute();
        }
        catch (Exception e) {
            //TO DO : delete the file if it is not a valid file.
            String msg = "Exception while calling "+VERIFY+" Details: " + e.toString();
            throw new BuildException(msg, e);
        }
    }

    /**
     * Generate stubs & sketelton for each home found into the DD
     * Add all the generate class file into the ejb files
     * @param ithomes : iterator on home class
     * @param files   : file list , updated by the adding generated files
     */
    private void buildBorlandStubs(Iterator ithomes,Hashtable files ) {
        Execute execTask = null;

        execTask = new Execute(this);
        Project project = getTask().getProject();
        execTask.setAntRun(project);
        execTask.setWorkingDirectory(project.getBaseDir());
        
        Commandline commandline = new Commandline();
        commandline.setExecutable(JAVA2IIOP);
        //debug ?
        if ( java2iiopdebug ) {
            commandline.createArgument().setValue("-VBJdebug");                
        } // end of if ()
        //set the classpath 
        commandline.createArgument().setValue("-VBJclasspath");
        commandline.createArgument().setPath(getCombinedClasspath());
        //list file
        commandline.createArgument().setValue("-list_files");
        //no TIE classes
        commandline.createArgument().setValue("-no_tie");
        //root dir
        commandline.createArgument().setValue("-root_dir");
        commandline.createArgument().setValue(getConfig().srcDir.getAbsolutePath());
        //compiling order
        commandline.createArgument().setValue("-compile");
        //add the home class
        while ( ithomes.hasNext()) {
            commandline.createArgument().setValue(ithomes.next().toString());                
        } // end of while ()

        try {
            log("Calling java2iiop",Project.MSG_VERBOSE);                       
            log(commandline.toString(),Project.MSG_DEBUG);
            execTask.setCommandline(commandline.getCommandline());
            int result = execTask.execute();
            if ( result != 0 ) {
                String msg = "Failed executing java2iiop (ret code is "+result+")";
                throw new BuildException(msg, getTask().getLocation());
            }                       
        }
        catch (java.io.IOException e) {
            log("java2iiop exception :"+e.getMessage(),Project.MSG_ERR);
            throw new BuildException(e,getTask().getLocation());
        }            
    }

    /**
     * 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, String publicId) 
        throws BuildException {
        //build the home classes list.
        Vector homes = new Vector();
        Iterator it = files.keySet().iterator();
        while ( it.hasNext()) {
            String clazz = (String) it.next();
            if ( clazz.endsWith("Home.class") ) {
                //remove .class extension
                String home = toClass(clazz);
                homes.add(home);
                log(" Home "+home,Project.MSG_VERBOSE);
            } // end of if ()                                    
        } // end of while ()
        
        buildBorlandStubs(homes.iterator(),files);

        //add the gen files to the collection
        files.putAll(_genfiles);
        
        super.writeJar(baseName, jarFile, files, publicId);

        if ( verify ) {
            verifyBorlandJar(jarFile);
        } // end of if ()

        if ( generateclient) {
            generateClient(jarFile);
        } // end of if ()                       
    }

    /**
     * convert a class file name : A/B/C/toto.class
     * into    a class name: A.B.C.toto
     */
    private String toClass(String filename) {
        //remove the .class
        String classname = filename.substring(0,filename.lastIndexOf(".class"));
        classname = classname.replace('\\','.');
        return classname;
    }

    /**
     * convert a file name : A/B/C/toto.java
     * into    a class name: A/B/C/toto.class
     */
    private  String toClassFile(String filename) {
        //remove the .class
        String classfile = filename.substring(0,filename.lastIndexOf(".java"));
        classfile = classfile+".class";
        return classfile;
    }

    // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface

    public void start() throws IOException  { }
    public void stop()  {  }
    public void setProcessInputStream(OutputStream param1) throws IOException   { }

    /**
     *
     * @param param1 <description>
     * @exception java.io.IOException <description>
     */
    public void setProcessOutputStream(InputStream is) throws IOException
    {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String javafile;
            while ( ( javafile = reader.readLine()) != null) {
                log("buffer:" +javafile,Project.MSG_DEBUG);             
                if ( javafile.endsWith(".java") ) {
                    String classfile = toClassFile(javafile);                  
                    String key = classfile.substring(getConfig().srcDir.getAbsolutePath().length()+1);
                    log(" generated : "+ classfile ,Project.MSG_DEBUG);
                    log(" key       : "+ key       ,Project.MSG_DEBUG);
                    _genfiles.put(key, new File(classfile));                                           
                } // end of if ()                
            } // end of while ()
            reader.close();            
        }
        catch(Exception e) {
            String msg = "Exception while parsing  java2iiop output. Details: " + e.toString();
            throw new BuildException(msg, e);
        }
    }

    /**
     * @param param1 <description>
     * @exception java.io.IOException <description>
     */
    public void setProcessErrorStream(InputStream is) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String s = reader.readLine();
        if ( s != null) 
        {
            log("[java2iiop] "+s,Project.MSG_DEBUG);
        } // end of if ()        
    }
    
}
