/*
 * The Apache Software License, Version 1.1 
 *
 *
 * Copyright (c) 1999 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 acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" 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 name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * 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 and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>. 
 *
 * $Id$ 
 */

package org.apache.xml.utils.synthetic;

import java.io.IOException;

/** 
 * <meta name="usage" content="internal"/>
 * This class supports invoking Java compilation from within
 * a Java program. Recent versions of the Java environment have
 * provided such an API (in tools.jar). But that isn't available
 * on all platforms, and a fallback to the command line may be needed
 * (though this too may not always be available, eg. for security
 * reasons).
 * <p>
 * There's an additional complication in some environments --
 * such as Microsoft's VJ++ -- where the classpath as seen in
 * the System Properties may not be the one the user expects.
 * The code here is parameterized to try to deal with that.
 */
public class JavaUtils
{
        // One-time flag for whether we could dynamically load compiler API
        private static boolean cantLoadCompiler=false; 

        // Debug flag - generates debug stuff if true.
        private static boolean debug = false;
  
        /** Control whether compilation occurs with the -g option
         * (debugging information included in generated classfile).
         * This is an attribute, rather than a parameter on the compile
         * method, largely because it tends to be an all-or-nothing decision; 
         * generally you're either doing program development and want it,
         * or running in production mode and don't. But that may not match
         * the needs of future users...
         * <p>
         * TODO: Consider whether debug should be a parameter.
         * 
         * @param boolean newDebug True to request debugging data,
         * false to request optimized output. (It's uncommon to
         * want both or neither!)
         */ 
        public static void setDebug(boolean newDebug)
        {
            debug=newDebug;
        }

        /** Try to compile a .java file on disk. This will first attempt to
         * use the sun.java.tools.javac() method, then (if that is unavailable)
         * fall back upon shelling out to a command line and running javac
         * there.
         * <p>
         * NOTE: This must be _compiled_ with sun.java.tools.* (tools.jar)
         * available. We could change that to use reflection instead, if we
         * accept some overhead... minor compared to the cost of running the
         * compiler!
         * <p>
         * This has complications on some platforms. For example, under 
         * Microsoft Visual Java ++ (at least, as installed on my test system),
         * I found that I had to specify paths to both javac and xerces.jar
         * rather than counting on the shell's path and classpath having
         * been set to reach these. For that reason I've parameterized this
         * method with a few system properties, so you can adapt it to your
         * own system's needs without modifying the code:
         * <dl>
         * <dt>org.apache.xml.utils.synthetic.javac
         * <dd>Command line issued to invoke the compiler. Defaults to "javac",
         * which should work in most systems. In VJ++, try setting it to
         * "cmd /c %JAVA_HOME%\\bin\javac.exe"
         * <dt>org.apache.xml.utils.synthetic.moreclasspath
         * <dd>Additional classpath, to be prepended to the one retrieved from
         * java.class.path. Defaults to "" (empty). In VJ++, try setting it to
         * point to your copy of xerces.jar, which may not be found otherwise.
         * TODO: Reconsider prepend versus append!
         * </dl>
         * 
         * @param String fileName Which .java file to compile. Note that this may
         * be relative to the "current directory".
         * @param String classPath Additional places to look for classes that
         * this .java file depends upon. Becomes the javac command's
         * -classpath parameter value.
         * @return boolean True iff compilation succeeded.
         */
        public static boolean JDKcompile(String fileName, String classPath)
        {
                String moreClassPath=
                        System.getProperty("org.apache.xml.utils.synthetic.moreclasspath","")
                        .trim();
                if(moreClassPath.length()>0)
                        classPath=moreClassPath+';'+classPath;
                                                                                                  
                if (debug)
                {
                        System.err.println ("JavaEngine: Compiling " + fileName);
                        System.err.println ("JavaEngine: Classpath is " + classPath);
                }
    
                String code_option = debug ? "-g" : "-O";

                // Start by trying Sun's compiler API
            if(!cantLoadCompiler)
                {
                        String args[] = {
                                code_option,
                            "-classpath", classPath,
                                fileName
                        };
                                
//                         try
// 			    {
//                                 return new sun.tools.javac.Main(System.err, "javac").compile(args);
//                         }
//                         catch (Throwable th)
//                         {
//                                 System.err.println("INFORMATIONAL: Unable to load Java compiler API (eg tools.jar).");
//                                 System.err.println("\tSwitching to command-line invocation.");
//                                 cantLoadCompiler=true;
//                         }
                }
    
                // FALLTHRU:
                // Can't load javac() method; try shelling out to the command
                // line and invoking it via exec(). 
                String javac_command=
                        System.getProperty("org.apache.xml.utils.synthetic.javac","javac");
            String args[] = {
                        javac_command,
                        code_option,
                        "-classpath", classPath,
                        fileName
                        };
                try
                {
                        Process p=java.lang.Runtime.getRuntime().exec(args);
                        int compileOK=waitHardFor(p); // pause for debugging...
                        return compileOK==0; //0 == no error reported
                }
                catch(IOException e)
                {
                        System.err.println("ERROR: IO exception during exec(javac).");
                }
                catch(SecurityException e)
                {
                        System.err.println("ERROR: Unable to create subprocess to exec(javac).");
                }
                
                // FALLTHRU: All attempts failed.
                return false;
        }

  /** Subroutine: Like p.waitFor, but discards the InterruptedException
   * and goes right back into a wait. I don't want to report compiler
   * success or failure until it really has succeeded or failed... I think.
   * @param Process p to be waited for
   * @return the exitValue() of the process.
   */
  static int waitHardFor(java.lang.Process p)
  {
    boolean done=false;
    while(!done)
        try
        {
            p.waitFor();
            done=true;
        }
        catch(InterruptedException e)
        {
            System.err.println("(Compiler process wait interrupted and resumed)");
        }
     int ev=p.exitValue();  // Pause for debugging...
     return ev;
  }
        
}
