/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 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/>.
 */
package org.apache.xalan.xslt;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.xalan.Version;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.trace.PrintTraceListener;
import org.apache.xalan.trace.TraceManager;
import org.apache.xalan.transformer.XalanProperties;
import org.apache.xml.utils.DefaultErrorHandler;
import org.apache.xml.utils.ObjectFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * The main() method handles the Xalan command-line interface.
 * @xsl.usage general
 */
public class Process
{
  /**
   * Prints argument options.
   *
   * @param resbundle Resource bundle
   */
  protected static void printArgOptions(ResourceBundle resbundle)
  {
    System.out.println(resbundle.getString("xslProc_option"));  //"xslproc options: ");
    System.out.println("\n\t\t\t" + resbundle.getString("xslProc_common_options") + "\n");
    System.out.println(resbundle.getString("optionXSLTC"));  //"    [-XSLTC (use XSLTC for transformation)]
    System.out.println(resbundle.getString("optionIN"));  //"    [-IN inputXMLURL]");
    System.out.println(resbundle.getString("optionXSL"));  //"   [-XSL XSLTransformationURL]");
    System.out.println(resbundle.getString("optionOUT"));  //"   [-OUT outputFileName]");

    // System.out.println(resbundle.getString("optionE")); //"   [-E (Do not expand entity refs)]");
    System.out.println(resbundle.getString("optionV"));  //"   [-V (Version info)]");

    // System.out.println(resbundle.getString("optionVALIDATE")); //"   [-VALIDATE (Set whether validation occurs.  Validation is off by default.)]");
    System.out.println(resbundle.getString("optionEDUMP"));  //"   [-EDUMP {optional filename} (Do stackdump on error.)]");
    System.out.println(resbundle.getString("optionXML"));  //"   [-XML (Use XML formatter and add XML header.)]");
    System.out.println(resbundle.getString("optionTEXT"));  //"   [-TEXT (Use simple Text formatter.)]");
    System.out.println(resbundle.getString("optionHTML"));  //"   [-HTML (Use HTML formatter.)]");
    System.out.println(resbundle.getString("optionPARAM"));  //"   [-PARAM name expression (Set a stylesheet parameter)]");
    
    System.out.println(resbundle.getString("optionMEDIA"));
    System.out.println(resbundle.getString("optionFLAVOR"));
    System.out.println(resbundle.getString("optionDIAG"));
    System.out.println(resbundle.getString("optionURIRESOLVER"));  //"   [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]");    
    System.out.println(resbundle.getString("optionENTITYRESOLVER"));  //"   [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]");
    waitForReturnKey(resbundle);
    System.out.println(resbundle.getString("optionCONTENTHANDLER"));  //"   [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]");
    
    System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xalan_options") + "\n");
    
    System.out.println(resbundle.getString("optionQC"));  //"   [-QC (Quiet Pattern Conflicts Warnings)]");

    // System.out.println(resbundle.getString("optionQ"));  //"   [-Q  (Quiet Mode)]"); // sc 28-Feb-01 commented out
    System.out.println(resbundle.getString("optionTT"));  //"   [-TT (Trace the templates as they are being called.)]");
    System.out.println(resbundle.getString("optionTG"));  //"   [-TG (Trace each generation event.)]");
    System.out.println(resbundle.getString("optionTS"));  //"   [-TS (Trace each selection event.)]");
    System.out.println(resbundle.getString("optionTTC"));  //"   [-TTC (Trace the template children as they are being processed.)]");
    System.out.println(resbundle.getString("optionTCLASS"));  //"   [-TCLASS (TraceListener class for trace extensions.)]");
    System.out.println(resbundle.getString("optionLINENUMBERS")); //"   [-L use line numbers]"
    System.out.println(resbundle.getString("optionINCREMENTAL"));
    System.out.println(resbundle.getString("optionNOOPTIMIMIZE"));
    System.out.println(resbundle.getString("optionRL"));
        
    System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xsltc_options") + "\n");
    System.out.println(resbundle.getString("optionXO"));
    System.out.println(resbundle.getString("optionXD"));
    waitForReturnKey(resbundle);    
    System.out.println(resbundle.getString("optionXJ"));
    System.out.println(resbundle.getString("optionXP"));
    System.out.println(resbundle.getString("optionXN"));
    System.out.println(resbundle.getString("optionXX"));
    System.out.println(resbundle.getString("optionXT"));
  }
  
  /**
   * Command line interface to transform an XML document according to
   * the instructions found in an XSL stylesheet.  
   * <p>The Process class provides basic functionality for 
   * performing transformations from the command line.  To see a 
   * list of arguments supported, call with zero arguments.</p>
   * <p>To set stylesheet parameters from the command line, use 
   * <code>-PARAM name expression</code>. If you want to set the 
   * parameter to a string value, simply pass the string value 
   * as-is, and it will be interpreted as a string.  (Note: if 
   * the value has spaces in it, you may need to quote it depending 
   * on your shell environment).</p>
   *
   * @param argv Input parameters from command line
   */
  public static void main(String argv[])
  {
    
    // Runtime.getRuntime().traceMethodCalls(false); // turns Java tracing off
    boolean doStackDumpOnError = false;
    boolean setQuietMode = false;
    boolean doDiag = false;

    // Runtime.getRuntime().traceMethodCalls(false);
    // Runtime.getRuntime().traceInstructions(false);

    /**
     * The default diagnostic writer...
     */
    java.io.PrintWriter diagnosticsWriter = new PrintWriter(System.err, true);
    java.io.PrintWriter dumpWriter = diagnosticsWriter;
    ResourceBundle resbundle =
      (XSLMessages.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.ERROR_RESOURCES));
    String flavor = "s2s";

    if (argv.length < 1)
    {
      printArgOptions(resbundle);
    }
    else
    {
      boolean useXSLTC = false;
      for (int i = 0; i < argv.length; i++)
      {
        if ("-XSLTC".equalsIgnoreCase(argv[i]))
        {
          useXSLTC = true;
        }
      }
        
      TransformerFactory tfactory;
      if (useXSLTC)
      {
	 String key = "javax.xml.transform.TransformerFactory";
	 String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
	 Properties props = System.getProperties();
	 props.put(key, value);
	 System.setProperties(props);      
      }
      
      try
      {
        tfactory = TransformerFactory.newInstance();
      }
      catch (TransformerFactoryConfigurationError pfe)
      {
        pfe.printStackTrace(dumpWriter);
        diagnosticsWriter.println(
          XSLMessages.createMessage(
            XSLTErrorResources.ER_NOT_SUCCESSFUL, null));  //"XSL Process was not successful.");

        tfactory = null;  // shut up compiler

        doExit(-1);
      }

      boolean formatOutput = false;
      boolean useSourceLocation = false;
      String inFileName = null;
      String outFileName = null;
      String dumpFileName = null;
      String xslFileName = null;
      String treedumpFileName = null;
      PrintTraceListener tracer = null;
      String outputType = null;
      String media = null;
      Vector params = new Vector();
      boolean quietConflictWarnings = false;
      URIResolver uriResolver = null;
      EntityResolver entityResolver = null;
      ContentHandler contentHandler = null;
      int recursionLimit=-1;

      for (int i = 0; i < argv.length; i++)
      {
        if ("-XSLTC".equalsIgnoreCase(argv[i]))
        {
          // The -XSLTC option has been processed.
        }
        else if ("-TT".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
          {
            if (null == tracer)
              tracer = new PrintTraceListener(diagnosticsWriter);

            tracer.m_traceTemplates = true;
          }
          else
            printInvalidXSLTCOption("-TT");

          // tfactory.setTraceTemplates(true);
        }
        else if ("-TG".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
          {
            if (null == tracer)
              tracer = new PrintTraceListener(diagnosticsWriter);

            tracer.m_traceGeneration = true;
          }
          else
            printInvalidXSLTCOption("-TG");

          // tfactory.setTraceSelect(true);
        }
        else if ("-TS".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
          {
            if (null == tracer)
              tracer = new PrintTraceListener(diagnosticsWriter);

            tracer.m_traceSelection = true;
          }
          else
            printInvalidXSLTCOption("-TS");

          // tfactory.setTraceTemplates(true);
        }
        else if ("-TTC".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
          {
            if (null == tracer)
              tracer = new PrintTraceListener(diagnosticsWriter);

            tracer.m_traceElements = true;
          }
          else
            printInvalidXSLTCOption("-TTC");

          // tfactory.setTraceTemplateChildren(true);
        }
        else if ("-INDENT".equalsIgnoreCase(argv[i]))
        {
          int indentAmount;

          if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-'))
          {
            indentAmount = Integer.parseInt(argv[++i]);
          }
          else
          {
            indentAmount = 0;
          }

          // TBD:
          // xmlProcessorLiaison.setIndent(indentAmount);
        }
        else if ("-IN".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
            inFileName = argv[++i];
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-IN" }));  //"Missing argument for);
        }
        else if ("-MEDIA".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length)
            media = argv[++i];
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-MEDIA" }));  //"Missing argument for);
        }
        else if ("-OUT".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
            outFileName = argv[++i];
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-OUT" }));  //"Missing argument for);
        }
        else if ("-XSL".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
            xslFileName = argv[++i];
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-XSL" }));  //"Missing argument for);
        }
        else if ("-FLAVOR".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length)
          {
            flavor = argv[++i];
          }
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-FLAVOR" }));  //"Missing argument for);
        }
        else if ("-PARAM".equalsIgnoreCase(argv[i]))
        {
          if (i + 2 < argv.length)
          {
            String name = argv[++i];

            params.addElement(name);

            String expression = argv[++i];

            params.addElement(expression);
          }
          else
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-PARAM" }));  //"Missing argument for);
        }
        else if ("-E".equalsIgnoreCase(argv[i]))
        {

          // TBD:
          // xmlProcessorLiaison.setShouldExpandEntityRefs(false);
        }
        else if ("-V".equalsIgnoreCase(argv[i]))
        {
          diagnosticsWriter.println(resbundle.getString("version")  //">>>>>>> Xalan Version "
                                    + Version.getVersion() + ", " +

          /* xmlProcessorLiaison.getParserDescription()+ */
          resbundle.getString("version2"));  // "<<<<<<<");
        }
        else if ("-QC".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
            quietConflictWarnings = true;
          else
            printInvalidXSLTCOption("-QC");
        }
        else if ("-Q".equalsIgnoreCase(argv[i]))
        {
          setQuietMode = true;
        }
        else if ("-DIAG".equalsIgnoreCase(argv[i]))
        {
          doDiag = true;
        }
        else if ("-XML".equalsIgnoreCase(argv[i]))
        {
          outputType = "xml";
        }
        else if ("-TEXT".equalsIgnoreCase(argv[i]))
        {
          outputType = "text";
        }
        else if ("-HTML".equalsIgnoreCase(argv[i]))
        {
          outputType = "html";
        }
        else if ("-EDUMP".equalsIgnoreCase(argv[i]))
        {
          doStackDumpOnError = true;

          if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-'))
          {
            dumpFileName = argv[++i];
          }
        }
        else if ("-URIRESOLVER".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length)
          {
            try
            {
              uriResolver = (URIResolver) ObjectFactory.newInstance(
                argv[++i], ObjectFactory.findClassLoader(), true);

              tfactory.setURIResolver(uriResolver);
            }
            catch (ObjectFactory.ConfigurationError cnfe)
            {
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
                  new Object[]{ "-URIResolver" }));
              doExit(-1);
            }
          }
          else
          {
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-URIResolver" }));  //"Missing argument for);
            doExit(-1);
          }
        }
        else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length)
          {
            try
            {
              entityResolver = (EntityResolver) ObjectFactory.newInstance(
                argv[++i], ObjectFactory.findClassLoader(), true);
            }
            catch (ObjectFactory.ConfigurationError cnfe)
            {
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
                  new Object[]{ "-EntityResolver" }));
              doExit(-1);
            }
          }
          else
          {
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-EntityResolver" }));  //"Missing argument for);
            doExit(-1);
          }
        }
        else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i]))
        {
          if (i + 1 < argv.length)
          {
            try
            {
              contentHandler = (ContentHandler) ObjectFactory.newInstance(
                argv[++i], ObjectFactory.findClassLoader(), true);
            }
            catch (ObjectFactory.ConfigurationError cnfe)
            {
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
                  new Object[]{ "-ContentHandler" }));
              doExit(-1);
            }
          }
          else
          {
            System.err.println(
              XSLMessages.createMessage(
                XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                new Object[]{ "-ContentHandler" }));  //"Missing argument for);
            doExit(-1);
          }
        }
        else if ("-L".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
            useSourceLocation = true;
          else
            printInvalidXSLTCOption("-L");
        }
        else if ("-INCREMENTAL".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
            tfactory.setAttribute
              ("http://xml.apache.org/xalan/features/incremental", 
               java.lang.Boolean.TRUE);
          else
            printInvalidXSLTCOption("-INCREMENTAL");
        }
        else if ("-NOOPTIMIZE".equalsIgnoreCase(argv[i]))
        {
          // Default is true.
          //
          // %REVIEW% We should have a generalized syntax for negative
          // switches...  and probably should accept the inverse even
          // if it is the default.
          if (!useXSLTC)
            tfactory.setAttribute
              ("http://xml.apache.org/xalan/features/optimize", 
               java.lang.Boolean.FALSE);
          else
            printInvalidXSLTCOption("-NOOPTIMIZE");
	}
        else if ("-RL".equalsIgnoreCase(argv[i]))
        {
          if (!useXSLTC)
          {
            if (i + 1 < argv.length)
              recursionLimit = Integer.parseInt(argv[++i]);
            else
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                  new Object[]{ "-rl" }));  //"Missing argument for);
          }
          else
          {
            if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
             i++;
             
            printInvalidXSLTCOption("-RL");
          }
        }
        // Generate the translet class and optionally specify the name
        // of the translet class.
        else if ("-XO".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
            {
              tfactory.setAttribute("generate-translet", "true");
              tfactory.setAttribute("translet-name", argv[++i]);
            }
            else
              tfactory.setAttribute("generate-translet", "true");
          }
          else
          {
            if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
             i++;
            printInvalidXalanOption("-XO");
          }
        }
        // Specify the destination directory for the translet classes.
        else if ("-XD".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
              tfactory.setAttribute("destination-directory", argv[++i]);
            else
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                  new Object[]{ "-XD" }));  //"Missing argument for);
            
          }          
          else
          {
            if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
             i++;
             
            printInvalidXalanOption("-XD");
          }
        }
        // Specify the jar file name which the translet classes are packaged into.
        else if ("-XJ".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
            {
              tfactory.setAttribute("generate-translet", "true");
              tfactory.setAttribute("jar-name", argv[++i]);
            }
            else
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                  new Object[]{ "-XJ" }));  //"Missing argument for);
          }                    
          else
          {
            if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
             i++;
             
            printInvalidXalanOption("-XJ");
          }
        
        }
        // Specify the package name prefix for the generated translet classes.
        else if ("-XP".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
              tfactory.setAttribute("package-name", argv[++i]);
            else
              System.err.println(
                XSLMessages.createMessage(
                  XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
                  new Object[]{ "-XP" }));  //"Missing argument for);
          }                              
          else
          {
            if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
             i++;
             
            printInvalidXalanOption("-XP");
          }
        
        }
        // Enable template inlining.
        else if ("-XN".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            tfactory.setAttribute("enable-inlining", "true");
          }                                        
          else
            printInvalidXalanOption("-XN");        
        }
        // Turns on additional debugging message output
        else if ("-XX".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            tfactory.setAttribute("debug", "true");
          }                                        
          else
            printInvalidXalanOption("-XX");        
        }
        // Create the Transformer from the translet if the translet class is newer
        // than the stylesheet.
        else if ("-XT".equalsIgnoreCase(argv[i]))
        {
          if (useXSLTC)
          {
            tfactory.setAttribute("auto-translet", "true");
          }                                        
          else
            printInvalidXalanOption("-XT");        
        }
        else
          System.err.println(
            XSLMessages.createMessage(
              XSLTErrorResources.ER_INVALID_OPTION, new Object[]{ argv[i] }));  //"Invalid argument:);
      }
      
      // Print usage instructions if no xml and xsl file is specified in the command line
      if (inFileName == null && xslFileName == null)
      {
        System.err.println(resbundle.getString("xslProc_no_input"));
        doExit(-1);
      }

      // Note that there are usage cases for calling us without a -IN arg
      // The main XSL transformation occurs here!
      try
      {
        long start = System.currentTimeMillis();

        if (null != dumpFileName)
        {
          dumpWriter = new PrintWriter(new FileWriter(dumpFileName));
        }

        Templates stylesheet = null;

        if (null != xslFileName)
        {
          if (flavor.equals("d2d"))
          {

            // Parse in the xml data into a DOM
            DocumentBuilderFactory dfactory =
              DocumentBuilderFactory.newInstance();

            dfactory.setNamespaceAware(true);

            DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
            Node xslDOM = docBuilder.parse(new InputSource(xslFileName));

            stylesheet = tfactory.newTemplates(new DOMSource(xslDOM,
                    xslFileName));
          }
          else
          {
            // System.out.println("Calling newTemplates: "+xslFileName);
            stylesheet = tfactory.newTemplates(new StreamSource(xslFileName));
            // System.out.println("Done calling newTemplates: "+xslFileName);
          }
        }

        PrintWriter resultWriter;
        StreamResult strResult;

        if (null != outFileName)
        {
          strResult = new StreamResult(new FileOutputStream(outFileName));
          // One possible improvement might be to ensure this is 
          //  a valid URI before setting the systemId, but that 
          //  might have subtle changes that pre-existing users 
          //  might notice; we can think about that later -sc r1.46
          strResult.setSystemId(outFileName);
        }
        else
        {
          strResult = new StreamResult(System.out);
	  // We used to default to incremental mode in this case.
	  // We've since decided that since the -INCREMENTAL switch is
	  // available, that default is probably not necessary nor
	  // necessarily a good idea.
        }

        SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
        
		// This is currently controlled via TransformerFactoryImpl.
        if (!useXSLTC && useSourceLocation)
           stf.setAttribute(XalanProperties.SOURCE_LOCATION, Boolean.TRUE);        

        // Did they pass in a stylesheet, or should we get it from the 
        // document?
        if (null == stylesheet)
        {
          Source source =
            stf.getAssociatedStylesheet(new StreamSource(inFileName), media,
                                        null, null);

          if (null != source)
            stylesheet = tfactory.newTemplates(source);
          else
          {
            if (null != media)
              throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_IN_MEDIA, new Object[]{inFileName, media})); //"No stylesheet found in: "
                                            // + inFileName + ", media="
                                            // + media);
            else
              throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_PI, new Object[]{inFileName})); //"No xml-stylesheet PI found in: "
                                             //+ inFileName);
          }
        }

        if (null != stylesheet)
        {
          Transformer transformer = flavor.equals("th") ? null : stylesheet.newTransformer();

          // Override the output format?
          if (null != outputType)
          {
            transformer.setOutputProperty(OutputKeys.METHOD, outputType);
          }

          if (transformer instanceof org.apache.xalan.transformer.TransformerImpl)
          {
            org.apache.xalan.transformer.TransformerImpl impl = (org.apache.xalan.transformer.TransformerImpl)transformer;
            TraceManager tm = impl.getTraceManager();

            if (null != tracer)
              tm.addTraceListener(tracer);

            impl.setQuietConflictWarnings(quietConflictWarnings);

			// This is currently controlled via TransformerFactoryImpl.
            if (useSourceLocation)
              impl.setProperty(XalanProperties.SOURCE_LOCATION, Boolean.TRUE);

	    if(recursionLimit>0)
	      impl.setRecursionLimit(recursionLimit);

            // sc 28-Feb-01 if we re-implement this, please uncomment helpmsg in printArgOptions
            // impl.setDiagnosticsOutput( setQuietMode ? null : diagnosticsWriter );
          }

          int nParams = params.size();

          for (int i = 0; i < nParams; i += 2)
          {
            transformer.setParameter((String) params.elementAt(i),
                                     (String) params.elementAt(i + 1));
          }

          if (uriResolver != null)
            transformer.setURIResolver(uriResolver);

          if (null != inFileName)
          {
            if (flavor.equals("d2d"))
            {

              // Parse in the xml data into a DOM
              DocumentBuilderFactory dfactory =
                DocumentBuilderFactory.newInstance();

              dfactory.setCoalescing(true);
              dfactory.setNamespaceAware(true);

              DocumentBuilder docBuilder = dfactory.newDocumentBuilder();

              if (entityResolver != null)
                docBuilder.setEntityResolver(entityResolver);

              Node xmlDoc = docBuilder.parse(new InputSource(inFileName));
              Document doc = docBuilder.newDocument();
              org.w3c.dom.DocumentFragment outNode =
                doc.createDocumentFragment();

              transformer.transform(new DOMSource(xmlDoc, inFileName),
                                    new DOMResult(outNode));

              // Now serialize output to disk with identity transformer
              Transformer serializer = stf.newTransformer();
              Properties serializationProps =
                stylesheet.getOutputProperties();

              serializer.setOutputProperties(serializationProps);

              if (contentHandler != null)
              {
                SAXResult result = new SAXResult(contentHandler);

                serializer.transform(new DOMSource(outNode), result);
              }
              else
                serializer.transform(new DOMSource(outNode), strResult);
            }
            else if (flavor.equals("th"))
            {
              for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior
              {
              // System.out.println("Testing the TransformerHandler...");

              // ===============
              XMLReader reader = null;

              // Use JAXP1.1 ( if possible )      
              try
              {
                javax.xml.parsers.SAXParserFactory factory =
                  javax.xml.parsers.SAXParserFactory.newInstance();

                factory.setNamespaceAware(true);

                javax.xml.parsers.SAXParser jaxpParser =
                  factory.newSAXParser();

                reader = jaxpParser.getXMLReader();
              }
              catch (javax.xml.parsers.ParserConfigurationException ex)
              {
                throw new org.xml.sax.SAXException(ex);
              }
              catch (javax.xml.parsers.FactoryConfigurationError ex1)
              {
                throw new org.xml.sax.SAXException(ex1.toString());
              }
              catch (NoSuchMethodError ex2){}
              catch (AbstractMethodError ame){}

              if (null == reader)
              {
                reader = XMLReaderFactory.createXMLReader();
              }
              
              if (!useXSLTC)
                stf.setAttribute(org.apache.xalan.processor.TransformerFactoryImpl.FEATURE_INCREMENTAL, 
                   Boolean.TRUE);
                 
              TransformerHandler th = stf.newTransformerHandler(stylesheet);
              
              reader.setContentHandler(th);
              reader.setDTDHandler(th);
              
              if(th instanceof org.xml.sax.ErrorHandler)
                reader.setErrorHandler((org.xml.sax.ErrorHandler)th);
              
              try
              {
                reader.setProperty(
                  "http://xml.org/sax/properties/lexical-handler", th);
              }
              catch (org.xml.sax.SAXNotRecognizedException e){}
              catch (org.xml.sax.SAXNotSupportedException e){}
              try
              {
                reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
                                  true);
              } catch (org.xml.sax.SAXException se) {}
        
              th.setResult(strResult);
              
              reader.parse(new InputSource(inFileName));
              }                            
            }
            else
            {
              if (entityResolver != null)
              {
                XMLReader reader = null;

                // Use JAXP1.1 ( if possible )      
                try
                {
                  javax.xml.parsers.SAXParserFactory factory =
                    javax.xml.parsers.SAXParserFactory.newInstance();

                  factory.setNamespaceAware(true);

                  javax.xml.parsers.SAXParser jaxpParser =
                    factory.newSAXParser();

                  reader = jaxpParser.getXMLReader();
                }
                catch (javax.xml.parsers.ParserConfigurationException ex)
                {
                  throw new org.xml.sax.SAXException(ex);
                }
                catch (javax.xml.parsers.FactoryConfigurationError ex1)
                {
                  throw new org.xml.sax.SAXException(ex1.toString());
                }
                catch (NoSuchMethodError ex2){}
                catch (AbstractMethodError ame){}

                if (null == reader)
                {
                  reader = XMLReaderFactory.createXMLReader();
                }

                reader.setEntityResolver(entityResolver);

                if (contentHandler != null)
                {
                  SAXResult result = new SAXResult(contentHandler);

                  transformer.transform(
                    new SAXSource(reader, new InputSource(inFileName)),
                    result);
                }
                else
                {
                  transformer.transform(
                    new SAXSource(reader, new InputSource(inFileName)),
                    strResult);
                }
              }
              else if (contentHandler != null)
              {
                SAXResult result = new SAXResult(contentHandler);

                transformer.transform(new StreamSource(inFileName), result);
              }
              else
              {
                // System.out.println("Starting transform");
                transformer.transform(new StreamSource(inFileName),
                                      strResult);
                // System.out.println("Done with transform");
              }
            }
          }
          else
          {
            StringReader reader =
              new StringReader("<?xml version=\"1.0\"?> <doc/>");

            transformer.transform(new StreamSource(reader), strResult);
          }
        }
        else
        {
          diagnosticsWriter.println(
            XSLMessages.createMessage(
              XSLTErrorResources.ER_NOT_SUCCESSFUL, null));  //"XSL Process was not successful.");
          doExit(-1);
        }
        
	// close output streams
	if (null != outFileName && strResult!=null)
	{
   	  java.io.OutputStream out = strResult.getOutputStream();
   	  java.io.Writer writer = strResult.getWriter();
   	  try
   	  {
      	    if (out != null) out.close();
      	    if (writer != null) writer.close();
   	  }
   	  catch(java.io.IOException ie) {}
	}        

        long stop = System.currentTimeMillis();
        long millisecondsDuration = stop - start;

        if (doDiag)
        {
        	Object[] msgArgs = new Object[]{ inFileName, xslFileName, new Long(millisecondsDuration) };
        	String msg = XSLMessages.createMessage("diagTiming", msgArgs);
        	diagnosticsWriter.println('\n');
          	diagnosticsWriter.println(msg);
        }
          
      }
      catch (Throwable throwable)
      {
        while (throwable
               instanceof org.apache.xml.utils.WrappedRuntimeException)
        {
          throwable =
            ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
        }

        if ((throwable instanceof NullPointerException)
                || (throwable instanceof ClassCastException))
          doStackDumpOnError = true;

        diagnosticsWriter.println();

        if (doStackDumpOnError)
          throwable.printStackTrace(dumpWriter);
        else
        {
          DefaultErrorHandler.printLocation(diagnosticsWriter, throwable);
          diagnosticsWriter.println(
            XSLMessages.createMessage(XSLTErrorResources.ER_XSLT_ERROR, null)
            + " (" + throwable.getClass().getName() + "): "
            + throwable.getMessage());
        }

        // diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
        if (null != dumpFileName)
        {
          dumpWriter.close();
        }

        doExit(-1);
      }

      if (null != dumpFileName)
      {
        dumpWriter.close();
      }

      if (null != diagnosticsWriter)
      {

        // diagnosticsWriter.close();
      }

      // if(!setQuietMode)
      //  diagnosticsWriter.println(resbundle.getString("xsldone")); //"Xalan: done");
      // else
      // diagnosticsWriter.println("");  //"Xalan: done");
    }
  }
  
  /** It is _much_ easier to debug under VJ++ if I can set a single breakpoint 
   * before this blows itself out of the water...
   * (I keep checking this in, it keeps vanishing. Grr!)
   * */
  static void doExit(int i)
  {
    System.exit(i);
  }
  
  /**
   * Wait for a return key to continue
   * 
   * @param resbundle The resource bundle
   */
  private static void waitForReturnKey(ResourceBundle resbundle)
  {
    System.out.println(resbundle.getString("xslProc_return_to_continue"));
    try
    {
      while (System.in.read() != '\n');
    }
    catch (java.io.IOException e) { }  
  }
  
  /**
   * Print a message if an option cannot be used with -XSLTC.
   *
   * @param option The option String
   */
  private static void printInvalidXSLTCOption(String option)
  {
    System.err.println(XSLMessages.createMessage("xslProc_invalid_xsltc_option", new Object[]{option}));
  }
  
  /**
   * Print a message if an option can only be used with -XSLTC.
   *
   * @param option The option String
   */
  private static void printInvalidXalanOption(String option)
  {
    System.err.println(XSLMessages.createMessage("xslProc_invalid_xalan_option", new Object[]{option}));
  }
}
