langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java
changeset 37938 42baa89d2156
parent 37858 7c04fcb12bd4
child 37939 3eb8c2a89b77
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java	Wed Jul 05 21:41:01 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,557 +0,0 @@
-/*
- * Copyright (c) 1997, 2016, 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 java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-
-import com.sun.javadoc.*;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.CommandLine;
-import com.sun.tools.javac.main.Option;
-import com.sun.tools.javac.file.BaseFileManager;
-import com.sun.tools.javac.platform.PlatformDescription;
-import com.sun.tools.javac.platform.PlatformUtils;
-import com.sun.tools.javac.util.ClientCodeException;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Options;
-
-import static com.sun.tools.javac.code.Flags.*;
-
-/**
- * Main program of Javadoc.
- * Previously named "Main".
- *
- *  <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>
- *
- * @since 1.2
- * @author Robert Field
- * @author Neal Gafter (rewrite)
- */
-public class Start extends ToolOption.Helper {
-    /** Context for this invocation. */
-    private final Context context;
-
-    private final String defaultDocletClassName;
-    private final ClassLoader docletParentClassLoader;
-
-    private static final String javadocName = "javadoc";
-
-    private static final String standardDocletClassName =
-        "com.sun.tools.doclets.standard.Standard";
-
-    private final long defaultFilter = PUBLIC | PROTECTED;
-
-    private final Messager messager;
-
-    private DocletInvoker docletInvoker;
-
-    /**
-     * In API mode, exceptions thrown while calling the doclet are
-     * propagated using ClientCodeException.
-     */
-    private boolean apiMode;
-
-    private JavaFileManager fileManager;
-
-    Start(String programName,
-          PrintWriter errWriter,
-          PrintWriter warnWriter,
-          PrintWriter noticeWriter,
-          String defaultDocletClassName) {
-        this(programName, errWriter, warnWriter, noticeWriter, defaultDocletClassName, null);
-    }
-
-    public Start(PrintWriter pw) {
-        this(javadocName, pw, pw, pw, standardDocletClassName);
-    }
-
-    public Start(String programName,
-          PrintWriter errWriter,
-          PrintWriter warnWriter,
-          PrintWriter noticeWriter,
-          String defaultDocletClassName,
-          ClassLoader docletParentClassLoader) {
-        context = new Context();
-        messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
-        this.defaultDocletClassName = defaultDocletClassName;
-        this.docletParentClassLoader = docletParentClassLoader;
-    }
-
-    Start(String programName, String defaultDocletClassName) {
-        this(programName, defaultDocletClassName, null);
-    }
-
-    Start(String programName, String defaultDocletClassName,
-          ClassLoader docletParentClassLoader) {
-        context = new Context();
-        messager = new Messager(context, programName);
-        this.defaultDocletClassName = defaultDocletClassName;
-        this.docletParentClassLoader = docletParentClassLoader;
-    }
-
-    Start(String programName, ClassLoader docletParentClassLoader) {
-        this(programName, standardDocletClassName, docletParentClassLoader);
-    }
-
-    Start(String programName) {
-        this(programName, standardDocletClassName);
-    }
-
-    Start(ClassLoader docletParentClassLoader) {
-        this(javadocName, docletParentClassLoader);
-    }
-
-    public Start() {
-        this(javadocName);
-    }
-
-    public Start(Context context) {
-        this.context = Objects.requireNonNull(context);
-        apiMode = true;
-        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
-     */
-    @Override
-    void usage() {
-        usage(true);
-    }
-
-    void usage(boolean exit) {
-        usage("main.usage", "-help", null, exit);
-    }
-
-    @Override
-    void Xusage() {
-        Xusage(true);
-    }
-
-    void Xusage(boolean exit) {
-        usage("main.Xusage", "-X", "main.Xusage.foot", exit);
-    }
-
-    private void usage(String main, String doclet, String foot, 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);
-
-        // let doclet print usage information (does nothing on error)
-        if (docletInvoker != null) {
-            // RFE: this is a pretty bad way to get the doclet to show
-            // help info. Moreover, the output appears on stdout,
-            // and <i>not</i> on any of the standard streams passed
-            // to javadoc, and in particular, not to the noticeWriter
-            // But, to fix this, we need to fix the Doclet API.
-            docletInvoker.optionLength(doclet);
-        }
-
-        if (foot != null)
-            messager.notice(foot);
-
-        if (exit) exit();
-    }
-
-    /**
-     * Exit
-     */
-    private void exit() {
-        messager.exit();
-    }
-
-
-    /**
-     * Main program - external wrapper
-     */
-    public int begin(String... argv) {
-        boolean ok = begin(null, argv, Collections.<JavaFileObject> emptySet());
-        return ok ? 0 : 1;
-    }
-
-    public boolean begin(Class<?> docletClass, Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
-        Collection<String> opts = new ArrayList<>();
-        for (String opt: options) opts.add(opt);
-        return begin(docletClass, opts.toArray(new String[opts.size()]), fileObjects);
-    }
-
-    private boolean begin(Class<?> docletClass, String[] options, Iterable<? extends JavaFileObject> fileObjects) {
-        boolean failed = false;
-
-        try {
-            failed = !parseAndExecute(docletClass, options, fileObjects);
-        } catch (Messager.ExitJavadoc exc) {
-            // ignore, we just exit this way
-        } catch (OutOfMemoryError ee) {
-            messager.error(Messager.NOPOS, "main.out.of.memory");
-            failed = true;
-        } catch (ClientCodeException e) {
-            // simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl
-            throw e;
-        } catch (Error ee) {
-            ee.printStackTrace(System.err);
-            messager.error(Messager.NOPOS, "main.fatal.error");
-            failed = true;
-        } catch (Exception ee) {
-            ee.printStackTrace(System.err);
-            messager.error(Messager.NOPOS, "main.fatal.exception");
-            failed = true;
-        } finally {
-            if (fileManager != null
-                    && fileManager instanceof BaseFileManager
-                    && ((BaseFileManager) fileManager).autoClose) {
-                try {
-                    fileManager.close();
-                } catch (IOException ignore) {
-                }
-            }
-            messager.exitNotice();
-            messager.flush();
-        }
-        failed |= messager.nerrors() > 0;
-        failed |= rejectWarnings && messager.nwarnings() > 0;
-        return !failed;
-    }
-
-    /**
-     * Main program - internal
-     */
-    private boolean parseAndExecute(
-            Class<?> docletClass,
-            String[] argv,
-            Iterable<? extends JavaFileObject> fileObjects) throws IOException {
-        long tm = System.currentTimeMillis();
-
-        ListBuffer<String> javaNames = new ListBuffer<>();
-
-        // Preprocess @file arguments
-        try {
-            argv = CommandLine.parse(argv);
-        } catch (FileNotFoundException e) {
-            messager.error(Messager.NOPOS, "main.cant.read", e.getMessage());
-            exit();
-        } catch (IOException e) {
-            e.printStackTrace(System.err);
-            exit();
-        }
-
-
-        fileManager = context.get(JavaFileManager.class);
-
-        setDocletInvoker(docletClass, fileManager, argv);
-
-        compOpts = Options.instance(context);
-        // Make sure no obsolete source/target messages are reported
-        compOpts.put("-Xlint:-options", "-Xlint:-options");
-
-        // Parse arguments
-        for (int i = 0 ; i < argv.length ; i++) {
-            String arg = argv[i];
-
-            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);
-                }
-            } else if (arg.equals("-XDaccessInternalAPI")) {
-                // pass this hidden option down to the doclet, if it wants it
-                if (docletInvoker.optionLength("-XDaccessInternalAPI") == 1) {
-                    setOption(arg);
-                }
-            } 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);
-                String value = (eq < 0) ? s : s.substring(eq+1);
-                compOpts.put(key, value);
-            }
-            // call doclet for its options
-            // other arg starts with - is invalid
-            else if (arg.startsWith("-")) {
-                int optionLength;
-                optionLength = docletInvoker.optionLength(arg);
-                if (optionLength < 0) {
-                    // error already displayed
-                    exit();
-                } else if (optionLength == 0) {
-                    // option not found
-                    usageError("main.invalid_flag", arg);
-                } else {
-                    // doclet added option
-                    if ((i + optionLength) > argv.length) {
-                        usageError("main.requires_argument", arg);
-                    }
-                    ListBuffer<String> args = new ListBuffer<>();
-                    for (int j = 0; j < optionLength-1; ++j) {
-                        args.append(argv[++i]);
-                    }
-                    setOption(arg, args.toList());
-                }
-            } else {
-                javaNames.append(arg);
-            }
-        }
-
-        if (fileManager == null) {
-            JavacFileManager.preRegister(context);
-            fileManager = context.get(JavaFileManager.class);
-            if (fileManager instanceof BaseFileManager) {
-                ((BaseFileManager) fileManager).autoClose = true;
-            }
-        }
-        if (fileManager instanceof BaseFileManager) {
-            ((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
-        }
-
-        String platformString = compOpts.get("-release");
-
-        if (platformString != null) {
-            if (compOpts.isSet("-source")) {
-                usageError("main.release.bootclasspath.conflict", "-source");
-            }
-            if (fileManagerOpts.containsKey(Option.BOOTCLASSPATH)) {
-                usageError("main.release.bootclasspath.conflict", Option.BOOTCLASSPATH.getText());
-            }
-
-            PlatformDescription platformDescription =
-                    PlatformUtils.lookupPlatformDescription(platformString);
-
-            if (platformDescription == null) {
-                usageError("main.unsupported.release.version", platformString);
-            }
-
-            compOpts.put(Option.SOURCE, platformDescription.getSourceVersion());
-
-            context.put(PlatformDescription.class, platformDescription);
-
-            Collection<Path> platformCP = platformDescription.getPlatformPath();
-
-            if (platformCP != null) {
-                if (fileManager instanceof StandardJavaFileManager) {
-                    StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
-
-                    sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
-                } else {
-                    usageError("main.release.not.standard.file.manager", platformString);
-                }
-            }
-        }
-
-        compOpts.notifyListeners();
-
-        if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
-            usageError("main.No_packages_or_classes_specified");
-        }
-
-        if (!docletInvoker.validOptions(options.toList())) {
-            // error message already displayed
-            exit();
-        }
-
-        JavadocTool comp = JavadocTool.make0(context);
-        if (comp == null) return false;
-
-        if (showAccess == null) {
-            setFilter(defaultFilter);
-        }
-
-        LanguageVersion languageVersion = docletInvoker.languageVersion();
-        RootDocImpl root = comp.getRootDocImpl(
-                docLocale,
-                encoding,
-                showAccess,
-                javaNames.toList(),
-                options.toList(),
-                fileObjects,
-                breakiterator,
-                subPackages.toList(),
-                excludedPackages.toList(),
-                docClasses,
-                // legacy?
-                languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1,
-                quiet);
-
-        // release resources
-        comp = null;
-
-        // pass off control to the doclet
-        boolean ok = root != null;
-        if (ok) ok = docletInvoker.start(root);
-
-        // We're done.
-        if (compOpts.get("-verbose") != null) {
-            tm = System.currentTimeMillis() - tm;
-            messager.notice("main.done_in", Long.toString(tm));
-        }
-
-        return ok;
-    }
-
-    private <T> boolean isEmpty(Iterable<T> iter) {
-        return !iter.iterator().hasNext();
-    }
-
-    /**
-     * Init the doclet invoker.
-     * The doclet class may be given explicitly, or via the -doclet option in
-     * argv.
-     * If the doclet class is not given explicitly, it will be loaded from
-     * the file manager's DOCLET_PATH location, if available, or via the
-     * -doclet path option in argv.
-     * @param docletClass The doclet class. May be null.
-     * @param fileManager The file manager used to get the class loader to load
-     * the doclet class if required. May be null.
-     * @param argv Args containing -doclet and -docletpath, in case they are required.
-     */
-    private void setDocletInvoker(Class<?> docletClass, JavaFileManager fileManager, String[] argv) {
-        boolean exportInternalAPI = false;
-        String docletClassName = null;
-        String docletPath = null;
-
-        // Parse doclet specifying arguments
-        for (int i = 0 ; i < argv.length ; i++) {
-            String arg = argv[i];
-            if (arg.equals(ToolOption.DOCLET.opt)) {
-                oneArg(argv, i++);
-                if (docletClassName != null) {
-                    usageError("main.more_than_one_doclet_specified_0_and_1",
-                               docletClassName, argv[i]);
-                }
-                docletClassName = argv[i];
-            } else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
-                oneArg(argv, i++);
-                if (docletPath == null) {
-                    docletPath = argv[i];
-                } else {
-                    docletPath += File.pathSeparator + argv[i];
-                }
-            } else if (arg.equals("-XDaccessInternalAPI")) {
-                exportInternalAPI = true;
-            }
-        }
-
-        if (docletClass != null) {
-            // TODO, check no -doclet, -docletpath
-            docletInvoker = new DocletInvoker(messager, docletClass, apiMode, exportInternalAPI);
-        } else {
-            if (docletClassName == null) {
-                docletClassName = defaultDocletClassName;
-            }
-
-            // attempt to find doclet
-            docletInvoker = new DocletInvoker(messager, fileManager,
-                    docletClassName, docletPath,
-                    docletParentClassLoader,
-                    apiMode,
-                    exportInternalAPI);
-        }
-    }
-
-    /**
-     * Set one arg option.
-     * Error and exit if one argument is not provided.
-     */
-    private void oneArg(String[] args, int index) {
-        if ((index + 1) < args.length) {
-            setOption(args[index], args[index+1]);
-        } else {
-            usageError("main.requires_argument", args[index]);
-        }
-    }
-
-    @Override
-    void usageError(String key, Object... args) {
-        messager.error(Messager.NOPOS, key, args);
-        usage(true);
-    }
-
-    /**
-     * indicate an option with no arguments was given.
-     */
-    private void setOption(String opt) {
-        String[] option = { opt };
-        options.append(option);
-    }
-
-    /**
-     * indicate an option with one argument was given.
-     */
-    private void setOption(String opt, String argument) {
-        String[] option = { opt, argument };
-        options.append(option);
-    }
-
-    /**
-     * indicate an option with the specified list of arguments was given.
-     */
-    private void setOption(String opt, List<String> arguments) {
-        String[] args = new String[arguments.length() + 1];
-        int k = 0;
-        args[k++] = opt;
-        for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
-            args[k++] = i.head;
-        }
-        options.append(args);
-    }
-}