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

Tue, 09 Oct 2012 19:10:00 -0700

author
jjg
date
Tue, 09 Oct 2012 19:10:00 -0700
changeset 1357
c75be5bc5283
parent 1135
36553cb94345
child 1359
25e14ad23cef
permissions
-rw-r--r--

8000663: clean up langtools imports
Reviewed-by: darcy

     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  * @since 1.2
    48  * @author Robert Field
    49  * @author Neal Gafter (rewrite)
    50  */
    51 class Start {
    53     private final String defaultDocletClassName;
    54     private final ClassLoader docletParentClassLoader;
    56     private static final String javadocName = "javadoc";
    58     private static final String standardDocletClassName =
    59         "com.sun.tools.doclets.standard.Standard";
    61     private ListBuffer<String[]> options = new ListBuffer<String[]>();
    63     private ModifierFilter showAccess = null;
    65     private long defaultFilter = PUBLIC | PROTECTED;
    67     private Messager messager;
    69     String docLocale = "";
    71     boolean breakiterator = false;
    72     boolean quiet = false;
    73     String encoding = null;
    75     private DocletInvoker docletInvoker;
    77     /* Treat warnings as errors. */
    78     private boolean rejectWarnings = false;
    80     Start(String programName,
    81           PrintWriter errWriter,
    82           PrintWriter warnWriter,
    83           PrintWriter noticeWriter,
    84           String defaultDocletClassName) {
    85         this(programName, errWriter, warnWriter, noticeWriter, defaultDocletClassName, null);
    86     }
    88     Start(String programName,
    89           PrintWriter errWriter,
    90           PrintWriter warnWriter,
    91           PrintWriter noticeWriter,
    92           String defaultDocletClassName,
    93           ClassLoader docletParentClassLoader) {
    94         Context tempContext = new Context(); // interim context until option decoding completed
    95         messager = new Messager(tempContext, programName, errWriter, warnWriter, noticeWriter);
    96         this.defaultDocletClassName = defaultDocletClassName;
    97         this.docletParentClassLoader = docletParentClassLoader;
    98     }
   100     Start(String programName, String defaultDocletClassName) {
   101         this(programName, defaultDocletClassName, null);
   102     }
   104     Start(String programName, String defaultDocletClassName,
   105           ClassLoader docletParentClassLoader) {
   106         Context tempContext = new Context(); // interim context until option decoding completed
   107         messager = new Messager(tempContext, programName);
   108         this.defaultDocletClassName = defaultDocletClassName;
   109         this.docletParentClassLoader = docletParentClassLoader;
   110     }
   112     Start(String programName, ClassLoader docletParentClassLoader) {
   113         this(programName, standardDocletClassName, docletParentClassLoader);
   114     }
   116     Start(String programName) {
   117         this(programName, standardDocletClassName);
   118     }
   120     Start(ClassLoader docletParentClassLoader) {
   121         this(javadocName, docletParentClassLoader);
   122     }
   124     Start() {
   125         this(javadocName);
   126     }
   128     /**
   129      * Usage
   130      */
   131     private void usage() {
   132         messager.notice("main.usage");
   134         // let doclet print usage information (does nothing on error)
   135         if (docletInvoker != null) {
   136             docletInvoker.optionLength("-help");
   137         }
   138     }
   140     /**
   141      * Usage
   142      */
   143     private void Xusage() {
   144         messager.notice("main.Xusage");
   145     }
   147     /**
   148      * Exit
   149      */
   150     private void exit() {
   151         messager.exit();
   152     }
   155     /**
   156      * Main program - external wrapper
   157      */
   158     int begin(String... argv) {
   159         boolean failed = false;
   161         try {
   162             failed = !parseAndExecute(argv);
   163         } catch(Messager.ExitJavadoc exc) {
   164             // ignore, we just exit this way
   165         } catch (OutOfMemoryError ee) {
   166             messager.error(null, "main.out.of.memory");
   167             failed = true;
   168         } catch (Error ee) {
   169             ee.printStackTrace(System.err);
   170             messager.error(null, "main.fatal.error");
   171             failed = true;
   172         } catch (Exception ee) {
   173             ee.printStackTrace(System.err);
   174             messager.error(null, "main.fatal.exception");
   175             failed = true;
   176         } finally {
   177             messager.exitNotice();
   178             messager.flush();
   179         }
   180         failed |= messager.nerrors() > 0;
   181         failed |= rejectWarnings && messager.nwarnings() > 0;
   182         return failed ? 1 : 0;
   183     }
   185     private void addToList(ListBuffer<String> list, String str){
   186         StringTokenizer st = new StringTokenizer(str, ":");
   187         String current;
   188         while(st.hasMoreTokens()){
   189             current = st.nextToken();
   190             list.append(current);
   191         }
   192     }
   194     /**
   195      * Main program - internal
   196      */
   197     private boolean parseAndExecute(String... argv) throws IOException {
   198         long tm = System.currentTimeMillis();
   200         ListBuffer<String> javaNames = new ListBuffer<String>();
   202         // Preprocess @file arguments
   203         try {
   204             argv = CommandLine.parse(argv);
   205         } catch (FileNotFoundException e) {
   206             messager.error(null, "main.cant.read", e.getMessage());
   207             exit();
   208         } catch (IOException e) {
   209             e.printStackTrace(System.err);
   210             exit();
   211         }
   213         setDocletInvoker(argv);
   214         ListBuffer<String> subPackages = new ListBuffer<String>();
   215         ListBuffer<String> excludedPackages = new ListBuffer<String>();
   217         Context context = new Context();
   218         // Setup a new Messager, using the same initial parameters as the
   219         // existing Messager, except that this one will be able to use any
   220         // options that may be set up below.
   221         Messager.preRegister(context,
   222                 messager.programName,
   223                 messager.getWriter(Log.WriterKind.ERROR),
   224                 messager.getWriter(Log.WriterKind.WARNING),
   225                 messager.getWriter(Log.WriterKind.NOTICE));
   227         Options compOpts = Options.instance(context);
   228         boolean docClasses = false;
   230         // Parse arguments
   231         for (int i = 0 ; i < argv.length ; i++) {
   232             String arg = argv[i];
   233             if (arg.equals("-subpackages")) {
   234                 oneArg(argv, i++);
   235                 addToList(subPackages, argv[i]);
   236             } else if (arg.equals("-exclude")){
   237                 oneArg(argv, i++);
   238                 addToList(excludedPackages, argv[i]);
   239             } else if (arg.equals("-verbose")) {
   240                 setOption(arg);
   241                 compOpts.put("-verbose", "");
   242             } else if (arg.equals("-encoding")) {
   243                 oneArg(argv, i++);
   244                 encoding = argv[i];
   245                 compOpts.put("-encoding", argv[i]);
   246             } else if (arg.equals("-breakiterator")) {
   247                 breakiterator = true;
   248                 setOption("-breakiterator");
   249             } else if (arg.equals("-quiet")) {
   250                 quiet = true;
   251                 setOption("-quiet");
   252             } else if (arg.equals("-help")) {
   253                 usage();
   254                 exit();
   255             } else if (arg.equals("-Xclasses")) {
   256                 setOption(arg);
   257                 docClasses = true;
   258             } else if (arg.equals("-Xwerror")) {
   259                 setOption(arg);
   260                 rejectWarnings = true;
   261             } else if (arg.equals("-private")) {
   262                 setOption(arg);
   263                 setFilter(ModifierFilter.ALL_ACCESS);
   264             } else if (arg.equals("-package")) {
   265                 setOption(arg);
   266                 setFilter(PUBLIC | PROTECTED |
   267                           ModifierFilter.PACKAGE );
   268             } else if (arg.equals("-protected")) {
   269                 setOption(arg);
   270                 setFilter(PUBLIC | PROTECTED );
   271             } else if (arg.equals("-public")) {
   272                 setOption(arg);
   273                 setFilter(PUBLIC);
   274             } else if (arg.equals("-source")) {
   275                 oneArg(argv, i++);
   276                 if (compOpts.get("-source") != null) {
   277                     usageError("main.option.already.seen", arg);
   278                 }
   279                 compOpts.put("-source", argv[i]);
   280             } else if (arg.equals("-prompt")) {
   281                 compOpts.put("-prompt", "-prompt");
   282                 messager.promptOnError = true;
   283             } else if (arg.equals("-sourcepath")) {
   284                 oneArg(argv, i++);
   285                 if (compOpts.get("-sourcepath") != null) {
   286                     usageError("main.option.already.seen", arg);
   287                 }
   288                 compOpts.put("-sourcepath", argv[i]);
   289             } else if (arg.equals("-classpath")) {
   290                 oneArg(argv, i++);
   291                 if (compOpts.get("-classpath") != null) {
   292                     usageError("main.option.already.seen", arg);
   293                 }
   294                 compOpts.put("-classpath", argv[i]);
   295             } else if (arg.equals("-sysclasspath")) {
   296                 oneArg(argv, i++);
   297                 if (compOpts.get("-bootclasspath") != null) {
   298                     usageError("main.option.already.seen", arg);
   299                 }
   300                 compOpts.put("-bootclasspath", argv[i]);
   301             } else if (arg.equals("-bootclasspath")) {
   302                 oneArg(argv, i++);
   303                 if (compOpts.get("-bootclasspath") != null) {
   304                     usageError("main.option.already.seen", arg);
   305                 }
   306                 compOpts.put("-bootclasspath", argv[i]);
   307             } else if (arg.equals("-extdirs")) {
   308                 oneArg(argv, i++);
   309                 if (compOpts.get("-extdirs") != null) {
   310                     usageError("main.option.already.seen", arg);
   311                 }
   312                 compOpts.put("-extdirs", argv[i]);
   313             } else if (arg.equals("-overview")) {
   314                 oneArg(argv, i++);
   315             } else if (arg.equals("-doclet")) {
   316                 i++;  // handled in setDocletInvoker
   317             } else if (arg.equals("-docletpath")) {
   318                 i++;  // handled in setDocletInvoker
   319             } else if (arg.equals("-locale")) {
   320                 if (i != 0)
   321                     usageError("main.locale_first");
   322                 oneArg(argv, i++);
   323                 docLocale = argv[i];
   324             } else if (arg.equals("-Xmaxerrs") || arg.equals("-Xmaxwarns")) {
   325                 oneArg(argv, i++);
   326                 if (compOpts.get(arg) != null) {
   327                     usageError("main.option.already.seen", arg);
   328                 }
   329                 compOpts.put(arg, argv[i]);
   330             } else if (arg.equals("-X")) {
   331                 Xusage();
   332                 exit();
   333             } else if (arg.startsWith("-XD")) {
   334                 String s = arg.substring("-XD".length());
   335                 int eq = s.indexOf('=');
   336                 String key = (eq < 0) ? s : s.substring(0, eq);
   337                 String value = (eq < 0) ? s : s.substring(eq+1);
   338                 compOpts.put(key, value);
   339             }
   340             // call doclet for its options
   341             // other arg starts with - is invalid
   342             else if ( arg.startsWith("-") ) {
   343                 int optionLength;
   344                 optionLength = docletInvoker.optionLength(arg);
   345                 if (optionLength < 0) {
   346                     // error already displayed
   347                     exit();
   348                 } else if (optionLength == 0) {
   349                     // option not found
   350                     usageError("main.invalid_flag", arg);
   351                 } else {
   352                     // doclet added option
   353                     if ((i + optionLength) > argv.length) {
   354                         usageError("main.requires_argument", arg);
   355                     }
   356                     ListBuffer<String> args = new ListBuffer<String>();
   357                     for (int j = 0; j < optionLength-1; ++j) {
   358                         args.append(argv[++i]);
   359                     }
   360                     setOption(arg, args.toList());
   361                 }
   362             } else {
   363                 javaNames.append(arg);
   364             }
   365         }
   367         if (javaNames.isEmpty() && subPackages.isEmpty()) {
   368             usageError("main.No_packages_or_classes_specified");
   369         }
   371         if (!docletInvoker.validOptions(options.toList())) {
   372             // error message already displayed
   373             exit();
   374         }
   376         JavadocTool comp = JavadocTool.make0(context);
   377         if (comp == null) return false;
   379         if (showAccess == null) {
   380             setFilter(defaultFilter);
   381         }
   383         LanguageVersion languageVersion = docletInvoker.languageVersion();
   384         RootDocImpl root = comp.getRootDocImpl(
   385                 docLocale, encoding, showAccess,
   386                 javaNames.toList(), options.toList(), breakiterator,
   387                 subPackages.toList(), excludedPackages.toList(),
   388                 docClasses,
   389                 // legacy?
   390                 languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
   392         // pass off control to the doclet
   393         boolean ok = root != null;
   394         if (ok) ok = docletInvoker.start(root);
   396         Messager docletMessager = Messager.instance0(context);
   397         messager.nwarnings += docletMessager.nwarnings;
   398         messager.nerrors += docletMessager.nerrors;
   400         // We're done.
   401         if (compOpts.get("-verbose") != null) {
   402             tm = System.currentTimeMillis() - tm;
   403             messager.notice("main.done_in", Long.toString(tm));
   404         }
   406         return ok;
   407     }
   409     private void setDocletInvoker(String[] argv) {
   410         String docletClassName = null;
   411         String docletPath = null;
   413         // Parse doclet specifying arguments
   414         for (int i = 0 ; i < argv.length ; i++) {
   415             String arg = argv[i];
   416             if (arg.equals("-doclet")) {
   417                 oneArg(argv, i++);
   418                 if (docletClassName != null) {
   419                     usageError("main.more_than_one_doclet_specified_0_and_1",
   420                                docletClassName, argv[i]);
   421                 }
   422                 docletClassName = argv[i];
   423             } else if (arg.equals("-docletpath")) {
   424                 oneArg(argv, i++);
   425                 if (docletPath == null) {
   426                     docletPath = argv[i];
   427                 } else {
   428                     docletPath += File.pathSeparator + argv[i];
   429                 }
   430             }
   431         }
   433         if (docletClassName == null) {
   434             docletClassName = defaultDocletClassName;
   435         }
   437         // attempt to find doclet
   438         docletInvoker = new DocletInvoker(messager,
   439                                           docletClassName, docletPath,
   440                                           docletParentClassLoader);
   441     }
   443     private void setFilter(long filterBits) {
   444         if (showAccess != null) {
   445             messager.error(null, "main.incompatible.access.flags");
   446             usage();
   447             exit();
   448         }
   449         showAccess = new ModifierFilter(filterBits);
   450     }
   452     /**
   453      * Set one arg option.
   454      * Error and exit if one argument is not provided.
   455      */
   456     private void oneArg(String[] args, int index) {
   457         if ((index + 1) < args.length) {
   458             setOption(args[index], args[index+1]);
   459         } else {
   460             usageError("main.requires_argument", args[index]);
   461         }
   462     }
   464     private void usageError(String key) {
   465         messager.error(null, key);
   466         usage();
   467         exit();
   468     }
   470     private void usageError(String key, String a1) {
   471         messager.error(null, key, a1);
   472         usage();
   473         exit();
   474     }
   476     private void usageError(String key, String a1, String a2) {
   477         messager.error(null, key, a1, a2);
   478         usage();
   479         exit();
   480     }
   482     /**
   483      * indicate an option with no arguments was given.
   484      */
   485     private void setOption(String opt) {
   486         String[] option = { opt };
   487         options.append(option);
   488     }
   490     /**
   491      * indicate an option with one argument was given.
   492      */
   493     private void setOption(String opt, String argument) {
   494         String[] option = { opt, argument };
   495         options.append(option);
   496     }
   498     /**
   499      * indicate an option with the specified list of arguments was given.
   500      */
   501     private void setOption(String opt, List<String> arguments) {
   502         String[] args = new String[arguments.length() + 1];
   503         int k = 0;
   504         args[k++] = opt;
   505         for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
   506             args[k++] = i.head;
   507         }
   508         options = options.append(args);
   509     }
   511 }

mercurial