duke@1: /* jjg@1797: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package com.sun.tools.javadoc; duke@1: jjg@1357: import java.io.File; jjg@1357: import java.io.FileNotFoundException; jjg@1357: import java.io.IOException; jjg@1357: import java.io.PrintWriter; jjg@1413: import java.util.ArrayList; jjg@1413: import java.util.Collection; jjg@1413: import java.util.Collections; jjg@1413: jjg@1413: import javax.tools.JavaFileManager; jjg@1413: import javax.tools.JavaFileObject; jjg@1357: duke@1: import com.sun.javadoc.*; duke@1: import com.sun.tools.javac.main.CommandLine; jjg@1413: import com.sun.tools.javac.util.ClientCodeException; duke@1: import com.sun.tools.javac.util.Context; duke@1: import com.sun.tools.javac.util.List; duke@1: import com.sun.tools.javac.util.ListBuffer; jjg@1135: import com.sun.tools.javac.util.Log; duke@1: import com.sun.tools.javac.util.Options; duke@1: import static com.sun.tools.javac.code.Flags.*; duke@1: duke@1: /** duke@1: * Main program of Javadoc. duke@1: * Previously named "Main". duke@1: * jjg@1359: *
This is NOT part of any supported API.
jjg@1359: * If you write code that depends on this, you do so at your own risk.
jjg@1359: * This code and its internal interfaces are subject to change or
jjg@1359: * deletion without notice.
jjg@1359: *
duke@1: * @since 1.2
duke@1: * @author Robert Field
duke@1: * @author Neal Gafter (rewrite)
duke@1: */
jjg@1411: public class Start extends ToolOption.Helper {
jjg@1392: /** Context for this invocation. */
jjg@1392: private final Context context;
duke@1:
duke@1: private final String defaultDocletClassName;
jjg@129: private final ClassLoader docletParentClassLoader;
duke@1:
duke@1: private static final String javadocName = "javadoc";
duke@1:
duke@1: private static final String standardDocletClassName =
duke@1: "com.sun.tools.doclets.standard.Standard";
duke@1:
duke@1: private long defaultFilter = PUBLIC | PROTECTED;
duke@1:
jjg@1392: private final Messager messager;
duke@1:
duke@1: private DocletInvoker docletInvoker;
duke@1:
jjg@1413: /**
jjg@1413: * In API mode, exceptions thrown while calling the doclet are
jjg@1413: * propagated using ClientCodeException.
jjg@1413: */
jjg@1413: private boolean apiMode;
jjg@1413:
duke@1: Start(String programName,
duke@1: PrintWriter errWriter,
duke@1: PrintWriter warnWriter,
duke@1: PrintWriter noticeWriter,
duke@1: String defaultDocletClassName) {
jjg@129: this(programName, errWriter, warnWriter, noticeWriter, defaultDocletClassName, null);
jjg@129: }
jjg@129:
jjg@129: Start(String programName,
jjg@129: PrintWriter errWriter,
jjg@129: PrintWriter warnWriter,
jjg@129: PrintWriter noticeWriter,
jjg@129: String defaultDocletClassName,
jjg@129: ClassLoader docletParentClassLoader) {
jjg@1392: context = new Context();
jjg@1392: messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
duke@1: this.defaultDocletClassName = defaultDocletClassName;
jjg@129: this.docletParentClassLoader = docletParentClassLoader;
duke@1: }
duke@1:
duke@1: Start(String programName, String defaultDocletClassName) {
jjg@129: this(programName, defaultDocletClassName, null);
jjg@129: }
jjg@129:
jjg@129: Start(String programName, String defaultDocletClassName,
jjg@129: ClassLoader docletParentClassLoader) {
jjg@1392: context = new Context();
jjg@1392: messager = new Messager(context, programName);
duke@1: this.defaultDocletClassName = defaultDocletClassName;
jjg@129: this.docletParentClassLoader = docletParentClassLoader;
jjg@129: }
jjg@129:
jjg@129: Start(String programName, ClassLoader docletParentClassLoader) {
jjg@129: this(programName, standardDocletClassName, docletParentClassLoader);
duke@1: }
duke@1:
duke@1: Start(String programName) {
duke@1: this(programName, standardDocletClassName);
duke@1: }
duke@1:
jjg@129: Start(ClassLoader docletParentClassLoader) {
jjg@129: this(javadocName, docletParentClassLoader);
jjg@129: }
jjg@129:
duke@1: Start() {
duke@1: this(javadocName);
duke@1: }
duke@1:
jjg@1411: public Start(Context context) {
jjg@1411: context.getClass(); // null check
jjg@1411: this.context = context;
jjg@1413: apiMode = true;
jjg@1411: defaultDocletClassName = standardDocletClassName;
jjg@1411: docletParentClassLoader = null;
jjg@1411:
jjg@1411: Log log = context.get(Log.logKey);
jjg@1411: if (log instanceof Messager)
jjg@1411: messager = (Messager) log;
jjg@1411: else {
jjg@1411: PrintWriter out = context.get(Log.outKey);
jjg@1411: messager = (out == null) ? new Messager(context, javadocName)
jjg@1411: : new Messager(context, javadocName, out, out, out);
jjg@1411: }
jjg@1411: }
jjg@1411:
duke@1: /**
duke@1: * Usage
duke@1: */
jjg@1411: @Override
jjg@1411: void usage() {
jjg@1411: usage(true);
jjg@1411: }
jjg@1411:
jjg@1797: void usage(boolean exit) {
jjg@1797: usage("main.usage", "-help", null, exit);
jjg@1411: }
jjg@1411:
jjg@1411: @Override
jjg@1411: void Xusage() {
jjg@1411: Xusage(true);
duke@1: }
duke@1:
jjg@1797: void Xusage(boolean exit) {
jjg@1797: usage("main.Xusage", "-X", "main.Xusage.foot", exit);
jjg@1797: }
jjg@1797:
jjg@1797: private void usage(String main, String doclet, String foot, boolean exit) {
jjg@1797: // RFE: it would be better to replace the following with code to
jjg@1797: // write a header, then help for each option, then a footer.
jjg@1797: messager.notice(main);
jjg@1797:
jjg@1797: // let doclet print usage information (does nothing on error)
jjg@1797: if (docletInvoker != null) {
jjg@1797: // RFE: this is a pretty bad way to get the doclet to show
jjg@1797: // help info. Moreover, the output appears on stdout,
jjg@1797: // and not on any of the standard streams passed
jjg@1797: // to javadoc, and in particular, not to the noticeWriter
jjg@1797: // But, to fix this, we need to fix the Doclet API.
jjg@1797: docletInvoker.optionLength(doclet);
jjg@1797: }
jjg@1797:
jjg@1797: if (foot != null)
jjg@1797: messager.notice(foot);
jjg@1797:
jjg@1411: if (exit) exit();
jjg@584: }
jjg@584:
jjg@584: /**
duke@1: * Exit
duke@1: */
duke@1: private void exit() {
duke@1: messager.exit();
duke@1: }
duke@1:
duke@1:
duke@1: /**
duke@1: * Main program - external wrapper
duke@1: */
jjg@127: int begin(String... argv) {
jjg@1413: boolean ok = begin(null, argv, Collections.