8003257: refactor javadoc tool option handling
authorjjg
Thu, 15 Nov 2012 14:41:31 -0800
changeset 14543 43edeaf6d0a9
parent 14542 7062120649c2
child 14544 d71d992cb905
8003257: refactor javadoc tool option handling Reviewed-by: darcy
langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java
langtools/src/share/classes/com/sun/tools/javadoc/DocLocale.java
langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java
langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java
langtools/src/share/classes/com/sun/tools/javadoc/Messager.java
langtools/src/share/classes/com/sun/tools/javadoc/Start.java
langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Thu Nov 15 14:41:31 2012 -0800
@@ -211,8 +211,8 @@
     public void setLocale(String localeName) {
         // create locale specifics
         doclocale = new DocLocale(this, localeName, breakiterator);
-        // reset Messager if locale has changed.
-        messager.reset();
+        // update Messager if locale has changed.
+        messager.setLocale(doclocale.locale);
     }
 
     /** Check whether this member should be documented. */
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocLocale.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocLocale.java	Thu Nov 15 14:41:31 2012 -0800
@@ -49,7 +49,7 @@
     final String localeName;
 
     /**
-     * The locale to be used. If user doesen't provide this,
+     * The locale to be used. If user doesn't provide this,
      * then set it to default locale value.
      */
     final Locale locale;
@@ -98,7 +98,7 @@
         if (locale == null) {
             docenv.exit();
         } else {
-            Locale.setDefault(locale);
+            Locale.setDefault(locale); // NOTE: updating global state
         }
         collator = Collator.getInstance(locale);
         sentenceBreaker = BreakIterator.getSentenceInstance(locale);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Thu Nov 15 14:41:31 2012 -0800
@@ -95,7 +95,7 @@
         try {
             dc = appClassLoader.loadClass(docletClassName);
         } catch (ClassNotFoundException exc) {
-            messager.error(null, "main.doclet_class_not_found", docletClassName);
+            messager.error(Messager.NOPOS, "main.doclet_class_not_found", docletClassName);
             messager.exit();
         }
         docletClass = dc;
@@ -168,7 +168,7 @@
         if (retVal instanceof Boolean) {
             return ((Boolean)retVal).booleanValue();
         } else {
-            messager.error(null, "main.must_return_boolean",
+            messager.error(Messager.NOPOS, "main.must_return_boolean",
                            docletClassName, methodName);
             return false;
         }
@@ -192,7 +192,7 @@
         if (retVal instanceof Integer) {
             return ((Integer)retVal).intValue();
         } else {
-            messager.error(null, "main.must_return_int",
+            messager.error(Messager.NOPOS, "main.must_return_int",
                            docletClassName, methodName);
             return -1;
         }
@@ -217,7 +217,7 @@
         if (retVal instanceof Boolean) {
             return ((Boolean)retVal).booleanValue();
         } else {
-            messager.error(null, "main.must_return_boolean",
+            messager.error(Messager.NOPOS, "main.must_return_boolean",
                            docletClassName, methodName);
             return false;
         }
@@ -241,7 +241,7 @@
             if (retVal instanceof LanguageVersion) {
                 return (LanguageVersion)retVal;
             } else {
-                messager.error(null, "main.must_return_languageversion",
+                messager.error(Messager.NOPOS, "main.must_return_languageversion",
                                docletClassName, methodName);
                 return JAVA_1_1;
             }
@@ -261,19 +261,19 @@
                 meth = docletClass.getMethod(methodName, paramTypes);
             } catch (NoSuchMethodException exc) {
                 if (returnValueIfNonExistent == null) {
-                    messager.error(null, "main.doclet_method_not_found",
+                    messager.error(Messager.NOPOS, "main.doclet_method_not_found",
                                    docletClassName, methodName);
                     throw new DocletInvokeException();
                 } else {
                     return returnValueIfNonExistent;
                 }
             } catch (SecurityException exc) {
-                messager.error(null, "main.doclet_method_not_accessible",
+                messager.error(Messager.NOPOS, "main.doclet_method_not_accessible",
                                docletClassName, methodName);
                 throw new DocletInvokeException();
             }
             if (!Modifier.isStatic(meth.getModifiers())) {
-                messager.error(null, "main.doclet_method_must_be_static",
+                messager.error(Messager.NOPOS, "main.doclet_method_must_be_static",
                                docletClassName, methodName);
                 throw new DocletInvokeException();
             }
@@ -283,23 +283,23 @@
                 Thread.currentThread().setContextClassLoader(appClassLoader);
                 return meth.invoke(null , params);
             } catch (IllegalArgumentException exc) {
-                messager.error(null, "main.internal_error_exception_thrown",
+                messager.error(Messager.NOPOS, "main.internal_error_exception_thrown",
                                docletClassName, methodName, exc.toString());
                 throw new DocletInvokeException();
             } catch (IllegalAccessException exc) {
-                messager.error(null, "main.doclet_method_not_accessible",
+                messager.error(Messager.NOPOS, "main.doclet_method_not_accessible",
                                docletClassName, methodName);
                 throw new DocletInvokeException();
             } catch (NullPointerException exc) {
-                messager.error(null, "main.internal_error_exception_thrown",
+                messager.error(Messager.NOPOS, "main.internal_error_exception_thrown",
                                docletClassName, methodName, exc.toString());
                 throw new DocletInvokeException();
             } catch (InvocationTargetException exc) {
                 Throwable err = exc.getTargetException();
                 if (err instanceof java.lang.OutOfMemoryError) {
-                    messager.error(null, "main.out.of.memory");
+                    messager.error(Messager.NOPOS, "main.out.of.memory");
                 } else {
-                messager.error(null, "main.exception_thrown",
+                messager.error(Messager.NOPOS, "main.exception_thrown",
                                docletClassName, methodName, exc.toString());
                     exc.getTargetException().printStackTrace();
                 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu Nov 15 14:41:31 2012 -0800
@@ -38,7 +38,6 @@
 import javax.tools.StandardLocation;
 
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -65,11 +64,9 @@
 public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
     DocEnv docenv;
 
-    final Context context;
     final Messager messager;
-    final JavadocClassReader reader;
-    final JavadocEnter enter;
-    final Annotate annotate;
+    final JavadocClassReader javadocReader;
+    final JavadocEnter javadocEnter;
 
     /**
      * Construct a new JavaCompiler processor, using appropriately
@@ -77,11 +74,9 @@
      */
     protected JavadocTool(Context context) {
         super(context);
-        this.context = context;
         messager = Messager.instance0(context);
-        reader = JavadocClassReader.instance0(context);
-        enter = JavadocEnter.instance0(context);
-        annotate = Annotate.instance(context);
+        javadocReader = JavadocClassReader.instance0(context);
+        javadocEnter = JavadocEnter.instance0(context);
     }
 
     /**
@@ -138,7 +133,7 @@
         docenv.setEncoding(encoding);
         docenv.docClasses = docClasses;
         docenv.legacyDoclet = legacyDoclet;
-        reader.sourceCompleter = docClasses ? null : this;
+        javadocReader.sourceCompleter = docClasses ? null : this;
 
         ListBuffer<String> names = new ListBuffer<String>();
         ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
@@ -156,7 +151,7 @@
                 } else if (isValidPackageName(name)) {
                     names = names.append(name);
                 } else if (name.endsWith(".java")) {
-                    docenv.error(null, "main.file_not_found", name);
+                        docenv.error(null, "main.file_not_found", name);
                 } else {
                     docenv.error(null, "main.illegal_package_name", name);
                 }
@@ -179,7 +174,7 @@
 
                 // Enter symbols for all files
                 docenv.notice("main.Building_tree");
-                enter.main(classTrees.toList().appendList(packTrees.toList()));
+                javadocEnter.main(classTrees.toList().appendList(packTrees.toList()));
             }
         } catch (Abort ex) {}
 
@@ -240,7 +235,7 @@
         }
 
         if (!hasFiles) {
-            messager.warning(null, "main.no_source_files_for_package",
+            messager.warning(Messager.NOPOS, "main.no_source_files_for_package",
                     name.replace(File.separatorChar, '.'));
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java	Thu Nov 15 14:41:31 2012 -0800
@@ -25,13 +25,15 @@
 
 package com.sun.tools.javadoc;
 
-import java.io.PrintWriter;  // Access to 'javac' output streams
+import java.io.PrintWriter;
 import java.text.MessageFormat;
-import java.util.MissingResourceException;
+import java.util.Locale;
 import java.util.ResourceBundle;
 
 import com.sun.javadoc.*;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JavacMessages;
 import com.sun.tools.javac.util.Log;
 
 /**
@@ -51,6 +53,7 @@
  * @author Neal Gafter (rewrite)
  */
 public class Messager extends Log implements DocErrorReporter {
+    public static final SourcePosition NOPOS = null;
 
     /** Get the current messager, which is also the compiler log. */
     public static Messager instance0(Context context) {
@@ -91,7 +94,9 @@
 
     final String programName;
 
-    private ResourceBundle messageRB = null;
+    private Locale locale;
+    private final JavacMessages messages;
+    private final JCDiagnostic.Factory javadocDiags;
 
     /** The default writer for diagnostics
      */
@@ -121,6 +126,9 @@
                        PrintWriter warnWriter,
                        PrintWriter noticeWriter) {
         super(context, errWriter, warnWriter, noticeWriter);
+        messages = JavacMessages.instance(context);
+        messages.add("com.sun.tools.javadoc.resources.javadoc");
+        javadocDiags = new JCDiagnostic.Factory(messages, "javadoc");
         this.programName = programName;
     }
 
@@ -134,94 +142,18 @@
         return Integer.MAX_VALUE;
     }
 
-    /**
-     * Reset resource bundle, eg. locale has changed.
-     */
-    public void reset() {
-        messageRB = null;
-    }
-
-    /**
-     * Get string from ResourceBundle, initialize ResourceBundle
-     * if needed.
-     */
-    private String getString(String key) {
-        if (messageRB == null) {
-            try {
-                messageRB = ResourceBundle.getBundle(
-                          "com.sun.tools.javadoc.resources.javadoc");
-            } catch (MissingResourceException e) {
-                throw new Error("Fatal: Resource for javadoc is missing");
-            }
-        }
-        return messageRB.getString(key);
-    }
-
-    /**
-     * get and format message string from resource
-     *
-     * @param key selects message from resource
-     */
-    String getText(String key) {
-        return getText(key, (String)null);
+    public void setLocale(Locale locale) {
+        this.locale = locale;
     }
 
     /**
      * get and format message string from resource
      *
      * @param key selects message from resource
-     * @param a1 first argument
-     */
-    String getText(String key, String a1) {
-        return getText(key, a1, null);
-    }
-
-    /**
-     * get and format message string from resource
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     */
-    String getText(String key, String a1, String a2) {
-        return getText(key, a1, a2, null);
-    }
-
-    /**
-     * get and format message string from resource
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
+     * @param args arguments for the message
      */
-    String getText(String key, String a1, String a2, String a3) {
-        return getText(key, a1, a2, a3, null);
-    }
-
-    /**
-     * get and format message string from resource
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
-     * @param a4 fourth argument
-     */
-    String getText(String key, String a1, String a2, String a3,
-                          String a4) {
-        try {
-            String message = getString(key);
-            String[] args = new String[4];
-            args[0] = a1;
-            args[1] = a2;
-            args[2] = a3;
-            args[3] = a4;
-            return MessageFormat.format(message, (Object[])args);
-        } catch (MissingResourceException e) {
-            return "********** Resource for javadoc is broken. There is no " +
-                key + " key in resource.";
-        }
+    String getText(String key, Object... args) {
+        return messages.getLocalizedString(locale, key, args);
     }
 
     /**
@@ -307,41 +239,8 @@
      *
      * @param key selects message from resource
      */
-    public void error(SourcePosition pos, String key) {
-        printError(pos, getText(key));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     */
-    public void error(SourcePosition pos, String key, String a1) {
-        printError(pos, getText(key, a1));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     */
-    public void error(SourcePosition pos, String key, String a1, String a2) {
-        printError(pos, getText(key, a1, a2));
-    }
-
-    /**
-     * Print error message, increment error count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
-     */
-    public void error(SourcePosition pos, String key, String a1, String a2, String a3) {
-        printError(pos, getText(key, a1, a2, a3));
+    public void error(SourcePosition pos, String key, Object... args) {
+        printError(pos, getText(key, args));
     }
 
     /**
@@ -349,54 +248,8 @@
      *
      * @param key selects message from resource
      */
-    public void warning(SourcePosition pos, String key) {
-        printWarning(pos, getText(key));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     */
-    public void warning(SourcePosition pos, String key, String a1) {
-        printWarning(pos, getText(key, a1));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     */
-    public void warning(SourcePosition pos, String key, String a1, String a2) {
-        printWarning(pos, getText(key, a1, a2));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
-     */
-    public void warning(SourcePosition pos, String key, String a1, String a2, String a3) {
-        printWarning(pos, getText(key, a1, a2, a3));
-    }
-
-    /**
-     * Print warning message, increment warning count.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
-     */
-    public void warning(SourcePosition pos, String key, String a1, String a2, String a3,
-                        String a4) {
-        printWarning(pos, getText(key, a1, a2, a3, a4));
+    public void warning(SourcePosition pos, String key, Object... args) {
+        printWarning(pos, getText(key, args));
     }
 
     /**
@@ -404,41 +257,8 @@
      *
      * @param key selects message from resource
      */
-    public void notice(String key) {
-        printNotice(getText(key));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     */
-    public void notice(String key, String a1) {
-        printNotice(getText(key, a1));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     */
-    public void notice(String key, String a1, String a2) {
-        printNotice(getText(key, a1, a2));
-    }
-
-    /**
-     * Print a message.
-     *
-     * @param key selects message from resource
-     * @param a1 first argument
-     * @param a2 second argument
-     * @param a3 third argument
-     */
-    public void notice(String key, String a1, String a2, String a3) {
-        printNotice(getText(key, a1, a2, a3));
+    public void notice(String key, Object... args) {
+        printNotice(getText(key, args));
     }
 
     /**
@@ -475,5 +295,4 @@
     public void exit() {
         throw new ExitJavadoc();
     }
-
 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java	Thu Nov 15 09:18:36 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java	Thu Nov 15 14:41:31 2012 -0800
@@ -29,7 +29,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.StringTokenizer;
 
 import com.sun.javadoc.*;
 import com.sun.tools.javac.main.CommandLine;
@@ -53,7 +52,7 @@
  * @author Robert Field
  * @author Neal Gafter (rewrite)
  */
-class Start {
+public class Start extends ToolOption.Helper {
     /** Context for this invocation. */
     private final Context context;
 
@@ -65,25 +64,12 @@
     private static final String standardDocletClassName =
         "com.sun.tools.doclets.standard.Standard";
 
-    private ListBuffer<String[]> options = new ListBuffer<String[]>();
-
-    private ModifierFilter showAccess = null;
-
     private long defaultFilter = PUBLIC | PROTECTED;
 
     private final Messager messager;
 
-    String docLocale = "";
-
-    boolean breakiterator = false;
-    boolean quiet = false;
-    String encoding = null;
-
     private DocletInvoker docletInvoker;
 
-    /* Treat warnings as errors. */
-    private boolean rejectWarnings = false;
-
     Start(String programName,
           PrintWriter errWriter,
           PrintWriter warnWriter,
@@ -132,23 +118,58 @@
         this(javadocName);
     }
 
+    public Start(Context context) {
+        context.getClass(); // null check
+        this.context = context;
+        defaultDocletClassName = standardDocletClassName;
+        docletParentClassLoader = null;
+
+        Log log = context.get(Log.logKey);
+        if (log instanceof Messager)
+            messager = (Messager) log;
+        else {
+            PrintWriter out = context.get(Log.outKey);
+            messager = (out == null) ? new Messager(context, javadocName)
+                    : new Messager(context, javadocName, out, out, out);
+        }
+    }
+
     /**
      * Usage
      */
-    private void usage() {
+    @Override
+    void usage() {
+        usage(true);
+    }
+
+
+    /**
+     * Usage
+     */
+    private void usage(boolean exit) {
+        // RFE: it would be better to replace the following with code to
+        // write a header, then help for each option, then a footer.
         messager.notice("main.usage");
 
         // let doclet print usage information (does nothing on error)
         if (docletInvoker != null) {
             docletInvoker.optionLength("-help");
         }
+
+        if (exit) exit();
+    }
+
+    @Override
+    void Xusage() {
+        Xusage(true);
     }
 
     /**
      * Usage
      */
-    private void Xusage() {
+    private void Xusage(boolean exit) {
         messager.notice("main.Xusage");
+        if (exit) exit();
     }
 
     /**
@@ -167,18 +188,18 @@
 
         try {
             failed = !parseAndExecute(argv);
-        } catch(Messager.ExitJavadoc exc) {
+        } catch (Messager.ExitJavadoc exc) {
             // ignore, we just exit this way
         } catch (OutOfMemoryError ee) {
-            messager.error(null, "main.out.of.memory");
+            messager.error(Messager.NOPOS, "main.out.of.memory");
             failed = true;
         } catch (Error ee) {
             ee.printStackTrace(System.err);
-            messager.error(null, "main.fatal.error");
+            messager.error(Messager.NOPOS, "main.fatal.error");
             failed = true;
         } catch (Exception ee) {
             ee.printStackTrace(System.err);
-            messager.error(null, "main.fatal.exception");
+            messager.error(Messager.NOPOS, "main.fatal.exception");
             failed = true;
         } finally {
             messager.exitNotice();
@@ -189,15 +210,6 @@
         return failed ? 1 : 0;
     }
 
-    private void addToList(ListBuffer<String> list, String str){
-        StringTokenizer st = new StringTokenizer(str, ":");
-        String current;
-        while(st.hasMoreTokens()){
-            current = st.nextToken();
-            list.append(current);
-        }
-    }
-
     /**
      * Main program - internal
      */
@@ -210,7 +222,7 @@
         try {
             argv = CommandLine.parse(argv);
         } catch (FileNotFoundException e) {
-            messager.error(null, "main.cant.read", e.getMessage());
+            messager.error(Messager.NOPOS, "main.cant.read", e.getMessage());
             exit();
         } catch (IOException e) {
             e.printStackTrace(System.err);
@@ -218,116 +230,29 @@
         }
 
         setDocletInvoker(argv);
-        ListBuffer<String> subPackages = new ListBuffer<String>();
-        ListBuffer<String> excludedPackages = new ListBuffer<String>();
 
-        Options compOpts = Options.instance(context);
-        boolean docClasses = false;
+        compOpts = Options.instance(context);
 
         // Parse arguments
         for (int i = 0 ; i < argv.length ; i++) {
             String arg = argv[i];
-            if (arg.equals("-subpackages")) {
-                oneArg(argv, i++);
-                addToList(subPackages, argv[i]);
-            } else if (arg.equals("-exclude")){
-                oneArg(argv, i++);
-                addToList(excludedPackages, argv[i]);
-            } else if (arg.equals("-verbose")) {
-                setOption(arg);
-                compOpts.put("-verbose", "");
-            } else if (arg.equals("-encoding")) {
-                oneArg(argv, i++);
-                encoding = argv[i];
-                compOpts.put("-encoding", argv[i]);
-            } else if (arg.equals("-breakiterator")) {
-                breakiterator = true;
-                setOption("-breakiterator");
-            } else if (arg.equals("-quiet")) {
-                quiet = true;
-                setOption("-quiet");
-            } else if (arg.equals("-help")) {
-                usage();
-                exit();
-            } else if (arg.equals("-Xclasses")) {
-                setOption(arg);
-                docClasses = true;
-            } else if (arg.equals("-Xwerror")) {
-                setOption(arg);
-                rejectWarnings = true;
-            } else if (arg.equals("-private")) {
-                setOption(arg);
-                setFilter(ModifierFilter.ALL_ACCESS);
-            } else if (arg.equals("-package")) {
-                setOption(arg);
-                setFilter(PUBLIC | PROTECTED |
-                          ModifierFilter.PACKAGE );
-            } else if (arg.equals("-protected")) {
-                setOption(arg);
-                setFilter(PUBLIC | PROTECTED );
-            } else if (arg.equals("-public")) {
-                setOption(arg);
-                setFilter(PUBLIC);
-            } else if (arg.equals("-source")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-source") != null) {
-                    usageError("main.option.already.seen", arg);
+
+            ToolOption o = ToolOption.get(arg);
+            if (o != null) {
+                // hack: this restriction should be removed
+                if (o == ToolOption.LOCALE && i > 0)
+                    usageError("main.locale_first");
+
+                if (o.hasArg) {
+                    oneArg(argv, i++);
+                    o.process(this, argv[i]);
+                } else {
+                    setOption(arg);
+                    o.process(this);
                 }
-                compOpts.put("-source", argv[i]);
-            } else if (arg.equals("-prompt")) {
-                compOpts.put("-prompt", "-prompt");
-                messager.promptOnError = true;
-            } else if (arg.equals("-sourcepath")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-sourcepath") != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put("-sourcepath", argv[i]);
-            } else if (arg.equals("-classpath")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-classpath") != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put("-classpath", argv[i]);
-            } else if (arg.equals("-sysclasspath")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-bootclasspath") != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put("-bootclasspath", argv[i]);
-            } else if (arg.equals("-bootclasspath")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-bootclasspath") != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put("-bootclasspath", argv[i]);
-            } else if (arg.equals("-extdirs")) {
-                oneArg(argv, i++);
-                if (compOpts.get("-extdirs") != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put("-extdirs", argv[i]);
-            } else if (arg.equals("-overview")) {
-                oneArg(argv, i++);
-            } else if (arg.equals("-doclet")) {
-                i++;  // handled in setDocletInvoker
-            } else if (arg.equals("-docletpath")) {
-                i++;  // handled in setDocletInvoker
-            } else if (arg.equals("-locale")) {
-                if (i != 0)
-                    usageError("main.locale_first");
-                oneArg(argv, i++);
-                docLocale = argv[i];
-            } else if (arg.equals("-Xmaxerrs") || arg.equals("-Xmaxwarns")) {
-                oneArg(argv, i++);
-                if (compOpts.get(arg) != null) {
-                    usageError("main.option.already.seen", arg);
-                }
-                compOpts.put(arg, argv[i]);
-            } else if (arg.equals("-X")) {
-                Xusage();
-                exit();
+
             } else if (arg.startsWith("-XD")) {
+                // hidden javac options
                 String s = arg.substring("-XD".length());
                 int eq = s.indexOf('=');
                 String key = (eq < 0) ? s : s.substring(0, eq);
@@ -336,7 +261,7 @@
             }
             // call doclet for its options
             // other arg starts with - is invalid
-            else if ( arg.startsWith("-") ) {
+            else if (arg.startsWith("-")) {
                 int optionLength;
                 optionLength = docletInvoker.optionLength(arg);
                 if (optionLength < 0) {
@@ -380,12 +305,18 @@
 
         LanguageVersion languageVersion = docletInvoker.languageVersion();
         RootDocImpl root = comp.getRootDocImpl(
-                docLocale, encoding, showAccess,
-                javaNames.toList(), options.toList(), breakiterator,
-                subPackages.toList(), excludedPackages.toList(),
+                docLocale,
+                encoding,
+                showAccess,
+                javaNames.toList(),
+                options.toList(),
+                breakiterator,
+                subPackages.toList(),
+                excludedPackages.toList(),
                 docClasses,
                 // legacy?
-                languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
+                languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1,
+                quiet);
 
         // release resources
         comp = null;
@@ -437,15 +368,6 @@
                                           docletParentClassLoader);
     }
 
-    private void setFilter(long filterBits) {
-        if (showAccess != null) {
-            messager.error(null, "main.incompatible.access.flags");
-            usage();
-            exit();
-        }
-        showAccess = new ModifierFilter(filterBits);
-    }
-
     /**
      * Set one arg option.
      * Error and exit if one argument is not provided.
@@ -458,22 +380,10 @@
         }
     }
 
-    private void usageError(String key) {
-        messager.error(null, key);
-        usage();
-        exit();
-    }
-
-    private void usageError(String key, String a1) {
-        messager.error(null, key, a1);
-        usage();
-        exit();
-    }
-
-    private void usageError(String key, String a1, String a2) {
-        messager.error(null, key, a1, a2);
-        usage();
-        exit();
+    @Override
+    void usageError(String key, Object... args) {
+        messager.error(Messager.NOPOS, key, args);
+        usage(true);
     }
 
     /**
@@ -502,7 +412,6 @@
         for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
             args[k++] = i.head;
         }
-        options = options.append(args);
+        options.append(args);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java	Thu Nov 15 14:41:31 2012 -0800
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javadoc;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Options;
+import java.util.StringTokenizer;
+
+
+/**
+ * javadoc tool options.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public enum ToolOption {
+    // ----- options for underlying compiler -----
+
+    BOOTCLASSPATH("-bootclasspath", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    CLASSPATH("-classpath", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    EXTDIRS("-extdirs", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    SOURCEPATH("-sourcepath", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    SYSCLASSPATH("-sysclasspath", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt("-bootclasspath", arg);
+        }
+    },
+
+    ENCODING("-encoding", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.encoding = arg;
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    SOURCE("-source", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    XMAXERRS("-Xmaxerrs", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    XMAXWARNS("-Xmaxwarns", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setCompilerOpt(opt, arg);
+        }
+    },
+
+    // ----- doclet options -----
+
+    DOCLET("-doclet", true), // handled in setDocletInvoker
+
+    DOCLETPATH("-docletpath", true), // handled in setDocletInvoker
+
+    // ----- selection options -----
+
+    SUBPACKAGES("-subpackages", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.addToList(helper.subPackages, arg);
+        }
+    },
+
+    EXCLUDE("-exclude", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.addToList(helper.excludedPackages, arg);
+        }
+    },
+
+    // ----- filtering options -----
+
+    PACKAGE("-package") {
+        @Override
+        public void process(Helper helper) {
+            helper.setFilter(
+                    Flags.PUBLIC | Flags.PROTECTED | ModifierFilter.PACKAGE);
+        }
+    },
+
+    PRIVATE("-private") {
+        @Override
+        public void process(Helper helper) {
+            helper.setFilter(ModifierFilter.ALL_ACCESS);
+        }
+    },
+
+    PROTECTED("-protected") {
+        @Override
+        public void process(Helper helper) {
+            helper.setFilter(Flags.PUBLIC | Flags.PROTECTED);
+        }
+    },
+
+    PUBLIC("-public") {
+        @Override
+        public void process(Helper helper) {
+            helper.setFilter(Flags.PUBLIC);
+        }
+    },
+
+    // ----- output control options -----
+
+    PROMPT("-prompt") {
+        @Override
+        public void process(Helper helper) {
+            helper.compOpts.put("-prompt", "-prompt");
+            helper.promptOnError = true;
+        }
+    },
+
+    QUIET("-quiet") {
+        @Override
+        public void process(Helper helper) {
+            helper.quiet = true;
+        }
+    },
+
+    VERBOSE("-verbose") {
+        @Override
+        public void process(Helper helper) {
+            helper.compOpts.put("-verbose", "");
+        }
+    },
+
+    XWERROR("-Xwerror") {
+        @Override
+        public void process(Helper helper) {
+            helper.rejectWarnings = true;
+
+        }
+    },
+
+    // ----- other options -----
+
+    BREAKITERATOR("-breakiterator") {
+        @Override
+        public void process(Helper helper) {
+            helper.breakiterator = true;
+        }
+    },
+
+    LOCALE("-locale", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.docLocale = arg;
+        }
+    },
+
+    OVERVIEW("-overview", true),
+
+    XCLASSES("-Xclasses") {
+        @Override
+        public void process(Helper helper) {
+            helper.docClasses = true;
+
+        }
+    },
+
+    // ----- help options -----
+
+    HELP("-help") {
+        @Override
+        public void process(Helper helper) {
+            helper.usage();
+        }
+    },
+
+    X("-X") {
+        @Override
+        public void process(Helper helper) {
+            helper.Xusage();
+        }
+    };
+
+    public final String opt;
+    public final boolean hasArg;
+
+    ToolOption(String opt) {
+        this(opt, false);
+    }
+
+    ToolOption(String opt, boolean hasArg) {
+        this.opt = opt;
+        this.hasArg = hasArg;
+    }
+
+    void process(Helper helper, String arg) { }
+
+    void process(Helper helper) { }
+
+    static ToolOption get(String name) {
+        for (ToolOption o: values()) {
+            if (name.equals(o.opt))
+                return o;
+        }
+        return null;
+    }
+
+    static abstract class Helper {
+        /** List of decoded options. */
+        final ListBuffer<String[]> options = new ListBuffer<String[]>();
+
+        /** Selected packages, from -subpackages. */
+        final ListBuffer<String> subPackages = new ListBuffer<String>();
+
+        /** Excluded packages, from -exclude. */
+        final ListBuffer<String> excludedPackages = new ListBuffer<String>();
+
+        /** javac options, set by various options. */
+        Options compOpts; // = Options.instance(context)
+
+        /* Encoding for javac, and files written? set by -encoding. */
+        String encoding = null;
+
+        /** Set by -breakiterator. */
+        boolean breakiterator = false;
+
+        /** Set by -quiet. */
+        boolean quiet = false;
+
+        /** Set by -Xclasses. */
+        boolean docClasses = false;
+
+        /** Set by -Xwerror. */
+        boolean rejectWarnings = false;
+
+        /** Set by -prompt. */
+        boolean promptOnError;
+
+        /** Set by -locale. */
+        String docLocale = "";
+
+        /** Set by -public, private, -protected, -package. */
+        ModifierFilter showAccess = null;
+
+        abstract void usage();
+        abstract void Xusage();
+
+        abstract void usageError(String msg, Object... args);
+
+        protected void addToList(ListBuffer<String> list, String str){
+            StringTokenizer st = new StringTokenizer(str, ":");
+            String current;
+            while(st.hasMoreTokens()){
+                current = st.nextToken();
+                list.append(current);
+            }
+        }
+
+        protected void setFilter(long filterBits) {
+            if (showAccess != null) {
+                usageError("main.incompatible.access.flags");
+            }
+            showAccess = new ModifierFilter(filterBits);
+        }
+
+        private void setCompilerOpt(String opt, String arg) {
+            if (compOpts.get(opt) != null) {
+                usageError("main.option.already.seen", opt);
+            }
+            compOpts.put(opt, arg);
+        }
+    }
+}