/* gnu.classpath.tools.gjdoc.Main
   Copyright (C) 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

package gnu.classpath.tools.gjdoc;

import com.sun.javadoc.*;
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import java.text.Collator;

import gnu.classpath.tools.FileSystemClassLoader;

/**
 * Class that will launch the gjdoc tool.
 */
public final class Main
{

  /**
   * Do we load classes that are referenced as base class?
   */
  static final boolean DESCEND_SUPERCLASS = true;

  /**
   * Do we load classes that are referenced as interface?
   */
  static final boolean DESCEND_INTERFACES = false;

  /**
   * Do we load classes that are imported in a source file?
   */
  static final boolean DESCEND_IMPORTED = true;

  /**
   * Document only public members.
   */
  static final int COVERAGE_PUBLIC = 0;

  /**
   * Document only public and protected members.
   */
  static final int COVERAGE_PROTECTED = 1;

  /**
   * Document public, protected and package private members.
   */
  static final int COVERAGE_PACKAGE = 2;

  /**
   * Document all members.
   */
  static final int COVERAGE_PRIVATE = 3;

  /*
   *  FIXME: This should come from a ResourceBundle
   */
  private static final String STRING_TRY_GJDOC_HELP = 
     "Try `gjdoc --help' for more information.";

  /**
   * Grid for looking up whether a particular access level is included in the
   * documentation.
   */
  static final boolean[][] coverageTemplates = new boolean[][]
    { new boolean[]
      { true, false, false, false }, // public
        new boolean[]
          { true, true, false, false }, // protected
        new boolean[]
          { true, true, true, false }, // package
        new boolean[]
          { true, true, true, true }, // private
    };

  /**
   * Holds the Singleton instance of this class.
   */
  private static Main instance = new Main();

  /**
   * Avoid re-instantiation of this class.
   */
  private Main()
  {
  }

  private static RootDocImpl rootDoc;

  private ErrorReporter reporter;

  /**
   * Cache for version string from resource /version.properties
   */
  private String gjdocVersion;

  /**
   * <code>false</code> during Phase I: preparation of the documentation data.
   * <code>true</code> during Phase II: documentation output by doclet.
   */
  boolean docletRunning = false;

  //---- Command line options

  /**
   * Option "-doclet": name of the Doclet class to use.
   */
  private String option_doclet = "gnu.classpath.tools.doclets.htmldoclet.HtmlDoclet";

  /**
   * Option "-overview": path to the special overview file.
   */
  private String option_overview;

  /**
   * Option "-coverage": which members to include in generated documentation.
   */
  private int option_coverage = COVERAGE_PROTECTED;

  /**
   * Option "-help": display command line usage.
   */
  private boolean option_help;

  /**
   * Option "-docletpath": path to doclet classes.
   */
  private String option_docletpath;

  /**
   * Option "-classpath": path to additional classes.
   */
  private String option_classpath;

  /**
   * Option "-sourcepath": path to the Java source files to be documented.
   * FIXME: this should be a list of paths
   */
  private List option_sourcepath = new ArrayList();

  /**
   * Option "-extdirs": path to Java extension files.
   */
  private String option_extdirs;

  /**
   * Option "-verbose": Be verbose when generating documentation.
   */
  private boolean option_verbose;

  /**
   * Option "-nowarn": Do not print warnings.
   */
  private boolean option_nowarn;

  /**
   * Option "-locale:" Specify the locale charset of Java source files.
   */
  private Locale option_locale = new Locale("en", "us");

  /**
   * Option "-encoding": Specify character encoding of Java source files.
   */
  private String option_encoding;

  /**
   * Option "-J": Specify flags to be passed to Java runtime.
   */
  private List option_java_flags = new LinkedList(); //ArrayList();

  /**
   * Option "-source:" should be 1.4 to handle assertions, 1.1 is no
   * longer supported.
   */
  private String option_source = "1.2";

  /**
   * Option "-subpackages": list of subpackages to be recursively
   * added.
   */
  private List option_subpackages = new ArrayList();

  /**
   * Option "-exclude": list of subpackages to exclude.
   */
  private List option_exclude = new ArrayList();

  /**
   * Option "-breakiterator" - whether to use BreakIterator for
   * detecting the end of the first sentence.
   */
  private boolean option_breakiterator;

  /**
   * Option "-licensetext" - whether to copy license text.
   */
  private boolean option_licensetext;

  /**
   * The locale-dependent collator used for sorting.
   */
  private Collator collator;

  /**
   * true when --version has been specified on the command line.
   */
  private boolean option_showVersion;
  
  /**
   * true when -bootclasspath has been specified on the command line.
   */
  private boolean option_bootclasspath_specified;
  
  /**
   * true when -all has been specified on the command line.
   */
  private boolean option_all;

  /**
   * true when -reflection has been specified on the command line.
   */
  private boolean option_reflection;
  
  // TODO: add the rest of the options as instance variables
  
  /**
   * Parse all source files/packages and subsequentially start the Doclet given
   * on the command line.
   * 
   * @param allOptions List of all command line tokens
   */
  private boolean startDoclet(List allOptions)
  {

    try
    {

      //--- Fetch the Class object for the Doclet.

      Debug.log(1, "loading doclet class...");

      Class docletClass;

      if (null != option_docletpath) {
        try {
          FileSystemClassLoader docletPathClassLoader
            = new FileSystemClassLoader(option_docletpath);
          System.err.println("trying to load class  " + option_doclet + " from path " + option_docletpath);
          docletClass = docletPathClassLoader.findClass(option_doclet);
        }
        catch (Exception e) {
          docletClass = Class.forName(option_doclet);
        }
      }
      else {
        docletClass = Class.forName(option_doclet);
      }
      //Object docletInstance = docletClass.newInstance();

      Debug.log(1, "doclet class loaded...");

      Method startTempMethod = null;
      Method startMethod = null;
      Method optionLenMethod = null;
      Method validOptionsMethod = null;

      //--- Try to find the optionLength method in the Doclet class.

      try
      {
        optionLenMethod = docletClass.getMethod("optionLength", new Class[]
          { String.class });
      }
      catch (NoSuchMethodException e)
      {
        // Ignore if not found; it's OK it the Doclet class doesn't define
        // this method.
      }

      //--- Try to find the validOptions method in the Doclet class.

      try
      {
        validOptionsMethod = docletClass.getMethod("validOptions", new Class[]
          { String[][].class, DocErrorReporter.class });
      }
      catch (NoSuchMethodException e)
      {
        // Ignore if not found; it's OK it the Doclet class doesn't define
        // this method.
      }

      //--- Find the start method in the Doclet class; complain if not found

      try
      {
        startTempMethod = docletClass.getMethod("start", new Class[]
          { TemporaryStore.class });
      }
      catch (Exception e)
      {
        // ignore
      }
      startMethod = docletClass.getMethod("start", new Class[]
        { RootDoc.class });

      //--- Feed the custom command line tokens to the Doclet

      // stores all recognized options
      List options = new LinkedList();

      // stores packages and classes defined on the command line
      List packageAndClasses = new LinkedList();

      for (Iterator it = allOptions.iterator(); it.hasNext();)
      {
        String option = (String) it.next();

        Debug.log(9, "parsing option '" + option + "'");

        if (option.startsWith("-"))
        {

          //--- Parse option

          int optlen = optionLength(option);

          //--- Try to get option length from Doclet class

          if (optlen <= 0 && optionLenMethod != null)
          {

            optionLenMethod.invoke(null, new Object[]
              { option });

            Debug.log(3, "invoking optionLen method");

            optlen = ((Integer) optionLenMethod.invoke(null, new Object[]
              { option })).intValue();

            Debug.log(3, "done");
          }

          if (optlen <= 0) {

            if (option.startsWith("-JD")) {
              // Simulate VM option -D
              String propertyValue = option.substring(3);
              int ndx = propertyValue.indexOf('=');
              if (ndx <= 0) {
                reporter.printError("Illegal format in option " + option + ": use -JDproperty=value");
                return false;
              }
              else {
                String property = propertyValue.substring(0, ndx);
                String value = propertyValue.substring(ndx + 1);
                System.setProperty(property, value);
              }
            }
            else if (option.startsWith("-J")) {
              //--- Warn if VM option is encountered
              reporter.printWarning("Ignored option " + option + ". Pass this option to the VM if required.");
            }
            else {
              //--- Complain if not found

              reporter.printError("Unknown option " + option);
              reporter.printNotice(STRING_TRY_GJDOC_HELP);
              return false;
            }
          }
          else
          {

            //--- Read option values

            String[] optionAndValues = new String[optlen];
            optionAndValues[0] = option;
            for (int i = 1; i < optlen; ++i)
            {
              if (!it.hasNext())
              {
                reporter.printError("Missing value for option " + option);
                return false;
              }
              else
              {
                optionAndValues[i] = (String) it.next();
              }
            }

            //--- Store option for processing later

            options.add(optionAndValues);
          }
        }
        else if (option.length() > 0)
        {

          //--- Add to list of packages/classes if not option or option
          // value

          packageAndClasses.add(option);
        }
      }

      Debug.log(9, "options parsed...");

      //--- For each package specified with the -subpackages option on
      //         the command line, recursively find all valid java files
      //         beneath it.

      //--- For each class or package specified on the command line,
      //         check that it exists and find out whether it is a class
      //         or a package

      for (Iterator it = option_subpackages.iterator(); it.hasNext();)
      {
        String subpackage = (String) it.next();
        Set foundPackages = new LinkedHashSet();

        for (Iterator pit = option_sourcepath.iterator(); pit.hasNext(); ) {
          File sourceDir = (File)pit.next();
          File packageDir = new File(sourceDir, subpackage.replace('.', File.separatorChar));
          findPackages(subpackage, packageDir, foundPackages);
        }

        addFoundPackages(subpackage, foundPackages);
      }

      if (option_all) {
        Set foundPackages = new LinkedHashSet();
        for (Iterator pit = option_sourcepath.iterator(); pit.hasNext(); ) {
          File sourceDir = (File)pit.next();
          findPackages("", sourceDir, foundPackages);
        }
        addFoundPackages(null, foundPackages);
        for (Iterator packageIt = foundPackages.iterator(); packageIt.hasNext(); ) {
          String packageName = (String)packageIt.next();
          if (null == packageName) {
            packageName = "";
          }
          rootDoc.addSpecifiedPackageName(packageName);
        }
      }

      for (Iterator it = packageAndClasses.iterator(); it.hasNext();)
      {

        String classOrPackage = (String) it.next();

        boolean foundSourceFile = false;

        if (classOrPackage.endsWith(".java")) {
          for (Iterator pit = option_sourcepath.iterator(); pit.hasNext() && !foundSourceFile; ) {
            File sourceDir = (File)pit.next();
            File sourceFile = new File(sourceDir, classOrPackage);
            if (sourceFile.exists() && !sourceFile.isDirectory()) {
              rootDoc.addSpecifiedSourceFile(sourceFile);
              foundSourceFile = true;
              break;
            }
          }
          if (!foundSourceFile) {
            File sourceFile = new File(classOrPackage);
            if (sourceFile.exists() && !sourceFile.isDirectory()) {
              rootDoc.addSpecifiedSourceFile(sourceFile);
              foundSourceFile = true;
            } 
          }
        }

        if (!foundSourceFile) {
        //--- Check for illegal name

        if (classOrPackage.startsWith(".")
            || classOrPackage.endsWith(".")
            || classOrPackage.indexOf("..") > 0
            || !checkCharSet(classOrPackage,
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_."))
        {
          throw new ParseException("Illegal class or package name '"
              + classOrPackage + "'");
        }

        //--- Assemble absolute path to package

        String classOrPackageRelPath = classOrPackage.replace('.',
            File.separatorChar);

        //--- Create one file object each for a possible package directory
        //         and a possible class file, and find out if they exist.

        List packageDirs = rootDoc.findSourceFiles(classOrPackageRelPath);
        List sourceFiles = rootDoc.findSourceFiles(classOrPackageRelPath + ".java");

        boolean packageDirExists = !packageDirs.isEmpty();
        boolean sourceFileExists = !sourceFiles.isEmpty();

        //--- Complain if neither exists: not found

        if (!packageDirExists && !sourceFileExists)
        {
          reporter.printError("Class or package " + classOrPackage
              + " not found.");
          return false;
        }

        //--- Complain if both exist: ambigious

        else
          if (packageDirExists && sourceFileExists)
          {
            reporter.printError("Ambigious class/package name "
                + classOrPackage + ".");
            return false;
          }

          //--- Otherwise, if the package directory exists, it is a package

          else
            if (packageDirExists) {
              Iterator packageDirIt = packageDirs.iterator();
              boolean packageDirFound = false;
              while (packageDirIt.hasNext()) {
                File packageDir = (File)packageDirIt.next();
                if (packageDir.isDirectory()) {
                  rootDoc.addSpecifiedPackageName(classOrPackage);
                  packageDirFound = true;
                  break;
                }
              }
              if (!packageDirFound) {
                reporter.printError("No suitable file or directory found for" + classOrPackage);
                return false;
              }
            }

            //--- Otherwise, emit error message

            else {
                reporter.printError("No sources files found for package " + classOrPackage);
            }
        }
      }

      //--- Complain if no packages or classes specified

      if (option_help) {
        usage();
        return true;
      }

      //--- Validate custom options passed on command line
      //         by asking the Doclet if they are OK.

      String[][] customOptionArr = (String[][]) options
          .toArray(new String[0][0]);
      if (validOptionsMethod != null
          && !((Boolean) validOptionsMethod.invoke(null, new Object[]
            { customOptionArr, reporter })).booleanValue())
      {
        // Not ok: shutdown system.
        reporter.printNotice(STRING_TRY_GJDOC_HELP);
        return false;
      }

      if (!rootDoc.hasSpecifiedPackagesOrClasses()) {
        reporter.printError("No packages or classes specified.");
        reporter.printNotice(STRING_TRY_GJDOC_HELP);
        return false;
      }

      rootDoc.setOptions(customOptionArr);

      rootDoc.build();

      //--- Bail out if no classes found

      if (0 == rootDoc.classes().length
          && 0 == rootDoc.specifiedPackages().length
          && 0 == rootDoc.specifiedClasses().length)
      {
        reporter.printError("No packages or classes found(!).");
        return false;
      }

      //--- Our work is done, tidy up memory

      System.gc();
      System.gc();

      //--- Set flag indicating Phase II of documentation generation

      docletRunning = true;

      //--- Invoke the start method on the Doclet: produce output

      reporter.printNotice("Running doclet...");

      TemporaryStore tstore = new TemporaryStore(Main.rootDoc);

      Thread.currentThread().setContextClassLoader(docletClass.getClassLoader());

      if (null != startTempMethod)
      {
        startTempMethod.invoke(null, new Object[]
          { tstore });
      }
      else
      {
        startMethod.invoke(null, new Object[]
          { tstore.getAndClear() });
      }

      //--- Let the user know how many warnings/errors occured

      if (reporter.getWarningCount() > 0)
      {
        reporter.printNotice(reporter.getWarningCount() + " warnings");
      }

      if (reporter.getErrorCount() > 0)
      {
        reporter.printNotice(reporter.getErrorCount() + " errors");
      }

      System.gc();

      //--- Done.
      return true;
    }
    catch (Exception e)
    {
      e.printStackTrace();
      return false;
    }
  }

  private void addFoundPackages(String subpackage, Set foundPackages)
  {        
    if (foundPackages.isEmpty()) {
      reporter.printWarning("No classes found under subpackage " + subpackage);
    }
    else {
      boolean onePackageAdded = false;
      for (Iterator rit = foundPackages.iterator(); rit.hasNext();) {
        String foundPackage = (String)rit.next();
        boolean excludeThisPackage = false;

        for (Iterator eit = option_exclude.iterator(); eit.hasNext();) {
          String excludePackage = (String)eit.next();
          if (foundPackage.equals(excludePackage) ||
              foundPackage.startsWith(excludePackage + ":")) {
            excludeThisPackage = true;
            break;
          }
        }

        if (!excludeThisPackage) {
          rootDoc.addSpecifiedPackageName(foundPackage);
          onePackageAdded = true;
        }
      }
      if (!onePackageAdded) {
        if (null != subpackage) {
          reporter.printWarning("No non-excluded classes found under subpackage " + subpackage);
        }
        else {
          reporter.printWarning("No non-excluded classes found.");
        }
      }
    }
  }

  /**
   *  Verify that the given file is a valid Java source file and that
   *  it specifies the given package.
   */
  private boolean isValidJavaFile(File file,
                                  String expectedPackage)
  {
    try {
      InputStream in = new BufferedInputStream(new FileInputStream(file));

      int ch, prevChar = 0;

      final int STATE_DEFAULT = 0;
      final int STATE_COMMENT = 1;
      final int STATE_LINE_COMMENT = 2;

      int state = STATE_DEFAULT;

      StringBuffer word = new StringBuffer();
      int wordIndex = 0;

      while ((ch = in.read()) >= 0) {
        String completeWord = null;

        switch (state) {
        case STATE_COMMENT:
          if (prevChar == '*' && ch == '/') {
            state = STATE_DEFAULT;
          }
          break;

        case STATE_LINE_COMMENT:
          if (ch == '\n') {
            state = STATE_DEFAULT;
          }
          break;

        case STATE_DEFAULT:
          if (prevChar == '/' && ch == '*') {
            word.deleteCharAt(word.length() - 1);
            if (word.length() > 0) {
              completeWord = word.toString();
              word.setLength(0);
            }
            state = STATE_COMMENT;
          }
          else if (prevChar == '/' && ch == '/') {
            word.deleteCharAt(word.length() - 1);
            if (word.length() > 0) {
              completeWord = word.toString();
              word.setLength(0);
            }
            state = STATE_LINE_COMMENT;
          }
          else if (" \t\r\n".indexOf(ch) >= 0) {
            if (word.length() > 0) {
              completeWord = word.toString();
              word.setLength(0);
            }
          }
          else if (1 == wordIndex && ';' == ch) {
            if (word.length() > 0) {
              completeWord = word.toString();
              word.setLength(0);
            }
            else {
              // empty package name in source file: "package ;" -> invalid source file
              in.close();
              return false;
            }
          }
          else {
            word.append((char)ch);
          }
          break;
        }

        if (null != completeWord) {
          if (0 == wordIndex && !"package".equals(completeWord)) {
            in.close();
            return "".equals(expectedPackage);
          }
          else if (1 == wordIndex) {
            in.close();
            return expectedPackage.equals(completeWord);
          }
          ++ wordIndex;
        }

        prevChar = ch;
      }

      // no package or class found before end-of-file -> invalid source file

      in.close();
      return false;
    }
    catch (IOException e) {
      reporter.printWarning("Could not examine file " + file + ": " + e);
      return false;
    }
  }

  /**
   *  Recursively try to locate valid Java packages under the given
   *  package specified by its name and its directory. Add the names
   *  of all valid packages to the result list.
   */
  private void findPackages(String subpackage, 
                            File packageDir, 
                            Set result)
  {
    File[] files = packageDir.listFiles();
    if (null != files) {
      for (int i=0; i<files.length; ++i) {
        File file = files[i];
        if (!file.isDirectory() && file.getName().endsWith(".java")) {
          if (isValidJavaFile(file, subpackage)) {
            if ("".equals(subpackage)) {
              result.add(null);
            }
            else {
              result.add(subpackage);
            }
            break;
          }
        }
      }
      for (int i=0; i<files.length; ++i) {
        File file = files[i];
        if (file.isDirectory()) {
          String newSubpackage;
          if (null != subpackage && subpackage.length() > 0) {
            newSubpackage = subpackage + "." + file.getName();
          }
          else {
            newSubpackage = file.getName();
          }
          findPackages(newSubpackage, file, result);
        }
      }
    }
  }

  /**
   *
   */
  private static boolean validOptions(String options[][],
      DocErrorReporter reporter)
  {

    boolean foundDocletOption = false;
    for (int i = 0; i < options.length; i++)
    {
      String[] opt = options[i];
      if (opt[0].equalsIgnoreCase("-doclet"))
      {
        if (foundDocletOption)
        {
          reporter.printError("Only one -doclet option allowed.");
          return false;
        }
        else
        {
          foundDocletOption = true;
        }
      }
    }

    return true;
  }

  /**
   * Main entry point. This is the method called when gjdoc is invoked from the
   * command line.
   * 
   * @param args
   *          command line arguments
   */
  public static void main(String[] args)
  {

    try
    {
      //--- Remember current time for profiling purposes

      Timer.setStartTime();

      //--- Handle control to the Singleton instance of this class

      int result = instance.start(args);

      if (result < 0) {
        // fatal error
        System.exit(5);
      }
      else if (result > 0) {
        // errors encountered
        System.exit(1);
      }
      else {
        // success
        System.exit(0);
      }
    }
    catch (Exception e)
    {
      //--- unexpected error
      e.printStackTrace();
      System.exit(1);
    }
  }

  /**
   * Parses command line arguments and subsequentially handles control to the
   * startDoclet() method
   *   
   * @param args The command line parameters.
   */
   public static int execute(String[] args)
   {
     try
     {
       int result = instance.start(args);
       if (result < 0) {
         // fatal error
         return 5;
       }
       else if (result > 0) {
         // errors encountered
         return 1;
       }
       else {
         // success
         return 0;
       }
     }
     catch (Exception e)
     {
       // unexpected error
       return 1;
     }
   }

  /**
   * @param programName Name of the program (for error messages). *disregarded*
   * @param args The command line parameters.
   * @returns The return code.
   */
  public static int execute(String programName,
                            String[] args)
  {
    return execute(args);
  }
 
  /**
   * @param programName Name of the program (for error messages).
   * @param defaultDocletClassName Fully qualified class name.
   * @param args The command line parameters.
   * @returns The return code.
   *//*
  public static int execute(String programName,
                            String defaultDocletClassName,
                            String[] args)
  {
    // not yet implemented
  }*/
 
  /**
   * @param programName Name of the program (for error messages).
   * @param defaultDocletClassName Fully qualified class name.
   * @param args The command line parameters.
   * @returns The return code.
   *//*
  public static int execute(String programName,
                            String defaultDocletClassName,
                            String[] args)
  {
    // not yet implemented
  }*/
 
  /**
   * @param programName Name of the program (for error messages).
   * @param errWriter PrintWriter to receive error messages.
   * @param warnWriter PrintWriter to receive error messages.
   * @param noticeWriter PrintWriter to receive error messages.
   * @param defaultDocletClassName Fully qualified class name.
   * @param args The command line parameters.
   * @returns The return code.
   *//*
  public static int execute(String programName,
                            PrintWriter errWriter,
                            PrintWriter warnWriter,
                            PrintWriter noticeWriter,
                            String defaultDocletClassName,
                            String[] args)
  {
    // not yet implemented
  }*/

  /**
   * Parses command line arguments and subsequentially handles control to the
   * startDoclet() method
   * 
   * @param args
   *          Command line arguments, as passed to the main() method
   * @return {@code -1} in case of a fatal error (invalid arguments),
   * or the number of errors encountered.
   * @exception ParseException
   *              FIXME
   * @exception IOException
   *              if an IO problem occur
   */
  public int start(String[] args) throws ParseException, IOException
  {

    //--- Collect unparsed arguments in array and resolve references
    //         to external argument files.

    List arguments = new ArrayList(args.length);

    for (int i = 0; i < args.length; ++i)
    {
      if (!args[i].startsWith("@"))
      {
        arguments.add(args[i]);
      }
      else
      {
        FileReader reader = new FileReader(args[i].substring(1));
        StreamTokenizer st = new StreamTokenizer(reader);
        st.resetSyntax();
        st.wordChars('\u0000', '\uffff');
        st.quoteChar('\"');
        st.quoteChar('\'');
        st.whitespaceChars(' ', ' ');
        st.whitespaceChars('\t', '\t');
        st.whitespaceChars('\r', '\r');
        st.whitespaceChars('\n', '\n');
        while (st.nextToken() != StreamTokenizer.TT_EOF)
        {
          arguments.add(st.sval);
        }
      }
    }

    //--- Initialize Map for option parsing

    initOptions();

    //--- This will hold all options recognized by gjdoc itself
    //         and their associated arguments.
    //         Contains objects of type String[], where each entry
    //         specifies an option along with its aguments.

    List options = new LinkedList();

    //--- This will hold all command line tokens not recognized
    //         to be part of a standard option.
    //         These options are intended to be processed by the doclet
    //         Contains objects of type String, where each entry is
    //         one unrecognized token.

    List customOptions = new LinkedList();

    rootDoc = new RootDocImpl();
    reporter = rootDoc.getReporter();

    //--- Iterate over all options given on the command line

    for (Iterator it = arguments.iterator(); it.hasNext();)
    {

      String arg = (String) it.next();

      //--- Check if gjdoc recognizes this option as a standard option
      //         and remember the options' argument count

      int optlen = optionLength(arg);

      //--- Argument count == 0 indicates that the option is not recognized.
      //         Add it to the list of custom option tokens

      //--- Otherwise the option is recognized as a standard option.
      //         if all required arguments are supplied. Create a new String
      //         array for the option and its arguments, and store it
      //         in the options array.

      if (optlen > 0)
      {
        String[] option = new String[optlen];
        option[0] = arg;
        boolean optargs_ok = true;
        for (int j = 1; j < optlen && optargs_ok; ++j)
        {
          if (it.hasNext())
          {
            option[j] = (String) it.next();
            if (option[j].startsWith("-"))
            {
              optargs_ok = false;
            }
          }
          else
          {
            optargs_ok = false;
          }
        }
        if (optargs_ok)
          options.add(option);
        else
        {
          //         If the option requires more arguments than given on the
          //         command line, issue a fatal error

          reporter.printFatal("Missing value for option " + arg + ".");
        }
      }
    }

    //--- Create an array of String arrays from the dynamic array built above

    String[][] optionArr = (String[][]) options.toArray(new String[options
        .size()][0]);

    //--- Validate all options and issue warnings/errors

    if (validOptions(optionArr, rootDoc))
    {

      //--- We got valid options; parse them and store the parsed values
      //         in 'option_*' fields.

      readOptions(optionArr);

      //--- Show version and exit if requested by user

      if (option_showVersion) {
        System.out.println("gjdoc " + getGjdocVersion());
        System.exit(0);
      }

      if (option_bootclasspath_specified) {
        reporter.printWarning("-bootclasspath ignored: not supported by"
                              + " gjdoc wrapper script, or no wrapper script in use.");
      }

      // If we have an empty source path list, add the current directory ('.')

      if (option_sourcepath.size() == 0)
        option_sourcepath.add(new File("."));

      //--- We have all information we need to start the doclet at this time
    
      if (null != option_encoding) {
        rootDoc.setSourceEncoding(option_encoding);
      }
      else {
        // be quiet about this for now:
        // reporter.printNotice("No encoding specified, using platform default: " + System.getProperty("file.encoding"));
        rootDoc.setSourceEncoding(System.getProperty("file.encoding"));
      }
      rootDoc.setSourcePath(option_sourcepath);

      //addJavaLangClasses();

      if (!startDoclet(arguments)) {
        return -1;
      }
    }

    return reporter.getErrorCount();
  }

  private void addJavaLangClasses()
    throws IOException
  {
    String resourceName = "/java.lang-classes-" + option_source + ".txt";
    InputStream in = getClass().getResourceAsStream(resourceName);
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line;
    while ((line = reader.readLine()) != null) {
      
      String className = line.trim();
      if (className.length() > 0) {
        ClassDocImpl classDoc =
          new ClassDocImpl(null, new PackageDocImpl("java.lang"),
                           ProgramElementDocImpl.ACCESS_PUBLIC,
                           false, false, null);
        classDoc.setClass(className);
        rootDoc.addClassDoc(classDoc);
      }
    }
  }

  /**
   * Helper class for parsing command line arguments. An instance of this class
   * represents a particular option accepted by gjdoc (e.g. '-sourcepath') along
   * with the number of expected arguments and behavior to parse the arguments.
   */
  private abstract class OptionProcessor
  {

    /**
     * Number of arguments expected by this option.
     */
    private int argCount;

    /**
     * Initializes this instance.
     * 
     * @param argCount
     *          number of arguments
     */
    public OptionProcessor(int argCount)
    {
      this.argCount = argCount;
    }

    /**
     * Overridden by derived classes with behavior to parse the arguments
     * specified with this option.
     * 
     * @param args
     *          command line arguments
     */
    abstract void process(String[] args);
  }

  /**
   * Maps option tags (e.g. '-sourcepath') to OptionProcessor objects.
   * Initialized only once by method initOptions(). FIXME: Rename to
   * 'optionProcessors'.
   */
  private static Map options = null;

  /**
   * Initialize all OptionProcessor objects needed to scan/parse command line
   * options. This cannot be done in a static initializer block because
   * OptionProcessors need access to the Singleton instance of the Main class.
   */
  private void initOptions()
  {

    options = new HashMap();

    //--- Put one OptionProcessor object into the map
    //         for each option recognized.

    options.put("-overview", new OptionProcessor(2)
      {

        void process(String[] args)
        {
          option_overview = args[0];
        }
      });
    options.put("-public", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_coverage = COVERAGE_PUBLIC;
        }
      });
    options.put("-protected", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_coverage = COVERAGE_PROTECTED;
        }
      });
    options.put("-package", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_coverage = COVERAGE_PACKAGE;
        }
      });
    options.put("-private", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_coverage = COVERAGE_PRIVATE;
        }
      });
    OptionProcessor helpProcessor = new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_help = true;
        }
      };

    options.put("-help", helpProcessor);
    options.put("--help", helpProcessor);
    options.put("-doclet", new OptionProcessor(2)
        {

          void process(String[] args)
          {
            option_doclet = args[0];
          }
        });
    options.put("-docletpath", new OptionProcessor(2)
        {

          void process(String[] args)
          {
            option_docletpath = args[0];
          }
        });
    options.put("-nowarn", new OptionProcessor(1)
        {

          void process(String[] args)
          {
            option_nowarn = true;
          }
        });
    options.put("-source", new OptionProcessor(2)
        {

          void process(String[] args)
          {
            option_source = args[0];
            if (!"1.2".equals(option_source) 
                && !"1.3".equals(option_source)
                && !"1.4".equals(option_source)) {

              throw new RuntimeException("Only he following values are currently"
                                         + " supported for option -source: 1.2, 1.3, 1.4.");
            }
          }
        });
    OptionProcessor sourcePathProcessor = new OptionProcessor(2) {
        void process(String[] args)
        {
          Debug.log(1, "-sourcepath is '" + args[0] + "'");
          for (StringTokenizer st = new StringTokenizer(args[0],
              File.pathSeparator); st.hasMoreTokens();)
          {
            String path = st.nextToken();
            File file = new File(path);
            if (!(file.exists()))
            {
              throw new RuntimeException("The source path " + path
                  + " does not exist.");
            }
            option_sourcepath.add(file);
          }
        }
      };
    options.put("-s", sourcePathProcessor);
    options.put("-sourcepath", sourcePathProcessor);
    options.put("-subpackages", new OptionProcessor(2)
      {
        void process(String[] args)
        {
          StringTokenizer st = new StringTokenizer(args[0], ":"); 
          while (st.hasMoreTokens()) {
            String packageName = st.nextToken();

            if (packageName.startsWith(".")
                || packageName.endsWith(".")
                || packageName.indexOf("..") > 0
                || !checkCharSet(packageName,
                                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.")) {
              throw new RuntimeException("Illegal package name '"
                                         + packageName + "'");
            }
            option_subpackages.add(packageName);
          }
        }
      });
    options.put("-exclude", new OptionProcessor(2)
      {
        void process(String[] args)
        {
          StringTokenizer st = new StringTokenizer(args[0], ":"); 
          while (st.hasMoreTokens()) {
            String packageName = st.nextToken();

            if (packageName.startsWith(".")
                || packageName.endsWith(".")
                || packageName.indexOf("..") > 0
                || !checkCharSet(packageName,
                                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.")) {
              throw new RuntimeException("Illegal package name '"
                                         + packageName + "'");
            }
            option_exclude.add(packageName);
          }
        }
      });
    // TODO include other options here
    options.put("-verbose", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          option_verbose = true;
          System.err.println("WARNING: Unsupported option -verbose ignored");
        }
      });
    options.put("-quiet", new OptionProcessor(1)
      {

        void process(String[] args)
        {
          reporter.setQuiet(true);
        }
      });
    options.put("-locale", new OptionProcessor(2)
      {

        void process(String[] args)
        {
          String localeName = args[0];
          String language = null;
          String country = null;
          String variant = null;
          StringTokenizer st = new StringTokenizer(localeName, "_");
          if (st.hasMoreTokens()) {
            language = st.nextToken();
          }
          if (st.hasMoreTokens()) {
            country = st.nextToken();
          }
          if (st.hasMoreTokens()) {
            variant = st.nextToken();
          }
          if (variant != null) {
            option_locale = new Locale(language, country, variant);
          }
          else if (country != null) {
             option_locale = new Locale(language, country);
          }
          else if (language != null) {
             option_locale = new Locale(language);
          }
          else {
              throw new RuntimeException("Illegal locale specification '"
                                         + localeName + "'");
          }
        }
      });
    options.put("-encoding", new OptionProcessor(2)
      {

        void process(String[] args)
        {
          option_encoding = args[0];
        }
      });
    options.put("-breakiterator", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_breakiterator = true;
        }
      });
    options.put("-licensetext", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_licensetext = true;
        }
      });
    options.put("-overview", new OptionProcessor(2)
      {
        void process(String[] args)
        {
          try {
            getRootDoc().setRawCommentText(RootDocImpl.readHtmlBody(new File(args[0])));
          }
          catch (IOException e) { 
            throw new RuntimeException("Cannot read file specified in option -overview: " + e.getMessage());
          }
        }
      });
    options.put("-classpath", new OptionProcessor(2)
      {
        void process(String[] args)
        {
          reporter.printWarning("-classpath option could not be passed to the VM.  Faking it with ");
          reporter.printWarning("    System.setProperty(\"java.class.path\", \"" + args[0] + "\");");
          System.setProperty("java.class.path", args[0]);
        }
      });
    options.put("--version", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_showVersion = true;
        }
      });
    options.put("-bootclasspath", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_bootclasspath_specified = true;
        }
      });
    options.put("-all", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_all = true;
        }
      });
    options.put("-reflection", new OptionProcessor(1)
      {
        void process(String[] args)
        {
          option_reflection = true;
        }
      });
  }

  /**
   * Determine how many arguments the given option requires.
   * 
   * @param option
   *          The name of the option without leading dash.
   */
  private static int optionLength(String option)
  {

    OptionProcessor op = (OptionProcessor) options.get(option.toLowerCase());
    if (op != null)
      return op.argCount;
    else
      return 0;
  }

  /**
   * Process all given options. Assumes that the options have been validated
   * before.
   * 
   * @param optionArr
   *          Each element is a series of Strings where [0] is the name of the
   *          option and [1..n] are the arguments to the option.
   */
  private void readOptions(String[][] optionArr)
  {

    //--- For each option, find the appropriate OptionProcessor
    //        and call its process() method

    for (int i = 0; i < optionArr.length; ++i)
    {
      String[] opt = optionArr[i];
      String[] args = new String[opt.length - 1];
      System.arraycopy(opt, 1, args, 0, opt.length - 1);
      OptionProcessor op = (OptionProcessor) options.get(opt[0].toLowerCase());
      op.process(args);
    }
  }

  /**
   * Print command line usage.
   */
  private static void usage()
  {
    System.out
        .print("\n"
            + "USAGE: gjdoc [options] [packagenames] "
            + "[sourcefiles] [@files]\n\n"
            + "  --version                Show version information and exit\n"
            + "  -all                     Process all source files found in the source path\n"
            + "  -overview <file>         Read overview documentation from HTML file\n"
            + "  -public                  Include only public classes and members\n"
            + "  -protected               Include protected and public classes and members\n"
            + "                           This is the default\n"
            + "  -package                 Include package/protected/public classes and members\n"
            + "  -private                 Include all classes and members\n"
            + "  -help, --help            Show this information\n"
            + "  -doclet <class>          Doclet class to use for generating output\n"
            + "  -docletpath <classpath>  Specifies the search path for the doclet and\n"
            + "                           dependencies\n"
            + "  -source <release>        Provide source compatibility with specified\n"
            + "                           release (1.4 to handle assertion)\n"
            + "  -sourcepath <pathlist>   Where to look for source files\n"
            + "  -s <pathlist>            Alias for -sourcepath\n"
            + "  -subpackages <spkglist>  List of subpackages to recursively load\n"
            + "  -exclude <pkglist>       List of packages to exclude\n"
            + "  -verbose                 Output messages about what Gjdoc is doing [ignored]\n"
            + "  -quiet                   Do not print non-error and non-warning messages\n"
            + "  -locale <name>           Locale to be used, e.g. en_US or en_US_WIN\n"
            + "  -encoding <name>         Source file encoding name\n"
            + "  -breakiterator           Compute first sentence with BreakIterator\n"
            + "  -classpath <pathlist>    Set the path used for loading auxilliary classes\n"
            + "\n"
            + "Standard doclet options:\n"
            + "  -d                      Set target directory\n"
            + "  -use                    Includes the 'Use' page for each documented class\n"
            + "                          and package\n"
            + "  -version                Includes the '@version' tag\n"
            + "  -author                 Includes the '@author' tag\n"
            + "  -splitindex             Splits the index file into multiple files\n"
            + "  -windowtitle <text>     Browser window title\n"
            + "  -doctitle <text>        Title near the top of the overview summary file\n"
            + "                          (HTML allowed)\n"
            + "  -title <text>           Title for this set of API documentation\n"
            + "                          (deprecated, -doctitle should be used instead)\n"
            + "  -header <text>          Text to include in the top navigation bar\n"
            + "                          (HTML allowed)\n"
            + "  -footer <text>          Text to include in the bottom navigation bar\n"
            + "                          (HTML allowed)\n"
            + "  -bottom <text>          Text to include at the bottom of each output file\n"
            + "                          (HTML allowed)\n"
            + "  -link <extdoc URL>      Link to external generated documentation at URL\n"
            + "  -linkoffline <extdoc URL> <packagelistLoc>\n"
            + "                          Link to external generated documentation for\n"
            + "                          the specified package-list\n"
            + "  -linksource             Creates an HTML version of each source file\n"
            + "  -group <groupheading> <packagepattern:packagepattern:...>\n"
            + "                          Separates packages on the overview page into groups\n"
            + "  -nodeprecated           Prevents the generation of any deprecated API\n"
            + "  -nodeprecatedlist       Prevents the generation of the file containing\n"
            + "                          the list of deprecated APIs and the link to the\n"
            + "                          navigation bar to that page\n"
            + "  -nosince                Omit the '@since' tag\n"
            + "  -notree                 Do not generate the class/interface hierarchy page\n"
            + "  -noindex                Do not generate the index file\n"
            + "  -nohelp                 Do not generate the help link\n"
            + "  -nonavbar               Do not generate the navbar, header and footer\n"
            + "  -helpfile <filen>       Path to an alternate help file\n"
            + "  -stylesheetfile <file>  Path to an alternate CSS stylesheet\n"
            + "  -addstylesheet <file>   Path to an additional CSS stylesheet\n"
            + "  -serialwarn             Complain about missing '@serial' tags [ignored]\n"
            + "  -charset <IANACharset>  Specifies the HTML charset\n"
            + "  -docencoding <IANACharset>\n"
            + "                          Specifies the encoding of the generated HTML files\n"
            + "  -tag <tagname>:Xaoptcmf:\"<taghead>\"\n"
            + "                          Enables gjdoc to interpret a custom tag\n"
            + "  -taglet                 Adds a Taglet class to the map of taglets\n"
            + "  -tagletpath             Sets the CLASSPATH to load subsequent Taglets from\n"
            + "  -docfilessubdirs        Enables deep copy of 'doc-files' directories\n"
            + "  -excludedocfilessubdir <name1:name2:...>\n"
            + "                          Excludes 'doc-files' subdirectories with a give name\n"
            + "  -noqualifier all|<packagename1:packagename2:...>\n"
            + "                          Do never fully qualify given package names\n"
            + "  -nocomment              Suppress the entire comment body including the main\n"
            + "                          description and all tags, only generate declarations\n"
            + "\n"
            + "Gjdoc extension options:\n"
            + "  -reflection             Use reflection for resolving unqualified class names\n"
            + "  -licensetext            Include license text from source files\n"
            + "  -validhtml              Use valid HTML/XML names (breaks compatibility)\n"
            + "  -baseurl <url>          Hardwire the given base URL into generated pages\n"
               /**
            + "  -genhtml                Generate HTML code instead of XML code. This is the\n"
            + "                          default.\n"
            + "  -geninfo                Generate Info code instead of XML code.\n"
            + "  -xslsheet <file>        If specified, XML files will be written to a\n"
            + "                          temporary directory and transformed using the\n"
            + "                          given XSL sheet. The result of the transformation\n"
            + "                          is written to the output directory. Not required if\n"
            + "                          -genhtml or -geninfo has been specified.\n"
            + "  -xmlonly                Generate XML code only, do not generate HTML code.\n"
            + "  -bottomnote             HTML code to include at the bottom of each page.\n"
            + "  -nofixhtml              If not specified, heurestics will be applied to\n"
            + "                          fix broken HTML code in comments.\n"
            + "  -nohtmlwarn             Do not emit warnings when encountering broken HTML\n"
            + "                          code.\n"
            + "  -noemailwarn            Do not emit warnings when encountering strings like\n"
            + "                          <abc@foo.com>.\n"
            + "  -indentstep <n>         How many spaces to indent each tag level in\n"
            + "                          generated XML code.\n"
            + "  -xsltdriver <class>     Specifies the XSLT driver to use for transformation.\n"
            + "                          By default, xsltproc is used.\n"
            + "  -postprocess <class>    XmlDoclet postprocessor class to apply after XSL\n"
            + "                          transformation.\n"
            + "  -compress               Generated info pages will be Zip-compressed.\n"
            + "  -workpath               Specify a temporary directory to use.\n"
            + "  -authormail <type>      Specify handling of mail addresses in @author tags.\n"
            + "     no-replace             do not replace mail addresses (default).\n"
            + "     mailto-name            replace by <a>Real Name</a>.\n"
            + "     name-mailto-address    replace by Real Name (<a>abc@foo.com</a>).\n"
            + "     name-mangled-address   replace by Real Name (<a>abc AT foo DOT com</a>).\n"
               **/
            );
  }

  /**
   * The root of the gjdoc tool.
   * 
   * @return all the options of the gjdoc application.
   */
  public static RootDocImpl getRootDoc()
  {
    return rootDoc;
  }

  /**
   * Get the gjdoc singleton.
   * 
   * @return the gjdoc instance.
   */
  public static Main getInstance()
  {
    return instance;
  }

  /**
   * Is this access level covered?
   * 
   * @param accessLevel
   *          the access level we want to know if it is covered.
   * @return true if the access level is covered.
   */
  public boolean includeAccessLevel(int accessLevel)
  {
    return coverageTemplates[option_coverage][accessLevel];
  }

  /**
   * Is the doclet running?
   * 
   * @return true if it's running
   */
  public boolean isDocletRunning()
  {
    return docletRunning;
  }

  /**
   * Check the charset. Check that all the characters of the string 'toCheck'
   * and query if they exist in the 'charSet'. The order does not matter. The
   * number of times a character is in the variable does not matter.
   * 
   * @param toCheck
   *          the charset to check.
   * @param charSet
   *          the reference charset
   * @return true if they match.
   */
  public static boolean checkCharSet(String toCheck, String charSet)
  {
    for (int i = 0; i < toCheck.length(); ++i)
    {
      if (charSet.indexOf(toCheck.charAt(i)) < 0)
        return false;
    }
    return true;
  }

  /**
   * Makes the RootDoc eligible for the GC.
   */
  public static void releaseRootDoc()
  {
    rootDoc.flush();
  }

  /**
   * Return whether the -breakiterator option has been specified.
   */
  public boolean isUseBreakIterator()
  {
    return this.option_breakiterator
      || !getLocale().getLanguage().equals(Locale.ENGLISH.getLanguage());
  }

  /**
   * Return whether boilerplate license text should be copied.
   */
  public boolean isCopyLicenseText()
  {
    return this.option_licensetext;
  }

  /**
   *  Return the locale specified using the -locale option or the
   *  default locale;
   */
  public Locale getLocale()
  {
    return this.option_locale;
  }

  /**
   *  Return the collator to use based on the specified -locale
   *  option. If no collator can be found for the given locale, a
   *  warning is emitted and the default collator is used instead.
   */
  public Collator getCollator()
  {
    if (null == this.collator) {
      Locale locale = getLocale();
      this.collator = Collator.getInstance(locale);
      Locale defaultLocale = Locale.getDefault();
      if (null == this.collator
          && !defaultLocale.equals(locale)) {
        this.collator = Collator.getInstance(defaultLocale);
        if (null != this.collator) {
          reporter.printWarning("No collator found for locale " 
                                + locale.getDisplayName() 
                                + "; using collator for default locale " 
                                + defaultLocale.getDisplayName()
                                + ".");
        }
        else {
          this.collator = Collator.getInstance();
          reporter.printWarning("No collator found for specified locale " 
                                + locale.getDisplayName() 
                                + " or default locale " 
                                + defaultLocale.getDisplayName()
                                + ": using default collator.");
        }
      }
      if (null == this.collator) {
        this.collator = Collator.getInstance();
        reporter.printWarning("No collator found for locale " 
                              + locale.getDisplayName() 
                              + ": using default collator.");
      }
    }
    return this.collator;
  }

  public boolean isCacheRawComments()
  {
    return true;
  }

  public String getGjdocVersion()
  {
    if (null == gjdocVersion) {
      try {
        Properties versionProperties = new Properties();
        versionProperties.load(getClass().getResourceAsStream("version.properties"));
        gjdocVersion = versionProperties.getProperty("gjdoc.version");
      }
      catch (IOException ignore) {
      }
      if (null == gjdocVersion) {
        gjdocVersion = "unknown";
      }
    }
    return gjdocVersion;
  }

  public boolean isReflectionEnabled()
  {
    return this.option_reflection;
  }
}
