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

Sat, 01 Dec 2007 00:00:00 +0000

author
duke
date
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1
9a66ca7c79fa
child 127
d593587c5938
permissions
-rw-r--r--

Initial load

     1 /*
     2  * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any 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.main.JavaCompiler;
    32 import com.sun.tools.javac.util.Context;
    33 import com.sun.tools.javac.util.List;
    34 import com.sun.tools.javac.util.ListBuffer;
    35 import com.sun.tools.javac.util.Options;
    37 import com.sun.tools.javadoc.Messager;
    38 import com.sun.tools.javadoc.DocletInvoker;
    39 import com.sun.tools.javadoc.RootDocImpl;
    40 import com.sun.tools.javadoc.ModifierFilter;
    42 import java.io.IOException;
    43 import java.io.File;
    44 import java.io.FileNotFoundException;
    45 import java.io.PrintWriter;
    47 import java.util.StringTokenizer;
    49 import static com.sun.tools.javac.code.Flags.*;
    51 /**
    52  * Main program of Javadoc.
    53  * Previously named "Main".
    54  *
    55  * @since 1.2
    56  * @author Robert Field
    57  * @author Neal Gafter (rewrite)
    58  */
    59 class Start {
    60     /** Context for this invocation. */
    61     private final Context context;
    63     /**
    64      * Name of the program
    65      */
    66     private final String defaultDocletClassName;
    68     private static final String javadocName = "javadoc";
    70     private static final String standardDocletClassName =
    71         "com.sun.tools.doclets.standard.Standard";
    73     private ListBuffer<String[]> options = new ListBuffer<String[]>();
    75     private ModifierFilter showAccess = null;
    77     private long defaultFilter = PUBLIC | PROTECTED;
    79     private Messager messager;
    81     String docLocale = "";
    83     boolean breakiterator = false;
    84     boolean quiet = false;
    85     String encoding = null;
    87     private DocletInvoker docletInvoker;
    89     private static final int F_VERBOSE = 1 << 0;
    90     private static final int F_WARNINGS = 1 << 2;
    92     /* Treat warnings as errors. */
    93     private boolean rejectWarnings = false;
    95     Start(String programName,
    96           PrintWriter errWriter,
    97           PrintWriter warnWriter,
    98           PrintWriter noticeWriter,
    99           String defaultDocletClassName) {
   100         context = new Context();
   101         messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
   102         this.defaultDocletClassName = defaultDocletClassName;
   103     }
   105     Start(String programName, String defaultDocletClassName) {
   106         context = new Context();
   107         messager = new Messager(context, programName);
   108         this.defaultDocletClassName = defaultDocletClassName;
   109     }
   111     Start(String programName) {
   112         this(programName, standardDocletClassName);
   113     }
   115     Start() {
   116         this(javadocName);
   117     }
   119     /**
   120      * Usage
   121      */
   122     private void usage() {
   123         messager.notice("main.usage");
   125         // let doclet print usage information (does nothing on error)
   126         if (docletInvoker != null) {
   127             docletInvoker.optionLength("-help");
   128         }
   129     }
   131     /**
   132      * Exit
   133      */
   134     private void exit() {
   135         messager.exit();
   136     }
   139     /**
   140      * Main program - external wrapper
   141      */
   142     int begin(String argv[]) {
   143         boolean failed = false;
   145         try {
   146             failed = !parseAndExecute(argv);
   147         } catch(Messager.ExitJavadoc exc) {
   148             // ignore, we just exit this way
   149         } catch (OutOfMemoryError ee) {
   150             messager.error(null, "main.out.of.memory");
   151             failed = true;
   152         } catch (Error ee) {
   153             ee.printStackTrace();
   154             messager.error(null, "main.fatal.error");
   155             failed = true;
   156         } catch (Exception ee) {
   157             ee.printStackTrace();
   158             messager.error(null, "main.fatal.exception");
   159             failed = true;
   160         } finally {
   161             messager.exitNotice();
   162             messager.flush();
   163         }
   164         failed |= messager.nerrors() > 0;
   165         failed |= rejectWarnings && messager.nwarnings() > 0;
   166         return failed ? 1 : 0;
   167     }
   169     private void addToList(ListBuffer<String> list, String str){
   170         StringTokenizer st = new StringTokenizer(str, ":");
   171         String current;
   172         while(st.hasMoreTokens()){
   173             current = st.nextToken();
   174             list.append(current);
   175         }
   176     }
   178     /**
   179      * Main program - internal
   180      */
   181     private boolean parseAndExecute(String argv[]) throws IOException {
   182         long tm = System.currentTimeMillis();
   184         ListBuffer<String> javaNames = new ListBuffer<String>();
   186         // Preprocess @file arguments
   187         try {
   188             argv = CommandLine.parse(argv);
   189         } catch (FileNotFoundException e) {
   190             messager.error(null, "main.cant.read", e.getMessage());
   191             exit();
   192         } catch (IOException e) {
   193             e.printStackTrace();
   194             exit();
   195         }
   197         setDocletInvoker(argv);
   198         ListBuffer<String> subPackages = new ListBuffer<String>();
   199         ListBuffer<String> excludedPackages = new ListBuffer<String>();
   200         Options compOpts = Options.instance(context);
   201         boolean docClasses = false;
   203         // Parse arguments
   204         for (int i = 0 ; i < argv.length ; i++) {
   205             String arg = argv[i];
   206             if (arg.equals("-subpackages")) {
   207                 oneArg(argv, i++);
   208                 addToList(subPackages, argv[i]);
   209             } else if (arg.equals("-exclude")){
   210                 oneArg(argv, i++);
   211                 addToList(excludedPackages, argv[i]);
   212             } else if (arg.equals("-verbose")) {
   213                 setOption(arg);
   214                 compOpts.put("-verbose", "");
   215             } else if (arg.equals("-encoding")) {
   216                 oneArg(argv, i++);
   217                 encoding = argv[i];
   218                 compOpts.put("-encoding", argv[i]);
   219             } else if (arg.equals("-breakiterator")) {
   220                 breakiterator = true;
   221                 setOption("-breakiterator");
   222             } else if (arg.equals("-quiet")) {
   223                 quiet = true;
   224                 setOption("-quiet");
   225             } else if (arg.equals("-help")) {
   226                 usage();
   227                 exit();
   228             } else if (arg.equals("-Xclasses")) {
   229                 setOption(arg);
   230                 docClasses = true;
   231             } else if (arg.equals("-Xwerror")) {
   232                 setOption(arg);
   233                 rejectWarnings = true;
   234             } else if (arg.equals("-private")) {
   235                 setOption(arg);
   236                 setFilter(ModifierFilter.ALL_ACCESS);
   237             } else if (arg.equals("-package")) {
   238                 setOption(arg);
   239                 setFilter(PUBLIC | PROTECTED |
   240                           ModifierFilter.PACKAGE );
   241             } else if (arg.equals("-protected")) {
   242                 setOption(arg);
   243                 setFilter(PUBLIC | PROTECTED );
   244             } else if (arg.equals("-public")) {
   245                 setOption(arg);
   246                 setFilter(PUBLIC);
   247             } else if (arg.equals("-source")) {
   248                 oneArg(argv, i++);
   249                 if (compOpts.get("-source") != null) {
   250                     usageError("main.option.already.seen", arg);
   251                 }
   252                 compOpts.put("-source", argv[i]);
   253             } else if (arg.equals("-prompt")) {
   254                 compOpts.put("-prompt", "-prompt");
   255                 messager.promptOnError = true;
   256             } else if (arg.equals("-sourcepath")) {
   257                 oneArg(argv, i++);
   258                 if (compOpts.get("-sourcepath") != null) {
   259                     usageError("main.option.already.seen", arg);
   260                 }
   261                 compOpts.put("-sourcepath", argv[i]);
   262             } else if (arg.equals("-classpath")) {
   263                 oneArg(argv, i++);
   264                 if (compOpts.get("-classpath") != null) {
   265                     usageError("main.option.already.seen", arg);
   266                 }
   267                 compOpts.put("-classpath", argv[i]);
   268             } else if (arg.equals("-sysclasspath")) {
   269                 oneArg(argv, i++);
   270                 if (compOpts.get("-bootclasspath") != null) {
   271                     usageError("main.option.already.seen", arg);
   272                 }
   273                 compOpts.put("-bootclasspath", argv[i]);
   274             } else if (arg.equals("-bootclasspath")) {
   275                 oneArg(argv, i++);
   276                 if (compOpts.get("-bootclasspath") != null) {
   277                     usageError("main.option.already.seen", arg);
   278                 }
   279                 compOpts.put("-bootclasspath", argv[i]);
   280             } else if (arg.equals("-extdirs")) {
   281                 oneArg(argv, i++);
   282                 if (compOpts.get("-extdirs") != null) {
   283                     usageError("main.option.already.seen", arg);
   284                 }
   285                 compOpts.put("-extdirs", argv[i]);
   286             } else if (arg.equals("-overview")) {
   287                 oneArg(argv, i++);
   288             } else if (arg.equals("-doclet")) {
   289                 i++;  // handled in setDocletInvoker
   290             } else if (arg.equals("-docletpath")) {
   291                 i++;  // handled in setDocletInvoker
   292             } else if (arg.equals("-locale")) {
   293                 if (i != 0)
   294                     usageError("main.locale_first");
   295                 oneArg(argv, i++);
   296                 docLocale = argv[i];
   297             } else if (arg.startsWith("-XD")) {
   298                 String s = arg.substring("-XD".length());
   299                 int eq = s.indexOf('=');
   300                 String key = (eq < 0) ? s : s.substring(0, eq);
   301                 String value = (eq < 0) ? s : s.substring(eq+1);
   302                 compOpts.put(key, value);
   303             }
   304             // call doclet for its options
   305             // other arg starts with - is invalid
   306             else if ( arg.startsWith("-") ) {
   307                 int optionLength;
   308                 optionLength = docletInvoker.optionLength(arg);
   309                 if (optionLength < 0) {
   310                     // error already displayed
   311                     exit();
   312                 } else if (optionLength == 0) {
   313                     // option not found
   314                     usageError("main.invalid_flag", arg);
   315                 } else {
   316                     // doclet added option
   317                     if ((i + optionLength) > argv.length) {
   318                         usageError("main.requires_argument", arg);
   319                     }
   320                     ListBuffer<String> args = new ListBuffer<String>();
   321                     for (int j = 0; j < optionLength-1; ++j) {
   322                         args.append(argv[++i]);
   323                     }
   324                     setOption(arg, args.toList());
   325                 }
   326             } else {
   327                 javaNames.append(arg);
   328             }
   329         }
   331         if (javaNames.isEmpty() && subPackages.isEmpty()) {
   332             usageError("main.No_packages_or_classes_specified");
   333         }
   335         if (!docletInvoker.validOptions(options.toList())) {
   336             // error message already displayed
   337             exit();
   338         }
   340         JavadocTool comp = JavadocTool.make0(context);
   341         if (comp == null) return false;
   343         if (showAccess == null) {
   344             setFilter(defaultFilter);
   345         }
   347         LanguageVersion languageVersion = docletInvoker.languageVersion();
   348         RootDocImpl root = comp.getRootDocImpl(
   349                 docLocale, encoding, showAccess,
   350                 javaNames.toList(), options.toList(), breakiterator,
   351                 subPackages.toList(), excludedPackages.toList(),
   352                 docClasses,
   353                 // legacy?
   354                 languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
   356         // pass off control to the doclet
   357         boolean ok = root != null;
   358         if (ok) ok = docletInvoker.start(root);
   360         // We're done.
   361         if (compOpts.get("-verbose") != null) {
   362             tm = System.currentTimeMillis() - tm;
   363             messager.notice("main.done_in", Long.toString(tm));
   364         }
   366         return ok;
   367     }
   369     private void setDocletInvoker(String[] argv) {
   370         String docletClassName = null;
   371         String docletPath = null;
   373         // Parse doclet specifying arguments
   374         for (int i = 0 ; i < argv.length ; i++) {
   375             String arg = argv[i];
   376             if (arg.equals("-doclet")) {
   377                 oneArg(argv, i++);
   378                 if (docletClassName != null) {
   379                     usageError("main.more_than_one_doclet_specified_0_and_1",
   380                                docletClassName, argv[i]);
   381                 }
   382                 docletClassName = argv[i];
   383             } else if (arg.equals("-docletpath")) {
   384                 oneArg(argv, i++);
   385                 if (docletPath == null) {
   386                     docletPath = argv[i];
   387                 } else {
   388                     docletPath += File.pathSeparator + argv[i];
   389                 }
   390             }
   391         }
   393         if (docletClassName == null) {
   394             docletClassName = defaultDocletClassName;
   395         }
   397         // attempt to find doclet
   398         docletInvoker = new DocletInvoker(messager,
   399                                           docletClassName, docletPath);
   400     }
   402     private void setFilter(long filterBits) {
   403         if (showAccess != null) {
   404             messager.error(null, "main.incompatible.access.flags");
   405             usage();
   406             exit();
   407         }
   408         showAccess = new ModifierFilter(filterBits);
   409     }
   411     /**
   412      * Set one arg option.
   413      * Error and exit if one argument is not provided.
   414      */
   415     private void oneArg(String[] args, int index) {
   416         if ((index + 1) < args.length) {
   417             setOption(args[index], args[index+1]);
   418         } else {
   419             usageError("main.requires_argument", args[index]);
   420         }
   421     }
   423     private void usageError(String key) {
   424         messager.error(null, key);
   425         usage();
   426         exit();
   427     }
   429     private void usageError(String key, String a1) {
   430         messager.error(null, key, a1);
   431         usage();
   432         exit();
   433     }
   435     private void usageError(String key, String a1, String a2) {
   436         messager.error(null, key, a1, a2);
   437         usage();
   438         exit();
   439     }
   441     /**
   442      * indicate an option with no arguments was given.
   443      */
   444     private void setOption(String opt) {
   445         String[] option = { opt };
   446         options.append(option);
   447     }
   449     /**
   450      * indicate an option with one argument was given.
   451      */
   452     private void setOption(String opt, String argument) {
   453         String[] option = { opt, argument };
   454         options.append(option);
   455     }
   457     /**
   458      * indicate an option with the specified list of arguments was given.
   459      */
   460     private void setOption(String opt, List<String> arguments) {
   461         String[] args = new String[arguments.length() + 1];
   462         int k = 0;
   463         args[k++] = opt;
   464         for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
   465             args[k++] = i.head;
   466         }
   467         options = options.append(args);
   468     }
   470 }

mercurial