src/share/classes/com/sun/tools/javadoc/Start.java

Thu, 15 Nov 2012 09:18:36 -0800

author
jjg
date
Thu, 15 Nov 2012 09:18:36 -0800
changeset 1410
bfec2a1cc869
parent 1392
352d130c47c5
child 1411
467f4f754368
permissions
-rw-r--r--

8000800: javadoc uses static non-final fields
Reviewed-by: bpatel

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.javadoc;
    28 import java.io.File;
    29 import java.io.FileNotFoundException;
    30 import java.io.IOException;
    31 import java.io.PrintWriter;
    32 import java.util.StringTokenizer;
    34 import com.sun.javadoc.*;
    35 import com.sun.tools.javac.main.CommandLine;
    36 import com.sun.tools.javac.util.Context;
    37 import com.sun.tools.javac.util.List;
    38 import com.sun.tools.javac.util.ListBuffer;
    39 import com.sun.tools.javac.util.Log;
    40 import com.sun.tools.javac.util.Options;
    41 import static com.sun.tools.javac.code.Flags.*;
    43 /**
    44  * Main program of Javadoc.
    45  * Previously named "Main".
    46  *
    47  *  <p><b>This is NOT part of any supported API.
    48  *  If you write code that depends on this, you do so at your own risk.
    49  *  This code and its internal interfaces are subject to change or
    50  *  deletion without notice.</b>
    51  *
    52  * @since 1.2
    53  * @author Robert Field
    54  * @author Neal Gafter (rewrite)
    55  */
    56 class Start {
    57     /** Context for this invocation. */
    58     private final Context context;
    60     private final String defaultDocletClassName;
    61     private final ClassLoader docletParentClassLoader;
    63     private static final String javadocName = "javadoc";
    65     private static final String standardDocletClassName =
    66         "com.sun.tools.doclets.standard.Standard";
    68     private ListBuffer<String[]> options = new ListBuffer<String[]>();
    70     private ModifierFilter showAccess = null;
    72     private long defaultFilter = PUBLIC | PROTECTED;
    74     private final Messager messager;
    76     String docLocale = "";
    78     boolean breakiterator = false;
    79     boolean quiet = false;
    80     String encoding = null;
    82     private DocletInvoker docletInvoker;
    84     /* Treat warnings as errors. */
    85     private boolean rejectWarnings = false;
    87     Start(String programName,
    88           PrintWriter errWriter,
    89           PrintWriter warnWriter,
    90           PrintWriter noticeWriter,
    91           String defaultDocletClassName) {
    92         this(programName, errWriter, warnWriter, noticeWriter, defaultDocletClassName, null);
    93     }
    95     Start(String programName,
    96           PrintWriter errWriter,
    97           PrintWriter warnWriter,
    98           PrintWriter noticeWriter,
    99           String defaultDocletClassName,
   100           ClassLoader docletParentClassLoader) {
   101         context = new Context();
   102         messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
   103         this.defaultDocletClassName = defaultDocletClassName;
   104         this.docletParentClassLoader = docletParentClassLoader;
   105     }
   107     Start(String programName, String defaultDocletClassName) {
   108         this(programName, defaultDocletClassName, null);
   109     }
   111     Start(String programName, String defaultDocletClassName,
   112           ClassLoader docletParentClassLoader) {
   113         context = new Context();
   114         messager = new Messager(context, programName);
   115         this.defaultDocletClassName = defaultDocletClassName;
   116         this.docletParentClassLoader = docletParentClassLoader;
   117     }
   119     Start(String programName, ClassLoader docletParentClassLoader) {
   120         this(programName, standardDocletClassName, docletParentClassLoader);
   121     }
   123     Start(String programName) {
   124         this(programName, standardDocletClassName);
   125     }
   127     Start(ClassLoader docletParentClassLoader) {
   128         this(javadocName, docletParentClassLoader);
   129     }
   131     Start() {
   132         this(javadocName);
   133     }
   135     /**
   136      * Usage
   137      */
   138     private void usage() {
   139         messager.notice("main.usage");
   141         // let doclet print usage information (does nothing on error)
   142         if (docletInvoker != null) {
   143             docletInvoker.optionLength("-help");
   144         }
   145     }
   147     /**
   148      * Usage
   149      */
   150     private void Xusage() {
   151         messager.notice("main.Xusage");
   152     }
   154     /**
   155      * Exit
   156      */
   157     private void exit() {
   158         messager.exit();
   159     }
   162     /**
   163      * Main program - external wrapper
   164      */
   165     int begin(String... argv) {
   166         boolean failed = false;
   168         try {
   169             failed = !parseAndExecute(argv);
   170         } catch(Messager.ExitJavadoc exc) {
   171             // ignore, we just exit this way
   172         } catch (OutOfMemoryError ee) {
   173             messager.error(null, "main.out.of.memory");
   174             failed = true;
   175         } catch (Error ee) {
   176             ee.printStackTrace(System.err);
   177             messager.error(null, "main.fatal.error");
   178             failed = true;
   179         } catch (Exception ee) {
   180             ee.printStackTrace(System.err);
   181             messager.error(null, "main.fatal.exception");
   182             failed = true;
   183         } finally {
   184             messager.exitNotice();
   185             messager.flush();
   186         }
   187         failed |= messager.nerrors() > 0;
   188         failed |= rejectWarnings && messager.nwarnings() > 0;
   189         return failed ? 1 : 0;
   190     }
   192     private void addToList(ListBuffer<String> list, String str){
   193         StringTokenizer st = new StringTokenizer(str, ":");
   194         String current;
   195         while(st.hasMoreTokens()){
   196             current = st.nextToken();
   197             list.append(current);
   198         }
   199     }
   201     /**
   202      * Main program - internal
   203      */
   204     private boolean parseAndExecute(String... argv) throws IOException {
   205         long tm = System.currentTimeMillis();
   207         ListBuffer<String> javaNames = new ListBuffer<String>();
   209         // Preprocess @file arguments
   210         try {
   211             argv = CommandLine.parse(argv);
   212         } catch (FileNotFoundException e) {
   213             messager.error(null, "main.cant.read", e.getMessage());
   214             exit();
   215         } catch (IOException e) {
   216             e.printStackTrace(System.err);
   217             exit();
   218         }
   220         setDocletInvoker(argv);
   221         ListBuffer<String> subPackages = new ListBuffer<String>();
   222         ListBuffer<String> excludedPackages = new ListBuffer<String>();
   224         Options compOpts = Options.instance(context);
   225         boolean docClasses = false;
   227         // Parse arguments
   228         for (int i = 0 ; i < argv.length ; i++) {
   229             String arg = argv[i];
   230             if (arg.equals("-subpackages")) {
   231                 oneArg(argv, i++);
   232                 addToList(subPackages, argv[i]);
   233             } else if (arg.equals("-exclude")){
   234                 oneArg(argv, i++);
   235                 addToList(excludedPackages, argv[i]);
   236             } else if (arg.equals("-verbose")) {
   237                 setOption(arg);
   238                 compOpts.put("-verbose", "");
   239             } else if (arg.equals("-encoding")) {
   240                 oneArg(argv, i++);
   241                 encoding = argv[i];
   242                 compOpts.put("-encoding", argv[i]);
   243             } else if (arg.equals("-breakiterator")) {
   244                 breakiterator = true;
   245                 setOption("-breakiterator");
   246             } else if (arg.equals("-quiet")) {
   247                 quiet = true;
   248                 setOption("-quiet");
   249             } else if (arg.equals("-help")) {
   250                 usage();
   251                 exit();
   252             } else if (arg.equals("-Xclasses")) {
   253                 setOption(arg);
   254                 docClasses = true;
   255             } else if (arg.equals("-Xwerror")) {
   256                 setOption(arg);
   257                 rejectWarnings = true;
   258             } else if (arg.equals("-private")) {
   259                 setOption(arg);
   260                 setFilter(ModifierFilter.ALL_ACCESS);
   261             } else if (arg.equals("-package")) {
   262                 setOption(arg);
   263                 setFilter(PUBLIC | PROTECTED |
   264                           ModifierFilter.PACKAGE );
   265             } else if (arg.equals("-protected")) {
   266                 setOption(arg);
   267                 setFilter(PUBLIC | PROTECTED );
   268             } else if (arg.equals("-public")) {
   269                 setOption(arg);
   270                 setFilter(PUBLIC);
   271             } else if (arg.equals("-source")) {
   272                 oneArg(argv, i++);
   273                 if (compOpts.get("-source") != null) {
   274                     usageError("main.option.already.seen", arg);
   275                 }
   276                 compOpts.put("-source", argv[i]);
   277             } else if (arg.equals("-prompt")) {
   278                 compOpts.put("-prompt", "-prompt");
   279                 messager.promptOnError = true;
   280             } else if (arg.equals("-sourcepath")) {
   281                 oneArg(argv, i++);
   282                 if (compOpts.get("-sourcepath") != null) {
   283                     usageError("main.option.already.seen", arg);
   284                 }
   285                 compOpts.put("-sourcepath", argv[i]);
   286             } else if (arg.equals("-classpath")) {
   287                 oneArg(argv, i++);
   288                 if (compOpts.get("-classpath") != null) {
   289                     usageError("main.option.already.seen", arg);
   290                 }
   291                 compOpts.put("-classpath", argv[i]);
   292             } else if (arg.equals("-sysclasspath")) {
   293                 oneArg(argv, i++);
   294                 if (compOpts.get("-bootclasspath") != null) {
   295                     usageError("main.option.already.seen", arg);
   296                 }
   297                 compOpts.put("-bootclasspath", argv[i]);
   298             } else if (arg.equals("-bootclasspath")) {
   299                 oneArg(argv, i++);
   300                 if (compOpts.get("-bootclasspath") != null) {
   301                     usageError("main.option.already.seen", arg);
   302                 }
   303                 compOpts.put("-bootclasspath", argv[i]);
   304             } else if (arg.equals("-extdirs")) {
   305                 oneArg(argv, i++);
   306                 if (compOpts.get("-extdirs") != null) {
   307                     usageError("main.option.already.seen", arg);
   308                 }
   309                 compOpts.put("-extdirs", argv[i]);
   310             } else if (arg.equals("-overview")) {
   311                 oneArg(argv, i++);
   312             } else if (arg.equals("-doclet")) {
   313                 i++;  // handled in setDocletInvoker
   314             } else if (arg.equals("-docletpath")) {
   315                 i++;  // handled in setDocletInvoker
   316             } else if (arg.equals("-locale")) {
   317                 if (i != 0)
   318                     usageError("main.locale_first");
   319                 oneArg(argv, i++);
   320                 docLocale = argv[i];
   321             } else if (arg.equals("-Xmaxerrs") || arg.equals("-Xmaxwarns")) {
   322                 oneArg(argv, i++);
   323                 if (compOpts.get(arg) != null) {
   324                     usageError("main.option.already.seen", arg);
   325                 }
   326                 compOpts.put(arg, argv[i]);
   327             } else if (arg.equals("-X")) {
   328                 Xusage();
   329                 exit();
   330             } else if (arg.startsWith("-XD")) {
   331                 String s = arg.substring("-XD".length());
   332                 int eq = s.indexOf('=');
   333                 String key = (eq < 0) ? s : s.substring(0, eq);
   334                 String value = (eq < 0) ? s : s.substring(eq+1);
   335                 compOpts.put(key, value);
   336             }
   337             // call doclet for its options
   338             // other arg starts with - is invalid
   339             else if ( arg.startsWith("-") ) {
   340                 int optionLength;
   341                 optionLength = docletInvoker.optionLength(arg);
   342                 if (optionLength < 0) {
   343                     // error already displayed
   344                     exit();
   345                 } else if (optionLength == 0) {
   346                     // option not found
   347                     usageError("main.invalid_flag", arg);
   348                 } else {
   349                     // doclet added option
   350                     if ((i + optionLength) > argv.length) {
   351                         usageError("main.requires_argument", arg);
   352                     }
   353                     ListBuffer<String> args = new ListBuffer<String>();
   354                     for (int j = 0; j < optionLength-1; ++j) {
   355                         args.append(argv[++i]);
   356                     }
   357                     setOption(arg, args.toList());
   358                 }
   359             } else {
   360                 javaNames.append(arg);
   361             }
   362         }
   363         compOpts.notifyListeners();
   365         if (javaNames.isEmpty() && subPackages.isEmpty()) {
   366             usageError("main.No_packages_or_classes_specified");
   367         }
   369         if (!docletInvoker.validOptions(options.toList())) {
   370             // error message already displayed
   371             exit();
   372         }
   374         JavadocTool comp = JavadocTool.make0(context);
   375         if (comp == null) return false;
   377         if (showAccess == null) {
   378             setFilter(defaultFilter);
   379         }
   381         LanguageVersion languageVersion = docletInvoker.languageVersion();
   382         RootDocImpl root = comp.getRootDocImpl(
   383                 docLocale, encoding, showAccess,
   384                 javaNames.toList(), options.toList(), breakiterator,
   385                 subPackages.toList(), excludedPackages.toList(),
   386                 docClasses,
   387                 // legacy?
   388                 languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
   390         // release resources
   391         comp = null;
   393         // pass off control to the doclet
   394         boolean ok = root != null;
   395         if (ok) ok = docletInvoker.start(root);
   397         // We're done.
   398         if (compOpts.get("-verbose") != null) {
   399             tm = System.currentTimeMillis() - tm;
   400             messager.notice("main.done_in", Long.toString(tm));
   401         }
   403         return ok;
   404     }
   406     private void setDocletInvoker(String[] argv) {
   407         String docletClassName = null;
   408         String docletPath = null;
   410         // Parse doclet specifying arguments
   411         for (int i = 0 ; i < argv.length ; i++) {
   412             String arg = argv[i];
   413             if (arg.equals("-doclet")) {
   414                 oneArg(argv, i++);
   415                 if (docletClassName != null) {
   416                     usageError("main.more_than_one_doclet_specified_0_and_1",
   417                                docletClassName, argv[i]);
   418                 }
   419                 docletClassName = argv[i];
   420             } else if (arg.equals("-docletpath")) {
   421                 oneArg(argv, i++);
   422                 if (docletPath == null) {
   423                     docletPath = argv[i];
   424                 } else {
   425                     docletPath += File.pathSeparator + argv[i];
   426                 }
   427             }
   428         }
   430         if (docletClassName == null) {
   431             docletClassName = defaultDocletClassName;
   432         }
   434         // attempt to find doclet
   435         docletInvoker = new DocletInvoker(messager,
   436                                           docletClassName, docletPath,
   437                                           docletParentClassLoader);
   438     }
   440     private void setFilter(long filterBits) {
   441         if (showAccess != null) {
   442             messager.error(null, "main.incompatible.access.flags");
   443             usage();
   444             exit();
   445         }
   446         showAccess = new ModifierFilter(filterBits);
   447     }
   449     /**
   450      * Set one arg option.
   451      * Error and exit if one argument is not provided.
   452      */
   453     private void oneArg(String[] args, int index) {
   454         if ((index + 1) < args.length) {
   455             setOption(args[index], args[index+1]);
   456         } else {
   457             usageError("main.requires_argument", args[index]);
   458         }
   459     }
   461     private void usageError(String key) {
   462         messager.error(null, key);
   463         usage();
   464         exit();
   465     }
   467     private void usageError(String key, String a1) {
   468         messager.error(null, key, a1);
   469         usage();
   470         exit();
   471     }
   473     private void usageError(String key, String a1, String a2) {
   474         messager.error(null, key, a1, a2);
   475         usage();
   476         exit();
   477     }
   479     /**
   480      * indicate an option with no arguments was given.
   481      */
   482     private void setOption(String opt) {
   483         String[] option = { opt };
   484         options.append(option);
   485     }
   487     /**
   488      * indicate an option with one argument was given.
   489      */
   490     private void setOption(String opt, String argument) {
   491         String[] option = { opt, argument };
   492         options.append(option);
   493     }
   495     /**
   496      * indicate an option with the specified list of arguments was given.
   497      */
   498     private void setOption(String opt, List<String> arguments) {
   499         String[] args = new String[arguments.length() + 1];
   500         int k = 0;
   501         args[k++] = opt;
   502         for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
   503             args[k++] = i.head;
   504         }
   505         options = options.append(args);
   506     }
   508 }

mercurial