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

Tue, 24 Jan 2012 15:51:44 -0800

author
jjh
date
Tue, 24 Jan 2012 15:51:44 -0800
changeset 1187
ac36176b7de0
parent 1135
36553cb94345
child 1357
c75be5bc5283
permissions
-rw-r--r--

7126832: com.sun.tools.javac.api.ClientCodeWrapper$WrappedJavaFileManager cannot be cast
Reviewed-by: jjg

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

mercurial